Modularize index.html into separate CSS/JS files

Split the monolithic 5510-line index.html into 14 separate files:
- css/styles.css (1085 lines) - all styling
- js/translations.js - i18n (FR/EN/UA/DE)
- js/data.js - categories, presets, fallback data
- js/utils.js - shuffle, seed encoding/decoding
- js/seed.js - seed generation algorithms
- js/ribbon.js - country/category ribbon selectors
- js/setup.js - custom panel, mode selection, presets
- js/game.js - core game loop, state, timer
- js/game-end.js - end screen, Hungarian algorithm, odometer
- js/daily.js - daily mode, seeded RNG, leaderboard
- js/hints.js - tooltips, country descriptions
- js/ui-effects.js - animations, ripple, particles
- js/mobile.js - responsive ribbon tabs

Also allow .docx/.xlsx in .gitignore (used as dev resources).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Joshua Hirsig 2026-02-27 19:53:23 +01:00
parent 4ae45072eb
commit ea561cd0bd
15 changed files with 5027 additions and 5015 deletions

2
.gitignore vendored
View file

@ -2,6 +2,4 @@
*.DS_Store
node_modules/
.wrangler/
*.docx
*.xlsx
config.js

1085
css/styles.css Normal file

File diff suppressed because it is too large Load diff

5029
index.html

File diff suppressed because it is too large Load diff

306
js/daily.js Normal file
View file

@ -0,0 +1,306 @@
// ─── DAILY MODE ───────────────────────────────────────────────────────────────
var DAILY_API = (new URLSearchParams(window.location.search).get('api')) || window.GEOQUIZ_API || 'https://legrandgeoquiz-api.mathieu-viart73.workers.dev';
var dailyDate = ''; // "YYYY-MM-DD" du jour courant
var dailyToken = ''; // seed token reçu de l'API
var dailyScore = null; // score de la partie daily en cours
var isDailyMode = false;
// ── Initialisation : vérifie si déjà joué + affiche la date ──────────────────
async function initDailyBlock() {
// Date locale en YYYY-MM-DD
var now = new Date();
dailyDate = now.getFullYear() + '-' +
String(now.getMonth() + 1).padStart(2, '0') + '-' +
String(now.getDate()).padStart(2, '0');
// Afficher la date sur le badge
var badge = document.getElementById('daily-date-badge');
if (badge) badge.textContent = dailyDate;
// Vérifier si déjà joué aujourd'hui via l'API
try {
var res = await fetch(DAILY_API + '/api/played', { method: 'GET' });
if (res.ok) {
var data = await res.json();
if (data.played) {
_setDailyPlayed();
}
}
} catch(e) {
// Pas de connexion ? On laisse jouer, le serveur rejettera si besoin
console.warn('Daily check failed (offline?)', e);
}
}
function _setDailyPlayed() {
var btn = document.getElementById('btn-daily');
var msg = document.getElementById('daily-played-msg');
if (btn) { btn.disabled = true; }
if (msg) { msg.classList.remove('hidden'); }
}
// ── Lancer la partie Daily ────────────────────────────────────────────────────
async function startDailyGame() {
var btn = document.getElementById('btn-daily');
if (btn) { btn.disabled = true; btn.textContent = '⏳'; }
try {
// Récupérer le token du jour
var res = await fetch(DAILY_API + '/api/seed');
if (!res.ok) throw new Error('API error ' + res.status);
var data = await res.json();
dailyDate = data.date;
dailyToken = data.token;
} catch(e) {
alert(t('dailyErrNetwork'));
if (btn) { btn.disabled = false; btn.textContent = '🏆 Daily'; }
return;
}
// Générer une seed déterministe depuis le token
// On utilise le token comme graine pour mélanger les pays/catégories
var seed = _generateDailySeed(dailyToken);
if (!seed) {
alert(t('dailyErrNetwork'));
if (btn) { btn.disabled = false; }
return;
}
isDailyMode = true;
dailyScore = null;
// Lancer en mode custom / normal / 20s
gameMode = 'custom';
customSubMode = 'normal';
N_TURNS = 8;
TIME_PER_TURN = 20;
// Masquer le score et la seed pendant la partie (anti-triche)
document.getElementById('game-seed-display').style.display = 'none';
startGame('custom', seed);
}
// Génère une seed déterministe depuis le token du jour
function _generateDailySeed(token) {
// Utilise le token comme générateur pseudo-aléatoire déterministe
// On dérive un état RNG depuis le token, puis on tire pays et catégories
var rng = _makeRng(token);
// Pool complet
var countryPool = [];
for (var i = 0; i < countriesDB.length; i++) countryPool.push(i);
var catPool = [];
for (var i = 0; i < ALL_CATEGORIES.length; i++) catPool.push(i);
// Fisher-Yates shuffle déterministe
_shuffle(countryPool, rng);
_shuffle(catPool, rng);
// Prendre les 8 premiers pays et catégories compatibles
var n = 8;
var chosenCats = catPool.slice(0, n);
var catIds = chosenCats.map(function(i) { return ALL_CATEGORIES[i].id; });
// Filtrer les pays qui ont toutes les catégories
var eligible = countryPool.filter(function(ci) {
return catIds.every(function(id) {
var v = countriesDB[ci][id];
return v !== false && v !== null && v !== undefined;
});
});
if (eligible.length < n) {
// Fallback : on prend les meilleurs pays même si incomplets
eligible = countryPool;
}
var chosenCountries = eligible.slice(0, n);
// Re-mélanger l'ordre pour que les pays n'arrivent pas triés par index
_shuffle(chosenCountries, rng);
_shuffle(chosenCats, rng);
return encodeSeed(chosenCountries, chosenCats, 'normal', 20);
}
// LCG simple — suffisant pour une seed déterministe non-cryptographique
function _makeRng(token) {
// Hash du token → seed numérique
var seed = 0;
for (var i = 0; i < token.length; i++) {
seed = (seed * 31 + token.charCodeAt(i)) & 0x7FFFFFFF;
}
seed = seed || 12345;
return function() {
seed = (seed * 1664525 + 1013904223) & 0x7FFFFFFF;
return seed / 0x7FFFFFFF;
};
}
function _shuffle(arr, rng) {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(rng() * (i + 1));
var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
return arr;
}
// ── Fin de partie Daily : intercepte showEndPanel ─────────────────────────────
var _origShowEndPanel = null;
function _dailyShowEndPanel() {
// Appeler l'original
_origShowEndPanel();
if (!isDailyMode) return;
// Cacher la combinaison optimale et la seed (anti-triche daily)
var optBlock = document.getElementById('opt-block');
if (optBlock) optBlock.style.display = 'none';
var seedBox = document.getElementById('seed-display');
if (seedBox) seedBox.style.display = 'none';
var copyBtns = document.querySelector('[id="btn-copy-seed"]');
if (copyBtns) copyBtns.parentElement.style.display = 'none';
// Sauvegarder le score et ouvrir le modal submit
dailyScore = totalScore;
setTimeout(function() { openSubmitModal(); }, 600);
}
// ── Modal submit ──────────────────────────────────────────────────────────────
function openSubmitModal() {
var overlay = document.getElementById('daily-submit-overlay');
var display = document.getElementById('daily-score-display');
var input = document.getElementById('daily-pseudo-input');
var msg = document.getElementById('daily-submit-msg');
if (display) display.textContent = dailyScore !== null ? dailyScore + ' pts' : '—';
if (msg) msg.textContent = '';
if (input) input.value = '';
if (overlay) { overlay.style.display = 'flex'; setTimeout(function(){ if(input) input.focus(); }, 100); }
applyTranslations();
}
function skipDailySubmit() {
var overlay = document.getElementById('daily-submit-overlay');
if (overlay) overlay.style.display = 'none';
isDailyMode = false;
_setDailyPlayed();
// Ouvrir le leaderboard
setTimeout(openLeaderboard, 200);
}
async function submitDailyScore() {
var pseudo = (document.getElementById('daily-pseudo-input').value || '').trim();
var msg = document.getElementById('daily-submit-msg');
if (!pseudo || pseudo.length < 1 || pseudo.length > 20) {
msg.textContent = t('dailyErrPseudo');
msg.className = 'daily-submit-msg err';
return;
}
msg.textContent = '⏳';
msg.className = 'daily-submit-msg';
try {
var res = await fetch(DAILY_API + '/api/score', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pseudo: pseudo, score: dailyScore, seed_date: dailyDate })
});
var data = await res.json();
if (!res.ok) {
if (data.already_played) {
msg.textContent = t('dailyErrPlayed');
} else {
msg.textContent = data.error || t('dailyErrNetwork');
}
msg.className = 'daily-submit-msg err';
return;
}
// Succès
var rankStr = t('dailyRank') + ' ' + data.rank + ' ' + t('dailyOf') + ' ' + data.total;
msg.textContent = '✓ ' + rankStr;
msg.className = 'daily-submit-msg ok';
_setDailyPlayed();
isDailyMode = false;
// Fermer et ouvrir le leaderboard après 1.5s
setTimeout(function() {
document.getElementById('daily-submit-overlay').style.display = 'none';
openLeaderboard();
}, 1500);
} catch(e) {
msg.textContent = t('dailyErrNetwork');
msg.className = 'daily-submit-msg err';
}
}
// ── Leaderboard modal ─────────────────────────────────────────────────────────
async function openLeaderboard() {
var overlay = document.getElementById('daily-lb-overlay');
var dateEl = document.getElementById('daily-lb-date');
var rowsEl = document.getElementById('daily-lb-rows');
var totalEl = document.getElementById('daily-lb-total');
if (!overlay) return;
overlay.classList.add('open');
if (dateEl) dateEl.textContent = dailyDate || new Date().toISOString().slice(0,10);
if (rowsEl) rowsEl.innerHTML = '<div class="lb-empty">⏳</div>';
if (totalEl) totalEl.textContent = '';
applyTranslations();
try {
var date = dailyDate || new Date().toISOString().slice(0,10);
var res = await fetch(DAILY_API + '/api/leaderboard?date=' + date);
var data = await res.json();
_renderLeaderboard(data.scores || [], data.total || 0);
} catch(e) {
if (rowsEl) rowsEl.innerHTML = '<div class="lb-empty">' + t('dailyErrNetwork') + '</div>';
}
}
function _renderLeaderboard(scores, total) {
var rowsEl = document.getElementById('daily-lb-rows');
var totalEl = document.getElementById('daily-lb-total');
if (!scores || scores.length === 0) {
rowsEl.innerHTML = '<div class="lb-empty">' + t('dailyLbEmpty') + '</div>';
if (totalEl) totalEl.textContent = '';
return;
}
var medals = ['🥇', '🥈', '🥉'];
var rankClasses = ['gold', 'silver', 'bronze'];
var html = '';
scores.forEach(function(s, i) {
var rank = i + 1;
var rankStr = rank <= 3 ? medals[rank - 1] : rank;
var cls = rank <= 3 ? rankClasses[rank - 1] : '';
html += '<div class="lb-row">' +
'<span class="lb-rank ' + cls + '">' + rankStr + '</span>' +
'<span class="lb-pseudo">' + _escHtml(s.pseudo) + '</span>' +
'<span class="lb-score">' + s.score + '</span>' +
'</div>';
});
rowsEl.innerHTML = html;
if (totalEl && total > scores.length) {
totalEl.textContent = 'Top ' + scores.length + ' / ' + total + ' ' + (total > 1 ? t('lbTotalPlayersP') : t('lbTotalPlayers'));
}
}
function closeLbModal() {
var overlay = document.getElementById('daily-lb-overlay');
if (overlay) overlay.classList.remove('open');
}
function _escHtml(str) {
return String(str).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

147
js/data.js Normal file
View file

@ -0,0 +1,147 @@
// ─── CATEGORIES ───────────────────────────────────────────────────────────────
var ALL_CATEGORIES = [
{id:'pib',icon:'💰',fr:'PIB Total',en:'Total GDP',ua:'Загальний ВВП',de:'BIP Gesamt',desc:{fr:'Valeur totale des biens et services produits par un pays sur une année. Le rang indique la position économique globale.',en:"Total value of goods and services produced in a year. The rank indicates the country's overall economic position.",ua:'Загальна вартість товарів і послуг за рік. Ранг відображає економічне становище країни.',de:'Gesamtwert aller in einem Jahr produzierten Güter und Dienstleistungen. Der Rang zeigt die wirtschaftliche Position.'}},
{id:'nb_habitant',icon:'👥',fr:"Nb d'habitants",en:'Population',ua:'Населення',de:'Einwohnerzahl',desc:{fr:"Nombre total de personnes résidant dans le pays, indicateur fondamental de la taille d'un État.",en:"Total number of people residing in the country, a fundamental indicator of a state's size.",ua:'Загальна кількість людей у країні — базовий показник розміру держави.',de:'Gesamtzahl der im Land lebenden Personen, grundlegender Indikator für die Grösse eines Staates.'}},
{id:'depense_defense_pctg_pib',icon:'🛡️',fr:'Dépense défense % PIB',en:'Defense spending % GDP',ua:'Витрати на оборону % ВВП',de:'Verteidigungsausgaben % BIP',desc:{fr:"Part du budget national allouée à la défense, en % du PIB. Reflète les priorités stratégiques d'un pays.",en:"Share of national budget allocated to defense, as % of GDP. Reflects a country's strategic priorities.",ua:'Частка бюджету на оборону у відсотках від ВВП. Відображає стратегічні пріоритети країни.',de:'Anteil des Staatshaushalts für Verteidigung in % des BIP. Spiegelt die strategischen Prioritäten wider.'}},
{id:'indice_paix',icon:'☮️',fr:'Indice de paix',en:'Peace index',ua:'Індекс миру',de:'Friedensindex',desc:{fr:'Mesure le niveau de paix : conflits internes, relations avec les voisins, stabilité politique. Rang faible = plus pacifique.',en:'Measures peace and security: internal conflicts, neighbor relations, political stability. Low rank = more peaceful.',ua:'Вимірює рівень миру: конфлікти, відносини з сусідами, стабільність. Низький ранг = мирніша країна.',de:'Misst das Friedensniveau: interne Konflikte, Nachbarschaftsbeziehungen, politische Stabilität. Niedriger Rang = friedlicher.'}},
{id:'densite_pop',icon:'🏙️',fr:'Densité de population',en:'Population density',ua:'Густота населення',de:'Bevölkerungsdichte',desc:{fr:'Nombre d\'habitants par km², reflétant la concentration de la population sur le territoire.',en:'Number of inhabitants per km², reflecting the concentration of the population.',ua:'Кількість мешканців на км² — концентрація населення на території.',de:'Einwohner pro km², zeigt die Konzentration der Bevölkerung auf dem Staatsgebiet.'}},
{id:'age_median',icon:'📅',fr:'Âge médian',en:'Median age',ua:'Середній вік',de:'Medianalter',desc:{fr:'Âge qui sépare la population en deux groupes égaux. Indique si la population est plutôt jeune ou vieillissante.',en:'Age that divides the population into two equal groups. Indicates whether the population is younger or aging.',ua:'Вік, який ділить населення навпіл. Вказує, молода чи стара країна.',de:'Alter, das die Bevölkerung in zwei gleich grosse Gruppen teilt. Zeigt ob die Bevölkerung eher jung oder alt ist.'}},
{id:'taux_mortalite',icon:'💀',fr:'Taux de mortalité',en:'Mortality rate',ua:'Рівень смертності',de:'Sterberate',desc:{fr:'Nombre de décès pour 1 000 habitants, indicateur général de la santé d\'une population.',en:'Number of deaths per 1,000 inhabitants, a general health indicator.',ua:'Кількість смертей на 1 000 жителів — загальний показник здоров\'я населення.',de:'Anzahl Todesf00e4lle pro 1.000 Einwohner, allgemeiner Gesundheitsindikator.'}},
{id:'taux_mortalite_routiere',icon:'🚗',fr:'Mortalité routière',en:'Road mortality',ua:'Дорожня смертність',de:'Verkehrstote',desc:{fr:'Nombre de décès liés aux accidents de la route pour 100 000 habitants.',en:'Number of road accident deaths per 100,000 inhabitants.',ua:'Кількість загиблих у ДТП на 100 000 жителів.',de:'Anzahl Verkehrstote pro 100\'000 Einwohner.'}},
{id:'taux_fecondite',icon:'🍼',fr:'Taux de fécondité',en:'Fertility rate',ua:'Рівень народжуваності',de:'Geburtenrate',desc:{fr:'Nombre moyen d\'enfants par femme. Influence la croissance démographique.',en:'Average number of children per woman. Directly influences population growth.',ua:'Середня кількість дітей на жінку. Впливає на демографічне зростання.',de:'Durchschnittliche Kinderzahl pro Frau. Beeinflusst das Bevölkerungswachstum.'}},
{id:'esperance_vie',icon:'❤️',fr:'Espérance de vie',en:'Life expectancy',ua:'Очікувана тривалість життя',de:'Lebenserwartung',desc:{fr:'Âge moyen auquel on s\'attend à vivre. Indicateur clé de la qualité de vie.',en:'Average age one is expected to live to. A key quality of life indicator.',ua:'Середній очікуваний вік. Ключовий показник якості життя.',de:'Durchschnittliches erwartetes Lebensalter. Wichtiger Indikator für Lebensqualität.'}},
{id:'pib_habitant',icon:'💵',fr:'PIB / Habitant',en:'GDP per capita',ua:'ВВП на душу населення',de:'BIP / Einwohner',desc:{fr:'Richesse économique moyenne par personne (PIB ÷ nb habitants).',en:'Average economic wealth per person (GDP ÷ population).',ua:'Середній економічний добробут на одну особу (ВВП ÷ населення).',de:'Durchschnittlicher wirtschaftlicher Wohlstand pro Person (BIP ÷ Einwohner).'}},
{id:'dette_publique_pctg_pib',icon:'📉',fr:'Dette publique % PIB',en:'Public debt % GDP',ua:'Держборг % ВВП',de:'Staatsverschuldung % BIP',desc:{fr:"Niveau d'endettement d'un État par rapport à sa richesse économique annuelle, en % du PIB.",en:"Level of a state's debt relative to its annual economic wealth, as % of GDP.",ua:'Рівень заборгованості держави відносно ВВП, у відсотках.',de:'Verschuldungsgrad eines Staates im Verhältnis zur jährlichen Wirtschaftsleistung, in % des BIP.'}},
{id:'indice_corruption',icon:'🕵️',fr:'Indice de corruption',en:'Corruption index',ua:'Індекс корупції',de:'Korruptionsindex',desc:{fr:'Mesure le niveau perçu de corruption dans le secteur public.',en:'Measures the perceived level of corruption in the public sector.',ua:'Вимірює сприйнятий рівень корупції в державному секторі.',de:'Misst das wahrgenommene Korruptionsniveau im öffentlichen Sektor.'}},
{id:'nb_touriste',icon:'✈️',fr:'Arrivées touristiques',en:'Tourist arrivals',ua:'Туристичні прибуття',de:'Touristenankünfte',desc:{fr:"Nombre total de visiteurs internationaux, indicateur de l'attractivité touristique.",en:"Total number of international visitors, an indicator of tourist attractiveness.",ua:'Загальна кількість міжнародних відвідувачів — показник привабливості країни.',de:'Gesamtzahl internationaler Besucher, Indikator für touristische Attraktivität.'}},
{id:'niveau_mathematique',icon:'📐',fr:'Niveau mathématiques',en:'Math level',ua:'Рівень математики',de:'Mathematikniveau',desc:{fr:'Performance en mathématiques mesurée par des tests standardisés internationaux (PISA).',en:'Math performance measured by international standardized tests (PISA).',ua:'Успішність з математики за міжнародними тестами (PISA).',de:'Mathematische Leistung gemessen durch internationale standardisierte Tests (PISA).'}},
{id:'empreinte_ecologique_par_habitant',icon:'🌱',fr:'Empreinte éco/hab',en:'Eco footprint/capita',ua:'Екослід на душу',de:'Öko-Fussabdruck/Einw.',desc:{fr:'Pression sur les ressources naturelles par habitant, en hectares globaux.',en:'Pressure on natural resources per inhabitant, in global hectares.',ua:'Навантаження на природні ресурси на одного жителя, у глобальних гектарах.',de:'Belastung der natürlichen Ressourcen pro Einwohner, in globalen Hektar.'}},
{id:'empreinte_ecologique',icon:'🌍',fr:'Empreinte écologique',en:'Ecological footprint',ua:'Екологічний слід',de:'Ökologischer Fussabdruck',desc:{fr:'Pression totale exercée par un pays sur les ressources naturelles, en hectares globaux.',en:"Total pressure exerted by a country on natural resources, in global hectares.",ua:'Загальне навантаження країни на природні ресурси, у глобальних гектарах.',de:'Gesamtbelastung eines Landes auf die natürlichen Ressourcen, in globalen Hektar.'}},
{id:'surface_foret_pctg_territoire',icon:'🌲',fr:'Surface forestière %',en:'Forest cover %',ua:'Лісовий покрив %',de:'Waldfläche %',desc:{fr:'Pourcentage du territoire couvert par des forêts. Indicateur de biodiversité.',en:'Percentage of the territory covered by forests. A biodiversity indicator.',ua:'Відсоток території, вкритої лісами. Показник біорізноманіття.',de:'Prozent des Staatsgebiets, das von Wald bedeckt ist. Biodiversitätsindikator.'}},
{id:'production_or',icon:'🥇',fr:"Production d'or",en:'Gold production',ua:'Виробництво золота',de:'Goldproduktion',desc:{fr:"Quantité d'or produite, liée à l'activité minière et aux ressources naturelles.",en:'Amount of gold produced, linked to mining activity and natural resources.',ua:'Кількість видобутого золота, пов\'язана з гірничодобувною діяльністю.',de:'Produzierte Goldmenge, verbunden mit Bergbau und nat\u00fcrlichen Ressourcen.'}},
{id:'pctg_irreligieux',icon:'🔮',fr:'% Irréligieux',en:'% Non-religious',ua:'% Нерелігійних',de:'% Nicht-Religiöse',desc:{fr:"Proportion de la population ne s'identifiant à aucune religion.",en:'Proportion of the population not identifying with any religion.',ua:'Частка населення без релігійної приналежності.',de:'Anteil der Bevölkerung, der sich keiner Religion zugehörig fühlt.'}},
{id:'taux_suicide',icon:'📊',fr:'Taux de suicide',en:'Suicide rate',ua:'Рівень суїциду',de:'Suizidrate',desc:{fr:'Nombre de suicides pour 100 000 habitants. Indicateur de santé mentale.',en:'Number of suicides per 100,000 inhabitants. A mental health indicator.',ua:'Кількість самогубств на 100 000 жителів. Показник психічного здоров\'я.',de:'Anzahl Suizide pro 100.000 Einwohner. Indikator f\u00fcr psychische Gesundheit.'}},
{id:'taux_tabagisme',icon:'🚬',fr:'Taux de tabagisme',en:'Smoking rate',ua:'Рівень куріння',de:'Raucherquote',desc:{fr:'Pourcentage de la population qui fume régulièrement.',en:'Percentage of the population that smokes regularly.',ua:'Відсоток населення, яке регулярно курить.',de:'Prozentsatz der Bevölkerung, die regelmässig raucht.'}},
{id:'conso_alcool_par_habitant',icon:'🍺',fr:'Conso alcool/hab',en:'Alcohol consumption/capita',ua:'Споживання алкоголю',de:'Alkoholkonsum/Einw.',desc:{fr:"Quantité moyenne d'alcool pur consommée par personne et par an.",en:'Average amount of pure alcohol consumed per person per year.',ua:'Середня кількість чистого алкоголю на одну особу на рік.',de:'Durchschnittliche Menge reinen Alkohols pro Person und Jahr.'}},
{id:'travail_enfant',icon:'👶',fr:'Travail des enfants',en:'Child labour',ua:'Дитяча праця',de:'Kinderarbeit',desc:{fr:"Prévalence du travail des enfants dans une activité économique. Reflète les conditions sociales.",en:'Prevalence of child labor in economic activity. Reflects social conditions.',ua:'Поширеність дитячої праці. Відображає соціально-економічні умови.',de:'Verbreitung von Kinderarbeit in wirtschaftlicher Tätigkeit. Spiegelt soziale Bedingungen wider.'}},
{id:'nb_militaire',icon:'🪖',fr:'Nb de militaires',en:'Military personnel',ua:'Військовий персонал',de:'Militärpersonal',desc:{fr:"Effectif total des forces armées. Indicateur de la capacité militaire d'un pays.",en:"Total size of a country's armed forces. A military capacity indicator.",ua:'Загальна чисельність збройних сил. Показник військового потенціалу країни.',de:'Gesamtstärke der Streitkräfte. Indikator für die militärische Kapazität eines Landes.'}},
{id:'classement_fifa_H',icon:'⚽',fr:'Classement FIFA (H)',en:'FIFA Ranking (M)',ua:'Рейтинг ФІФА (Ч)',de:'FIFA-Rangliste (M)',desc:{fr:"Position de l'équipe nationale masculine de football au classement mondial FIFA.",en:"Position of the men's national football team in the FIFA world rankings.",ua:'Позиція чоловічої збірної з футболу у світовому рейтингу ФІФА.',de:'Position der Herren-Fussballnationalmannschaft in der FIFA-Weltrangliste.'}},
{id:'classement_fifa_F',icon:'⚽',fr:'Classement FIFA (F)',en:'FIFA Ranking (W)',ua:'Рейтинг ФІФА (Ж)',de:'FIFA-Rangliste (F)',desc:{fr:"Position de l'équipe nationale féminine de football au classement mondial FIFA.",en:"Position of the women's national football team in the FIFA world rankings.",ua:'Позиція жіночої збірної з футболу у світовому рейтингу ФІФА.',de:'Position der Frauen-Fussballnationalmannschaft in der FIFA-Weltrangliste.'}},
{id:'classement_rugby_H',icon:'🏉',fr:'Classement Rugby (H)',en:'Rugby Ranking (M)',ua:'Рейтинг регбі (Ч)',de:'Rugby-Rangliste (M)',desc:{fr:"Position de l'équipe nationale masculine de rugby au classement mondial World Rugby.",en:"Position of the men's national rugby team in the World Rugby rankings.",ua:'Позиція чоловічої збірної з регбі у світовому рейтингу World Rugby.',de:'Position der Herren-Rugbynationalmannschaft in der World-Rugby-Weltrangliste.'}},
{id:'point_culminant',icon:'🏔️',fr:'Point culminant',en:'Highest point',ua:'Найвища точка',de:'Höchster Punkt',desc:{fr:"Altitude du sommet le plus élevé du pays, reflétant le relief du territoire.",en:"Altitude of the country's highest peak, reflecting the terrain.",ua:'Висота найвищої вершини країни, що відображає рельєф території.',de:'Höhe des höchsten Gipfels des Landes, spiegelt das Gelände wider.'}},
{id:'ordre_alphabetique',icon:'🔤',fr:'Ordre alphabétique',en:'Alphabetical order',ua:'Алфавітний порядок',de:'Alphabetische Reihenfolge',desc:{fr:"Position du pays dans une liste triée par nom (de A à Z).",en:"Position of the country in a list sorted by name (from A to Z).",ua:'Позиція країни у списку, відсортованому за назвою (від А до Я).',de:'Position des Landes in einer alphabetisch sortierten Liste (A bis Z).'}},
{id:'medaille_jo',icon:'🏅',fr:'Médailles JO',en:'Olympic medals',ua:'Олімпійські медалі',de:'Olympische Medaillen',desc:{fr:"Nombre total de médailles obtenues aux Jeux Olympiques. Reflète la puissance sportive.",en:"Total number of medals won at the Olympic Games. Reflects sporting prowess.",ua:'Загальна кількість медалей, здобутих на Олімпійських іграх. Відображає спортивну міць.',de:'Gesamtzahl der bei Olympischen Spielen gewonnenen Medaillen. Zeigt die sportliche Stärke.'}},
{id:'taux_obesite',icon:'🍔',fr:"Taux d'obésité",en:'Obesity rate',ua:'Рівень ожиріння',de:'Adipositasrate',desc:{fr:"Pourcentage de la population adulte souffrant d'obésité. Indicateur de santé publique.",en:"Percentage of the adult population suffering from obesity. A public health indicator.",ua:'Відсоток дорослого населення з ожирінням. Показник здоров’я нації.',de:'Prozentsatz der erwachsenen Bevölkerung mit Adipositas. Indikator für öffentliche Gesundheit.'}},
{id:'prevalence_cannabis_pctg',icon:'🌿',fr:'Prévalence cannabis',en:'Cannabis prevalence',ua:'Поширеність канабісу',de:'Cannabisverbreitung',desc:{fr:"Pourcentage de la population ayant consommé du cannabis au cours de l'année écoulée.",en:"Percentage of the population that has used cannabis in the past year.",ua:'Відсоток населення, яке вживало канабіс протягом останнього року.',de:'Prozentsatz der Bevölkerung, die im letzten Jahr Cannabis konsumiert hat.'}},
{id:'classement_bball_M',icon:'🏀',fr:'Classement Basket (M)',en:'Basketball ranking (M)',ua:'Рейтинг баскетболу (Ч)',de:'Basketball-Rangliste (M)',desc:{fr:"Position de l'équipe nationale masculine de basketball au classement mondial FIBA.",en:"Position of the men's national basketball team in the FIBA world rankings.",ua:'Позиція чоловічої збірної з баскетболу у світовому рейтингу FIBA.',de:'Position der Herren-Basketballnationalmannschaft in der FIBA-Weltrangliste.'}},
{id:'heureux',icon:'😊',fr:'Indice de bonheur',en:'Happiness index',ua:'Індекс щастя',de:'Glücksindex',desc:{fr:"Mesure le bien-être subjectif et la satisfaction de vie globale des habitants.",en:"Measures subjective well-being and overall life satisfaction of residents.",ua:'Вимірює суб’єктивне благополуччя та загальну задоволеність життям мешканців.',de:'Misst das subjektive Wohlbefinden und die allgemeine Lebenszufriedenheit der Bevölkerung.'}},
{id:'inegalite',icon:'⚖️',fr:'Indice dinégalité',en:'Inequality index',ua:'Індекс нерівності',de:'Ungleichheitsindex',desc:{fr:"Mesure les écarts de revenus et la répartition des richesses au sein de la population.",en:"Measures income gaps and wealth distribution within the population.",ua:'Вимірює розрив у доходах та розподіл багатства серед населення.',de:'Misst Einkommensunterschiede und Vermögensverteilung innerhalb der Bevölkerung.'}},
{id:'dictature',icon:'👮',fr:'Indice de dictature',en:'Dictatorship index',ua:'Індекс диктатури',de:'Diktaturindex',desc:{fr:"Mesure le niveau de liberté politique et le type de régime (de dicature à démocratie).",en:"Measures the level of political freedom and regime type (from dictatorship to democracy).",ua:'Вимірює рівень політичної свободи та тип режиму (від диктатури до демократії).',de:'Misst das Niveau politischer Freiheit und den Regimetyp (von Diktatur bis Demokratie).'}}
];
function catName(cat) { return cat[currentLang] || cat.fr; }
function catDesc(cat) { return (cat.desc && cat.desc[currentLang]) ? cat.desc[currentLang] : (cat.desc ? cat.desc.fr : ''); }
function getCountryName(c) {
if (currentLang === 'de') return c.country_DE || c.country_EN || c.country_FR || c.name || '???';
if (currentLang === 'en') return c.country_EN || c.country_FR || c.name || '???';
if (currentLang === 'ua') return c.country_UA || c.country_FR || c.name || '???';
return c.country_FR || c.country_EN || c.name || '???';
}
// ─── FALLBACK DATA ─────────────────────────────────────────────────────────
function getFallbackData() {
return [
{country_FR:'France', country_EN:'France', country_UA:'Франція',country_DE:'Frankreich', flag:'🇫🇷',pib:17, nb_habitant:80, pib_habitant:15, taux_fecondite:100,taux_suicide:20, empreinte_ecologique:55, conso_alcool_par_habitant:12, indice_paix:67, densite_pop:30, esperance_vie:35,travail_enfant:180},
{country_FR:'États-Unis',country_EN:'United States', country_UA:'США',country_DE:'Vereinigte Staaten', flag:'🇺🇸',pib:1, nb_habitant:3, pib_habitant:8, taux_fecondite:95, taux_suicide:55, empreinte_ecologique:5, conso_alcool_par_habitant:25, indice_paix:128,densite_pop:145,esperance_vie:55,travail_enfant:190},
{country_FR:'Brésil', country_EN:'Brazil', country_UA:'Бразилія',country_DE:'Brasilien', flag:'🇧🇷',pib:9, nb_habitant:7, pib_habitant:80, taux_fecondite:60, taux_suicide:60, empreinte_ecologique:40, conso_alcool_par_habitant:38, indice_paix:111,densite_pop:110,esperance_vie:70,travail_enfant:60},
{country_FR:'Japon', country_EN:'Japan', country_UA:'Японія',country_DE:'Japan', flag:'🇯🇵',pib:4, nb_habitant:11, pib_habitant:28, taux_fecondite:200,taux_suicide:30, empreinte_ecologique:35, conso_alcool_par_habitant:55, indice_paix:9, densite_pop:10, esperance_vie:5, travail_enfant:195},
{country_FR:'Inde', country_EN:'India', country_UA:'Індія',country_DE:'Indien', flag:'🇮🇳',pib:5, nb_habitant:2, pib_habitant:140,taux_fecondite:40, taux_suicide:45, empreinte_ecologique:130,conso_alcool_par_habitant:135,indice_paix:135,densite_pop:20, esperance_vie:90,travail_enfant:30},
{country_FR:'Norvège', country_EN:'Norway', country_UA:'Норвегія',country_DE:'Norwegen', flag:'🇳🇴',pib:35, nb_habitant:120,pib_habitant:3, taux_fecondite:130,taux_suicide:90, empreinte_ecologique:10, conso_alcool_par_habitant:70, indice_paix:17, densite_pop:180,esperance_vie:10,travail_enfant:192},
{country_FR:'Nigeria', country_EN:'Nigeria', country_UA:'Нігерія',country_DE:'Nigeria', flag:'🇳🇬',pib:28, nb_habitant:6, pib_habitant:150,taux_fecondite:5, taux_suicide:120,empreinte_ecologique:100,conso_alcool_par_habitant:80, indice_paix:150,densite_pop:50, esperance_vie:140,travail_enfant:15},
{country_FR:'Argentine', country_EN:'Argentina', country_UA:'Аргентина',country_DE:'Argentinien', flag:'🇦🇷',pib:22, nb_habitant:45, pib_habitant:65, taux_fecondite:80, taux_suicide:75, empreinte_ecologique:65, conso_alcool_par_habitant:45, indice_paix:74, densite_pop:155,esperance_vie:60,travail_enfant:120},
{country_FR:'Australie', country_EN:'Australia', country_UA:'Австралія',country_DE:'Australien', flag:'🇦🇺',pib:13, nb_habitant:55, pib_habitant:12, taux_fecondite:115,taux_suicide:80, empreinte_ecologique:8, conso_alcool_par_habitant:30, indice_paix:13, densite_pop:200,esperance_vie:15,travail_enfant:193},
{country_FR:'Chine', country_EN:'China', country_UA:'Китай',country_DE:'China', flag:'🇨🇳',pib:2, nb_habitant:2, pib_habitant:72, taux_fecondite:175,taux_suicide:40, empreinte_ecologique:3, conso_alcool_par_habitant:60, indice_paix:100,densite_pop:60, esperance_vie:50,travail_enfant:110}
];
}
// ─── PRESET DATA ──────────────────────────────────────────────────────────
// ─── PRESETS ──────────────────────────────────────────────────────────────────
var EUROPEAN_CODES = [
'AL','AD','AT','BY','BE','BA','BG','HR','CZ','DK',
'EE','FI','FR','DE','GR','HU','IS','IE','IT','XK',
'LV','LI','LT','LU','MT','MD','MC','ME','NL','MK',
'NO','PL','PT','RO','SM','RS','SK','SI','ES','SE',
'CH','UA','GB','VA','CY','AZ','GE','AM'
];
var AFRICAN_CODES = [
'DZ','AO','BJ','BW','BF','BI','CM','CV','CF','TD',
'KM','CG','CD','CI','DJ','EG','GQ','ER','SZ','ET',
'GA','GM','GH','GN','GW','KE','LS','LR','LY','MG',
'MW','ML','MR','MU','MA','MZ','NA','NE','NG','RE',
'RW','ST','SN','SL','SO','ZA','SS','SD','TZ','TG',
'TN','UG','ZM','ZW','SH'
];
var AMERICAS_CODES = [
'AG','AR','BS','BB','BZ','BO','BR','CA','CL','CO',
'CR','CU','DM','DO','EC','SV','GD','GT','GY','HT',
'HN','JM','MX','NI','PA','PY','PE','KN','LC','VC',
'SR','TT','US','UY','VE','PR','GP','MQ','GF'
];
var ASIAN_CODES = [
'AF','AM','AZ','BH','BD','BT','BN','KH','CN','CY',
'GE','IN','ID','IR','IQ','IL','JP','JO','KZ','KW',
'KG','LA','LB','MY','MV','MN','MM','NP','KP','OM',
'PK','PS','PH','QA','SA','SG','KR','LK','SY','TW',
'TJ','TH','TL','TM','AE','UZ','VN','YE','HK','MO'
];
var OCEANIA_CODES = [
'AU','FJ','KI','MH','FM','NR','NZ','PW','PG','WS',
'SB','TO','TV','VU','CK','PF','GU','NC','NU','NF',
'MP','AS','TK','WF'
];
var TOP100_PIB_CODES = [
'US','CN','JP','DE','IN','GB','FR','RU','CA','IT',
'BR','AU','KR','MX','ES','ID','SA','NL','TR','CH',
'TW','PL','AR','NO','SE','BE','IE','IL','AE','TH',
'EG','NG','AT','SG','BD','IR','VN','MY','ZA','PH',
'DK','PK','HK','CO','CL','RO','CZ','FI','IQ','PT',
'NZ','PE','QA','KZ','GR','DZ','HU','KW','UA','MA',
'ET','SK','EC','OM','DO','PR','KE','CU','AO','GT',
'VE','BG','LU','UZ','AZ','PA','TZ','LK','GH','BY',
'HR','UY','LT','CI','CR','CD','RS','MM','SI','TM',
'SD','JO','TN','LY','UG','BH','BO','CM','PY','LV'
];
var SPORT_CAT_IDS = ['classement_fifa_H','classement_fifa_F','classement_rugby_H','classement_bball_M'];
// Pays < ~1M habitants (rang nb_habitant >= 162 dans la DB)
var SMALL_COUNTRIES_CODES = [
'FJ','KM','GY','BT','SB','MO','LU','ME','SR','CV',
'MT','MV','BN','BS','BZ','IS','VU','PF','NC','BB',
'ST','WS','CW','LC','GU','KI','GD','FM','JE','TO',
'SC','AW','VC','VI','AG','IM','AD','DM','KY','BM',
'GG','GL','FO','MP','KN','TC','SX','AS','MH','LI',
'MC','SM','MF','BQ','PW','NR','TV'
];
// Pays partageant une frontière avec la France (métropole + DOM)
var FRANCE_NEIGHBORS_CODES = [
'BE','LU','DE','CH','IT','MC','AD','ES', // métropole
'GB', // tunnel sous la Manche
'BR','SR','SX' // Guyane française + Saint-Martin
];
// Pays enclavés (sans accès à la mer)
var LANDLOCKED_CODES = [
'AF','AM','AZ','BY','BT','BO','BW','BF','BI','CF',
'TD','CZ','ET','HU','KZ','KG','LA','LS','LI','LU',
'MW','ML','MD','MN','NP','NE','MK','PY','RW','SM',
'RS','SK','SS','SZ','TJ','TM','UG','UZ','ZM','ZW',
'AT','XK'
];
// Pays insulaires (entièrement entourés d'eau)
var ISLANDS_CODES = [
'AG','AU','BS','BB','CV','KM','CU','DM','FJ','GD',
'HT','IS','ID','JM','JP','KI','MV','MT','MH','MU',
'FM','NR','NZ','PW','PG','PH','KN','LC','VC','WS',
'ST','SC','SB','LK','TO','TT','TV','VU','CY','BN',
'TL','SG','GB','IE','MG','TW'
];

457
js/game-end.js Normal file
View file

@ -0,0 +1,457 @@
// ─── END GAME ─────────────────────────────────────────────────────────────────
// ─── OPTIMAL SOLVER — Algorithme Hongrois O(n³) ──────────────────────────────
// Remplace le brute-force O(n!) qui explose à partir de n=10 (16! = 20 billions)
// L'algorithme hongrois (Munkres) résout le problème d'affectation optimale en O(n³)
// et fonctionne instantanément pour n=16 comme pour n=8.
var optimalResult = null; // { score, assignment: [{country, catId, catObj, value}] }
function solveOptimal() {
var n = gameCountries.length;
var cats = gameCategories.map(function(c) { return c.id; });
var INF = 1e9;
var MISSING = 999; // coût pour une donnée manquante
// ── Construire la matrice de coûts n×n ──────────────────────────────────────
// cost[i][j] = coût d'assigner le pays i à la catégorie j
var cost = [];
for (var i = 0; i < n; i++) {
cost[i] = [];
for (var j = 0; j < n; j++) {
var v = gameCountries[i][cats[j]];
cost[i][j] = (v === false || v === null || v === undefined || isNaN(Number(v)))
? MISSING
: Number(v);
}
}
// ── Algorithme Hongrois (Munkres) ───────────────────────────────────────────
// Variables de potentiel (u pour lignes/pays, v pour colonnes/cats)
var u = new Array(n + 1).fill(0);
var v = new Array(n + 1).fill(0);
// p[j] = indice du pays actuellement affecté à la catégorie j (1-indexé, 0 = libre)
var p = new Array(n + 1).fill(0);
// way[j] = via quelle catégorie on est arrivé à j dans le chemin augmentant
var way = new Array(n + 1).fill(0);
for (var i = 1; i <= n; i++) {
// On place le pays i : on cherche le chemin augmentant le moins coûteux
p[0] = i;
var j0 = 0;
var minVal = new Array(n + 1).fill(INF);
var used = new Array(n + 1).fill(false);
do {
used[j0] = true;
var i0 = p[j0];
var delta = INF;
var j1 = -1;
for (var j = 1; j <= n; j++) {
if (!used[j]) {
// Coût réduit (en tenant compte des potentiels courants)
var cur = cost[i0 - 1][j - 1] - u[i0] - v[j];
if (cur < minVal[j]) {
minVal[j] = cur;
way[j] = j0;
}
if (minVal[j] < delta) {
delta = minVal[j];
j1 = j;
}
}
}
// Mise à jour des potentiels
for (var j = 0; j <= n; j++) {
if (used[j]) {
u[p[j]] += delta;
v[j] -= delta;
} else {
minVal[j] -= delta;
}
}
j0 = j1;
} while (p[j0] !== 0);
// Augmenter le long du chemin trouvé
do {
p[j0] = p[way[j0]];
j0 = way[j0];
} while (j0 !== 0);
}
// ── Reconstruire l'affectation depuis p[] ───────────────────────────────────
// p[j] = pays affecté à la catégorie j (indices 1-basés)
var catOfCountry = new Array(n); // catOfCountry[i] = indice de catégorie pour pays i
for (var j = 1; j <= n; j++) {
if (p[j] !== 0) catOfCountry[p[j] - 1] = j - 1;
}
var bestScore = 0;
var assignment = [];
for (var i = 0; i < n; i++) {
var ci = gameCountries[i];
var cj = catOfCountry[i];
var catId = cats[cj];
var val = ci[catId];
var numVal = (val === false || val === null || val === undefined || isNaN(Number(val)))
? null : Number(val);
bestScore += numVal !== null ? numVal : MISSING;
assignment.push({
country: ci,
catId: catId,
catObj: gameCategories[cj],
value: numVal
});
}
return { score: bestScore, assignment: assignment };
}
function endGame() {
if (timerInterval && timerInterval._raf) timerInterval._raf(); timerInterval = null;
// Apply ended theme
document.body.classList.remove('hardcore','custom-mode','reverse-mode');
if (isHardcoreActive()) document.body.classList.add('hardcore-ended');
document.getElementById('panel-game').classList.add('hidden');
// Show the dramatic reveal screen first
showEndReveal(function() {
// After reveal → show normal end panel
var revealEl = document.getElementById('end-reveal-screen');
revealEl.style.opacity = '0';
setTimeout(function() {
revealEl.style.display = 'none';
showEndPanel();
}, 400);
});
}
function showEndReveal(onDone) {
var screen = document.getElementById('end-reveal-screen');
var container = document.getElementById('reveal-rows-container');
var scoreEl = document.getElementById('reveal-running-score');
var labelEl = document.getElementById('reveal-running-label');
var titleEl = document.getElementById('reveal-screen-title');
container.innerHTML = '';
scoreEl.textContent = '0';
screen.style.display = 'flex';
screen.style.opacity = '0';
screen.style.flexDirection = 'column';
screen.style.alignItems = 'center';
screen.style.justifyContent = 'center';
// i18n labels
titleEl.textContent = isHardcoreActive() ? t('revealTitleHC') : t('revealTitle');
labelEl.textContent = t('revealScoreLabel');
// Fix: use inline style for opacity, not class (inline wins over class)
setTimeout(function() { screen.style.opacity = '1'; }, 30);
var delay = isHardcoreActive() ? 420 : 300;
// Pre-compute running totals so each setTimeout has the right snapshot
var cumulative = [];
var acc = 0;
gameLog.forEach(function(entry) {
var add = (entry.points === false || entry.points === null || isNaN(entry.points)) ? 0 : Number(entry.points);
acc += add;
cumulative.push(acc);
});
// Build all rows (hidden), then reveal one by one
gameLog.forEach(function(entry, i) {
var row = document.createElement('div');
row.className = 'reveal-row' + (entry.isPenalty ? ' penalty-row' : '');
var catLabel;
if (entry.isHint) {
catLabel = entry.hintLevel === 1 ? t('catLabelHint1') : t('catLabelHint2');
} else if (entry.isPenalty) {
catLabel = t('catLabelTimeUp');
} else {
catLabel = entry.catObj ? entry.catObj.icon + ' ' + catName(entry.catObj) : '?';
}
var ptsVal = entry.isPenalty ? '+' + entry.points : (entry.points === false ? '—' : entry.points);
var ptsClass = entry.isPenalty ? 'rr-pts penalty' : 'rr-pts';
var starHtml = '';
if (!entry.isPenalty && !entry.isHint && entry.starData) {
if (entry.starData.isGlobalBest) starHtml = '<span class="rr-star">🌟</span>';
else if (entry.starData.isGameBest) starHtml = '<span class="rr-star">⭐</span>';
}
row.innerHTML =
'<span class="rr-flag">' + entry.flag + '</span>' +
'<div class="rr-info">' +
'<div class="rr-name">' + entry.name + '</div>' +
'<div class="rr-cat">' + catLabel + '</div>' +
'</div>' +
'<span class="' + ptsClass + '">' + ptsVal + starHtml + '</span>';
container.appendChild(row);
applyEmoji(row);
setTimeout(function(r, prevScore, newScore) {
r.classList.add('shown');
if (newScore !== prevScore) {
animateCounter(scoreEl, prevScore, newScore, 300, null);
scoreEl.classList.remove('score-pop');
void scoreEl.offsetWidth;
scoreEl.classList.add('score-pop');
}
}.bind(null, row, i > 0 ? cumulative[i-1] : 0, cumulative[i]), (i + 1) * delay);
});
var totalDelay = (gameLog.length + 1) * delay + 800;
setTimeout(onDone, totalDelay);
}
function animateCounter(el, from, to, duration, onStep) {
var start = null;
function step(ts) {
if (!start) start = ts;
var progress = Math.min((ts - start) / duration, 1);
var eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
var current = Math.round(from + (to - from) * eased);
el.textContent = current;
if (onStep) onStep(current);
if (progress < 1) requestAnimationFrame(step);
else el.textContent = to;
}
requestAnimationFrame(step);
}
function showEndPanel() {
document.getElementById('panel-end').classList.remove('hidden');
// Recompute from gameLog to be bulletproof against any NaN accumulation
var computedScore = 0;
gameLog.forEach(function(e) {
var v = Number(e.points);
if (!isNaN(v)) computedScore += v;
});
var safeScore = computedScore;
totalScore = safeScore;
document.getElementById('final-score').textContent = safeScore;
var tl = t('taglines');
var idx = safeScore < 100 ? 0 : safeScore < 300 ? 1 : safeScore < 600 ? 2 : safeScore < 1000 ? 3 : 4;
document.getElementById('end-tagline').textContent = tl[idx];
document.getElementById('seed-display').innerHTML =
'<strong>' + t('seedShare') + '</strong><span id="seed-value">' + currentSeed + '</span>';
// Animate final score
var scoreEl2 = document.getElementById('final-score');
scoreEl2.textContent = '0';
animateCounter(scoreEl2, 0, safeScore, 900, null);
// Compute optimal
optimalResult = solveOptimal();
var diff = safeScore - optimalResult.score;
document.getElementById('opt-your-score').textContent = safeScore;
document.getElementById('opt-best-score').textContent = optimalResult.score;
applyTranslations();
var diffEl = document.getElementById('opt-diff-row');
if (diff <= 0) {
diffEl.innerHTML = '<span style="color:var(--accent);font-weight:700;">' + t('optPerfect') + '</span>';
} else {
diffEl.innerHTML = t('optDiff') + ': <span style="color:#ffb34f;font-weight:700;">+' + diff + '</span> pts';
}
}
function showOptModal() {
if (!optimalResult) return;
var modal = document.getElementById('opt-modal');
document.getElementById('opt-modal-explain').textContent = t('optExplain');
var rowsEl = document.getElementById('opt-modal-rows');
rowsEl.innerHTML = '';
// ── Construire un lookup optimal : country_FR → {catObj, catId, value} ─────
var optMap = {};
optimalResult.assignment.forEach(function(a) {
var key = a.country.country_FR || a.country.country_EN || '';
optMap[key] = { catObj: a.catObj, catId: a.catId, value: a.value };
});
// ── En-tête de colonnes ────────────────────────────────────────────────────
var header = document.createElement('div');
header.className = 'opt-row-header';
header.innerHTML =
'<span></span>' +
'<span></span>' +
'<span></span>' +
'<span style="color:#4fc3f7">' + t('optColOptimal') + '</span>' +
'<span class="opt-header-opt">' + t('optColOptimal').slice(0,3) + '</span>' +
'<span class="opt-header-mine">' + t('optColMine') + '</span>' +
'<span class="opt-header-diff">' + t('optColDiff') + '</span>';
rowsEl.appendChild(header);
// ── Lignes dans l'ordre de jeu — on ignore les hints (isHint:true) ─────────
var totalOpt = 0;
var totalMine = 0;
gameLog.forEach(function(entry) {
// Ignorer les entrées de hints (pénalités internes au tour, pas des tours)
if (entry.isHint) return;
var flag = entry.flag || '🌍';
var cname = entry.name || '?';
var cname_short = cname.length > 14 ? cname.slice(0, 13) + '…' : cname;
// Score du joueur pour ce tour
var myScore = entry.isPenalty ? null : (entry.points !== undefined ? entry.points : null);
var myScoreTxt = entry.isPenalty ? '⚠️' : (myScore !== null ? myScore : '?');
// Affectation optimale pour ce pays (via country ref ou fallback nom)
var countryKey = entry.country
? (entry.country.country_FR || entry.country.country_EN || cname)
: cname;
var optEntry = optMap[countryKey];
var optCatObj = optEntry ? optEntry.catObj : null;
var optVal = optEntry ? optEntry.value : null;
var optTxt = optVal !== null ? optVal : '?';
var optCatName = optCatObj ? catName(optCatObj) : (optEntry ? optEntry.catId : '?');
var optCatShort = optCatName.length > 14 ? optCatName.slice(0, 13) + '…' : optCatName;
// Diff
var diffTxt = '';
var diffClass = '';
if (!entry.isPenalty && myScore !== null && optVal !== null) {
var diff = myScore - optVal;
diffTxt = diff === 0 ? '=' : (diff > 0 ? '+' + diff : '' + diff);
diffClass = diff === 0 ? 'zero' : (diff > 0 ? 'pos' : 'zero');
} else if (entry.isPenalty) {
diffTxt = '+200';
diffClass = 'pos';
}
// Accumulation totaux
if (!entry.isPenalty && myScore !== null) totalMine += myScore;
if (optVal !== null) totalOpt += optVal;
var row = document.createElement('div');
row.className = 'opt-row' + (entry.isPenalty ? ' was-penalty' : '');
row.innerHTML =
'<span class="opt-row-flag">' + flag + '</span>' +
'<span class="opt-row-country" title="' + cname + '">' + cname_short + '</span>' +
'<span class="opt-row-arrow">→</span>' +
'<span class="opt-row-cat" title="' + optCatName + '">' + optCatShort + '</span>' +
'<span class="opt-row-score">' + optTxt + '</span>' +
'<span class="opt-row-mine">' + myScoreTxt + '</span>' +
'<span class="opt-row-diff ' + diffClass + '">' + diffTxt + '</span>';
rowsEl.appendChild(row);
});
applyEmoji(rowsEl);
// ── Footer totaux ──────────────────────────────────────────────────────────
var totalDiff = totalMine - totalOpt;
document.getElementById('opt-modal-total').textContent = totalOpt;
document.getElementById('opt-modal-mine').textContent = totalMine;
var diffEl = document.getElementById('opt-modal-diff-total');
diffEl.textContent = totalDiff === 0 ? '0' : (totalDiff > 0 ? '+' + totalDiff : '' + totalDiff);
diffEl.style.color = totalDiff <= 0 ? 'var(--accent)' : '#ff7c7c';
modal.style.display = 'block';
setTimeout(function(){ modal.style.opacity='1'; }, 10);
}
function hideOptModal() {
document.getElementById('opt-modal').style.display = 'none';
}
// Close modal on background click
document.getElementById('opt-modal').addEventListener('click', function(e) {
if (e.target === this) hideOptModal();
});
function resetToMenu() {
// Nettoyer le hash URL
history.replaceState(null, '', window.location.pathname + window.location.search);
document.body.classList.remove('hardcore','hardcore-ended','custom-mode','reverse-mode');
TIME_PER_TURN = 20;
N_TURNS = 8;
gameMode = 'normal';
// Réinitialiser les éléments daily
isDailyMode = false;
dailyScore = null;
document.getElementById('game-seed-display').style.display = '';
var optBlock = document.getElementById('opt-block');
if (optBlock) optBlock.style.display = '';
var seedBox = document.getElementById('seed-display');
if (seedBox) seedBox.style.display = '';
var copyBtnsParent = document.getElementById('btn-copy-seed');
if (copyBtnsParent && copyBtnsParent.parentElement) copyBtnsParent.parentElement.style.display = '';
draftMode = 'auto';
customSubMode = 'normal';
['normal','hardcore','reverse'].forEach(function(m) {
var el = document.getElementById('submode-pill-' + m);
if (!el) return;
el.classList.remove('active-normal','active-hardcore','active-reverse');
if (m === 'normal') el.classList.add('active-normal');
});
document.getElementById('panel-custom').classList.add('hidden');
document.getElementById('panel-end').classList.add('hidden');
var revealEl = document.getElementById('end-reveal-screen');
revealEl.style.display = 'none';
revealEl.classList.remove('visible');
document.getElementById('panel-setup').classList.remove('hidden');
document.getElementById('setup-ready').classList.remove('hidden');
document.getElementById('loader').classList.add('hidden');
applyTranslations();
}
function replayGame() {
// Replay with same mode and settings (skip menu)
document.getElementById('panel-end').classList.add('hidden');
var revealEl = document.getElementById('end-reveal-screen');
revealEl.style.display = 'none';
revealEl.classList.remove('visible');
isDailyMode = false;
dailyScore = null;
startGame(gameMode);
}
function getShareUrl() {
var base = window.location.href.split('#')[0];
return base + '#seed=' + encodeURIComponent(currentSeed);
}
function _copyToClipboard(text, btn, successMsg) {
var orig = btn ? btn.textContent : '';
var done = function() {
if (btn) { btn.textContent = successMsg; setTimeout(function() { btn.textContent = orig; }, 2000); }
};
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(done).catch(function() {
var ta = document.createElement('textarea');
ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
done();
});
} else {
var ta = document.createElement('textarea');
ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
done();
}
}
function copySeed() {
var btn = document.getElementById('btn-copy-seed');
_copyToClipboard(currentSeed || '', btn, t('copied'));
}
function copyUrl() {
var btn = document.getElementById('btn-copy-url');
_copyToClipboard(getShareUrl(), btn, t('copiedUrl'));
}

838
js/game.js Normal file
View file

@ -0,0 +1,838 @@
// ─── STATE ────────────────────────────────────────────────────────────────────
var countriesDB = [];
var gameCountries = [];
var gameCategories = [];
var currentStep = 0;
var totalScore = 0;
var timerInterval = null;
var timeLeft = 20;
var usedCategories = {};
var gameLog = []; // [{flag, name, catObj, points, isPenalty}]
var currentSeed = '';
var TIME_PER_TURN = 20;
var isRevealing = false;
var gameMode = 'normal'; // 'normal' | 'hardcore' | 'custom'
var N_TURNS = 8;
// hideScore : true en mode hardcore (le score est masque pendant la partie)
function hideScore() { return gameMode === 'hardcore' || (gameMode === 'custom' && customSubMode === 'hardcore'); }
function isHardcoreActive() { return gameMode === 'hardcore' || (gameMode === 'custom' && customSubMode === 'hardcore'); }
var CUSTOM_TIME = 20;
var draftMode = 'auto'; // 'auto'|'cats'|'countries'
var reverseAssignments = {}; // countryIdx -> catId, for reverse mode
var draftCounter = 0; // increments each game, used for alternating
var lastDraftUsed = ''; // 'cats' or 'countries' — set during generation
// ─── INIT ─────────────────────────────────────────────────────────────────────
async function initApp() {
try {
var res = await fetch('./country.json');
if (!res.ok) throw new Error('not found');
var data = await res.json();
countriesDB = data.Main || data.countries || data;
} catch(e) {
console.warn('country.json not found — using fallback');
countriesDB = getFallbackData();
}
document.getElementById('loader').classList.add('hidden');
document.getElementById('setup-ready').classList.remove('hidden');
applyTranslations();
// ── Patch showEndPanel pour le mode Daily ──────────────────────────────────
_origShowEndPanel = showEndPanel;
showEndPanel = _dailyShowEndPanel;
// ── Initialiser le bloc Daily (vérif already-played, date badge) ───────────
initDailyBlock();
// ── Lecture du hash URL : #seed=XXXX ──────────────────────────────────────
var hash = window.location.hash;
var match = hash.match(/[#&]seed=([^&]+)/);
if (match) {
var seedFromUrl = decodeURIComponent(match[1]);
setTimeout(function() {
startGame('custom', seedFromUrl);
}, 100);
}
}
function showCountdown(onDone) {
var overlay = document.getElementById('countdown-overlay');
var numEl = document.getElementById('countdown-num');
var subEl = document.getElementById('countdown-sub');
var counts = ['3','2','1','GO'];
overlay.classList.add('active');
subEl.textContent = '';
var i = 0;
function showStep() {
numEl.className = 'countdown-num';
void numEl.offsetWidth;
numEl.textContent = counts[i];
// On GO: show draft emoji as subtitle
if (i === counts.length - 1) {
subEl.textContent = lastDraftUsed === 'countries' ? '🌍' : '📊';
} else {
subEl.textContent = '';
}
i++;
if (i < counts.length) {
setTimeout(function() {
numEl.classList.add('fadeout');
setTimeout(showStep, 300);
}, 700);
} else {
setTimeout(function() {
numEl.classList.add('fadeout');
setTimeout(function() {
overlay.classList.remove('active');
subEl.textContent = '';
onDone();
}, 280);
}, 550);
}
}
showStep();
}
// ─── GAME START ───────────────────────────────────────────────────────────────
function startGame(modeOrSeed, seedOverride) {
if (modeOrSeed === 'normal' || modeOrSeed === 'hardcore' || modeOrSeed === 'custom' || modeOrSeed === 'reverse') {
gameMode = modeOrSeed;
} else if (typeof modeOrSeed === 'string' && modeOrSeed) {
seedOverride = modeOrSeed;
}
// Apply N_TURNS and time per mode
document.body.classList.remove('hardcore', 'custom-mode', 'reverse-mode');
if (gameMode === 'custom') {
if (!seedOverride) {
N_TURNS = parseInt(document.getElementById('custom-n-slider').value, 10) || 8;
}
TIME_PER_TURN = customTimeSelected;
document.body.classList.add('custom-mode');
document.getElementById('panel-custom').classList.add('hidden');
document.getElementById('panel-setup').classList.add('hidden');
// Apply sub-mode
if (customSubMode === 'hardcore') {
document.body.classList.add('hardcore');
} else if (customSubMode === 'reverse') {
document.body.classList.add('reverse-mode');
reverseAssignments = {};
}
} else if (gameMode === 'reverse') {
N_TURNS = 8;
TIME_PER_TURN = 20;
document.body.classList.add('reverse-mode');
document.getElementById('panel-setup').classList.add('hidden');
reverseAssignments = {};
} else {
N_TURNS = 8;
TIME_PER_TURN = (gameMode === 'hardcore') ? 10 : 20;
if (gameMode === 'hardcore') document.body.classList.add('hardcore');
document.getElementById('panel-setup').classList.add('hidden');
}
var seed = seedOverride || generateSeed();
if (!applyGameFromSeed(seed)) return;
// Sync N_TURNS to actual game size (important when loading a seed)
N_TURNS = gameCountries.length;
currentSeed = seed;
currentStep = 0;
totalScore = 0;
usedCategories = {};
gameLog = [];
isRevealing = false;
if (typeof resetHints === 'function') resetHints();
// Show countdown, then launch
showCountdown(function() {
document.getElementById('panel-game').classList.remove('hidden');
document.getElementById('game-seed-display').textContent = currentSeed;
// Mettre à jour le hash URL pour permettre le partage
history.replaceState(null, '', '#seed=' + encodeURIComponent(currentSeed));
renderCategoryButtons();
showTurn();
});
}
function startWithSeedInput() {
var raw = document.getElementById('seed-input').value.trim();
if (!raw) { alert(t('enterSeed')); return; }
// Support ancien format legacy (12-45_0-5) et nouveau format Base62
var seed = raw;
// Si l'utilisateur a collé du texte avec une seed entourée d'espaces, on nettoie
seed = seed.replace(/\s+/g, '');
startGame('custom', seed);
}
// ─── CATEGORY BUTTONS ─────────────────────────────────────────────────────────
function makeCatBtnHTML(cat) {
return '<div class="cat-btn-top">'
+ '<span class="cat-icon">' + cat.icon + '</span>'
+ '<span class="cat-info-btn" data-catid="' + cat.id + '">i</span>'
+ '</div>'
+ '<span class="cat-label-text">' + catName(cat) + '</span>';
}
function renderCategoryButtons() {
var grid = document.getElementById('cats-grid');
grid.innerHTML = '';
gameCategories.forEach(function(cat) {
var btn = document.createElement('button');
btn.className = 'cat-btn';
btn.id = 'cat-' + cat.id;
btn.innerHTML = makeCatBtnHTML(cat);
btn.addEventListener('click', function(e) {
if (e.target.closest('.cat-info-btn')) return;
handleChoice(cat.id);
});
grid.appendChild(btn);
});
attachInfoListeners();
}
// ─── RERENDER CURRENT TURN ON LANG CHANGE ─────────────────────────────────────
// Appelé par setLang() pour mettre à jour immédiatement le tour en cours
// sans attendre le prochain tour.
function rerenderCurrentTurn() {
var inGame = (document.getElementById('panel-game') &&
!document.getElementById('panel-game').classList.contains('hidden'));
if (!inGame) return;
if (currentStep >= gameCountries.length && currentStep >= gameCategories.length) return;
var isReverse = (gameMode === 'reverse' ||
(gameMode === 'custom' && customSubMode === 'reverse'));
if (isReverse) {
// ── Reverse : mettre à jour la catégorie affichée ─────────────────────
if (currentStep < gameCategories.length) {
var cat = gameCategories[currentStep];
document.getElementById('reverse-cat-name').textContent = catName(cat);
document.getElementById('reverse-cat-tooltip').textContent = catDesc(cat);
document.getElementById('turn-label').textContent =
t('reverseTurn') + ' ' + (currentStep + 1) + ' ' + t('of') + ' ' + gameCategories.length;
}
} else {
// ── Normal / Hardcore / Custom ─────────────────────────────────────────
if (currentStep < gameCountries.length) {
var c = gameCountries[currentStep];
document.getElementById('country-name').textContent = getCountryName(c);
document.getElementById('turn-label').textContent =
t('turn') + ' ' + (currentStep + 1) + ' ' + t('of') + ' ' + gameCountries.length;
// Hint buttons : état selon s'ils ont été révélés ou non
var btn1 = document.getElementById('hint-btn-1');
var btn2 = document.getElementById('hint-btn-2');
if (btn1 && !btn1.classList.contains('revealed')) {
btn1.innerHTML = '\uD83D\uDCA1 ' + t('hint1btn');
}
if (btn2 && !btn2.classList.contains('revealed')) {
btn2.innerHTML = '\uD83D\uDD0D ' + t('hint2btn');
}
// Labels des hints déjà révélés (titre de section)
if (hintState.hint1Revealed) {
var lbl1 = document.getElementById('hint-label-1');
if (lbl1) lbl1.innerHTML = t('hintLabel1') + ' <span class="cost-badge cost-badge-1">-25 pts</span>';
}
if (hintState.hint2Revealed) {
var lbl2 = document.getElementById('hint-label-2');
if (lbl2) lbl2.innerHTML = t('hintLabel2') + ' <span class="cost-badge cost-badge-2">-50 pts</span>';
}
}
}
}
function rerenderCategoryButtonNames() {
gameCategories.forEach(function(cat) {
var btn = document.getElementById('cat-' + cat.id);
if (!btn || btn.disabled) return;
var el = btn.querySelector('.cat-label-text');
if (el) el.textContent = catName(cat);
var infoBtn = btn.querySelector('.cat-info-btn');
if (infoBtn) {
infoBtn.replaceWith(infoBtn.cloneNode(true));
}
});
attachInfoListeners();
}
function attachInfoListeners() {
document.querySelectorAll('.cat-info-btn').forEach(function(el) {
var clone = el.cloneNode(true);
el.parentNode.replaceChild(clone, el);
clone.addEventListener('mouseenter', function() { showTooltip(clone.dataset.catid, clone); });
clone.addEventListener('mouseleave', hideTooltip);
clone.addEventListener('click', function(e) {
e.stopPropagation();
var tip = document.getElementById('cat-tooltip');
if (tip.classList.contains('visible')) hideTooltip();
else showTooltip(clone.dataset.catid, clone);
});
});
}
// ─── TURN DISPLAY ─────────────────────────────────────────────────────────────
function showTurn() {
if (currentStep >= gameCountries.length) { endGame(); return; }
if (gameMode === 'reverse' || (gameMode === 'custom' && customSubMode === 'reverse')) { showTurnReverse(); return; }
var c = gameCountries[currentStep];
var name = getCountryName(c);
var flag = c.flag || c.emoji || '🌍';
document.getElementById('country-flag').textContent = flag;
applyEmoji(document.getElementById('country-flag'));
document.getElementById('country-name').textContent = name;
document.getElementById('country-sub').textContent = '';
var btn1 = document.getElementById('hint-btn-1');
var desc1 = getCountryDesc(c);
btn1.style.display = desc1 ? 'inline-flex' : 'none';
document.getElementById('hint-btn-2').style.display = 'none';
document.getElementById('turn-label').textContent = t('turn') + ' ' + (currentStep+1) + ' ' + t('of') + ' ' + gameCountries.length;
document.getElementById('total-score').textContent = totalScore;
gameCategories.forEach(function(cat) {
var btn = document.getElementById('cat-' + cat.id);
if (!btn) return;
if (usedCategories[cat.id]) {
btn.disabled = true;
} else {
btn.disabled = false;
btn.innerHTML = makeCatBtnHTML(cat);
btn.style.borderColor = '';
btn.style.color = '';
// re-bind click
var newBtn = btn.cloneNode(true);
btn.parentNode.replaceChild(newBtn, btn);
(function(catId) {
newBtn.addEventListener('click', function(e) {
if (e.target.closest('.cat-info-btn')) return;
handleChoice(catId);
});
})(cat.id);
}
});
applyEmoji(document.getElementById('cats-grid'));
resetHints();
attachInfoListeners();
clearFeedback();
startTimer();
}
// ─── REVERSE MODE TURN ────────────────────────────────────────────────────────
function showTurnReverse() {
// In reverse: currentStep = which category is active
// All countries shown as buttons; user picks which country gets this category
var cat = gameCategories[currentStep];
document.getElementById('turn-label').textContent = t('reverseTurn') + ' ' + (currentStep+1) + ' ' + t('of') + ' ' + gameCategories.length;
document.getElementById('total-score').textContent = totalScore;
// Show the active category
document.getElementById('reverse-cat-icon').textContent = cat.icon;
applyEmoji(document.getElementById('reverse-cat-icon'));
document.getElementById('reverse-cat-name').textContent = catName(cat);
document.getElementById('reverse-cat-tooltip').textContent = catDesc(cat);
document.getElementById('reverse-cat-tooltip').classList.remove('open');
renderCountryButtons();
clearFeedback();
startTimer();
}
function toggleReverseCatInfo() {
var el = document.getElementById('reverse-cat-tooltip');
el.classList.toggle('open');
// refresh text in case lang changed
var cat = gameCategories[currentStep];
if (cat) el.textContent = catDesc(cat);
}
function renderCountryButtons() {
var grid = document.getElementById('countries-grid');
grid.innerHTML = '';
gameCountries.forEach(function(country, idx) {
var btn = document.createElement('button');
btn.className = 'country-btn';
btn.id = 'country-btn-' + idx;
var flag = country.flag || country.emoji || '🌍';
var name = getCountryName(country);
var assignedCatId = reverseAssignments[idx];
var catBadge = '';
if (assignedCatId) {
var assignedCat = gameCategories.find(function(c) { return c.id === assignedCatId; });
catBadge = assignedCat ? (assignedCat.icon + ' ' + catName(assignedCat)) : '';
btn.classList.add('assigned');
btn.disabled = true;
}
btn.innerHTML =
'<span class="cb-flag">' + flag + '</span>' +
'<span class="cb-info">' +
'<span class="cb-name">' + name + '</span>' +
(catBadge ? '<span class="cb-cat-badge">' + catBadge + '</span>' : '') +
'</span>';
applyEmoji(btn);
if (!assignedCatId) {
(function(i) {
btn.addEventListener('click', function() { handleCountryChoice(i); });
})(idx);
}
grid.appendChild(btn);
});
}
function handleCountryChoice(countryIdx) {
if (isRevealing) return;
if (timerInterval && timerInterval._raf) timerInterval._raf(); timerInterval = null;
var btn = document.getElementById('country-btn-' + countryIdx);
if (!btn || btn.disabled) return;
var cat = gameCategories[currentStep];
var country = gameCountries[countryIdx];
var rawVal = country[cat.id];
var points = (rawVal === false || rawVal === null || rawVal === undefined) ? false : Number(rawVal);
var pts = (points === false || isNaN(points)) ? 0 : Number(points);
var flag = country.flag || country.emoji || '🌍';
var cName = getCountryName(country);
reverseAssignments[countryIdx] = cat.id;
isRevealing = true;
// Mark chosen button
document.querySelectorAll('.country-btn').forEach(function(b) { b.disabled = true; });
btn.style.borderColor = '#f5c842';
btn.style.boxShadow = '0 0 14px rgba(245,200,66,0.35)';
var rsd = computeStarDataReverse(cat, countryIdx);
gameLog.push({flag:flag, name:cName, catObj:cat, points:pts, isPenalty:false, starData:rsd, country:gameCountries[countryIdx]});
var bestHtmlR = buildBestCountriesPanel(cat, countryIdx);
showReveal(flag, cName, cat, points, function() {
isRevealing = false;
if (pts > 0) {
totalScore += pts;
document.getElementById('total-score').textContent = totalScore;
}
currentStep++;
showTurn();
}, rsd, bestHtmlR);
}
function autoPick_reverse() {
// Timeout in reverse: penalty, assign to first available country
var firstFree = -1;
for (var i = 0; i < gameCountries.length; i++) {
if (!reverseAssignments[i]) { firstFree = i; break; }
}
if (firstFree === -1) { currentStep++; showTurn(); return; }
var cat = gameCategories[currentStep];
var country = gameCountries[firstFree];
var flag = country.flag || country.emoji || '🌍';
var cName = getCountryName(country);
var PENALTY = 200;
totalScore += PENALTY;
reverseAssignments[firstFree] = cat.id;
gameLog.push({flag:flag, name:cName, catObj:cat, points:PENALTY, isPenalty:true, country:country});
document.getElementById('total-score').textContent = totalScore;
var overlay = document.createElement('div');
overlay.id = 'reveal-overlay';
overlay.innerHTML =
'<div class="reveal-card" style="border-color:#ff9d00;">' +
'<div class="reveal-cat-label" style="color:#ff9d00;">' + t('timeUp') + '</div>' +
'<div class="reveal-cat-name" style="color:#f5c842;">' + cat.icon + ' ' + catName(cat) + '</div>' +
'<div class="reveal-country"><span class="reveal-flag">' + flag + '</span>' +
'<span class="reveal-country-name">' + cName + '</span></div>' +
'<div style="font-family:\'DM Mono\',monospace;font-size:4em;font-weight:700;color:#ff9d00;margin:16px 0;animation:penaltyPop 0.4s cubic-bezier(0.34,1.56,0.64,1);">+' + PENALTY + '</div>' +
'<div class="reveal-points-label" style="color:#ff9d00;">' + t('penalty') + '</div>' +
'<button class="reveal-skip" id="reveal-skip-btn" style="border-color:#f5c842;color:#f5c842;">' + t('skip') + '</button>' +
'</div>';
var s = document.createElement('style');
s.textContent = '@keyframes penaltyPop{from{transform:scale(0.5);opacity:0}to{transform:scale(1);opacity:1}}';
overlay.appendChild(s);
document.body.appendChild(overlay);
applyEmoji(overlay);
var closed = false;
function close() {
if (closed) return; closed = true;
overlay.style.transition = 'opacity 0.3s'; overlay.style.opacity = '0';
setTimeout(function() { isRevealing = false; overlay.remove(); currentStep++; showTurn(); }, 300);
}
document.getElementById('reveal-skip-btn').onclick = close;
setTimeout(close, 2500);
}
// ─── TIMER ────────────────────────────────────────────────────────────────────
function startTimer() {
if (timerInterval && timerInterval._raf) timerInterval._raf(); timerInterval = null;
// Infinite time: show ∞, no countdown, no autopick
if (TIME_PER_TURN === 0) {
var numEl2 = document.getElementById('timer-num');
var fillEl2 = document.getElementById('progress-fill');
numEl2.textContent = '∞';
fillEl2.style.width = '100%';
fillEl2.classList.remove('urgent');
numEl2.classList.remove('urgent', 'danger');
timerInterval = { _raf: function() {} };
return;
}
timeLeft = TIME_PER_TURN;
var startedAt = Date.now();
var fired = false;
var rafId = null;
var fillEl = document.getElementById('progress-fill');
fillEl.style.transition = 'none';
function tick() {
var elapsed = (Date.now() - startedAt) / 1000;
var remaining = Math.max(0, TIME_PER_TURN - elapsed);
timeLeft = Math.ceil(remaining);
updateTimerUI(remaining);
if (!fired && remaining <= 0) {
fired = true;
autoPick();
return;
}
if (!fired) rafId = requestAnimationFrame(tick);
}
timerInterval = { _raf: null };
rafId = requestAnimationFrame(tick);
timerInterval._raf = function() { cancelAnimationFrame(rafId); fired = true; };
updateTimerUI(TIME_PER_TURN);
}
function updateTimerUI(remaining) {
var numEl = document.getElementById('timer-num');
var fillEl = document.getElementById('progress-fill');
// remaining can be undefined on first call
var pct = (remaining !== undefined)
? (remaining / TIME_PER_TURN * 100)
: 100;
var displayNum = (remaining !== undefined) ? Math.ceil(remaining) : TIME_PER_TURN;
numEl.textContent = displayNum;
fillEl.style.width = pct + '%';
var urgent = displayNum <= (isHardcoreActive() ? 4 : 8);
numEl.classList.toggle('urgent', urgent);
fillEl.classList.toggle('urgent', urgent);
// Hardcore danger pulse
if (isHardcoreActive()) {
numEl.classList.toggle('danger', displayNum <= 4);
} else {
numEl.classList.remove('danger');
}
}
// ─── AUTO PICK ────────────────────────────────────────────────────────────────
function autoPick() {
if (isRevealing) return;
isRevealing = true;
if (timerInterval && timerInterval._raf) timerInterval._raf(); timerInterval = null;
if (gameMode === 'reverse' || (gameMode === 'custom' && customSubMode === 'reverse')) { autoPick_reverse(); return; }
disableAllCatButtons();
var PENALTY = 200;
totalScore += PENALTY;
var country = gameCountries[currentStep];
var cName = getCountryName(country);
var flag = country.flag || country.emoji || '🌍';
gameLog.push({flag:flag, name:cName, catObj:null, points:PENALTY, isPenalty:true, country:country});
// HC: no overlay, advance silently
if (isHardcoreActive()) {
setTimeout(function() { isRevealing = false; currentStep++; showTurn(); }, 350);
return;
}
// Normal mode: show penalty overlay
document.getElementById('total-score').textContent = totalScore;
var overlay = document.createElement('div');
overlay.id = 'reveal-overlay';
overlay.innerHTML =
'<div class="reveal-card" style="border-color:var(--accent2);">'
+ '<div class="reveal-cat-label" style="color:var(--accent2);">' + t('timeUp') + '</div>'
+ '<div class="reveal-cat-name" style="color:var(--accent2);">' + t('noAnswer') + '</div>'
+ '<div class="reveal-country"><span class="reveal-flag">' + flag + '</span>'
+ '<span class="reveal-country-name">' + cName + '</span></div>'
+ '<div style="font-family:\'DM Mono\',monospace;font-size:4em;font-weight:700;color:var(--accent2);margin:16px 0;animation:penaltyPop 0.4s cubic-bezier(0.34,1.56,0.64,1);">+' + PENALTY + '</div>'
+ '<div class="reveal-points-label" style="color:var(--accent2);">' + t('penalty') + '</div>'
+ '<button class="reveal-skip" id="reveal-skip-btn" style="border-color:var(--accent2);color:var(--accent2);">' + t('skip') + '</button>'
+ '</div>';
var s = document.createElement('style');
s.textContent = '@keyframes penaltyPop{from{transform:scale(0.5);opacity:0}to{transform:scale(1);opacity:1}}';
overlay.appendChild(s);
document.body.appendChild(overlay);
var overlayClosed = false;
function closeOverlay() {
if (overlayClosed) return;
overlayClosed = true;
overlay.style.transition = 'opacity 0.3s';
overlay.style.opacity = '0';
setTimeout(function() { isRevealing = false; overlay.remove(); currentStep++; showTurn(); }, 300);
}
applyEmoji(overlay);
document.getElementById('reveal-skip-btn').onclick = closeOverlay;
setTimeout(closeOverlay, 2800);
}
// ─── HANDLE CHOICE ────────────────────────────────────────────────────────────
function handleChoice(catId) {
if (isRevealing) return;
if (timerInterval && timerInterval._raf) timerInterval._raf(); timerInterval = null;
var btn = document.getElementById('cat-' + catId);
if (!btn || btn.disabled) return;
var country = gameCountries[currentStep];
var rawVal = country[catId];
var points = (rawVal === false || rawVal === null || rawVal === undefined) ? false : Number(rawVal);
var cName = getCountryName(country);
var flag = country.flag || country.emoji || '🌍';
var catObj = gameCategories.find(function(c) { return c.id === catId; });
usedCategories[catId] = true;
disableAllCatButtons();
btn.innerHTML =
'<div class="cat-btn-top"><span class="cat-icon">' + catObj.icon + '</span></div>'
+ '<span class="cat-label-text">' + catName(catObj) + '</span>'
+ '<span class="cat-badge"><span class="badge-flag">' + flag + '</span>' + cName + '</span>';
btn.style.borderColor = 'var(--accent3)';
btn.style.color = 'var(--accent3)';
applyEmoji(btn);
isRevealing = true;
var pts = (points === false || points === null || points === undefined || isNaN(points)) ? 0 : Number(points);
gameLog.push({flag:flag, name:cName, catObj:catObj, points:pts, isPenalty:false, country:country});
var sd = computeStarData(country, catId);
var lastEntry = gameLog[gameLog.length - 1]; if (lastEntry) lastEntry.starData = sd;
if (isHardcoreActive()) {
totalScore += pts;
setTimeout(function() { isRevealing = false; currentStep++; showTurn(); }, 420);
} else {
var bestHtml = buildBestCatsPanel(country, catId);
showReveal(flag, cName, catObj, points, function() {
isRevealing = false;
if (points !== false) totalScore += pts;
document.getElementById('total-score').textContent = totalScore;
currentStep++;
showTurn();
}, sd, bestHtml);
}
}
function disableAllCatButtons() {
document.querySelectorAll('.cat-btn').forEach(function(b) { b.disabled = true; });
}
// ─── STAR RATING HELPERS ─────────────────────────────────────────────────────
function computeStarData(country, chosenCatId) {
// Le jeu = MINIMISER le score : etoile = valeur la plus BASSE choisie
var chosenRaw = country[chosenCatId];
var chosenVal = (chosenRaw === false || chosenRaw === null || chosenRaw === undefined || isNaN(Number(chosenRaw))) ? null : Number(chosenRaw);
if (chosenVal === null) return { chosenVal:0, gameBest:0, globalBest:0, isGameBest:false, isGlobalBest:false };
// gameBest = valeur minimale parmi les categories disponibles pour ce pays
var gb = Infinity;
gameCategories.forEach(function(cat) {
var v = country[cat.id];
if (v !== false && v !== null && v !== undefined && !isNaN(Number(v))) {
var n = Number(v); if (n < gb) gb = n;
}
});
// globalBest = valeur minimale sur TOUTES les categories connues
var ab = Infinity;
ALL_CATEGORIES.forEach(function(cat) {
var v = country[cat.id];
if (v !== false && v !== null && v !== undefined && !isNaN(Number(v))) {
var n = Number(v); if (n < ab) ab = n;
}
});
gb = gb === Infinity ? 0 : gb;
ab = ab === Infinity ? 0 : ab;
var isGameBest = (chosenVal > 0 && chosenVal <= gb);
var isGlobalBest = (chosenVal > 0 && chosenVal <= ab);
return { chosenVal:chosenVal, gameBest:gb, globalBest:ab, isGameBest:isGameBest, isGlobalBest:isGlobalBest };
}
function computeStarDataReverse(cat, chosenIdx) {
// Mode reverse : etoile = pays avec la valeur la plus BASSE pour cette categorie
var country = gameCountries[chosenIdx];
var chosenRaw = country[cat.id];
var chosenVal = (chosenRaw===false||chosenRaw===null||chosenRaw===undefined||isNaN(Number(chosenRaw))) ? null : Number(chosenRaw);
if (chosenVal === null) return { chosenVal:0, gameBest:0, globalBest:0, isGameBest:false, isGlobalBest:false };
var gb = Infinity;
gameCountries.forEach(function(c) {
var v = c[cat.id];
if (v !== false && v !== null && v !== undefined && !isNaN(Number(v))) {
var n = Number(v); if (n < gb) gb = n;
}
});
var ab = Infinity;
countriesDB.forEach(function(c) {
var v = c[cat.id];
if (v !== false && v !== null && v !== undefined && !isNaN(Number(v))) {
var n = Number(v); if (n < ab) ab = n;
}
});
gb = gb === Infinity ? 0 : gb;
ab = ab === Infinity ? 0 : ab;
var isGameBest = (chosenVal > 0 && chosenVal <= gb);
var isGlobalBest = (chosenVal > 0 && chosenVal <= ab);
return { chosenVal:chosenVal, gameBest:gb, globalBest:ab, isGameBest:isGameBest, isGlobalBest:isGlobalBest };
}
// Panneau 'meilleurs choix' : trier par valeur ASCENDANTE (bas = meilleur score)
function buildBestCatsPanel(country, chosenCatId) {
var rows=[];
gameCategories.forEach(function(cat){var v=country[cat.id];if(v!==false&&v!==null&&v!==undefined&&!isNaN(Number(v)))rows.push({cat:cat,val:Number(v)});});
rows.sort(function(a,b){return a.val-b.val;});
return rows.slice(0,3).map(function(r){
var mark=r.cat.id===chosenCatId?' <span style="color:var(--accent)">&#10003;</span>':'';
return '<div class="reveal-best-row"><span class="rbr-cat">'+r.cat.icon+' '+catName(r.cat)+mark+'</span><span class="rbr-val">'+r.val+'</span></div>';
}).join('');
}
function buildBestCountriesPanel(cat, chosenIdx) {
var rows=[];
gameCountries.forEach(function(c,i){var v=c[cat.id];if(v!==false&&v!==null&&v!==undefined&&!isNaN(Number(v)))rows.push({c:c,i:i,val:Number(v)});});
rows.sort(function(a,b){return a.val-b.val;});
return rows.slice(0,3).map(function(r){
var flag=r.c.flag||r.c.emoji||'';
var mark=r.i===chosenIdx?' <span style="color:var(--accent)">&#10003;</span>':'';
return '<div class="reveal-best-row"><span class="rbr-cat">'+flag+' '+getCountryName(r.c)+mark+'</span><span class="rbr-val">'+r.val+'</span></div>';
}).join('');
}
function showReveal(flag, cName, catObj, finalValue, onDone, starData, bestPanelHtml) {
var overlay = document.createElement('div');
overlay.id = 'reveal-overlay';
var isFalse = finalValue === false;
var target = isFalse ? 0 : Math.abs(finalValue);
overlay.innerHTML =
'<div class="reveal-card">'
+ '<div class="reveal-cat-label">' + t('catSelected') + '</div>'
+ '<div class="reveal-cat-name">' + catObj.icon + ' ' + catName(catObj) + '</div>'
+ '<div class="reveal-country"><span class="reveal-flag">' + flag + '</span>'
+ '<span class="reveal-country-name">' + cName + '</span></div>'
+ '<div class="odometer-wrap" id="odo-wrap" style="' + (isHardcoreActive() ? 'display:none' : '') + '"></div>'
+ '<div class="reveal-points-label" style="' + (isHardcoreActive() ? 'display:none' : '') + '">' + (isFalse ? t('noData') : t('ptsAdded')) + '</div>'
+ '<button class="reveal-skip" id="reveal-skip-btn">' + t('skip') + '</button>'
+ '</div>';
document.body.appendChild(overlay);
applyEmoji(overlay);
var digits = target.toString().split('').map(Number);
if (!digits.length) digits.push(0);
var wrap = document.getElementById('odo-wrap');
buildOdometer(wrap, digits.length);
var animDone = false;
var skipBtn = document.getElementById('reveal-skip-btn');
var revealClosed = false;
function closeReveal() {
if (revealClosed) return;
revealClosed = true;
overlay.style.transition = 'opacity 0.3s';
overlay.style.opacity = '0';
setTimeout(function() { overlay.remove(); onDone(); }, 300);
}
function onComplete() {
animDone = true;
wrap.querySelectorAll('.odo-digit-wrap').forEach(function(d) { d.classList.add('done'); });
var slot = document.getElementById('reveal-star-slot');
if (slot && starData && !hideScore()) {
if (starData.isGlobalBest) {
slot.innerHTML = '<div class="reveal-star mega">🌟</div>';
var rect = slot.getBoundingClientRect();
burstStars(rect.left + rect.width/2, rect.top + rect.height/2);
} else if (starData.isGameBest) {
slot.innerHTML = '<div class="reveal-star">⭐</div>';
}
}
skipBtn.onclick = closeReveal;
var autoDelay = (starData && !hideScore() && (starData.isGlobalBest || starData.isGameBest)) ? 2800 : 1800;
setTimeout(function() { if (document.getElementById('reveal-overlay')) closeReveal(); }, autoDelay);
}
function onSkip() {
setOdometerToFinal(wrap, digits);
onComplete();
}
skipBtn.onclick = function() { animDone ? closeReveal() : onSkip(); };
runOdometerAnimation(wrap, digits, target, isFalse, onComplete, onSkip);
}
function buildOdometer(wrap, n) {
wrap.innerHTML = '';
for (var i = 0; i < n; i++) {
var dw = document.createElement('div');
dw.className = 'odo-digit-wrap';
var inner = document.createElement('div');
inner.className = 'odo-digit-inner';
for (var d = 0; d <= 9; d++) {
var span = document.createElement('div');
span.className = 'odo-digit';
span.textContent = d;
inner.appendChild(span);
}
var ft = document.createElement('div'); ft.className = 'odo-fade-top';
var fb = document.createElement('div'); fb.className = 'odo-fade-bot';
dw.appendChild(inner); dw.appendChild(ft); dw.appendChild(fb);
wrap.appendChild(dw);
setDigitTo(dw, 0, false);
}
}
function setDigitTo(dw, value, animated) {
var inner = dw.querySelector('.odo-digit-inner');
inner.style.transition = animated ? 'transform 0.12s cubic-bezier(0.4,0,0.2,1)' : 'none';
inner.style.transform = 'translateY(' + (-value * 74) + 'px)';
}
function setOdometerToFinal(wrap, digits) {
var dws = wrap.querySelectorAll('.odo-digit-wrap');
digits.forEach(function(d, i) { setDigitTo(dws[i], d, false); });
}
function runOdometerAnimation(wrap, finalDigits, finalValue, isFalse, onComplete, onSkip) {
if (isFalse || finalValue === 0) { setTimeout(onComplete, 600); return; }
var DURATION = 2400;
var start = performance.now();
var dws = Array.from(wrap.querySelectorAll('.odo-digit-wrap'));
var cancelled = false;
var skipBtn = document.getElementById('reveal-skip-btn');
if (skipBtn) skipBtn.onclick = function() { cancelled = true; onSkip(); };
function ease(t) { return t < 0.5 ? 4*t*t*t : 1 - Math.pow(-2*t+2,3)/2; }
function renderValue(val) {
var str = Math.round(val).toString().padStart(finalDigits.length, '0');
str.split('').forEach(function(ch, i) { if (i < dws.length) setDigitTo(dws[i], Number(ch), true); });
}
function tick(now) {
if (cancelled) return;
var t = Math.min((now - start) / DURATION, 1);
renderValue(ease(t) * finalValue);
if (t < 1) requestAnimationFrame(tick);
else { renderValue(finalValue); onComplete(); }
}
requestAnimationFrame(tick);
}
// ─── FEEDBACK ─────────────────────────────────────────────────────────────────
function clearFeedback() {
var el = document.getElementById('feedback');
el.textContent = ''; el.className = 'feedback';
}

615
js/hints.js Normal file
View file

@ -0,0 +1,615 @@
// ─── TOOLTIP ──────────────────────────────────────────────────────────────────
var tooltipTimeout = null;
function showTooltip(catId, targetEl) {
var cat = ALL_CATEGORIES.find(function(c) { return c.id === catId; });
if (!cat) return;
document.getElementById('tt-title').textContent = cat.icon + ' ' + catName(cat);
document.getElementById('tt-body').textContent = catDesc(cat);
var tip = document.getElementById('cat-tooltip');
var tipWidth = 280;
var rect = targetEl.getBoundingClientRect();
var left = Math.max(8, Math.min(rect.left + rect.width/2 - tipWidth/2, window.innerWidth - tipWidth - 8));
tip.style.width = tipWidth + 'px';
tip.style.left = left + 'px';
tip.style.visibility = 'hidden';
tip.classList.add('visible');
var tipH = tip.offsetHeight;
tip.classList.remove('visible');
tip.style.visibility = '';
tip.style.top = (rect.top - 8 - tipH < 8) ? (rect.bottom + 8) + 'px' : (rect.top - 8 - tipH) + 'px';
clearTimeout(tooltipTimeout);
tip.classList.add('visible');
}
function hideTooltip() {
clearTimeout(tooltipTimeout);
tooltipTimeout = setTimeout(function() {
document.getElementById('cat-tooltip').classList.remove('visible');
}, 120);
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.cat-info-btn') && !e.target.closest('#cat-tooltip')) {
document.getElementById('cat-tooltip').classList.remove('visible');
}
});
// ─── COUNTRY DESCRIPTIONS ─────────────────────────────────────────────────────
// Keyed by ISO2 country_code ; fallback matching by country_FR name
var COUNTRY_DESCRIPTIONS = {
AF:{fr:"État d'Asie centrale enclavé, entouré par l'Iran, le Pakistan et les anciennes républiques soviétiques.",en:"Landlocked state in Central Asia, bordered by Iran, Pakistan and former Soviet republics.",ua:"Держава в Центральній Азії, оточена Іраном, Пакистаном та колишніми радянськими республіками.",de:'Binnenstaat in Zentralasien, umgeben von Iran, Pakistan und ehemaligen Sowjetrepubliken.'},
AL:{fr:"Petit pays des Balkans sur la côte adriatique, entre le Monténégro, le Kosovo, la Macédoine et la Grèce.",en:"Small Balkan country on the Adriatic coast, between Montenegro, Kosovo, North Macedonia and Greece.",ua:"Невелика балканська країна на Адріатичному узбережжі.",de:'Kleines Balkanland an der Adriakueste, zwischen Montenegro, Kosovo, Nordmazedonien und Griechenland.'},
DZ:{fr:"Plus grand pays d'Afrique par la superficie, situé au nord du continent sur la côte méditerranéenne.",en:"Africa's largest country by area, located in the north of the continent on the Mediterranean coast.",ua:"Найбільша за площею країна Африки, на північ від континенту на Середземноморському узбережжі.",de:'Flaechenmaessig groesstes Land Afrikas, im Norden des Kontinents an der Mittelmeerkueste.'},
AD:{fr:"Minuscule principauté nichée dans les Pyrénées, entre la France et l'Espagne.",en:"Tiny principality nestled in the Pyrenees, between France and Spain.",ua:"Крихітне князівство в Піренеях між Францією та Іспанією.",de:'Winziges Fuerstentum in den Pyrenaeen, zwischen Frankreich und Spanien.'},
AO:{fr:"Grand pays d'Afrique subsaharienne occidentale, bordé par la Namibie, la Zambie et le Congo.",en:"Large country in western sub-Saharan Africa, bordered by Namibia, Zambia and the Congo.",ua:"Велика країна Західної Африки на південь від Сахари.",de:'Grosses Land im westlichen Subsahara-Afrika, angrenzend an Namibia, Sambia und den Kongo.'},
AG:{fr:"Petit État insulaire des Caraïbes, composé de deux îles principales dans la mer des Antilles.",en:"Small island state in the Caribbean, consisting of two main islands in the Antilles.",ua:"Невеликий острівний острів у Карибському морі.",de:'Kleiner Inselstaat in der Karibik, bestehend aus zwei Hauptinseln der Antillen.'},
AR:{fr:"Vaste pays du cône Sud de l'Amérique latine, bordé par le Chili, la Bolivie, le Paraguay, le Brésil et l'Uruguay.",en:"Vast country in southern South America, bordered by Chile, Bolivia, Paraguay, Brazil and Uruguay.",ua:"Велика країна на півдні Південної Америки, межує з Чилі, Болівією, Парагваєм, Бразилією та Уругваєм.",de:'Riesiges Land im suedlichen Suedamerika, angrenzend an Chile, Bolivien, Paraguay, Brasilien und Uruguay.'},
AM:{fr:"Petit pays du Caucase du Sud, enclavé entre la Turquie, la Géorgie, l'Azerbaïdjan et l'Iran.",en:"Small country in the South Caucasus, landlocked between Turkey, Georgia, Azerbaijan and Iran.",ua:"Невелика держава Південного Кавказу між Туреччиною, Грузією, Азербайджаном та Іраном.",de:'Kleines Land im Suedkaukasus, Binnenstaat zwischen Tuerkei, Georgien, Aserbaidschan und Iran.'},
AU:{fr:"Continent-pays de l'hémisphère sud, entouré par l'océan Indien et le Pacifique.",en:"Continent-country in the southern hemisphere, surrounded by the Indian and Pacific Oceans.",ua:"Країна-континент у Південній півкулі, оточена Індійським та Тихим океанами.",de:'Kontinent-Land auf der Suedhalbkugel, umgeben vom Indischen und Pazifischen Ozean.'},
AT:{fr:"Pays alpin d'Europe centrale, sans accès à la mer, entouré par l'Allemagne, la Suisse, l'Italie et plusieurs autres pays.",en:"Alpine country in central Europe, landlocked, surrounded by Germany, Switzerland, Italy and others.",ua:"Альпійська держава Центральної Європи, оточена Німеччиною, Швейцарією, Італією та іншими.",de:'Alpenland in Mitteleuropa, Binnenstaat, umgeben von Deutschland, der Schweiz, Italien und weiteren Laendern.'},
AZ:{fr:"Pays du Caucase du Sud bordant la mer Caspienne, entre la Russie, la Géorgie, l'Arménie et l'Iran.",en:"South Caucasus country bordering the Caspian Sea, between Russia, Georgia, Armenia and Iran.",ua:"Країна Південного Кавказу на березі Каспійського моря.",de:'Suedkaukasisches Land am Kaspischen Meer, zwischen Russland, Georgien, Armenien und Iran.'},
BS:{fr:"Archipel de près de 700 îles dans les Caraïbes, au nord des Grandes Antilles.",en:"Archipelago of nearly 700 islands in the Caribbean, north of the Greater Antilles.",ua:"Архіпелаг із ~700 островів у Карибському морі.",de:'Archipel aus fast 700 Inseln in der Karibik, noerdlich der Grossen Antillen.'},
BH:{fr:"Petit archipel du Golfe persique, relié à l'Arabie saoudite par un pont.",en:"Small archipelago in the Persian Gulf, connected to Saudi Arabia by a causeway.",ua:"Невеликий архіпелаг у Перській затоці.",de:'Kleiner Archipel im Persischen Golf, durch einen Damm mit Saudi-Arabien verbunden.'},
BD:{fr:"Pays d'Asie du Sud formant une enclave presque complète dans l'Inde, avec un accès au golfe du Bengale.",en:"South Asian country almost entirely enclosed by India, with access to the Bay of Bengal.",ua:"Країна Південної Азії, майже повністю оточена Індією, з виходом до Бенгальської затоки.",de:'Suedasiatisches Land, fast vollstaendig von Indien umschlossen, mit Zugang zum Golf von Bengalen.'},
BB:{fr:"Petite île des Caraïbes orientales, à l'est de l'arc des Antilles.",en:"Small island in the eastern Caribbean, east of the Antilles arc.",ua:"Невеликий острів у Карибському морі.",de:'Kleine Insel in der oestlichen Karibik, oestlich des Antillenbogens.'},
BY:{fr:"Pays d'Europe de l'Est enclavé, entre la Pologne, la Lituanie, la Lettonie, la Russie et l'Ukraine.",en:"Landlocked country in Eastern Europe, between Poland, Lithuania, Latvia, Russia and Ukraine.",ua:"Держава Східної Європи без виходу до моря, між Польщею та Росією.",de:'Binnenstaat in Osteuropa, zwischen Polen, Litauen, Lettland, Russland und der Ukraine.'},
BE:{fr:"Petit pays d'Europe occidentale situé entre la France, l'Allemagne, les Pays-Bas et le Luxembourg.",en:"Small country in Western Europe between France, Germany, the Netherlands and Luxembourg.",ua:"Невелика держава Західної Європи між Францією, Німеччиною та Нідерландами.",de:'Kleines Land in Westeuropa zwischen Frankreich, Deutschland, den Niederlanden und Luxemburg.'},
BZ:{fr:"Petit pays d'Amérique centrale bordant la mer des Caraïbes, entre le Mexique et le Guatemala.",en:"Small Central American country on the Caribbean coast, between Mexico and Guatemala.",ua:"Невелика центральноамериканська країна на Карибському узбережжі.",de:'Kleines zentralamerikanisches Land an der Karibikkueste, zwischen Mexiko und Guatemala.'},
BJ:{fr:"Pays d'Afrique de l'Ouest, entre le Togo, le Nigéria, le Burkina Faso et le Niger, avec un accès au golfe de Guinée.",en:"West African country between Togo, Nigeria, Burkina Faso and Niger, with access to the Gulf of Guinea.",ua:"Держава Західної Африки між Того, Нігерією та Гвінейською затокою.",de:'Westafrikanisches Land zwischen Togo, Nigeria, Burkina Faso und Niger, mit Zugang zum Golf von Guinea.'},
BT:{fr:"Petit royaume bouddhiste enclavé dans l'Himalaya, entre l'Inde et la Chine.",en:"Small Buddhist kingdom landlocked in the Himalayas, between India and China.",ua:"Невеле буддистське королівство в Гімалаях між Індією та Китаєм.",de:'Kleines buddhistisches Koenigreich im Himalaya, Binnenstaat zwischen Indien und China.'},
BO:{fr:"Pays enclavé d'Amérique du Sud, situé dans les Andes, entre le Pérou, le Brésil, le Chili, l'Argentine et le Paraguay.",en:"Landlocked country in South America, in the Andes, between Peru, Brazil, Chile, Argentina and Paraguay.",ua:"Країна без виходу до моря в Андах Південної Америки.",de:'Binnenstaat in Suedamerika, in den Anden, zwischen Peru, Brasilien, Chile, Argentinien und Paraguay.'},
BA:{fr:"Pays des Balkans occidentaux, entre la Croatie, la Serbie et le Monténégro.",en:"Country in the western Balkans, between Croatia, Serbia and Montenegro.",ua:"Держава Балканського півострова між Хорватією, Сербією та Чорногорією.",de:'Land auf dem westlichen Balkan, zwischen Kroatien, Serbien und Montenegro.'},
BW:{fr:"Pays enclavé d'Afrique australe, bordé par l'Afrique du Sud, la Namibie, le Zimbabwe et la Zambie.",en:"Landlocked country in southern Africa, bordered by South Africa, Namibia, Zimbabwe and Zambia.",ua:"Держава на півдні Африки без виходу до моря.",de:'Binnenstaat im suedlichen Afrika, angrenzend an Suedafrika, Namibia, Simbabwe und Sambia.'},
BR:{fr:"Immense pays d'Amérique du Sud, le plus grand du continent, bordant l'Atlantique et la quasi-totalité de ses voisins.",en:"Vast country in South America, the largest on the continent, bordering the Atlantic and nearly all its neighbors.",ua:"Величезна держава Південної Америки, найбільша на континенті.",de:'Riesiges Land in Suedamerika, das groesste des Kontinents, an den Atlantik und fast alle Nachbarlaender grenzend.'},
BN:{fr:"Petit sultanat d'Asie du Sud-Est sur l'île de Bornéo, enclavé dans la Malaisie.",en:"Small sultanate in Southeast Asia on the island of Borneo, surrounded by Malaysia.",ua:"Невеликий султанат у Південно-Східній Азії на острові Борнео.",de:'Kleines Sultanat in Suedostasien auf der Insel Borneo, umgeben von Malaysia.'},
BG:{fr:"Pays des Balkans sur la mer Noire, entre la Roumanie, la Serbie, la Macédoine, la Grèce et la Turquie.",en:"Balkan country on the Black Sea, between Romania, Serbia, North Macedonia, Greece and Turkey.",ua:"Балканська держава на Чорному морі.",de:'Balkanland am Schwarzen Meer, zwischen Rumaenien, Serbien, Nordmazedonien, Griechenland und der Tuerkei.'},
BF:{fr:"Pays enclavé d'Afrique de l'Ouest, entouré par le Mali, le Niger, le Bénin, le Togo, le Ghana et la Côte d'Ivoire.",en:"Landlocked country in West Africa, surrounded by Mali, Niger, Benin, Togo, Ghana and Ivory Coast.",ua:"Країна без виходу до моря у Західній Африці.",de:'Binnenstaat in Westafrika, umgeben von Mali, Niger, Benin, Togo, Ghana und der Elfenbeinkueste.'},
BI:{fr:"Petit pays d'Afrique centrale enclavé, au bord du lac Tanganyika, entouré par la RDC, le Rwanda et la Tanzanie.",en:"Small landlocked country in Central Africa, on Lake Tanganyika, surrounded by DR Congo, Rwanda and Tanzania.",ua:"Невелика держава Центральної Африки біля озера Танганьїка.",de:'Kleiner Binnenstaat in Zentralafrika, am Tanganjikasee, umgeben von DR Kongo, Ruanda und Tansania.'},
CV:{fr:"Archipel de l'Atlantique, à environ 500 km des côtes de l'Afrique de l'Ouest.",en:"Atlantic archipelago, about 500 km off the coast of West Africa.",ua:"Архіпелаг в Атлантичному океані, за ~500 км від узбережжя Західної Африки.",de:'Atlantischer Archipel, etwa 500 km vor der Kueste Westafrikas.'},
KH:{fr:"Pays d'Asie du Sud-Est bordé par la Thaïlande, le Laos et le Vietnam, avec un accès au golfe de Thaïlande.",en:"Southeast Asian country bordered by Thailand, Laos and Vietnam, with access to the Gulf of Thailand.",ua:"Держава Південно-Східної Азії між Таїландом, Лаосом та В'єтнамом.",de:'Suedostasiatisches Land, angrenzend an Thailand, Laos und Vietnam, mit Zugang zum Golf von Thailand.'},
CM:{fr:"Pays d'Afrique centrale avec un accès à l'Atlantique, souvent surnommé «l'Afrique en miniature».",en:"Central African country with Atlantic access, often nicknamed 'Africa in miniature'.",ua:"Держава Центральної Африки з виходом до Атлантичного океану.",de:'Zentralafrikanisches Land mit Atlantikzugang, oft als \u00abAfrika im Kleinen\u00bb bezeichnet.'},
CA:{fr:"Deuxième plus grand pays du monde par la superficie, occupant la majeure partie du nord de l'Amérique du Nord.",en:"The world's second-largest country by area, occupying most of northern North America.",ua:"Друга за площею держава світу, займає більшу частину Північної Америки.",de:'Zweitgroesstes Land der Welt nach Flaeche, nimmt den groessten Teil Nordamerikas ein.'},
CF:{fr:"Pays enclavé d'Afrique centrale, entouré par le Cameroun, le Tchad, le Soudan, la RDC et la République du Congo.",en:"Landlocked country in Central Africa, surrounded by Cameroon, Chad, Sudan, DR Congo and Republic of Congo.",ua:"Держава без виходу до моря в Центральній Африці.",de:'Binnenstaat in Zentralafrika, umgeben von Kamerun, Tschad, Sudan, DR Kongo und der Republik Kongo.'},
TD:{fr:"Grand pays enclavé d'Afrique centrale, s'étendant du désert du Sahara au sud semi-aride.",en:"Large landlocked country in Central Africa, stretching from the Sahara desert to a semi-arid south.",ua:"Велика держава без виходу до моря в Центральній Африці.",de:'Grosser Binnenstaat in Zentralafrika, von der Sahara bis zum semiariden Sueden reichend.'},
CL:{fr:"Pays en forme de lanière le long de la côte occidentale de l'Amérique du Sud, entre les Andes et le Pacifique.",en:"Strip-shaped country along the western coast of South America, between the Andes and the Pacific.",ua:"Вузька держава вздовж західного узбережжя Південної Америки між Андами та Тихим океаном.",de:'Streifenfoermiges Land entlang der Westkueste Suedamerikas, zwischen den Anden und dem Pazifik.'},
CN:{fr:"Plus grand pays d'Asie et troisième du monde par la superficie, bordant 14 pays voisins.",en:"The largest country in Asia and third in the world by area, bordering 14 neighboring countries.",ua:"Найбільша держава Азії та третя у світі за площею, межує з 14 країнами.",de:'Groesstes Land Asiens und drittgroesstes der Welt, angrenzend an 14 Nachbarlaender.'},
CO:{fr:"Pays d'Amérique du Sud au carrefour de l'Amazonie, des Andes et des Caraïbes.",en:"South American country at the crossroads of the Amazon, the Andes and the Caribbean.",ua:"Держава Південної Америки на перетині Амазонії, Анд та Карибського моря.",de:'Suedamerikanisches Land am Schnittpunkt von Amazonas, Anden und Karibik.'},
KM:{fr:"Archipel de l'océan Indien, entre le Mozambique et Madagascar.",en:"Archipelago in the Indian Ocean, between Mozambique and Madagascar.",ua:"Архіпелаг в Індійському океані між Мозамбіком та Мадагаскаром.",de:'Archipel im Indischen Ozean, zwischen Mosambik und Madagaskar.'},
CG:{fr:"Pays d'Afrique centrale avec un accès à l'Atlantique, bordé par le Cameroun, la RCA, la RDC, le Gabon et l'Angola.",en:"Central African country with Atlantic access, bordered by Cameroon, CAR, DR Congo, Gabon and Angola.",ua:"Держава Центральної Африки з виходом до Атлантики.",de:'Zentralafrikanisches Land mit Atlantikzugang, angrenzend an Kamerun, ZAR, DR Kongo, Gabun und Angola.'},
CD:{fr:"Immense pays d'Afrique centrale, le deuxième plus grand du continent, au cœur du bassin du fleuve Congo.",en:"Vast country in Central Africa, second largest on the continent, at the heart of the Congo River basin.",ua:"Величезна держава Центральної Африки, друга за площею на континенті.",de:'Riesiges Land in Zentralafrika, zweitgroesstes des Kontinents, im Herzen des Kongobeckens.'},
CR:{fr:"Pays d'Amérique centrale entre le Nicaragua et le Panama, avec des côtes sur le Pacifique et les Caraïbes.",en:"Central American country between Nicaragua and Panama, with coasts on both the Pacific and Caribbean.",ua:"Центральноамериканська держава між Нікарагуа та Панамою.",de:'Zentralamerikanisches Land zwischen Nicaragua und Panama, mit Kuesten am Pazifik und der Karibik.'},
HR:{fr:"Pays des Balkans avec un long littoral sur la mer Adriatique, bordé par la Slovénie, la Hongrie, la Serbie, la BiH et le Monténégro.",en:"Balkan country with a long Adriatic coastline, bordered by Slovenia, Hungary, Serbia, BiH and Montenegro.",ua:"Балканська держава з довгим Адріатичним узбережжям.",de:'Balkanland mit langer Adriakueste, angrenzend an Slowenien, Ungarn, Serbien, BiH und Montenegro.'},
CU:{fr:"Grande île des Caraïbes, la plus grande des Antilles, entre le golfe du Mexique et la mer des Caraïbes.",en:"Large island in the Caribbean, the largest in the Antilles, between the Gulf of Mexico and the Caribbean Sea.",ua:"Великий острів у Карибському морі, найбільший в Антильських островах.",de:'Grosse Insel in der Karibik, die groesste der Antillen, zwischen dem Golf von Mexiko und dem Karibischen Meer.'},
CY:{fr:"Île de la Méditerranée orientale, au sud de la Turquie et à l'ouest du Liban.",en:"Island in the eastern Mediterranean, south of Turkey and west of Lebanon.",ua:"Острів у Східному Середземномор'ї на південь від Туреччини.",de:'Insel im oestlichen Mittelmeer, suedlich der Tuerkei und westlich des Libanon.'},
CZ:{fr:"Pays enclavé d'Europe centrale, anciennement Tchécoslovaquie, bordé par l'Allemagne, la Pologne, la Slovaquie et l'Autriche.",en:"Landlocked country in Central Europe, formerly Czechoslovakia, bordered by Germany, Poland, Slovakia and Austria.",ua:"Держава Центральної Європи без виходу до моря між Німеччиною та Польщею.",de:'Binnenstaat in Mitteleuropa, ehemals Tschechoslowakei, angrenzend an Deutschland, Polen, die Slowakei und Oesterreich.'},
DK:{fr:"Pays nordique d'Europe du Nord, comprenant la péninsule du Jutland et de nombreuses îles en mer du Nord et Baltique.",en:"Nordic country in Northern Europe, comprising the Jutland Peninsula and many islands in the North and Baltic Seas.",ua:"Скандинавська країна Північної Європи, включає півострів Ютландія та численні острови.",de:'Nordisches Land in Nordeuropa, bestehend aus der Halbinsel Juetland und vielen Inseln in Nord- und Ostsee.'},
DJ:{fr:"Petit pays de la Corne de l'Afrique, sur le golfe d'Aden, entre l'Éthiopie, l'Érythrée et la Somalie.",en:"Small country in the Horn of Africa, on the Gulf of Aden, between Ethiopia, Eritrea and Somalia.",ua:"Невелика держава Африканського Рогу на березі Аденської затоки.",de:'Kleines Land am Horn von Afrika, am Golf von Aden, zwischen Aethiopien, Eritrea und Somalia.'},
DM:{fr:"Petite île volcanique des Petites Antilles dans la mer des Caraïbes.",en:"Small volcanic island in the Lesser Antilles in the Caribbean Sea.",ua:"Невеликий вулканічний острів у Карибському морі.",de:'Kleine vulkanische Insel der Kleinen Antillen im Karibischen Meer.'},
DO:{fr:"Pays des Caraïbes occupant les deux tiers orientaux de l'île d'Hispaniola, partagée avec Haïti.",en:"Caribbean country occupying the eastern two-thirds of Hispaniola island, shared with Haiti.",ua:"Держава на сході острова Гіспаньйола в Карибському морі.",de:'Karibikstaat, der die oestlichen zwei Drittel der Insel Hispaniola einnimmt, geteilt mit Haiti.'},
EC:{fr:"Pays andin d'Amérique du Sud sur le Pacifique, entre la Colombie et le Pérou, incluant les Galápagos.",en:"Andean country in South America on the Pacific coast, between Colombia and Peru, including the Galápagos.",ua:"Андська держава на узбережжі Тихого океану між Колумбією та Перу.",de:'Andenland in Suedamerika an der Pazifikkueste, zwischen Kolumbien und Peru, einschliesslich der Galapagos-Inseln.'},
EG:{fr:"Pays d'Afrique du Nord-Est à cheval entre l'Afrique et l'Asie, arrosé par le Nil.",en:"Country in northeastern Africa straddling Africa and Asia, watered by the Nile.",ua:"Країна на північному сході Африки на перетині Африки та Азії, омивається Нілом.",de:'Land im Nordosten Afrikas an der Schnittstelle von Afrika und Asien, vom Nil durchflossen.'},
SV:{fr:"Petit pays d'Amérique centrale sur le Pacifique, le plus petit et le plus dense d'Amérique continentale.",en:"Small Central American country on the Pacific, the smallest and most densely populated in mainland America.",ua:"Невелика центральноамериканська держава на Тихоокеанському узбережжі.",de:'Kleines zentralamerikanisches Land am Pazifik, das kleinste und am dichtesten besiedelte auf dem amerikanischen Festland.'},
GQ:{fr:"Petit pays d'Afrique centrale constitué d'une partie continentale et d'îles dans le golfe de Guinée.",en:"Small Central African country with a mainland part and islands in the Gulf of Guinea.",ua:"Невелика держава Центральної Африки з материковою частиною та островами.",de:'Kleines zentralafrikanisches Land mit Festlandteil und Inseln im Golf von Guinea.'},
ER:{fr:"Pays de la Corne de l'Afrique sur la mer Rouge, entre le Soudan, l'Éthiopie et Djibouti.",en:"Country in the Horn of Africa on the Red Sea, between Sudan, Ethiopia and Djibouti.",ua:"Держава Африканського Рогу на Червоному морі між Суданом та Ефіопією.",de:'Land am Horn von Afrika am Roten Meer, zwischen Sudan, Aethiopien und Dschibuti.'},
EE:{fr:"Petit pays balte d'Europe du Nord, au bord de la mer Baltique, entre la Lettonie et la Russie.",en:"Small Baltic country in Northern Europe, on the Baltic Sea, between Latvia and Russia.",ua:"Невелика балтійська держава Північної Європи між Латвією та Росією.",de:'Kleines baltisches Land in Nordeuropa, an der Ostsee, zwischen Lettland und Russland.'},
ET:{fr:"Grand pays enclavé de la Corne de l'Afrique, le pays le plus peuplé d'Afrique subsaharienne.",en:"Large landlocked country in the Horn of Africa, the most populous in sub-Saharan Africa.",ua:"Велика держава без виходу до моря на Африканському Розі.",de:'Grosser Binnenstaat am Horn von Afrika, das bevoelkerungsreichste Land Subsahara-Afrikas.'},
FJ:{fr:"Archipel d'environ 330 îles dans le Pacifique Sud, au nord-est de l'Australie.",en:"Archipelago of around 330 islands in the South Pacific, northeast of Australia.",ua:"Архіпелаг із ~330 островів у Південному Тихому океані.",de:'Archipel aus rund 330 Inseln im Suedpazifik, nordoestlich von Australien.'},
FI:{fr:"Pays nordique d'Europe du Nord, borné par la Suède, la Norvège et la Russie, avec un long littoral sur la mer Baltique.",en:"Nordic country in Northern Europe, bordered by Sweden, Norway and Russia, with a long Baltic Sea coastline.",ua:"Скандинавська держава Північної Європи між Швецією, Норвегією та Росією.",de:'Nordisches Land in Nordeuropa, angrenzend an Schweden, Norwegen und Russland, mit langer Ostseekueste.'},
FR:{fr:"Pays d'Europe occidentale avec des façades sur l'Atlantique et la Méditerranée, au cœur de l'Union européenne.",en:"Western European country with Atlantic and Mediterranean coastlines, at the heart of the European Union.",ua:"Держава Західної Європи з виходом до Атлантичного океану та Середземного моря.",de:'Westeuropaeisches Land mit Atlantik- und Mittelmeerkueste, im Herzen der Europaeischen Union.'},
GA:{fr:"Pays d'Afrique centrale sur l'Atlantique, recouvert à plus de 80 % de forêt équatoriale.",en:"Central African country on the Atlantic, more than 80% covered by equatorial forest.",ua:"Держава Центральної Африки на Атлантичному узбережжі, вкрита екваторіальним лісом.",de:'Zentralafrikanisches Land am Atlantik, zu mehr als 80 % von aequatorialem Regenwald bedeckt.'},
GM:{fr:"Petit pays d'Afrique de l'Ouest presque entièrement enclavé dans le Sénégal, avec un court accès à l'Atlantique.",en:"Small West African country almost entirely surrounded by Senegal, with a short Atlantic coast.",ua:"Найменша держава континентальної Африки, майже повністю оточена Сенегалом.",de:'Kleines westafrikanisches Land, fast vollstaendig von Senegal umgeben, mit kurzer Atlantikkueste.'},
GE:{fr:"Pays du Caucase du Sud sur la mer Noire, entre la Russie, l'Arménie, l'Azerbaïdjan et la Turquie.",en:"South Caucasus country on the Black Sea, between Russia, Armenia, Azerbaijan and Turkey.",ua:"Держава Південного Кавказу на Чорному морі між Росією та Туреччиною.",de:'Suedkaukasisches Land am Schwarzen Meer, zwischen Russland, Armenien, Aserbaidschan und der Tuerkei.'},
DE:{fr:"Pays d'Europe centrale au cœur de l'Union européenne, bordant 9 pays voisins.",en:"Central European country at the heart of the European Union, bordering 9 countries.",ua:"Держава Центральної Європи в серці Євросоюзу, межує з 9 країнами.",de:'Mitteleuropaeisches Land im Herzen der Europaeischen Union, angrenzend an 9 Nachbarlaender.'},
GH:{fr:"Pays d'Afrique de l'Ouest sur le golfe de Guinée, entre la Côte d'Ivoire, le Burkina Faso et le Togo.",en:"West African country on the Gulf of Guinea, between Ivory Coast, Burkina Faso and Togo.",ua:"Держава Західної Африки на Гвінейській затоці.",de:'Westafrikanisches Land am Golf von Guinea, zwischen der Elfenbeinkueste, Burkina Faso und Togo.'},
GR:{fr:"Pays du sud des Balkans avec un vaste archipel en Méditerranée, entre l'Adriatique et la mer Égée.",en:"Country in the southern Balkans with a vast Mediterranean archipelago, between the Adriatic and Aegean Seas.",ua:"Держава на півдні Балканського півострова з великим архіпелагом у Середземному морі.",de:'Land im suedlichen Balkan mit grossem Mittelmeer-Archipel, zwischen Adria und Aegaeis.'},
GD:{fr:"Petite île-État des Caraïbes orientales, dans les Petites Antilles.",en:"Small island state in the eastern Caribbean, in the Lesser Antilles.",ua:"Невелика острівна держава у Карибському морі.",de:'Kleiner Inselstaat in der oestlichen Karibik, in den Kleinen Antillen.'},
GT:{fr:"Pays d'Amérique centrale au cœur de l'Amérique centrale, bordant le Mexique, Belize, le Honduras et El Salvador.",en:"Country in the heart of Central America, bordering Mexico, Belize, Honduras and El Salvador.",ua:"Держава в центрі Центральної Америки.",de:'Land im Herzen Zentralamerikas, angrenzend an Mexiko, Belize, Honduras und El Salvador.'},
GN:{fr:"Pays d'Afrique de l'Ouest sur l'Atlantique, entre la Guinée-Bissau, le Sénégal, le Mali, la Côte d'Ivoire, le Liberia et la Sierra Leone.",en:"West African country on the Atlantic, between Guinea-Bissau, Senegal, Mali, Ivory Coast, Liberia and Sierra Leone.",ua:"Держава Західної Африки на Атлантичному узбережжі.",de:'Westafrikanisches Land am Atlantik, zwischen Guinea-Bissau, Senegal, Mali, der Elfenbeinkueste, Liberia und Sierra Leone.'},
GW:{fr:"Petit pays d'Afrique de l'Ouest avec des façades sur l'Atlantique, entre le Sénégal et la Guinée.",en:"Small West African country with an Atlantic coast, between Senegal and Guinea.",ua:"Невелика держава Західної Африки між Сенегалом та Гвінеєю.",de:'Kleines westafrikanisches Land mit Atlantikkueste, zwischen Senegal und Guinea.'},
GY:{fr:"Pays d'Amérique du Sud sur la côte atlantique, entre le Venezuela, le Brésil et le Suriname.",en:"South American country on the Atlantic coast, between Venezuela, Brazil and Suriname.",ua:"Держава на узбережжі Атлантики в Південній Америці.",de:'Suedamerikanisches Land an der Atlantikkueste, zwischen Venezuela, Brasilien und Suriname.'},
HT:{fr:"Pays des Caraïbes occupant le tiers occidental de l'île d'Hispaniola, partagée avec la République dominicaine.",en:"Caribbean country occupying the western third of Hispaniola island, shared with the Dominican Republic.",ua:"Держава на заході острова Гіспаньйола в Карибському морі.",de:'Karibikstaat im westlichen Drittel der Insel Hispaniola, geteilt mit der Dominikanischen Republik.'},
HN:{fr:"Pays d'Amérique centrale entre le Guatemala, El Salvador et le Nicaragua, avec des côtes sur le Pacifique et la mer des Caraïbes.",en:"Central American country between Guatemala, El Salvador and Nicaragua, with coasts on both the Pacific and Caribbean.",ua:"Центральноамериканська держава між Гватемалою та Нікарагуа.",de:'Zentralamerikanisches Land zwischen Guatemala, El Salvador und Nicaragua, mit Kuesten am Pazifik und der Karibik.'},
HU:{fr:"Pays enclavé d'Europe centrale, ancien cœur de l'empire austro-hongrois, entouré par l'Autriche, la Slovaquie, l'Ukraine, la Roumanie, la Serbie, la Croatie et la Slovénie.",en:"Landlocked Central European country, former heart of the Austro-Hungarian Empire, surrounded by Austria, Slovakia, Ukraine, Romania, Serbia, Croatia and Slovenia.",ua:"Держава без виходу до моря в Центральній Європі, оточена сімома країнами.",de:'Binnenstaat in Mitteleuropa, ehemaliges Herz der Oesterreichisch-Ungarischen Monarchie, umgeben von sieben Nachbarlaendern.'},
IS:{fr:"Grande île volcanique de l'Atlantique Nord, entre le Groenland et la Norvège, au bord du cercle polaire.",en:"Large volcanic island in the North Atlantic, between Greenland and Norway, near the Arctic Circle.",ua:"Великий вулканічний острів в Атлантиці між Гренландією та Норвегією.",de:'Grosse vulkanische Insel im Nordatlantik, zwischen Groenland und Norwegen, nahe dem Polarkreis.'},
IN:{fr:"Immense pays d'Asie du Sud en forme de péninsule, s'avançant dans l'océan Indien entre la mer d'Arabie et le golfe du Bengale.",en:"Vast South Asian country in the shape of a peninsula, jutting into the Indian Ocean between the Arabian Sea and Bay of Bengal.",ua:"Величезна держава Південної Азії у формі півострова між Аравійським морем та Бенгальською затокою.",de:'Riesiges suedasiatisches Land in Halbinselform, zwischen dem Arabischen Meer und dem Golf von Bengalen in den Indischen Ozean ragend.'},
ID:{fr:"Plus grand archipel du monde, s'étendant sur plus de 5000 km entre l'Asie du Sud-Est et l'Australie.",en:"The world's largest archipelago, stretching over 5,000 km between Southeast Asia and Australia.",ua:"Найбільший архіпелаг світу, розтягнувся на понад 5000 км між Південно-Східною Азією та Австралією.",de:'Groesster Archipel der Welt, ueber 5.000 km zwischen Suedostasien und Australien reichend.'},
IR:{fr:"Grand pays du Moyen-Orient et d'Asie centrale, ancien empire perse, entre la mer Caspienne et le golfe Persique.",en:"Large Middle Eastern and Central Asian country, ancient Persian Empire, between the Caspian Sea and the Persian Gulf.",ua:"Велика держава Близького Сходу, стародавня Перська імперія між Каспійським морем та Перською затокою.",de:'Grosses Land im Nahen Osten und Zentralasien, ehemaliges Persisches Reich, zwischen Kaspischem Meer und Persischem Golf.'},
IQ:{fr:"Pays du Moyen-Orient arrosé par le Tigre et l'Euphrate, berceau de la Mésopotamie antique.",en:"Middle Eastern country watered by the Tigris and Euphrates, cradle of ancient Mesopotamia.",ua:"Держава Близького Сходу, омивається Тигром та Євфратом — колиска Месопотамії.",de:'Land im Nahen Osten, durchflossen von Tigris und Euphrat, Wiege des antiken Mesopotamien.'},
IE:{fr:"Île d'Europe du Nord-Ouest dans l'Atlantique, à l'ouest de la Grande-Bretagne.",en:"Island in northwestern Europe in the Atlantic, west of Great Britain.",ua:"Острів на північному заході Європи в Атлантичному океані.",de:'Insel im Nordwesten Europas im Atlantik, westlich von Grossbritannien.'},
IL:{fr:"Pays du Proche-Orient sur la Méditerranée orientale, entre le Liban, la Syrie, la Jordanie et l'Égypte.",en:"Middle Eastern country on the eastern Mediterranean, between Lebanon, Syria, Jordan and Egypt.",ua:"Держава Близького Сходу на Середземноморському узбережжі.",de:'Land im Nahen Osten am oestlichen Mittelmeer, zwischen Libanon, Syrien, Jordanien und Aegypten.'},
IT:{fr:"Pays d'Europe du Sud en forme de botte avançant dans la Méditerranée, incluant la Sicile et la Sardaigne.",en:"Southern European country shaped like a boot jutting into the Mediterranean, including Sicily and Sardinia.",ua:"Держава Південної Європи у формі чобота в Середземному морі.",de:'Suedeuropaeisches Land in Stiefelform, ins Mittelmeer ragend, einschliesslich Sizilien und Sardinien.'},
JM:{fr:"Île des Grandes Antilles dans la mer des Caraïbes, au sud de Cuba.",en:"Island in the Greater Antilles in the Caribbean Sea, south of Cuba.",ua:"Острів у Великих Антильських островах у Карибському морі.",de:'Insel der Grossen Antillen im Karibischen Meer, suedlich von Kuba.'},
JP:{fr:"Archipel d'Asie de l'Est composé de quatre grandes îles et de milliers de petites, en bordure de l'océan Pacifique.",en:"East Asian archipelago composed of four main islands and thousands of smaller ones, on the Pacific Ocean.",ua:"Архіпелаг Східної Азії з чотирьох великих островів та тисяч менших.",de:'Ostasiatischer Archipel aus vier Hauptinseln und Tausenden kleinerer Inseln am Pazifischen Ozean.'},
JO:{fr:"Pays du Proche-Orient entre Israël, la Syrie, l'Irak et l'Arabie saoudite, sans accès à la mer sauf un court littoral sur la mer Rouge.",en:"Middle Eastern country between Israel, Syria, Iraq and Saudi Arabia, with just a short Red Sea coastline.",ua:"Держава Близького Сходу між Ізраїлем, Сирією, Іраком та Саудівською Аравією.",de:'Land im Nahen Osten zwischen Israel, Syrien, Irak und Saudi-Arabien, mit nur kurzem Zugang zum Roten Meer.'},
KZ:{fr:"Immense pays d'Asie centrale entre la mer Caspienne et la Russie, le 9e plus grand pays du monde.",en:"Vast country in Central Asia between the Caspian Sea and Russia, the 9th largest country in the world.",ua:"Величезна держава Центральної Азії між Каспійським морем та Росією.",de:'Riesiges Land in Zentralasien zwischen dem Kaspischen Meer und Russland, das 9. groesste Land der Welt.'},
KE:{fr:"Pays d'Afrique de l'Est sur l'océan Indien, traversé par l'équateur, entre l'Éthiopie, la Somalie, la Tanzanie et l'Ouganda.",en:"East African country on the Indian Ocean, crossed by the equator, between Ethiopia, Somalia, Tanzania and Uganda.",ua:"Держава Східної Африки на Індійському океані, перетинається екватором.",de:'Ostafrikanisches Land am Indischen Ozean, vom Aequator durchquert, zwischen Aethiopien, Somalia, Tansania und Uganda.'},
KI:{fr:"Archipel d'atolls coralliens dispersés dans le Pacifique central, à cheval sur l'équateur.",en:"Archipelago of coral atolls scattered across the central Pacific, straddling the equator.",ua:"Архіпелаг коралових атолів у центральній частині Тихого океану.",de:'Archipel aus Korallenatollen im zentralen Pazifik, beidseitig des Aequators.'},
KP:{fr:"Pays d'Asie de l'Est occupant la moitié nord de la péninsule coréenne, entre la Chine, la Russie et la Corée du Sud.",en:"East Asian country occupying the northern half of the Korean Peninsula, between China, Russia and South Korea.",ua:"Держава Східної Азії на північ Корейського півострова.",de:'Ostasiatisches Land auf der noerdlichen Haelfte der Koreanischen Halbinsel, zwischen China, Russland und Suedkorea.'},
KR:{fr:"Pays d'Asie de l'Est occupant la moitié sud de la péninsule coréenne, entre la mer du Japon et la mer Jaune.",en:"East Asian country occupying the southern half of the Korean Peninsula, between the Sea of Japan and the Yellow Sea.",ua:"Держава Східної Азії на півдні Корейського півострова.",de:'Ostasiatisches Land auf der suedlichen Haelfte der Koreanischen Halbinsel, zwischen Japanischem und Gelbem Meer.'},
KW:{fr:"Petit émirat du Golfe persique, entre l'Arabie saoudite et l'Irak.",en:"Small emirate on the Persian Gulf, between Saudi Arabia and Iraq.",ua:"Невеликий еміrat у Перській затоці між Саудівською Аравією та Іраком.",de:'Kleines Emirat am Persischen Golf, zwischen Saudi-Arabien und dem Irak.'},
KG:{fr:"Pays montagneux d'Asie centrale enclavé dans les monts Tian Shan, entre le Kazakhstan, la Chine, le Tadjikistan et l'Ouzbékistan.",en:"Mountainous landlocked country in Central Asia in the Tian Shan mountains, between Kazakhstan, China, Tajikistan and Uzbekistan.",ua:"Гірська держава Центральної Азії без виходу до моря в горах Тянь-Шань.",de:'Gebirgiger Binnenstaat in Zentralasien im Tian-Shan-Gebirge, zwischen Kasachstan, China, Tadschikistan und Usbekistan.'},
LA:{fr:"Pays enclavé d'Asie du Sud-Est dans la péninsule indochinoise, entre le Vietnam, la Chine, le Myanmar, la Thaïlande et le Cambodge.",en:"Landlocked country in Southeast Asia in the Indochinese peninsula, between Vietnam, China, Myanmar, Thailand and Cambodia.",ua:"Держава без виходу до моря в Індокитайському півострові.",de:'Binnenstaat in Suedostasien auf der Indochinesischen Halbinsel, zwischen Vietnam, China, Myanmar, Thailand und Kambodscha.'},
LV:{fr:"Pays balte d'Europe du Nord entre l'Estonie, la Russie, la Biélorussie et la Lituanie, avec un accès à la mer Baltique.",en:"Baltic country in Northern Europe between Estonia, Russia, Belarus and Lithuania, with Baltic Sea access.",ua:"Балтійська держава Північної Європи між Естонією та Литвою.",de:'Baltisches Land in Nordeuropa zwischen Estland, Russland, Belarus und Litauen, mit Ostseezugang.'},
LB:{fr:"Petit pays du Proche-Orient sur la Méditerranée orientale, entre la Syrie et Israël.",en:"Small Middle Eastern country on the eastern Mediterranean, between Syria and Israel.",ua:"Невелика держава Близького Сходу на Середземноморі між Сирією та Ізраїлем.",de:'Kleines Land im Nahen Osten am oestlichen Mittelmeer, zwischen Syrien und Israel.'},
LS:{fr:"Petit pays enclavé dans l'Afrique du Sud, entièrement entouré par son voisin.",en:"Small country entirely surrounded by and landlocked within South Africa.",ua:"Невелика держава, повністю оточена Південно-Африканською Республікою.",de:'Kleines Land, vollstaendig von Suedafrika umschlossen.'},
LR:{fr:"Pays d'Afrique de l'Ouest sur la côte atlantique, entre la Sierra Leone, la Guinée et la Côte d'Ivoire.",en:"West African country on the Atlantic coast, between Sierra Leone, Guinea and Ivory Coast.",ua:"Держава Західної Африки на Атлантичному узбережжі.",de:'Westafrikanisches Land an der Atlantikkueste, zwischen Sierra Leone, Guinea und der Elfenbeinkueste.'},
LY:{fr:"Grand pays d'Afrique du Nord sur la mer Méditerranée, entre la Tunisie, l'Algérie, le Niger, le Tchad, le Soudan et l'Égypte.",en:"Large North African country on the Mediterranean Sea, between Tunisia, Algeria, Niger, Chad, Sudan and Egypt.",ua:"Велика держава Північної Африки на Середземноморському узбережжі.",de:'Grosses nordafrikanisches Land am Mittelmeer, zwischen Tunesien, Algerien, Niger, Tschad, Sudan und Aegypten.'},
LI:{fr:"Minuscule principauté d'Europe centrale enclavée entre la Suisse et l'Autriche.",en:"Tiny principality in Central Europe, landlocked between Switzerland and Austria.",ua:"Крихітне князівство між Швейцарією та Австрією.",de:'Winziges Fuerstentum in Mitteleuropa, Binnenstaat zwischen der Schweiz und Oesterreich.'},
LT:{fr:"Pays balte d'Europe du Nord entre la Lettonie, la Biélorussie, la Pologne et l'enclave russe de Kaliningrad.",en:"Baltic country in Northern Europe between Latvia, Belarus, Poland and the Russian exclave of Kaliningrad.",ua:"Балтійська держава Північної Європи між Латвією, Польщею та Білоруссю.",de:'Baltisches Land in Nordeuropa zwischen Lettland, Belarus, Polen und der russischen Exklave Kaliningrad.'},
LU:{fr:"Petit grand-duché d'Europe occidentale enclavé entre la France, la Belgique et l'Allemagne.",en:"Small grand duchy in Western Europe, landlocked between France, Belgium and Germany.",ua:"Невеликий великий герцогство між Францією, Бельгією та Німеччиною.",de:'Kleines Grossherzogtum in Westeuropa, Binnenstaat zwischen Frankreich, Belgien und Deutschland.'},
MG:{fr:"Grande île de l'océan Indien au large de l'Afrique de l'Est, quatrième plus grande île du monde.",en:"Large island in the Indian Ocean off the coast of East Africa, the world's fourth-largest island.",ua:"Великий острів в Індійському океані біля узбережжя Східної Африки.",de:'Grosse Insel im Indischen Ozean vor der Kueste Ostafrikas, viertgroesste Insel der Welt.'},
MW:{fr:"Petit pays enclavé d'Afrique orientale le long du lac Malawi, entre la Tanzanie, la Zambie et le Mozambique.",en:"Small landlocked country in East Africa along Lake Malawi, between Tanzania, Zambia and Mozambique.",ua:"Невелика держава без виходу до моря в Східній Африці вздовж озера Малаві.",de:'Kleiner Binnenstaat in Ostafrika entlang des Malawisees, zwischen Tansania, Sambia und Mosambik.'},
MY:{fr:"Pays d'Asie du Sud-Est composé de deux parties : la péninsule malaise et le nord de Bornéo.",en:"Southeast Asian country composed of two parts: the Malay Peninsula and northern Borneo.",ua:"Держава Південно-Східної Азії, складається з Малайського півострова та частини Борнео.",de:'Suedostasiatisches Land bestehend aus zwei Teilen: der Malaiischen Halbinsel und Nord-Borneo.'},
MV:{fr:"Archipel de l'océan Indien au sud-ouest du Sri Lanka, composé d'environ 1200 récifs coralliens.",en:"Indian Ocean archipelago southwest of Sri Lanka, composed of around 1,200 coral reefs.",ua:"Архіпелаг в Індійському океані на південний захід від Шрі-Ланки.",de:'Archipel im Indischen Ozean suedwestlich von Sri Lanka, bestehend aus rund 1.200 Korallenriffen.'},
ML:{fr:"Grand pays enclavé d'Afrique de l'Ouest, dont le nord est en partie occupé par le Sahara.",en:"Large landlocked country in West Africa, whose north is partly covered by the Sahara.",ua:"Велика держава без виходу до моря у Західній Африці, північ займає Сахара.",de:'Grosser Binnenstaat in Westafrika, dessen Norden teilweise von der Sahara bedeckt ist.'},
MT:{fr:"Petit archipel de l'Europe du Sud au centre de la Méditerranée, au sud de la Sicile.",en:"Small Southern European archipelago in the center of the Mediterranean, south of Sicily.",ua:"Невеликий архіпелаг у центрі Середземного моря на південь від Сицилії.",de:'Kleiner suedeuropaeischer Archipel im Zentrum des Mittelmeers, suedlich von Sizilien.'},
MH:{fr:"Archipel de deux chaînes d'atolls dans le Pacifique Nord, entre Hawaï et les Philippines.",en:"Archipelago of two chains of atolls in the North Pacific, between Hawaii and the Philippines.",ua:"Архіпелаг двох ланцюгів атолів у Північній частині Тихого океану.",de:'Archipel aus zwei Atollketten im Nordpazifik, zwischen Hawaii und den Philippinen.'},
MR:{fr:"Grand pays du nord-ouest de l'Afrique entre le Sahara et le Sahel, entre le Maroc, l'Algérie, le Mali et le Sénégal.",en:"Large country in northwestern Africa between the Sahara and the Sahel, between Morocco, Algeria, Mali and Senegal.",ua:"Велика держава північно-заходу Африки між Сахарою та Сахелем.",de:'Grosses Land im Nordwesten Afrikas zwischen Sahara und Sahel, zwischen Marokko, Algerien, Mali und Senegal.'},
MU:{fr:"Île volcanique de l'océan Indien à l'est de Madagascar.",en:"Volcanic island in the Indian Ocean east of Madagascar.",ua:"Вулканічний острів в Індійському океані на схід від Мадагаскару.",de:'Vulkanische Insel im Indischen Ozean oestlich von Madagaskar.'},
MX:{fr:"Grand pays d'Amérique du Nord entre les États-Unis et l'Amérique centrale, avec des côtes sur le Pacifique et le golfe du Mexique.",en:"Large North American country between the United States and Central America, with coasts on both the Pacific and Gulf of Mexico.",ua:"Велика держава Північної Америки між США та Центральною Америкою.",de:'Grosses nordamerikanisches Land zwischen den USA und Zentralamerika, mit Kuesten am Pazifik und am Golf von Mexiko.'},
FM:{fr:"Archipel d'États fédérés du Pacifique occidental, au nord de la Nouvelle-Guinée.",en:"Archipelago of federated states in the western Pacific, north of New Guinea.",ua:"Архіпелаг федеративних держав у Тихому океані.",de:'Archipel foederierter Staaten im westlichen Pazifik, noerdlich von Neuguinea.'},
MD:{fr:"Petit pays enclavé d'Europe de l'Est entre la Roumanie et l'Ukraine.",en:"Small landlocked country in Eastern Europe between Romania and Ukraine.",ua:"Невелика держава без виходу до моря між Румунією та Україною.",de:'Kleiner Binnenstaat in Osteuropa zwischen Rumaenien und der Ukraine.'},
MC:{fr:"Minuscule principauté sur la Côte d'Azur, enclavée dans le département français des Alpes-Maritimes.",en:"Tiny principality on the French Riviera, enclosed within the French department of Alpes-Maritimes.",ua:"Крихітне князівство на Французькій Рив'єрі.",de:'Winziges Fuerstentum an der Cote d\u2019Azur, eingeschlossen im franzoesischen Departement Alpes-Maritimes.'},
MN:{fr:"Grand pays enclavé d'Asie de l'Est entre la Russie et la Chine, cœur historique de l'empire mongol.",en:"Large landlocked country in East Asia between Russia and China, historic heart of the Mongol Empire.",ua:"Велика держава без виходу до моря між Росією та Китаєм.",de:'Grosser Binnenstaat in Ostasien zwischen Russland und China, historisches Herz des Mongolischen Reichs.'},
ME:{fr:"Petit pays des Balkans sur la mer Adriatique, entre la Croatie, la BiH, la Serbie et l'Albanie.",en:"Small Balkan country on the Adriatic Sea, between Croatia, BiH, Serbia and Albania.",ua:"Невелика балканська держава на Адріатичному морі.",de:'Kleines Balkanland an der Adria, zwischen Kroatien, BiH, Serbien und Albanien.'},
MA:{fr:"Pays du nord-ouest de l'Afrique sur l'Atlantique et la Méditerranée, face à l'Espagne.",en:"Country in northwestern Africa on the Atlantic and Mediterranean, facing Spain.",ua:"Держава на північному заході Африки на Атлантиці та Середземноморі.",de:'Land im Nordwesten Afrikas an Atlantik und Mittelmeer, gegenueber von Spanien.'},
MZ:{fr:"Pays d'Afrique australe sur l'océan Indien, entre la Tanzanie, le Malawi, la Zambie, le Zimbabwe et l'Afrique du Sud.",en:"Southern African country on the Indian Ocean, between Tanzania, Malawi, Zambia, Zimbabwe and South Africa.",ua:"Держава Південної Африки на Індійському океані.",de:'Land im suedlichen Afrika am Indischen Ozean, zwischen Tansania, Malawi, Sambia, Simbabwe und Suedafrika.'},
MM:{fr:"Grand pays d'Asie du Sud-Est, le plus grand de la péninsule indochinoise, entre l'Inde, la Chine, la Thaïlande, le Laos et le Bangladesh.",en:"Large Southeast Asian country, the largest in the Indochinese peninsula, between India, China, Thailand, Laos and Bangladesh.",ua:"Велика держава Південно-Східної Азії, найбільша в Індокитаї.",de:'Grosses suedostasiatisches Land, das groesste auf der Indochinesischen Halbinsel, zwischen Indien, China, Thailand, Laos und Bangladesch.'},
NA:{fr:"Pays d'Afrique australe sur l'Atlantique, entre l'Angola, la Zambie, le Botswana et l'Afrique du Sud.",en:"Southern African country on the Atlantic, between Angola, Zambia, Botswana and South Africa.",ua:"Держава Південної Африки на Атлантичному узбережжі.",de:'Land im suedlichen Afrika am Atlantik, zwischen Angola, Sambia, Botswana und Suedafrika.'},
NR:{fr:"Minuscule île-État du Pacifique central, l'un des plus petits pays du monde.",en:"Tiny island state in the central Pacific, one of the smallest countries in the world.",ua:"Крихітна острівна держава в Центральному Тихому океані.",de:'Winziger Inselstaat im zentralen Pazifik, eines der kleinsten Laender der Welt.'},
NP:{fr:"Pays himalayen enclavé entre l'Inde et la Chine, abritant l'Everest et les plus hauts sommets du monde.",en:"Himalayan landlocked country between India and China, home to Everest and the world's highest peaks.",ua:"Гімалайська держава між Індією та Китаєм, де знаходиться Еверест.",de:'Himalaya-Binnenstaat zwischen Indien und China, Heimat des Mount Everest und der hoechsten Gipfel der Welt.'},
NL:{fr:"Pays d'Europe occidentale aux côtes sur la mer du Nord, entre la Belgique et l'Allemagne, connu pour ses terres conquises sur la mer.",en:"Western European country on the North Sea coast, between Belgium and Germany, known for its land reclaimed from the sea.",ua:"Держава Західної Європи на Північному морі між Бельгією та Німеччиною.",de:'Westeuropaeisches Land an der Nordseekueste, zwischen Belgien und Deutschland, bekannt fuer dem Meer abgerungenes Land.'},
NZ:{fr:"Archipel de l'Océanie dans le Pacifique Sud composé de deux grandes îles et de nombreuses îles plus petites.",en:"Oceanian archipelago in the South Pacific composed of two main islands and many smaller ones.",ua:"Архіпелаг Океанії у Південному Тихому океані, складається з двох великих островів.",de:'Ozeanischer Archipel im Suedpazifik, bestehend aus zwei Hauptinseln und vielen kleineren.'},
NI:{fr:"Pays d'Amérique centrale entre le Honduras et le Costa Rica, avec des côtes sur le Pacifique et la mer des Caraïbes.",en:"Central American country between Honduras and Costa Rica, with coasts on both the Pacific and Caribbean.",ua:"Центральноамериканська держава між Гондурасом та Коста-Рікою.",de:'Zentralamerikanisches Land zwischen Honduras und Costa Rica, mit Kuesten am Pazifik und der Karibik.'},
NE:{fr:"Grand pays enclavé d'Afrique de l'Ouest dont les deux tiers sont couverts par le désert du Sahara.",en:"Large landlocked country in West Africa, two-thirds of which is covered by the Sahara desert.",ua:"Велика держава без виходу до моря у Західній Африці, дві третини — Сахара.",de:'Grosser Binnenstaat in Westafrika, zwei Drittel sind von der Sahara bedeckt.'},
NG:{fr:"Pays le plus peuplé d'Afrique, sur le golfe de Guinée, entre le Bénin, le Niger, le Tchad et le Cameroun.",en:"Africa's most populous country, on the Gulf of Guinea, between Benin, Niger, Chad and Cameroon.",ua:"Найбільша за населенням країна Африки на Гвінейській затоці.",de:'Bevoelkerungsreichstes Land Afrikas, am Golf von Guinea, zwischen Benin, Niger, Tschad und Kamerun.'},
NO:{fr:"Pays nordique d'Europe du Nord avec un long littoral sur la mer du Nord et l'Atlantique, incluant le Svalbard.",en:"Nordic country in Northern Europe with a long coastline on the North Sea and Atlantic, including Svalbard.",ua:"Скандинавська держава Північної Європи з довгим узбережжям Атлантики.",de:'Nordisches Land in Nordeuropa mit langer Kueste an Nordsee und Atlantik, einschliesslich Spitzbergen.'},
OM:{fr:"Pays du Moyen-Orient au sud-est de la péninsule arabique sur le golfe d'Oman et la mer d'Arabie.",en:"Middle Eastern country in the southeastern Arabian Peninsula, on the Gulf of Oman and Arabian Sea.",ua:"Держава Близького Сходу на південному сході Аравійського півострова.",de:'Land im Nahen Osten im Suedosten der Arabischen Halbinsel, am Golf von Oman und Arabischen Meer.'},
PK:{fr:"Grand pays d'Asie du Sud entre l'Iran, l'Afghanistan, l'Inde et la Chine, avec un accès à la mer d'Arabie.",en:"Large South Asian country between Iran, Afghanistan, India and China, with access to the Arabian Sea.",ua:"Велика держава Південної Азії між Іраном, Афганістаном та Індією.",de:'Grosses suedasiatisches Land zwischen Iran, Afghanistan, Indien und China, mit Zugang zum Arabischen Meer.'},
PW:{fr:"Archipel de quelques 340 îles du Pacifique occidental, au nord-est des Philippines.",en:"Archipelago of about 340 islands in the western Pacific, northeast of the Philippines.",ua:"Архіпелаг із ~340 островів у Тихому океані.",de:'Archipel aus rund 340 Inseln im westlichen Pazifik, nordoestlich der Philippinen.'},
PA:{fr:"Pays d'Amérique centrale reliant le continent américain du Nord au Sud, avec le canal de Panama.",en:"Central American country linking North and South America, home to the Panama Canal.",ua:"Центральноамериканська держава, що з'єднує Північ і Південь Америки через Панамський канал.",de:'Zentralamerikanisches Land, das Nord- und Suedamerika verbindet, Heimat des Panamakanals.'},
PG:{fr:"Pays d'Océanie occupant la moitié orientale de la Nouvelle-Guinée et de nombreuses îles du Pacifique.",en:"Oceanian country occupying the eastern half of New Guinea and many Pacific islands.",ua:"Держава Океанії на сході острова Нова Гвінея та численних тихоокеанських островах.",de:'Ozeanisches Land auf der oestlichen Haelfte Neuguineas und vielen Pazifikinseln.'},
PY:{fr:"Pays enclavé d'Amérique du Sud entre l'Argentine, la Bolivie et le Brésil.",en:"Landlocked country in South America between Argentina, Bolivia and Brazil.",ua:"Держава без виходу до моря між Аргентиною, Болівією та Бразилією.",de:'Binnenstaat in Suedamerika zwischen Argentinien, Bolivien und Brasilien.'},
PE:{fr:"Pays andin d'Amérique du Sud sur le Pacifique, berceau de l'empire inca, entre l'Équateur, la Colombie, le Brésil, la Bolivie et le Chili.",en:"Andean South American country on the Pacific, cradle of the Inca Empire, between Ecuador, Colombia, Brazil, Bolivia and Chile.",ua:"Андська держава на узбережжі Тихого океану, колиска імперії Інків.",de:'Andenland in Suedamerika am Pazifik, Wiege des Inkareichs, zwischen Ecuador, Kolumbien, Brasilien, Bolivien und Chile.'},
PH:{fr:"Archipel d'Asie du Sud-Est de plus de 7600 îles dans la mer de Chine méridionale et le Pacifique.",en:"Southeast Asian archipelago of over 7,600 islands in the South China Sea and Pacific.",ua:"Архіпелаг Південно-Східної Азії з понад 7600 островів у Тихому океані.",de:'Suedostasiatischer Archipel aus ueber 7.600 Inseln im Suedchinesischen Meer und Pazifik.'},
PL:{fr:"Grand pays d'Europe centrale entre l'Allemagne, la République tchèque, la Slovaquie, l'Ukraine, la Biélorussie, la Lituanie et la Russie.",en:"Large Central European country between Germany, Czech Republic, Slovakia, Ukraine, Belarus, Lithuania and Russia.",ua:"Велика держава Центральної Європи між Німеччиною та Україною.",de:'Grosses mitteleuropaeisches Land zwischen Deutschland, Tschechien, der Slowakei, der Ukraine, Belarus, Litauen und Russland.'},
PT:{fr:"Pays d'Europe du Sud-Ouest à l'extrémité de la péninsule ibérique sur l'Atlantique, incluant les Açores et Madère.",en:"Country in southwestern Europe at the tip of the Iberian Peninsula on the Atlantic, including the Azores and Madeira.",ua:"Держава на крайньому заході Піренейського півострова на Атлантиці.",de:'Land im Suedwesten Europas am Ende der Iberischen Halbinsel am Atlantik, einschliesslich der Azoren und Madeiras.'},
QA:{fr:"Petite péninsule du Golfe persique, entre l'Arabie saoudite et les Émirats arabes unis.",en:"Small peninsula in the Persian Gulf, between Saudi Arabia and the United Arab Emirates.",ua:"Невеликий півострів у Перській затоці між Саудівською Аравією та ОАЕ.",de:'Kleine Halbinsel im Persischen Golf, zwischen Saudi-Arabien und den Vereinigten Arabischen Emiraten.'},
RO:{fr:"Pays des Balkans du Nord sur la mer Noire, entre la Bulgarie, la Serbie, la Hongrie, la Moldavie et l'Ukraine.",en:"Northern Balkan country on the Black Sea, between Bulgaria, Serbia, Hungary, Moldova and Ukraine.",ua:"Держава північних Балкан на Чорному морі між Болгарією та Угорщиною.",de:'Noerdliches Balkanland am Schwarzen Meer, zwischen Bulgarien, Serbien, Ungarn, Moldau und der Ukraine.'},
RU:{fr:"Plus grand pays du monde par la superficie, s'étendant de l'Europe de l'Est jusqu'au Pacifique à travers toute l'Asie du Nord.",en:"The world's largest country by area, stretching from Eastern Europe to the Pacific across all of northern Asia.",ua:"Найбільша держава у світі за площею, простягається від Східної Європи до Тихого океану.",de:'Flaechenmaessig groesstes Land der Welt, von Osteuropa bis zum Pazifik ueber ganz Nordasien reichend.'},
RW:{fr:"Petit pays enclavé d'Afrique centrale entre la RDC, l'Ouganda, la Tanzanie et le Burundi.",en:"Small landlocked country in Central Africa between DR Congo, Uganda, Tanzania and Burundi.",ua:"Невелика держава без виходу до моря в Центральній Африці.",de:'Kleiner Binnenstaat in Zentralafrika zwischen DR Kongo, Uganda, Tansania und Burundi.'},
KN:{fr:"Petit État insulaire des Caraïbes orientales composé de deux îles.",en:"Small island state in the eastern Caribbean composed of two islands.",ua:"Невелика острівна держава у Карибському морі.",de:'Kleiner Inselstaat in der oestlichen Karibik, bestehend aus zwei Inseln.'},
LC:{fr:"Île des Petites Antilles dans les Caraïbes orientales, entre Martinique et Saint-Vincent.",en:"Island in the Lesser Antilles in the eastern Caribbean, between Martinique and Saint Vincent.",ua:"Острів у Малих Антильських островах у Карибському морі.",de:'Insel der Kleinen Antillen in der oestlichen Karibik, zwischen Martinique und St. Vincent.'},
VC:{fr:"Île des Petites Antilles dans les Caraïbes orientales, au sud de Sainte-Lucie.",en:"Island in the Lesser Antilles in the eastern Caribbean, south of Saint Lucia.",ua:"Острів у Карибському морі на південь від Сент-Люсії.",de:'Insel der Kleinen Antillen in der oestlichen Karibik, suedlich von St. Lucia.'},
WS:{fr:"Archipel polynésien du Pacifique Sud composé de deux grandes îles et de plusieurs îles plus petites.",en:"Polynesian archipelago in the South Pacific composed of two main islands and several smaller ones.",ua:"Полінезійський архіпелаг у Південному Тихому океані.",de:'Polynesischer Archipel im Suedpazifik, bestehend aus zwei Hauptinseln und mehreren kleineren.'},
SM:{fr:"Minuscule État enclavé au cœur de l'Italie centrale, dans les Apennins.",en:"Tiny landlocked state in the heart of central Italy, in the Apennines.",ua:"Крихітна держава в центрі Італії в Апеннінах.",de:'Winziger Binnenstaat im Herzen Mittelitaliens, in den Apenninen.'},
ST:{fr:"Petit archipel du golfe de Guinée, à environ 250 km des côtes du Cameroun et du Gabon.",en:"Small archipelago in the Gulf of Guinea, about 250 km from the coasts of Cameroon and Gabon.",ua:"Невеликий архіпелаг у Гвінейській затоці.",de:'Kleiner Archipel im Golf von Guinea, etwa 250 km von den Kuesten Kameruns und Gabuns.'},
SA:{fr:"Vaste pays du Moyen-Orient occupant la majeure partie de la péninsule arabique.",en:"Vast Middle Eastern country occupying most of the Arabian Peninsula.",ua:"Велика держава Близького Сходу, займає більшу частину Аравійського півострова.",de:'Riesiges Land im Nahen Osten, das den groessten Teil der Arabischen Halbinsel einnimmt.'},
SN:{fr:"Pays d'Afrique de l'Ouest sur l'Atlantique, presque entourant la Gambie, entre la Mauritanie, le Mali, la Guinée et la Guinée-Bissau.",en:"West African country on the Atlantic, almost surrounding Gambia, between Mauritania, Mali, Guinea and Guinea-Bissau.",ua:"Держава Західної Африки на Атлантиці, майже оточує Гамбію.",de:'Westafrikanisches Land am Atlantik, Gambia fast vollstaendig umschliessend, zwischen Mauretanien, Mali, Guinea und Guinea-Bissau.'},
RS:{fr:"Pays des Balkans centraux enclavé entre la Croatie, la Bosnie, le Monténégro, la Bulgarie, la Macédoine et la Hongrie.",en:"Central Balkan country landlocked between Croatia, Bosnia, Montenegro, Bulgaria, North Macedonia and Hungary.",ua:"Держава центральних Балкан між Хорватією, Боснією та Угорщиною.",de:'Zentrales Balkanland, Binnenstaat zwischen Kroatien, Bosnien, Montenegro, Bulgarien, Nordmazedonien und Ungarn.'},
SC:{fr:"Archipel de l'océan Indien au nord-est de Madagascar, à environ 1500 km des côtes d'Afrique de l'Est.",en:"Indian Ocean archipelago northeast of Madagascar, about 1,500 km from the East African coast.",ua:"Архіпелаг в Індійському океані на північний схід від Мадагаскару.",de:'Archipel im Indischen Ozean nordoestlich von Madagaskar, etwa 1.500 km von der ostafrikanischen Kueste.'},
SL:{fr:"Pays d'Afrique de l'Ouest sur l'Atlantique, entre la Guinée et le Liberia.",en:"West African country on the Atlantic, between Guinea and Liberia.",ua:"Держава Західної Африки між Гвінеєю та Ліберією.",de:'Westafrikanisches Land am Atlantik, zwischen Guinea und Liberia.'},
SG:{fr:"Cité-État insulaire d'Asie du Sud-Est au sud de la Malaisie, à l'extrémité de la péninsule malaise.",en:"Island city-state in Southeast Asia at the southern tip of the Malay Peninsula.",ua:"Острівне місто-держава в Південно-Східній Азії на крайньому півдні Малайського півострова.",de:'Insel-Stadtstaat in Suedostasien an der Suedspitze der Malaiischen Halbinsel.'},
SK:{fr:"Pays enclavé d'Europe centrale entre la Pologne, l'Ukraine, la Hongrie, l'Autriche et la République tchèque.",en:"Landlocked Central European country between Poland, Ukraine, Hungary, Austria and Czech Republic.",ua:"Держава Центральної Європи без виходу до моря між Польщею та Угорщиною.",de:'Binnenstaat in Mitteleuropa zwischen Polen, der Ukraine, Ungarn, Oesterreich und Tschechien.'},
SI:{fr:"Petit pays d'Europe centrale avec un accès à la mer Adriatique, entre l'Italie, l'Autriche, la Hongrie et la Croatie.",en:"Small Central European country with Adriatic Sea access, between Italy, Austria, Hungary and Croatia.",ua:"Невелика держава Центральної Європи з виходом до Адріатичного моря.",de:'Kleines mitteleuropaeisches Land mit Adriazugang, zwischen Italien, Oesterreich, Ungarn und Kroatien.'},
SB:{fr:"Archipel du Pacifique Sud à l'est de la Nouvelle-Guinée et au nord de l'Australie.",en:"South Pacific archipelago east of New Guinea and north of Australia.",ua:"Архіпелаг Південного Тихого океану на схід від Нової Гвінеї.",de:'Suedpazifischer Archipel oestlich von Neuguinea und noerdlich von Australien.'},
SO:{fr:"Pays de la Corne de l'Afrique avec le plus long littoral d'Afrique continentale sur l'océan Indien.",en:"Country in the Horn of Africa with the longest coastline on mainland Africa, on the Indian Ocean.",ua:"Держава Африканського Рогу з найдовшим узбережжям континентальної Африки.",de:'Land am Horn von Afrika mit der laengsten Kueste des afrikanischen Festlands am Indischen Ozean.'},
ZA:{fr:"Pays d'Afrique australe sur l'Atlantique et l'océan Indien, entourant le Lesotho et bordant le Swaziland, le Mozambique, le Zimbabwe et d'autres.",en:"Southern African country on the Atlantic and Indian Oceans, surrounding Lesotho and bordering Eswatini, Mozambique, Zimbabwe and others.",ua:"Держава на півдні Африки між Атлантичним та Індійським океанами.",de:'Land im suedlichen Afrika an Atlantik und Indischem Ozean, Lesotho umschliessend, angrenzend an Eswatini, Mosambik, Simbabwe und weitere.'},
SS:{fr:"Pays enclavé d'Afrique de l'Est, le plus jeune pays du monde (indépendant depuis 2011), entre le Soudan, l'Éthiopie, le Kenya, l'Ouganda et la RDC.",en:"Landlocked East African country, the world's youngest nation (independent since 2011), between Sudan, Ethiopia, Kenya, Uganda and DR Congo.",ua:"Наймолодша держава світу (незалежна з 2011 р.) у Східній Африці без виходу до моря.",de:'Ostafrikanischer Binnenstaat, juengste Nation der Welt (unabhaengig seit 2011), zwischen Sudan, Aethiopien, Kenia, Uganda und DR Kongo.'},
ES:{fr:"Pays d'Europe du Sud occupant la majeure partie de la péninsule ibérique, sur l'Atlantique et la Méditerranée.",en:"Southern European country occupying most of the Iberian Peninsula, on the Atlantic and Mediterranean.",ua:"Держава Південної Європи на Піренейському півострові між Атлантикою та Середземномор'ям.",de:'Suedeuropaeisches Land auf dem groessten Teil der Iberischen Halbinsel, an Atlantik und Mittelmeer.'},
LK:{fr:"Grande île de l'océan Indien au sud-est de l'Inde, séparée du continent par le détroit de Palk.",en:"Large island in the Indian Ocean southeast of India, separated from the mainland by the Palk Strait.",ua:"Великий острів в Індійському океані на південь від Індії.",de:'Grosse Insel im Indischen Ozean suedoestlich von Indien, durch die Palkstrasse vom Festland getrennt.'},
SD:{fr:"Grand pays d'Afrique du Nord-Est entre la Libye, l'Égypte, la mer Rouge, l'Érythrée et l'Éthiopie.",en:"Large country in northeastern Africa between Libya, Egypt, the Red Sea, Eritrea and Ethiopia.",ua:"Велика держава Північно-Східної Африки між Лівією та Ефіопією.",de:'Grosses Land im Nordosten Afrikas zwischen Libyen, Aegypten, dem Roten Meer, Eritrea und Aethiopien.'},
SR:{fr:"Petit pays d'Amérique du Sud sur la côte atlantique, entre la Guyana, le Brésil et la Guyane française.",en:"Small South American country on the Atlantic coast, between Guyana, Brazil and French Guiana.",ua:"Невелика держава на Атлантичному узбережжі Південної Америки.",de:'Kleines suedamerikanisches Land an der Atlantikkueste, zwischen Guyana, Brasilien und Franzoesisch-Guayana.'},
SZ:{fr:"Petit pays enclavé d'Afrique australe entouré par l'Afrique du Sud et le Mozambique.",en:"Small landlocked country in southern Africa surrounded by South Africa and Mozambique.",ua:"Невелика держава без виходу до моря, оточена ПАР та Мозамбіком.",de:'Kleiner Binnenstaat im suedlichen Afrika, umgeben von Suedafrika und Mosambik.'},
SE:{fr:"Grand pays nordique de la péninsule Scandinavie, entre la Norvège, la Finlande et la mer Baltique.",en:"Large Nordic country on the Scandinavian Peninsula, between Norway, Finland and the Baltic Sea.",ua:"Велика скандинавська держава між Норвегією, Фінляндією та Балтійським морем.",de:'Grosses nordisches Land auf der Skandinavischen Halbinsel, zwischen Norwegen, Finnland und der Ostsee.'},
CH:{fr:"Pays alpin d'Europe centrale enclavé entre l'Allemagne, la France, l'Italie, l'Autriche et le Liechtenstein.",en:"Alpine landlocked country in Central Europe between Germany, France, Italy, Austria and Liechtenstein.",ua:"Альпійська держава Центральної Європи між Францією, Німеччиною та Італією.",de:'Alpiner Binnenstaat in Mitteleuropa zwischen Deutschland, Frankreich, Italien, Oesterreich und Liechtenstein.'},
SY:{fr:"Pays du Proche-Orient sur la Méditerranée orientale, entre la Turquie, l'Irak, la Jordanie, Israël et le Liban.",en:"Middle Eastern country on the eastern Mediterranean, between Turkey, Iraq, Jordan, Israel and Lebanon.",ua:"Держава Близького Сходу на Середземноморі між Туреччиною та Іраком.",de:'Land im Nahen Osten am oestlichen Mittelmeer, zwischen der Tuerkei, dem Irak, Jordanien, Israel und dem Libanon.'},
TW:{fr:"Île d'Asie de l'Est dans l'océan Pacifique, au large du sud-est de la Chine continentale.",en:"East Asian island in the Pacific Ocean, off the southeastern coast of mainland China.",ua:"Острів Східної Азії в Тихому океані біля берегів Китаю.",de:'Ostasiatische Insel im Pazifischen Ozean, vor der Suedostkueste des chinesischen Festlands.'},
TJ:{fr:"Pays montagneux d'Asie centrale enclavé dans le Pamir, entre la Chine, l'Afghanistan, l'Ouzbékistan et le Kirghizistan.",en:"Mountainous landlocked country in Central Asia in the Pamirs, between China, Afghanistan, Uzbekistan and Kyrgyzstan.",ua:"Гірська держава Центральної Азії в горах Паміру.",de:'Gebirgiger Binnenstaat in Zentralasien im Pamir, zwischen China, Afghanistan, Usbekistan und Kirgisistan.'},
TZ:{fr:"Pays d'Afrique de l'Est sur l'océan Indien, incluant les îles de Zanzibar, entre le Kenya, l'Ouganda, le Rwanda, le Burundi, la RDC, la Zambie, le Malawi et le Mozambique.",en:"East African country on the Indian Ocean including Zanzibar islands, between Kenya, Uganda, Rwanda, Burundi, DR Congo, Zambia, Malawi and Mozambique.",ua:"Держава Східної Африки на Індійському океані, включає острови Занзібар.",de:'Ostafrikanisches Land am Indischen Ozean einschliesslich Sansibar, zwischen Kenia, Uganda, Ruanda, Burundi, DR Kongo, Sambia, Malawi und Mosambik.'},
TH:{fr:"Pays d'Asie du Sud-Est au cœur de la péninsule indochinoise, entre le Myanmar, le Laos, le Cambodge et la Malaisie.",en:"Southeast Asian country at the heart of the Indochinese Peninsula, between Myanmar, Laos, Cambodia and Malaysia.",ua:"Держава Південно-Східної Азії в центрі Індокитайського півострова.",de:'Suedostasiatisches Land im Herzen der Indochinesischen Halbinsel, zwischen Myanmar, Laos, Kambodscha und Malaysia.'},
TL:{fr:"Demi-île du Pacifique occidental et de l'Asie du Sud-Est, à l'est de l'île de Timor, entre l'Indonésie et l'Australie.",en:"Half-island in the western Pacific and Southeast Asia, on the eastern part of Timor Island, between Indonesia and Australia.",ua:"Держава на Тиморському острові у Тихому океані між Індонезією та Австралією.",de:'Halb-Insel im westlichen Pazifik und Suedostasien, im Ostteil der Insel Timor, zwischen Indonesien und Australien.'},
TG:{fr:"Petit pays allongé d'Afrique de l'Ouest sur le golfe de Guinée, entre le Bénin et le Ghana.",en:"Small elongated country in West Africa on the Gulf of Guinea, between Benin and Ghana.",ua:"Невелика видовжена держава Західної Африки між Беніном та Ганою.",de:'Kleines langgestrecktes Land in Westafrika am Golf von Guinea, zwischen Benin und Ghana.'},
TO:{fr:"Archipel polynésien du Pacifique Sud à l'est des Fidji et au nord de la Nouvelle-Zélande.",en:"Polynesian archipelago in the South Pacific, east of Fiji and north of New Zealand.",ua:"Полінезійський архіпелаг у Південному Тихому океані.",de:'Polynesischer Archipel im Suedpazifik, oestlich von Fidschi und noerdlich von Neuseeland.'},
TT:{fr:"Île-État des Caraïbes au large de la côte nord du Venezuela, la plus méridionale des Grandes Antilles.",en:"Island state in the Caribbean off the northern coast of Venezuela, the southernmost of the Greater Antilles.",ua:"Острівна держава у Карибському морі біля узбережжя Венесуели.",de:'Inselstaat in der Karibik vor der Nordkueste Venezuelas, suedlichster der Grossen Antillen.'},
TN:{fr:"Pays d'Afrique du Nord sur la Méditerranée, entre l'Algérie et la Libye.",en:"North African country on the Mediterranean, between Algeria and Libya.",ua:"Держава Північної Африки на Середземному морі між Алжиром та Лівією.",de:'Nordafrikanisches Land am Mittelmeer, zwischen Algerien und Libyen.'},
TR:{fr:"Pays à cheval entre l'Europe du Sud-Est et l'Asie occidentale, au carrefour de la mer Noire, de la Méditerranée et du Proche-Orient.",en:"Country straddling southeastern Europe and western Asia, at the crossroads of the Black Sea, the Mediterranean and the Middle East.",ua:"Держава на межі Південно-Східної Європи та Близького Сходу між Чорним та Середземним морями.",de:'Land an der Schnittstelle von Suedosteuropa und Westasien, am Kreuzpunkt von Schwarzem Meer, Mittelmeer und Nahem Osten.'},
TM:{fr:"Pays d'Asie centrale en grande partie désertique (désert du Karakoum), entre le Kazakhstan, l'Ouzbékistan, l'Afghanistan et l'Iran.",en:"Largely desert Central Asian country (Karakum Desert), between Kazakhstan, Uzbekistan, Afghanistan and Iran.",ua:"Переважно пустельна держава Центральної Азії між Казахстаном та Іраном.",de:'Groesstenteils wuestes zentralasiatisches Land (Karakum-Wueste), zwischen Kasachstan, Usbekistan, Afghanistan und Iran.'},
TV:{fr:"Minuscule archipel polynésien du Pacifique central, l'un des plus petits et isolés pays du monde.",en:"Tiny Polynesian archipelago in the central Pacific, one of the world's smallest and most isolated countries.",ua:"Крихітний полінезійський архіпелаг у центральній частині Тихого океану.",de:'Winziger polynesischer Archipel im zentralen Pazifik, eines der kleinsten und abgelegensten Laender der Welt.'},
UG:{fr:"Pays enclavé d'Afrique de l'Est, au bord du lac Victoria, entre la RDC, le Soudan du Sud, le Kenya, la Tanzanie et le Rwanda.",en:"Landlocked East African country on Lake Victoria, between DR Congo, South Sudan, Kenya, Tanzania and Rwanda.",ua:"Держава без виходу до моря в Східній Африці біля озера Вікторія.",de:'Ostafrikanischer Binnenstaat am Victoriasee, zwischen DR Kongo, Suedsudan, Kenia, Tansania und Ruanda.'},
UA:{fr:"Grand pays d'Europe de l'Est, le plus grand entièrement en Europe, entre la Russie, la Biélorussie, la Pologne, la Slovaquie, la Hongrie, la Roumanie et la Moldavie.",en:"Large Eastern European country, the largest entirely within Europe, between Russia, Belarus, Poland, Slovakia, Hungary, Romania and Moldova.",ua:"Найбільша держава Європи (повністю в межах континенту), між Росією, Польщею та Румунією.",de:'Grosses osteuropaeisches Land, das groesste vollstaendig in Europa liegende, zwischen Russland, Belarus, Polen, der Slowakei, Ungarn, Rumaenien und Moldau.'},
AE:{fr:"Fédération de 7 émirats sur la côte du Golfe persique et du golfe d'Oman, entre l'Arabie saoudite et Oman.",en:"Federation of 7 emirates on the Persian Gulf and Gulf of Oman coast, between Saudi Arabia and Oman.",ua:"Федерація 7 еміратів на Перській затоці між Саудівською Аравією та Оманом.",de:'Foederation aus 7 Emiraten am Persischen Golf und Golf von Oman, zwischen Saudi-Arabien und Oman.'},
GB:{fr:"Archipel d'Europe du Nord-Ouest composé de la Grande-Bretagne, de l'Irlande du Nord et de nombreuses petites îles.",en:"Northwestern European archipelago composed of Great Britain, Northern Ireland and many smaller islands.",ua:"Архіпелаг Північно-Західної Європи, включає Велику Британію та Північну Ірландію.",de:'Nordwesteuropaeischer Archipel bestehend aus Grossbritannien, Nordirland und vielen kleineren Inseln.'},
US:{fr:"Immense pays d'Amérique du Nord entre le Canada et le Mexique, avec des côtes sur l'Atlantique et le Pacifique, incluant l'Alaska et Hawaï.",en:"Vast North American country between Canada and Mexico, with Atlantic and Pacific coasts, including Alaska and Hawaii.",ua:"Велика держава Північної Америки між Канадою та Мексикою з узбережжями Атлантики та Тихого океану.",de:'Riesiges nordamerikanisches Land zwischen Kanada und Mexiko, mit Atlantik- und Pazifikkueste, einschliesslich Alaska und Hawaii.'},
UY:{fr:"Petit pays d'Amérique du Sud sur l'Atlantique, entre l'Argentine et le Brésil.",en:"Small South American country on the Atlantic, between Argentina and Brazil.",ua:"Невелика держава на Атлантичному узбережжі Південної Америки між Аргентиною та Бразилією.",de:'Kleines suedamerikanisches Land am Atlantik, zwischen Argentinien und Brasilien.'},
UZ:{fr:"Grand pays enclavé d'Asie centrale, berceau de la Route de la Soie, entre le Kazakhstan, le Kirghizistan, le Tadjikistan, l'Afghanistan et le Turkménistan.",en:"Large landlocked Central Asian country, historic Silk Road hub, between Kazakhstan, Kyrgyzstan, Tajikistan, Afghanistan and Turkmenistan.",ua:"Велика держава без виходу до моря в Центральній Азії, колишній центр Шовкового шляху.",de:'Grosser zentralasiatischer Binnenstaat, historischer Knotenpunkt der Seidenstrasse, zwischen Kasachstan, Kirgisistan, Tadschikistan, Afghanistan und Turkmenistan.'},
VU:{fr:"Archipel de l'Océanie dans le Pacifique Sud, à l'est de l'Australie et au nord de la Nouvelle-Calédonie.",en:"Oceanian archipelago in the South Pacific, east of Australia and north of New Caledonia.",ua:"Архіпелаг Океанії у Південному Тихому океані.",de:'Ozeanischer Archipel im Suedpazifik, oestlich von Australien und noerdlich von Neukaledonien.'},
VE:{fr:"Pays d'Amérique du Sud sur la mer des Caraïbes, entre la Colombie, le Brésil et le Guyana.",en:"South American country on the Caribbean Sea, between Colombia, Brazil and Guyana.",ua:"Держава Південної Америки на Карибському морі між Колумбією та Бразилією.",de:'Suedamerikanisches Land am Karibischen Meer, zwischen Kolumbien, Brasilien und Guyana.'},
VN:{fr:"Pays d'Asie du Sud-Est en forme de bande côtière le long du golfe du Tonkin et de la mer de Chine méridionale.",en:"Southeast Asian country in the shape of a coastal strip along the Gulf of Tonkin and South China Sea.",ua:"Держава Південно-Східної Азії вздовж узбережжя Південнокитайського моря.",de:'Suedostasiatisches Land in Form eines Kuestenstreifens entlang des Golfs von Tonkin und des Suedchinesischen Meers.'},
YE:{fr:"Pays de la péninsule arabique sur la mer d'Arabie et le golfe d'Aden, entre l'Arabie saoudite et Oman.",en:"Country on the Arabian Peninsula on the Arabian Sea and Gulf of Aden, between Saudi Arabia and Oman.",ua:"Держава на Аравійському півострові між Саудівською Аравією та Оманом.",de:'Land auf der Arabischen Halbinsel am Arabischen Meer und Golf von Aden, zwischen Saudi-Arabien und Oman.'},
ZM:{fr:"Pays enclavé d'Afrique australe entre la RDC, la Tanzanie, le Malawi, le Mozambique, le Zimbabwe, le Botswana, la Namibie et l'Angola.",en:"Landlocked country in southern Africa between DR Congo, Tanzania, Malawi, Mozambique, Zimbabwe, Botswana, Namibia and Angola.",ua:"Держава без виходу до моря в Південній Африці між вісьмома країнами.",de:'Binnenstaat im suedlichen Afrika zwischen DR Kongo, Tansania, Malawi, Mosambik, Simbabwe, Botswana, Namibia und Angola.'},
ZW:{fr:"Pays enclavé d'Afrique australe entre la Zambie, le Mozambique, l'Afrique du Sud et le Botswana.",en:"Landlocked country in southern Africa between Zambia, Mozambique, South Africa and Botswana.",ua:"Держава без виходу до моря в Південній Африці між Замбією, Мозамбіком та ПАР.",de:'Binnenstaat im suedlichen Afrika zwischen Sambia, Mosambik, Suedafrika und Botswana.'}
};
function getCountryDesc(c) {
// Try by country_code first, then by matching known names
var code = (c.country_code || '').toUpperCase();
if (code && COUNTRY_DESCRIPTIONS[code]) {
var d = COUNTRY_DESCRIPTIONS[code];
return d[currentLang] || d.fr;
}
// Fallback: try matching by country_FR
var nameFR = (c.country_FR || '').toLowerCase();
var nameLookup = {
'france':'FR','états-unis':'US','etats-unis':'US','brésil':'BR','bresil':'BR',
'japon':'JP','inde':'IN','norvège':'NO','norvege':'NO','nigeria':'NG',
'argentine':'AR','australie':'AU','chine':'CN','allemagne':'DE','russie':'RU',
'royaume-uni':'GB','espagne':'ES','italie':'IT','canada':'CA','mexique':'MX'
};
var mapped = nameLookup[nameFR];
if (mapped && COUNTRY_DESCRIPTIONS[mapped]) {
var d2 = COUNTRY_DESCRIPTIONS[mapped];
return d2[currentLang] || d2.fr;
}
return null;
}
// ─── COUNTRY HINTS LEVEL 2 ────────────────────────────────────────────────────
var COUNTRY_HINTS2 = {
AF:{fr:"Parmi les pays les plus pauvres du monde. Économie quasi inexistante. Carrefour stratégique entre Asie centrale et Moyen-Orient. Conflits armés permanents.",en:"Among the world's poorest countries. Almost no formal economy. Strategic crossroads between Central Asia and the Middle East. Permanent armed conflicts.",ua:"Серед найбідніших країн. Стратегічне перехрестя Центральної Азії та Близького Сходу. Постійні збройні конфлікти.",de:'Eines der aermsten Laender der Welt. Kaum formelle Wirtschaft. Strategischer Knotenpunkt zwischen Zentralasien und Nahem Osten. Permanente bewaffnete Konflikte.'},
DZ:{fr:"Grand producteur de gaz naturel et pétrole. Armée parmi les plus puissantes d'Afrique. Économie très dépendante des hydrocarbures.",en:"Major natural gas and oil producer. One of Africa's most powerful armies. Economy heavily reliant on hydrocarbons.",ua:"Великий виробник газу та нафти. Одна з найпотужніших армій Африки. Економіка залежить від вуглеводнів.",de:'Grosser Erdgas- und Oelproduzent. Eine der staerksten Armeen Afrikas. Wirtschaft stark von Kohlenwasserstoffen abhaengig.'},
AR:{fr:"Puissance économique régionale mais dette chroniquement élevée et inflation record. Grands producteurs de soja et de bœuf.",en:"Regional economic power but chronically high debt and record inflation. Major soybean and beef producers.",ua:"Регіональна економічна сила, але хронічно висока заборгованість та рекордна інфляція. Великий виробник сої та яловичини.",de:'Regionale Wirtschaftsmacht, aber chronisch hohe Verschuldung und Rekordinflation. Grosser Soja- und Rindfleischproduzent.'},
AM:{fr:"Petite économie enclavée, dépendante des transferts de la diaspora. Conflits avec l'Azerbaïdjan. Industrie minière (cuivre, or).",en:"Small landlocked economy dependent on diaspora remittances. Conflicts with Azerbaijan. Mining industry (copper, gold).",ua:"Мала економіка, залежна від переказів діаспори. Конфлікти з Азербайджаном. Видобуток міді та золота.",de:'Kleine Binnenwirtschaft, abhaengig von Ueberweisungen der Diaspora. Konflikte mit Aserbaidschan. Bergbau (Kupfer, Gold).'},
AU:{fr:"Économie très développée, l'une des plus riches per capita. Immenses ressources minières. Très faible densité de population. Exportateur majeur de charbon et de minerai de fer.",en:"Highly developed economy, one of the richest per capita. Vast mining resources. Very low population density. Major coal and iron ore exporter.",ua:"Розвинена економіка, одна з найбагатших. Величезні гірничодобувні ресурси. Мала густота населення.",de:'Hochentwickelte Wirtschaft, eine der reichsten pro Kopf. Riesige Bodenschaetze. Sehr geringe Bevoelkerungsdichte. Grosser Kohle- und Eisenerz-Exporteur.'},
AT:{fr:"Économie très développée. Neutre militairement depuis 1955. Fort tourisme alpin. Siège de nombreuses organisations internationales.",en:"Highly developed economy. Militarily neutral since 1955. Strong Alpine tourism. Headquarters of many international organizations.",ua:"Розвинена економіка. Нейтральна з 1955 р. Альпійський туризм. Штаб-квартири міжнародних організацій.",de:'Hochentwickelte Wirtschaft. Militaerisch neutral seit 1955. Starker Alpentourismus. Sitz vieler internationaler Organisationen.'},
AZ:{fr:"Grand producteur de pétrole et de gaz de la mer Caspienne. Régime autoritaire. Conflit récent sur le Haut-Karabakh.",en:"Major Caspian Sea oil and gas producer. Authoritarian regime. Recent conflict over Nagorno-Karabakh.",ua:"Великий виробник нафти та газу. Авторитарний режим. Нещодавній конфлікт за Нагірний Карабах.",de:'Grosser Oel- und Gasproduzent am Kaspischen Meer. Autoritaeres Regime. Juengster Konflikt um Bergkarabach.'},
BE:{fr:"Siège de l'UE et de l'OTAN. Économie très développée, grand exportateur. Fortement endetté. Pays divisé entre francophones et néerlandophones.",en:"EU and NATO headquarters. Highly developed economy, major exporter. Heavily indebted. Country divided between French and Dutch speakers.",ua:"Штаб-квартира ЄС та НАТО. Розвинена економіка. Велика заборгованість. Лінгвістично розділена країна.",de:'EU- und NATO-Hauptquartier. Hochentwickelte Wirtschaft, grosser Exporteur. Hoch verschuldet. Land zwischen Franzoesisch- und Niederlaendischsprachigen geteilt.'},
BD:{fr:"Économie émergente, grand exportateur de textile. Parmi les pays les plus densément peuplés. Très vulnérable aux cyclones et inondations.",en:"Emerging economy, major textile exporter. Among the world's most densely populated. Very vulnerable to cyclones and flooding.",ua:"Економіка, що розвивається, великий експортер текстилю. Одна з найгустіше заселених країн. Вразлива до ударів стихії.",de:'Aufstrebende Wirtschaft, grosser Textilexporteur. Eines der am dichtesten besiedelten Laender. Sehr anfaellig fuer Zyklone und Ueberschwemmungen.'},
BY:{fr:"Régime autoritaire très proche de la Russie. Économie planifiée, peu réformée. Sous sanctions depuis 2020.",en:"Highly authoritarian regime closely aligned with Russia. Planned economy, barely reformed. Under sanctions since 2020.",ua:"Авторитарний режим, тісно пов'язаний з Росією. Планова нереформована економіка. Санкції з 2020 р.",de:'Stark autoritaeres Regime, eng mit Russland verbuendet. Planwirtschaft, kaum reformiert. Seit 2020 unter Sanktionen.'},
BO:{fr:"Grandes réserves de lithium parmi les premières mondiales. Gaz naturel. L'un des plus pauvres d'Amérique du Sud.",en:"World-leading lithium reserves. Natural gas. One of the poorest in South America.",ua:"Одні з найбільших запасів літію. Природний газ. Одна з найбідніших країн Південної Америки.",de:'Weltweit fuehrende Lithiumreserven. Erdgas. Eines der aermsten Laender Suedamerikas.'},
BA:{fr:"Économie en développement post-guerre civile des années 1990. Gouvernance très complexe. Candidat à l'UE.",en:"Developing economy post-1990s civil war. Very complex governance. EU candidate.",ua:"Економіка відновлюється після громадянської війни 1990-х. Складне управління. Кандидат у члени ЄС.",de:'Sich entwickelnde Wirtschaft nach dem Buergerkrieg der 1990er. Sehr komplexe Regierungsstruktur. EU-Kandidat.'},
BR:{fr:"Plus grande économie d'Amérique latine, 9e mondiale. Immenses ressources naturelles. Armée la plus grande d'Amérique du Sud. Forte inégalité.",en:"Largest Latin American economy, 9th globally. Vast natural resources. Largest military in South America. High inequality.",ua:"Найбільша економіка Латинської Америки. Найбільша армія Південної Америки. Висока нерівність.",de:'Groesste lateinamerikanische Wirtschaft, weltweit 9. Riesige Bodenschaetze. Groesste Armee Suedamerikas. Hohe Ungleichheit.'},
BG:{fr:"Parmi les moins développées de l'UE. Forte émigration. Ancienne économie communiste en transition.",en:"Among the EU's least developed. High emigration. Former communist economy in transition.",ua:"Серед найменш розвинених в ЄС. Висока еміграція. Колишня комуністична економіка.",de:'Eines der am wenigsten entwickelten EU-Laender. Hohe Abwanderung. Ehemalige kommunistische Wirtschaft im Uebergang.'},
BF:{fr:"Parmi les plus pauvres du monde. Grave insécurité liée aux groupes armés sahéliens. Ressources en or.",en:"Among the world's poorest. Severe insecurity from Sahelian armed groups. Gold resources.",ua:"Серед найбідніших. Серйозна нестабільність від озброєних груп. Золото.",de:'Eines der aermsten Laender der Welt. Schwere Unsicherheit durch bewaffnete Sahelgruppen. Goldvorkommen.'},
CA:{fr:"Économie du G7. Immenses ressources naturelles (pétrole, gaz, bois, minerais). Très faible densité de population.",en:"G7 economy. Vast natural resources (oil, gas, timber, minerals). Very low population density.",ua:"Економіка G7. Величезні природні ресурси. Дуже мала густота населення.",de:'G7-Wirtschaft. Riesige Bodenschaetze (Oel, Gas, Holz, Mineralien). Sehr geringe Bevoelkerungsdichte.'},
CL:{fr:"Économie la plus développée d'Amérique du Sud. Premier producteur mondial de cuivre. Faible corruption régionale.",en:"Most developed economy in South America. World's top copper producer. Low regional corruption.",ua:"Найрозвиненіша економіка Південної Америки. №1 виробник міді. Низька корупція.",de:'Am weitesten entwickelte Wirtschaft Suedamerikas. Weltweit groesster Kupferproduzent. Geringe regionale Korruption.'},
CN:{fr:"2e économie mondiale. Plus grande armée en effectifs. Exportateur n°1 mondial. Membre permanent du Conseil de sécurité de l'ONU. Puissance nucléaire.",en:"World's 2nd economy. Largest military by headcount. #1 global exporter. Permanent UN Security Council member. Nuclear power.",ua:"2-га економіка світу. Найбільша армія. №1 експортер. Постійний член РБ ООН. Ядерна держава.",de:'Zweitgroesste Wirtschaft der Welt. Groesste Armee nach Personenzahl. Groesster Exporteur weltweit. Staendiges Mitglied im UN-Sicherheitsrat. Atommacht.'},
CO:{fr:"Une des plus grandes économies d'Amérique du Sud. Grand producteur de café. Longtemps touché par les narcotrafiquants et guérillas.",en:"One of South America's largest economies. Major coffee producer. Long affected by drug cartels and guerrillas.",ua:"Одна з найбільших економік Південної Америки. Великий виробник кави. Тривалий вплив наркокартелів.",de:'Eine der groessten Wirtschaften Suedamerikas. Grosser Kaffeeproduzent. Lange von Drogenkartellen und Guerilla betroffen.'},
CD:{fr:"Richesses naturelles immenses (cobalt, coltan, diamants, or). Malgré cela, l'un des plus pauvres. Conflits armés récurrents à l'est.",en:"Immense natural wealth (cobalt, coltan, diamonds, gold). Despite this, one of the poorest. Recurrent armed conflicts in the east.",ua:"Величезні природні ресурси. Але одна з найбідніших. Збройні конфлікти на сході.",de:'Immenser Rohstoffreichtum (Kobalt, Coltan, Diamanten, Gold). Dennoch eines der aermsten Laender. Wiederkehrende bewaffnete Konflikte im Osten.'},
CU:{fr:"Économie planifiée sous embargo américain. Fort niveau d'éducation et de santé malgré la pauvreté.",en:"Planned economy under US embargo. High education and health levels despite poverty.",ua:"Планова економіка під американським ембарго. Висока освіта та охорона здоров'я попри бідність.",de:'Planwirtschaft unter US-Embargo. Hohes Bildungs- und Gesundheitsniveau trotz Armut.'},
CZ:{fr:"Économie la plus industrialisée d'Europe centrale. Grand constructeur automobile. Parmi les moins corrompus d'Europe de l'Est.",en:"Most industrialized economy in Central Europe. Major car manufacturer. Among the least corrupt in Eastern Europe.",ua:"Найбільш індустріалізована економіка Центральної Європи. Великий виробник автомобілів.",de:'Am staerksten industrialisierte Wirtschaft Mitteleuropas. Grosser Automobilhersteller. Eines der am wenigsten korrupten Laender Osteuropas.'},
DK:{fr:"Parmi les plus riches per capita. Leader en énergie éolienne. Très faible corruption. Haut niveau de bien-être social.",en:"Among the richest per capita. Wind energy leader. Very low corruption. High social welfare.",ua:"Серед найбагатших. Лідер у вітровій енергетиці. Дуже низька корупція.",de:'Eines der reichsten Laender pro Kopf. Vorreiter bei Windenergie. Sehr geringe Korruption. Hohes Sozialniveau.'},
EG:{fr:"Économie la plus importante du monde arabe après l'Arabie saoudite. Canal de Suez stratégique. Grande armée.",en:"Most important Arab economy after Saudi Arabia. Strategic Suez Canal. Large military.",ua:"Найважливіша арабська економіка після Саудівської Аравії. Суецький канал. Велика армія.",de:'Wichtigste arabische Wirtschaft nach Saudi-Arabien. Strategischer Suezkanal. Grosse Armee.'},
ET:{fr:"Économie à croissance rapide mais très pauvre. Grande armée. Siège de l'Union africaine. Population très jeune.",en:"Fast-growing but very poor economy. Large military. African Union HQ. Very young population.",ua:"Швидке зростання, але бідна. Велика армія. Штаб-квартира АС. Молоде населення.",de:'Schnell wachsende, aber sehr arme Wirtschaft. Grosse Armee. Sitz der Afrikanischen Union. Sehr junge Bevoelkerung.'},
FI:{fr:"Économie très développée. Leader mondial en éducation (modèle PISA). Parmi les moins corrompus.",en:"Highly developed economy. Global education leader (PISA model). Among world's least corrupt.",ua:"Розвинена економіка. Світовий лідер в освіті. Серед найменш корумпованих.",de:'Hochentwickelte Wirtschaft. Weltweit fuehrend im Bildungswesen (PISA-Modell). Eines der am wenigsten korrupten Laender.'},
FR:{fr:"5e ou 6e économie mondiale, membre du G7. Puissance nucléaire, membre permanent du Conseil de sécurité de l'ONU. 1re destination touristique mondiale.",en:"5th or 6th economy worldwide, G7 member. Nuclear power, permanent UN Security Council member. World's top tourist destination.",ua:"5-та або 6-та економіка світу, G7. Ядерна держава, постійний член РБ ООН. №1 туристичне призначення.",de:'5. oder 6. Wirtschaft weltweit, G7-Mitglied. Atommacht, staendiges Mitglied im UN-Sicherheitsrat. Meistbesuchtes Reiseziel der Welt.'},
DE:{fr:"Plus grande économie d'Europe, 3e ou 4e mondiale. Leader de l'industrie automobile et chimique. Membre fondateur de l'UE.",en:"Europe's largest economy, 3rd or 4th globally. Leader in automotive and chemical industries. EU founding member.",ua:"Найбільша економіка Європи. Лідер автомобільної промисловості. Засновник ЄС.",de:'Groesste Wirtschaft Europas, weltweit 3. oder 4. Fuehrend in Automobil- und Chemieindustrie. EU-Gruendungsmitglied.'},
GH:{fr:"Économie stable d'Afrique de l'Ouest. Producteur d'or et de cacao. Démocratie modèle pour l'Afrique.",en:"Stable West African economy. Gold and cocoa producer. Model democracy for Africa.",ua:"Стабільна економіка Африки. Виробник золота та какао. Зразкова демократія.",de:'Stabile westafrikanische Wirtschaft. Gold- und Kakaoproduzent. Vorbild-Demokratie fuer Afrika.'},
GR:{fr:"Grave crise financière post-2008. Forte dette publique. Tourisme majeur. Armée relativement forte en raison des tensions avec la Turquie.",en:"Severe post-2008 financial crisis. High public debt. Major tourism. Relatively strong military due to tensions with Turkey.",ua:"Фінансова криза після 2008 р. Великий борг. Важливий туризм. Напруга з Туреччиною.",de:'Schwere Finanzkrise nach 2008. Hohe Staatsverschuldung. Bedeutender Tourismus. Relativ starke Armee wegen Spannungen mit der Tuerkei.'},
HU:{fr:"Ancienne économie communiste. Régime politique controversé en Europe. Faible natalité et vieillissement rapide.",en:"Former communist economy. Controversial political regime in Europe. Low birth rate and rapid aging.",ua:"Колишня комуністична економіка. Суперечливий режим. Низька народжуваність.",de:'Ehemalige kommunistische Wirtschaft. Umstrittenes politisches Regime in Europa. Niedrige Geburtenrate und schnelle Alterung.'},
IN:{fr:"3e économie mondiale en PPA. Puissance nucléaire. Très grande armée. Membre des BRICS. Géant technologique.",en:"3rd economy by PPP. Nuclear power. Very large military. BRICS member. Tech giant.",ua:"3-тя економіка за ПКС. Ядерна держава. Велика армія. БРІКС. Технологічний гігант.",de:'3. Wirtschaft nach Kaufkraftparitaet. Atommacht. Sehr grosse Armee. BRICS-Mitglied. Technologieriese.'},
ID:{fr:"Plus grande économie d'Asie du Sud-Est, G20. Grand producteur de charbon, d'huile de palme et de nickel.",en:"Largest Southeast Asian economy, G20. Major coal, palm oil and nickel producer.",ua:"Найбільша економіка Південно-Східної Азії, G20. Великий виробник вугілля та пальмової олії.",de:'Groesste Wirtschaft Suedostasiens, G20. Grosser Kohle-, Palmoel- und Nickelproduzent.'},
IR:{fr:"Grande économie du Moyen-Orient sous sanctions. Immenses réserves pétrolières. Puissance militaire régionale. Programme nucléaire controversé.",en:"Large Middle Eastern economy under sanctions. Huge oil reserves. Regional military power. Controversial nuclear program.",ua:"Велика економіка під санкціями. Нафтові запаси. Регіональна воєнна сила. Ядерна програма.",de:'Grosse Wirtschaft im Nahen Osten unter Sanktionen. Riesige Oelreserven. Regionale Militaermacht. Umstrittenes Atomprogramm.'},
IQ:{fr:"Grandes réserves pétrolières (top 5). Économie très dépendante du pétrole. Instabilité récurrente depuis les années 1980.",en:"Major oil reserves (top 5). Oil-dependent economy. Recurring instability since the 1980s.",ua:"Великі нафтові запаси (топ-5). Залежна від нафти. Нестабільність з 1980-х.",de:'Grosse Oelreserven (Top 5). Oelabhaengige Wirtschaft. Wiederkehrende Instabilitaet seit den 1980ern.'},
IE:{fr:"Économie très développée, parmi les plus riches per capita. Siège européen de grandes multinationales. Très faible corruption.",en:"Highly developed, among Europe's richest. European HQ of major multinationals. Very low corruption.",ua:"Одна з найбагатших в Європі. Штаб-квартири транснаціональних корпорацій. Дуже низька корупція.",de:'Hochentwickelt, eines der reichsten Laender Europas. Europasitz grosser Konzerne. Sehr geringe Korruption.'},
IL:{fr:"Économie très développée, 'Start-up Nation'. Puissance nucléaire présumée. Armée technologiquement avancée.",en:"Highly developed, 'Start-up Nation'. Presumed nuclear power. Technologically advanced military.",ua:"'Стартап-нація'. Ймовірна ядерна держава. Передова армія.",de:'Hochentwickelt, \u00abStart-up-Nation\u00bb. Vermutete Atommacht. Technologisch fortschrittliche Armee.'},
IT:{fr:"3e économie de la zone euro, 8e mondiale. Leader du luxe et de la mode. Forte dette publique. Instabilité politique chronique.",en:"3rd eurozone economy, 8th globally. Leader in luxury and fashion. High public debt. Chronic political instability.",ua:"3-тя економіка єврозони. Лідер розкоші та моди. Великий борг. Хронічна нестабільність.",de:'3. Wirtschaft der Eurozone, weltweit 8. Fuehrend in Luxus und Mode. Hohe Staatsverschuldung. Chronische politische Instabilitaet.'},
JP:{fr:"3e économie mondiale. Technologies de pointe. Armée puissante. Population la plus vieillissante au monde.",en:"World's 3rd economy. Cutting-edge technology. Powerful military. World's most aging population.",ua:"3-тя економіка. Передові технології. Потужна армія. Найстаріше населення у світі.",de:'3. Wirtschaft der Welt. Spitzentechnologie. Starke Armee. Aelteste Bevoelkerung der Welt.'},
KZ:{fr:"Grandes réserves de pétrole, gaz et uranium. Économie la plus développée d'Asie centrale. Régime autoritaire.",en:"Large oil, gas and uranium reserves. Most developed Central Asian economy. Authoritarian regime.",ua:"Нафта, газ, уран. Найрозвиненіша економіка Центральної Азії. Авторитарний режим.",de:'Grosse Oel-, Gas- und Uranreserven. Am weitesten entwickelte Wirtschaft Zentralasiens. Autoritaeres Regime.'},
KE:{fr:"Plus grande économie d'Afrique de l'Est. Hub technologique africain. Centre financier régional.",en:"East Africa's largest economy. African tech hub. Regional financial center.",ua:"Найбільша економіка Східної Африки. Технологічний хаб. Регіональний фінансовий центр.",de:'Groesste Wirtschaft Ostafrikas. Afrikanisches Technologiezentrum. Regionales Finanzzentrum.'},
KP:{fr:"Régime totalitaire très fermé. Puissance nucléaire. Armée très grande en effectifs. Économie isolée et peu développée.",en:"Very closed totalitarian regime. Nuclear power. Very large military by headcount. Isolated and underdeveloped economy.",ua:"Закритий тоталітарний режим. Ядерна держава. Велика армія. Ізольована економіка.",de:'Sehr geschlossenes totalitaeres Regime. Atommacht. Sehr grosse Armee nach Personenzahl. Isolierte und unterentwickelte Wirtschaft.'},
KR:{fr:"4e économie d'Asie. Leader de la construction navale, de l'électronique (Samsung, LG) et de l'automobile (Hyundai, Kia).",en:"4th Asian economy. Leader in shipbuilding, electronics (Samsung, LG) and cars (Hyundai, Kia).",ua:"4-та економіка Азії. Лідер суднобудування, електроніки (Samsung) та авто (Hyundai).",de:'4. Wirtschaft Asiens. Fuehrend im Schiffbau, Elektronik (Samsung, LG) und Automobilbau (Hyundai, Kia).'},
KW:{fr:"Très riches réserves pétrolières, un des plus riches per capita. Économie très dépendante du pétrole.",en:"Very large oil reserves, one of the world's richest per capita. Oil-dependent economy.",ua:"Великі нафтові запаси. Одна з найбагатших країн. Залежить від нафти.",de:'Sehr grosse Oelreserven, eines der reichsten Laender pro Kopf. Oelabhaengige Wirtschaft.'},
LY:{fr:"Grandes réserves pétrolières. Instabilité politique majeure depuis 2011. Économie très dépendante du pétrole.",en:"Large oil reserves. Major political instability since 2011. Oil-dependent economy.",ua:"Нафтові запаси. Нестабільність з 2011 р. Залежність від нафти.",de:'Grosse Oelreserven. Erhebliche politische Instabilitaet seit 2011. Oelabhaengige Wirtschaft.'},
MX:{fr:"2e économie d'Amérique latine, G20. Grand producteur pétrolier. Exportateur industriel vers les États-Unis. Violence chronique liée aux cartels.",en:"2nd Latin American economy, G20. Major oil producer. Industrial exporter to the US. Chronic cartel violence.",ua:"2-га економіка Латинської Америки, G20. Нафта. Промисловий експорт до США. Картелі.",de:'2. lateinamerikanische Wirtschaft, G20. Grosser Oelproduzent. Industrieexporteur in die USA. Chronische Kartellgewalt.'},
MA:{fr:"Économie la plus stable du Maghreb. Grand producteur de phosphates (top 3 mondial). Hub d'investissement en Afrique.",en:"Most stable Maghreb economy. Top-3 global phosphate producer. Investment hub for Africa.",ua:"Найстабільніша економіка Магрибу. Топ-3 фосфатів. Інвестиційний хаб Африки.",de:'Stabilste Wirtschaft des Maghreb. Top-3-Phosphatproduzent weltweit. Investitionszentrum fuer Afrika.'},
NL:{fr:"5e économie de l'UE. Premier port d'Europe (Rotterdam). Grand exportateur agricole. Centre financier mondial.",en:"5th EU economy. Europe's largest port (Rotterdam). Major agricultural exporter. Global financial center.",ua:"5-та економіка ЄС. Найбільший порт (Роттердам). Великий аграрний експортер.",de:'5. EU-Wirtschaft. Groesster Hafen Europas (Rotterdam). Grosser Agrarexporteur. Globales Finanzzentrum.'},
NZ:{fr:"Économie très développée. Faible corruption. Qualité de vie parmi les meilleures du monde.",en:"Highly developed economy. Low corruption. Quality of life among the world's best.",ua:"Розвинена економіка. Низька корупція. Одна з найвищих якостей життя.",de:'Hochentwickelte Wirtschaft. Geringe Korruption. Lebensqualitaet unter den besten der Welt.'},
NG:{fr:"Plus grande économie d'Afrique. Grand producteur de pétrole. Grande pauvreté malgré les ressources. Armée la plus puissante d'Afrique de l'Ouest.",en:"Africa's largest economy. Major oil producer. Widespread poverty despite resources. West Africa's strongest military.",ua:"Найбільша економіка Африки. Нафта. Попри ресурси — бідність. Найсильніша армія Західної Африки.",de:'Groesste Wirtschaft Afrikas. Grosser Oelproduzent. Verbreitete Armut trotz Ressourcen. Staerkste Armee Westafrikas.'},
NO:{fr:"Un des plus riches per capita grâce au pétrole. Plus grand fonds souverain du monde. Très faible corruption.",en:"One of the world's richest per capita thanks to oil. World's largest sovereign wealth fund. Very low corruption.",ua:"Одна з найбагатших завдяки нафті. Найбільший суверенний фонд. Дуже низька корупція.",de:'Eines der reichsten Laender pro Kopf dank Oel. Groesster Staatsfonds der Welt. Sehr geringe Korruption.'},
PK:{fr:"Puissance nucléaire. Grande armée. Instabilité politique et sécuritaire récurrente. Relations tendues avec l'Inde.",en:"Nuclear power. Large military. Recurring political and security instability. Tense relations with India.",ua:"Ядерна держава. Велика армія. Нестабільність. Напружені відносини з Індією.",de:'Atommacht. Grosse Armee. Wiederkehrende politische und sicherheitspolitische Instabilitaet. Angespannte Beziehungen zu Indien.'},
PL:{fr:"Plus grande économie d'Europe de l'Est, 6e de l'UE. Armée parmi les plus puissantes d'Europe. Membre UE et OTAN.",en:"Largest Eastern European economy, 6th in EU. One of Europe's most powerful armies. EU and NATO member.",ua:"Найбільша економіка Східної Європи. Одна з найпотужніших армій. ЄС та НАТО.",de:'Groesste osteuropaeische Wirtschaft, 6. in der EU. Eine der staerksten Armeen Europas. EU- und NATO-Mitglied.'},
PT:{fr:"Économie développée mais parmi les moins riches d'Europe occidentale. Forte dépendance au tourisme. Membre fondateur de l'OTAN.",en:"Developed but among Western Europe's least wealthy. Strong tourism dependence. NATO founding member.",ua:"Розвинена, але менш заможна. Велика залежність від туризму. Засновник НАТО.",de:'Entwickelt, aber eines der weniger wohlhabenden westeuropaeischen Laender. Starke Tourismusabhaengigkeit. NATO-Gruendungsmitglied.'},
QA:{fr:"Un des plus riches per capita grâce au gaz. 3e réserves mondiales de gaz. A organisé la Coupe du Monde 2022.",en:"One of the world's richest per capita thanks to gas. 3rd largest gas reserves globally. Hosted the 2022 World Cup.",ua:"Одна з найбагатших завдяки газу. 3-ті запаси газу. ЧС-2022.",de:'Eines der reichsten Laender pro Kopf dank Gas. Drittgroesste Gasreserven weltweit. Gastgeber der WM 2022.'},
RO:{fr:"Économie en développement rapide dans l'UE. Producteur agricole et pétrolier. Forte émigration.",en:"Fast-developing EU economy. Agricultural and oil producer. High emigration.",ua:"Швидко зростаюча економіка в ЄС. Аграрний та нафтовий виробник. Масова еміграція.",de:'Schnell wachsende EU-Wirtschaft. Agrar- und Oelproduzent. Hohe Abwanderung.'},
RU:{fr:"2e arsenal nucléaire mondial. Membre permanent du Conseil de sécurité de l'ONU. Grand producteur de pétrole et gaz. Sous sanctions depuis 2022.",en:"World's 2nd nuclear arsenal. Permanent UN Security Council member. Major oil and gas producer. Under sanctions since 2022.",ua:"2-й ядерний арсенал. Постійний член РБ ООН. Нафта та газ. Санкції з 2022 р.",de:'Zweitgroesstes Atomwaffenarsenal der Welt. Staendiges Mitglied im UN-Sicherheitsrat. Grosser Oel- und Gasproduzent. Seit 2022 unter Sanktionen.'},
SA:{fr:"1er exportateur mondial de pétrole. Économie la plus grande du monde arabe. Armée puissante. Aucune démocratie.",en:"World's #1 oil exporter. Largest Arab economy. Powerful military. No democracy.",ua:"№1 експортер нафти. Найбільша арабська економіка. Потужна армія. Без демократії.",de:'Groesster Oelexporteur der Welt. Groesste arabische Wirtschaft. Starke Armee. Keine Demokratie.'},
SG:{fr:"Hub financier et commercial mondial malgré sa très petite superficie. Un des plus riches per capita. Port parmi les plus actifs.",en:"Global financial hub despite tiny size. One of the richest per capita. One of the world's busiest ports.",ua:"Глобальний фінансовий хаб. Один з найбагатших. Один з найактивніших портів.",de:'Globales Finanzzentrum trotz winziger Groesse. Eines der reichsten Laender pro Kopf. Einer der geschaeftigsten Haefen der Welt.'},
ZA:{fr:"Plus grande économie d'Afrique australe. Producteur d'or, platine et diamants. Très forte inégalité.",en:"Largest southern African economy. Gold, platinum and diamond producer. Very high inequality.",ua:"Найбільша економіка Південної Африки. Золото, платина, алмази. Висока нерівність.",de:'Groesste Wirtschaft des suedlichen Afrikas. Gold-, Platin- und Diamantenproduzent. Sehr hohe Ungleichheit.'},
ES:{fr:"4e économie de la zone euro. Grand producteur d'huile d'olive et de vin. Tourisme majeur. Chômage élevé.",en:"4th eurozone economy. Major olive oil and wine producer. Major tourism. High unemployment.",ua:"4-та економіка єврозони. Оливкова олія та вино. Великий туризм. Безробіття.",de:'4. Wirtschaft der Eurozone. Grosser Olivenoel- und Weinproduzent. Bedeutender Tourismus. Hohe Arbeitslosigkeit.'},
LK:{fr:"Grave crise financière en 2022. Grand producteur de thé. Dépendance au tourisme.",en:"Severe financial crisis in 2022. Major tea producer. Tourism dependent.",ua:"Фінансова криза 2022 р. Великий виробник чаю. Залежність від туризму.",de:'Schwere Finanzkrise 2022. Grosser Teeproduzent. Tourismusabhaengig.'},
SE:{fr:"Économie très développée. Marques mondiales (IKEA, H&M, Volvo). Très faible corruption. Entrée récente dans l'OTAN.",en:"Highly developed. Global brands (IKEA, H&M, Volvo). Very low corruption. Recently joined NATO.",ua:"Розвинена. Глобальні бренди (IKEA, H&M). Нещодавно в НАТО. Низька корупція.",de:'Hochentwickelt. Globale Marken (IKEA, H&M, Volvo). Sehr geringe Korruption. Kuerzlich der NATO beigetreten.'},
CH:{fr:"Parmi les plus riches per capita. Centre financier mondial. Sièges d'organisations internationales. Neutralité historique.",en:"Among the world's richest per capita. Global financial center. International organization HQs. Historic neutrality.",ua:"Серед найбагатших. Фінансовий центр. Штаб-квартири міжнародних організацій. Нейтралітет.",de:'Eines der reichsten Laender pro Kopf. Globales Finanzzentrum. Sitz internationaler Organisationen. Historische Neutralitaet.'},
SY:{fr:"Pays ravagé par la guerre civile depuis 2011. Économie en ruines. Sous sanctions internationales.",en:"Country ravaged by civil war since 2011. Economy in ruins. Under international sanctions.",ua:"Громадянська війна з 2011 р. Зруйнована економіка. Міжнародні санкції.",de:'Vom Buergerkrieg verwuestetes Land seit 2011. Wirtschaft in Truemmern. Unter internationalen Sanktionen.'},
TR:{fr:"G20. Armée parmi les plus grandes de l'OTAN. Inflation très élevée. Carrefour Europe-Asie. Exportateur textile et agricole.",en:"G20. One of NATO's largest armies. Very high inflation. Europe-Asia crossroads. Textile and agricultural exporter.",ua:"G20. Велика армія НАТО. Висока інфляція. Міст Європа-Азія.",de:'G20. Eine der groessten NATO-Armeen. Sehr hohe Inflation. Schnittpunkt Europa-Asien. Textil- und Agrarexporteur.'},
TM:{fr:"Grand producteur de gaz naturel (top 5). Régime très autoritaire. Économie quasi entièrement étatique.",en:"Major gas producer (top 5). Very authoritarian regime. Almost fully state-controlled economy.",ua:"Великий виробник газу (топ-5). Авторитарний режим. Державна економіка.",de:'Grosser Gasproduzent (Top 5). Sehr autoritaeres Regime. Fast vollstaendig staatlich kontrollierte Wirtschaft.'},
UA:{fr:"Économie en guerre depuis 2022. Grand exportateur de blé et d'acier. Armée en forte expansion.",en:"Economy at war since 2022. Major wheat and steel exporter. Rapidly expanding military.",ua:"Економіка у стані війни. Великий експортер зерна та сталі. Армія зростає.",de:'Kriegswirtschaft seit 2022. Grosser Weizen- und Stahlexporteur. Schnell wachsende Armee.'},
AE:{fr:"Hub financier et commercial mondial (Dubaï). Un des plus riches per capita. Économie diversifiée.",en:"Global financial and commercial hub (Dubai). One of the richest per capita. Diversified economy.",ua:"Глобальний хаб (Дубай). Одна з найбагатших. Диверсифікована економіка.",de:'Globales Finanz- und Handelszentrum (Dubai). Eines der reichsten Laender pro Kopf. Diversifizierte Wirtschaft.'},
GB:{fr:"5e ou 6e économie mondiale. Puissance nucléaire, membre permanent du Conseil de sécurité de l'ONU. Centre financier mondial (Londres). Brexit 2020.",en:"5th or 6th economy. Nuclear power, permanent UN Security Council member. Global financial center (London). Brexit 2020.",ua:"5-та або 6-та економіка. Ядерна держава, РБ ООН. Лондон — фінансовий центр. Brexit 2020.",de:'5. oder 6. Wirtschaft. Atommacht, staendiges Mitglied im UN-Sicherheitsrat. Globales Finanzzentrum (London). Brexit 2020.'},
US:{fr:"1ère économie mondiale. 1ère puissance militaire. Puissance nucléaire. Membre permanent du Conseil de sécurité de l'ONU. Dollar = monnaie de réserve mondiale.",en:"World's #1 economy. #1 military power. Nuclear power. Permanent UN Security Council member. Dollar is the global reserve currency.",ua:"№1 економіка. №1 військова сила. Ядерна держава. РБ ООН. Долар — світова резервна валюта.",de:'Groesste Wirtschaft der Welt. Staerkste Militaermacht. Atommacht. Staendiges Mitglied im UN-Sicherheitsrat. Dollar ist die globale Leitwaehrung.'},
UZ:{fr:"Grandes réserves de gaz et d'or. Régime autoritaire en transition. Grand exportateur de coton.",en:"Large gas and gold reserves. Authoritarian regime in transition. Major cotton exporter.",ua:"Газ та золото. Авторитарний режим. Великий експортер бавовни.",de:'Grosse Gas- und Goldreserven. Autoritaeres Regime im Wandel. Grosser Baumwollexporteur.'},
VE:{fr:"Plus grandes réserves prouvées de pétrole au monde. Grave crise économique et humanitaire. Régime autoritaire. Forte émigration.",en:"World's largest proven oil reserves. Severe economic and humanitarian crisis. Authoritarian regime. High emigration.",ua:"Найбільші запаси нафти. Криза. Авторитарний режим. Масова еміграція.",de:'Groesste nachgewiesene Oelreserven der Welt. Schwere wirtschaftliche und humanitaere Krise. Autoritaeres Regime. Hohe Abwanderung.'},
VN:{fr:"Économie émergente à forte croissance. Ancien pays communiste ouvert depuis les années 1990. Grand producteur de riz et de café.",en:"Fast-growing emerging economy. Former communist country opened since 1990s. Major rice and coffee producer.",ua:"Швидке зростання. Колишній комунізм, відкрита торгівля з 1990-х. Рис та кава.",de:'Schnell wachsende Schwellenwirtschaft. Ehemals kommunistisches Land, seit den 1990ern geoeffnet. Grosser Reis- und Kaffeeproduzent.'},
ZM:{fr:"Grand producteur de cuivre (top mondial). Économie très dépendante du cours du cuivre.",en:"Major copper producer (global top). Economy highly dependent on copper prices.",ua:"Великий виробник міді. Залежність від ціни міді.",de:'Grosser Kupferproduzent (weltweit fuehrend). Wirtschaft stark von Kupferpreisen abhaengig.'},
ZW:{fr:"Économie instable, connue pour son hyperinflation historique. Riches ressources minières (platine, diamants, or).",en:"Unstable economy, known for historic hyperinflation. Rich mineral resources (platinum, diamonds, gold).",ua:"Нестабільна економіка та гіперінфляція. Платина, алмази, золото.",de:'Instabile Wirtschaft, bekannt fuer historische Hyperinflation. Reiche Bodenschaetze (Platin, Diamanten, Gold).'},
EC:{fr:"Membre de l'OPEP. Producteur de pétrole et grand exportateur de bananes. Économie dollarisée.",en:"OPEC member. Oil producer and major banana exporter. Dollarized economy.",ua:"ОПЕК. Нафта та банани. Доларизована економіка.",de:'OPEC-Mitglied. Oelproduzent und grosser Bananenexporteur. Dollarisierte Wirtschaft.'},
PE:{fr:"Producteur majeur de cuivre, d'or et d'argent. Économie en développement rapide. Inégalités élevées.",en:"Major copper, gold and silver producer. Fast-developing economy. High inequality.",ua:"Мідь, золото, срібло. Швидко зростає. Висока нерівність.",de:'Grosser Kupfer-, Gold- und Silberproduzent. Schnell wachsende Wirtschaft. Hohe Ungleichheit.'},
PH:{fr:"Économie émergente à forte croissance. Exportateur de travailleurs à l'étranger. Hub d'outsourcing. Catastrophes naturelles fréquentes.",en:"Fast-growing emerging economy. Major overseas worker exporter. Outsourcing hub. Frequent natural disasters.",ua:"Зростаюча економіка. Велика трудова еміграція. Аутсорсинг. Стихійні лиха.",de:'Schnell wachsende Schwellenwirtschaft. Grosser Exporteur von Arbeitskraeften. Outsourcing-Zentrum. Haeufige Naturkatastrophen.'},
GT:{fr:"Plus grande économie d'Amérique centrale. Importantes inégalités. Exportateur de café, bananes et sucre.",en:"Largest Central American economy. Major inequalities. Coffee, banana and sugar exporter.",ua:"Найбільша економіка Центральної Америки. Нерівність. Кава та банани.",de:'Groesste zentralamerikanische Wirtschaft. Grosse Ungleichheit. Kaffee-, Bananen- und Zuckerexporteur.'},
PY:{fr:"Économie agricole. Grand producteur de soja et d'énergie hydroélectrique (Itaipu).",en:"Agricultural economy. Major soybean and hydroelectric power producer (Itaipu).",ua:"Сільськогосподарська. Соя та гідроенергія (Ітайпу).",de:'Agrarwirtschaft. Grosser Soja- und Wasserkraftproduzent (Itaipu).'},
CM:{fr:"Économie la plus diversifiée d'Afrique centrale. Producteur de pétrole, cacao et café.",en:"Most diversified Central African economy. Oil, cocoa and coffee producer.",ua:"Найдиверсифікованіша у Центральній Африці. Нафта, какао, кава.",de:'Am staerksten diversifizierte Wirtschaft Zentralafrikas. Oel-, Kakao- und Kaffeeproduzent.'},
TN:{fr:"Économie émergente, la plus développée du Maghreb après le Maroc. Tourisme important. Crise politique depuis 2011.",en:"Emerging economy, most developed in Maghreb after Morocco. Important tourism. Political crisis since 2011.",ua:"Найрозвиненіший Магриб після Марокко. Туризм. Криза з 2011 р.",de:'Schwellenwirtschaft, nach Marokko am weitesten entwickelt im Maghreb. Bedeutender Tourismus. Politische Krise seit 2011.'},
SN:{fr:"Hub régional d'Afrique de l'Ouest. Économie stable et diversifiée. Siège de nombreuses ONG.",en:"West Africa's regional hub. Stable, diversified economy. HQ of many NGOs.",ua:"Регіональний хаб Африки. Стабільна економіка. Штаб-квартири НУО.",de:'Regionales Zentrum Westafrikas. Stabile, diversifizierte Wirtschaft. Sitz vieler NGOs.'},
MG:{fr:"Biodiversité unique au monde. Économie pauvre, dépendante de l'agriculture. Vanille de haute qualité.",en:"Unique worldwide biodiversity. Poor, agriculture-dependent economy. High-quality vanilla.",ua:"Унікальне біорізноманіття. Бідна. Якісна ваніль.",de:'Weltweit einzigartige Biodiversitaet. Arme, landwirtschaftsabhaengige Wirtschaft. Hochwertige Vanille.'},
ML:{fr:"Grande richesse culturelle (Tombouctou). Insécurité liée aux groupes armés au nord. Parmi les plus pauvres.",en:"Rich cultural heritage (Timbuktu). Armed groups in the north. Among the world's poorest.",ua:"Томбукту. Збройні групи на півночі. Серед найбідніших.",de:'Reiches kulturelles Erbe (Timbuktu). Bewaffnete Gruppen im Norden. Eines der aermsten Laender der Welt.'},
NE:{fr:"Un des plus pauvres du monde. Grandes réserves d'uranium. Défis climatiques majeurs (désertification).",en:"One of the world's poorest. Large uranium reserves. Major climate challenges (desertification).",ua:"Серед найбідніших. Уран. Серйозна посуха та спустелення.",de:'Eines der aermsten Laender der Welt. Grosse Uranreserven. Grosse Klimaherausforderungen (Wuestenbildung).'},
AO:{fr:"Grand producteur de pétrole et de diamants. Malgré les ressources, grande pauvreté. Économie post-guerre civile.",en:"Major oil and diamond producer. Despite resources, widespread poverty. Post-civil war economy.",ua:"Нафта та алмази. Попри ресурси — бідність. Після громадянської війни.",de:'Grosser Oel- und Diamantenproduzent. Trotz Ressourcen verbreitete Armut. Nachkriegswirtschaft.'},
OM:{fr:"Producteur de pétrole modéré. Régime stable et diplomatie équilibrée dans le Golfe. Diversification économique.",en:"Moderate oil producer. Stable regime and balanced diplomacy in the Gulf. Economic diversification.",ua:"Помірний виробник нафти. Стабільний режим. Збалансована дипломатія.",de:'Maessiger Oelproduzent. Stabiles Regime und ausgewogene Diplomatie im Golf. Wirtschaftliche Diversifizierung.'},
KG:{fr:"Parmi les plus pauvres d'Asie centrale. Dépendant des transferts de la diaspora. Ressources hydrauliques importantes.",en:"Among the poorest in Central Asia. Dependent on diaspora remittances. Important water resources.",ua:"Серед найбідніших у Центральній Азії. Переказ грошей. Водні ресурси.",de:'Eines der aermsten Laender Zentralasiens. Abhaengig von Ueberweisungen der Diaspora. Wichtige Wasserressourcen.'},
GE:{fr:"Économie en développement, réformes importantes. Hub touristique du Caucase. Conflits territoriaux avec la Russie.",en:"Developing economy with major reforms. Caucasus tourist hub. Territorial conflicts with Russia.",ua:"Реформована економіка. Туристичний хаб Кавказу. Конфлікти з Росією.",de:'Sich entwickelnde Wirtschaft mit grossen Reformen. Tourismuszentrum im Kaukasus. Territorialkonflikte mit Russland.'},
BI:{fr:"Parmi les plus pauvres du monde. Instabilité politique récurrente. Agriculture de subsistance.",en:"Among the world's poorest. Recurring political instability. Subsistence agriculture.",ua:"Серед найбідніших. Нестабільність. Натуральне господарство.",de:'Eines der aermsten Laender der Welt. Wiederkehrende politische Instabilitaet. Subsistenzlandwirtschaft.'},
BY:{fr:"Régime autoritaire proche de la Russie. Économie planifiée. Sous sanctions depuis 2020.",en:"Authoritarian regime aligned with Russia. Planned economy. Under sanctions since 2020.",ua:"Авторитарний режим, пов'язаний з Росією. Планова. Санкції з 2020.",de:'Autoritaeres Regime eng mit Russland verbunden. Planwirtschaft. Seit 2020 unter Sanktionen.'},
UY:{fr:'Économie la plus stable et équitable d\'Amérique du Sud. Très faible corruption. État providence fort. Grand exportateur agricole (viande, soja, laine).',en:'South America\'s most stable and equal economy. Very low corruption. Strong welfare state. Major agricultural exporter (beef, soybeans, wool).',ua:'Найстабільніша економіка Південної Америки. Низька корупція. Сильна соціальна держава. Агроекспорт.',de:'Stabilste und gerechteste Wirtschaft Suedamerikas. Sehr geringe Korruption. Starker Sozialstaat. Grosser Agrarexporteur (Rindfleisch, Soja, Wolle).'},
LT:{fr:'Économie la plus développée des trois États baltes. Hub technologique et financier régional. Membre UE et OTAN depuis 2004. Très bon niveau d\'éducation.',en:'Most developed of the three Baltic states. Regional tech and financial hub. EU and NATO member since 2004. High education level.',ua:'Найрозвиненіша з трьох балтійських держав. Технологічний та фінансовий хаб. ЄС та НАТО з 2004 р.',de:'Am weitesten entwickelter der drei baltischen Staaten. Regionales Tech- und Finanzzentrum. EU- und NATO-Mitglied seit 2004. Hohes Bildungsniveau.'},
SI:{fr:'Économie la plus développée des Balkans, proche du niveau d\'Europe occidentale. Fort secteur industriel. Tourisme alpin important. Membre UE et OTAN depuis 2004.',en:'Most developed Balkan economy, close to Western European levels. Strong industrial sector. Important Alpine tourism. EU and NATO member since 2004.',ua:'Найрозвиненіша балканська економіка. Сильний промисловий сектор. Гірський туризм. ЄС та НАТО з 2004 р.',de:'Am weitesten entwickelte Balkanwirtschaft, nahe westeuropaeischem Niveau. Starker Industriesektor. Bedeutender Alpentourismus. EU- und NATO-Mitglied seit 2004.'},
MN:{fr:'Économie dépendante des ressources minières (charbon, cuivre, or). Régime démocratique entre deux grandes puissances. Nomadisme encore présent. Très faible densité de population.',en:'Economy dependent on mining (coal, copper, gold). Democratic regime between two superpowers. Nomadism still present. Very low population density.',ua:'Залежна від видобутку корисних копалин. Демократія між двома наддержавами. Номадизм. Дуже мала густота населення.',de:'Wirtschaft abhaengig vom Bergbau (Kohle, Kupfer, Gold). Demokratisches Regime zwischen zwei Supermaechten. Nomadentum noch vorhanden. Sehr geringe Bevoelkerungsdichte.'},
TH:{fr:'2e économie d\'Asie du Sud-Est. Hub touristique majeur et mondial. Grand exportateur de riz, caoutchouc et produits électroniques. Régimes militaires fréquents.',en:'2nd largest Southeast Asian economy. Major global tourism hub. Large rice, rubber and electronics exporter. Frequent military coups.',ua:'2-га економіка Південно-Східної Азії. Великий туристичний хаб. Рис, гума, електроніка. Часті перевороти.',de:'2. groesste Wirtschaft Suedostasiens. Globales Tourismuszentrum. Grosser Reis-, Kautschuk- und Elektronikexporteur. Haeufige Militaerputsche.'},
HR:{fr:'Membre de l\'UE depuis 2013, de l\'OTAN depuis 2009. Tourisme majeur sur l\'Adriatique. Économie post-guerre en développement continu. Zone euro depuis 2023.',en:'EU member since 2013, NATO since 2009. Major Adriatic tourism. Post-war economy in continuous development. Eurozone since 2023.',ua:'ЄС з 2013, НАТО з 2009. Туризм на Адріатиці. Постконфліктна економіка. Єврозона з 2023 р.',de:'EU-Mitglied seit 2013, NATO seit 2009. Bedeutender Adriatourismus. Nachkriegswirtschaft in stetiger Entwicklung. Eurozone seit 2023.'},
LV:{fr:'Hub financier et logistique de la région baltique. Économie ouverte et très exportatrice. Forte émigration depuis 2004. Membre UE et OTAN.',en:'Financial and logistics hub of the Baltic region. Open, highly export-oriented economy. High emigration since 2004. EU and NATO member.',ua:'Фінансовий та логістичний хаб Балтії. Висока еміграція з 2004 р. ЄС та НАТО.',de:'Finanz- und Logistikzentrum der baltischen Region. Offene, stark exportorientierte Wirtschaft. Hohe Abwanderung seit 2004. EU- und NATO-Mitglied.'},
RS:{fr:'Candidate à l\'UE. Économie en développement, ancienne économie communiste. Tensions régionales avec le Kosovo. Important producteur agricole.',en:'EU candidate. Developing economy, former communist. Regional tensions with Kosovo. Important agricultural producer.',ua:'Кандидат в ЄС. Економіка розвивається. Напруга з Косово. Аграрний виробник.',de:'EU-Kandidat. Sich entwickelnde Wirtschaft, ehemals kommunistisch. Regionale Spannungen mit dem Kosovo. Bedeutender Agrarproduzent.'},
EE:{fr:'Surnommée \'République numérique\'. Gouvernement en ligne pionnier (e-résidence). Économie très développée pour la région baltique. Très faible corruption.',en:'Nicknamed \'Digital Republic\'. Pioneer of online government (e-residency). Highly developed economy for the Baltic region. Very low corruption.',ua:'\'Цифрова республіка\'. Піонер е-уряду. Розвинена економіка. Дуже низька корупція.',de:'Als \u00abDigitale Republik\u00bb bekannt. Pionier der Online-Verwaltung (e-Residency). Hochentwickelte Wirtschaft fuer die baltische Region. Sehr geringe Korruption.'},
MD:{fr:'L\'un des pays les plus pauvres d\'Europe. Très dépendant des transferts de la diaspora. Importante production vinicole. Conflit gelé en Transnistrie.',en:'One of Europe\'s poorest countries. Highly dependent on diaspora remittances. Important wine production. Frozen conflict in Transnistria.',ua:'Одна з найбідніших в Європі. Залежність від переказів діаспори. Вино. Заморожений конфлікт у Придністров\'ї.',de:'Eines der aermsten Laender Europas. Stark abhaengig von Ueberweisungen der Diaspora. Bedeutende Weinproduktion. Eingefrorener Konflikt in Transnistrien.'},
IS:{fr:'Économie très développée basée sur la géothermie, la pêche et le tourisme. Quasiment 100% d\'énergie renouvelable. Très faible corruption. Armée inexistante.',en:'Highly developed economy based on geothermal energy, fishing and tourism. Nearly 100% renewable energy. Very low corruption. No standing army.',ua:'Геотермальна енергія, рибальство, туризм. Майже 100% відновлювана енергетика. Без армії. Дуже низька корупція.',de:'Hochentwickelte Wirtschaft basierend auf Geothermie, Fischerei und Tourismus. Fast 100 % erneuerbare Energie. Sehr geringe Korruption. Keine stehende Armee.'},
MU:{fr:'Hub financier et touristique de l\'océan Indien. Économie parmi les plus développées d\'Afrique. Faible corruption, bonne gouvernance. Forte diaspora indienne.',en:'Financial and tourism hub of the Indian Ocean. One of Africa\'s most developed economies. Low corruption, good governance. Large Indian diaspora.',ua:'Фінансовий хаб Індійського океану. Одна з найрозвиненіших в Африці. Низька корупція. Велика індійська діаспора.',de:'Finanz- und Tourismuszentrum des Indischen Ozeans. Eine der am weitesten entwickelten Wirtschaften Afrikas. Geringe Korruption, gute Regierungsfuehrung. Grosse indische Diaspora.'},
SK:{fr:'Économie industrielle intégrée dans l\'UE (depuis 2004). Grand producteur d\'automobiles per capita. Zone euro depuis 2009. Faible corruption régionale.',en:'Industrial economy integrated into EU (since 2004). Major car producer per capita. Eurozone since 2009. Low regional corruption.',ua:'Промислова економіка в ЄС. Великий виробник авто на душу населення. Єврозона з 2009 р.',de:'In die EU integrierte Industriewirtschaft (seit 2004). Grosser Autoproduzent pro Kopf. Eurozone seit 2009. Geringe regionale Korruption.'},
LU:{fr:'2e PIB per capita mondial. Capitale financière de l\'UE. Siège de nombreuses institutions européennes. Très faible corruption. Hub d\'investissement mondial.',en:'2nd highest GDP per capita globally. EU\'s financial capital. Seat of many EU institutions. Very low corruption. Global investment hub.',ua:'2-й ВВП на душу в світі. Фінансова столиця ЄС. Штаб-квартири інститутів ЄС. Дуже низька корупція.',de:'2. hoechstes BIP pro Kopf weltweit. Finanzhauptstadt der EU. Sitz vieler EU-Institutionen. Sehr geringe Korruption. Globales Investitionszentrum.'},
CR:{fr:'Seul pays d\'Amérique latine sans armée (abolie en 1949). Fort éco-tourisme. Économie de services en développement rapide. Énergie quasi 100% renouvelable.',en:'Only Latin American country with no army (abolished 1949). Strong eco-tourism. Fast-growing service economy. Nearly 100% renewable energy.',ua:'Єдина латиноамериканська країна без армії (скасована 1949). Екотуризм. Майже 100% відновлювана енергія.',de:'Einziges lateinamerikanisches Land ohne Armee (abgeschafft 1949). Starker Oekotourismus. Schnell wachsende Dienstleistungswirtschaft. Fast 100 % erneuerbare Energie.'},
SV:{fr:'Économie dollarisée (dollar US). Premier pays à adopter le Bitcoin comme monnaie légale (2021). Problèmes récurrents de gangs et violence. Maquiladoras.',en:'Dollarized economy. First country to adopt Bitcoin as legal tender (2021). Recurring gang and violence problems. Maquiladoras.',ua:'Доларизована економіка. Перша країна з біткоїном як законним платіжним засобом (2021). Проблеми з бандами.',de:'Dollarisierte Wirtschaft. Erstes Land mit Bitcoin als Zahlungsmittel (2021). Wiederkehrende Banden- und Gewaltprobleme. Maquiladoras.'},
MT:{fr:'Hub financier et touristique de la Méditerranée. Économie très développée pour sa taille. Siège de nombreuses sociétés de jeux en ligne. Membre UE (2004).',en:'Mediterranean financial and tourism hub. Highly developed economy for its size. HQ of many online gaming companies. EU member (2004).',ua:'Фінансовий хаб Середземномор\'я. Розвинена для своїх розмірів. Онлайн-гемблінг. ЄС з 2004 р.',de:'Mediterranes Finanz- und Tourismuszentrum. Hochentwickelte Wirtschaft fuer seine Groesse. Sitz vieler Online-Gaming-Unternehmen. EU-Mitglied (2004).'},
MY:{fr:'Économie émergente avancée d\'Asie du Sud-Est. Grand exportateur de semi-conducteurs, d\'huile de palme et de caoutchouc. Pétrole via Petronas. Pays à revenus intermédiaires supérieurs.',en:'Advanced emerging economy in Southeast Asia. Major semiconductor, palm oil and rubber exporter. Oil via Petronas. Upper-middle-income country.',ua:'Розвинена ринкова економіка. Напівпровідники, пальмова олія, каучук. Petronas (нафта).',de:'Fortgeschrittene Schwellenwirtschaft in Suedostasien. Grosser Halbleiter-, Palmoel- und Kautschukexporteur. Oel ueber Petronas. Land mit gehobenem mittlerem Einkommen.'},
KH:{fr:'Économie à forte croissance basée sur le textile et le tourisme (Angkor Vat). Régime semi-autoritaire. Très dépendant de l\'aide internationale. Séquelles des Khmers rouges.',en:'Fast-growing economy based on textiles and tourism (Angkor Wat). Semi-authoritarian regime. Highly dependent on international aid. Lingering effects of the Khmer Rouge.',ua:'Швидке зростання: текстиль та туризм (Ангкор Ват). Напівавторитарний режим. Спадщина Червоних кхмерів.',de:'Schnell wachsende Wirtschaft basierend auf Textilien und Tourismus (Angkor Wat). Semi-autoritaeres Regime. Stark abhaengig von internationaler Hilfe. Nachwirkungen der Roten Khmer.'},
DO:{fr:'Plus grande économie des Caraïbes. Fort tourisme (Punta Cana). Exportateur de cigares et de cacao. Inégalités importantes. Forte dépendance aux transferts de la diaspora.',en:'Largest Caribbean economy. Strong tourism (Punta Cana). Cigar and cocoa exporter. High inequality. Strong dependence on diaspora transfers.',ua:'Найбільша економіка Карибів. Туризм (Пунта-Кана). Сигари та какао. Нерівність.',de:'Groesste karibische Wirtschaft. Starker Tourismus (Punta Cana). Zigarren- und Kakaoexporteur. Hohe Ungleichheit. Starke Abhaengigkeit von Diaspora-Ueberweisungen.'},
PA:{fr:'Canal de Panama = revenu stratégique et transit mondial. Hub financier offshore. Économie très dollarisée. Fort secteur des services et de la logistique.',en:'Panama Canal = strategic revenue and global transit. Offshore financial hub. Highly dollarized economy. Strong services and logistics sector.',ua:'Панамський канал. Офшорний фінансовий хаб. Доларизована. Логістика та послуги.',de:'Panamakanal = strategische Einnahmen und globaler Transit. Offshore-Finanzzentrum. Stark dollarisierte Wirtschaft. Starker Dienstleistungs- und Logistiksektor.'},
CY:{fr:'Hub financier méditerranéen (et offshore). Membre de l\'UE depuis 2004. Île divisée entre la République de Chypre (sud) et la zone turque (nord). Tourisme majeur.',en:'Mediterranean (and offshore) financial hub. EU member since 2004. Island divided between the Republic of Cyprus (south) and Turkish zone (north). Major tourism.',ua:'Фінансовий хаб. ЄС з 2004. Острів розділений між Республікою та турецькою зоною. Туризм.',de:'Mediterranes (und Offshore-)Finanzzentrum. EU-Mitglied seit 2004. Insel geteilt zwischen Republik Zypern (Sueden) und tuerkischer Zone (Norden). Bedeutender Tourismus.'},
AL:{fr:'Économie parmi les moins développées d\'Europe. Candidate à l\'UE. Forte émigration. Tourisme en forte croissance. Réformes anti-corruption en cours.',en:'One of Europe\'s least developed economies. EU candidate. High emigration. Fast-growing tourism. Ongoing anti-corruption reforms.',ua:'Одна з найменш розвинених в Європі. Кандидат ЄС. Висока еміграція. Туризм зростає.',de:'Eine der am wenigsten entwickelten Wirtschaften Europas. EU-Kandidat. Hohe Abwanderung. Schnell wachsender Tourismus. Laufende Antikorruptionsreformen.'},
JM:{fr:'Économie basée sur le tourisme, la bauxite et l\'agriculture (café, sucre). Forte diaspora mondiale. Centre culturel (reggae, Bob Marley). Criminalité élevée.',en:'Economy based on tourism, bauxite and agriculture (coffee, sugar). Large global diaspora. Cultural center (reggae, Bob Marley). High crime.',ua:'Туризм, боксит, сільське господарство. Велика діаспора. Культурний центр (регі, Боб Марлі). Висока злочинність.',de:'Wirtschaft basierend auf Tourismus, Bauxit und Landwirtschaft (Kaffee, Zucker). Grosse globale Diaspora. Kulturzentrum (Reggae, Bob Marley). Hohe Kriminalitaet.'},
LB:{fr:'Économie effondrée depuis 2019 (l\'une des pires crises financières de l\'histoire moderne). Ancienne \'Suisse du Moyen-Orient\'. Reconstruction très difficile. Forte diaspora.',en:'Economy collapsed since 2019 (one of the worst financial crises in modern history). Former \'Switzerland of the Middle East\'. Very difficult reconstruction. Large diaspora.',ua:'Економіка в колапсі з 2019 р. Колишня \'Швейцарія Близького Сходу\'. Велика діаспора. Криза.',de:'Wirtschaft zusammengebrochen seit 2019 (eine der schlimmsten Finanzkrisen der Geschichte). Ehemals \u00abSchweiz des Nahen Ostens\u00bb. Sehr schwieriger Wiederaufbau. Grosse Diaspora.'},
LS:{fr:'Enclave pauvre dans l\'Afrique du Sud. Économie très dépendante des transferts de travailleurs miniers en RSA. Textile en développement. Très fort taux de VIH/SIDA.',en:'Poor enclave within South Africa. Economy highly dependent on remittances from miners in SA. Growing textile sector. Very high HIV/AIDS rate.',ua:'Бідна анклав у ПАР. Перекази від шахтарів. Текстиль. Дуже високий рівень ВІЛ/СНІДу.',de:'Arme Enklave in Suedafrika. Wirtschaft stark abhaengig von Ueberweisungen der Minenarbeiter in SA. Wachsender Textilsektor. Sehr hohe HIV/AIDS-Rate.'},
SZ:{fr:'Petite monarchie absolue d\'Afrique australe. Économie très dépendante de l\'Afrique du Sud. Fort taux de VIH/SIDA au monde. Industrie textile pour l\'export.',en:'Small absolute monarchy in southern Africa. Economy highly dependent on South Africa. One of the world\'s highest HIV/AIDS rates. Textile industry for export.',ua:'Абсолютна монархія. Залежить від ПАР. Найвищий рівень ВІЛ у світі. Текстиль.',de:'Kleine absolute Monarchie im suedlichen Afrika. Wirtschaft stark von Suedafrika abhaengig. Eine der hoechsten HIV/AIDS-Raten der Welt. Textilindustrie fuer den Export.'},
GY:{fr:'Récentes découvertes pétrolières offshore majeures (depuis 2015) qui transforment l\'économie. Anciennement dépendant de la bauxite et du sucre. Très faible densité.',en:'Major recent offshore oil discoveries (since 2015) transforming the economy. Formerly dependent on bauxite and sugar. Very low population density.',ua:'Великі нафтові відкриття з 2015 р. Раніше — боксит та цукор. Дуже мала густота населення.',de:'Grosse juengste Offshore-Oelfunde (seit 2015) transformieren die Wirtschaft. Frueher abhaengig von Bauxit und Zucker. Sehr geringe Bevoelkerungsdichte.'},
VU:{fr:'Économie basée sur l\'agriculture, la pêche et le tourisme. Paradis fiscal et offshore. Très vulnérable aux cyclones et catastrophes naturelles. Peu développé.',en:'Economy based on agriculture, fishing and tourism. Tax haven and offshore center. Highly vulnerable to cyclones and natural disasters. Underdeveloped.',ua:'Сільське господарство, рибальство, туризм. Офшорна зона. Вразлива до циклонів.',de:'Wirtschaft basierend auf Landwirtschaft, Fischerei und Tourismus. Steueroase und Offshore-Zentrum. Sehr anfaellig fuer Zyklone und Naturkatastrophen. Unterentwickelt.'},
TT:{fr:'Économie basée sur le pétrole et le gaz naturel (réserves importantes). L\'une des plus riches des Caraïbes per capita. Berceau du calypso et du steel pan.',en:'Economy based on oil and natural gas (significant reserves). One of the richest in the Caribbean per capita. Birthplace of calypso and steel pan music.',ua:'Нафта та природний газ. Одна з найбагатших у Карибах за ВВП на душу. Батьківщина каліпсо.',de:'Wirtschaft basierend auf Oel und Erdgas (bedeutende Reserven). Eines der reichsten karibischen Laender pro Kopf. Geburtsort von Calypso und Steelpan-Musik.'},
ME:{fr:'Candidate à l\'UE. Membre de l\'OTAN depuis 2017. Économie basée sur le tourisme adriatique et les investissements étrangers. Ancienne partie de la Yougoslavie.',en:'EU candidate. NATO member since 2017. Economy based on Adriatic tourism and foreign investment. Former part of Yugoslavia.',ua:'Кандидат ЄС. НАТО з 2017. Туризм та іноземні інвестиції. Колишня частина Югославії.',de:'EU-Kandidat. NATO-Mitglied seit 2017. Wirtschaft basierend auf Adriatourismus und Auslandsinvestitionen. Ehemaliger Teil Jugoslawiens.'},
NA:{fr:'Grand producteur de diamants et d\'uranium. Économie minière importante. Très faible densité de population. Forte inégalité héritée de l\'apartheid namibien.',en:'Major diamond and uranium producer. Important mining economy. Very low population density. High inequality inherited from Namibian apartheid.',ua:'Алмази та уран. Гірничодобувна економіка. Висока нерівність, спадщина апартеїду.',de:'Grosser Diamanten- und Uranproduzent. Bedeutende Bergbauwirtschaft. Sehr geringe Bevoelkerungsdichte. Hohe Ungleichheit als Erbe der namibischen Apartheid.'},
BW:{fr:'Succès économique remarquable d\'Afrique australe grâce aux diamants (Debswana). L\'une des plus faibles corruptions d\'Afrique. Fort taux de VIH mais bonne réponse sanitaire.',en:'Remarkable economic success in southern Africa thanks to diamonds (Debswana). One of Africa\'s lowest corruption levels. High HIV rate but good health response.',ua:'Успіх завдяки алмазам (Debswana). Низька корупція в Африці. Висока поширеність ВІЛ.',de:'Bemerkenswerter wirtschaftlicher Erfolg im suedlichen Afrika dank Diamanten (Debswana). Eines der niedrigsten Korruptionsniveaus Afrikas. Hohe HIV-Rate, aber gute Gesundheitsversorgung.'},
HT:{fr:'L\'un des pays les plus pauvres de l\'hémisphère occidental. Instabilité politique chronique. Séisme dévastateur de 2010. Forte dépendance à l\'aide internationale.',en:'One of the poorest countries in the Western Hemisphere. Chronic political instability. Devastating 2010 earthquake. Highly dependent on international aid.',ua:'Одна з найбідніших країн Заходу. Хронічна нестабільність. Землетрус 2010 р. Залежність від допомоги.',de:'Eines der aermsten Laender der westlichen Hemisphaere. Chronische politische Instabilitaet. Verheerendes Erdbeben 2010. Stark abhaengig von internationaler Hilfe.'},
MW:{fr:'Parmi les pays les plus pauvres du monde. Économie agricole (tabac, thé, sucre). Fort taux de VIH. Peu de ressources naturelles exploitées.',en:'Among the world\'s poorest countries. Agricultural economy (tobacco, tea, sugar). High HIV rate. Few exploited natural resources.',ua:'Серед найбідніших. Аграрна (тютюн, чай, цукор). Висока поширеність ВІЛ. Мало ресурсів.',de:'Eines der aermsten Laender der Welt. Agrarwirtschaft (Tabak, Tee, Zucker). Hohe HIV-Rate. Wenig genutzte Bodenschaetze.'},
CI:{fr:'Plus grande économie d\'Afrique de l\'Ouest francophone. 1er producteur mondial de cacao. Croissance économique rapide. Ancienne instabilité politique post-guerre civile.',en:'Largest economy in francophone West Africa. World\'s #1 cocoa producer. Fast economic growth. Past political instability after civil war.',ua:'Найбільша франкомовна економіка Африки. №1 виробник какао. Швидке зростання.',de:'Groesste Wirtschaft im frankophonen Westafrika. Weltweit groesster Kakaoproduzent. Schnelles Wirtschaftswachstum. Vergangene politische Instabilitaet nach Buergerkrieg.'},
BJ:{fr:'Économie agricole pauvre (coton, noix de cajou). Havre de stabilité relative en Afrique de l\'Ouest. Berceau du vaudou africain. Peu de ressources naturelles.',en:'Poor agricultural economy (cotton, cashews). Oasis of relative stability in West Africa. Birthplace of African voodoo. Few natural resources.',ua:'Бідна аграрна (бавовна, кеш\'ю). Відносна стабільність у Західній Африці. Батьківщина вуду.',de:'Arme Agrarwirtschaft (Baumwolle, Cashews). Oase relativer Stabilitaet in Westafrika. Geburtsort des afrikanischen Voodoo. Wenige Bodenschaetze.'},
SL:{fr:'Parmi les pays les plus pauvres. Dévasté par une longue guerre civile. Grand producteur de diamants (mais \'diamants du sang\'). Reconstruction lente.',en:'Among the world\'s poorest. Devastated by a long civil war. Major diamond producer (but \'blood diamonds\'). Slow reconstruction.',ua:'Серед найбідніших. Розорена громадянською війною. Алмази (\'криваві\'). Повільна відбудова.',de:'Eines der aermsten Laender der Welt. Verwuestet durch langen Buergerkrieg. Grosser Diamantenproduzent (aber \u00abBlutdiamanten\u00bb). Langsamer Wiederaufbau.'},
KM:{fr:'Très pauvre archipel. Instabilité politique extrême (plus de 20 coups d\'État ou tentatives depuis l\'indépendance). Forte émigration vers la France.',en:'Very poor archipelago. Extreme political instability (over 20 coups or attempts since independence). High emigration to France.',ua:'Дуже бідний архіпелаг. Понад 20 переворотів. Велика еміграція до Франції.',de:'Sehr armer Archipel. Extreme politische Instabilitaet (ueber 20 Putsche oder Versuche seit der Unabhaengigkeit). Hohe Auswanderung nach Frankreich.'},
MK:{fr:'Candidate à l\'UE, membre de l\'OTAN depuis 2020. Différend long résolu avec la Grèce sur le nom (ex-ARYM). Économie en développement lent.',en:'EU candidate, NATO member since 2020. Long dispute resolved with Greece over the name (formerly FYROM). Slowly developing economy.',ua:'Кандидат ЄС, НАТО з 2020. Тривала суперечка з Грецією про назву. Повільний розвиток.',de:'EU-Kandidat, NATO-Mitglied seit 2020. Langer Namensstreit mit Griechenland geloest (ehemals FYROM). Langsam wachsende Wirtschaft.'},
TD:{fr:'Parmi les pays les plus pauvres et fragiles. Importante production pétrolière mais bénéfices mal redistribués. Conflits armés récurrents au nord. Très peu développé.',en:'Among the poorest and most fragile countries. Significant oil production but poorly redistributed benefits. Recurring armed conflicts in the north. Very underdeveloped.',ua:'Серед найбідніших. Нафта, але погано розподілена. Збройні конфлікти на півночі.',de:'Eines der aermsten und fragilsten Laender. Bedeutende Oelproduktion, aber schlecht umverteilte Ertraege. Wiederkehrende bewaffnete Konflikte im Norden. Sehr unterentwickelt.'},
GM:{fr:'L\'une des économies les plus petites d\'Afrique. Forte dépendance au tourisme et aux transferts de la diaspora. Exportateur d\'arachides. Ancienne dictature.',en:'One of Africa\'s smallest economies. High dependence on tourism and diaspora remittances. Groundnut exporter. Former dictatorship.',ua:'Одна з найменших економік Африки. Туризм та перекази. Арахіс. Колишня диктатура.',de:'Eine der kleinsten Wirtschaften Afrikas. Hohe Abhaengigkeit von Tourismus und Diaspora-Ueberweisungen. Erdnussexporteur. Ehemalige Diktatur.'},
TO:{fr:'Seul royaume polynésien. Économie basée sur l\'agriculture, la pêche et les transferts de la diaspora. Très vulnérable aux cyclones et montée des eaux.',en:'The only Polynesian kingdom. Economy based on agriculture, fishing and diaspora remittances. Highly vulnerable to cyclones and rising sea levels.',ua:'Єдине полінезійське королівство. Сільське господарство та рибальство. Вразливе до підняття рівня моря.',de:'Das einzige polynesische Koenigreich. Wirtschaft basierend auf Landwirtschaft, Fischerei und Diaspora-Ueberweisungen. Sehr anfaellig fuer Zyklone und steigende Meeresspiegel.'},
BH:{fr:'Petit État du Golfe en diversification économique (finance, tourisme, F1). Moins riche en pétrole que ses voisins. Tensions politiques liées à la majorité chiite.',en:'Small Gulf state diversifying economy (finance, tourism, F1). Less oil-rich than its neighbors. Political tensions linked to the Shia majority.',ua:'Диверсифікація (фінанси, туризм, Ф-1). Менше нафти, ніж у сусідів. Шиїтська напруга.',de:'Kleiner Golfstaat mit diversifizierender Wirtschaft (Finanzen, Tourismus, F1). Weniger oelreich als Nachbarn. Politische Spannungen durch schiitische Mehrheit.'},
LA:{fr:'Économie communiste en ouverture progressive. Grand producteur d\'hydroélectricité exportée vers les voisins. Très pauvre mais croissance récente. \'Batterie de l\'Asie du Sud-Est\'.',en:'Communist economy gradually opening. Major hydroelectric producer exporting to neighbors. Very poor but recent growth. \'Battery of Southeast Asia\'.',ua:'Комунізм, що поступово відкривається. ГЕС для сусідів. \'Батарея Південно-Східної Азії\'.',de:'Kommunistische Wirtschaft oeffnet sich schrittweise. Grosser Wasserkraftproduzent mit Export an Nachbarn. Sehr arm, aber juengst wachsend. \u00abBatterie Suedostasiens\u00bb.'},
SC:{fr:'Économie insulaire très développée pour l\'Afrique. Forte dépendance au tourisme et à la pêche au thon. L\'un des revenus par habitant les plus élevés d\'Afrique.',en:'Highly developed island economy for Africa. Strong dependence on tourism and tuna fishing. One of Africa\'s highest per capita incomes.',ua:'Розвинена острівна економіка для Африки. Туризм та тунець. Один з найвищих доходів на душу.',de:'Hochentwickelte Inselwirtschaft fuer Afrika. Starke Abhaengigkeit von Tourismus und Thunfischfang. Eines der hoechsten Pro-Kopf-Einkommen Afrikas.'},
YE:{fr:'Guerre civile dévastatrice depuis 2015 (intervention de la coalition saoudienne). L\'une des pires crises humanitaires mondiales. Économie quasi effondrée.',en:'Devastating civil war since 2015 (Saudi coalition intervention). One of the world\'s worst humanitarian crises. Near-collapsed economy.',ua:'Громадянська війна з 2015 (саудівська коаліція). Одна з найгірших гуманітарних криз. Економіка в колапсі.',de:'Verheerender Buergerkrieg seit 2015 (Intervention der Saudi-Koalition). Eine der schlimmsten humanitaeren Krisen der Welt. Fast zusammengebrochene Wirtschaft.'},
TL:{fr:'L\'un des pays les plus jeunes du monde (indépendance 2002). Économie très dépendante du pétrole et du gaz (Mer de Timor) en déclin. Parmi les plus pauvres d\'Asie.',en:'One of the world\'s youngest countries (independence 2002). Economy highly dependent on oil and gas (Timor Sea) now declining. Among Asia\'s poorest.',ua:'Серед наймолодших (незалежність 2002). Нафта та газ у спаді. Серед найбідніших Азії.',de:'Eines der juengsten Laender der Welt (Unabhaengigkeit 2002). Wirtschaft stark abhaengig von Oel und Gas (Timorsee), nun ruecklaeufig. Eines der aermsten in Asien.'},
BB:{fr:'L\'une des économies les plus développées des Caraïbes. Tourisme, services financiers. Devenue république en 2021 (ex-monarchie britannique). Faible corruption.',en:'One of the most developed Caribbean economies. Tourism, financial services. Became a republic in 2021 (formerly British monarchy). Low corruption.',ua:'Одна з найрозвиненіших у Карибах. Туризм та фінанси. Стала республікою у 2021 р.',de:'Eine der am weitesten entwickelten karibischen Wirtschaften. Tourismus, Finanzdienstleistungen. Wurde 2021 Republik (zuvor britische Monarchie). Geringe Korruption.'},
BS:{fr:'Économie très développée pour les Caraïbes. Fort hub touristique (croisières, casinos). Centre financier offshore. Très forte inégalité.',en:'Highly developed economy for the Caribbean. Strong tourism hub (cruises, casinos). Offshore financial center. Very high inequality.',ua:'Розвинена для Карибів. Туризм (круїзи, казино). Офшорний центр. Висока нерівність.',de:'Hochentwickelte Wirtschaft fuer die Karibik. Starkes Tourismuszentrum (Kreuzfahrten, Kasinos). Offshore-Finanzzentrum. Sehr hohe Ungleichheit.'},
BN:{fr:'Sultanat très riche grâce au pétrole et au gaz. L\'un des plus hauts revenus per capita en Asie. Pas de taxes personnelles. Économie très dépendante des hydrocarbures.',en:'Very wealthy sultanate thanks to oil and gas. One of Asia\'s highest per capita incomes. No personal taxes. Economy highly dependent on hydrocarbons.',ua:'Дуже багатий нафтою та газом. Один з найвищих доходів в Азії. Відсутність прибуткового податку.',de:'Sehr wohlhabendes Sultanat dank Oel und Gas. Eines der hoechsten Pro-Kopf-Einkommen Asiens. Keine Einkommensteuer. Wirtschaft stark von Kohlenwasserstoffen abhaengig.'},
ST:{fr:'Petit archipel très dépendant de l\'aide étrangère et du cacao. Économie de subsistance. Démocratie stable pour la région. Découvertes pétrolières offshore.',en:'Small archipelago highly dependent on foreign aid and cocoa. Subsistence economy. Stable democracy for the region. Offshore oil discoveries.',ua:'Залежить від допомоги та какао. Стабільна демократія. Офшорна нафта.',de:'Kleiner Archipel, stark abhaengig von Auslandshilfe und Kakao. Subsistenzwirtschaft. Stabile Demokratie fuer die Region. Offshore-Oelfunde.'},
JO:{fr:'Économie dépendante de l\'aide étrangère et du tourisme (Pétra). Peu de ressources naturelles. Hub régional de réfugiés (Syriens, Palestiniens). Stabilité relative.',en:'Economy dependent on foreign aid and tourism (Petra). Few natural resources. Regional refugee hub (Syrians, Palestinians). Relative stability.',ua:'Залежить від іноземної допомоги та туризму (Петра). Мало ресурсів. Хаб для біженців.',de:'Wirtschaft abhaengig von Auslandshilfe und Tourismus (Petra). Wenige Bodenschaetze. Regionales Fluechtlingszentrum (Syrer, Palaestinenser). Relative Stabilitaet.'},
SR:{fr:'Économie basée sur la bauxite, l\'or et le pétrole. Transformée par de nouvelles découvertes pétrolières offshore. Petite économie avec forte instabilité historique.',en:'Economy based on bauxite, gold and oil. Transformed by new offshore oil discoveries. Small economy with historically high instability.',ua:'Боксит, золото, нафта. Нові офшорні відкриття. Мала нестабільна економіка.',de:'Wirtschaft basierend auf Bauxit, Gold und Oel. Durch neue Offshore-Oelfunde transformiert. Kleine Wirtschaft mit historisch hoher Instabilitaet.'},
CV:{fr:'Économie insulaire stable et bien gouvernée. Forte dépendance au tourisme et aux transferts de la diaspora. Peu de ressources naturelles. Modèle de gouvernance africaine.',en:'Stable, well-governed island economy. Strong dependence on tourism and diaspora remittances. Few natural resources. African governance model.',ua:'Стабільна острівна економіка. Туризм та перекази. Мало ресурсів. Еталон управління в Африці.',de:'Stabile, gut regierte Inselwirtschaft. Starke Abhaengigkeit von Tourismus und Diaspora-Ueberweisungen. Wenige Bodenschaetze. Afrikanisches Regierungsmodell.'},
CF:{fr:'Parmi les pays les plus pauvres et fragiles du monde. Immenses ressources naturelles inexploitées (diamants, or, uranium). Conflits armés permanents. Présence militaire russe (Wagner).',en:'Among the world\'s poorest and most fragile. Vast unexploited natural resources (diamonds, gold, uranium). Permanent armed conflicts. Russian military presence (Wagner).',ua:'Серед найбідніших. Алмази, золото, уран. Постійні конфлікти. Присутність Вагнера.',de:'Eines der aermsten und fragilsten Laender der Welt. Riesige ungenutzte Bodenschaetze (Diamanten, Gold, Uran). Permanente bewaffnete Konflikte. Russische Militaerpraesenz (Wagner).'},
FJ:{fr:'Économie basée sur le tourisme, la canne à sucre et les exportations d\'eau. Hub régional du Pacifique. Deux coups d\'état majeurs (1987 et 2000). Fragilité climatique.',en:'Economy based on tourism, sugarcane and water exports. Regional Pacific hub. Two major coups (1987 and 2000). Climate vulnerability.',ua:'Туризм, цукровий очерет, вода. Регіональний хаб. Два перевороти. Кліматична вразливість.',de:'Wirtschaft basierend auf Tourismus, Zuckerrohr und Wasserexport. Regionales Pazifikzentrum. Zwei grosse Putsche (1987 und 2000). Klimaanfaelligkeit.'},
DJ:{fr:'Port stratégique de la mer Rouge et du golfe d\'Aden. Présences militaires étrangères multiples (France, USA, Chine). Économie basée sur les services portuaires. Très peu de ressources propres.',en:'Strategic port on the Red Sea and Gulf of Aden. Multiple foreign military bases (France, USA, China). Economy based on port services. Very few own resources.',ua:'Стратегічний порт. Іноземні бази (Франція, США, Китай). Портові послуги. Мало ресурсів.',de:'Strategischer Hafen am Roten Meer und Golf von Aden. Mehrere auslaendische Militaerbasen (Frankreich, USA, China). Wirtschaft basierend auf Hafendiensten. Kaum eigene Ressourcen.'},
SO:{fr:'État longtemps déliquescent. Piraterie maritime. Territoire en partie contrôlé par les milices Al-Shabaab. Croissance lente grâce aux transferts de la diaspora.',en:'Long-failed state. Maritime piracy. Territory partly controlled by Al-Shabaab militias. Slow growth thanks to diaspora remittances.',ua:'\'Провалена держава\'. Піратство. Аль-Шабааб. Перекази діаспори.',de:'Langjaehriger gescheiterter Staat. Seepiraterie. Teile des Territoriums von Al-Shabaab-Milizen kontrolliert. Langsames Wachstum dank Diaspora-Ueberweisungen.'},
SS:{fr:'Le plus jeune pays du monde (2011). Conflit civil depuis 2013. Économie quasi entièrement dépendante du pétrole. L\'une des pires crises humanitaires mondiales.',en:'The world\'s youngest country (2011). Civil conflict since 2013. Economy almost entirely dependent on oil. One of the world\'s worst humanitarian crises.',ua:'Наймолодша (2011). Конфлікт з 2013. Залежність від нафти. Одна з найгірших гуманітарних криз.',de:'Juengster Staat der Welt (2011). Buergerkonflikt seit 2013. Wirtschaft fast vollstaendig oelabhaengig. Eine der schlimmsten humanitaeren Krisen der Welt.'},
GW:{fr:'Parmi les plus pauvres du monde. Économie basée sur la noix de cajou (90% des exports). Instabilité politique extrême (nombreux coups d\'état). Plaque tournante du trafic de drogue.',en:'Among the world\'s poorest. Economy based on cashews (90% of exports). Extreme political instability (many coups). Major drug trafficking hub.',ua:'Серед найбідніших. Кеш\'ю (90% експорту). Нестабільність. Транзит наркотиків.',de:'Eines der aermsten Laender der Welt. Wirtschaft basierend auf Cashews (90 % der Exporte). Extreme politische Instabilitaet (viele Putsche). Bedeutendes Drogentransitzentrum.'},
GA:{fr:'Pays pétrolier d\'Afrique centrale avec un revenu per capita relativement élevé. Mais forte inégalité. Coup d\'État en 2023. Forêts tropicales immenses.',en:'Central African oil country with relatively high per capita income. But high inequality. Coup in 2023. Vast tropical forests.',ua:'Нафтова країна з відносно високим доходом. Нерівність. Переворот 2023. Тропічні ліси.',de:'Zentralafrikanisches Oelland mit relativ hohem Pro-Kopf-Einkommen. Aber hohe Ungleichheit. Putsch 2023. Riesige Tropenwaelder.'},
GQ:{fr:'Grand producteur de pétrole per capita mais richesse très inégalement distribuée. Régime autoritaire corrompu. L\'une des plus grandes inégalités mondiales.',en:'Major oil producer per capita but wealth very unequally distributed. Corrupt authoritarian regime. One of the world\'s highest inequalities.',ua:'Великий виробник нафти, але вкрай нерівний розподіл. Корумпований режим.',de:'Grosser Oelproduzent pro Kopf, aber Reichtum sehr ungleich verteilt. Korruptes autoritaeres Regime. Eine der hoechsten Ungleichheiten der Welt.'},
CG:{fr:'Production pétrolière offshore significative. Forte dette publique. Forêts tropicales étendues. Régime autoritaire de longue date.',en:'Significant offshore oil production. High public debt. Extensive tropical forests. Long-standing authoritarian regime.',ua:'Офшорна нафта. Великий борг. Тропічні ліси. Довгостроковий авторитаризм.',de:'Bedeutende Offshore-Oelproduktion. Hohe Staatsverschuldung. Ausgedehnte Tropenwaelder. Langjaehriges autoritaeres Regime.'},
LR:{fr:'Parmi les plus pauvres. Reconstruction post-guerre civile longue et difficile. Caoutchouc et minerai de fer. Anciennement fondé par des esclaves libérés américains.',en:'Among the poorest. Long and difficult post-civil war reconstruction. Rubber and iron ore. Originally founded by freed American slaves.',ua:'Серед найбідніших. Відбудова після громадянської війни. Каучук та залізна руда. Заснована звільненими рабами.',de:'Eines der aermsten Laender. Langer und schwieriger Wiederaufbau nach dem Buergerkrieg. Kautschuk und Eisenerz. Urspruenglich von befreiten amerikanischen Sklaven gegruendet.'},
LC:{fr:'Économie caribéenne basée sur le tourisme et les bananes. Hub de services financiers offshore. Relativement stable politiquement.',en:'Caribbean economy based on tourism and bananas. Offshore financial services hub. Relatively stable politically.',ua:'Туризм та банани. Офшорні фінанси. Відносно стабільна.',de:'Karibische Wirtschaft basierend auf Tourismus und Bananen. Offshore-Finanzdienstleistungszentrum. Politisch relativ stabil.'},
GN:{fr:'Immenses ressources minières (bauxite, or, fer, diamants) mais reste très pauvre. Coup d\'État en 2021. Potentiel hydroélectrique énorme.',en:'Immense mining resources (bauxite, gold, iron, diamonds) but remains very poor. Coup in 2021. Enormous hydroelectric potential.',ua:'Боксит, золото, залізо, алмази — але дуже бідна. Переворот 2021. Гідроенергетика.',de:'Immense Bergbauressourcen (Bauxit, Gold, Eisen, Diamanten), aber dennoch sehr arm. Putsch 2021. Enormes Wasserkraftpotenzial.'},
NI:{fr:'Parmi les plus pauvres d\'Amérique centrale. Régime de plus en plus autoritaire (Ortega). Grave fuite des cerveaux et émigration. Récentes découvertes d\'or.',en:'Among the poorest in Central America. Increasingly authoritarian regime (Ortega). Serious brain drain and emigration. Recent gold discoveries.',ua:'Серед найбідніших Центральної Америки. Авторитарний режим. Відтік мізків. Золото.',de:'Eines der aermsten Laender Zentralamerikas. Zunehmend autoritaeres Regime (Ortega). Ernste Abwanderung von Fachkraeften. Juengste Goldfunde.'},
BZ:{fr:'Petite économie basée sur le tourisme, la canne à sucre et les agrumes. Hub de transit de drogues. Faible densité de population. Récentes découvertes pétrolières.',en:'Small economy based on tourism, sugarcane and citrus. Drug transit hub. Low population density. Recent oil discoveries.',ua:'Туризм, цукор, цитрусові. Транзит наркотиків. Мала густота. Нафта.',de:'Kleine Wirtschaft basierend auf Tourismus, Zuckerrohr und Zitrusfruechten. Drogentransitzentrum. Geringe Bevoelkerungsdichte. Juengste Oelfunde.'},
SD:{fr:'Économie en crise depuis la sécession du Soudan du Sud (2011). Grandes réserves pétrolières restantes. Sous sanctions américaines longtemps. Instabilité politique.',en:'Economy in crisis since South Sudan\'s secession (2011). Remaining large oil reserves. Long under US sanctions. Political instability.',ua:'Криза після відокремлення Судану (2011). Нафтові запаси. Санкції. Нестабільність.',de:'Wirtschaft in der Krise seit der Abspaltung des Suedsudan (2011). Verbleibende grosse Oelreserven. Lange unter US-Sanktionen. Politische Instabilitaet.'},
HN:{fr:'Parmi les plus pauvres d\'Amérique centrale. Forte violence des gangs (ex-pays le plus meurtrier du monde). Exportateur de café et bananes. Émigration massive vers les USA.',en:'Among the poorest in Central America. High gang violence (once world\'s most murderous country). Coffee and banana exporter. Mass migration to the USA.',ua:'Серед найбідніших. Банди (колись найбільш смертоносна). Кава та банани. Еміграція до США.',de:'Eines der aermsten Laender Zentralamerikas. Hohe Bandengewalt (einst Land mit hoechster Mordrate). Kaffee- und Bananenexporteur. Massenmigration in die USA.'},
MR:{fr:'Grande économie minière (fer, or, cuivre). Très vaste territoire quasi-désertique. Pratique de l\'esclavage encore présente. Frontière entre monde arabe et Afrique noire.',en:'Large mining economy (iron, gold, copper). Vast near-desert territory. Slavery still practiced. Border between the Arab world and Black Africa.',ua:'Залізо, золото, мідь. Пустельна. Рабство ще практикується. Межа арабського та африканського світів.',de:'Grosse Bergbauwirtschaft (Eisen, Gold, Kupfer). Riesiges fast wuestenartiges Territorium. Sklaverei noch praktiziert. Grenze zwischen arabischer Welt und Schwarzafrika.'},
TJ:{fr:'Pays le plus pauvre d\'Asie centrale. Économie basée sur les transferts de la diaspora (Russie). Hydroélectricité majeure. Régime très autoritaire.',en:'Poorest country in Central Asia. Economy based on diaspora remittances (Russia). Major hydroelectricity. Very authoritarian regime.',ua:'Найбідніша Центральна Азія. Перекази з Росії. ГЕС. Дуже авторитарний режим.',de:'Aermstes Land Zentralasiens. Wirtschaft basierend auf Diaspora-Ueberweisungen (Russland). Grosse Wasserkraft. Sehr autoritaeres Regime.'},
PG:{fr:'Immenses ressources naturelles (or, cuivre, gaz, forêts) mais très peu développé. Grande biodiversité. Nombreuses langues (800+). LNG important.',en:'Immense natural resources (gold, copper, gas, forests) but very underdeveloped. Great biodiversity. Many languages (800+). Important LNG.',ua:'Золото, мідь, газ, ліси — але дуже нерозвинена. Біорізноманіття. 800+ мов. ЗПГ.',de:'Immense Bodenschaetze (Gold, Kupfer, Gas, Waelder), aber sehr unterentwickelt. Grosse Biodiversitaet. Viele Sprachen (800+). Wichtiges LNG.'},
VC:{fr:'Économie caribéenne basée sur la banane et le tourisme. Très vulnérable aux cyclones. Éruption volcanique majeure en 2021 (La Soufrière).',en:'Caribbean economy based on bananas and tourism. Highly vulnerable to hurricanes. Major volcanic eruption in 2021 (La Soufrière).',ua:'Банани та туризм. Вразлива до ураганів. Виверження вулкану 2021 (Ла-Суфрієр).',de:'Karibische Wirtschaft basierend auf Bananen und Tourismus. Sehr anfaellig fuer Hurrikane. Grosser Vulkanausbruch 2021 (La Soufriere).'},
BT:{fr:'Petit royaume bouddhiste très fermé. Mesure le \'Bonheur national brut\'. Économie basée sur l\'hydroélectricité exportée vers l\'Inde. Très faible développement.',en:'Small, very closed Buddhist kingdom. Measures \'Gross National Happiness\'. Economy based on hydroelectricity exported to India. Very limited development.',ua:'Закрите королівство. Вимірює \'Валовий національний щастя\'. ГЕС для Індії.',de:'Kleines, sehr verschlossenes buddhistisches Koenigreich. Misst das \u00abBruttonationalglueck\u00bb. Wirtschaft basierend auf Wasserkraftexport nach Indien. Sehr begrenzte Entwicklung.'},
AG:{fr:'Double île caribéenne. Économie basée sur le tourisme (plages de classe mondiale). Hub d\'yachting de luxe. Revenus per capita relativement élevés pour les Caraïbes.',en:'Twin-island Caribbean nation. Economy based on tourism (world-class beaches). Luxury yachting hub. Relatively high per capita income for the Caribbean.',ua:'Туризм (пляжі). Яхтинг. Відносно високий дохід для Карибів.',de:'Karibischer Zweiinselstaat. Wirtschaft basierend auf Tourismus (erstklassige Straende). Luxusjachten-Zentrum. Relativ hohes Pro-Kopf-Einkommen fuer die Karibik.'},
SB:{fr:'Économie basée sur l\'exploitation forestière (menace environnementale) et la pêche. Conflit entre Taiwan et Chine pour l\'influence. Très peu développé.',en:'Economy based on logging (environmental threat) and fishing. Competition between Taiwan and China for influence. Very underdeveloped.',ua:'Лісозаготівля та рибальство. Змагання Тайваню та Китаю за вплив. Нерозвинений.',de:'Wirtschaft basierend auf Holzeinschlag (Umweltbedrohung) und Fischerei. Wettbewerb zwischen Taiwan und China um Einfluss. Sehr unterentwickelt.'},
KI:{fr:'État en première ligne du changement climatique (montée des eaux). Économie basée sur la pêche et les licences de pêche étrangères. Très isolé.',en:'State on the front line of climate change (rising sea levels). Economy based on fishing and foreign fishing licenses. Very isolated.',ua:'Під загрозою підйому рівня моря. Рибальство. Дуже ізольований.',de:'Staat an vorderster Front des Klimawandels (steigende Meeresspiegel). Wirtschaft basierend auf Fischerei und Fischereilizenzen. Sehr isoliert.'},
WS:{fr:'Économie basée sur l\'agriculture, la pêche et les transferts de la diaspora (Nouvelle-Zélande, Australie). Très vulnérable aux cyclones et tsunamis.',en:'Economy based on agriculture, fishing and diaspora remittances (NZ, Australia). Highly vulnerable to cyclones and tsunamis.',ua:'Сільське господарство та перекази (Нова Зеландія, Австралія). Вразлива до циклонів.',de:'Wirtschaft basierend auf Landwirtschaft, Fischerei und Diaspora-Ueberweisungen (NZ, Australien). Sehr anfaellig fuer Zyklone und Tsunamis.'},
MV:{fr:'Économie quasi entièrement basée sur le tourisme de luxe. En première ligne de la montée des eaux (altitude maximale ~2m). Forte croissance récente.',en:'Economy almost entirely based on luxury tourism. On the front line of rising sea levels (max altitude ~2m). Strong recent growth.',ua:'Практично лише туризм класу люкс. Під загрозою підйому моря (макс. ~2 м). Швидке зростання.',de:'Wirtschaft fast vollstaendig auf Luxustourismus basierend. An vorderster Front steigender Meeresspiegel (max. Hoehe ca. 2 m). Starkes juengstes Wirtschaftswachstum.'},
PS:{fr:'Territoire sous occupation et siège partiel. Économie très dépendante de l\'aide internationale. Gaza sous blocus depuis 2007. Forte dépendance à Israël.',en:'Territory under partial occupation and siege. Economy highly dependent on international aid. Gaza under blockade since 2007. High dependence on Israel.',ua:'Окупована / облогова територія. Залежність від допомоги. Блокада Гази з 2007.',de:'Gebiet unter teilweiser Besatzung und Belagerung. Wirtschaft stark abhaengig von internationaler Hilfe. Gaza seit 2007 unter Blockade. Hohe Abhaengigkeit von Israel.'},
GD:{fr:'Petite économie caribéenne. Tourisme, épices (noix de muscade). Connue pour l\'invasion américaine de 1983. Revenus relativement stables.',en:'Small Caribbean economy. Tourism, spices (nutmeg). Known for 1983 US invasion. Relatively stable income.',ua:'Туризм, прянощі (мускатний горіх). Американське вторгнення 1983 р.',de:'Kleine karibische Wirtschaft. Tourismus, Gewuerze (Muskatnuss). Bekannt fuer die US-Invasion 1983. Relativ stabiles Einkommen.'},
KN:{fr:'Deux petites îles caribéennes. Économie basée sur le tourisme et les services financiers offshore. L\'un des plus faibles PIB des Amériques.',en:'Two small Caribbean islands. Economy based on tourism and offshore financial services. One of the Americas\' smallest GDPs.',ua:'Туризм та офшорні фінанси. Один з найменших ВВП Америки.',de:'Zwei kleine karibische Inseln. Wirtschaft basierend auf Tourismus und Offshore-Finanzdienstleistungen. Eines der kleinsten BIPs Amerikas.'},
TW:{fr:'Économie très développée (\'Tigre asiatique\'). Leader mondial des semi-conducteurs (TSMC). Hub technologique mondial. Statut politique contesté par la Chine.',en:'Highly developed economy (\'Asian Tiger\'). World semiconductor leader (TSMC). Global tech hub. Political status contested by China.',ua:'\'Азійський тигр\'. Лідер напівпровідників (TSMC). Статус оскаржується Китаєм.',de:'Hochentwickelte Wirtschaft (\u00abAsiatischer Tiger\u00bb). Weltweiter Halbleiterfuehrer (TSMC). Globales Technologiezentrum. Politischer Status von China beansprucht.'},
DM:{fr:'Petite île caribéenne volcanique. Économie basée sur l\'agriculture (bananes) et l\'éco-tourisme. L\'une des moins développées des Caraïbes. Connue comme \'l\'île nature\'.',en:'Small volcanic Caribbean island. Economy based on agriculture (bananas) and eco-tourism. One of the Caribbean\'s least developed. Known as the \'nature island\'.',ua:'Бананів та екотуризм. Одна з найменш розвинених. \'Острів природи\'.',de:'Kleine vulkanische Karibikinsel. Wirtschaft basierend auf Landwirtschaft (Bananen) und Oekotourismus. Eines der am wenigsten entwickelten karibischen Laender. Als \u00abNaturinsel\u00bb bekannt.'},
TV:{fr:'L\'un des plus petits pays du monde. Revenu issu de la vente du domaine .tv à des chaînes de télévision. En danger d\'inondation (montée des eaux). Très isolé.',en:'One of the world\'s smallest countries. Income from selling the .tv domain to TV channels. Flooding risk (rising sea levels). Very isolated.',ua:'Одна з найменших. Дохід від домену .tv. Загроза затоплення. Ізольована.',de:'Eines der kleinsten Laender der Welt. Einnahmen aus dem Verkauf der .tv-Domain an TV-Sender. Ueberschwemmungsrisiko (steigende Meeresspiegel). Sehr isoliert.'},
PW:{fr:'Économie basée sur le tourisme plongée sous-marine et l\'aide américaine (Compact of Free Association). Très peu développé économiquement.',en:'Economy based on scuba diving tourism and US aid (Compact of Free Association). Very economically underdeveloped.',ua:'Дайвінг та американська допомога (Компакт). Нерозвинений.',de:'Wirtschaft basierend auf Tauchtourismus und US-Hilfe (Assoziierungsvertrag). Wirtschaftlich sehr unterentwickelt.'},
FM:{fr:'Économie dépendante de l\'aide américaine (Compact of Free Association). Pêche et subsistance. Très peu développé. Vulnérable au changement climatique.',en:'Economy dependent on US aid (Compact of Free Association). Fishing and subsistence. Very underdeveloped. Vulnerable to climate change.',ua:'Американська допомога. Рибальство. Нерозвинений. Кліматична вразливість.',de:'Wirtschaft abhaengig von US-Hilfe (Assoziierungsvertrag). Fischerei und Subsistenz. Sehr unterentwickelt. Anfaellig fuer Klimawandel.'},
SM:{fr:'République enclée dans l\'Italie. Un des pays les plus riches per capita. Économie basée sur le tourisme, la finance et la vente de franchises postales.',en:'Republic enclosed within Italy. One of the richest per capita countries. Economy based on tourism, finance and postal franchise sales.',ua:'Анклав в Італії. Один з найбагатших. Туризм та фінанси.',de:'Republik inmitten Italiens. Eines der reichsten Laender pro Kopf. Wirtschaft basierend auf Tourismus, Finanzen und Briefmarkenverkauf.'},
NR:{fr:'Île dont l\'économie fut basée sur le phosphate (épuisé). Aujourd\'hui dépendante de l\'aide étrangère. Obésité massive. Considérée paradis fiscal.',en:'Island whose economy was based on phosphate (now depleted). Now dependent on foreign aid. Massive obesity. Considered a tax haven.',ua:'Фосфат вичерпано. Залежність від допомоги. Масове ожиріння. Офшор.',de:'Insel, deren Wirtschaft auf Phosphat basierte (jetzt erschoepft). Nun abhaengig von Auslandshilfe. Massive Fettleibigkeit. Als Steueroase betrachtet.'},
MH:{fr:'Site d\'essais nucléaires américains (Bikini). Économie dépendante de l\'aide américaine. Très vulnérable à la montée des eaux. Population dispersée.',en:'Site of American nuclear tests (Bikini). Economy dependent on US aid. Very vulnerable to rising sea levels. Dispersed population.',ua:'Ядерні випробування (Бікіні). Американська допомога. Дуже вразливий до підйому рівня моря.',de:'Schauplatz amerikanischer Atomtests (Bikini). Wirtschaft abhaengig von US-Hilfe. Sehr anfaellig fuer steigende Meeresspiegel. Verstreute Bevoelkerung.'},
MC:{fr:'2e plus petit pays du monde. Paradis fiscal et financier. Densité de population la plus élevée du monde. Hub de luxe, casino et yachting. Famille Grimaldi.',en:'World\'s 2nd smallest country. Tax and financial haven. World\'s highest population density. Luxury, casino and yachting hub. Grimaldi family.',ua:'2-га найменша країна. Офшор та фінанси. Найвища густота населення. Казино. Грімальді.',de:'Zweitkleinstes Land der Welt. Steuer- und Finanzoase. Hoechste Bevoelkerungsdichte der Welt. Luxus-, Casino- und Jachtzentrum. Familie Grimaldi.'},
AD:{fr:'Microfiscalité : pas d\'impôt sur le revenu. Hub de shopping et tourisme de ski. Économie très dépendante du commerce transfrontalier avec la France et l\'Espagne.',en:'Micro-taxation: no income tax. Shopping and ski tourism hub. Economy highly dependent on cross-border trade with France and Spain.',ua:'Без прибуткового податку. Шопінг та лижний туризм. Залежить від Франції та Іспанії.',de:'Mikrosteuerstaat: keine Einkommensteuer. Shopping- und Skitourismuszentrum. Wirtschaft stark abhaengig vom grenzueberschreitenden Handel mit Frankreich und Spanien.'},
XK:{fr:'Un des plus jeunes pays du monde (indépendance 2008). Économie en développement, aide internationale majeure. Reconnaissance internationale partielle. Candidat UE.',en:'One of the world\'s youngest countries (independence 2008). Developing economy, major international aid. Partial international recognition. EU candidate.',ua:'Незалежність 2008. Часткове визнання. Міжнародна допомога. Кандидат ЄС.',de:'Einer der juengsten Staaten der Welt (Unabhaengigkeit 2008). Sich entwickelnde Wirtschaft, grosse internationale Hilfe. Teilweise internationale Anerkennung. EU-Kandidat.'},
MO:{fr:'Région administrative spéciale de la Chine. PIB per capita parmi les plus élevés du monde (jeux de casino). Las Vegas de l\'Asie. Monopoly du jeu.',en:'China\'s special administrative region. GDP per capita among the world\'s highest (casino gambling). Las Vegas of Asia. Gambling monopoly.',ua:'Особлива адміністративна зона. Один з найвищих ВВП на душу (казино). Лас-Вегас Азії.',de:'Chinesische Sonderverwaltungszone. BIP pro Kopf unter den hoechsten der Welt (Casino-Gluecksspiel). Las Vegas Asiens. Gluecksspielmonopol.'},
PR:{fr:'Territoire américain non incorporé. Économie basée sur la pharmacie, la finance et le tourisme. Forte dette et crise économique depuis 2006. Entre deux statuts.',en:'Unincorporated US territory. Economy based on pharmaceuticals, finance and tourism. Heavy debt and economic crisis since 2006. Between two statuses.',ua:'Неінкорпорована територія США. Фармацевтика та туризм. Великий борг і криза.',de:'Nicht inkorporiertes US-Territorium. Wirtschaft basierend auf Pharmazie, Finanzen und Tourismus. Hohe Verschuldung und Wirtschaftskrise seit 2006. Zwischen zwei Status.'},
HK:{fr:'Ancienne colonie britannique, maintenant région administrative spéciale de la Chine. L\'un des plus grands centres financiers mondiaux. Autonomie fortement réduite depuis 2020.',en:'Former British colony, now China\'s special administrative region. One of the world\'s largest financial centers. Autonomy greatly reduced since 2020.',ua:'Колишня британська колонія, тепер ОАР. Фінансовий центр. Автономія скорочена з 2020.',de:'Ehemalige britische Kolonie, jetzt chinesische Sonderverwaltungszone. Eines der groessten Finanzzentren der Welt. Autonomie seit 2020 stark eingeschraenkt.'},
NC:{fr:'Territoire français d\'Outre-mer. Immenses réserves de nickel (25-30% mondial). Économie dépendante du nickel et de la France. Mouvement indépendantiste kanak.',en:'French Overseas Territory. Vast nickel reserves (25-30% of global). Economy dependent on nickel and France. Kanak independence movement.',ua:'Французька заморська. Величезні запаси нікелю. Рух за незалежність канаків.',de:'Franzoesisches Ueberseegebiet. Riesige Nickelreserven (25-30 % weltweit). Wirtschaft abhaengig von Nickel und Frankreich. Kanakische Unabhaengigkeitsbewegung.'},
PF:{fr:'Collectivité française d\'Outre-mer (Tahiti). Fort autonomie. Économie basée sur le tourisme de luxe et les perles de Tahiti. Fortement dépendant de la France.',en:'French Overseas Collectivity (Tahiti). High autonomy. Economy based on luxury tourism and Tahitian pearls. Highly dependent on France.',ua:'Французька (Таїті). Туризм класу люкс та перли. Залежить від Франції.',de:'Franzoesische Ueberseekollektivitaet (Tahiti). Hohe Autonomie. Wirtschaft basierend auf Luxustourismus und Tahiti-Perlen. Stark abhaengig von Frankreich.'},
GL:{fr:'Territoire autonome du Danemark. Économie basée sur la pêche et les subventions danoises. Immenses ressources minières encore peu exploitées. Intérêt géopolitique croissant.',en:'Autonomous Danish territory. Economy based on fishing and Danish subsidies. Vast mineral resources still largely unexploited. Growing geopolitical interest.',ua:'Автономна данська територія. Рибальство та субсидії. Ресурси невикористані. Зростаючий геополітичний інтерес.',de:'Autonomes daenisches Territorium. Wirtschaft basierend auf Fischerei und daenischen Subventionen. Riesige, noch weitgehend ungenutzte Bodenschaetze. Wachsendes geopolitisches Interesse.'},
FO:{fr:'Territoire autonome du Danemark. Économie très prospère basée sur la pêche industrielle. Fort sentiment d\'indépendance. Haute qualité de vie.',en:'Autonomous Danish territory. Very prosperous economy based on industrial fishing. Strong independence sentiment. High quality of life.',ua:'Автономна данська. Процвітаюча рибальська економіка. Незалежницький настрій. Якість життя.',de:'Autonomes daenisches Territorium. Sehr wohlhabende Wirtschaft basierend auf industrieller Fischerei. Starkes Unabhaengigkeitsstreben. Hohe Lebensqualitaet.'},
LI:{fr:'Deuxième plus petit pays germanophone. Paradis fiscal (siège de nombreux holdings). L\'un des plus hauts revenus per capita du monde. Dans l\'espace Schengen.',en:'Second smallest German-speaking country. Tax haven (HQ of many holdings). One of the world\'s highest per capita incomes. In the Schengen area.',ua:'Офшор (холдинги). Один з найвищих доходів. Шенгенська зона.',de:'Zweitkleinster deutschsprachiger Staat. Steueroase (Sitz vieler Holdings). Eines der hoechsten Pro-Kopf-Einkommen der Welt. Im Schengen-Raum.'},
AW:{fr:'Île caribéenne autonome des Pays-Bas. Économie basée sur le tourisme et le raffinage du pétrole (ex). Revenus per capita relativement élevés pour les Caraïbes.',en:'Autonomous Dutch Caribbean island. Economy based on tourism and (formerly) oil refining. Relatively high per capita income for the Caribbean.',ua:'Автономний нідерландський острів. Туризм. Відносно високий дохід.',de:'Autonome niederlaendische Karibikinsel. Wirtschaft basierend auf Tourismus und (ehemals) Oelraffinerie. Relativ hohes Pro-Kopf-Einkommen fuer die Karibik.'},
ER:{fr:'L\'un des régimes les plus fermés du monde (\'la Corée du Nord de l\'Afrique\'). Service militaire obligatoire indéfini. Économie quasi inexistante et isolée.',en:'One of the world\'s most closed regimes (\'the North Korea of Africa\'). Indefinite mandatory military service. Almost non-existent and isolated economy.',ua:'\'Північна Корея Африки\'. Безстрокова військова служба. Ізольована та нерозвинена.',de:'Eines der geschlossensten Regime der Welt (\u00abNordkorea Afrikas\u00bb). Unbefristeter Pflichtmilitaerdienst. Nahezu nicht existente und isolierte Wirtschaft.'},
MM:{fr:'Riches ressources naturelles (jade, rubis, gaz, bois). Régime militaire depuis le coup d\'État de 2021. Économie en crise et sanctions internationales. Guerre civile.',en:'Rich natural resources (jade, rubies, gas, timber). Military regime since 2021 coup. Economy in crisis and under international sanctions. Civil war.',ua:'Нефрит, рубіни, газ. Переворот 2021. Санкції. Громадянська війна.',de:'Reiche Bodenschaetze (Jade, Rubine, Gas, Holz). Militaerregime seit Putsch 2021. Wirtschaft in der Krise und unter internationalen Sanktionen. Buergerkrieg.'},
RW:{fr:'Économie en forte croissance depuis le génocide de 1994. Modèle de gouvernance africaine (faible corruption). Hub technologique. Kagame au pouvoir.',en:'Fast-growing economy since the 1994 genocide. African governance model (low corruption). Tech hub. Kagame in power.',ua:'Швидке зростання після геноциду 1994. Модель управління. Технохаб. Кагаме.',de:'Schnell wachsende Wirtschaft seit dem Voelkermord 1994. Afrikanisches Regierungsmodell (geringe Korruption). Technologiezentrum. Kagame an der Macht.'},
TG:{fr:'Économie basée sur le phosphate, l\'agriculture et les ports (hub régional). Régime politique stable mais peu démocratique. L\'une des plus faibles dépenses sociales.',en:'Economy based on phosphate, agriculture and ports (regional hub). Stable but undemocratic political regime. Among the lowest social spending.',ua:'Фосфат, сільське господарство та порти. Стабільний, але недемократичний режим.',de:'Wirtschaft basierend auf Phosphat, Landwirtschaft und Haefen (regionales Zentrum). Stabiles, aber undemokratisches Regime. Unter den niedrigsten Sozialausgaben.'},
UG:{fr:'Économie à forte croissance, agricole. Récentes découvertes de pétrole. Siège de certaines institutions africaines. Régime Museveni depuis 1986.',en:'Fast-growing, agricultural economy. Recent oil discoveries. Home to some African institutions. Museveni regime since 1986.',ua:'Швидке аграрне зростання. Нафтові відкриття. Режим Мусевені з 1986 р.',de:'Schnell wachsende Agrarwirtschaft. Juengste Oelfunde. Sitz einiger afrikanischer Institutionen. Museveni-Regime seit 1986.'},
MZ:{fr:'Découvertes majeures de gaz naturel offshore (Rovuma). L\'un des plus pauvres. Reconstruction post-guerre civile. LNG en développement.',en:'Major offshore gas discoveries (Rovuma). One of the world\'s poorest. Post-civil war reconstruction. LNG under development.',ua:'Газ (Ровума). Один з найбідніших. Відбудова. ЗПГ у розвитку.',de:'Grosse Offshore-Gasfunde (Rovuma). Eines der aermsten Laender der Welt. Wiederaufbau nach dem Buergerkrieg. LNG in Entwicklung.'},
NP:{fr:'Économie très pauvre et enclavée. Transferts de travailleurs (Golfe, Inde). Hydroélectricité immense non exploitée. Everest et tourisme de montagne.',en:'Very poor and landlocked economy. Worker remittances (Gulf, India). Vast unexploited hydroelectric potential. Everest and mountain tourism.',ua:'Бідна без виходу до моря. Перекази (Затока, Індія). ГЕС. Еверест і туризм.',de:'Sehr arme Binnenwirtschaft. Ueberweisungen von Arbeitern (Golf, Indien). Riesiges ungenutztes Wasserkraftpotenzial. Everest- und Bergtourismus.'},
BF:{fr:'Parmi les plus pauvres. Grave insécurité terroriste sahélienne depuis 2015. Exportateur d\'or. Coup d\'état en 2022. Présence russe (Wagner).',en:'Among the poorest. Severe Sahelian terrorist insecurity since 2015. Gold exporter. Coup in 2022. Russian presence (Wagner).',ua:'Серед найбідніших. Терористи Сахелю. Золото. Переворот 2022. Вагнер.',de:'Eines der aermsten Laender. Schwere terroristische Unsicherheit in der Sahelzone seit 2015. Goldexporteur. Putsch 2022. Russische Praesenz (Wagner).'},
ML:{fr:'Vaste pays sahélien très pauvre. Instabilité depuis 2012 (jihadistes au nord). Coups d\'état en 2020 et 2021. Présence russe (Wagner). Producteur d\'or.',en:'Vast, very poor Sahelian country. Instability since 2012 (jihadists in the north). Coups in 2020 and 2021. Russian presence (Wagner). Gold producer.',ua:'Величезна бідна Сахельська. Нестабільність з 2012. Перевороти. Вагнер. Золото.',de:'Riesiges, sehr armes Sahelland. Instabilitaet seit 2012 (Dschihadisten im Norden). Putsche 2020 und 2021. Russische Praesenz (Wagner). Goldproduzent.'},
NE:{fr:'L\'un des plus pauvres et plus fragiles. 4e producteur mondial d\'uranium. Coup d\'état en 2023. Très forte croissance démographique.',en:'Among the poorest and most fragile. World\'s 4th largest uranium producer. Coup in 2023. Very fast population growth.',ua:'Серед найбідніших. Уран (4-те місце). Переворот 2023. Дуже швидке зростання населення.',de:'Eines der aermsten und fragilsten Laender. Viertgroesster Uranproduzent der Welt. Putsch 2023. Sehr schnelles Bevoelkerungswachstum.'},
};
function getCountryDesc2(c) {
var code = (c.country_code || '').toUpperCase();
if (code && COUNTRY_HINTS2[code]) {
var d = COUNTRY_HINTS2[code];
return d[currentLang] || d.fr;
}
var nameFR = (c.country_FR || '').toLowerCase();
var nameLookup = {
'france':'FR','états-unis':'US','etats-unis':'US','brésil':'BR','bresil':'BR',
'japon':'JP','inde':'IN','norvège':'NO','norvege':'NO','nigeria':'NG',
'argentine':'AR','australie':'AU','chine':'CN','allemagne':'DE','russie':'RU',
'royaume-uni':'GB','espagne':'ES','italie':'IT','canada':'CA','mexique':'MX',
'colombie':'CO','viêt nam':'VN','viet nam':'VN','vietnam':'VN',
'turquie':'TR','ukraine':'UA','pologne':'PL','pays-bas':'NL'
};
var mapped = nameLookup[nameFR];
if (mapped && COUNTRY_HINTS2[mapped]) {
var d2 = COUNTRY_HINTS2[mapped];
return d2[currentLang] || d2.fr;
}
return null;
}
// ─── COUNTRY TOOLTIP ──────────────────────────────────────────────────────────
// Hint state for current turn
var hintState = { hint1Revealed: false, hint2Revealed: false };
// ─── HINT REVEAL FUNCTIONS ─────────────────────────────────────────────────
function revealHint1(e) {
if (hintState.hint1Revealed || isRevealing || isHardcoreActive()) return;
hintState.hint1Revealed = true;
totalScore += 25;
document.getElementById('total-score').textContent = totalScore;
flashScore();
// Log hint penalty for end-screen recap
var _c1 = gameCountries[currentStep];
gameLog.push({
flag: _c1.flag || _c1.emoji || '🌍',
name: getCountryName(_c1),
catObj: null,
points: 25,
isPenalty: true,
isHint: true,
hintLevel: 1
});
var btn1 = document.getElementById('hint-btn-1');
if (e) { spawnRipple(btn1, e); spawnParticles(btn1, 'green'); }
var c = gameCountries[currentStep];
var desc = getCountryDesc(c);
// Set label text directly (no data-i18n)
document.getElementById('hint-label-1').innerHTML = t('hintLabel1') + ' <span class="cost-badge cost-badge-1">-25 pts</span>';
document.getElementById('hint-text-1').textContent = desc || '—';
// Trigger panel open with animation
var panel = document.getElementById('hint-panel');
panel.classList.remove('open');
void panel.offsetWidth;
panel.classList.add('open');
btn1.classList.add('revealed');
btn1.innerHTML = '💡 ✓';
// Show hint2 if desc2 exists
var desc2 = getCountryDesc2(c);
if (desc2) {
var btn2 = document.getElementById('hint-btn-2');
btn2.style.display = 'inline-flex';
// small bounce-in delay
btn2.style.animation = 'none';
setTimeout(function() {
btn2.style.animation = 'hintBoom 0.32s cubic-bezier(0.34,1.56,0.64,1) both';
}, 120);
}
}
function revealHint2(e) {
if (hintState.hint2Revealed || isRevealing || isHardcoreActive()) return;
hintState.hint2Revealed = true;
totalScore += 50;
document.getElementById('total-score').textContent = totalScore;
flashScore();
// Log hint penalty for end-screen recap
var _c2 = gameCountries[currentStep];
gameLog.push({
flag: _c2.flag || _c2.emoji || '🌍',
name: getCountryName(_c2),
catObj: null,
points: 50,
isPenalty: true,
isHint: true,
hintLevel: 2
});
var btn2 = document.getElementById('hint-btn-2');
if (e) { spawnRipple(btn2, e); spawnParticles(btn2, 'orange'); }
var c = gameCountries[currentStep];
var desc2 = getCountryDesc2(c);
document.getElementById('hint-label-2').innerHTML = t('hintLabel2') + ' <span class="cost-badge cost-badge-2">-50 pts</span>';
document.getElementById('hint-text-2').textContent = desc2 || '—';
var block2 = document.getElementById('hint-block-2');
block2.style.display = 'block';
block2.style.animation = 'none';
void block2.offsetWidth;
block2.style.animation = 'hintSlideIn 0.3s ease both';
btn2.classList.add('revealed');
btn2.innerHTML = '🔍 ✓';
}
function resetHints() {
hintState = { hint1Revealed: false, hint2Revealed: false };
if (gameMode === 'reverse') { var tt = document.getElementById('reverse-cat-tooltip'); if(tt) tt.classList.remove('open'); }
var panel = document.getElementById('hint-panel');
panel.classList.remove('open');
document.getElementById('hint-block-2').style.display = 'none';
document.getElementById('hint-text-1').textContent = '';
document.getElementById('hint-text-2').textContent = '';
document.getElementById('hint-label-1').textContent = '';
document.getElementById('hint-label-2').textContent = '';
var btn1 = document.getElementById('hint-btn-1');
btn1.classList.remove('revealed');
btn1.style.animation = '';
btn1.innerHTML = '💡 ' + t('hint1btn');
btn1.style.display = 'inline-flex';
var btn2 = document.getElementById('hint-btn-2');
btn2.classList.remove('revealed');
btn2.style.animation = '';
btn2.innerHTML = '🔍 ' + t('hint2btn');
btn2.style.display = 'none';
// Check availability for current country
if (currentStep < N_TURNS && gameCountries[currentStep]) {
if (!getCountryDesc(gameCountries[currentStep])) btn1.style.display = 'none';
}
}

146
js/mobile.js Normal file
View file

@ -0,0 +1,146 @@
// ── Ribbon mobile tabs ────────────────────────────────────────────────────────
// Sur écrans <= 540px : remplace la grille 3-col par des onglets tactiles
var MOB_BP = 540;
function isMob() { return window.innerWidth <= MOB_BP; }
// État actif par ribbon
var mobRibbonTab = 'poss';
var mobCatRibbonTab = 'poss';
function initMobRibbons() {
if (!isMob()) return;
_buildMobRibbon('ribbon', mobRibbonTab);
_buildMobRibbon('catribbon', mobCatRibbonTab);
}
function _buildMobRibbon(prefix, activeTab) {
var exclEl = document.getElementById(prefix + '-excl');
if (!exclEl) return;
var wrap = exclEl.closest('.ribbon-wrap');
if (!wrap || wrap.classList.contains('mob-tabbed')) return; // déjà fait
wrap.classList.add('mob-tabbed');
// ── Onglets ────────────────────────────────────────────────────────────────
var tabs = document.createElement('div');
tabs.className = 'mob-ribbon-tabs';
tabs.id = prefix + '-mob-tabs';
var tabDefs = [
{ col: 'excl', label: t('ribbonColExcl') },
{ col: 'poss', label: t('ribbonColPoss') },
{ col: 'incl', label: t('ribbonColIncl') },
];
tabDefs.forEach(function(def) {
var btn = document.createElement('button');
btn.className = 'mob-ribbon-tab';
btn.dataset.col = def.col;
btn.textContent = def.label;
(function(col) {
btn.addEventListener('click', function() { _switchMobTab(prefix, col); });
})(def.col);
tabs.appendChild(btn);
});
wrap.parentNode.insertBefore(tabs, wrap);
// ── Barre d'actions ────────────────────────────────────────────────────────
var actions = document.createElement('div');
actions.className = 'mob-ribbon-actions';
actions.id = prefix + '-mob-actions';
wrap.parentNode.insertBefore(actions, wrap.nextSibling);
// Activer l'onglet initial
_switchMobTab(prefix, activeTab);
}
function _switchMobTab(prefix, col) {
// Mémoriser
if (prefix === 'ribbon') mobRibbonTab = col;
else mobCatRibbonTab = col;
var exclEl = document.getElementById(prefix + '-excl');
if (!exclEl) return;
var wrap = exclEl.closest('.ribbon-wrap');
// Afficher la bonne colonne
wrap.querySelectorAll('.ribbon-col').forEach(function(c) {
c.classList.remove('mob-visible');
});
var targetCol = document.getElementById(prefix + '-' + col);
if (targetCol) targetCol.closest('.ribbon-col').classList.add('mob-visible');
// Activer le bon onglet
var tabs = document.getElementById(prefix + '-mob-tabs');
if (tabs) {
tabs.querySelectorAll('.mob-ribbon-tab').forEach(function(btn) {
btn.classList.remove('tab-excl', 'tab-poss', 'tab-incl');
if (btn.dataset.col === col) btn.classList.add('tab-' + col);
});
}
// Mettre à jour la barre d'actions
var actions = document.getElementById(prefix + '-mob-actions');
if (!actions) return;
actions.innerHTML = '';
var isCountry = (prefix === 'ribbon');
var moveFn = isCountry ? ribbonMove : catRibbonMove;
var actionDefs;
if (col === 'excl') {
actionDefs = [
{ label: t('mobActToPoss'), cls: 'act-poss', fn: function() { moveFn('excl','poss',false); } },
{ label: t('mobActAllToPoss'), cls: 'act-poss', fn: function() { moveFn('excl','poss',true); } },
];
} else if (col === 'poss') {
actionDefs = [
{ label: t('mobActExcl'), cls: 'act-excl', fn: function() { moveFn('poss','excl',false); } },
{ label: t('mobActForce'), cls: 'act-incl', fn: function() { moveFn('poss','incl',false); } },
{ label: t('mobActAllExcl'), cls: 'act-excl', fn: function() { moveFn('poss','excl',true); } },
];
} else { // incl
actionDefs = [
{ label: t('mobActRemove'), cls: 'act-poss', fn: function() { moveFn('incl','poss',false); } },
];
}
actionDefs.forEach(function(def) {
var btn = document.createElement('button');
btn.className = 'mob-ribbon-action ' + def.cls;
btn.textContent = def.label;
btn.addEventListener('click', def.fn);
actions.appendChild(btn);
});
}
// Réinitialiser quand on quitte le panel custom
function destroyMobRibbons() {
['ribbon', 'catribbon'].forEach(function(prefix) {
var exclEl = document.getElementById(prefix + '-excl');
if (!exclEl) return;
var wrap = exclEl.closest('.ribbon-wrap');
if (wrap) wrap.classList.remove('mob-tabbed');
wrap.querySelectorAll('.ribbon-col').forEach(function(c) { c.classList.remove('mob-visible'); });
var tabs = document.getElementById(prefix + '-mob-tabs');
if (tabs) tabs.remove();
var actions = document.getElementById(prefix + '-mob-actions');
if (actions) actions.remove();
});
mobRibbonTab = 'poss';
mobCatRibbonTab = 'poss';
}
// Resize : reconstruire si on repasse en mobile
var _mobResizeTimer;
window.addEventListener('resize', function() {
clearTimeout(_mobResizeTimer);
_mobResizeTimer = setTimeout(function() {
var panelCustom = document.getElementById('panel-custom');
if (!panelCustom || panelCustom.classList.contains('hidden')) return;
if (!isMob()) {
destroyMobRibbons();
} else {
initMobRibbons();
}
}, 200);
});

295
js/ribbon.js Normal file
View file

@ -0,0 +1,295 @@
// ─── COUNTRY RIBBON SELECTOR ──────────────────────────────────────────────────
// State: each country is in exactly one of 3 buckets
// ribbonState[i] = 'excl' | 'poss' | 'incl' (i = index in countriesDB)
var ribbonState = {}; // countriesDB index → 'excl'|'poss'|'incl'
var ribbonSelected = {}; // countriesDB index → true (multi-select)
var ribbonDragSrc = null; // {idx, fromCol}
function ribbonInit() {
// Called when openCustomPanel — reset to default state
ribbonState = {};
ribbonSelected = {};
for (var i = 0; i < countriesDB.length; i++) {
ribbonState[i] = 'poss';
}
ribbonFilter('');
ribbonRender();
}
function ribbonFilter(query) {
document.getElementById('ribbon-search').value = query;
ribbonRender(query.toLowerCase().trim());
}
function ribbonRender(filter) {
filter = filter || '';
var cols = { excl: [], poss: [], incl: [] };
for (var i = 0; i < countriesDB.length; i++) {
var c = countriesDB[i];
var name = (currentLang === 'de' ? (c.country_DE || c.country_EN || c.country_FR) :
currentLang === 'en' ? (c.country_EN || c.country_FR) :
currentLang === 'ua' ? (c.country_UA || c.country_FR) :
(c.country_FR || c.country_EN)) || '';
if (filter && name.toLowerCase().indexOf(filter) === -1) continue;
cols[ribbonState[i]].push({ i: i, name: name, flag: c.flag || '' });
}
// Sort each column alphabetically
['excl','poss','incl'].forEach(function(col) {
cols[col].sort(function(a,b){ return a.name.localeCompare(b.name); });
var el = document.getElementById('ribbon-' + col);
el.innerHTML = '';
cols[col].forEach(function(item) {
var div = document.createElement('div');
div.className = 'ribbon-item' + (ribbonSelected[item.i] ? ' selected ' + col : '');
div.dataset.idx = item.i;
div.draggable = true;
div.innerHTML =
'<span class="ribbon-item-flag">' + item.flag + '</span>' +
'<span class="ribbon-item-name" title="' + item.name + '">' + item.name + '</span>';
div.addEventListener('click', function(e) { ribbonToggleSelect(parseInt(this.dataset.idx)); });
div.addEventListener('dragstart', function(e) {
ribbonDragSrc = { idx: parseInt(this.dataset.idx), fromCol: ribbonState[parseInt(this.dataset.idx)] };
e.dataTransfer.effectAllowed = 'move';
});
el.appendChild(div);
});
});
applyEmoji(document.getElementById('ribbon-excl'));
applyEmoji(document.getElementById('ribbon-poss'));
applyEmoji(document.getElementById('ribbon-incl'));
ribbonUpdateSlots();
}
function ribbonToggleSelect(idx) {
if (ribbonSelected[idx]) {
delete ribbonSelected[idx];
} else {
ribbonSelected[idx] = true;
}
ribbonRender(document.getElementById('ribbon-search').value.toLowerCase().trim());
}
function ribbonMove(fromCol, toCol, all) {
var moved = false;
if (all) {
// Only move between excl ↔ poss (the Add All / Remove All restriction)
if ((fromCol === 'excl' && toCol === 'poss') || (fromCol === 'poss' && toCol === 'excl')) {
for (var i = 0; i < countriesDB.length; i++) {
if (ribbonState[i] === fromCol) { ribbonState[i] = toCol; moved = true; }
}
}
} else {
// Move selected items; if none selected, move all visible in fromCol
var hasSelection = Object.keys(ribbonSelected).some(function(k) {
return ribbonState[parseInt(k)] === fromCol;
});
if (hasSelection) {
Object.keys(ribbonSelected).forEach(function(k) {
var idx = parseInt(k);
if (ribbonState[idx] === fromCol) {
ribbonState[idx] = toCol; delete ribbonSelected[idx]; moved = true;
}
});
} else {
// No selection: move all visible (filtered) items from fromCol
var filter = document.getElementById('ribbon-search').value.toLowerCase().trim();
for (var i = 0; i < countriesDB.length; i++) {
if (ribbonState[i] !== fromCol) continue;
var c = countriesDB[i];
var name = (currentLang === 'de' ? (c.country_DE || c.country_EN || c.country_FR) :
currentLang === 'en' ? (c.country_EN || c.country_FR) :
currentLang === 'ua' ? (c.country_UA || c.country_FR) :
(c.country_FR || c.country_EN)) || '';
if (!filter || name.toLowerCase().indexOf(filter) !== -1) {
ribbonState[i] = toCol; moved = true;
}
}
}
}
if (moved) ribbonRender(document.getElementById('ribbon-search').value.toLowerCase().trim());
}
function ribbonDragOver(e) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }
function ribbonDrop(e, toCol) {
e.preventDefault();
if (!ribbonDragSrc) return;
var idx = ribbonDragSrc.idx;
var fromCol = ribbonDragSrc.fromCol;
ribbonDragSrc = null;
// Only allow valid moves: excl↔poss and poss→incl and incl→poss
var validMoves = {
'excl-poss':true, 'poss-excl':true,
'poss-incl':true, 'incl-poss':true,
'excl-incl':false, 'incl-excl':false
};
if (validMoves[fromCol + '-' + toCol]) {
ribbonState[idx] = toCol;
delete ribbonSelected[idx];
ribbonRender(document.getElementById('ribbon-search').value.toLowerCase().trim());
}
}
function ribbonUpdateSlots() {
var n = parseInt(document.getElementById('custom-n-slider').value, 10) || 8;
var nIncl = Object.keys(ribbonState).filter(function(k){ return ribbonState[k]==='incl'; }).length;
var pct = Math.min(nIncl / n * 100, 100);
var fill = document.getElementById('ribbon-slots-fill');
fill.style.width = pct + '%';
fill.className = 'ribbon-slots-fill' + (nIncl > n ? ' over' : nIncl === n ? ' full' : '');
document.getElementById('ribbon-slots-txt').textContent = nIncl + ' / ' + n + ' ' + t('ribbonSlotsTxt');
document.getElementById('ribbon-incl-count').textContent = nIncl + ' ' + (nIncl > 1 ? t('ribbonSlotsForcedP') : t('ribbonSlotsForced'));
}
// Called by the N slider to update the slots indicator live
function ribbonOnSliderChange(val) {
document.getElementById('custom-n-display').textContent = val;
ribbonUpdateSlots();
catRibbonUpdateSlots();
}
// ─── CATEGORY RIBBON SELECTOR ─────────────────────────────────────────────────
// catRibbonState[i] = 'excl'|'poss'|'incl' (i = index in ALL_CATEGORIES)
var catRibbonState = {};
var catRibbonSelected = {};
var catRibbonDragSrc = null;
function catRibbonInit() {
catRibbonState = {};
catRibbonSelected = {};
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
catRibbonState[i] = 'poss';
}
catRibbonRender();
}
function catRibbonFilter(query) {
document.getElementById('catribbon-search').value = query;
catRibbonRender(query.toLowerCase().trim());
}
function catRibbonRender(filter) {
filter = filter || '';
var cols = { excl: [], poss: [], incl: [] };
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
var cat = ALL_CATEGORIES[i];
var name = catName(cat);
if (filter && name.toLowerCase().indexOf(filter) === -1) continue;
cols[catRibbonState[i]].push({ i: i, name: name, icon: cat.icon || '📊' });
}
['excl','poss','incl'].forEach(function(col) {
cols[col].sort(function(a,b){ return a.name.localeCompare(b.name); });
var el = document.getElementById('catribbon-' + col);
el.innerHTML = '';
cols[col].forEach(function(item) {
var div = document.createElement('div');
div.className = 'ribbon-item' + (catRibbonSelected[item.i] ? ' selected ' + col : '');
div.dataset.idx = item.i;
div.draggable = true;
div.innerHTML =
'<span class="ribbon-item-flag">' + item.icon + '</span>' +
'<span class="ribbon-item-name" title="' + item.name + '">' + item.name + '</span>';
div.addEventListener('click', function() { catRibbonToggleSelect(parseInt(this.dataset.idx)); });
div.addEventListener('dragstart', function(e) {
catRibbonDragSrc = { idx: parseInt(this.dataset.idx), fromCol: catRibbonState[parseInt(this.dataset.idx)] };
e.dataTransfer.effectAllowed = 'move';
});
el.appendChild(div);
});
});
applyEmoji(document.getElementById('catribbon-excl'));
applyEmoji(document.getElementById('catribbon-poss'));
applyEmoji(document.getElementById('catribbon-incl'));
catRibbonUpdateSlots();
}
function catRibbonToggleSelect(idx) {
if (catRibbonSelected[idx]) { delete catRibbonSelected[idx]; }
else { catRibbonSelected[idx] = true; }
catRibbonRender(document.getElementById('catribbon-search').value.toLowerCase().trim());
}
function catRibbonMove(fromCol, toCol, all) {
var moved = false;
if (all) {
if ((fromCol === 'excl' && toCol === 'poss') || (fromCol === 'poss' && toCol === 'excl')) {
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
if (catRibbonState[i] === fromCol) { catRibbonState[i] = toCol; moved = true; }
}
}
} else {
var hasSelection = Object.keys(catRibbonSelected).some(function(k) {
return catRibbonState[parseInt(k)] === fromCol;
});
if (hasSelection) {
Object.keys(catRibbonSelected).forEach(function(k) {
var idx = parseInt(k);
if (catRibbonState[idx] === fromCol) {
catRibbonState[idx] = toCol; delete catRibbonSelected[idx]; moved = true;
}
});
} else {
var filter = document.getElementById('catribbon-search').value.toLowerCase().trim();
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
if (catRibbonState[i] !== fromCol) continue;
var name = catName(ALL_CATEGORIES[i]);
if (!filter || name.toLowerCase().indexOf(filter) !== -1) {
catRibbonState[i] = toCol; moved = true;
}
}
}
}
if (moved) catRibbonRender(document.getElementById('catribbon-search').value.toLowerCase().trim());
}
function catRibbonDragOver(e) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }
function catRibbonDrop(e, toCol) {
e.preventDefault();
if (!catRibbonDragSrc) return;
var idx = catRibbonDragSrc.idx;
var fromCol = catRibbonDragSrc.fromCol;
catRibbonDragSrc = null;
var validMoves = {
'excl-poss':true, 'poss-excl':true,
'poss-incl':true, 'incl-poss':true,
'excl-incl':false, 'incl-excl':false
};
if (validMoves[fromCol + '-' + toCol]) {
catRibbonState[idx] = toCol;
delete catRibbonSelected[idx];
catRibbonRender(document.getElementById('catribbon-search').value.toLowerCase().trim());
}
}
function catRibbonUpdateSlots() {
var n = parseInt(document.getElementById('custom-n-slider').value, 10) || 8;
var nIncl = Object.keys(catRibbonState).filter(function(k){ return catRibbonState[k]==='incl'; }).length;
var pct = Math.min(nIncl / n * 100, 100);
var fill = document.getElementById('catribbon-slots-fill');
if (!fill) return;
fill.style.width = pct + '%';
fill.className = 'ribbon-slots-fill' + (nIncl > n ? ' over' : nIncl === n ? ' full' : '');
document.getElementById('catribbon-slots-txt').textContent = nIncl + ' / ' + n + ' ' + t('ribbonSlotsTxt');
document.getElementById('catribbon-incl-count').textContent = nIncl + ' ' + (nIncl > 1 ? t('ribbonCatForcedP') : t('ribbonCatForced'));
}
// Returns a pool of ALL_CATEGORIES indices filtered according to catRibbon state
function getCatRibbonPool() {
var included = [], possible = [];
if (Object.keys(catRibbonState).length === 0) {
for (var i = 0; i < ALL_CATEGORIES.length; i++) possible.push(i);
return { included: included, possible: possible };
}
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
if (catRibbonState[i] === 'incl') included.push(i);
else if (catRibbonState[i] === 'poss') possible.push(i);
}
if (included.length + possible.length < 2) {
for (var i = 0; i < ALL_CATEGORIES.length; i++) possible.push(i);
}
return { included: included, possible: possible };
}

139
js/seed.js Normal file
View file

@ -0,0 +1,139 @@
function generateSeedCatsFirst() {
var cp = getCatRibbonPool();
var forcedCatIdxs = cp.included.slice();
var possibleCatIdxs = cp.possible;
var nCatRandom = Math.max(0, N_TURNS - forcedCatIdxs.length);
var catPool = shuffle(forcedCatIdxs.concat(shuffle(possibleCatIdxs).slice(0, nCatRandom * 2))).slice(0, N_TURNS);
if (catPool.length < N_TURNS) {
var allCi = ALL_CATEGORIES.map(function(_,i){return i;});
catPool = catPool.concat(shuffle(allCi.filter(function(i){return catPool.indexOf(i)===-1;}))).slice(0, N_TURNS);
}
var catIds = catPool.map(function(i){return ALL_CATEGORIES[i].id;});
var pool = getRibbonCountryPool();
var forcedIdxs = pool.included.slice();
var available = pool.possible;
var nRandom = Math.max(0, N_TURNS - forcedIdxs.length);
var eligible = available.filter(function(i){ return catIds.every(function(id){
var v = countriesDB[i][id]; return v !== false && v !== null && v !== undefined;
});});
var randomPool;
if (eligible.length >= nRandom) {
randomPool = shuffle(eligible).slice(0, nRandom);
} else {
var scored = available.map(function(i){
return {i:i, score:catIds.filter(function(id){var v=countriesDB[i][id];return v!==false&&v!==null&&v!==undefined;}).length};
}).sort(function(a,b){return b.score-a.score;});
randomPool = shuffle(scored.slice(0, Math.min(nRandom*2+4, scored.length))).slice(0, nRandom).map(function(x){return x.i;});
}
var validForced = forcedIdxs.filter(function(i){
return catIds.every(function(id){var v=countriesDB[i][id];return v!==false&&v!==null&&v!==undefined;});
});
var shortage = forcedIdxs.length - validForced.length;
var extra = shortage > 0 ? shuffle(eligible.filter(function(i){return validForced.indexOf(i)===-1;})).slice(0,shortage) : [];
var finalIdxs = shuffle(validForced.concat(extra).concat(randomPool)).slice(0, N_TURNS);
lastDraftUsed = 'cats';
return encodeSeed(finalIdxs, catPool, _currentGameMode(), TIME_PER_TURN);
}
function generateSeedCountriesFirst() {
var pool = getRibbonCountryPool();
var forcedIdxs = pool.included.slice();
var available = shuffle(pool.possible);
var nRandom = Math.max(0, N_TURNS - forcedIdxs.length);
var finalIdxs = forcedIdxs.concat(available.slice(0, nRandom)).slice(0, N_TURNS);
var chosenCountries = finalIdxs.map(function(i){ return {c: countriesDB[i], i: i}; });
var cp = getCatRibbonPool();
var forcedCatIdxs = cp.included.slice();
var possibleCatIdxs = cp.possible;
var validPossible = possibleCatIdxs.map(function(i){return {cat:ALL_CATEGORIES[i],i:i};}).filter(function(x){
return chosenCountries.every(function(co){var v=co.c[x.cat.id];return v!==false&&v!==null&&v!==undefined;});
});
var validForced = forcedCatIdxs.filter(function(i){
return chosenCountries.every(function(co){var v=co.c[ALL_CATEGORIES[i].id];return v!==false&&v!==null&&v!==undefined;});
});
var nCatRandom = Math.max(0, N_TURNS - validForced.length);
if (validForced.length + validPossible.length >= N_TURNS) {
var catPool = validForced.concat(shuffle(validPossible).slice(0, nCatRandom).map(function(x){return x.i;}));
lastDraftUsed = 'countries';
return encodeSeed(finalIdxs, catPool, _currentGameMode(), TIME_PER_TURN);
}
var allCatIds2 = ALL_CATEGORIES.map(function(c){return c.id;});
var relaxPool = shuffle(available.map(function(i){
return {i:i, score:allCatIds2.filter(function(id){var v=countriesDB[i][id];return v!==false&&v!==null&&v!==undefined;}).length};
}).sort(function(a,b){return b.score-a.score;}).slice(0, Math.min(N_TURNS*4, available.length)));
var relaxIdxs = forcedIdxs.concat(relaxPool.slice(0,nRandom).map(function(x){return x.i;})).slice(0,N_TURNS);
var relaxCountries = relaxIdxs.map(function(i){return {c:countriesDB[i],i:i};});
var relaxValidPoss = possibleCatIdxs.map(function(i){return {cat:ALL_CATEGORIES[i],i:i};}).filter(function(x){
return relaxCountries.every(function(co){var v=co.c[x.cat.id];return v!==false&&v!==null&&v!==undefined;});
});
var relaxValidForced = forcedCatIdxs.filter(function(i){
return relaxCountries.every(function(co){var v=co.c[ALL_CATEGORIES[i].id];return v!==false&&v!==null&&v!==undefined;});
});
if (relaxValidForced.length + relaxValidPoss.length >= N_TURNS) {
var nRCatRand = Math.max(0, N_TURNS - relaxValidForced.length);
var catPool2 = relaxValidForced.concat(shuffle(relaxValidPoss).slice(0, nRCatRand).map(function(x){return x.i;}));
lastDraftUsed = 'countries';
return encodeSeed(relaxIdxs, catPool2, _currentGameMode(), TIME_PER_TURN);
}
return generateSeedCatsFirst();
}
function generateSeed() {
var useCats;
if (draftMode === 'cats') { useCats = true; }
else if (draftMode === 'countries') { useCats = false; }
else { useCats = (draftCounter % 2 === 0); }
draftCounter++;
return useCats ? generateSeedCatsFirst() : generateSeedCountriesFirst();
}
function applyGameFromSeed(str) {
var decoded = decodeSeed(str);
if (!decoded) { alert(t('invalidSeed')); return false; }
var ci = decoded.countryIndices, ki = decoded.catIndices;
if (ci.some(function(i){return i<0||i>=countriesDB.length;})) { alert(t('invalidSeedIdx')); return false; }
if (ki.some(function(i){return i<0||i>=ALL_CATEGORIES.length;})) { alert(t('invalidSeedIdx')); return false; }
gameCountries = ci.map(function(i){return countriesDB[i];});
gameCategories = ki.map(function(i){return ALL_CATEGORIES[i];});
currentSeed = str;
if (!decoded.legacy) {
var m = decoded.mode;
document.body.classList.remove('hardcore','reverse-mode');
if (m === 'hardcore') {
document.body.classList.add('hardcore');
if (gameMode === 'custom') customSubMode = 'hardcore'; else gameMode = 'hardcore';
} else if (m === 'reverse') {
document.body.classList.add('reverse-mode');
reverseAssignments = {};
if (gameMode === 'custom') customSubMode = 'reverse'; else gameMode = 'reverse';
} else {
if (gameMode === 'custom') customSubMode = 'normal';
}
TIME_PER_TURN = decoded.timeSecs;
}
return true;
}
// ─── RIBBON-AWARE SEED GENERATION ────────────────────────────────────────────
// Returns a pool of countriesDB indices filtered according to ribbon state
function getRibbonCountryPool() {
var included = [], possible = [];
// If ribbon never initialized (normal game), all countries are possible
if (Object.keys(ribbonState).length === 0) {
for (var i = 0; i < countriesDB.length; i++) possible.push(i);
return { included: included, possible: possible };
}
for (var i = 0; i < countriesDB.length; i++) {
if (ribbonState[i] === 'incl') included.push(i);
else if (ribbonState[i] === 'poss') possible.push(i);
// 'excl' → ignored
}
// Safety: if possible+included is too small, open all
if (included.length + possible.length < 2) {
for (var i = 0; i < countriesDB.length; i++) possible.push(i);
}
return { included: included, possible: possible };
}

177
js/setup.js Normal file
View file

@ -0,0 +1,177 @@
// ─── CUSTOM MODE ──────────────────────────────────────────────────────────────
var customTimeSelected = 20;
var customSubMode = 'normal'; // 'normal' | 'hardcore' | 'reverse'
function selectSubModePill(mode) {
customSubMode = mode;
['normal','hardcore','reverse'].forEach(function(m) {
var el = document.getElementById('submode-pill-' + m);
if (!el) return;
el.classList.remove('active-normal','active-hardcore','active-reverse');
if (m === mode) el.classList.add('active-' + mode);
});
}
var TIME_STEPS = [1, 5, 10, 15, 20, 30, 60, 0]; // 0 = infini
function selectTimeSlider(idx) {
idx = parseInt(idx, 10);
customTimeSelected = TIME_STEPS[idx];
var labels = ['1s','5s','10s','15s','20s','30s','60s','∞'];
document.getElementById('time-slider-val').textContent = labels[idx];
// Update tick highlights
var ticks = document.querySelectorAll('.time-slider-ticks span');
ticks.forEach(function(t, i) {
t.classList.toggle('active-tick', i === idx);
});
}
function selectDraftPill(mode) {
['auto','cats','countries'].forEach(function(m) {
var el = document.getElementById('draft-pill-' + m);
if (el) el.classList.toggle('active', m === mode);
});
draftMode = mode;
}
function toggleDraftInfo() {
var el = document.getElementById('draft-tooltip');
el.classList.toggle('visible');
// Populate with current lang
el.textContent = t('customDraftInfo');
}
function openCustomPanel() {
// Sur mobile : initialiser les onglets ribbon après rendu
if (isMob()) {
setTimeout(initMobRibbons, 80);
}
document.getElementById('panel-setup').classList.add('hidden');
document.getElementById('panel-custom').classList.remove('hidden');
if (countriesDB.length > 0 && Object.keys(ribbonState).length === 0) {
ribbonInit();
}
if (ALL_CATEGORIES.length > 0 && Object.keys(catRibbonState).length === 0) {
catRibbonInit();
}
ribbonUpdateSlots();
catRibbonUpdateSlots();
}
function closeCustomPanel() {
if (isMob()) destroyMobRibbons();
document.getElementById('panel-custom').classList.add('hidden');
document.getElementById('panel-setup').classList.remove('hidden');
}
function togglePresets() {
var toggle = document.getElementById('presets-toggle');
var body = document.getElementById('presets-body');
toggle.classList.toggle('open');
body.classList.toggle('open');
}
function applyPreset(name, btn) {
// S'assurer que les ribbons sont initialisés
if (Object.keys(ribbonState).length === 0) ribbonInit();
if (Object.keys(catRibbonState).length === 0) catRibbonInit();
// Helper : set country ribbon by code whitelist
function setCountryByList(allowedCodes) {
for (var i = 0; i < countriesDB.length; i++) {
var code = (countriesDB[i].country_code || '').toUpperCase();
ribbonState[i] = (allowedCodes.indexOf(code) !== -1) ? 'poss' : 'excl';
}
ribbonSelected = {};
}
// Helper : reset all countries to possible
function resetCountries() {
for (var i = 0; i < countriesDB.length; i++) ribbonState[i] = 'poss';
ribbonSelected = {};
}
// Helper : reset all cats to possible
function resetCats() {
for (var i = 0; i < ALL_CATEGORIES.length; i++) catRibbonState[i] = 'poss';
catRibbonSelected = {};
}
if (name === 'no-russia') {
resetCountries();
for (var i = 0; i < countriesDB.length; i++) {
if ((countriesDB[i].country_code || '').toUpperCase() === 'RU') { ribbonState[i] = 'excl'; break; }
}
resetCats();
setPresetDefaults();
} else if (name === 'europe') { setCountryByList(EUROPEAN_CODES); resetCats(); setPresetDefaults();
} else if (name === 'africa') { setCountryByList(AFRICAN_CODES); resetCats(); setPresetDefaults();
} else if (name === 'americas') { setCountryByList(AMERICAS_CODES); resetCats(); setPresetDefaults();
} else if (name === 'asia') { setCountryByList(ASIAN_CODES); resetCats(); setPresetDefaults();
} else if (name === 'oceania') { setCountryByList(OCEANIA_CODES); resetCats(); setPresetDefaults();
} else if (name === 'top100pib'){ setCountryByList(TOP100_PIB_CODES);resetCats(); setPresetDefaults();
} else if (name === 'small') { setCountryByList(SMALL_COUNTRIES_CODES); resetCats(); setPresetDefaults();
} else if (name === 'france-neighbors') { setCountryByList(FRANCE_NEIGHBORS_CODES); resetCats(); setPresetDefaults();
} else if (name === 'landlocked') { setCountryByList(LANDLOCKED_CODES); resetCats(); setPresetDefaults();
} else if (name === 'islands') { setCountryByList(ISLANDS_CODES); resetCats(); setPresetDefaults();
} else if (name === 'flag-guesser') {
resetCountries(); resetCats();
// 10 tours
document.getElementById('custom-n-slider').value = 10;
ribbonOnSliderChange(10);
// 60 secondes (index 6)
document.getElementById('time-slider').value = 6; selectTimeSlider(6);
// Mode Hardcore (drapeau seul, pas de nom)
selectSubModePill('hardcore');
// Ordre : pays d'abord
selectDraftPill('countries');
} else if (name === 'sport') {
resetCountries();
for (var i = 0; i < ALL_CATEGORIES.length; i++) {
catRibbonState[i] = (SPORT_CAT_IDS.indexOf(ALL_CATEGORIES[i].id) !== -1) ? 'incl' : 'poss';
}
catRibbonSelected = {};
setPresetDefaults();
} else if (name === 'chill') {
resetCountries(); resetCats();
document.getElementById('custom-n-slider').value = 8;
document.getElementById('custom-n-display').textContent = 8;
document.getElementById('time-slider').value = 7; selectTimeSlider(7); // ∞
selectSubModePill('normal');
selectDraftPill('auto');
} else if (name === 'ultra') {
resetCountries(); resetCats();
// 16 tours
document.getElementById('custom-n-slider').value = 16;
ribbonOnSliderChange(16);
// 1 seconde (index 0)
document.getElementById('time-slider').value = 0; selectTimeSlider(0);
// Hardcore
selectSubModePill('hardcore');
// Ordre par pays
selectDraftPill('countries');
}
// Re-render
ribbonRender();
catRibbonRender();
ribbonUpdateSlots();
catRibbonUpdateSlots();
// Highlight actif
document.querySelectorAll('.preset-btn').forEach(function(b) { b.classList.remove('active'); });
if (btn) btn.classList.add('active');
}
function setPresetDefaults() {
document.getElementById('custom-n-slider').value = 8;
ribbonOnSliderChange(8);
document.getElementById('time-slider').value = 4; selectTimeSlider(4); // 20s
selectSubModePill('normal');
selectDraftPill('auto');
}

626
js/translations.js Normal file
View file

@ -0,0 +1,626 @@
// ─── I18N ─────────────────────────────────────────────────────────────────────
var currentLang = (function() { var bl = (navigator.language || navigator.userLanguage || 'fr').slice(0,2).toLowerCase(); var supported = ['fr','en','ua','de']; return supported.indexOf(bl) !== -1 ? bl : 'fr'; })();
var TRANSLATIONS = {
fr: {
subtitle: 'Le jeu de g\u00e9ographie strat\u00e9gique \u2014 8 pays, 8 cat\u00e9gories, le score le plus <span class="highlight2">faible</span> possible.',
loading: 'Chargement des donn\u00e9es...',
rule1: 'Chaque tour, associez le pays affich\u00e9 \u00e0 une cat\u00e9gorie.',
rule2: 'Votre score = la valeur du pays dans cette cat\u00e9gorie (rang, taux, nb\u2026).',
rule3: 'Chaque cat\u00e9gorie ne peut \u00eatre utilis\u00e9e qu\'\u003cstrong style="color:var(--text)"\u003eune seule fois\u003c/strong\u003e.',
rule4: 'Vous avez \u003cstrong style="color:var(--text)"\u003e20 secondes\u003c/strong\u003e par pays. Sinon\u00a0: +200 points de p\u00e9nalit\u00e9\u00a0!',
rule5: 'Objectif\u00a0: minimiser votre score total\u00a0!',
seedLabel: '\uD83D\uDD11 JOUER AVEC UNE SEED',
seedPlaceholder:'ex: 3-12-45-..._0-5-11-...',
seedLoad: 'Charger',
newGame: 'Nouvelle partie \u2192',
modeCustomLabel: 'Personnalis\u00e9 \u0026 Seed',
btnCustom: 'Personnalis\u00e9',
customTitle: 'Mode personnalis\u00e9',
customCountLabel:'Pays \u0026 cat\u00e9gories',
customCountUnit: 'tours',
customTimeLabel: 'Temps par tour',
customTimeInf: '\u221e Infini',
customSubModeLabel:'Mode de jeu',
customDraftLabel:'Ordre de sélection',
customDraftInfo: '📊 Cat\u00e9gories d\u0027abord\u00a0: on tire les cat\u00e9gories, puis les pays qui les couvrent (diversit\u00e9 des stats). 🌍 Pays d\u0027abord\u00a0: on tire les pays librement, puis on adapte les cat\u00e9gories (laisse plus de chances aux petits pays). 🔀 Auto\u00a0: alterne \u00e0 chaque partie.',
draftAuto: 'Auto',
draftCats: 'Catégories',
draftCountries: 'Pays',
customStart: 'Lancer la partie',
back: '\u2190 Retour',
btnReverse: 'Reverse',
modeReverseLabel:'Reverse',
reverseInfoBtn: 'En savoir plus',
reverseTurn: 'Cat\u00e9gorie',
btnNormal: 'Normale',
btnHardcore: 'Hardcore',
score: 'Score',
time: 'Temps',
turn: 'Tour',
of: '/',
gameOver: '\u25c8 Partie termin\u00e9e',
finalScore: 'Score',
final: 'Final',
copySeed: '\uD83D\uDCCB Copier la seed',
copyUrl: '🔗 Partager l\'URL',
playAgain: 'Rejouer',
seedShare: '\uD83D\uDD11 SEED \u2014 partagez cette partie\u00a0!',
catSelected: 'cat\u00e9gorie s\u00e9lectionn\u00e9e',
ptsAdded: 'points ajout\u00e9s au score',
noData: '\u26a0 Donn\u00e9e non disponible',
timeUp: '\u23f1 temps \u00e9coul\u00e9\u00a0!',
noAnswer: 'Pas de r\u00e9ponse',
penalty: 'p\u00e9nalit\u00e9 ajout\u00e9e au score',
hint1btn: 'Indice +25pts',
modeNormalBadge:'Classique',
modeNormalTitle:'Normal',
modeNormalDesc: '8 pays · 8 cat\u00e9gories · 20s · Indices disponibles',
modeHardBadge: 'HARDCORE',
modeHardTitle: 'Hardcore',
modeHardDesc: 'Drapeaux uniquement · 10s · Score cach\u00e9 · Aucun indice',
modeHardRules: ['Identifiez le pays gr\u00e2ce au drapeau uniquement.','Le score est la valeur du pays dans la cat\u00e9gorie choisie.','10 secondes par tour. Aucun indice disponible.','Score cach\u00e9 pendant la partie. Bonne chance\u00a0!','Objectif\u00a0: minimiser votre score total\u00a0!'],
optTitle: 'Combinaison optimale',
optYours: 'Votre score',
optBest: 'Score optimal',
optDiff: 'Diff\u00e9rence',
optBtn: '\uD83E\uDDE0 Voir la combinaison optimale',
optClose: 'Fermer',
optExplain: 'Si vous aviez su exactement quels pays allaient appara\u00eetre, voici la meilleure assignation possible\u00a0:',
optPerfect: '\uD83C\uDFC6 Score parfait\u00a0!',
hint2btn: 'D\u00e9tails +50pts',
hintLabel1: '\uD83D\uDCA1 Indice g\u00e9ographique',
hintLabel2: '\uD83D\uDD0D Informations suppl\u00e9mentaires',
skip: 'Passer \u2192',
cont: 'Continuer \u2192',
invalidSeed: 'Seed invalide\u00a0!',
invalidSeedIdx: 'Seed invalide \u2014 indices hors limites.',
enterSeed: 'Entrez une seed d\'abord\u00a0!',
taglines: ['\uD83C\uDFC6 Score exceptionnel \u2014 ma\u00eetrise totale\u00a0!','\uD83C\uDF1F Tr\u00e8s bon score \u2014 vous connaissez votre g\u00e9o\u00a0!','\uD83D\uDC4D Score correct \u2014 quelques bons choix\u00a0!','\uD83D\uDE2C Score moyen \u2014 \u00e0 am\u00e9liorer\u00a0!','\uD83D\uDCDA Score \u00e9lev\u00e9 \u2014 r\u00e9visez votre g\u00e9o\u00a0!'],
ribbonCountriesTitle: '🌍 Sélection des pays',
ribbonCatsTitle: '📊 Sélection des catégories',
ribbonSearchCountry: '🔍 Rechercher un pays…',
ribbonSearchCat: '🔍 Rechercher une catégorie…',
ribbonColExcl: '❌ Exclus',
ribbonColPoss: '🎲 Possible',
ribbonColIncl: '✅ Inclus',
ribbonColExclCat: '❌ Excluses',
ribbonColInclCat: '✅ Incluses',
ribbonSlotsForced: 'forcé',
ribbonSlotsForcedP: 'forcés',
ribbonCatForced: 'forcée',
ribbonCatForcedP: 'forcées',
ribbonSlotsTxt: 'slots forcés',
ribbonTitleToExcl: 'Remettre dans Possible',
ribbonTitleAllToExcl: 'Tout remettre dans Possible',
ribbonTitleExcl: 'Exclure la sélection',
ribbonTitleAllExcl: 'Tout exclure',
ribbonTitleIncl: 'Inclure la sélection',
ribbonTitleRemove: 'Retirer de linclusion',
revealTitle: 'Récapitulatif',
revealScoreLabel: 'Score total',
lbTotalPlayers: 'joueur',
lbTotalPlayersP: 'joueurs',
mobActToPoss: '→ Possible',
mobActAllToPoss: '→ Possible (tous)',
mobActExcl: '❌ Exclure',
mobActAllExcl: '❌ Tout exclure',
mobActForce: '✅ Forcer',
mobActRemove: '← Retirer',
// ── Daily mode ──────────────────────────────────────────────────────────
btnDaily: 'Daily Challenge',
dailyAlreadyPlayed: 'Vous avez déjà joué aujourdhui ! Revenez demain ★',
dailyLeaderboardLink: 'Voir le classement du jour →',
dailyLbTitle: 'Classement du jour',
dailyLbColPlayer: 'Joueur',
dailyLbColScore: 'Score',
dailyLbEmpty: 'Aucun score pour aujourdhui encore.',
dailySubmitTitle: 'Enregistrer mon score',
dailySubmitDesc: 'Entrez un pseudo pour apparaître dans le classement.',
dailyPseudoPlaceholder:'Votre pseudo (max 20 car.)',
dailySubmitBtn: 'Valider',
dailySkip: 'Ne pas enregistrer',
dailyRank: 'Votre rang :',
dailyOf: 'sur',
dailyErrNetwork: 'Erreur réseau — vérifiez votre connexion.',
dailyErrPlayed: 'Vous avez déjà soumis un score aujourdhui.',
dailyErrPseudo: 'Pseudo invalide (120 caractères).',
copied: 'Copi\u00e9 !',
copiedUrl: 'URL copi\u00e9e !',
revealTitleHC: 'R\u00e9v\u00e9lation',
catLabelHint1: 'Indice 1 utilis\u00e9',
catLabelHint2: 'Indice 2 utilis\u00e9',
catLabelTimeUp: 'Temps \u00e9coul\u00e9',
optColOptimal: 'Optimal',
optColMine: 'Mon score',
optColDiff: 'Diff\u00e9rence',
presetNoRussia: 'Sans la Russie',
presetEuropean: 'Européen',
presetAfrican: 'Africain',
presetAmericas: 'Amériques',
presetAsian: 'Asiatique',
presetOceanian: 'Océanie',
presetTop100PIB: 'Top 100 PIB',
presetSport: 'Sport Enjoyer',
presetChill: 'Chill',
presetUltraHC: 'Ultra Hardcore',
presetSmallPop: '- 1M hab.',
presetNeighborsFR: 'Voisins France',
presetLandlocked: 'Enclavés',
presetIslands: 'Îles seulement',
presetFlagGuesser: 'Flag Guesser',
presetHeader: 'Préréglages',
},
en: {
subtitle: 'The strategic geography game \u2014 8 countries, 8 categories, the <span class="highlight2">lowest</span> score possible.',
loading: 'Loading data...',
rule1: 'Each turn, match the displayed country to a category.',
rule2: 'Your score = the country\'s value in that category (rank, rate, count\u2026).',
rule3: 'Each category can only be used \u003cstrong style="color:var(--text)"\u003eonce\u003c/strong\u003e.',
rule4: 'You have \u003cstrong style="color:var(--text)"\u003e20 seconds\u003c/strong\u003e per country. Otherwise: +200 penalty points!',
rule5: 'Goal: minimize your total score!',
seedLabel: '\uD83D\uDD11 PLAY WITH A SEED (optional)',
seedPlaceholder:'e.g. 3-12-45-..._0-5-11-...',
seedLoad: 'Load',
newGame: 'New game \u2192',
modeCustomLabel: 'Custom \u0026 Seed',
btnCustom: 'Custom',
customTitle: 'Custom Mode',
customCountLabel:'Countries \u0026 categories',
customCountUnit: 'turns',
customTimeLabel: 'Time per turn',
customTimeInf: '\u221e Infinite',
customSubModeLabel:'Game mode',
customDraftLabel:'Selection order',
customDraftInfo: '📊 Categories first: draw categories, then find matching countries (favors stat diversity). 🌍 Countries first: draw countries freely, then adapt categories (favors geographic diversity, gives small countries more chances). 🔀 Auto: alternates each game.',
draftAuto: 'Auto',
draftCats: 'Categories',
draftCountries: 'Countries',
customStart: 'Start game',
back: '\u2190 Back',
btnReverse: 'Reverse',
modeReverseLabel:'Reverse',
reverseInfoBtn: 'Info',
reverseTurn: 'Category',
btnNormal: 'Normal',
btnHardcore: 'Hardcore',
score: 'Score',
time: 'Time',
turn: 'Round',
of: '/',
gameOver: '\u25c8 Game over',
finalScore: 'Final',
final: 'Score',
copySeed: '\uD83D\uDCCB Copy seed',
copyUrl: '🔗 Share URL',
playAgain: 'Play again',
seedShare: '\uD83D\uDD11 SEED \u2014 share this game!',
catSelected: 'selected category',
ptsAdded: 'points added to score',
noData: '\u26a0 Data not available',
timeUp: '\u23f1 time\'s up!',
noAnswer: 'No answer',
penalty: 'penalty added to score',
hintLabel2: '🔍 Additional information',
hintLabel1: '💡 Geographic hint',
hint2btn: 'Details +50pts',
hint1btn: 'Hint +25pts',
skip: 'Skip \u2192',
cont: 'Continue \u2192',
invalidSeed: 'Invalid seed!',
invalidSeedIdx: 'Invalid seed \u2014 indices out of bounds.',
enterSeed: 'Please enter a seed first!',
taglines: ['\uD83C\uDFC6 Exceptional score \u2014 total mastery!','\uD83C\uDF1F Great score \u2014 you know your geography!','\uD83D\uDC4D Decent score \u2014 a few good choices!','\uD83D\uDE2C Average score \u2014 room for improvement!','\uD83D\uDCDA High score \u2014 study your geography!'],
ribbonCountriesTitle: '🌍 Country selection',
ribbonCatsTitle: '📊 Category selection',
ribbonSearchCountry: '🔍 Search a country…',
ribbonSearchCat: '🔍 Search a category…',
ribbonColExcl: '❌ Excluded',
ribbonColPoss: '🎲 Possible',
ribbonColIncl: '✅ Included',
ribbonColExclCat: '❌ Excluded',
ribbonColInclCat: '✅ Included',
ribbonSlotsForced: 'forced',
ribbonSlotsForcedP: 'forced',
ribbonCatForced: 'forced',
ribbonCatForcedP: 'forced',
ribbonSlotsTxt: 'forced slots',
ribbonTitleToExcl: 'Move back to Possible',
ribbonTitleAllToExcl: 'Move all back to Possible',
ribbonTitleExcl: 'Exclude selection',
ribbonTitleAllExcl: 'Exclude all',
ribbonTitleIncl: 'Include selection',
ribbonTitleRemove: 'Remove from inclusion',
revealTitle: 'Summary',
revealScoreLabel: 'Total score',
lbTotalPlayers: 'player',
lbTotalPlayersP: 'players',
mobActToPoss: '→ Possible',
mobActAllToPoss: '→ Possible (all)',
mobActExcl: '❌ Exclude',
mobActAllExcl: '❌ Exclude all',
mobActForce: '✅ Force',
mobActRemove: '← Remove',
// ── Optimal score block (missing translations) ──────────────────────────
optTitle: 'Optimal combination',
optYours: 'Your score',
optBest: 'Optimal score',
optDiff: 'Difference',
optBtn: '🧠 View optimal combination',
optClose: 'Close',
optExplain: 'If you had known exactly which countries would appear, here is the best possible assignment:',
optPerfect: '🏆 Perfect score!',
// ── Daily mode ──────────────────────────────────────────────────────────
btnDaily: 'Daily Challenge',
dailyAlreadyPlayed: 'Youve already played today! Come back tomorrow ★',
dailyLeaderboardLink: 'View todays leaderboard →',
dailyLbTitle: 'Daily Leaderboard',
dailyLbColPlayer: 'Player',
dailyLbColScore: 'Score',
dailyLbEmpty: 'No scores recorded yet today.',
dailySubmitTitle: 'Submit my score',
dailySubmitDesc: 'Enter a username to appear in todays leaderboard.',
dailyPseudoPlaceholder:'Your username (max 20 chars)',
dailySubmitBtn: 'Submit',
dailySkip: 'Dont save',
dailyRank: 'Your rank:',
dailyOf: 'of',
dailyErrNetwork: 'Network error — check your connection.',
dailyErrPlayed: 'You already submitted a score today.',
dailyErrPseudo: 'Invalid username (120 characters).',
copied: 'Copied!',
copiedUrl: 'URL copied!',
revealTitleHC: 'Reveal',
catLabelHint1: 'Hint 1 used',
catLabelHint2: 'Hint 2 used',
catLabelTimeUp: 'Time up',
optColOptimal: 'Optimal',
optColMine: 'My score',
optColDiff: 'Difference',
presetNoRussia: 'No Russia',
presetEuropean: 'European',
presetAfrican: 'African',
presetAmericas: 'Americas',
presetAsian: 'Asian',
presetOceanian: 'Oceania',
presetTop100PIB: 'Top 100 GDP',
presetSport: 'Sport Enjoyer',
presetChill: 'Chill',
presetUltraHC: 'Ultra Hardcore',
presetSmallPop: '< 1M pop.',
presetNeighborsFR: 'France neighbors',
presetLandlocked: 'Landlocked',
presetIslands: 'Islands only',
presetFlagGuesser: 'Flag Guesser',
presetHeader: 'Presets',
},
ua: {
subtitle: '\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0456\u0447\u043d\u0430 \u0433\u0435\u043e\u0433\u0440\u0430\u0444\u0456\u0447\u043d\u0430 \u0433\u0440\u0430 \u2014 8 \u043a\u0440\u0430\u0457\u043d, 8 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0439, \u044f\u043a\u043e\u043c\u043e\u0433\u0430 <span class="highlight2">\u043c\u0435\u043d\u0448\u0438\u0439</span> \u0440\u0430\u0445\u0443\u043d\u043e\u043a.',
loading: '\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445...',
rule1: '\u041a\u043e\u0436\u0435\u043d \u0445\u0456\u0434 \u2014 \u043f\u043e\u0432\'\u044f\u0436\u0456\u0442\u044c \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0443 \u043a\u0440\u0430\u0457\u043d\u0443 \u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0454\u044e.',
rule2: '\u0412\u0430\u0448 \u0440\u0430\u0445\u0443\u043d\u043e\u043a = \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043a\u0440\u0430\u0457\u043d\u0438 \u0432 \u0446\u0456\u0439 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457 (\u0440\u0430\u043d\u0433, \u0432\u0456\u0434\u0441\u043e\u0442\u043e\u043a, \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c\u2026).',
rule3: '\u041a\u043e\u0436\u043d\u0443 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e \u043c\u043e\u0436\u043d\u0430 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u003cstrong style="color:var(--text)"\u003e\u043e\u0434\u0438\u043d \u0440\u0430\u0437\u003c/strong\u003e.',
rule4: '\u0423 \u0432\u0430\u0441 \u0454 \u003cstrong style="color:var(--text)"\u003e20 \u0441\u0435\u043a\u0443\u043d\u0434\u003c/strong\u003e \u043d\u0430 \u043a\u0440\u0430\u0457\u043d\u0443. \u0406\u043d\u0430\u043a\u0448\u0435: +200 \u0448\u0442\u0440\u0430\u0444\u043d\u0438\u0445 \u043e\u0447\u043e\u043a!',
rule5: '\u041c\u0435\u0442\u0430: \u043c\u0456\u043d\u0456\u043c\u0456\u0437\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0430\u0445\u0443\u043d\u043e\u043a!',
seedLabel: '\uD83D\uDD11 \u0413\u0420\u0410\u0422\u0418 \u0417 \u0421\u0406\u0414\u041e\u041c (\u043d\u0435\u043e\u0431\u043e\u0432\'\u044f\u0437\u043a\u043e\u0432\u043e)',
seedPlaceholder:'\u043d\u0430\u043f\u0440. 3-12-45-..._0-5-11-...',
seedLoad: '\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438',
newGame: '\u041d\u043e\u0432\u0430 \u0433\u0440\u0430 \u2192',
modeCustomLabel: '\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0026 Seed',
btnCustom: '\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f',
customTitle: '\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f',
customCountLabel:'\u041a\u0440\u0430\u0457\u043d\u0438 \u0026 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457',
customCountUnit: '\u0442\u0443\u0440\u0456\u0432',
customTimeLabel: '\u0427\u0430\u0441',
customTimeInf: '\u221e \u0411\u0435\u0437\u043b\u0456\u043c',
customSubModeLabel:'Режим гри',
customDraftLabel:'Порядок вибору',
customDraftInfo: '📊 Спочатку категорії: тягнемо категорії, потім країни. 🌍 Спочатку країни: тягнемо країни вільно, потім адаптуємо категорії. 🔀 Авто: чергується.',
draftAuto: 'Авто',
draftCats: 'Категорії',
draftCountries: 'Країни',
customStart: '\u041f\u043e\u0447\u0430\u0442\u0438',
back: '\u2190 \u041d\u0430\u0437\u0430\u0434',
btnReverse: '\u0420\u0435\u0432\u0435\u0440\u0441',
modeReverseLabel:'Reverse',
reverseInfoBtn: '\u0406\u043d\u0444\u043e',
reverseTurn: '\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044f',
btnNormal: '\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0430',
btnHardcore: 'Hardcore',
score: '\u0420\u0430\u0445\u0443\u043d\u043e\u043a',
time: '\u0427\u0430\u0441',
turn: '\u0425\u0456\u0434',
of: '/',
gameOver: '\u25c8 \u0413\u0440\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e',
finalScore: '\u0424\u0456\u043d\u0430\u043b\u044c\u043d\u0438\u0439',
final: '\u0420\u0430\u0445\u0443\u043d\u043e\u043a',
copySeed: '\uD83D\uDCCB \u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0441\u0456\u0434',
copyUrl: '🔗 Поділитися URL',
playAgain: '\u0413\u0440\u0430\u0442\u0438 \u0437\u043d\u043e\u0432\u0443',
seedShare: '\uD83D\uDD11 \u0421\u0406\u0414 \u2014 \u043f\u043e\u0434\u0456\u043b\u0456\u0442\u044c\u0441\u044f \u0446\u0456\u0454\u044e \u0433\u0440\u043e\u044e!',
catSelected: '\u043e\u0431\u0440\u0430\u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044f',
ptsAdded: '\u043e\u0447\u043a\u0438 \u0434\u043e\u0434\u0430\u043d\u043e \u0434\u043e \u0440\u0430\u0445\u0443\u043d\u043a\u0443',
noData: '\u26a0 \u0414\u0430\u043d\u0456 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456',
timeUp: '\u23f1 \u0447\u0430\u0441 \u0432\u0438\u0439\u0448\u043e\u0432!',
noAnswer: '\u041d\u0435\u043c\u0430\u0454 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456',
penalty: '\u0448\u0442\u0440\u0430\u0444 \u0434\u043e\u0434\u0430\u043d\u043e \u0434\u043e \u0440\u0430\u0445\u0443\u043d\u043a\u0443',
hint1btn: '\u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0430 +25',
copied: '\u2713 \u0421\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043e!',
copiedUrl: '\u2713 \u041f\u043e\u0441\u0438\u043b\u0430\u043d\u043d\u044f \u0441\u043a\u043e\u043f\u0456\u044c\u043e\u0432\u0430\u043d\u043e!',
revealTitleHC: '\u2014 \u0420\u041e\u0417\u041a\u0420\u0418\u0422\u0422\u042f \u2014',
catLabelTimeUp: '\u0427\u0430\u0441 \u0432\u0438\u0439\u0448\u043e\u0432 (+200)',
catLabelHint1: '\uD83D\uDCA1 \u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0430 (+25)',
catLabelHint2: '\uD83D\uDD0D \u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0456\u044f (+50)',
optColOptimal: '\u041e\u043f\u0442\u0438\u043c\u0430\u043b',
optColMine: '\u041c\u043e\u0454',
optColDiff: '\u0420\u0456\u0437\u043d.',
modeNormalBadge:'\u041a\u043b\u0430\u0441\u0438\u043a\u0430',
modeNormalTitle:'\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0438\u0439',
modeNormalDesc: '8 \u043a\u0440\u0430\u0457\u043d · 8 \u043a\u0430\u0442\u0435\u0433 · 20\u0441 · \u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0438',
modeHardBadge: 'HARDCORE',
modeHardTitle: 'Hardcore',
modeHardDesc: '\u041b\u0438\u0448\u0435 \u043f\u0440\u0430\u043f\u043e\u0440\u0438 · 10\u0441 · \u0420\u0430\u0445\u0443\u043d\u043e\u043a \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u0438\u0439',
modeHardRules: ['\u0406\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0443\u0439\u0442\u0435 \u043a\u0440\u0430\u0457\u043d\u0443 \u0437\u0430 \u043f\u0440\u0430\u043f\u043e\u0440\u043e\u043c.','\u0420\u0430\u0445\u0443\u043d\u043e\u043a = \u0440\u0430\u043d\u0433 \u043a\u0440\u0430\u0457\u043d\u0438.','10 \u0441\u0435\u043a\u0443\u043d\u0434. \u041f\u0456\u0434\u043a\u0430\u0437\u043e\u043a \u043d\u0435\u043c\u0430\u0454.','\u0420\u0430\u0445\u0443\u043d\u043e\u043a \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u0438\u0439. \u0423\u0434\u0430\u0447\u0456!','\u041c\u0435\u0442\u0430: \u043c\u0456\u043d\u0456\u043c\u0456\u0437\u0443\u0432\u0430\u0442\u0438 \u043e\u0447\u043a\u0438!'],
optTitle: '\u041e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u043e\u043c\u0431\u0456\u043d\u0430\u0446\u0456\u044f',
optYours: '\u0412\u0430\u0448 \u0440\u0430\u0445\u0443\u043d\u043e\u043a',
optBest: '\u041e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0430\u0445\u0443\u043d\u043e\u043a',
optDiff: '\u0420\u0456\u0437\u043d\u0438\u0446\u044f',
optBtn: '\uD83E\uDDE0 \u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0443',
optClose: '\u0417\u0430\u043a\u0440\u0438\u0442\u0438',
optExplain: '\u042f\u043a\u0449\u043e \u0432\u0438 \u0437\u043d\u0430\u043b\u0438 \u0432\u0441\u0456 \u043a\u0440\u0430\u0457\u043d\u0438 \u0437\u0430\u0440\u0430\u043d\u0456\u0435, \u043e\u0441\u044c \u043d\u0430\u0439\u043a\u0440\u0430\u0449\u0435 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043d\u044f:',
optPerfect: '\uD83C\uDFC6 \u0406\u0434\u0435\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!',
hint2btn: '\u0414\u0435\u0442\u0430\u043b\u0456 +50',
hintLabel1: '\uD83D\uDCA1 \u0413\u0435\u043e\u0433\u0440\u0430\u0444\u0456\u0447\u043d\u0430 \u043f\u0456\u0434\u043a\u0430\u0437\u043a\u0430',
hintLabel2: '\uD83D\uDD0D \u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f',
skip: '\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u2192',
cont: '\u041f\u0440\u043e\u0434\u043e\u0432\u0436\u0438\u0442\u0438 \u2192',
invalidSeed: '\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0438\u0439 \u0441\u0456\u0434!',
invalidSeedIdx: '\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0438\u0439 \u0441\u0456\u0434 \u2014 \u0456\u043d\u0434\u0435\u043a\u0441\u0438 \u043f\u043e\u0437\u0430 \u043c\u0435\u0436\u0430\u043c\u0438.',
enterSeed: '\u0421\u043f\u043e\u0447\u0430\u0442\u043a\u0443 \u0432\u0432\u0435\u0434\u0456\u0442\u044c \u0441\u0456\u0434!',
taglines: ['\uD83C\uDFC6 \u0412\u0438\u043a\u043b\u044e\u0447\u043d\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!','\uD83C\uDF1F \u0427\u0443\u0434\u043e\u0432\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!','\uD83D\uDC4D \u041d\u0435\u043f\u043e\u0433\u0430\u043d\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!','\uD83D\uDE2C \u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442!','\uD83D\uDCDA \u0412\u0438\u0441\u043e\u043a\u0438\u0439 \u0440\u0430\u0445\u0443\u043d\u043e\u043a!'],
ribbonCountriesTitle: '🌍 Вибір країн',
ribbonCatsTitle: '📊 Вибір категорій',
ribbonSearchCountry: '🔍 Пошук країни…',
ribbonSearchCat: '🔍 Пошук категорії…',
ribbonColExcl: '❌ Виключені',
ribbonColPoss: '🎲 Можливі',
ribbonColIncl: '✅ Включені',
ribbonColExclCat: '❌ Виключені',
ribbonColInclCat: '✅ Включені',
ribbonSlotsForced: 'обов’язковий',
ribbonSlotsForcedP: 'обов’язкових',
ribbonCatForced: 'обов’язкова',
ribbonCatForcedP: 'обов’язкових',
ribbonSlotsTxt: 'обов’язкові слоти',
ribbonTitleToExcl: 'Повернути до Можливі',
ribbonTitleAllToExcl: 'Усі → Можливі',
ribbonTitleExcl: 'Виключити вибрані',
ribbonTitleAllExcl: 'Виключити всі',
ribbonTitleIncl: 'Додати вибрані',
ribbonTitleRemove: 'Видалити з обов’язкових',
revealTitle: 'Підсумок',
revealScoreLabel: 'Загальний рахунок',
lbTotalPlayers: 'гравець',
lbTotalPlayersP: 'гравці',
mobActToPoss: '→ Можливі',
mobActAllToPoss: '→ Усі → Можливі',
mobActExcl: '❌ Виключити',
mobActAllExcl: '❌ Виключити всі',
mobActForce: '✅ Додати',
mobActRemove: '← Видалити',
btnDaily: 'Daily Challenge',
dailyAlreadyPlayed: 'Ви вже грали сьогодні! Поверніться завтра ★',
dailyLeaderboardLink: 'Переглянути таблицю лідерів →',
dailyLbTitle: 'Таблиця лідерів',
dailyLbColPlayer: 'Гравець',
dailyLbColScore: 'Рахунок',
dailyLbEmpty: 'Сьогодні ще немає результатів.',
dailySubmitTitle: 'Зберегти результат',
dailySubmitDesc: 'Введіть псевдонім для запису в таблицю.',
dailyPseudoPlaceholder:'Ваш псевдонім (20 симв.)',
dailySubmitBtn: 'Підтвердити',
dailySkip: 'Не зберігати',
dailyRank: 'Ваше місце:',
dailyOf: 'з',
dailyErrNetwork: 'Помилка мережі.',
dailyErrPlayed: 'Ви вже надіслали результат сьогодні.',
dailyErrPseudo: 'Невірний псевдонім (120 символів).',
presetNoRussia: 'Без Росії',
presetEuropean: 'Європейський',
presetAfrican: 'Африканський',
presetAmericas: 'Америка',
presetAsian: 'Азіатський',
presetOceanian: 'Океанія',
presetTop100PIB: 'Топ 100 ВВП',
presetSport: 'Любитель спорту',
presetChill: 'Розслаблений',
presetUltraHC: 'Ультра Хардкор',
presetSmallPop: '< 1M нас.',
presetNeighborsFR: 'Сусіди Франції',
presetLandlocked: 'Без виходу до моря',
presetIslands: 'Лише острови',
presetFlagGuesser: 'Вгадай прапор',
presetHeader: 'Шаблони',
},
de: {
subtitle: 'Das strategische Geografie-Spiel \u2014 8 L\u00e4nder, 8 Kategorien, die <span class="highlight2">niedrigste</span> Punktzahl gewinnt.',
loading: 'Daten werden geladen...',
rule1: 'Ordne jede Runde das angezeigte Land einer Kategorie zu.',
rule2: 'Dein Score = der Wert des Landes in dieser Kategorie (Rang, Quote, Anzahl\u2026).',
rule3: 'Jede Kategorie kann nur <strong style="color:var(--text)">einmal</strong> verwendet werden.',
rule4: 'Du hast <strong style="color:var(--text)">20 Sekunden</strong> pro Land. Sonst: +200 Strafpunkte!',
rule5: 'Ziel: Minimiere deinen Gesamtscore!',
seedLabel: '\uD83D\uDD11 MIT EINEM SEED SPIELEN (optional)',
seedPlaceholder:'z.B. 3-12-45-..._0-5-11-...',
seedLoad: 'Laden',
newGame: 'Neues Spiel \u2192',
modeCustomLabel: 'Benutzerdefiniert \u0026 Seed',
btnCustom: 'Benutzerdefiniert',
btnNormal: 'Normal',
btnHardcore: 'Hardcore',
btnReverse: 'Umgekehrt',
btnDaily: 'Daily Challenge',
dailyAlreadyPlayed: 'Du hast heute schon gespielt! Komm morgen wieder \u2605',
dailyLeaderboardLink: 'Heutige Bestenliste ansehen \u2192',
dailyLbTitle: 'Tages-Bestenliste',
dailyLbColPlayer: 'Spieler',
dailyLbColScore: 'Score',
dailyLbEmpty: 'Noch keine Scores f\u00fcr heute.',
dailySubmitTitle: 'Meinen Score speichern',
dailySubmitDesc: 'Gib einen Benutzernamen ein, um in der Bestenliste zu erscheinen.',
dailyPseudoPlaceholder: 'Dein Name (max 20 Zeichen)',
dailySubmitBtn: 'Absenden',
dailySkip: 'Nicht speichern',
dailyRank: 'Dein Rang:',
dailyOf: 'von',
dailyErrNetwork: 'Netzwerkfehler \u2014 pr\u00fcfe deine Verbindung.',
dailyErrPlayed: 'Du hast heute bereits einen Score eingereicht.',
dailyErrPseudo: 'Ung\u00fcltiger Benutzername (1\u201320 Zeichen).',
score: 'Score',
time: 'Zeit',
copyUrl: '\uD83D\uDD17 URL kopieren',
copySeed: '\uD83D\uDD11 Seed kopieren',
playAgain: 'Nochmal spielen',
skip: '\u00dcberspringen',
optTitle: 'Optimale Kombination',
optClose: 'Schliessen',
customTitle: 'Benutzerdefiniert',
customCountLabel: 'L\u00e4nder \u0026 Kategorien',
customCountUnit: 'Runden',
customTimeLabel: 'Zeit pro Runde',
customTimeInf: '\u221e Unbegrenzt',
customSubModeLabel: 'Spielmodus',
customDraftLabel: 'Auswahlreihenfolge',
customDraftInfo: '\uD83D\uDCCA Kategorien zuerst: Kategorien ziehen, dann passende L\u00e4nder finden (f\u00f6rdert statistische Vielfalt). \uD83C\uDF0D L\u00e4nder zuerst: L\u00e4nder frei ziehen, dann Kategorien anpassen (f\u00f6rdert geografische Vielfalt). \uD83D\uDD00 Auto: wechselt jedes Spiel.',
draftAuto: 'Auto',
draftCats: 'Kategorien',
draftCountries: 'L\u00e4nder',
customStart: 'Spiel starten',
back: '\u2190 Zur\u00fcck',
modeReverseLabel: 'Umgekehrt',
reverseInfoBtn: 'Info',
reverseTurn: 'Kategorie',
turn: 'Runde',
of: '/',
gameOver: '\u25c8 Spiel vorbei',
finalScore: 'Endergebnis',
final: 'Score',
seedShare: '\uD83D\uDD11 SEED \u2014 Teile dieses Spiel!',
catSelected: 'gew\u00e4hlte Kategorie',
ptsAdded: 'Punkte zum Score hinzugef\u00fcgt',
noData: '\u26a0 Daten nicht verf\u00fcgbar',
timeUp: '\u23f1 Zeit abgelaufen!',
noAnswer: 'Keine Antwort',
penalty: 'Strafpunkte zum Score hinzugef\u00fcgt',
hint1btn: 'Hinweis +25Pkt',
hint2btn: 'Details +50Pkt',
hintLabel1: '\uD83D\uDCA1 Geografischer Hinweis',
hintLabel2: '\uD83D\uDD0D Zusatzinformationen',
modeNormalBadge: 'NORMAL',
modeNormalTitle: 'Normaler Modus',
modeNormalDesc: 'Ländername, Flagge und Hinweise sichtbar.',
modeHardBadge: 'HARDCORE',
modeHardTitle: 'Hardcore-Modus',
modeHardDesc: 'Nur die Flagge ist sichtbar \u2014 Name und Hinweise verborgen.',
modeHardRules: ['Nur die Flagge ist sichtbar.','L\u00e4ndername und Hinweise sind verborgen.','Der Score ist w\u00e4hrend des Spiels versteckt.','Der Timer ist intensiver.','H\u00f6chste Schwierigkeit!'],
optYours: 'Dein Score',
optBest: 'Optimaler Score',
optDiff: 'Differenz',
optBtn: '\uD83E\uDDE0 Optimale Kombination anzeigen',
optExplain: 'H\u00e4ttest du gewusst, welche L\u00e4nder kommen, w\u00e4re dies die beste Zuordnung:',
optPerfect: '\uD83C\uDFC6 Perfekter Score!',
cont: 'Weiter \u2192',
invalidSeed: 'Ung\u00fcltiger Seed!',
invalidSeedIdx: 'Ung\u00fcltiger Seed \u2014 Indizes ausserhalb des g\u00fcltigen Bereichs.',
enterSeed: 'Bitte zuerst einen Seed eingeben!',
taglines: ['\uD83C\uDFC6 Herausragend \u2014 totale Meisterschaft!','\uD83C\uDF1F Toller Score \u2014 du kennst deine Geografie!','\uD83D\uDC4D Solider Score \u2014 einige gute Entscheidungen!','\uD83D\uDE2C Durchschnittlich \u2014 da geht noch was!','\uD83D\uDCDA Hoher Score \u2014 lern deine Geografie!'],
ribbonCountriesTitle: '\uD83C\uDF0D L\u00e4nderauswahl',
ribbonCatsTitle: '\uD83D\uDCCA Kategorieauswahl',
ribbonSearchCountry: '\uD83D\uDD0D Land suchen\u2026',
ribbonSearchCat: '\uD83D\uDD0D Kategorie suchen\u2026',
ribbonColExcl: '\u274c Ausgeschlossen',
ribbonColPoss: '\uD83C\uDFB2 M\u00f6glich',
ribbonColIncl: '\u2705 Eingeschlossen',
ribbonColExclCat: '\u274c Ausgeschlossen',
ribbonColInclCat: '\u2705 Eingeschlossen',
ribbonSlotsForced: 'erzwungen',
ribbonSlotsForcedP: 'erzwungen',
ribbonCatForced: 'erzwungen',
ribbonCatForcedP: 'erzwungen',
ribbonSlotsTxt: 'erzwungene Slots',
ribbonTitleToExcl: 'Zur\u00fcck zu M\u00f6glich',
ribbonTitleAllToExcl: 'Alle zur\u00fcck zu M\u00f6glich',
ribbonTitleExcl: 'Auswahl ausschliessen',
ribbonTitleAllExcl: 'Alle ausschliessen',
ribbonTitleIncl: 'Auswahl einschliessen',
ribbonTitleRemove: 'Aus Einschluss entfernen',
revealTitle: '\u00dcbersicht',
revealScoreLabel: 'Gesamtscore',
lbTotalPlayers: 'Spieler',
lbTotalPlayersP: 'Spieler',
mobActToPoss: '\u2192 M\u00f6glich',
mobActAllToPoss: '\u2192 M\u00f6glich (alle)',
mobActExcl: '\u274c Ausschliessen',
mobActAllExcl: '\u274c Alle ausschliessen',
mobActForce: '\u2705 Erzwingen',
mobActRemove: '\u2190 Entfernen',
copied: 'Kopiert!',
copiedUrl: 'URL kopiert!',
revealTitleHC: 'Aufl\u00f6sung',
catLabelHint1: 'Hinweis 1 genutzt',
catLabelHint2: 'Hinweis 2 genutzt',
catLabelTimeUp: 'Zeit abgelaufen',
optColOptimal: 'Optimal',
optColMine: 'Mein Score',
optColDiff: 'Differenz',
presetNoRussia: 'Ohne Russland',
presetEuropean: 'Europäisch',
presetAfrican: 'Afrikanisch',
presetAmericas: 'Amerika',
presetAsian: 'Asiatisch',
presetOceanian: 'Ozeanien',
presetTop100PIB: 'Top 100 BIP',
presetSport: 'Sport-Fan',
presetChill: 'Entspannt',
presetUltraHC: 'Ultra Hardcore',
presetSmallPop: '< 1M Einw.',
presetNeighborsFR: 'Nachbarn Frankreichs',
presetLandlocked: 'Binnenstaaten',
presetIslands: 'Nur Inseln',
presetFlagGuesser: 'Flaggen-Raten',
presetHeader: 'Vorlagen',
},
};
function t(key) {
var lang = TRANSLATIONS[currentLang];
if (lang && lang[key] !== undefined) return lang[key];
return TRANSLATIONS['fr'][key] || key;
}
function setLang(lang) {
currentLang = lang;
document.querySelectorAll('.lang-btn').forEach(function(b) {
b.classList.toggle('active', b.textContent.trim() === lang.toUpperCase());
});
document.documentElement.lang = (lang === 'ua') ? 'uk' : lang;
applyTranslations();
if (gameCategories.length > 0 && currentStep < gameCountries.length) rerenderCategoryButtonNames();
rerenderCurrentTurn();
}
function applyTranslations() {
document.querySelectorAll('[data-i18n]').forEach(function(el) {
el.innerHTML = t(el.dataset.i18n);
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el) {
el.placeholder = t(el.dataset.i18nPlaceholder);
});
document.querySelectorAll('[data-i18n-title]').forEach(function(el) {
el.title = t(el.dataset.i18nTitle);
});
}

67
js/ui-effects.js Normal file
View file

@ -0,0 +1,67 @@
// ─── UI EFFECTS ───────────────────────────────────────────────────────────────
function spawnRipple(btn, e) {
var r = document.createElement('span');
r.className = 'ripple-el';
var rect = btn.getBoundingClientRect();
r.style.top = (e.clientY - rect.top) + 'px';
r.style.left = (e.clientX - rect.left) + 'px';
btn.appendChild(r);
setTimeout(function() { r.remove(); }, 600);
}
function spawnParticles(btn, color) {
var rect = btn.getBoundingClientRect();
var cx = rect.left + rect.width / 2;
var cy = rect.top + rect.height / 2;
var container = document.createElement('div');
container.className = 'hint-particles';
document.body.appendChild(container);
var colors = color === 'green'
? ['#4fffb0','#a0ffda','#00e87a','#fff']
: ['#ffb34f','#ffd08a','#ff8c00','#fff'];
for (var i = 0; i < 14; i++) {
var p = document.createElement('div');
p.className = 'hint-particle';
var angle = (i / 14) * Math.PI * 2;
var dist = 40 + Math.random() * 55;
var tx = Math.cos(angle) * dist;
var ty = Math.sin(angle) * dist;
var dur = (0.45 + Math.random() * 0.3) + 's';
p.style.cssText = 'left:' + cx + 'px;top:' + cy + 'px;background:' + colors[i % colors.length] + ';--tx:' + tx + 'px;--ty:' + ty + 'px;--dur:' + dur + ';animation-delay:' + (Math.random() * 0.05) + 's';
container.appendChild(p);
}
setTimeout(function() { container.remove(); }, 900);
}
function flashScore() {
var el = document.getElementById('total-score');
el.classList.remove('score-flash');
void el.offsetWidth; // reflow
el.classList.add('score-flash');
setTimeout(function() { el.classList.remove('score-flash'); }, 500);
}
function burstStars(cx,cy){
var burst=document.createElement('div'); burst.className='star-burst'; document.body.appendChild(burst);
for(var i=0;i<12;i++){
var p=document.createElement('div'); p.className='star-particle'; p.textContent='⭐';
var angle=Math.random()*360,dist=90+Math.random()*140;
var tx=Math.round(Math.cos(angle*Math.PI/180)*dist),ty=Math.round(Math.sin(angle*Math.PI/180)*dist);
p.style.cssText='left:'+cx+'px;top:'+cy+'px;--tx:'+tx+'px;--ty:'+ty+'px;--rot:'+Math.round(Math.random()*360)+'deg;animation-delay:'+(Math.random()*0.18)+'s';
burst.appendChild(p);
}
setTimeout(function(){burst.remove();},1400);
}
// ─── TWEMOJI HELPER ──────────────────────────────────────────────────────────────
function applyEmoji(el) {
if (typeof twemoji !== 'undefined') {
twemoji.parse(el, {
folder: 'svg',
ext: '.svg',
base: 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/'
});
}
}

113
js/utils.js Normal file
View file

@ -0,0 +1,113 @@
// ─── SEED ─────────────────────────────────────────────────────────────────────
function shuffle(arr) { return arr.slice().sort(function() { return Math.random() - 0.5; }); }
// ─── SEED ENGINE v2 ───────────────────────────────────────────────────────────
// Format interne (avant encodage) :
// [version:1][mode:1][time:2][n:1][countries:n*2][cats:n*2][checksum:2]
// mode : 0=normal 1=hardcore 2=reverse
// time : secondes (0=infini)
// Encodage : Base62 → chaîne opaque, non-lisible, non-modifiable à la main
var SEED_VERSION = 2;
var BASE62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
function bytesToBase62(bytes) {
var digits = [0];
for (var b = 0; b < bytes.length; b++) {
var carry = bytes[b];
for (var d = 0; d < digits.length; d++) {
carry += digits[d] * 256;
digits[d] = carry % 62;
carry = Math.floor(carry / 62);
}
while (carry > 0) { digits.push(carry % 62); carry = Math.floor(carry / 62); }
}
var result = '';
for (var d = digits.length - 1; d >= 0; d--) result += BASE62[digits[d]];
return result || '0';
}
function base62ToBytes(str, expectedLen) {
var digits = [];
for (var i = 0; i < str.length; i++) {
var v = BASE62.indexOf(str[i]);
if (v < 0) return null;
digits.push(v);
}
var bytes = [0];
for (var d = 0; d < digits.length; d++) {
var carry = digits[d];
for (var b = 0; b < bytes.length; b++) {
carry += bytes[b] * 62;
bytes[b] = carry & 0xFF;
carry >>= 8;
}
while (carry > 0) { bytes.push(carry & 0xFF); carry >>= 8; }
}
bytes.reverse();
while (bytes.length < expectedLen) bytes.unshift(0);
if (bytes.length > expectedLen) bytes = bytes.slice(bytes.length - expectedLen);
return bytes;
}
function encodeSeed(countryIdxs, catIdxs, mode, timeSecs) {
var modeCode = (mode === 'hardcore') ? 1 : (mode === 'reverse') ? 2 : 0;
var time = (timeSecs === undefined || timeSecs === null) ? 20 : timeSecs;
var n = countryIdxs.length;
var bytes = [];
bytes.push(SEED_VERSION);
bytes.push(modeCode);
bytes.push(time & 0xFF);
bytes.push((time >> 8) & 0xFF);
bytes.push(n);
for (var i = 0; i < n; i++) { bytes.push(countryIdxs[i] & 0xFF); bytes.push((countryIdxs[i] >> 8) & 0xFF); }
for (var i = 0; i < n; i++) { bytes.push(catIdxs[i] & 0xFF); bytes.push((catIdxs[i] >> 8) & 0xFF); }
var checksum = 0;
for (var b = 0; b < bytes.length; b++) checksum = (checksum + bytes[b]) & 0xFFFF;
bytes.push(checksum & 0xFF);
bytes.push((checksum >> 8) & 0xFF);
return bytesToBase62(bytes);
}
function decodeSeed(str) {
if (!str || typeof str !== 'string') return null;
str = str.trim();
// Rétrocompatibilité ancien format "12-45_0-5"
if (/^\d[\d-]*_[\d-]*\d$/.test(str)) {
var parts = str.split('_');
if (parts.length !== 2) return null;
var ci = parts[0].split('-').map(Number);
var ki = parts[1].split('-').map(Number);
if (ci.length !== ki.length || ci.length < 2) return null;
if (ci.some(isNaN) || ki.some(isNaN)) return null;
return { countryIndices: ci, catIndices: ki, mode: 'normal', timeSecs: 20, legacy: true };
}
// Format v2 Base62 — taille header = 5 + n*4 + 2
// On essaie n=2..16 jusqu'à trouver un checksum valide
for (var n = 2; n <= 16; n++) {
var expectedLen = 5 + n * 4 + 2;
var bytes = base62ToBytes(str, expectedLen);
if (!bytes || bytes.length !== expectedLen) continue;
if (bytes[0] !== SEED_VERSION) continue;
if (bytes[4] !== n) continue;
var checksumStored = bytes[expectedLen - 2] + (bytes[expectedLen - 1] << 8);
var checksumCalc = 0;
for (var b = 0; b < expectedLen - 2; b++) checksumCalc = (checksumCalc + bytes[b]) & 0xFFFF;
if (checksumStored !== checksumCalc) continue;
var modeCode = bytes[1];
var timeSecs = bytes[2] + (bytes[3] << 8);
var ci = [], ki = [], offset = 5;
for (var i = 0; i < n; i++) { ci.push(bytes[offset] + (bytes[offset+1] << 8)); offset += 2; }
for (var i = 0; i < n; i++) { ki.push(bytes[offset] + (bytes[offset+1] << 8)); offset += 2; }
var mode = modeCode === 1 ? 'hardcore' : modeCode === 2 ? 'reverse' : 'normal';
return { countryIndices: ci, catIndices: ki, mode: mode, timeSecs: timeSecs, legacy: false };
}
return null;
}
function _currentGameMode() {
if (gameMode === 'custom') return customSubMode || 'normal';
return gameMode;
}