diff --git a/.github/workflows/codelist-drift.yml b/.github/workflows/codelist-drift.yml new file mode 100644 index 0000000..a6cd823 --- /dev/null +++ b/.github/workflows/codelist-drift.yml @@ -0,0 +1,61 @@ +name: OECD codelist drift + +# Detects drift between the committed DAC area codelists and the live OECD source. +# Runs OFF the PR path (the live endpoint is an external dependency and must never +# block contributors). On a schedule it refreshes from the live source and, if the +# committed mappings are out of date, opens a pull request with the proposed diff +# for a maintainer to review and merge. + +on: + schedule: + - cron: "0 6 * * 1" # Mondays 06:00 UTC + workflow_dispatch: {} # allow manual runs + +permissions: + contents: write + pull-requests: write + +jobs: + refresh: + name: Refresh and open PR on drift + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install uv + uses: astral-sh/setup-uv@v8.1.0 + + - name: Set up Python 3.11 + run: uv python install '3.11' + + - name: Install dependencies + run: uv sync --frozen --all-groups + + - name: Refresh DAC codelists from the live OECD source + run: uv run python -m scripts.data_maintenance.refresh_dac_codelists --write + + - name: Open a pull request if the codelists drifted + uses: peter-evans/create-pull-request@v7 + with: + branch: chore/refresh-oecd-codelists + base: main + commit-message: "chore: refresh OECD DAC area codelists" + title: "chore: refresh OECD DAC area codelists" + body: | + Automated refresh of the DAC area codelists from the live OECD source + (`development-finance-codelists.oecd.org`). + + This PR exists because the committed `dac{1,2}_codes_area.json` are out of + date with the live codelists. Review the diff before merging: + + - **Added** codes are new active DAC areas — confirm they look legitimate. + - **Changed** values are codes whose `.stat` (dotstatcode) was updated + upstream — confirm the change is intended (these affect translation output). + - Historical codes are preserved (never deleted), so old data still translates. + + Merging runs the normal CI suite. If nothing here looks right, close the PR + and investigate the source rather than merging. + labels: | + maintenance + automated + delete-branch: true diff --git a/pyproject.toml b/pyproject.toml index c2d44a8..a6af471 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,9 @@ convention = "google" [tool.ruff.lint.per-file-ignores] # Tests don't need annotations, pylint-magic-value gates, or line-length limits. -"tests/**/*.py" = ["ANN", "PLR2004", "E501"] +# PLC0415: in-test imports are a deliberate pattern for monkeypatching module +# objects (monkeypatch.setattr needs the module, not just the symbol). +"tests/**/*.py" = ["ANN", "PLR2004", "E501", "PLC0415"] "docs/examples/**/*.py" = ["E501"] # Notebooks: exploration style — don't require annotations; allow REPL patterns. "**/*.ipynb" = ["ANN", "F401", "F811", "E402"] @@ -162,6 +164,7 @@ testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] +pythonpath = ["."] markers = [ "unit: Fast unit tests (no external dependencies)", "integration: Tests that call real OECD API", @@ -179,7 +182,7 @@ addopts = [ python-version = "3.11" [tool.ty.src] -include = ["src/oda_reader"] +include = ["src/oda_reader", "scripts"] [tool.ty.analysis] # Replace pandas / numpy type information with `Any`. Eliminates the cascade of diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/data_maintenance/__init__.py b/scripts/data_maintenance/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/data_maintenance/_common.py b/scripts/data_maintenance/_common.py new file mode 100644 index 0000000..38a9d26 --- /dev/null +++ b/scripts/data_maintenance/_common.py @@ -0,0 +1,50 @@ +"""Shared helpers for data_maintenance scripts.""" + +from __future__ import annotations + +import difflib +import json +import sys + + +def dumps_canonical(mapping: dict[str, str]) -> str: + """Render a {str_code: str_value} mapping in canonical form. + + Keys that are all-digits are sorted ascending by int value; the + AREA_PASSTHROUGH sentinel ``{"(.*)": "\\\\1"}`` is always appended last + (unconditionally — callers do not need to include it in *mapping*). + Returns a JSON string with indent=2, ensure_ascii=True, trailing newline. + """ + passthrough_key = "(.*)" + digit_items = sorted( + ((k, v) for k, v in mapping.items() if k != passthrough_key and k.isdigit()), + key=lambda kv: int(kv[0]), + ) + # Non-digit, non-passthrough keys (e.g. price codes "V", "Q") sorted lexically + other_items = sorted( + (k, v) for k, v in mapping.items() if k != passthrough_key and not k.isdigit() + ) + # Preserve any explicit passthrough value from mapping; default to "\\1" + passthrough_val = mapping.get(passthrough_key, "\\1") + ordered: dict[str, str] = ( + dict(digit_items) | dict(other_items) | {passthrough_key: passthrough_val} + ) + return json.dumps(ordered, indent=2, ensure_ascii=True) + "\n" + + +def emit_json_diff( + original: str, + proposed: str, + *, + fromfile: str, + tofile: str, +) -> None: + """Write a unified diff of *original* vs *proposed* to stdout.""" + sys.stdout.writelines( + difflib.unified_diff( + original.splitlines(keepends=True), + proposed.splitlines(keepends=True), + fromfile=fromfile, + tofile=tofile, + ) + ) diff --git a/scripts/data_maintenance/_static_overlays.py b/scripts/data_maintenance/_static_overlays.py new file mode 100644 index 0000000..59305ee --- /dev/null +++ b/scripts/data_maintenance/_static_overlays.py @@ -0,0 +1,16 @@ +"""Hand-maintained, source-less SDMX rules; never scraped. + +These constants are version-controlled overlays applied on top of the +area codelists fetched from the OECD codelist app. They must match the +committed mapping files in src/oda_reader/schemas/mappings/ exactly. +""" + +# dac1_codes_prices.json +DAC1_PRICES: dict[str, str] = {"V": "A", "Q": "D"} + +# dac1_codes_flow_types.json — includes the SDMX regex passthrough rule +DAC1_FLOW_TYPES: dict[str, str] = {"115": "C", "112": "D", "(.*)": "\\1"} + +# Appended as the last entry of every rendered area map so that unknown +# codes pass through unchanged in the SDMX mapping engine. +AREA_PASSTHROUGH: dict[str, str] = {"(.*)": "\\1"} diff --git a/scripts/data_maintenance/refresh_dac_codelists.py b/scripts/data_maintenance/refresh_dac_codelists.py new file mode 100644 index 0000000..73c6427 --- /dev/null +++ b/scripts/data_maintenance/refresh_dac_codelists.py @@ -0,0 +1,438 @@ +"""Refresh OECD DAC area codelist snapshots. + +Fetches two OECD area codelists (Providers=5, Recipients=13) via the +two-step ASPX/VIEWSTATE POST handshake, projects each into the existing +{dac_numeric_code: dotstat_code} shape, prints a unified diff against +the committed mappings/*.json, and never auto-writes. + +Usage: + # diff-only (default): + uv run python -m scripts.data_maintenance.refresh_dac_codelists + + # capture raw fixtures for offline testing (writes and exits): + uv run python -m scripts.data_maintenance.refresh_dac_codelists \\ + --capture-fixtures tests/fixtures/oecd + + # apply proposed changes: + uv run python -m scripts.data_maintenance.refresh_dac_codelists --write +""" + +from __future__ import annotations + +import argparse +import datetime +import http.cookiejar +import json +import re +import sys +import urllib.parse +import urllib.request +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +from oda_reader.common import ImporterPaths +from scripts.data_maintenance._common import dumps_canonical, emit_json_diff + +_OECD_URL = "https://development-finance-codelists.oecd.org/CodesList.aspx" + +# Both dac1 and dac2 use providers(5) union recipients(13) — the committed dac1 +# file contains recipient countries (AFG, ALB, AGO...), so dac1 is not +# providers-only. Providers are listed first so they win on key collision +# within the live union. +_AREA_CODELIST_IDS: dict[str, list[str]] = { + "dac1": ["5", "13"], + "dac2": ["5", "13"], +} + +_PROVENANCE_PATH = Path(__file__).resolve().parent.parent.parent / ( + "src/oda_reader/schemas/mappings/_provenance.json" +) + + +@dataclass(frozen=True, slots=True, kw_only=True) +class RefreshSettings: + """Runtime settings for the refresh tool.""" + + target: str | None = None # "dac1" | "dac2" | None (both) + capture_fixtures: Path | None = None + write: bool = False + check: bool = False # exit non-zero if the live data differs from committed + + +def fetch_codelist_json( + codelist_id: str, *, standard: str = "0", timeout: int = 30 +) -> bytes: + """Fetch a codelist from the OECD codelist app via the ASPX two-step handshake. + + Args: + codelist_id: OECD codelist ID (e.g. "5" for providers, "13" for recipients). + standard: DDL_CRSTOSSD value (default "0"). + timeout: Per-request timeout in seconds. + + Returns: + Raw JSON bytes from the OECD server. + """ + cj = http.cookiejar.CookieJar() + opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) + opener.addheaders = [("User-Agent", "oda-importer/refresh-dac-codelists")] + + def _hidden(html: str, name: str) -> str: + m = re.search(rf']*name="{re.escape(name)}"[^>]*value="([^"]*)"', html) + return m.group(1) if m else "" + + # Step 1: GET the page to collect initial VIEWSTATE tokens + with opener.open(_OECD_URL, timeout=timeout) as r: + html = r.read().decode("utf-8", "replace") + + base: dict[str, str] = { + "__EVENTARGUMENT": "", + "__LASTFOCUS": "", + "__VIEWSTATE": _hidden(html, "__VIEWSTATE"), + "__VIEWSTATEGENERATOR": _hidden(html, "__VIEWSTATEGENERATOR"), + "__VIEWSTATEENCRYPTED": "", + "__EVENTVALIDATION": _hidden(html, "__EVENTVALIDATION"), + "DDl_codeslist": codelist_id, + "DDL_CRSTOSSD": standard, + "Cblstatus$0": "on", + "Cblstatus$2": "on", + "tb_search": "", + } + + # Step 2: POST to select the codelist (triggers VIEWSTATE re-seed) + p1 = dict(base, __EVENTTARGET="DDl_codeslist") + with opener.open( + urllib.request.Request( + _OECD_URL, + data=urllib.parse.urlencode(p1).encode(), + method="POST", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + ), + timeout=timeout, + ) as r2: + h2 = r2.read().decode("utf-8", "replace") + + # Re-scrape tokens from the updated page + base["__VIEWSTATE"] = _hidden(h2, "__VIEWSTATE") + base["__VIEWSTATEGENERATOR"] = _hidden(h2, "__VIEWSTATEGENERATOR") + base["__EVENTVALIDATION"] = _hidden(h2, "__EVENTVALIDATION") + + # Step 3: POST to request JSON download + p2 = dict(base, __EVENTTARGET="", b_json="JSON") + with opener.open( + urllib.request.Request( + _OECD_URL, + data=urllib.parse.urlencode(p2).encode(), + method="POST", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + ), + timeout=timeout, + ) as r3: + return r3.read() + + +def _unwrap_rows(raw_json: bytes) -> tuple[list[dict[str, Any]], str | None]: + """Unwrap the OECD JSON envelope into (rows, date_last_modified).""" + payload = json.loads(raw_json) + codelist_list = payload["codelists"]["codelist"] + if not codelist_list: + raise ValueError( + "Expected at least one codelist in payload['codelists']['codelist']; got empty list" + ) + codelist_node = codelist_list[0] + rows: list[dict[str, Any]] = codelist_node["codelist-items"]["codelist-item"] + date_last_modified: str | None = payload["codelists"].get("date-last-modified") + return rows, date_last_modified + + +def parse_area_codelist(raw_json: bytes) -> dict[str, str]: + """Parse raw OECD JSON into {str(code): dotstatcode or iso-alpha-3-code}. + + The mapping value is the code the .stat schema uses (the conversion target of + ``convert_*_to_dotstat_codes``), so ``dotstatcode`` is preferred. It equals the + ISO3 code for ordinary countries but diverges where OECD's .stat code differs + from the ISO code (e.g. Kosovo: dotstatcode ``XKV`` vs iso3 ``XKX`` — the .stat + value is ``XKV``). ``iso-alpha-3-code`` is the fallback, and for multilateral + organisations without an ISO3 the dotstatcode is the only code (e.g. provider + 807 → ``1UN016``). Only active rows with at least one code field are included. + + Args: + raw_json: Raw bytes from fetch_codelist_json. + + Returns: + Mapping of DAC numeric code (string) to .stat code (string). + """ + rows, _ = _unwrap_rows(raw_json) + result: dict[str, str] = {} + for row in rows: + if row.get("status", "").lower() != "active": + continue + dotstat: str | None = row.get("dotstatcode") or None + iso3: str | None = row.get("iso-alpha-3-code") or None + code_val = dotstat or iso3 + if code_val is None: + continue + result[str(row["code"])] = code_val + return result + + +def build_live_union(target: str, raw_by_id: dict[str, bytes]) -> dict[str, str]: + """Merge the live area codelists for *target* into one digit-keyed map. + + Providers (codelist 5) are listed first in ``_AREA_CODELIST_IDS`` and win on + collision within the live union. + + Args: + target: "dac1" or "dac2". + raw_by_id: Mapping of codelist_id → raw JSON bytes. + + Returns: + Mapping of DAC numeric code (string) to .stat code (string). + """ + live: dict[str, str] = {} + for cid in _AREA_CODELIST_IDS[target]: + for k, v in parse_area_codelist(raw_by_id[cid]).items(): + live.setdefault(k, v) + return live + + +def build_area_map( + *, + target: str, + raw_by_id: dict[str, bytes], + committed: dict[str, str], +) -> dict[str, str]: + """Build the canonical area map using additive-merge semantics. + + The proposed map = committed union live, so that historical codes absent from + the current OECD endpoint (Anguilla, Aruba, Bermuda, Cayman Islands, etc.) + are NEVER dropped -- they are still needed to translate historical ODA data. + Live values win on conflict (e.g. code 57 XKV->XKX, 918 4EU003->4EU001), + surfacing genuine updates transparently in the diff. + + Merge order: + 1. Start from committed digit-keyed entries (preserves every historical code). + 2. Build the live union (providers first; providers win on collision within live). + 3. Overlay live onto committed (``merged.update(live)``) so live wins on conflict. + 4. ``dumps_canonical`` handles int-sort and appends AREA_PASSTHROUGH last. + + Args: + target: "dac1" or "dac2". + raw_by_id: Mapping of codelist_id → raw JSON bytes. + committed: The currently-committed digit-keyed area map (without passthrough + sentinel); loaded from ``ImporterPaths.mappings / "_codes_area.json"`` + and passed in by ``run()`` to keep this function pure. + + Returns: + Ordered {str_code: str_dotstat} dict, digit keys ascending then ``(.*)`` last. + """ + if target not in _AREA_CODELIST_IDS: + raise ValueError( + f"unknown target {target!r}; expected one of {set(_AREA_CODELIST_IDS)}" + ) + + live = build_live_union(target, raw_by_id) + + # Start from committed digit keys (drop passthrough sentinel if present — + # dumps_canonical re-appends it). + merged: dict[str, str] = {k: v for k, v in committed.items() if k.isdigit()} + # Overlay live: live values win on conflict. + merged.update(live) + return merged + + +def _render_provenance( + *, + query_date: str, + codelist_ids: list[str], + date_last_modified: str | None, +) -> str: + """Render the provenance sidecar as a JSON string.""" + doc = { + "source_url": _OECD_URL, + "aspx_codelist_ids": codelist_ids, + "oecd_query_date": query_date, + "codelist_date_last_modified": date_last_modified, + } + return json.dumps(doc, indent=2, ensure_ascii=True) + "\n" + + +def run(*, settings: RefreshSettings) -> int: + """Fetch OECD DAC area codelists and print diffs against committed mappings. + + Returns: + 0 on success, 1 on error. + """ + targets = ( + list(_AREA_CODELIST_IDS.keys()) + if settings.target is None + else [settings.target] + ) + if settings.target is not None and settings.target not in _AREA_CODELIST_IDS: + print( + f"error: unknown --target {settings.target!r}; " + f"choose from {sorted(_AREA_CODELIST_IDS)}", + file=sys.stderr, + ) + return 1 + + # Collect the set of codelist IDs we actually need + needed_ids: list[str] = [] + for t in targets: + for cid in _AREA_CODELIST_IDS[t]: + if cid not in needed_ids: + needed_ids.append(cid) + + capture_dir = settings.capture_fixtures + if capture_dir is not None: + capture_dir.mkdir(parents=True, exist_ok=True) + + raw_by_id: dict[str, bytes] = {} + last_modified_by_id: dict[str, str | None] = {} + + for cid in needed_ids: + print(f"Fetching codelist {cid}...", file=sys.stderr) + try: + raw = fetch_codelist_json(cid) + except Exception as exc: + print(f"error fetching codelist {cid}: {exc}", file=sys.stderr) + return 1 + + if capture_dir is not None: + out_path = capture_dir / f"codelist_{cid}.json" + out_path.write_bytes(raw) + print(f" wrote {out_path}", file=sys.stderr) + else: + raw_by_id[cid] = raw + _, dlm = _unwrap_rows(raw) + last_modified_by_id[cid] = dlm + + if capture_dir is not None: + return 0 + + query_date = datetime.date.today().isoformat() + + drift_detected = False + for target in targets: + area_path = ImporterPaths.mappings / f"{target}_codes_area.json" + original_text = ( + area_path.read_text(encoding="utf-8") if area_path.exists() else "" + ) + # Load the committed digit-keyed map; drop passthrough — build_area_map + # (via dumps_canonical) re-appends it as the last entry. + committed_full: dict[str, str] = ( + json.loads(original_text) if original_text else {} + ) + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + # Count how many live codes this target fetches + live_union = build_live_union(target, raw_by_id) + + proposed_map = build_area_map( + target=target, raw_by_id=raw_by_id, committed=committed_digits + ) + proposed_text = dumps_canonical(proposed_map) + + # Per-target summary + added = [k for k in live_union if k not in committed_digits] + changed = [ + k + for k in live_union + if k in committed_digits and live_union[k] != committed_digits[k] + ] + historical = [k for k in committed_digits if k not in live_union] + print( + f"[{target}] {len(live_union)} live, {len(committed_digits)} committed" + f" → +{len(added)} added, {len(changed)} changed," + f" {len(historical)} historical preserved", + file=sys.stderr, + ) + if changed: + for k in changed: + print( + f" changed {k}: {committed_digits[k]!r} → {live_union[k]!r}", + file=sys.stderr, + ) + + if original_text == proposed_text: + print(f"[{target}] No changes detected.", file=sys.stderr) + else: + drift_detected = True + emit_json_diff( + original_text, + proposed_text, + fromfile=f"{target}_codes_area.json (current)", + tofile=f"{target}_codes_area.json (proposed)", + ) + if settings.write: + area_path.write_text(proposed_text, encoding="utf-8") + print(f"[{target}] wrote {area_path}", file=sys.stderr) + + if settings.write: + # Update provenance sidecar with all fetched IDs + all_ids = sorted( + {cid for t in targets for cid in _AREA_CODELIST_IDS[t]}, key=int + ) + dlm = next((v for v in last_modified_by_id.values() if v is not None), None) + prov_text = _render_provenance( + query_date=query_date, + codelist_ids=all_ids, + date_last_modified=dlm, + ) + _PROVENANCE_PATH.write_text(prov_text, encoding="utf-8") + print(f"wrote {_PROVENANCE_PATH}", file=sys.stderr) + + if settings.check and drift_detected: + print( + "error: committed codelists are out of date with the live OECD source; " + "run `python -m scripts.data_maintenance.refresh_dac_codelists --write` " + "and review the diff.", + file=sys.stderr, + ) + return 1 + + return 0 + + +def main(argv: list[str] | None = None) -> None: + """CLI entry point.""" + parser = argparse.ArgumentParser( + description="Refresh OECD DAC area codelist mappings." + ) + parser.add_argument( + "--target", + choices=list(_AREA_CODELIST_IDS.keys()), + default=None, + help="Which target to refresh (default: both dac1 and dac2).", + ) + parser.add_argument( + "--capture-fixtures", + metavar="DIR", + type=Path, + default=None, + help="Write raw codelist JSON to DIR and exit (for offline testing).", + ) + parser.add_argument( + "--write", + action="store_true", + default=False, + help="Write proposed changes to the mappings directory (default: diff only).", + ) + parser.add_argument( + "--check", + action="store_true", + default=False, + help="Exit non-zero if the live source differs from committed (for CI drift checks).", + ) + args = parser.parse_args(argv) + settings = RefreshSettings( + target=args.target, + capture_fixtures=args.capture_fixtures, + write=args.write, + check=args.check, + ) + sys.exit(run(settings=settings)) + + +if __name__ == "__main__": + main() diff --git a/src/oda_reader/schemas/crs_translation.py b/src/oda_reader/schemas/crs_translation.py index a50f6ed..48afaa2 100644 --- a/src/oda_reader/schemas/crs_translation.py +++ b/src/oda_reader/schemas/crs_translation.py @@ -3,9 +3,7 @@ from oda_reader.common import ImporterPaths from oda_reader.schemas.dac1_translation import prices_mapping from oda_reader.schemas.schema_tools import map_amount_type_codes, map_area_codes -from oda_reader.schemas.xml_tools import ( - read_mapping, -) +from oda_reader.schemas.xml_tools import read_mapping MAPPINGS = { "dac2_codes_area": ImporterPaths.mappings / "dac2_codes_area.json", @@ -16,30 +14,28 @@ def area_code_mapping() -> dict: """Reads the area code mapping.""" return read_mapping( - MAPPINGS["dac2_codes_area"], keys_as_int=True, update=lambda d: d + MAPPINGS["dac2_codes_area"], + keys_as_int=True, ) | read_mapping( - MAPPINGS["area_code_corrections"], keys_as_int=True, update=lambda d: d + MAPPINGS["area_code_corrections"], + keys_as_int=True, ) def convert_crs_to_dotstat_codes(df: pd.DataFrame) -> pd.DataFrame: """Convert the CRS data to the .stat schema. + Args: - df (pd.DataFrame): The CRS data. + df: The CRS data. Returns: - pd.DataFrame: The CRS data in the .stat schema. + The CRS data in the .stat schema. """ - # Get the area codes area_codes = area_code_mapping() - - # Prices mapping prices_codes = prices_mapping() - # Map the donor codes df = map_area_codes(df, area_code_mapping=area_codes) - # Map region codes df = map_area_codes( df, area_code_mapping=area_codes, @@ -47,7 +43,6 @@ def convert_crs_to_dotstat_codes(df: pd.DataFrame) -> pd.DataFrame: target_column="recipient_code", ) - # Map the prices codes df = map_amount_type_codes( df, prices_mapping=prices_codes, diff --git a/src/oda_reader/schemas/dac1_translation.py b/src/oda_reader/schemas/dac1_translation.py index 77ad70a..e687996 100644 --- a/src/oda_reader/schemas/dac1_translation.py +++ b/src/oda_reader/schemas/dac1_translation.py @@ -6,13 +6,7 @@ map_amount_type_codes, map_area_codes, ) -from oda_reader.schemas.xml_tools import ( - extract_dac_to_area_codes, - extract_datatypes_to_prices_codes, - extract_flowtype_to_flowtype_codes, - parse_xml, - read_mapping, -) +from oda_reader.schemas.xml_tools import read_mapping MAPPINGS = { "dac1_codes_area": ImporterPaths.mappings / "dac1_codes_area.json", @@ -22,39 +16,15 @@ "dac1_codes_flow_types": ImporterPaths.mappings / "dac1_codes_flow_types.json", } -DAC1_TRANSLATION_SCHEMA_URL = ( - "https://stats.oecd.org/FileView2.aspx?IDFile=b9613c8b-b31d-4fd9-ba95-5f129729d693" -) - - -def update_dac1_translation_mappings() -> None: - """Pipeline to update the DAC1 translation mappings""" - xml_data = parse_xml(xml_url=DAC1_TRANSLATION_SCHEMA_URL)["Structures"] - - # price mapping - extract_datatypes_to_prices_codes( - xml_dict=xml_data, filename=MAPPINGS["dac1_codes_prices"] - ) - - # flow types mapping - extract_flowtype_to_flowtype_codes( - xml_dict=xml_data, filename=MAPPINGS["dac1_codes_flow_types"] - ) - - # oecd dac donor codes to area codes - extract_dac_to_area_codes(xml_dict=xml_data, filename=MAPPINGS["dac1_codes_area"]) - def area_code_mapping() -> dict: """Reads the area code mapping.""" return read_mapping( MAPPINGS["dac1_codes_area"], keys_as_int=True, - update=update_dac1_translation_mappings, ) | read_mapping( MAPPINGS["area_code_corrections"], keys_as_int=True, - update=update_dac1_translation_mappings, ) @@ -63,11 +33,9 @@ def prices_mapping() -> dict: return read_mapping( MAPPINGS["dac1_codes_prices"], keys_as_int=False, - update=update_dac1_translation_mappings, ) | read_mapping( MAPPINGS["prices_corrections"], keys_as_int=False, - update=update_dac1_translation_mappings, ) @@ -76,21 +44,15 @@ def flow_types_mapping() -> dict: return read_mapping( MAPPINGS["dac1_codes_flow_types"], keys_as_int=False, - update=update_dac1_translation_mappings, ) def convert_dac1_to_dotstat_codes(df: pd.DataFrame) -> pd.DataFrame: - # Get the area codes area_codes = area_code_mapping() - - # Prices mapping prices_codes = prices_mapping() - # Map the donor codes df = map_area_codes(df, area_code_mapping=area_codes) - # Map the prices codes df = convert_unit_measure_to_amount_type(df) df = map_amount_type_codes(df, prices_mapping=prices_codes) diff --git a/src/oda_reader/schemas/dac2_translation.py b/src/oda_reader/schemas/dac2_translation.py index 6e7b021..c5b61b9 100644 --- a/src/oda_reader/schemas/dac2_translation.py +++ b/src/oda_reader/schemas/dac2_translation.py @@ -3,15 +3,7 @@ from oda_reader.common import ImporterPaths from oda_reader.schemas.dac1_translation import prices_mapping from oda_reader.schemas.schema_tools import map_amount_type_codes, map_area_codes -from oda_reader.schemas.xml_tools import ( - extract_dac_to_area_codes, - parse_xml, - read_mapping, -) - -DAC2_TRANSLATION_SCHEMA_URL = ( - "https://stats.oecd.org/FileView2.aspx?IDFile=997ad7fb-48f1-4046-945d-067dc5bec7de" -) +from oda_reader.schemas.xml_tools import read_mapping MAPPINGS = { "dac2_codes_area": ImporterPaths.mappings / "dac2_codes_area.json", @@ -19,45 +11,31 @@ } -def update_dac2_translation_mappings() -> None: - """Pipeline to update the DAC2A translation mappings""" - xml_data = parse_xml(xml_url=DAC2_TRANSLATION_SCHEMA_URL)["Structures"] - - # oecd dac donor codes to area codes - extract_dac_to_area_codes(xml_dict=xml_data, filename=MAPPINGS["dac2_codes_area"]) - - def area_code_mapping() -> dict: """Reads the area code mapping.""" return read_mapping( MAPPINGS["dac2_codes_area"], keys_as_int=True, - update=update_dac2_translation_mappings, ) | read_mapping( MAPPINGS["area_code_corrections"], keys_as_int=True, - update=update_dac2_translation_mappings, ) def convert_dac2a_to_dotstat_codes(df: pd.DataFrame) -> pd.DataFrame: """Convert the DAC2A data to the .stat schema. + Args: - df (pd.DataFrame): The DAC2A data. + df: The DAC2A data. Returns: - pd.DataFrame: The DAC2A data in the .stat schema. + The DAC2A data in the .stat schema. """ - # Get the area codes area_codes = area_code_mapping() - - # Prices mapping prices_codes = prices_mapping() - # Map the donor codes df = map_area_codes(df, area_code_mapping=area_codes) - # Map region codes df = map_area_codes( df, area_code_mapping=area_codes, @@ -65,7 +43,6 @@ def convert_dac2a_to_dotstat_codes(df: pd.DataFrame) -> pd.DataFrame: target_column="recipient_code", ) - # Map the prices codes df = map_amount_type_codes( df, prices_mapping=prices_codes, diff --git a/src/oda_reader/schemas/mappings/_provenance.json b/src/oda_reader/schemas/mappings/_provenance.json new file mode 100644 index 0000000..899b983 --- /dev/null +++ b/src/oda_reader/schemas/mappings/_provenance.json @@ -0,0 +1,9 @@ +{ + "source_url": "https://development-finance-codelists.oecd.org/CodesList.aspx", + "aspx_codelist_ids": [ + "5", + "13" + ], + "oecd_query_date": "2026-06-15", + "codelist_date_last_modified": "2026-06-15T13:06:09" +} diff --git a/src/oda_reader/schemas/mappings/dac1_codes_area.json b/src/oda_reader/schemas/mappings/dac1_codes_area.json index 6497af1..f7fffb9 100644 --- a/src/oda_reader/schemas/mappings/dac1_codes_area.json +++ b/src/oda_reader/schemas/mappings/dac1_codes_area.json @@ -1,405 +1,394 @@ { - "801": "AUS", "1": "AUT", "2": "BEL", - "301": "CAN", - "434": "CHL", - "437": "COL", - "336": "CRI", - "68": "CZE", "3": "DNK", - "82": "EST", - "18": "FIN", "4": "FRA", "5": "DEU", - "40": "GRC", - "75": "HUN", - "20": "ISL", - "21": "IRL", - "546": "ISR", "6": "ITA", - "701": "JPN", - "742": "KOR", - "83": "LVA", - "84": "LTU", - "22": "LUX", - "358": "MEX", "7": "NLD", - "820": "NZL", "8": "NOR", - "76": "POL", "9": "PRT", - "69": "SVK", - "61": "SVN", - "50": "ESP", "10": "SWE", "11": "CHE", - "55": "TUR", "12": "GBR", - "302": "USA", - "625": "AFG", + "18": "FIN", + "20": "ISL", + "21": "IRL", + "22": "LUX", + "26": "MCO", + "30": "CYP", + "35": "GIB", + "40": "GRC", + "45": "MLT", + "50": "ESP", + "55": "TUR", + "57": "XKV", + "60": "YUG_F", + "61": "SVN", + "62": "HRV", + "63": "SRB", + "64": "BIH", + "65": "MNE", + "66": "MKD", + "68": "CZE", + "69": "SVK", + "70": "LIE", "71": "ALB", + "72": "BGR", + "75": "HUN", + "76": "POL", + "77": "ROU", + "82": "EST", + "83": "LVA", + "84": "LTU", + "85": "UKR", + "86": "BLR", + "87": "RUS", + "88": "SFRY_X", + "89": "E_X", + "93": "MDA", + "104": "9OTH019", "130": "DZA", + "133": "LBY", + "136": "MAR", + "139": "TUN", + "142": "EGY", + "189": "F4_X", + "218": "ZAF", "225": "AGO", - "376": "AIA", - "377": "ATG", - "425": "ARG", - "610": "ARM", - "373": "ABW", - "611": "AZE", - "328": "BHS", - "530": "BHR", - "666": "BGD", - "329": "BRB", - "86": "BLR", - "352": "BLZ", - "236": "BEN", - "331": "BMU", - "630": "BTN", - "428": "BOL", - "64": "BIH", "227": "BWA", - "431": "BRA", - "388": "VGB", - "725": "BRN", - "72": "BGR", - "287": "BFA", "228": "BDI", - "230": "CPV", - "728": "KHM", "229": "CMR", - "386": "CYM", + "230": "CPV", "231": "CAF", "232": "TCD", - "730": "CHN", "233": "COM", "234": "COG", - "831": "COK", - "247": "CIV", - "62": "HRV", - "338": "CUB", - "30": "CYP", - "740": "PRK", "235": "COD", - "274": "DJI", - "378": "DMA", - "340": "DOM", - "440": "ECU", - "142": "EGY", - "342": "SLV", - "245": "GNQ", - "271": "ERI", - "280": "SWZ", + "236": "BEN", "238": "ETH", - "443": "FLK", - "832": "FJI", - "840": "PYF", "239": "GAB", "240": "GMB", - "612": "GEO", "241": "GHA", - "35": "GIB", - "381": "GRD", - "347": "GTM", "243": "GIN", "244": "GNB", - "446": "GUY", - "349": "HTI", - "351": "HND", - "735": "HKG", - "645": "IND", - "738": "IDN", - "540": "IRN", - "543": "IRQ", - "354": "JAM", - "549": "JOR", - "613": "KAZ", + "245": "GNQ", + "247": "CIV", "248": "KEN", - "836": "KIR", - "57": "XKV", - "552": "KWT", - "614": "KGZ", - "745": "LAO", - "555": "LBN", "249": "LSO", "251": "LBR", - "133": "LBY", - "70": "LIE", - "748": "MAC", "252": "MDG", "253": "MWI", - "751": "MYS", - "655": "MDV", "255": "MLI", - "45": "MLT", - "859": "MHL", "256": "MRT", "257": "MUS", "258": "MYT", - "860": "FSM", - "93": "MDA", - "26": "MCO", - "753": "MNG", - "65": "MNE", - "385": "MSR", - "136": "MAR", "259": "MOZ", - "635": "MMR", - "275": "NAM", - "845": "NRU", - "660": "NPL", - "850": "NCL", - "364": "NIC", "260": "NER", "261": "NGA", - "856": "NIU", - "66": "MKD", - "858": "MNP", - "558": "OMN", - "665": "PAK", - "861": "PLW", - "550": "PSE", - "366": "PAN", - "862": "PNG", - "451": "PRY", - "454": "PER", - "755": "PHL", - "561": "QAT", - "77": "ROU", - "87": "RUS", + "265": "ZWE", "266": "RWA", - "276": "SHN", - "382": "KNA", - "383": "LCA", - "384": "VCT", - "880": "WSM", "268": "STP", - "566": "SAU", "269": "SEN", - "63": "SRB", "270": "SYC", + "271": "ERI", "272": "SLE", - "761": "SGP", - "866": "SLB", "273": "SOM", - "218": "ZAF", - "279": "SSD", - "640": "LKA", + "274": "DJI", + "275": "NAM", + "276": "SHN", "278": "SDN", - "457": "SUR", - "573": "SYR", - "732": "TWN", - "615": "TJK", + "279": "SSD", + "280": "SWZ", "282": "TZA", - "764": "THA", - "765": "TLS", "283": "TGO", - "868": "TKL", - "870": "TON", + "285": "UGA", + "287": "BFA", + "288": "ZMB", + "289": "F6_X", + "298": "F_X", + "301": "CAN", + "302": "USA", + "328": "BHS", + "329": "BRB", + "331": "BMU", + "336": "CRI", + "338": "CUB", + "340": "DOM", + "342": "SLV", + "347": "GTM", + "349": "HTI", + "351": "HND", + "352": "BLZ", + "354": "JAM", + "358": "MEX", + "361": "SXM", + "364": "NIC", + "366": "PAN", + "373": "ABW", "375": "TTO", - "139": "TUN", - "616": "TKM", + "376": "AIA", + "377": "ATG", + "378": "DMA", + "381": "GRD", + "382": "KNA", + "383": "LCA", + "384": "VCT", + "385": "MSR", + "386": "CYM", "387": "TCA", - "872": "TUV", - "285": "UGA", - "85": "UKR", - "576": "ARE", + "388": "VGB", + "389": "A5_X", + "425": "ARG", + "428": "BOL", + "431": "BRA", + "434": "CHL", + "437": "COL", + "440": "ECU", + "443": "FLK", + "446": "GUY", + "451": "PRY", + "454": "PER", + "457": "SUR", "460": "URY", - "617": "UZB", - "854": "VUT", "463": "VEN", - "769": "VNM", - "876": "WLF", - "580": "YEM", - "288": "ZMB", - "265": "ZWE", - "10040": "ACP", - "10202": "SIDS", - "10203": "FSCAC", - "10004": "A", - "10056": "A2", - "10055": "A3", - "10054": "A4", - "10006": "A7", - "10010": "E", - "10001": "F", - "10050": "F3", - "10051": "F5", - "10052": "F7", - "10053": "F8", - "10011": "F97", - "10012": "O", - "10057": "O7", - "10058": "O8", - "10059": "O9", - "10007": "S", - "20005": "ALLD", - "20002": "ALLM", - "10200": "ALLR", - "10150": "ALLMR", - "20918": "4EU001", - "917": "4EU002", - "918": "4EU003", - "919": "4EU004", - "927": "4EU999", - "20013": "5IMF0", + "489": "A7_X", + "498": "A_X", + "530": "BHR", + "540": "IRN", + "543": "IRQ", + "546": "ISR", + "549": "JOR", + "550": "PSE", + "552": "KWT", + "555": "LBN", + "558": "OMN", + "561": "QAT", + "566": "SAU", + "573": "SYR", + "576": "ARE", + "580": "YEM", + "589": "F97_X", + "610": "ARM", + "611": "AZE", + "612": "GEO", + "613": "KAZ", + "614": "KGZ", + "615": "TJK", + "616": "TKM", + "617": "UZB", + "619": "S4_X", + "625": "AFG", + "630": "BTN", + "635": "MMR", + "640": "LKA", + "645": "IND", + "655": "MDV", + "660": "NPL", + "665": "PAK", + "666": "BGD", + "679": "S7_X", + "689": "S4_S7_X", + "701": "JPN", + "725": "BRN", + "728": "KHM", + "730": "CHN", + "732": "TWN", + "735": "HKG", + "738": "IDN", + "740": "PRK", + "742": "KOR", + "745": "LAO", + "748": "MAC", + "751": "MYS", + "753": "MNG", + "755": "PHL", + "761": "SGP", + "764": "THA", + "765": "TLS", + "769": "VNM", + "789": "S97_X", + "798": "S_X", + "801": "AUS", + "807": "1UN016", + "811": "9OTH011", + "812": "9OTH018", + "816": "5RDB999", + "820": "NZL", + "831": "COK", + "832": "FJI", + "836": "KIR", + "840": "PYF", + "845": "NRU", + "850": "NCL", + "854": "VUT", + "856": "NIU", + "858": "MNP", + "859": "MHL", + "860": "FSM", + "861": "PLW", + "862": "PNG", + "866": "SLB", + "868": "TKL", + "870": "TON", + "872": "TUV", + "876": "WLF", + "880": "WSM", + "889": "O_X", + "900": "5WBG003", + "901": "5WB001", + "902": "5WB004", + "903": "5WBG002", + "904": "5WB003", + "905": "5WB002", + "906": "5RDB004", "907": "5IMF01", - "958": "5IMF02", - "20022": "5RDB0", - "20016": "5AFDB0", + "909": "5IDB001", + "910": "5RDB003", + "912": "5IDB002", "913": "5AFDB001", "914": "5AFDB002", - "20015": "5ASDB0", "915": "5ASDB01", "916": "5ASDB02", - "20014": "5IDB0", - "909": "5IDB001", - "912": "5IDB002", - "1019": "5IDB003", - "1024": "5RDB001", - "981": "5RDB002", - "910": "5RDB003", - "906": "5RDB004", - "1013": "5RDB005", - "1015": "5RDB006", - "990": "5RDB007", - "1037": "5RDB008", - "976": "5RDB009", - "1044": "5RDB010", - "1045": "5RDB011", - "816": "5RDB999", - "20021": "1UN0", - "1020": "1UN001", - "1047": "1UN002", + "917": "4EU002", + "918": "4EU001", + "919": "4EU004", + "921": "9OTH003", + "923": "1UN011", + "927": "4EU999", + "928": "1UN026", "932": "1UN003", - "988": "1UN004", - "944": "1UN005", "940": "1UN006", - "1048": "1UN007", - "1039": "1UN008", - "965": "1UN009", - "1038": "1UN010", - "923": "1UN011", - "1046": "1UN012", - "971": "1UN013", - "959": "1UN014", + "944": "1UN005", "948": "1UN015", - "807": "1UN016", - "974": "1UN017", - "967": "1UN018", - "963": "1UN019", + "951": "9OTH020", + "953": "9OTH002", + "958": "5IMF02", + "959": "1UN014", + "960": "1UN023", "962": "1UN020", - "1406": "1UN021", + "963": "1UN019", "964": "1UN022", - "960": "1UN023", + "965": "1UN009", "966": "1UN024", - "1050": "1UN025", - "928": "1UN026", - "1023": "1UN027", - "1404": "1UN028", - "1401": "1UN029", + "967": "1UN018", + "971": "1UN013", + "974": "1UN017", "975": "1UN999", - "20012": "5WBG0", - "20033": "5WB0", - "901": "5WB001", - "905": "5WB002", - "904": "5WB003", - "902": "5WB004", - "903": "5WBG002", - "900": "5WBG003", - "20034": "9OTH0", - "1012": "9OTH001", - "953": "9OTH002", - "921": "9OTH003", - "1053": "9OTH004", - "1025": "9OTH005", + "976": "5RDB009", + "978": "9OTH021", + "981": "5RDB002", + "988": "1UN004", + "989": "9OTH998", + "990": "5RDB007", + "997": "9OTH014", + "998": "DPGC_X", "1011": "9OTH006", + "1012": "9OTH001", + "1013": "5RDB005", + "1014": "9OTH022", + "1015": "5RDB006", + "1016": "9OTH015", + "1017": "9OTH007", "1018": "9OTH010", + "1019": "5IDB003", + "1020": "1UN001", + "1023": "1UN027", + "1024": "5RDB001", + "1025": "9OTH005", + "1027": "F3_X", + "1028": "F5_X", + "1029": "F7_X", + "1030": "F8_X", + "1031": "A4_X", + "1032": "A3_X", + "1033": "O7_X", + "1034": "O8_X", + "1035": "O9_X", + "1037": "5RDB008", + "1038": "1UN010", + "1039": "1UN008", + "1040": "1UN032", "1041": "9OTH008", + "1044": "5RDB010", + "1045": "5RDB011", + "1046": "1UN012", + "1047": "1UN002", + "1048": "1UN007", + "1049": "9OTH017", + "1050": "1UN025", + "1052": "9OTH016", + "1053": "9OTH004", + "1054": "9OTH023", + "1055": "9OTH024", + "1057": "1UN030", + "1058": "5IMF03", "1311": "9OTH009", - "811": "9OTH011", "1312": "9OTH012", "1313": "9OTH013", - "997": "9OTH014", - "1016": "9OTH015", - "1052": "9OTH016", - "1049": "9OTH017", - "812": "9OTH018", - "104": "9OTH019", - "951": "9OTH020", - "978": "9OTH021", - "1014": "9OTH022", - "1054": "9OTH023", - "989": "9OTH998", - "20018": "9OTH999", - "21600": "9PRIV0", - "1637": "9PRIV1637", - "1625": "9PRIV1625", - "1609": "9PRIV1609", - "1646": "9PRIV1646", + "1401": "1UN029", + "1403": "1UN031", + "1404": "1UN028", + "1406": "1UN021", "1601": "9PRIV1601", - "1640": "9PRIV1640", - "1620": "9PRIV1620", - "1645": "9PRIV1645", + "1602": "9PLG0_NL", + "1603": "9PLG0_SE", + "1604": "9PLG0_GB", + "1605": "9PRIV1605", + "1606": "9PRIV1606", + "1608": "9PRIV1608", + "1609": "9PRIV1609", + "1610": "9PRIV1610", + "1611": "9PRIV1611", + "1612": "9PRIV1612", + "1613": "9PRIV1613", "1614": "9PRIV1614", "1615": "9PRIV1615", - "1632": "9PRIV1632", + "1616": "9PRIV1616", "1617": "9PRIV1617", "1618": "9PRIV1618", - "1644": "9PRIV1644", - "1627": "9PRIV1627", - "1616": "9PRIV1616", - "1626": "9PRIV1626", - "1612": "9PRIV1612", - "1642": "9PRIV1642", - "1608": "9PRIV1608", - "1636": "9PRIV1636", "1619": "9PRIV1619", - "1639": "9PRIV1639", - "1613": "9PRIV1613", - "1633": "9PRIV1633", - "1648": "9PRIV1648", - "1638": "9PRIV1638", - "1606": "9PRIV1606", - "1610": "9PRIV1610", - "1631": "9PRIV1631", - "1605": "9PRIV1605", + "1620": "9PRIV1620", "1621": "9PRIV1621", - "1611": "9PRIV1611", "1622": "9PRIV1622", - "1643": "9PRIV1643", "1623": "9PRIV1623", - "1641": "9PRIV1641", - "1629": "9PRIV1629", - "1628": "9PRIV1628", "1624": "9PRIV1624", + "1625": "9PRIV1625", + "1626": "9PRIV1626", + "1627": "9PRIV1627", + "1628": "9PRIV1628", + "1629": "9PRIV1629", "1630": "9PRIV1630", - "20035": "9PLG0", - "1602": "9PLG0_NL", - "1647": "9PLG0_DE", + "1631": "9PRIV1631", + "1632": "9PRIV1632", + "1633": "9PRIV1633", "1634": "9PLG0_NO", - "1604": "9PLG0_GB", - "1603": "9PLG0_SE", - "20001": "DAC", - "20003": "G7", - "20004": "DACEUEC", - "20006": "WXDAC", - "20007": "W_O", - "20011": "DACEU", - "60": "YUG_F", - "88": "SFRY_X", - "89": "E_X", - "298": "F_X", - "361": "SXM", - "489": "A7_X", - "498": "A_X", - "789": "S97_X", - "798": "S_X", - "889": "O_X", + "1636": "9PRIV1636", + "1637": "9PRIV1637", + "1638": "9PRIV1638", + "1639": "9PRIV1639", + "1640": "9PRIV1640", + "1641": "9PRIV1641", + "1642": "9PRIV1642", + "1643": "9PRIV1643", + "1644": "9PRIV1644", + "1645": "9PRIV1645", + "1646": "9PRIV1646", + "1647": "9PLG0_DE", + "1648": "9PRIV1648", + "1649": "9PRIV1649", + "1650": "9PRIV1650", "9998": "DPGC_X", + "10001": "F", "10002": "F4", "10003": "F6", + "10004": "A", "10005": "A5", + "10006": "A7", + "10007": "S", + "10010": "E", + "10011": "F97", + "10012": "O", "10016": "LDC", "10017": "OLIC", "10018": "LMIC", @@ -407,12 +396,48 @@ "10024": "INC_X", "10025": "MADCT", "10030": "HIPC", + "10040": "ACP", "10045": "OLICWB", "10046": "LMICWB", "10047": "UMICWB", "10048": "HICSWB", "10049": "INCWB_X", + "10050": "F3", + "10051": "F5", + "10052": "F7", + "10053": "F8", + "10054": "A4", + "10055": "A3", + "10056": "A2", + "10057": "O7", + "10058": "O8", + "10059": "O9", "10100": "DPGC", + "10150": "ALLMR", + "10200": "ALLR", "10201": "LLDC", + "10202": "SIDS", + "10203": "FSCAC", + "20001": "DAC", + "20002": "ALLM", + "20003": "G7", + "20004": "DACEUEC", + "20005": "ALLD", + "20006": "WXDAC", + "20007": "W_O", + "20011": "DACEU", + "20012": "5WBG0", + "20013": "5IMF0", + "20014": "5IDB0", + "20015": "5ASDB0", + "20016": "5AFDB0", + "20018": "9OTH999", + "20021": "1UN0", + "20022": "5RDB0", + "20033": "5WB0", + "20034": "9OTH0", + "20035": "9PLG0", + "20918": "4EU001", + "21600": "9PRIV0", "(.*)": "\\1" } diff --git a/src/oda_reader/schemas/mappings/dac2_codes_area.json b/src/oda_reader/schemas/mappings/dac2_codes_area.json index 8d399e1..0bf3c4e 100644 --- a/src/oda_reader/schemas/mappings/dac2_codes_area.json +++ b/src/oda_reader/schemas/mappings/dac2_codes_area.json @@ -1,405 +1,396 @@ { - "801": "AUS", "1": "AUT", "2": "BEL", - "301": "CAN", - "434": "CHL", - "437": "COL", - "336": "CRI", - "68": "CZE", "3": "DNK", - "82": "EST", - "18": "FIN", "4": "FRA", "5": "DEU", - "40": "GRC", - "75": "HUN", - "20": "ISL", - "21": "IRL", - "546": "ISR", "6": "ITA", - "701": "JPN", - "742": "KOR", - "83": "LVA", - "84": "LTU", - "22": "LUX", - "358": "MEX", "7": "NLD", - "820": "NZL", "8": "NOR", - "76": "POL", "9": "PRT", - "69": "SVK", - "61": "SVN", - "50": "ESP", "10": "SWE", "11": "CHE", - "55": "TUR", "12": "GBR", - "302": "USA", - "625": "AFG", + "18": "FIN", + "20": "ISL", + "21": "IRL", + "22": "LUX", + "26": "MCO", + "30": "CYP", + "35": "GIB", + "40": "GRC", + "45": "MLT", + "50": "ESP", + "55": "TUR", + "57": "XKV", + "60": "YUG_F", + "61": "SVN", + "62": "HRV", + "63": "SRB", + "64": "BIH", + "65": "MNE", + "66": "MKD", + "68": "CZE", + "69": "SVK", + "70": "LIE", "71": "ALB", + "72": "BGR", + "75": "HUN", + "76": "POL", + "77": "ROU", + "82": "EST", + "83": "LVA", + "84": "LTU", + "85": "UKR", + "86": "BLR", + "87": "RUS", + "88": "SFRY_X", + "89": "E_X", + "93": "MDA", + "104": "9OTH019", "130": "DZA", + "133": "LBY", + "136": "MAR", + "139": "TUN", + "142": "EGY", + "189": "F4_X", + "218": "ZAF", "225": "AGO", - "376": "AIA", - "377": "ATG", - "425": "ARG", - "610": "ARM", - "373": "ABW", - "611": "AZE", - "328": "BHS", - "530": "BHR", - "666": "BGD", - "329": "BRB", - "86": "BLR", - "352": "BLZ", - "236": "BEN", - "331": "BMU", - "630": "BTN", - "428": "BOL", - "64": "BIH", "227": "BWA", - "431": "BRA", - "388": "VGB", - "725": "BRN", - "72": "BGR", - "287": "BFA", "228": "BDI", - "230": "CPV", - "728": "KHM", "229": "CMR", - "386": "CYM", + "230": "CPV", "231": "CAF", "232": "TCD", - "730": "CHN", "233": "COM", "234": "COG", - "831": "COK", - "247": "CIV", - "62": "HRV", - "338": "CUB", - "30": "CYP", - "740": "PRK", "235": "COD", - "274": "DJI", - "378": "DMA", - "340": "DOM", - "440": "ECU", - "142": "EGY", - "342": "SLV", - "245": "GNQ", - "271": "ERI", - "280": "SWZ", + "236": "BEN", "238": "ETH", - "443": "FLK", - "832": "FJI", - "840": "PYF", "239": "GAB", "240": "GMB", - "612": "GEO", "241": "GHA", - "35": "GIB", - "381": "GRD", - "347": "GTM", "243": "GIN", "244": "GNB", - "446": "GUY", - "349": "HTI", - "351": "HND", - "735": "HKG", - "645": "IND", - "738": "IDN", - "540": "IRN", - "543": "IRQ", - "354": "JAM", - "549": "JOR", - "613": "KAZ", + "245": "GNQ", + "247": "CIV", "248": "KEN", - "836": "KIR", - "57": "XKV", - "552": "KWT", - "614": "KGZ", - "745": "LAO", - "555": "LBN", "249": "LSO", "251": "LBR", - "133": "LBY", - "70": "LIE", - "748": "MAC", "252": "MDG", "253": "MWI", - "751": "MYS", - "655": "MDV", "255": "MLI", - "45": "MLT", - "859": "MHL", "256": "MRT", "257": "MUS", "258": "MYT", - "860": "FSM", - "93": "MDA", - "26": "MCO", - "753": "MNG", - "65": "MNE", - "385": "MSR", - "136": "MAR", "259": "MOZ", - "635": "MMR", - "275": "NAM", - "845": "NRU", - "660": "NPL", - "850": "NCL", - "364": "NIC", "260": "NER", "261": "NGA", - "856": "NIU", - "66": "MKD", - "858": "MNP", - "558": "OMN", - "665": "PAK", - "861": "PLW", - "550": "PSE", - "366": "PAN", - "862": "PNG", - "451": "PRY", - "454": "PER", - "755": "PHL", - "561": "QAT", - "77": "ROU", - "87": "RUS", + "265": "ZWE", "266": "RWA", - "276": "SHN", - "382": "KNA", - "383": "LCA", - "384": "VCT", - "880": "WSM", "268": "STP", - "566": "SAU", "269": "SEN", - "63": "SRB", "270": "SYC", + "271": "ERI", "272": "SLE", - "761": "SGP", - "866": "SLB", "273": "SOM", - "218": "ZAF", - "279": "SSD", - "640": "LKA", + "274": "DJI", + "275": "NAM", + "276": "SHN", "278": "SDN", - "457": "SUR", - "573": "SYR", - "732": "TWN", - "615": "TJK", + "279": "SSD", + "280": "SWZ", "282": "TZA", - "764": "THA", - "765": "TLS", "283": "TGO", - "868": "TKL", - "870": "TON", + "285": "UGA", + "287": "BFA", + "288": "ZMB", + "289": "F6_X", + "298": "F_X", + "301": "CAN", + "302": "USA", + "328": "BHS", + "329": "BRB", + "331": "BMU", + "336": "CRI", + "338": "CUB", + "340": "DOM", + "342": "SLV", + "347": "GTM", + "349": "HTI", + "351": "HND", + "352": "BLZ", + "354": "JAM", + "358": "MEX", + "361": "SXM", + "364": "NIC", + "366": "PAN", + "373": "ABW", "375": "TTO", - "139": "TUN", - "616": "TKM", + "376": "AIA", + "377": "ATG", + "378": "DMA", + "381": "GRD", + "382": "KNA", + "383": "LCA", + "384": "VCT", + "385": "MSR", + "386": "CYM", "387": "TCA", - "872": "TUV", - "285": "UGA", - "85": "UKR", - "576": "ARE", + "388": "VGB", + "389": "A5_X", + "425": "ARG", + "428": "BOL", + "431": "BRA", + "434": "CHL", + "437": "COL", + "440": "ECU", + "443": "FLK", + "446": "GUY", + "451": "PRY", + "454": "PER", + "457": "SUR", "460": "URY", - "617": "UZB", - "854": "VUT", "463": "VEN", - "769": "VNM", - "876": "WLF", + "489": "A7_X", + "498": "A_X", + "530": "BHR", + "540": "IRN", + "543": "IRQ", + "546": "ISR", + "549": "JOR", + "550": "PSE", + "552": "KWT", + "555": "LBN", + "558": "OMN", + "561": "QAT", + "566": "SAU", + "573": "SYR", + "576": "ARE", "580": "YEM", - "288": "ZMB", - "265": "ZWE", - "10040": "ACP", - "10202": "SIDS", - "10203": "FSCAC", - "10004": "A", - "10056": "A2", - "10055": "A3", - "10054": "A4", - "10006": "A7", - "10010": "E", - "10001": "F", - "10050": "F3", - "10051": "F5", - "10052": "F7", - "10053": "F8", - "10011": "F97", - "10012": "O", - "10057": "O7", - "10058": "O8", - "10059": "O9", - "10007": "S", - "20005": "ALLD", - "20002": "ALLM", - "10200": "ALLR", - "10150": "ALLMR", - "20918": "4EU001", - "917": "4EU002", - "918": "4EU003", - "919": "4EU004", - "927": "4EU999", - "20013": "5IMF0", + "589": "F97_X", + "610": "ARM", + "611": "AZE", + "612": "GEO", + "613": "KAZ", + "614": "KGZ", + "615": "TJK", + "616": "TKM", + "617": "UZB", + "619": "S4_X", + "625": "AFG", + "630": "BTN", + "635": "MMR", + "640": "LKA", + "645": "IND", + "655": "MDV", + "660": "NPL", + "665": "PAK", + "666": "BGD", + "679": "S7_X", + "689": "S4_S7_X", + "701": "JPN", + "725": "BRN", + "728": "KHM", + "730": "CHN", + "732": "TWN", + "735": "HKG", + "738": "IDN", + "740": "PRK", + "742": "KOR", + "745": "LAO", + "748": "MAC", + "751": "MYS", + "753": "MNG", + "755": "PHL", + "761": "SGP", + "764": "THA", + "765": "TLS", + "769": "VNM", + "789": "S97_X", + "798": "S_X", + "801": "AUS", + "807": "1UN016", + "811": "9OTH011", + "812": "9OTH018", + "816": "5RDB999", + "820": "NZL", + "831": "COK", + "832": "FJI", + "836": "KIR", + "840": "PYF", + "845": "NRU", + "850": "NCL", + "854": "VUT", + "856": "NIU", + "858": "MNP", + "859": "MHL", + "860": "FSM", + "861": "PLW", + "862": "PNG", + "866": "SLB", + "868": "TKL", + "870": "TON", + "872": "TUV", + "876": "WLF", + "880": "WSM", + "889": "O_X", + "900": "5WBG003", + "901": "5WB001", + "902": "5WB004", + "903": "5WBG002", + "904": "5WB003", + "905": "5WB002", + "906": "5RDB004", "907": "5IMF01", - "958": "5IMF02", - "20022": "5RDB0", - "20016": "5AFDB0", + "909": "5IDB001", + "910": "5RDB003", + "912": "5IDB002", "913": "5AFDB001", "914": "5AFDB002", - "20015": "5ASDB0", "915": "5ASDB01", "916": "5ASDB02", - "20014": "5IDB0", - "909": "5IDB001", - "912": "5IDB002", - "1019": "5IDB003", - "1024": "5RDB001", - "981": "5RDB002", - "910": "5RDB003", - "906": "5RDB004", - "1013": "5RDB005", - "1015": "5RDB006", - "990": "5RDB007", - "1037": "5RDB008", - "976": "5RDB009", - "1044": "5RDB010", - "1045": "5RDB011", - "816": "5RDB999", - "20021": "1UN0", - "1020": "1UN001", - "1047": "1UN002", + "917": "4EU002", + "918": "4EU001", + "919": "4EU004", + "921": "9OTH003", + "923": "1UN011", + "927": "4EU999", + "928": "1UN026", "932": "1UN003", - "988": "1UN004", - "944": "1UN005", "940": "1UN006", - "1048": "1UN007", - "1039": "1UN008", - "965": "1UN009", - "1038": "1UN010", - "923": "1UN011", - "1046": "1UN012", - "971": "1UN013", - "959": "1UN014", + "944": "1UN005", "948": "1UN015", - "807": "1UN016", - "974": "1UN017", - "967": "1UN018", - "963": "1UN019", + "951": "9OTH020", + "953": "9OTH002", + "958": "5IMF02", + "959": "1UN014", + "960": "1UN023", "962": "1UN020", - "1406": "1UN021", + "963": "1UN019", "964": "1UN022", - "960": "1UN023", + "965": "1UN009", "966": "1UN024", - "1050": "1UN025", - "928": "1UN026", - "1023": "1UN027", - "1404": "1UN028", - "1401": "1UN029", + "967": "1UN018", + "971": "1UN013", + "974": "1UN017", "975": "1UN999", - "20012": "5WBG0", - "20033": "5WB0", - "901": "5WB001", - "905": "5WB002", - "904": "5WB003", - "902": "5WB004", - "903": "5WBG002", - "900": "5WBG003", - "20034": "9OTH0", - "1012": "9OTH001", - "953": "9OTH002", - "921": "9OTH003", - "1053": "9OTH004", - "1025": "9OTH005", + "976": "5RDB009", + "978": "9OTH021", + "981": "5RDB002", + "988": "1UN004", + "989": "9OTH998", + "990": "5RDB007", + "997": "9OTH014", + "998": "DPGC_X", "1011": "9OTH006", + "1012": "9OTH001", + "1013": "5RDB005", + "1014": "9OTH022", + "1015": "5RDB006", + "1016": "9OTH015", + "1017": "9OTH007", "1018": "9OTH010", + "1019": "5IDB003", + "1020": "1UN001", + "1023": "1UN027", + "1024": "5RDB001", + "1025": "9OTH005", + "1027": "F3_X", + "1028": "F5_X", + "1029": "F7_X", + "1030": "F8_X", + "1031": "A4_X", + "1032": "A3_X", + "1033": "O7_X", + "1034": "O8_X", + "1035": "O9_X", + "1037": "5RDB008", + "1038": "1UN010", + "1039": "1UN008", + "1040": "1UN032", "1041": "9OTH008", + "1044": "5RDB010", + "1045": "5RDB011", + "1046": "1UN012", + "1047": "1UN002", + "1048": "1UN007", + "1049": "9OTH017", + "1050": "1UN025", + "1052": "9OTH016", + "1053": "9OTH004", + "1054": "9OTH023", + "1055": "9OTH024", + "1057": "1UN030", + "1058": "5IMF03", "1311": "9OTH009", - "811": "9OTH011", "1312": "9OTH012", "1313": "9OTH013", - "997": "9OTH014", - "1016": "9OTH015", - "1052": "9OTH016", - "1049": "9OTH017", - "812": "9OTH018", - "104": "9OTH019", - "951": "9OTH020", - "978": "9OTH021", - "1014": "9OTH022", - "1054": "9OTH023", - "989": "9OTH998", - "20018": "9OTH999", - "21600": "9PRIV0", - "1637": "9PRIV1637", - "1625": "9PRIV1625", - "1609": "9PRIV1609", - "1646": "9PRIV1646", + "1401": "1UN029", + "1403": "1UN031", + "1404": "1UN028", + "1406": "1UN021", "1601": "9PRIV1601", - "1640": "9PRIV1640", - "1620": "9PRIV1620", - "1645": "9PRIV1645", + "1602": "9PLG0_NL", + "1603": "9PLG0_SE", + "1604": "9PLG0_GB", + "1605": "9PRIV1605", + "1606": "9PRIV1606", + "1608": "9PRIV1608", + "1609": "9PRIV1609", + "1610": "9PRIV1610", + "1611": "9PRIV1611", + "1612": "9PRIV1612", + "1613": "9PRIV1613", "1614": "9PRIV1614", "1615": "9PRIV1615", - "1632": "9PRIV1632", + "1616": "9PRIV1616", "1617": "9PRIV1617", "1618": "9PRIV1618", - "1644": "9PRIV1644", - "1627": "9PRIV1627", - "1616": "9PRIV1616", - "1626": "9PRIV1626", - "1612": "9PRIV1612", - "1642": "9PRIV1642", - "1608": "9PRIV1608", - "1636": "9PRIV1636", "1619": "9PRIV1619", - "1639": "9PRIV1639", - "1613": "9PRIV1613", - "1633": "9PRIV1633", - "1648": "9PRIV1648", - "1638": "9PRIV1638", - "1606": "9PRIV1606", - "1610": "9PRIV1610", - "1631": "9PRIV1631", - "1605": "9PRIV1605", + "1620": "9PRIV1620", "1621": "9PRIV1621", - "1611": "9PRIV1611", "1622": "9PRIV1622", - "1643": "9PRIV1643", "1623": "9PRIV1623", - "1641": "9PRIV1641", - "1629": "9PRIV1629", - "1628": "9PRIV1628", "1624": "9PRIV1624", + "1625": "9PRIV1625", + "1626": "9PRIV1626", + "1627": "9PRIV1627", + "1628": "9PRIV1628", + "1629": "9PRIV1629", "1630": "9PRIV1630", - "20035": "9PLG0", - "1602": "9PLG0_NL", - "1647": "9PLG0_DE", + "1631": "9PRIV1631", + "1632": "9PRIV1632", + "1633": "9PRIV1633", "1634": "9PLG0_NO", - "1604": "9PLG0_GB", - "1603": "9PLG0_SE", - "20001": "DAC", - "20003": "G7", - "20004": "DACEU_EC", - "20006": "WXDAC", - "20007": "W_O", - "20011": "DACEU", - "60": "YUG_F", - "88": "SFRY_X", - "89": "E_X", - "298": "F_X", - "361": "SXM", - "489": "A7_X", - "498": "A_X", - "789": "S97_X", - "798": "S_X", - "889": "O_X", + "1636": "9PRIV1636", + "1637": "9PRIV1637", + "1638": "9PRIV1638", + "1639": "9PRIV1639", + "1640": "9PRIV1640", + "1641": "9PRIV1641", + "1642": "9PRIV1642", + "1643": "9PRIV1643", + "1644": "9PRIV1644", + "1645": "9PRIV1645", + "1646": "9PRIV1646", + "1647": "9PLG0_DE", + "1648": "9PRIV1648", + "1649": "9PRIV1649", + "1650": "9PRIV1650", "9998": "DPGC_X", + "10001": "F", "10002": "F4", "10003": "F6", + "10004": "A", "10005": "A5", + "10006": "A7", + "10007": "S", + "10008": "S97", + "10009": "S4_S7", + "10010": "E", + "10011": "F97", + "10012": "O", "10016": "LDC", "10017": "OLIC", "10018": "LMIC", @@ -407,26 +398,48 @@ "10024": "INC_X", "10025": "MADCT", "10030": "HIPC", + "10040": "ACP", "10045": "OLICWB", "10046": "LMICWB", "10047": "UMICWB", "10048": "HICSWB", "10049": "INCWB_X", + "10050": "F3", + "10051": "F5", + "10052": "F7", + "10053": "F8", + "10054": "A4", + "10055": "A3", + "10056": "A2", + "10057": "O7", + "10058": "O8", + "10059": "O9", "10100": "DPGC", + "10150": "ALLMR", + "10200": "ALLR", "10201": "LLDC", - "189": "F4_X", - "289": "F6_X", - "389": "A5_X", - "589": "F97_X", - "619": "S4_X", - "689": "S4_S7_X", - "1027": "F3_X", - "1029": "F7_X", - "1030": "F8_X", - "1031": "A4_X", - "1032": "A3_X", - "10008": "S97", - "10009": "S4_S7", - "1055": "9OTH024", + "10202": "SIDS", + "10203": "FSCAC", + "20001": "DAC", + "20002": "ALLM", + "20003": "G7", + "20004": "DACEU_EC", + "20005": "ALLD", + "20006": "WXDAC", + "20007": "W_O", + "20011": "DACEU", + "20012": "5WBG0", + "20013": "5IMF0", + "20014": "5IDB0", + "20015": "5ASDB0", + "20016": "5AFDB0", + "20018": "9OTH999", + "20021": "1UN0", + "20022": "5RDB0", + "20033": "5WB0", + "20034": "9OTH0", + "20035": "9PLG0", + "20918": "4EU001", + "21600": "9PRIV0", "(.*)": "\\1" } diff --git a/src/oda_reader/schemas/xml_tools.py b/src/oda_reader/schemas/xml_tools.py index 6848b54..98ab71f 100644 --- a/src/oda_reader/schemas/xml_tools.py +++ b/src/oda_reader/schemas/xml_tools.py @@ -1,98 +1,7 @@ -import collections.abc import json from pathlib import Path -from xml.etree import ElementTree as ET -import requests - -from oda_reader.common import API_RATE_LIMITER, logger - - -def download_xml(xml_url: str) -> requests.models.Response: - """Download the XML file from OECD.Stat. - - Args: - xml_url (str): The URL of the XML file. - - Returns: - requests.models.Response: The response object from the API. - """ - logger.info(f"Downloading XML file from {xml_url}") - - # Get file with requests - API_RATE_LIMITER.wait() - response = requests.get(xml_url) - - # Check if the request was successful - response.raise_for_status() - - # Return content - return response - - -def xml_to_dict(root: ET.Element) -> dict: - """Convert an XML file to a dictionary. - - Args: - root: The root of the XML file. - - Returns: - dict: The XML file as a dictionary. - """ - logger.info("Converting XML to dictionary") - # Create a dictionary to store the XML data - d = {} - - # Add attributes to the dictionary - for key, val in root.attrib.items(): - d[f"@{key}"] = val - - # If the root has text, add it to the dictionary - if root.text and root.text.strip(): - d["#text"] = root.text.strip() - - # Add children to the dictionary - for child in root: - # Recursively convert children to dictionaries - child_dict = xml_to_dict(child) - - # Remove namespace - tag = child.tag.split("}")[-1] - - # If the tag is already in the dictionary, append the child dictionary - if tag in d: - # Check if the tag is already a list - if not isinstance(d[tag], list): - d[tag] = [d[tag]] - # Append the child dictionary - d[tag].append(child_dict) - else: - # Add the child dictionary to the dictionary - d[tag] = child_dict - return d - - -def parse_xml(xml_url: str) -> dict: - """ - Parse an XML file from OECD.Stat and convert it to a dictionary. - - Args: - xml_url: The URL of the XML file. - - Returns: - dict: The XML file as a dictionary. - - """ - # Download the XML file - response = download_xml(xml_url) - - # Parse response content as room XML - xml_root = ET.fromstring(response.content) - - # Convert the root of the XML to a dictionary - xml_dict = xml_to_dict(root=xml_root) - - return xml_dict +from oda_reader.common import logger def keys_to_int(dictionary: dict) -> dict: @@ -108,77 +17,33 @@ def keys_to_int(dictionary: dict) -> dict: return {int(k): v for k, v in dictionary.items() if k.isdigit()} -def save_dict_to_json(dictionary: dict, filename: str | Path) -> None: - """Saves a dictionary to a JSON file.""" - # Save the mapping to a JSON file - with open(rf"{filename}", "w") as f: - f.write(json.dumps(dictionary, indent=4)) - - -def extract_representation_mapping(xml_dict: dict, index: int) -> list: - """Extracts the representation mapping from the XML file.""" - return xml_dict["RepresentationMaps"]["RepresentationMap"][index][ - "RepresentationMapping" - ] - - -def representation_mapping_to_dict(representation_mapping: list) -> dict: - """Converts the representation mapping to a dictionary.""" - return { - code["SourceValue"]["#text"]: code["TargetValue"]["#text"] - for code in representation_mapping - } - - -def representation_to_json(xml_dict: dict, index: int, filename: str | Path) -> None: - """Pipeline to extract and save a representation mapping to a JSON file.""" - # Get the codes from the XML dictionary - codes = extract_representation_mapping(xml_dict, index=index) - - # Loop through the codes and add them to the mapping dictionary - mapping = representation_mapping_to_dict(codes) - - # Save the mapping to a JSON file - save_dict_to_json(mapping, filename=rf"{filename}") +def read_mapping(mapping_path: str | Path, *, keys_as_int: bool) -> dict: + """Read a JSON mapping file from disk. - # Log the result - logger.info(f"Saved {filename} to disk.") - - -def extract_dac_to_area_codes(xml_dict: dict, filename: str | Path) -> None: - """Extracts the DAC1 codes to Area codes from the XML file.""" - - # Convert the representation to a JSON file - representation_to_json(xml_dict, index=0, filename=filename) - - -def extract_datatypes_to_prices_codes(xml_dict: dict, filename: str | Path) -> None: - """Extracts the Datatypes to Prices codes from the XML file.""" - - # Convert the representation to a JSON file - representation_to_json(xml_dict, index=1, filename=filename) - - -def extract_flowtype_to_flowtype_codes(xml_dict: dict, filename: str | Path) -> None: - """Extracts the Flowtype to Flowtype codes from the XML file.""" - - # Convert the representation to a JSON file - representation_to_json(xml_dict, index=2, filename=filename) - - -def read_mapping( - mapping_path: str | Path, keys_as_int: bool, update: collections.abc.Callable -) -> dict: - # Read the mapping from a JSON file. If it doesn't exist, create it. + Args: + mapping_path: Path to the JSON file. + keys_as_int: When True, convert string digit keys to integers via + :func:`keys_to_int`. - if not Path(mapping_path).exists(): - logger.info("Not found, downloading.") - update() + Returns: + dict: The loaded mapping, optionally with integer keys. - with open(mapping_path) as f: + Raises: + FileNotFoundError: If *mapping_path* does not exist. The refresh + tool ``scripts/data_maintenance/refresh_dac_codelists.py`` is + the authoritative path for regenerating missing mapping files. + """ + path = Path(mapping_path) + if not path.exists(): + raise FileNotFoundError( + f"Mapping file not found: {path!r}. " + "Run scripts/data_maintenance/refresh_dac_codelists.py --write to regenerate." + ) + + logger.debug(f"Reading mapping from {path}") + with open(path) as f: mapping = json.load(f) - # Convert keys to integers (if required) if keys_as_int: mapping = keys_to_int(mapping) diff --git a/tests/fixtures/oecd/codelist_13.json b/tests/fixtures/oecd/codelist_13.json new file mode 100644 index 0000000..99450c7 --- /dev/null +++ b/tests/fixtures/oecd/codelist_13.json @@ -0,0 +1,8326 @@ +{ + "codelists": { + "date-last-modified": "2026-06-15T12:16:55", + "codelist": [ + { + "name": "Recipient", + "xml:lang": "en", + "CRS": "1", + "TOSSD": "1", + "complete": "1", + "metadata": { + "name": { + "narrative": "Recipient" + }, + "url": "https://www.oecd.org/dac/stats/dacandcrscodelists.htm" + }, + "codelist-items": { + "codelist-item": [ + { + "status": "active", + "activation-date": "2005-01-01", + "code": "55", + "name": { + "narrative": [ + "T\u00fcrkiye", + { + "xml:lang": "fr", + "#text": "T\u00fcrkiye" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TUR", + "iso-alpha-2-code": "TR", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "TUR" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "57", + "name": { + "narrative": [ + "Kosovo", + { + "xml:lang": "fr", + "#text": "Kosovo" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "XKX", + "iso-alpha-2-code": "XK", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "XKV" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "63", + "name": { + "narrative": [ + "Serbia", + { + "xml:lang": "fr", + "#text": "Serbie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SRB", + "iso-alpha-2-code": "RS", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "SRB" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "64", + "name": { + "narrative": [ + "Bosnia and Herzegovina", + { + "xml:lang": "fr", + "#text": "Bosnie-Herz\u00e9govine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BIH", + "iso-alpha-2-code": "BA", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BIH" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "65", + "name": { + "narrative": [ + "Montenegro", + { + "xml:lang": "fr", + "#text": "Mont\u00e9n\u00e9gro" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MNE", + "iso-alpha-2-code": "ME", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MNE" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "66", + "name": { + "narrative": [ + "North Macedonia", + { + "xml:lang": "fr", + "#text": "Mac\u00e9doine du Nord" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MKD", + "iso-alpha-2-code": "MK", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MKD" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "71", + "name": { + "narrative": [ + "Albania", + { + "xml:lang": "fr", + "#text": "Albanie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ALB", + "iso-alpha-2-code": "AL", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "ALB" + }, + { + "status": "active", + "activation-date": "2005-01-01", + "code": "85", + "name": { + "narrative": [ + "Ukraine", + { + "xml:lang": "fr", + "#text": "Ukraine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "UKR", + "iso-alpha-2-code": "UA", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "UKR" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "86", + "name": { + "narrative": [ + "Belarus", + { + "xml:lang": "fr", + "#text": "B\u00e9larus" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BLR", + "iso-alpha-2-code": "BY", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BLR" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "88", + "name": { + "narrative": [ + "States Ex-Yugoslavia unspecified", + { + "xml:lang": "fr", + "#text": "Etats ex-Yougoslavie non sp\u00e9cifi\u00e9" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "SFRY_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "89", + "name": { + "narrative": [ + "Europe, regional", + { + "xml:lang": "fr", + "#text": "Europe, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "E_X" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "93", + "name": { + "narrative": [ + "Moldova", + { + "xml:lang": "fr", + "#text": "Moldova" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MDA", + "iso-alpha-2-code": "MD", + "region": { + "region-code": "10010", + "name": { + "narrative": [ + "Europe", + { + "_xml:lang": "fr", + "#text": "Europe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MDA" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "130", + "name": { + "narrative": [ + "Algeria", + { + "xml:lang": "fr", + "#text": "Alg\u00e9rie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "DZA", + "iso-alpha-2-code": "DZ", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "DZA" + }, + { + "status": "active", + "activation-date": "2005-01-01", + "code": "133", + "name": { + "narrative": [ + "Libya", + { + "xml:lang": "fr", + "#text": "Libye" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LBY", + "iso-alpha-2-code": "LY", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "LBY" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "136", + "name": { + "narrative": [ + "Morocco", + { + "xml:lang": "fr", + "#text": "Maroc" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MAR", + "iso-alpha-2-code": "MA", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MAR" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "139", + "name": { + "narrative": [ + "Tunisia", + { + "xml:lang": "fr", + "#text": "Tunisie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TUN", + "iso-alpha-2-code": "TN", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "TUN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "142", + "name": { + "narrative": [ + "Egypt", + { + "xml:lang": "fr", + "#text": "Egypte" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "EGY", + "iso-alpha-2-code": "EG", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "EGY" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "189", + "name": { + "narrative": [ + "North of Sahara, regional", + { + "xml:lang": "fr", + "#text": "Nord du Sahara, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10002", + "name": { + "narrative": [ + "North of Sahara", + { + "_xml:lang": "fr", + "#text": "Nord du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F4_X" + }, + { + "status": "active", + "activation-date": "2005-01-01", + "code": "218", + "name": { + "narrative": [ + "South Africa", + { + "xml:lang": "fr", + "#text": "Afrique du Sud" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ZAF", + "iso-alpha-2-code": "ZA", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "ZAF" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "225", + "name": { + "narrative": [ + "Angola", + { + "xml:lang": "fr", + "#text": "Angola" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "AGO", + "iso-alpha-2-code": "AO", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "AGO" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "227", + "name": { + "narrative": [ + "Botswana", + { + "xml:lang": "fr", + "#text": "Botswana" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BWA", + "iso-alpha-2-code": "BW", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BWA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "228", + "name": { + "narrative": [ + "Burundi", + { + "xml:lang": "fr", + "#text": "Burundi" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BDI", + "iso-alpha-2-code": "BI", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "BDI" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "229", + "name": { + "narrative": [ + "Cameroon", + { + "xml:lang": "fr", + "#text": "Cameroun" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CMR", + "iso-alpha-2-code": "CM", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "CMR" + }, + { + "status": "active", + "activation-date": "2007-01-01", + "code": "230", + "name": { + "narrative": [ + "Cabo Verde", + { + "xml:lang": "fr", + "#text": "Cabo Verde" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CPV", + "iso-alpha-2-code": "CV", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "CPV" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "231", + "name": { + "narrative": [ + "Central African Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique centrafricaine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CAF", + "iso-alpha-2-code": "CF", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "CAF" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "232", + "name": { + "narrative": [ + "Chad", + { + "xml:lang": "fr", + "#text": "Tchad" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TCD", + "iso-alpha-2-code": "TD", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TCD" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "233", + "name": { + "narrative": [ + "Comoros", + { + "xml:lang": "fr", + "#text": "Comores" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COM", + "iso-alpha-2-code": "KM", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "COM" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "234", + "name": { + "narrative": [ + "Congo", + { + "xml:lang": "fr", + "#text": "Congo" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COG", + "iso-alpha-2-code": "CG", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "COG" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "235", + "name": { + "narrative": [ + "Democratic Republic of the Congo", + { + "xml:lang": "fr", + "#text": "R\u00e9publique d\u00e9mocratique du Congo" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COD", + "iso-alpha-2-code": "CD", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "COD" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "236", + "name": { + "narrative": [ + "Benin", + { + "xml:lang": "fr", + "#text": "B\u00e9nin" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BEN", + "iso-alpha-2-code": "BJ", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BEN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "238", + "name": { + "narrative": [ + "Ethiopia", + { + "xml:lang": "fr", + "#text": "Ethiopie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ETH", + "iso-alpha-2-code": "ET", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "ETH" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "239", + "name": { + "narrative": [ + "Gabon", + { + "xml:lang": "fr", + "#text": "Gabon" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GAB", + "iso-alpha-2-code": "GA", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GAB" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "240", + "name": { + "narrative": [ + "Gambia", + { + "xml:lang": "fr", + "#text": "Gambie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GMB", + "iso-alpha-2-code": "GM", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GMB" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "241", + "name": { + "narrative": [ + "Ghana", + { + "xml:lang": "fr", + "#text": "Ghana" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GHA", + "iso-alpha-2-code": "GH", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "GHA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "243", + "name": { + "narrative": [ + "Guinea", + { + "xml:lang": "fr", + "#text": "Guin\u00e9e" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GIN", + "iso-alpha-2-code": "GN", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GIN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "244", + "name": { + "narrative": [ + "Guinea-Bissau", + { + "xml:lang": "fr", + "#text": "Guin\u00e9e-Bissau" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GNB", + "iso-alpha-2-code": "GW", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GNB" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "245", + "name": { + "narrative": [ + "Equatorial Guinea", + { + "xml:lang": "fr", + "#text": "Guin\u00e9e \u00e9quatoriale" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GNQ", + "iso-alpha-2-code": "GQ", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GNQ" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "247", + "name": { + "narrative": [ + "C\u00f4te d'Ivoire", + { + "xml:lang": "fr", + "#text": "C\u00f4te d'Ivoire" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CIV", + "iso-alpha-2-code": "CI", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "CIV" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "248", + "name": { + "narrative": [ + "Kenya", + { + "xml:lang": "fr", + "#text": "Kenya" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KEN", + "iso-alpha-2-code": "KE", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "KEN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "249", + "name": { + "narrative": [ + "Lesotho", + { + "xml:lang": "fr", + "#text": "Lesotho" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LSO", + "iso-alpha-2-code": "LS", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "LSO" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "251", + "name": { + "narrative": [ + "Liberia", + { + "xml:lang": "fr", + "#text": "Lib\u00e9ria" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LBR", + "iso-alpha-2-code": "LR", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "LBR" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "252", + "name": { + "narrative": [ + "Madagascar", + { + "xml:lang": "fr", + "#text": "Madagascar" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MDG", + "iso-alpha-2-code": "MG", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MDG" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "253", + "name": { + "narrative": [ + "Malawi", + { + "xml:lang": "fr", + "#text": "Malawi" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MWI", + "iso-alpha-2-code": "MW", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MWI" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "255", + "name": { + "narrative": [ + "Mali", + { + "xml:lang": "fr", + "#text": "Mali" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MLI", + "iso-alpha-2-code": "ML", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MLI" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "256", + "name": { + "narrative": [ + "Mauritania", + { + "xml:lang": "fr", + "#text": "Mauritanie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MRT", + "iso-alpha-2-code": "MR", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MRT" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "257", + "name": { + "narrative": [ + "Mauritius", + { + "xml:lang": "fr", + "#text": "Maurice" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MUS", + "iso-alpha-2-code": "MU", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MUS" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "259", + "name": { + "narrative": [ + "Mozambique", + { + "xml:lang": "fr", + "#text": "Mozambique" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MOZ", + "iso-alpha-2-code": "MZ", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MOZ" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "260", + "name": { + "narrative": [ + "Niger", + { + "xml:lang": "fr", + "#text": "Niger" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NER", + "iso-alpha-2-code": "NE", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "NER" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "261", + "name": { + "narrative": [ + "Nigeria", + { + "xml:lang": "fr", + "#text": "Nig\u00e9ria" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NGA", + "iso-alpha-2-code": "NG", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "NGA" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "265", + "name": { + "narrative": [ + "Zimbabwe", + { + "xml:lang": "fr", + "#text": "Zimbabwe" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ZWE", + "iso-alpha-2-code": "ZW", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "ZWE" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "266", + "name": { + "narrative": [ + "Rwanda", + { + "xml:lang": "fr", + "#text": "Rwanda" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "RWA", + "iso-alpha-2-code": "RW", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "RWA" + }, + { + "status": "active", + "activation-date": "2025-01-01", + "code": "268", + "name": { + "narrative": [ + "Sao Tome and Principe", + { + "xml:lang": "fr", + "#text": "Sao Tom\u00e9-et-Principe" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "STP", + "iso-alpha-2-code": "ST", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "STP" + }, + { + "status": "active", + "activation-date": "2001-01-01", + "code": "269", + "name": { + "narrative": [ + "Senegal", + { + "xml:lang": "fr", + "#text": "S\u00e9n\u00e9gal" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SEN", + "iso-alpha-2-code": "SN", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "SEN" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "270", + "name": { + "narrative": [ + "Seychelles", + { + "xml:lang": "fr", + "#text": "Seychelles" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SYC", + "iso-alpha-2-code": "SC", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "SYC" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "271", + "name": { + "narrative": [ + "Eritrea", + { + "xml:lang": "fr", + "#text": "Erythr\u00e9e" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ERI", + "iso-alpha-2-code": "ER", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "ERI" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "272", + "name": { + "narrative": [ + "Sierra Leone", + { + "xml:lang": "fr", + "#text": "Sierra Leone" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SLE", + "iso-alpha-2-code": "SL", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SLE" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "273", + "name": { + "narrative": [ + "Somalia", + { + "xml:lang": "fr", + "#text": "Somalie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SOM", + "iso-alpha-2-code": "SO", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SOM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "274", + "name": { + "narrative": [ + "Djibouti", + { + "xml:lang": "fr", + "#text": "Djibouti" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "DJI", + "iso-alpha-2-code": "DJ", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "DJI" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "275", + "name": { + "narrative": [ + "Namibia", + { + "xml:lang": "fr", + "#text": "Namibie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NAM", + "iso-alpha-2-code": "NA", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "NAM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "276", + "name": { + "narrative": [ + "Saint Helena", + { + "xml:lang": "fr", + "#text": "Sainte-H\u00e9l\u00e8ne" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SHN", + "iso-alpha-2-code": "SH", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "SHN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "278", + "name": { + "narrative": [ + "Sudan", + { + "xml:lang": "fr", + "#text": "Soudan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SDN", + "iso-alpha-2-code": "SD", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SDN" + }, + { + "status": "active", + "activation-date": "2012-01-01", + "code": "279", + "name": { + "narrative": [ + "South Sudan", + { + "xml:lang": "fr", + "#text": "Soudan du Sud" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SSD", + "iso-alpha-2-code": "SS", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SSD" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "280", + "name": { + "narrative": [ + "Eswatini", + { + "xml:lang": "fr", + "#text": "Eswatini" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SWZ", + "iso-alpha-2-code": "SZ", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SWZ" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "282", + "name": { + "narrative": [ + "Tanzania", + { + "xml:lang": "fr", + "#text": "Tanzanie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TZA", + "iso-alpha-2-code": "TZ", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TZA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "283", + "name": { + "narrative": [ + "Togo", + { + "xml:lang": "fr", + "#text": "Togo" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TGO", + "iso-alpha-2-code": "TG", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TGO" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "285", + "name": { + "narrative": [ + "Uganda", + { + "xml:lang": "fr", + "#text": "Ouganda" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "UGA", + "iso-alpha-2-code": "UG", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "UGA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "287", + "name": { + "narrative": [ + "Burkina Faso", + { + "xml:lang": "fr", + "#text": "Burkina Faso" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BFA", + "iso-alpha-2-code": "BF", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "BFA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "288", + "name": { + "narrative": [ + "Zambia", + { + "xml:lang": "fr", + "#text": "Zambie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ZMB", + "iso-alpha-2-code": "ZM", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "ZMB" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "289", + "name": { + "narrative": [ + "South of Sahara, regional", + { + "xml:lang": "fr", + "#text": "Sud du Sahara, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10003", + "name": { + "narrative": [ + "South of Sahara", + { + "_xml:lang": "fr", + "#text": "Sud du Sahara" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F6_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "298", + "name": { + "narrative": [ + "Africa, regional", + { + "xml:lang": "fr", + "#text": "Afrique, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10001", + "name": { + "narrative": [ + "Africa", + { + "_xml:lang": "fr", + "#text": "Afrique" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "328", + "name": { + "narrative": [ + "Bahamas", + { + "xml:lang": "fr", + "#text": "Bahamas" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BHS", + "iso-alpha-2-code": "BS", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "BHS" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "329", + "name": { + "narrative": [ + "Barbados", + { + "xml:lang": "fr", + "#text": "Barbades" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BRB", + "iso-alpha-2-code": "BB", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "BRB" + }, + { + "status": "active", + "activation-date": "2003-01-01", + "code": "336", + "name": { + "narrative": [ + "Costa Rica", + { + "xml:lang": "fr", + "#text": "Costa Rica" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CRI", + "iso-alpha-2-code": "CR", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "CRI" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "338", + "name": { + "narrative": [ + "Cuba", + { + "xml:lang": "fr", + "#text": "Cuba" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CUB", + "iso-alpha-2-code": "CU", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "CUB" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "340", + "name": { + "narrative": [ + "Dominican Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique dominicaine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "DOM", + "iso-alpha-2-code": "DO", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "DOM" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "342", + "name": { + "narrative": [ + "El Salvador", + { + "xml:lang": "fr", + "#text": "El Salvador" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SLV", + "iso-alpha-2-code": "SV", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "SLV" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "347", + "name": { + "narrative": [ + "Guatemala", + { + "xml:lang": "fr", + "#text": "Guatemala" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GTM", + "iso-alpha-2-code": "GT", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "GTM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "349", + "name": { + "narrative": [ + "Haiti", + { + "xml:lang": "fr", + "#text": "Ha\u00efti" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "HTI", + "iso-alpha-2-code": "HT", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "HTI" + }, + { + "status": "active", + "activation-date": "2003-01-01", + "code": "351", + "name": { + "narrative": [ + "Honduras", + { + "xml:lang": "fr", + "#text": "Honduras" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "HND", + "iso-alpha-2-code": "HN", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "HND" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "352", + "name": { + "narrative": [ + "Belize", + { + "xml:lang": "fr", + "#text": "Belize" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BLZ", + "iso-alpha-2-code": "BZ", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BLZ" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "354", + "name": { + "narrative": [ + "Jamaica", + { + "xml:lang": "fr", + "#text": "Jama\u00efque" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "JAM", + "iso-alpha-2-code": "JM", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "JAM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "358", + "name": { + "narrative": [ + "Mexico", + { + "xml:lang": "fr", + "#text": "Mexique" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MEX", + "iso-alpha-2-code": "MX", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MEX" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "364", + "name": { + "narrative": [ + "Nicaragua", + { + "xml:lang": "fr", + "#text": "Nicaragua" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NIC", + "iso-alpha-2-code": "NI", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "NIC" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "366", + "name": { + "narrative": [ + "Panama", + { + "xml:lang": "fr", + "#text": "Panama" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PAN", + "iso-alpha-2-code": "PA", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "PAN" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "375", + "name": { + "narrative": [ + "Trinidad and Tobago", + { + "xml:lang": "fr", + "#text": "Trinit\u00e9-et-Tobago" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TTO", + "iso-alpha-2-code": "TT", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "TTO" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "377", + "name": { + "narrative": [ + "Antigua and Barbuda", + { + "xml:lang": "fr", + "#text": "Antigua-et-Barbuda" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ATG", + "iso-alpha-2-code": "AG", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "ATG" + }, + { + "status": "active", + "activation-date": "2003-01-01", + "code": "378", + "name": { + "narrative": [ + "Dominica", + { + "xml:lang": "fr", + "#text": "Dominique" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "DMA", + "iso-alpha-2-code": "DM", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "DMA" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "381", + "name": { + "narrative": [ + "Grenada", + { + "xml:lang": "fr", + "#text": "Grenade" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GRD", + "iso-alpha-2-code": "GD", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "GRD" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "382", + "name": { + "narrative": [ + "Saint Kitts and Nevis", + { + "xml:lang": "fr", + "#text": "Saint-Kitts-et-Nevis" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KNA", + "iso-alpha-2-code": "KN", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "KNA" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "383", + "name": { + "narrative": [ + "Saint Lucia", + { + "xml:lang": "fr", + "#text": "Sainte-Lucie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LCA", + "iso-alpha-2-code": "LC", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "LCA" + }, + { + "status": "active", + "activation-date": "2005-01-01", + "code": "384", + "name": { + "narrative": [ + "Saint Vincent and the Grenadines", + { + "xml:lang": "fr", + "#text": "Saint-Vincent-et-les-Grenadines" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "VCT", + "iso-alpha-2-code": "VC", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "VCT" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "385", + "name": { + "narrative": [ + "Montserrat", + { + "xml:lang": "fr", + "#text": "Montserrat" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MSR", + "iso-alpha-2-code": "MS", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MSR" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "389", + "name": { + "narrative": [ + "Caribbean & Central America, regional", + { + "xml:lang": "fr", + "#text": "Cara\u00efbes et Am\u00e9rique centrale, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10005", + "name": { + "narrative": [ + "Caribbean & Central America", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes et Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "A5_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "425", + "name": { + "narrative": [ + "Argentina", + { + "xml:lang": "fr", + "#text": "Argentine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ARG", + "iso-alpha-2-code": "AR", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "ARG" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "428", + "name": { + "narrative": [ + "Bolivia", + { + "xml:lang": "fr", + "#text": "Bolivie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BOL", + "iso-alpha-2-code": "BO", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BOL" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "431", + "name": { + "narrative": [ + "Brazil", + { + "xml:lang": "fr", + "#text": "Br\u00e9sil" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BRA", + "iso-alpha-2-code": "BR", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BRA" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "434", + "name": { + "narrative": [ + "Chile", + { + "xml:lang": "fr", + "#text": "Chili" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CHL", + "iso-alpha-2-code": "CL", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "CHL" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "437", + "name": { + "narrative": [ + "Colombia", + { + "xml:lang": "fr", + "#text": "Colombie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COL", + "iso-alpha-2-code": "CO", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "COL" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "440", + "name": { + "narrative": [ + "Ecuador", + { + "xml:lang": "fr", + "#text": "Equateur" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ECU", + "iso-alpha-2-code": "EC", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "ECU" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "446", + "name": { + "narrative": [ + "Guyana", + { + "xml:lang": "fr", + "#text": "Guyana" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GUY", + "iso-alpha-2-code": "GY", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "GUY" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "451", + "name": { + "narrative": [ + "Paraguay", + { + "xml:lang": "fr", + "#text": "Paraguay" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PRY", + "iso-alpha-2-code": "PY", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "PRY" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "454", + "name": { + "narrative": [ + "Peru", + { + "xml:lang": "fr", + "#text": "P\u00e9rou" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PER", + "iso-alpha-2-code": "PE", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "PER" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "457", + "name": { + "narrative": [ + "Suriname", + { + "xml:lang": "fr", + "#text": "Suriname" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SUR", + "iso-alpha-2-code": "SR", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "SUR" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "460", + "name": { + "narrative": [ + "Uruguay", + { + "xml:lang": "fr", + "#text": "Uruguay" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "URY", + "iso-alpha-2-code": "UY", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "URY" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "463", + "name": { + "narrative": [ + "Venezuela", + { + "xml:lang": "fr", + "#text": "Venezuela" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "VEN", + "iso-alpha-2-code": "VE", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "VEN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "489", + "name": { + "narrative": [ + "South America, regional", + { + "xml:lang": "fr", + "#text": "Am\u00e9rique du Sud, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10006", + "name": { + "narrative": [ + "South America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique du Sud" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "A7_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "498", + "name": { + "narrative": [ + "America, regional", + { + "xml:lang": "fr", + "#text": "Am\u00e9rique, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10004", + "name": { + "narrative": [ + "America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "A_X" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "540", + "name": { + "narrative": [ + "Iran", + { + "xml:lang": "fr", + "#text": "Iran" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "IRN", + "iso-alpha-2-code": "IR", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "IRN" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "543", + "name": { + "narrative": [ + "Iraq", + { + "xml:lang": "fr", + "#text": "Iraq" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "IRQ", + "iso-alpha-2-code": "IQ", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "IRQ" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "549", + "name": { + "narrative": [ + "Jordan", + { + "xml:lang": "fr", + "#text": "Jordanie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "JOR", + "iso-alpha-2-code": "JO", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "JOR" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "550", + "name": { + "narrative": [ + "West Bank and Gaza Strip", + { + "xml:lang": "fr", + "#text": "Cisjordanie et bande de Gaza" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PSE", + "iso-alpha-2-code": "PS", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "PSE" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "555", + "name": { + "narrative": [ + "Lebanon", + { + "xml:lang": "fr", + "#text": "Liban" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LBN", + "iso-alpha-2-code": "LB", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "LBN" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "573", + "name": { + "narrative": [ + "Syrian Arab Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique arabe syrienne" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SYR", + "iso-alpha-2-code": "SY", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10017", + "igname": { + "narrative": [ + "Other LICs", + { + "_xml:lang": "fr", + "#text": "Autres PFR" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SYR" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "580", + "name": { + "narrative": [ + "Yemen", + { + "xml:lang": "fr", + "#text": "Y\u00e9men" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "YEM", + "iso-alpha-2-code": "YE", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "YEM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "589", + "name": { + "narrative": [ + "Middle East, regional", + { + "xml:lang": "fr", + "#text": "Moyen-Orient, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10011", + "name": { + "narrative": [ + "Middle East", + { + "_xml:lang": "fr", + "#text": "Moyen-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F97_X" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "610", + "name": { + "narrative": [ + "Armenia", + { + "xml:lang": "fr", + "#text": "Arm\u00e9nie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ARM", + "iso-alpha-2-code": "AM", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "ARM" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "611", + "name": { + "narrative": [ + "Azerbaijan", + { + "xml:lang": "fr", + "#text": "Azerba\u00efdjan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "AZE", + "iso-alpha-2-code": "AZ", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "AZE" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "612", + "name": { + "narrative": [ + "Georgia", + { + "xml:lang": "fr", + "#text": "G\u00e9orgie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GEO", + "iso-alpha-2-code": "GE", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "GEO" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "613", + "name": { + "narrative": [ + "Kazakhstan", + { + "xml:lang": "fr", + "#text": "Kazakhstan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KAZ", + "iso-alpha-2-code": "KZ", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "KAZ" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "614", + "name": { + "narrative": [ + "Kyrgyzstan", + { + "xml:lang": "fr", + "#text": "Kirghizistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KGZ", + "iso-alpha-2-code": "KG", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "KGZ" + }, + { + "status": "active", + "activation-date": "2018-01-01", + "code": "615", + "name": { + "narrative": [ + "Tajikistan", + { + "xml:lang": "fr", + "#text": "Tadjikistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TJK", + "iso-alpha-2-code": "TJ", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TJK" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "616", + "name": { + "narrative": [ + "Turkmenistan", + { + "xml:lang": "fr", + "#text": "Turkm\u00e9nistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TKM", + "iso-alpha-2-code": "TM", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TKM" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "617", + "name": { + "narrative": [ + "Uzbekistan", + { + "xml:lang": "fr", + "#text": "Ouzb\u00e9kistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "UZB", + "iso-alpha-2-code": "UZ", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "UZB" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "619", + "name": { + "narrative": [ + "Central Asia, regional", + { + "xml:lang": "fr", + "#text": "Asie centrale, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "S4_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "625", + "name": { + "narrative": [ + "Afghanistan", + { + "xml:lang": "fr", + "#text": "Afghanistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "AFG", + "iso-alpha-2-code": "AF", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "AFG" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "630", + "name": { + "narrative": [ + "Bhutan", + { + "xml:lang": "fr", + "#text": "Bhoutan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BTN", + "iso-alpha-2-code": "BT", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "BTN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "635", + "name": { + "narrative": [ + "Myanmar", + { + "xml:lang": "fr", + "#text": "Myanmar" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MMR", + "iso-alpha-2-code": "MM", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "MMR" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "640", + "name": { + "narrative": [ + "Sri Lanka", + { + "xml:lang": "fr", + "#text": "Sri Lanka" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LKA", + "iso-alpha-2-code": "LK", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "LKA" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "645", + "name": { + "narrative": [ + "India", + { + "xml:lang": "fr", + "#text": "Inde" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "IND", + "iso-alpha-2-code": "IN", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "IND" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "655", + "name": { + "narrative": [ + "Maldives", + { + "xml:lang": "fr", + "#text": "Maldives" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MDV", + "iso-alpha-2-code": "MV", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MDV" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "660", + "name": { + "narrative": [ + "Nepal", + { + "xml:lang": "fr", + "#text": "N\u00e9pal" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NPL", + "iso-alpha-2-code": "NP", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "NPL" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "665", + "name": { + "narrative": [ + "Pakistan", + { + "xml:lang": "fr", + "#text": "Pakistan" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PAK", + "iso-alpha-2-code": "PK", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "PAK" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "666", + "name": { + "narrative": [ + "Bangladesh", + { + "xml:lang": "fr", + "#text": "Bangladesh" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BGD", + "iso-alpha-2-code": "BD", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "BGD" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "679", + "name": { + "narrative": [ + "South Asia, regional", + { + "xml:lang": "fr", + "#text": "Asie du Sud, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "S7_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "689", + "name": { + "narrative": [ + "South & Central Asia, regional", + { + "xml:lang": "fr", + "#text": "Asie du Sud & C., r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10009", + "name": { + "narrative": [ + "South & Central Asia", + { + "_xml:lang": "fr", + "#text": "Asie du Sud et centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "S4_S7_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "725", + "name": { + "narrative": [ + "Brunei Darussalam", + { + "xml:lang": "fr", + "#text": "Brunei Darussalam" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BRN", + "iso-alpha-2-code": "BN", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "BRN" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "728", + "name": { + "narrative": [ + "Cambodia", + { + "xml:lang": "fr", + "#text": "Cambodge" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KHM", + "iso-alpha-2-code": "KH", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "KHM" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "730", + "name": { + "narrative": [ + "China (People's Republic of)", + { + "xml:lang": "fr", + "#text": "Chine (R\u00e9publique populaire de)" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CHN", + "iso-alpha-2-code": "CN", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "CHN" + }, + { + "status": "active", + "activation-date": "2024-01-01", + "code": "738", + "name": { + "narrative": [ + "Indonesia", + { + "xml:lang": "fr", + "#text": "Indon\u00e9sie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "IDN", + "iso-alpha-2-code": "ID", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "IDN" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "740", + "name": { + "narrative": [ + "Democratic People's Republic of Korea", + { + "xml:lang": "fr", + "#text": "R\u00e9publique populaire d\u00e9mocratique de Cor\u00e9e" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PRK", + "iso-alpha-2-code": "KP", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10017", + "igname": { + "narrative": [ + "Other LICs", + { + "_xml:lang": "fr", + "#text": "Autres PFR" + } + ] + } + }, + "wb-income-group": "WB-L", + "land-locked": "0", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "PRK" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "745", + "name": { + "narrative": [ + "Lao People's Democratic Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique d\u00e9mocratique populaire lao" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "LAO", + "iso-alpha-2-code": "LA", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "1", + "sids": "0", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "LAO" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "751", + "name": { + "narrative": [ + "Malaysia", + { + "xml:lang": "fr", + "#text": "Malaisie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MYS", + "iso-alpha-2-code": "MY", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MYS" + }, + { + "status": "active", + "activation-date": "2008-01-01", + "code": "753", + "name": { + "narrative": [ + "Mongolia", + { + "xml:lang": "fr", + "#text": "Mongolie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MNG", + "iso-alpha-2-code": "MN", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "1", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MNG" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "755", + "name": { + "narrative": [ + "Philippines", + { + "xml:lang": "fr", + "#text": "Philippines" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PHL", + "iso-alpha-2-code": "PH", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "PHL" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "764", + "name": { + "narrative": [ + "Thailand", + { + "xml:lang": "fr", + "#text": "Tha\u00eflande" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "THA", + "iso-alpha-2-code": "TH", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "THA" + }, + { + "status": "active", + "activation-date": "2003-01-01", + "code": "765", + "name": { + "narrative": [ + "Timor-Leste", + { + "xml:lang": "fr", + "#text": "Timor-Leste" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TLS", + "iso-alpha-2-code": "TL", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "TLS" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "769", + "name": { + "narrative": [ + "Viet Nam", + { + "xml:lang": "fr", + "#text": "Viet Nam" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "VNM", + "iso-alpha-2-code": "VN", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "VNM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "789", + "name": { + "narrative": [ + "Far East Asia, regional", + { + "xml:lang": "fr", + "#text": "Extr\u00eame-Orient, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10008", + "name": { + "narrative": [ + "Far East Asia", + { + "_xml:lang": "fr", + "#text": "Extr\u00eame-Orient" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "S97_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "798", + "name": { + "narrative": [ + "Asia, regional", + { + "xml:lang": "fr", + "#text": "Asie, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10007", + "name": { + "narrative": [ + "Asia", + { + "_xml:lang": "fr", + "#text": "Asie" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "S_X" + }, + { + "status": "active", + "activation-date": "2020-01-01", + "code": "831", + "name": { + "narrative": [ + "Cook Islands", + { + "xml:lang": "fr", + "#text": "Iles Cook" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COK", + "iso-alpha-2-code": "CK", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10025", + "igname": { + "narrative": [ + "MADCTs", + { + "_xml:lang": "fr", + "#text": "PDPA" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "0", + "tossd": "1", + "dotstatcode": "COK" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "832", + "name": { + "narrative": [ + "Fiji", + { + "xml:lang": "fr", + "#text": "Fidji" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "FJI", + "iso-alpha-2-code": "FJ", + "region": { + "region-code": "10057", + "name": { + "narrative": [ + "Melanesia", + { + "_xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "FJI" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "836", + "name": { + "narrative": [ + "Kiribati", + { + "xml:lang": "fr", + "#text": "Kiribati" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "KIR", + "iso-alpha-2-code": "KI", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "KIR" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "845", + "name": { + "narrative": [ + "Nauru", + { + "xml:lang": "fr", + "#text": "Nauru" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NRU", + "iso-alpha-2-code": "NR", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "NRU" + }, + { + "status": "active", + "activation-date": "2021-01-01", + "code": "854", + "name": { + "narrative": [ + "Vanuatu", + { + "xml:lang": "fr", + "#text": "Vanuatu" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "VUT", + "iso-alpha-2-code": "VU", + "region": { + "region-code": "10057", + "name": { + "narrative": [ + "Melanesia", + { + "_xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "VUT" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "856", + "name": { + "narrative": [ + "Niue", + { + "xml:lang": "fr", + "#text": "Niue" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NIU", + "iso-alpha-2-code": "NU", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "NIU" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "859", + "name": { + "narrative": [ + "Marshall Islands", + { + "xml:lang": "fr", + "#text": "Iles Marshall" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "MHL", + "iso-alpha-2-code": "MH", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "MHL" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "860", + "name": { + "narrative": [ + "Micronesia", + { + "xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "FSM", + "iso-alpha-2-code": "FM", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "FSM" + }, + { + "status": "active", + "activation-date": "2000-01-01", + "code": "861", + "name": { + "narrative": [ + "Palau", + { + "xml:lang": "fr", + "#text": "Palaos" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PLW", + "iso-alpha-2-code": "PW", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-H", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "PLW" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "862", + "name": { + "narrative": [ + "Papua New Guinea", + { + "xml:lang": "fr", + "#text": "Papouasie-Nouvelle-Guin\u00e9e" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PNG", + "iso-alpha-2-code": "PG", + "region": { + "region-code": "10057", + "name": { + "narrative": [ + "Melanesia", + { + "_xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "PNG" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "866", + "name": { + "narrative": [ + "Solomon Islands", + { + "xml:lang": "fr", + "#text": "\u00celes Salomon" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "SLB", + "iso-alpha-2-code": "SB", + "region": { + "region-code": "10057", + "name": { + "narrative": [ + "Melanesia", + { + "_xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-LM", + "land-locked": "0", + "sids": "1", + "fragile-state": "1", + "crs": "1", + "tossd": "1", + "dotstatcode": "SLB" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "868", + "name": { + "narrative": [ + "Tokelau", + { + "xml:lang": "fr", + "#text": "Tok\u00e9laou" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TKL", + "iso-alpha-2-code": "TK", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "TKL" + }, + { + "status": "active", + "activation-date": "2014-01-01", + "code": "870", + "name": { + "narrative": [ + "Tonga", + { + "xml:lang": "fr", + "#text": "Tonga" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TON", + "iso-alpha-2-code": "TO", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "TON" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "872", + "name": { + "narrative": [ + "Tuvalu", + { + "xml:lang": "fr", + "#text": "Tuvalu" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TUV", + "iso-alpha-2-code": "TV", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10016", + "igname": { + "narrative": [ + "LDCs", + { + "_xml:lang": "fr", + "#text": "PMA" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "TUV" + }, + { + "status": "active", + "activation-date": "2011-01-01", + "code": "876", + "name": { + "narrative": [ + "Wallis and Futuna", + { + "xml:lang": "fr", + "#text": "Wallis-et-Futuna" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "WLF", + "iso-alpha-2-code": "WF", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10019", + "igname": { + "narrative": [ + "UMICs", + { + "_xml:lang": "fr", + "#text": "PRITS" + } + ] + } + }, + "wb-income-group": "WB-NC", + "land-locked": "0", + "sids": "0", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "WLF" + }, + { + "status": "active", + "activation-date": "2022-01-01", + "code": "880", + "name": { + "narrative": [ + "Samoa", + { + "xml:lang": "fr", + "#text": "Samoa" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "WSM", + "iso-alpha-2-code": "WS", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10018", + "igname": { + "narrative": [ + "LMICs", + { + "_xml:lang": "fr", + "#text": "PRITI" + } + ] + } + }, + "wb-income-group": "WB-UM", + "land-locked": "0", + "sids": "1", + "fragile-state": "0", + "crs": "1", + "tossd": "1", + "dotstatcode": "WSM" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "889", + "name": { + "narrative": [ + "Oceania, regional", + { + "xml:lang": "fr", + "#text": "Oc\u00e9anie, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10012", + "name": { + "narrative": [ + "Oceania", + { + "_xml:lang": "fr", + "#text": "Oc\u00e9anie" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "O_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "998", + "name": { + "narrative": [ + "Developing countries, unspecified", + { + "xml:lang": "fr", + "#text": "Pays en d\u00e9veloppement, non sp\u00e9cifi\u00e9" + } + ] + }, + "type": "n.a.", + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "DPGC_X" + }, + { + "status": "active", + "code": "999", + "name": { + "narrative": [ + "Global", + { + "xml:lang": "fr", + "#text": "Global" + } + ] + }, + "type": "n.a.", + "crs": "0", + "tossd": "1" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1027", + "name": { + "narrative": [ + "Eastern Africa, regional", + { + "xml:lang": "fr", + "#text": "Afrique de l'est, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10050", + "name": { + "narrative": [ + "Eastern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique de l'est" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F3_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1028", + "name": { + "narrative": [ + "Middle Africa, regional", + { + "xml:lang": "fr", + "#text": "Afrique centrale, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10051", + "name": { + "narrative": [ + "Middle Africa", + { + "_xml:lang": "fr", + "#text": "Afrique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F5_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1029", + "name": { + "narrative": [ + "Southern Africa, regional", + { + "xml:lang": "fr", + "#text": "Afrique australe, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10052", + "name": { + "narrative": [ + "Southern Africa", + { + "_xml:lang": "fr", + "#text": "Afrique australe" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F7_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1030", + "name": { + "narrative": [ + "Western Africa, regional", + { + "xml:lang": "fr", + "#text": "Afrique occidentale, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10053", + "name": { + "narrative": [ + "Western Africa", + { + "_xml:lang": "fr", + "#text": "Afrique occidentale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "F8_X" + }, + { + "status": "active", + "activation-date": "1996-01-01", + "code": "1031", + "name": { + "narrative": [ + "Caribbean, regional", + { + "xml:lang": "fr", + "#text": "Cara\u00efbes, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10054", + "name": { + "narrative": [ + "Caribbean", + { + "_xml:lang": "fr", + "#text": "Cara\u00efbes" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "A4_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1032", + "name": { + "narrative": [ + "Central America, regional", + { + "xml:lang": "fr", + "#text": "Am\u00e9rique centrale, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10055", + "name": { + "narrative": [ + "Central America", + { + "_xml:lang": "fr", + "#text": "Am\u00e9rique centrale" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "A3_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1033", + "name": { + "narrative": [ + "Melanesia, regional", + { + "xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10057", + "name": { + "narrative": [ + "Melanesia", + { + "_xml:lang": "fr", + "#text": "M\u00e9lan\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "O7_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1034", + "name": { + "narrative": [ + "Micronesia, regional", + { + "xml:lang": "fr", + "#text": "Micron\u00e9sie, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10058", + "name": { + "narrative": [ + "Micronesia", + { + "_xml:lang": "fr", + "#text": "Micron\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "O8_X" + }, + { + "status": "active", + "activation-date": "2019-01-01", + "code": "1035", + "name": { + "narrative": [ + "Polynesia, regional", + { + "xml:lang": "fr", + "#text": "Polyn\u00e9sie, r\u00e9gional" + } + ] + }, + "type": "Country", + "region": { + "region-code": "10059", + "name": { + "narrative": [ + "Polynesia", + { + "_xml:lang": "fr", + "#text": "Polyn\u00e9sie" + } + ] + } + }, + "income-group": { + "igcode": "10024", + "igname": { + "narrative": [ + "Part I unallocated by income", + { + "_xml:lang": "fr", + "#text": "Partie I non allou\u00e9s par groupe de revenu" + } + ] + } + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "O9_X" + } + ] + } + } + ] + } +} diff --git a/tests/fixtures/oecd/codelist_5.json b/tests/fixtures/oecd/codelist_5.json new file mode 100644 index 0000000..a61b99f --- /dev/null +++ b/tests/fixtures/oecd/codelist_5.json @@ -0,0 +1,4433 @@ +{ + "codelists": { + "date-last-modified": "2026-06-15T12:16:53", + "codelist": [ + { + "name": "Provider", + "xml:lang": "en", + "CRS": "1", + "TOSSD": "1", + "complete": "1", + "metadata": { + "name": { + "narrative": "Provider" + }, + "url": "https://www.oecd.org/dac/stats/dacandcrscodelists.htm" + }, + "codelist-items": { + "codelist-item": [ + { + "status": "Active", + "code": "1", + "name": { + "narrative": [ + "Austria", + { + "xml:lang": "fr", + "#text": "Autriche" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "AUT", + "iso-alpha-2-code": "AT", + "crs": "1", + "tossd": "1", + "dotstatcode": "AUT" + }, + { + "status": "Active", + "code": "2", + "name": { + "narrative": [ + "Belgium", + { + "xml:lang": "fr", + "#text": "Belgique" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "BEL", + "iso-alpha-2-code": "BE", + "crs": "1", + "tossd": "1", + "dotstatcode": "BEL" + }, + { + "status": "Active", + "code": "3", + "name": { + "narrative": [ + "Denmark", + { + "xml:lang": "fr", + "#text": "Danemark" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "DNK", + "iso-alpha-2-code": "DK", + "crs": "1", + "tossd": "1", + "dotstatcode": "DNK" + }, + { + "status": "Active", + "code": "4", + "name": { + "narrative": [ + "France", + { + "xml:lang": "fr", + "#text": "France" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "FRA", + "iso-alpha-2-code": "FR", + "crs": "1", + "tossd": "1", + "dotstatcode": "FRA" + }, + { + "status": "Active", + "code": "5", + "name": { + "narrative": [ + "Germany", + { + "xml:lang": "fr", + "#text": "Allemagne" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "DEU", + "iso-alpha-2-code": "DE", + "crs": "1", + "tossd": "1", + "dotstatcode": "DEU" + }, + { + "status": "Active", + "code": "6", + "name": { + "narrative": [ + "Italy", + { + "xml:lang": "fr", + "#text": "Italie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "ITA", + "iso-alpha-2-code": "IT", + "crs": "1", + "tossd": "1", + "dotstatcode": "ITA" + }, + { + "status": "Active", + "code": "7", + "name": { + "narrative": [ + "Netherlands", + { + "xml:lang": "fr", + "#text": "Pays-Bas" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "NLD", + "iso-alpha-2-code": "NL", + "crs": "1", + "tossd": "1", + "dotstatcode": "NLD" + }, + { + "status": "Active", + "code": "8", + "name": { + "narrative": [ + "Norway", + { + "xml:lang": "fr", + "#text": "Norv\u00e8ge" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "NOR", + "iso-alpha-2-code": "NO", + "crs": "1", + "tossd": "1", + "dotstatcode": "NOR" + }, + { + "status": "Active", + "code": "9", + "name": { + "narrative": [ + "Portugal", + { + "xml:lang": "fr", + "#text": "Portugal" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "PRT", + "iso-alpha-2-code": "PT", + "crs": "1", + "tossd": "1", + "dotstatcode": "PRT" + }, + { + "status": "Active", + "code": "10", + "name": { + "narrative": [ + "Sweden", + { + "xml:lang": "fr", + "#text": "Su\u00e8de" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "SWE", + "iso-alpha-2-code": "SE", + "crs": "1", + "tossd": "1", + "dotstatcode": "SWE" + }, + { + "status": "Active", + "code": "11", + "name": { + "narrative": [ + "Switzerland", + { + "xml:lang": "fr", + "#text": "Suisse" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "CHE", + "iso-alpha-2-code": "CH", + "crs": "1", + "tossd": "1", + "dotstatcode": "CHE" + }, + { + "status": "Active", + "code": "12", + "name": { + "narrative": [ + "United Kingdom", + { + "xml:lang": "fr", + "#text": "Royaume-Uni" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "GBR", + "iso-alpha-2-code": "GB", + "crs": "1", + "tossd": "1", + "dotstatcode": "GBR" + }, + { + "status": "Active", + "code": "18", + "name": { + "narrative": [ + "Finland", + { + "xml:lang": "fr", + "#text": "Finlande" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "FIN", + "iso-alpha-2-code": "FI", + "crs": "1", + "tossd": "1", + "dotstatcode": "FIN" + }, + { + "status": "Active", + "code": "20", + "name": { + "narrative": [ + "Iceland", + { + "xml:lang": "fr", + "#text": "Islande" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "ISL", + "iso-alpha-2-code": "IS", + "crs": "1", + "tossd": "1", + "dotstatcode": "ISL" + }, + { + "status": "Active", + "code": "21", + "name": { + "narrative": [ + "Ireland", + { + "xml:lang": "fr", + "#text": "Irlande" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "IRL", + "iso-alpha-2-code": "IE", + "crs": "1", + "tossd": "1", + "dotstatcode": "IRL" + }, + { + "status": "Active", + "code": "22", + "name": { + "narrative": [ + "Luxembourg", + { + "xml:lang": "fr", + "#text": "Luxembourg" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "LUX", + "iso-alpha-2-code": "LU", + "crs": "1", + "tossd": "1", + "dotstatcode": "LUX" + }, + { + "status": "Active", + "code": "26", + "name": { + "narrative": [ + "Monaco", + { + "xml:lang": "fr", + "#text": "Monaco" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "MCO", + "iso-alpha-2-code": "MC", + "crs": "1", + "tossd": "1", + "dotstatcode": "MCO" + }, + { + "status": "Active", + "code": "30", + "name": { + "narrative": [ + "Cyprus", + { + "xml:lang": "fr", + "#text": "Chypre" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "CYP", + "iso-alpha-2-code": "CY", + "crs": "1", + "tossd": "1", + "dotstatcode": "CYP" + }, + { + "status": "Active", + "code": "40", + "name": { + "narrative": [ + "Greece", + { + "xml:lang": "fr", + "#text": "Gr\u00e8ce" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "GRC", + "iso-alpha-2-code": "GR", + "crs": "1", + "tossd": "1", + "dotstatcode": "GRC" + }, + { + "status": "Active", + "code": "45", + "name": { + "narrative": [ + "Malta", + { + "xml:lang": "fr", + "#text": "Malte" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "MLT", + "iso-alpha-2-code": "MT", + "crs": "1", + "tossd": "1", + "dotstatcode": "MLT" + }, + { + "status": "Active", + "code": "50", + "name": { + "narrative": [ + "Spain", + { + "xml:lang": "fr", + "#text": "Espagne" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "ESP", + "iso-alpha-2-code": "ES", + "crs": "1", + "tossd": "1", + "dotstatcode": "ESP" + }, + { + "status": "Active", + "code": "55", + "name": { + "narrative": [ + "T\u00fcrkiye", + { + "xml:lang": "fr", + "#text": "T\u00fcrkiye" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "TUR", + "iso-alpha-2-code": "TR", + "crs": "1", + "tossd": "1", + "dotstatcode": "TUR" + }, + { + "status": "Active", + "code": "61", + "name": { + "narrative": [ + "Slovenia", + { + "xml:lang": "fr", + "#text": "Slov\u00e9nie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "SVN", + "iso-alpha-2-code": "SI", + "crs": "1", + "tossd": "1", + "dotstatcode": "SVN" + }, + { + "status": "Active", + "code": "62", + "name": { + "narrative": [ + "Croatia", + { + "xml:lang": "fr", + "#text": "Croatie" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "HRV", + "iso-alpha-2-code": "HR", + "crs": "1", + "tossd": "1", + "dotstatcode": "HRV" + }, + { + "status": "Active", + "code": "68", + "name": { + "narrative": [ + "Czechia", + { + "xml:lang": "fr", + "#text": "Tch\u00e9quie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "CZE", + "iso-alpha-2-code": "CZ", + "crs": "1", + "tossd": "1", + "dotstatcode": "CZE" + }, + { + "status": "Active", + "code": "69", + "name": { + "narrative": [ + "Slovak Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique slovaque" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "SVK", + "iso-alpha-2-code": "SK", + "crs": "1", + "tossd": "1", + "dotstatcode": "SVK" + }, + { + "status": "Active", + "code": "70", + "name": { + "narrative": [ + "Liechtenstein", + { + "xml:lang": "fr", + "#text": "Liechtenstein" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "LIE", + "iso-alpha-2-code": "LI", + "crs": "1", + "tossd": "1", + "dotstatcode": "LIE" + }, + { + "status": "Active", + "code": "72", + "name": { + "narrative": [ + "Bulgaria", + { + "xml:lang": "fr", + "#text": "Bulgarie" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "BGR", + "iso-alpha-2-code": "BG", + "crs": "1", + "tossd": "1", + "dotstatcode": "BGR" + }, + { + "status": "Active", + "code": "75", + "name": { + "narrative": [ + "Hungary", + { + "xml:lang": "fr", + "#text": "Hongrie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "HUN", + "iso-alpha-2-code": "HU", + "crs": "1", + "tossd": "1", + "dotstatcode": "HUN" + }, + { + "status": "Active", + "code": "76", + "name": { + "narrative": [ + "Poland", + { + "xml:lang": "fr", + "#text": "Pologne" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "POL", + "iso-alpha-2-code": "PL", + "crs": "1", + "tossd": "1", + "dotstatcode": "POL" + }, + { + "status": "Active", + "code": "77", + "name": { + "narrative": [ + "Romania", + { + "xml:lang": "fr", + "#text": "Roumanie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "ROU", + "iso-alpha-2-code": "RO", + "crs": "1", + "tossd": "1", + "dotstatcode": "ROU" + }, + { + "status": "Active", + "code": "82", + "name": { + "narrative": [ + "Estonia", + { + "xml:lang": "fr", + "#text": "Estonie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "EST", + "iso-alpha-2-code": "EE", + "crs": "1", + "tossd": "1", + "dotstatcode": "EST" + }, + { + "status": "Active", + "code": "83", + "name": { + "narrative": [ + "Latvia", + { + "xml:lang": "fr", + "#text": "Lettonie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "LVA", + "iso-alpha-2-code": "LV", + "crs": "1", + "tossd": "1", + "dotstatcode": "LVA" + }, + { + "status": "Active", + "code": "84", + "name": { + "narrative": [ + "Lithuania", + { + "xml:lang": "fr", + "#text": "Lituanie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "LTU", + "iso-alpha-2-code": "LT", + "crs": "1", + "tossd": "1", + "dotstatcode": "LTU" + }, + { + "status": "Active", + "code": "87", + "name": { + "narrative": [ + "Russia", + { + "xml:lang": "fr", + "#text": "Russie" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "RUS", + "iso-alpha-2-code": "RU", + "crs": "1", + "tossd": "1", + "dotstatcode": "RUS" + }, + { + "status": "Active", + "code": "104", + "name": { + "narrative": [ + "Nordic Development Fund", + { + "xml:lang": "fr", + "#text": "Fonds du d\u00e9v. nordique" + } + ] + }, + "acronym": { + "narrative": [ + "NDF", + { + "xml:lang": "fr", + "#text": "FDN" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH019" + }, + { + "status": "Active", + "code": "130", + "name": { + "narrative": [ + "Algeria", + { + "xml:lang": "fr", + "#text": "Alg\u00e9rie" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "DZA", + "iso-alpha-2-code": "DZ", + "crs": "1", + "tossd": "1", + "dotstatcode": "DZA" + }, + { + "status": "Active", + "code": "133", + "name": { + "narrative": [ + "Libya", + { + "xml:lang": "fr", + "#text": "Libye" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "LBY", + "iso-alpha-2-code": "LY", + "crs": "1", + "tossd": "1", + "dotstatcode": "LBY" + }, + { + "status": "Active", + "code": "139", + "name": { + "narrative": [ + "Tunisia", + { + "xml:lang": "fr", + "#text": "Tunisie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "TUN", + "iso-alpha-2-code": "TN", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "261", + "name": { + "narrative": [ + "Nigeria", + { + "xml:lang": "fr", + "#text": "Nig\u00e9ria" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "NGA", + "iso-alpha-2-code": "NG", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "301", + "name": { + "narrative": [ + "Canada", + { + "xml:lang": "fr", + "#text": "Canada" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "CAN", + "iso-alpha-2-code": "CA", + "crs": "1", + "tossd": "1", + "dotstatcode": "CAN" + }, + { + "status": "Active", + "code": "302", + "name": { + "narrative": [ + "United States", + { + "xml:lang": "fr", + "#text": "Etats-Unis" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "USA", + "iso-alpha-2-code": "US", + "crs": "1", + "tossd": "1", + "dotstatcode": "USA" + }, + { + "status": "Active", + "code": "336", + "name": { + "narrative": [ + "Costa Rica", + { + "xml:lang": "fr", + "#text": "Costa Rica" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CRI", + "iso-alpha-2-code": "CR", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "340", + "name": { + "narrative": [ + "Dominican Republic", + { + "xml:lang": "fr", + "#text": "R\u00e9publique dominicaine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "DOM", + "iso-alpha-2-code": "DO", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "347", + "name": { + "narrative": [ + "Guatemala", + { + "xml:lang": "fr", + "#text": "Guatemala" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "GTM", + "iso-alpha-2-code": "GT", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "358", + "name": { + "narrative": [ + "Mexico", + { + "xml:lang": "fr", + "#text": "Mexique" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "MEX", + "iso-alpha-2-code": "MX", + "crs": "1", + "tossd": "1", + "dotstatcode": "MEX" + }, + { + "status": "Active", + "code": "425", + "name": { + "narrative": [ + "Argentina", + { + "xml:lang": "fr", + "#text": "Argentine" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ARG", + "iso-alpha-2-code": "AR", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "431", + "name": { + "narrative": [ + "Brazil", + { + "xml:lang": "fr", + "#text": "Br\u00e9sil" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "BRA", + "iso-alpha-2-code": "BR", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "434", + "name": { + "narrative": [ + "Chile", + { + "xml:lang": "fr", + "#text": "Chili" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "CHL", + "iso-alpha-2-code": "CL", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "437", + "name": { + "narrative": [ + "Colombia", + { + "xml:lang": "fr", + "#text": "Colombie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "COL", + "iso-alpha-2-code": "CO", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "440", + "name": { + "narrative": [ + "Ecuador", + { + "xml:lang": "fr", + "#text": "Equateur" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "ECU", + "iso-alpha-2-code": "EC", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "454", + "name": { + "narrative": [ + "Peru", + { + "xml:lang": "fr", + "#text": "P\u00e9rou" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "PER", + "iso-alpha-2-code": "PE", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "460", + "name": { + "narrative": [ + "Uruguay", + { + "xml:lang": "fr", + "#text": "Uruguay" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "URY", + "iso-alpha-2-code": "UY", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "543", + "name": { + "narrative": [ + "Iraq", + { + "xml:lang": "fr", + "#text": "Irak" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "IRQ", + "iso-alpha-2-code": "IQ", + "crs": "1", + "tossd": "1", + "dotstatcode": "IRQ" + }, + { + "status": "Active", + "code": "546", + "name": { + "narrative": [ + "Israel", + { + "xml:lang": "fr", + "#text": "Isra\u00ebl" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "ISR", + "iso-alpha-2-code": "IL", + "crs": "1", + "tossd": "1", + "dotstatcode": "ISR" + }, + { + "status": "Active", + "code": "551", + "name": { + "narrative": [ + "Palestinian Authority", + { + "xml:lang": "fr", + "#text": "Palestinian Authority" + } + ] + }, + "type": "Country", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "552", + "name": { + "narrative": [ + "Kuwait", + { + "xml:lang": "fr", + "#text": "Koweit" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "KWT", + "iso-alpha-2-code": "KW", + "crs": "1", + "tossd": "1", + "dotstatcode": "KWT" + }, + { + "status": "Active", + "code": "561", + "name": { + "narrative": [ + "Qatar", + { + "xml:lang": "fr", + "#text": "Qatar" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "QAT", + "iso-alpha-2-code": "QA", + "crs": "1", + "tossd": "1", + "dotstatcode": "QAT" + }, + { + "status": "Active", + "code": "566", + "name": { + "narrative": [ + "Saudi Arabia", + { + "xml:lang": "fr", + "#text": "Arabie saoudite" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "SAU", + "iso-alpha-2-code": "SA", + "crs": "1", + "tossd": "1", + "dotstatcode": "SAU" + }, + { + "status": "Active", + "code": "576", + "name": { + "narrative": [ + "United Arab Emirates", + { + "xml:lang": "fr", + "#text": "Emirats arabes unis" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "ARE", + "iso-alpha-2-code": "AE", + "crs": "1", + "tossd": "1", + "dotstatcode": "ARE" + }, + { + "status": "Active", + "code": "611", + "name": { + "narrative": [ + "Azerbaijan", + { + "xml:lang": "fr", + "#text": "Azerba\u00efdjan" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "AZE", + "iso-alpha-2-code": "AZ", + "crs": "1", + "tossd": "1", + "dotstatcode": "AZE" + }, + { + "status": "Active", + "code": "613", + "name": { + "narrative": [ + "Kazakhstan", + { + "xml:lang": "fr", + "#text": "Kazakhstan" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "KAZ", + "iso-alpha-2-code": "KZ", + "crs": "1", + "tossd": "1", + "dotstatcode": "KAZ" + }, + { + "status": "Active", + "code": "701", + "name": { + "narrative": [ + "Japan", + { + "xml:lang": "fr", + "#text": "Japon" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "JPN", + "iso-alpha-2-code": "JP", + "crs": "1", + "tossd": "1", + "dotstatcode": "JPN" + }, + { + "status": "Active", + "code": "732", + "name": { + "narrative": [ + "Chinese Taipei", + { + "xml:lang": "fr", + "#text": "Taipei chinois" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "TWN", + "iso-alpha-2-code": "TW", + "crs": "1", + "tossd": "1", + "dotstatcode": "TWN" + }, + { + "status": "Active", + "code": "738", + "name": { + "narrative": [ + "Indonesia", + { + "xml:lang": "fr", + "#text": "Indon\u00e9sie" + } + ] + }, + "type": "Country", + "iso-alpha-3-code": "IDN", + "iso-alpha-2-code": "ID", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "742", + "name": { + "narrative": [ + "Korea", + { + "xml:lang": "fr", + "#text": "Cor\u00e9e" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "KOR", + "iso-alpha-2-code": "KR", + "crs": "1", + "tossd": "1", + "dotstatcode": "KOR" + }, + { + "status": "Active", + "code": "764", + "name": { + "narrative": [ + "Thailand", + { + "xml:lang": "fr", + "#text": "Tha\u00eflande" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "THA", + "iso-alpha-2-code": "TH", + "crs": "1", + "tossd": "1", + "dotstatcode": "THA" + }, + { + "status": "Active", + "code": "765", + "name": { + "narrative": [ + "Timor-Leste", + { + "xml:lang": "fr", + "#text": "Timor oriental" + } + ] + }, + "type": "Non-DAC member", + "iso-alpha-3-code": "TLS", + "iso-alpha-2-code": "TL", + "crs": "1", + "tossd": "1", + "dotstatcode": "TLS" + }, + { + "status": "Active", + "code": "801", + "name": { + "narrative": [ + "Australia", + { + "xml:lang": "fr", + "#text": "Australie" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "AUS", + "iso-alpha-2-code": "AU", + "crs": "1", + "tossd": "1", + "dotstatcode": "AUS" + }, + { + "status": "Active", + "code": "807", + "name": { + "narrative": [ + "UNEP", + { + "xml:lang": "fr", + "#text": "PNUE" + } + ] + }, + "acronym": { + "narrative": [ + "UNEP", + { + "xml:lang": "fr", + "#text": "PNUE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN016" + }, + { + "status": "Active", + "code": "811", + "name": { + "narrative": [ + "Global Environment Facility", + { + "xml:lang": "fr", + "#text": "Fonds pour l'environnement mondial" + } + ] + }, + "acronym": { + "narrative": [ + "GEF", + { + "xml:lang": "fr", + "#text": "FEM" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH011" + }, + { + "status": "Active", + "code": "812", + "name": { + "narrative": [ + "Montreal Protocol", + { + "xml:lang": "fr", + "#text": "Protocole de Montr\u00e9al" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH018" + }, + { + "status": "Active", + "code": "820", + "name": { + "narrative": [ + "New Zealand", + { + "xml:lang": "fr", + "#text": "Nouvelle-Z\u00e9lande" + } + ] + }, + "type": "DAC member", + "iso-alpha-3-code": "NZL", + "iso-alpha-2-code": "NZ", + "crs": "1", + "tossd": "1", + "dotstatcode": "NZL" + }, + { + "status": "Active", + "code": "901", + "name": { + "narrative": [ + "International Bank for Reconstruction and Development", + { + "xml:lang": "fr", + "#text": "Banque internationale pour la reconstruction et le d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "IBRD", + { + "xml:lang": "fr", + "#text": "BIRD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "5WB001" + }, + { + "status": "Active", + "code": "902", + "name": { + "narrative": [ + "Multilateral Investment Guarantee Agency", + { + "xml:lang": "fr", + "#text": "Agence\u00a0multilat\u00e9rale\u00a0de garantie des investissements" + } + ] + }, + "acronym": { + "narrative": [ + "MIGA", + { + "xml:lang": "fr", + "#text": "AMGI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "5WB004" + }, + { + "status": "Active", + "code": "903", + "name": { + "narrative": [ + "International Finance Corporation", + { + "xml:lang": "fr", + "#text": "Soci\u00e9t\u00e9 financi\u00e8re international" + } + ] + }, + "acronym": { + "narrative": [ + "IFC", + { + "xml:lang": "fr", + "#text": "SFI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "5WBG002" + }, + { + "status": "Active", + "code": "905", + "name": { + "narrative": [ + "International Development Association", + { + "xml:lang": "fr", + "#text": "Association internationale de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "IDA", + { + "xml:lang": "fr", + "#text": "IDA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "5WB002" + }, + { + "status": "Active", + "code": "906", + "name": { + "narrative": [ + "Caribbean Development Bank", + { + "xml:lang": "fr", + "#text": "Banque de d\u00e9veloppement des Cara\u00efbes" + } + ] + }, + "acronym": { + "narrative": [ + "CarDB", + { + "xml:lang": "fr", + "#text": "BDC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB004" + }, + { + "status": "Active", + "code": "907", + "name": { + "narrative": [ + "International Monetary Fund", + { + "xml:lang": "fr", + "#text": "Fond mon\u00e9taire international" + } + ] + }, + "acronym": { + "narrative": [ + "IMF", + { + "xml:lang": "fr", + "#text": "FMI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5IMF01" + }, + { + "status": "Active", + "code": "909", + "name": { + "narrative": [ + "Inter-American Development Bank", + { + "xml:lang": "fr", + "#text": "Banque Interam\u00e9ricaine de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "IDB", + { + "xml:lang": "fr", + "#text": "BID" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5IDB001" + }, + { + "status": "Active", + "code": "910", + "name": { + "narrative": [ + "Central American Bank for Economic Integration", + { + "xml:lang": "fr", + "#text": "Banque centram\u00e9ricaine d'int\u00e9gration \u00e9conomique" + } + ] + }, + "acronym": { + "narrative": [ + "CABEI", + { + "xml:lang": "fr", + "#text": "BCIE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB003" + }, + { + "status": "Active", + "code": "913", + "name": { + "narrative": [ + "African Development Bank", + { + "xml:lang": "fr", + "#text": "Banque Africaine de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "AfDB", + { + "xml:lang": "fr", + "#text": "BAfD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5AFDB001" + }, + { + "status": "Active", + "code": "914", + "name": { + "narrative": [ + "African Development Fund", + { + "xml:lang": "fr", + "#text": "Fonds Africaine de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "AfDF", + { + "xml:lang": "fr", + "#text": "FAfD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5AFDB002" + }, + { + "status": "Active", + "code": "915", + "name": { + "narrative": [ + "Asian Development Bank", + { + "xml:lang": "fr", + "#text": "Banque Asiatique de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "AsDB", + { + "xml:lang": "fr", + "#text": "BAsD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5ASDB01" + }, + { + "status": "Active", + "code": "918", + "name": { + "narrative": [ + "EU Institutions", + { + "xml:lang": "fr", + "#text": "Institutions de l'UE" + } + ] + }, + "acronym": { + "narrative": [ + "EU", + { + "xml:lang": "fr", + "#text": "UE" + } + ] + }, + "type": "DAC member", + "crs": "1", + "tossd": "1", + "dotstatcode": "4EU001" + }, + { + "status": "Active", + "code": "921", + "name": { + "narrative": [ + "Arab Fund (AFESD)", + { + "xml:lang": "fr", + "#text": "Fonds arabe (FADES)" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH003" + }, + { + "status": "Active", + "code": "923", + "name": { + "narrative": [ + "UN Peacebuilding Fund", + { + "xml:lang": "fr", + "#text": "Fonds de consolidation de la paix-ONU" + } + ] + }, + "acronym": { + "narrative": [ + "UNPBF", + { + "xml:lang": "fr", + "#text": "FCP" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN011" + }, + { + "status": "Active", + "code": "926", + "name": { + "narrative": [ + "Council of Europe", + { + "xml:lang": "fr", + "#text": "Conseil de l'Europe" + } + ] + }, + "acronym": { + "narrative": [ + "CoE", + { + "xml:lang": "fr", + "#text": "CoE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "928", + "name": { + "narrative": [ + "World Health Organisation", + { + "xml:lang": "fr", + "#text": "Organisation mondiale de la sant\u00e9" + } + ] + }, + "acronym": { + "narrative": [ + "WHO", + { + "xml:lang": "fr", + "#text": "OMS" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN026" + }, + { + "status": "Active", + "code": "932", + "name": { + "narrative": [ + "Food and Agriculture Organisation", + { + "xml:lang": "fr", + "#text": "Organisation pour l'alimentation et l'agriculture" + } + ] + }, + "acronym": { + "narrative": [ + "FAO", + { + "xml:lang": "fr", + "#text": "FAO" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN003" + }, + { + "status": "Active", + "code": "940", + "name": { + "narrative": [ + "International Labour Organisation", + { + "xml:lang": "fr", + "#text": "Organisation internationale du Travail" + } + ] + }, + "acronym": { + "narrative": [ + "ILO", + { + "xml:lang": "fr", + "#text": "OIT" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN006" + }, + { + "status": "Active", + "code": "944", + "name": { + "narrative": [ + "International Atomic Energy Agency", + { + "xml:lang": "fr", + "#text": "Agence internationale de l'\u00e9nergie atomique" + } + ] + }, + "acronym": { + "narrative": [ + "IAEA", + { + "xml:lang": "fr", + "#text": "AIEA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "1UN005" + }, + { + "status": "Active", + "code": "948", + "name": { + "narrative": [ + "UNECE", + { + "xml:lang": "fr", + "#text": "CEE-ONU" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN015" + }, + { + "status": "Active", + "code": "951", + "name": { + "narrative": [ + "OPEC Fund for International Development", + { + "xml:lang": "fr", + "#text": "Fonds OPEP pour le d\u00e9veloppement international" + } + ] + }, + "acronym": { + "narrative": [ + "OPEC Fund", + { + "xml:lang": "fr", + "#text": "Fonds OPEP" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH020" + }, + { + "status": "Active", + "code": "952", + "name": { + "narrative": [ + "OAPEC", + { + "xml:lang": "fr", + "#text": "OAPEC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "953", + "name": { + "narrative": [ + "Arab Bank for Economic Development in Africa", + { + "xml:lang": "fr", + "#text": "Banque arabe pour le d\u00e9veloppement \u00e9conomique en Afrique" + } + ] + }, + "acronym": { + "narrative": [ + "BADEA", + { + "xml:lang": "fr", + "#text": "BADEA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH002" + }, + { + "status": "Active", + "code": "954", + "name": { + "narrative": [ + "Special Arab Aid Fund for Africa", + { + "xml:lang": "fr", + "#text": "Fonds sp\u00e9cial arabe d'aide \u00e0 l'Afrique" + } + ] + }, + "acronym": { + "narrative": [ + "SAAFA", + { + "xml:lang": "fr", + "#text": "SAAFA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "956", + "name": { + "narrative": [ + "IMF Trust Fund", + { + "xml:lang": "fr", + "#text": "IMF Trust Fund" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "958", + "name": { + "narrative": [ + "IMF (Concessional Trust Funds)", + { + "xml:lang": "fr", + "#text": "FMI (Fonds fiduciaires concessionnels)" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5IMF02" + }, + { + "status": "Active", + "code": "959", + "name": { + "narrative": [ + "UNDP", + { + "xml:lang": "fr", + "#text": "PNUD" + } + ] + }, + "acronym": { + "narrative": [ + "UNDP", + { + "xml:lang": "fr", + "#text": "PNUD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN014" + }, + { + "status": "Active", + "code": "960", + "name": { + "narrative": [ + "UNTA", + { + "xml:lang": "fr", + "#text": "ATNU" + } + ] + }, + "acronym": { + "narrative": [ + "UNTA", + { + "xml:lang": "fr", + "#text": "ATNU" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN023" + }, + { + "status": "Active", + "code": "962", + "name": { + "narrative": [ + "United Nations Conference on Trade and Development", + { + "xml:lang": "fr", + "#text": "Conf\u00e9rence des Nations Unies sur le commerce et le d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "UNCTAD", + { + "xml:lang": "fr", + "#text": "CNUCED" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN020" + }, + { + "status": "Active", + "code": "963", + "name": { + "narrative": [ + "UNICEF", + { + "xml:lang": "fr", + "#text": "UNICEF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN019" + }, + { + "status": "Active", + "code": "964", + "name": { + "narrative": [ + "UNRWA", + { + "xml:lang": "fr", + "#text": "UNRWA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN022" + }, + { + "status": "Active", + "code": "966", + "name": { + "narrative": [ + "WFP", + { + "xml:lang": "fr", + "#text": "PAM" + } + ] + }, + "acronym": { + "narrative": [ + "WFP", + { + "xml:lang": "fr", + "#text": "PAM" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN024" + }, + { + "status": "Active", + "code": "967", + "name": { + "narrative": [ + "UNHCR", + { + "xml:lang": "fr", + "#text": "HCR" + } + ] + }, + "acronym": { + "narrative": [ + "UNHCR", + { + "xml:lang": "fr", + "#text": "HCR" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN018" + }, + { + "status": "Active", + "code": "971", + "name": { + "narrative": [ + "UNAIDS", + { + "xml:lang": "fr", + "#text": "UNAIDS" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN013" + }, + { + "status": "Active", + "code": "974", + "name": { + "narrative": [ + "UNFPA", + { + "xml:lang": "fr", + "#text": "FNUAP" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN017" + }, + { + "status": "Active", + "code": "976", + "name": { + "narrative": [ + "Islamic Development Bank", + { + "xml:lang": "fr", + "#text": "Banque de d\u00e9veloppement islamique" + } + ] + }, + "acronym": { + "narrative": [ + "IsDB", + { + "xml:lang": "fr", + "#text": "IsDB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB009" + }, + { + "status": "Active", + "code": "978", + "name": { + "narrative": [ + "OSCE", + { + "xml:lang": "fr", + "#text": "OSCE" + } + ] + }, + "acronym": { + "narrative": [ + "OSCE", + { + "xml:lang": "fr", + "#text": "OSCE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH021" + }, + { + "status": "Active", + "code": "979", + "name": { + "narrative": [ + "Islamic Monetary Fund", + { + "xml:lang": "fr", + "#text": "Fond mon\u00e9taire islamique" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "980", + "name": { + "narrative": [ + "Arab Fund for Technical Assistance to African and Arab Countries", + { + "xml:lang": "fr", + "#text": "Fonds arabe pour l'assistance technique aux pays africains et arabes" + } + ] + }, + "acronym": { + "narrative": [ + "AFTAAAC", + { + "xml:lang": "fr", + "#text": "" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "981", + "name": { + "narrative": [ + "Black Sea Trade & Development Bank", + { + "xml:lang": "fr", + "#text": "Banque de d\u00e9veloppement de la mer Noire" + } + ] + }, + "acronym": { + "narrative": [ + "BSTDB", + { + "xml:lang": "fr", + "#text": "BSTDB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB002" + }, + { + "status": "Active", + "code": "982", + "name": { + "narrative": [ + "GODE", + { + "xml:lang": "fr", + "#text": "GODE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "983", + "name": { + "narrative": [ + "Other Arab Agencies", + { + "xml:lang": "fr", + "#text": "Autres Agences Arabes" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "988", + "name": { + "narrative": [ + "IFAD", + { + "xml:lang": "fr", + "#text": "FIDA" + } + ] + }, + "acronym": { + "narrative": [ + "IFAD", + { + "xml:lang": "fr", + "#text": "FIDA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN004" + }, + { + "status": "Active", + "code": "990", + "name": { + "narrative": [ + "European Bank for Reconstruction and Development", + { + "xml:lang": "fr", + "#text": "Banque europ\u00e9enne pour la reconstruction et le d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "EBRD", + { + "xml:lang": "fr", + "#text": "BERD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "5RDB007" + }, + { + "status": "Active", + "code": "992", + "name": { + "narrative": [ + "UN AGENCIES", + { + "xml:lang": "fr", + "#text": "AGENCES DE L'ONU" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1" + }, + { + "status": "Active", + "code": "997", + "name": { + "narrative": [ + "Global Partnership for Education", + { + "xml:lang": "fr", + "#text": "Partenariat mondial pour l'\u00c9ducation" + } + ] + }, + "acronym": { + "narrative": [ + "GPE", + { + "xml:lang": "fr", + "#text": "GPE" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH014" + }, + { + "status": "Active", + "code": "1011", + "name": { + "narrative": [ + "Climate Investment Funds", + { + "xml:lang": "fr", + "#text": "Fonds d'investissement climatique" + } + ] + }, + "acronym": { + "narrative": [ + "CIF", + { + "xml:lang": "fr", + "#text": "FIC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH006" + }, + { + "status": "Active", + "code": "1012", + "name": { + "narrative": [ + "Adaptation Fund", + { + "xml:lang": "fr", + "#text": "Fonds d'adaptation" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH001" + }, + { + "status": "Active", + "code": "1013", + "name": { + "narrative": [ + "Council of Europe Development Bank", + { + "xml:lang": "fr", + "#text": "Banque de d\u00e9veloppement du Conseil de l'Europe" + } + ] + }, + "acronym": { + "narrative": [ + "CEB", + { + "xml:lang": "fr", + "#text": "CEB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB005" + }, + { + "status": "Active", + "code": "1014", + "name": { + "narrative": [ + "Private Infrastructure Development Group", + { + "xml:lang": "fr", + "#text": "Groupe\u00a0du d\u00e9veloppement\u00a0des infrastructures priv\u00e9es" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH022" + }, + { + "status": "Active", + "code": "1015", + "name": { + "narrative": [ + "Development Bank of Latin America", + { + "xml:lang": "fr", + "#text": "Banque de d\u00e9veloppement de l'Am\u00e9rique latine" + } + ] + }, + "acronym": { + "narrative": [ + "CAF", + { + "xml:lang": "fr", + "#text": "CAF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB006" + }, + { + "status": "Active", + "code": "1016", + "name": { + "narrative": [ + "Green Climate Fund", + { + "xml:lang": "fr", + "#text": "Fonds vert pour le climat" + } + ] + }, + "acronym": { + "narrative": [ + "GCF", + { + "xml:lang": "fr", + "#text": "FVC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH015" + }, + { + "status": "Active", + "code": "1017", + "name": { + "narrative": [ + "Credit Guarantee and Investment Facility", + { + "xml:lang": "fr", + "#text": "Credit Guarantee and Investment Facility" + } + ] + }, + "acronym": { + "narrative": [ + "CGIF", + { + "xml:lang": "fr", + "#text": "CGIF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH007" + }, + { + "status": "Active", + "code": "1018", + "name": { + "narrative": [ + "Global Energy Efficiency and Renewable Energy Fund", + { + "xml:lang": "fr", + "#text": "Fonds mondial de l'efficacit\u00e9 \u00e9nerg\u00e9tique et des \u00e9nergies renouvelables" + } + ] + }, + "acronym": { + "narrative": [ + "GEEREF", + { + "xml:lang": "fr", + "#text": "GEEREF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH010" + }, + { + "status": "Active", + "code": "1019", + "name": { + "narrative": [ + "IDB Invest", + { + "xml:lang": "fr", + "#text": "BID Invest" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5IDB003" + }, + { + "status": "Active", + "code": "1020", + "name": { + "narrative": [ + "Central Emergency Response Fund", + { + "xml:lang": "fr", + "#text": "Fonds central d'intervention pour les urgences humanitaires" + } + ] + }, + "acronym": { + "narrative": [ + "CERF", + { + "xml:lang": "fr", + "#text": "CERF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN001" + }, + { + "status": "Active", + "code": "1022", + "name": { + "narrative": [ + "UN inter-agency pooled funds", + { + "xml:lang": "fr", + "#text": "Fonds communs inter-institutions des Nations Unies" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1023", + "name": { + "narrative": [ + "World Tourism Organisation", + { + "xml:lang": "fr", + "#text": "Organisation mondiale du tourisme" + } + ] + }, + "acronym": { + "narrative": [ + "UNWTO", + { + "xml:lang": "fr", + "#text": "OMT" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN027" + }, + { + "status": "Active", + "code": "1024", + "name": { + "narrative": [ + "Asian Infrastructure Investment Bank", + { + "xml:lang": "fr", + "#text": "Banque asiatique d'investissement dans les infrastructures" + } + ] + }, + "acronym": { + "narrative": [ + "AIIB", + { + "xml:lang": "fr", + "#text": "AIIB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB001" + }, + { + "status": "Active", + "code": "1025", + "name": { + "narrative": [ + "Center of Excellence in Finance", + { + "xml:lang": "fr", + "#text": "Centre d'excellence en finance" + } + ] + }, + "acronym": { + "narrative": [ + "CEF", + { + "xml:lang": "fr", + "#text": "CEF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH005" + }, + { + "status": "Active", + "code": "1026", + "name": { + "narrative": [ + "SESRIC", + { + "xml:lang": "fr", + "#text": "SESRIC" + } + ] + }, + "acronym": { + "narrative": [ + "SESRIC", + { + "xml:lang": "fr", + "#text": "SESRIC" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1036", + "name": { + "narrative": [ + "UN Secretariat", + { + "xml:lang": "fr", + "#text": "Secretariat des Nations Unies" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1037", + "name": { + "narrative": [ + "International Investment Bank", + { + "xml:lang": "fr", + "#text": "Banque internationale d'investissement" + } + ] + }, + "acronym": { + "narrative": [ + "IIB", + { + "xml:lang": "fr", + "#text": "IIB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB008" + }, + { + "status": "Active", + "code": "1038", + "name": { + "narrative": [ + "UN Institute for Disarmament Research", + { + "xml:lang": "fr", + "#text": "Institut des Nations unies pour la recherche sur le d\u00e9sarmement" + } + ] + }, + "acronym": { + "narrative": [ + "UNIDIR", + { + "xml:lang": "fr", + "#text": "UNIDIR" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN010" + }, + { + "status": "Active", + "code": "1039", + "name": { + "narrative": [ + "UN Capital Development Fund", + { + "xml:lang": "fr", + "#text": "UN Capital Development Fund" + } + ] + }, + "acronym": { + "narrative": [ + "UNCDF", + { + "xml:lang": "fr", + "#text": "UNCDF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN008" + }, + { + "status": "Active", + "code": "1040", + "name": { + "narrative": [ + "UN Office on Drugs and Crime", + { + "xml:lang": "fr", + "#text": "Office des Nations Unies contre la drogue et le crime" + } + ] + }, + "acronym": { + "narrative": [ + "UNODC", + { + "xml:lang": "fr", + "#text": "UNODC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN032" + }, + { + "status": "Active", + "code": "1041", + "name": { + "narrative": [ + "Eurasian Fund for Stabilization and Development", + { + "xml:lang": "fr", + "#text": "Eurasian Fund for Stabilization and Development" + } + ] + }, + "acronym": { + "narrative": [ + "EFSD", + { + "xml:lang": "fr", + "#text": "EFSD" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1", + "dotstatcode": "9OTH008" + }, + { + "status": "Active", + "code": "1042", + "name": { + "narrative": [ + "UN Office of Counter-Terrorism", + { + "xml:lang": "fr", + "#text": "Bureau de l'ONU de lutte contre le terrorisme" + } + ] + }, + "acronym": { + "narrative": [ + "UNOCT", + { + "xml:lang": "fr", + "#text": "BLT" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1043", + "name": { + "narrative": [ + "Interpol", + { + "xml:lang": "fr", + "#text": "Interpol" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1044", + "name": { + "narrative": [ + "New Development Bank", + { + "xml:lang": "fr", + "#text": "New Development Bank" + } + ] + }, + "acronym": { + "narrative": [ + "NDB", + { + "xml:lang": "fr", + "#text": "NDB" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1", + "dotstatcode": "5RDB010" + }, + { + "status": "Active", + "code": "1045", + "name": { + "narrative": [ + "North American Development Bank", + { + "xml:lang": "fr", + "#text": "North American Development Bank" + } + ] + }, + "acronym": { + "narrative": [ + "NADB", + { + "xml:lang": "fr", + "#text": "NADB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5RDB011" + }, + { + "status": "Active", + "code": "1046", + "name": { + "narrative": [ + "UN Women", + { + "xml:lang": "fr", + "#text": "ONU Femmes" + } + ] + }, + "acronym": { + "narrative": [ + "UN Women", + { + "xml:lang": "fr", + "#text": "ONU Femmes" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN012" + }, + { + "status": "Active", + "code": "1047", + "name": { + "narrative": [ + "COVID-19 Response and Recovery Multi-Partner Trust Fund", + { + "xml:lang": "fr", + "#text": "COVID-19 Response and Recovery Multi-Partner Trust Fund" + } + ] + }, + "acronym": { + "narrative": [ + "UN COVID-19 MPTF", + { + "xml:lang": "fr", + "#text": "UN COVID-19 MPTF" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN002" + }, + { + "status": "Active", + "code": "1048", + "name": { + "narrative": [ + "Joint Sustainable Development Goals Fund", + { + "xml:lang": "fr", + "#text": "Fonds conjoint des objectifs de d\u00e9veloppement durable" + } + ] + }, + "acronym": { + "narrative": [ + "Joint SDG Fund", + { + "xml:lang": "fr", + "#text": "Fonds conjoint des ODD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN007" + }, + { + "status": "Active", + "code": "1049", + "name": { + "narrative": [ + "International Commission on Missing Persons", + { + "xml:lang": "fr", + "#text": "Commission internationale pour les personnes disparues" + } + ] + }, + "acronym": { + "narrative": [ + "ICMP", + { + "xml:lang": "fr", + "#text": "CIPD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH017" + }, + { + "status": "Active", + "code": "1050", + "name": { + "narrative": [ + "WHO-Strategic Preparedness and Response Plan", + { + "xml:lang": "fr", + "#text": "OMS-Plan strat\u00e9gique de pr\u00e9paration et de r\u00e9ponse" + } + ] + }, + "acronym": { + "narrative": [ + "SPRP", + { + "xml:lang": "fr", + "#text": "PSPR" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN025" + }, + { + "status": "Active", + "code": "1051", + "name": { + "narrative": [ + "United Nations Office for Disarmament Affairs", + { + "xml:lang": "fr", + "#text": "Bureau des Affaires de D\u00e9sarmement des Nations Unies" + } + ] + }, + "acronym": { + "narrative": [ + "UNODA", + { + "xml:lang": "fr", + "#text": "UNODA" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1052", + "name": { + "narrative": [ + "International Centre for Genetic Engineering and Biotechnology", + { + "xml:lang": "fr", + "#text": "Centre international de g\u00e9nie g\u00e9n\u00e9tique et de biotechnologie" + } + ] + }, + "acronym": { + "narrative": [ + "ICGEB", + { + "xml:lang": "fr", + "#text": "ICGEB" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH016" + }, + { + "status": "Active", + "code": "1053", + "name": { + "narrative": [ + "Asian Forest Cooperation Organisation", + { + "xml:lang": "fr", + "#text": "Organisation asiatique de coop\u00e9ration foresti\u00e8re" + } + ] + }, + "acronym": { + "narrative": [ + "AFoCO", + { + "xml:lang": "fr", + "#text": "AFoCO" + } + ] + }, + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH004" + }, + { + "status": "Active", + "code": "1054", + "name": { + "narrative": [ + "World Organisation for Animal Health", + { + "xml:lang": "fr", + "#text": "Organisation mondiale de la sant\u00e9 animale" + } + ] + }, + "acronym": { + "narrative": [ + "WOAH", + { + "xml:lang": "fr", + "#text": "OMSA" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH023" + }, + { + "status": "Active", + "code": "1055", + "name": { + "narrative": [ + "CGIAR", + { + "xml:lang": "fr", + "#text": "CGIAR" + } + ] + }, + "acronym": { + "narrative": [ + "CGIAR", + { + "xml:lang": "fr", + "#text": "CGIAR" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH024" + }, + { + "status": "Active", + "code": "1056", + "name": { + "narrative": [ + "Organisation of American States", + { + "xml:lang": "fr", + "#text": "Organisation des \u00c9tats am\u00e9ricains" + } + ] + }, + "acronym": { + "narrative": [ + "OAS", + { + "xml:lang": "fr", + "#text": "OEA" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1057", + "name": { + "narrative": [ + "UN Development Coordination Office", + { + "xml:lang": "fr", + "#text": "ONU-Bureau de la coordination des activit\u00e9s de d\u00e9veloppement" + } + ] + }, + "acronym": { + "narrative": [ + "UNDCO", + { + "xml:lang": "fr", + "#text": "BCAD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN030" + }, + { + "status": "Active", + "code": "1058", + "name": { + "narrative": [ + "IMF Resilience and Sustainability Trust", + { + "xml:lang": "fr", + "#text": "Fonds de r\u00e9silience et de durabilit\u00e9 du FMI" + } + ] + }, + "acronym": { + "narrative": [ + "IMF-RST", + { + "xml:lang": "fr", + "#text": "FMI-FRD" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "5IMF03" + }, + { + "status": "Active", + "code": "1059", + "name": { + "narrative": [ + "Arab Monetary Fund", + { + "xml:lang": "fr", + "#text": "Fonds mon\u00e9taire arabe" + } + ] + }, + "type": "Multilateral donor", + "crs": "0", + "tossd": "1" + }, + { + "status": "Active", + "code": "1311", + "name": { + "narrative": [ + "Global Alliance for Vaccines and Immunization", + { + "xml:lang": "fr", + "#text": "Alliance mondiale pour les vaccins et la vaccination" + } + ] + }, + "acronym": { + "narrative": [ + "GAVI", + { + "xml:lang": "fr", + "#text": "GAVI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH009" + }, + { + "status": "Active", + "code": "1312", + "name": { + "narrative": [ + "Global Fund", + { + "xml:lang": "fr", + "#text": "Fonds mondial" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH012" + }, + { + "status": "Active", + "code": "1313", + "name": { + "narrative": [ + "Global Green Growth Institute", + { + "xml:lang": "fr", + "#text": "Institut mondial de la croissance verte" + } + ] + }, + "acronym": { + "narrative": [ + "GGGI", + { + "xml:lang": "fr", + "#text": "GGGI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "9OTH013" + }, + { + "status": "Active", + "code": "1401", + "name": { + "narrative": [ + "WTO - International Trade Centre", + { + "xml:lang": "fr", + "#text": "Centre du commerce international de l'OMC" + } + ] + }, + "acronym": { + "narrative": [ + "ITC", + { + "xml:lang": "fr", + "#text": "CCI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN029" + }, + { + "status": "Active", + "code": "1403", + "name": { + "narrative": [ + "UN Economic and Social Commission for Western Asia", + { + "xml:lang": "fr", + "#text": "ONU Commission \u00e9conomique et sociale pour l'Asie occidentale" + } + ] + }, + "acronym": { + "narrative": [ + "UNESCWA", + { + "xml:lang": "fr", + "#text": "CESAO" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN031" + }, + { + "status": "Active", + "code": "1404", + "name": { + "narrative": [ + "World Trade Organisation", + { + "xml:lang": "fr", + "#text": "Organisation mondiale du commerce" + } + ] + }, + "acronym": { + "narrative": [ + "WTO", + { + "xml:lang": "fr", + "#text": "OMC" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN028" + }, + { + "status": "Active", + "code": "1406", + "name": { + "narrative": [ + "United Nations Industrial Development Organization", + { + "xml:lang": "fr", + "#text": "ONUDI" + } + ] + }, + "acronym": { + "narrative": [ + "UNIDO", + { + "xml:lang": "fr", + "#text": "ONUDI" + } + ] + }, + "type": "Multilateral donor", + "crs": "1", + "tossd": "1", + "dotstatcode": "1UN021" + }, + { + "status": "Active", + "code": "1601", + "name": { + "narrative": [ + "Gates Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Gates" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1601" + }, + { + "status": "Active", + "code": "1602", + "name": { + "narrative": [ + "Dutch Postcode Lottery", + { + "xml:lang": "fr", + "#text": "Dutch Postcode Lottery" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PLG0_NL" + }, + { + "status": "Active", + "code": "1603", + "name": { + "narrative": [ + "Swedish Postcode Lottery", + { + "xml:lang": "fr", + "#text": "Swedish Postcode Lottery" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PLG0_SE" + }, + { + "status": "Active", + "code": "1604", + "name": { + "narrative": [ + "People's Postcode Lottery", + { + "xml:lang": "fr", + "#text": "People's Postcode Lottery" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PLG0_GB" + }, + { + "status": "Active", + "code": "1605", + "name": { + "narrative": [ + "MetLife Foundation", + { + "xml:lang": "fr", + "#text": "Fondation MetLife" + } + ] + }, + "acronym": { + "narrative": [ + "MetLife", + { + "xml:lang": "fr", + "#text": "MetLife" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1605" + }, + { + "status": "Active", + "code": "1606", + "name": { + "narrative": [ + "Mastercard Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Mastercard" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1606" + }, + { + "status": "Active", + "code": "1608", + "name": { + "narrative": [ + "IKEA Foundation", + { + "xml:lang": "fr", + "#text": "Fondation IKEA" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1608" + }, + { + "status": "Active", + "code": "1609", + "name": { + "narrative": [ + "Van Leer Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Van Leer" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1609" + }, + { + "status": "Active", + "code": "1610", + "name": { + "narrative": [ + "MAVA Foundation", + { + "xml:lang": "fr", + "#text": "MAVA, Fondation pour la nature" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1610" + }, + { + "status": "Active", + "code": "1611", + "name": { + "narrative": [ + "Oak Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Oak" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1611" + }, + { + "status": "Active", + "code": "1612", + "name": { + "narrative": [ + "H&M Foundation", + { + "xml:lang": "fr", + "#text": "Fondation H&M" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1612" + }, + { + "status": "Active", + "code": "1613", + "name": { + "narrative": [ + "Laudes Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Laudes" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1613" + }, + { + "status": "Active", + "code": "1614", + "name": { + "narrative": [ + "Charity Projects Ltd (Comic Relief)", + { + "xml:lang": "fr", + "#text": "Charity Projects Ltd (Comic Relief)" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1614" + }, + { + "status": "Active", + "code": "1615", + "name": { + "narrative": [ + "Children's Investment Fund Foundation", + { + "xml:lang": "fr", + "#text": "Children's Investment Fund Foundation" + } + ] + }, + "acronym": { + "narrative": [ + "CIFF", + { + "xml:lang": "fr", + "#text": "CIFF" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1615" + }, + { + "status": "Active", + "code": "1616", + "name": { + "narrative": [ + "Gatsby Charitable Foundation", + { + "xml:lang": "fr", + "#text": "Gatsby Charitable Foundation" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1616" + }, + { + "status": "Active", + "code": "1617", + "name": { + "narrative": [ + "Conrad N. Hilton Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Conrad N. Hilton" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1617" + }, + { + "status": "Active", + "code": "1618", + "name": { + "narrative": [ + "David and Lucile Packard Foundation", + { + "xml:lang": "fr", + "#text": "Fondation David et Lucile Packard" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1618" + }, + { + "status": "Active", + "code": "1619", + "name": { + "narrative": [ + "John D. and Catherine T. MacArthur Foundation", + { + "xml:lang": "fr", + "#text": "Fondation John D. et Catherine T. MacArthur" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1619" + }, + { + "status": "Active", + "code": "1620", + "name": { + "narrative": [ + "Carnegie Corporation of New York", + { + "xml:lang": "fr", + "#text": "Carnegie Corporation of New York" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1620" + }, + { + "status": "Active", + "code": "1621", + "name": { + "narrative": [ + "Michael & Susan Dell Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Michael et Susan Dell" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1621" + }, + { + "status": "Active", + "code": "1622", + "name": { + "narrative": [ + "Omidyar Network Fund, Inc.", + { + "xml:lang": "fr", + "#text": "Omidyar Network Fund, Inc." + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1622" + }, + { + "status": "Active", + "code": "1623", + "name": { + "narrative": [ + "Rockefeller Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Rockefeller" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1623" + }, + { + "status": "Active", + "code": "1624", + "name": { + "narrative": [ + "William and Flora Hewlett Foundation", + { + "xml:lang": "fr", + "#text": "Fondation William et Flora Hewlett" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1624" + }, + { + "status": "Active", + "code": "1625", + "name": { + "narrative": [ + "Arcus Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Arcus" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1625" + }, + { + "status": "Active", + "code": "1626", + "name": { + "narrative": [ + "Gordon and Betty Moore Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Gordon et Betty Moore" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1626" + }, + { + "status": "Active", + "code": "1627", + "name": { + "narrative": [ + "Ford Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Ford" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1627" + }, + { + "status": "Active", + "code": "1628", + "name": { + "narrative": [ + "Wellcome Trust", + { + "xml:lang": "fr", + "#text": "Wellcome Trust" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1628" + }, + { + "status": "Active", + "code": "1629", + "name": { + "narrative": [ + "UBS Optimus Foundation", + { + "xml:lang": "fr", + "#text": "Fondation UBS Optimus" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1629" + }, + { + "status": "Active", + "code": "1630", + "name": { + "narrative": [ + "World Diabetes Foundation", + { + "xml:lang": "fr", + "#text": "World Diabetes Foundation" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1630" + }, + { + "status": "Active", + "code": "1631", + "name": { + "narrative": [ + "McKnight Foundation", + { + "xml:lang": "fr", + "#text": "Fondation McKnight" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1631" + }, + { + "status": "Active", + "code": "1632", + "name": { + "narrative": [ + "Citi Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Citi" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1632" + }, + { + "status": "Active", + "code": "1633", + "name": { + "narrative": [ + "LEGO Foundation", + { + "xml:lang": "fr", + "#text": "Fondation LEGO" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1633" + }, + { + "status": "Active", + "code": "1634", + "name": { + "narrative": [ + "Norwegian Postcode Lottery", + { + "xml:lang": "fr", + "#text": "Norwegian Postcode Lottery" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PLG0_NO" + }, + { + "status": "Active", + "code": "1636", + "name": { + "narrative": [ + "Jacobs Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Jacobs" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1636" + }, + { + "status": "Active", + "code": "1637", + "name": { + "narrative": [ + "Arcadia", + { + "xml:lang": "fr", + "#text": "Arcadia" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1637" + }, + { + "status": "Active", + "code": "1638", + "name": { + "narrative": [ + "Margaret A. Cargill Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Margaret A. Cargill" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1638" + }, + { + "status": "Active", + "code": "1639", + "name": { + "narrative": [ + "La Caixa Banking Foundation", + { + "xml:lang": "fr", + "#text": "Fondation la Caixa" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1639" + }, + { + "status": "Active", + "code": "1640", + "name": { + "narrative": [ + "Bloomberg Family Foundation", + { + "xml:lang": "fr", + "#text": "Bloomberg Family Foundation" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1640" + }, + { + "status": "Active", + "code": "1641", + "name": { + "narrative": [ + "Susan T. Buffett Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Susan T. Buffett" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1641" + }, + { + "status": "Active", + "code": "1642", + "name": { + "narrative": [ + "Howard G. Buffett Foundation", + { + "xml:lang": "fr", + "#text": "Fondation Howard G. Buffett" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1642" + }, + { + "status": "Active", + "code": "1643", + "name": { + "narrative": [ + "Open Society Foundations", + { + "xml:lang": "fr", + "#text": "Open Society Foundations" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1643" + }, + { + "status": "Active", + "code": "1644", + "name": { + "narrative": [ + "Fondation Botnar", + { + "xml:lang": "fr", + "#text": "Fondation Botnar" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1644" + }, + { + "status": "Active", + "code": "1645", + "name": { + "narrative": [ + "CHANEL Foundation", + { + "xml:lang": "fr", + "#text": "Fondation CHANEL" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1645" + }, + { + "status": "Active", + "code": "1646", + "name": { + "narrative": [ + "Bezos Earth Fund", + { + "xml:lang": "fr", + "#text": "Bezos Earth Fund" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1646" + }, + { + "status": "Active", + "code": "1647", + "name": { + "narrative": [ + "German Postcode Lottery", + { + "xml:lang": "fr", + "#text": "German Postcode Lottery" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PLG0_DE" + }, + { + "status": "Active", + "code": "1648", + "name": { + "narrative": [ + "Leona M. and Harry B. Helmsley Charitable Trust", + { + "xml:lang": "fr", + "#text": "Leona M. and Harry B. Helmsley Charitable Trust" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1648" + }, + { + "status": "Active", + "code": "1649", + "name": { + "narrative": [ + "Novo Nordisk Foundation", + { + "xml:lang": "fr", + "#text": "Novo Nordisk Foundation" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1649" + }, + { + "status": "Active", + "code": "1650", + "name": { + "narrative": [ + "Good Ventures Foundation", + { + "xml:lang": "fr", + "#text": "Good Ventures Foundation" + } + ] + }, + "type": "Private donor", + "crs": "1", + "tossd": "0", + "dotstatcode": "9PRIV1650" + } + ] + } + } + ] + } +} diff --git a/tests/schemas/unit/test_refresh_dac_codelists.py b/tests/schemas/unit/test_refresh_dac_codelists.py new file mode 100644 index 0000000..84059e0 --- /dev/null +++ b/tests/schemas/unit/test_refresh_dac_codelists.py @@ -0,0 +1,646 @@ +"""Offline parse/build/diff/static-guard tests for refresh_dac_codelists. + +All tests are @pytest.mark.unit and require no network access. +Fixture-backed tests skip automatically when the fixture files are absent +(run --capture-fixtures once to populate them). +""" + +from __future__ import annotations + +import json +from pathlib import Path + +import pytest + +from scripts.data_maintenance._common import dumps_canonical +from scripts.data_maintenance._static_overlays import ( + AREA_PASSTHROUGH, + DAC1_FLOW_TYPES, + DAC1_PRICES, +) +from scripts.data_maintenance.refresh_dac_codelists import ( + RefreshSettings, + build_area_map, + parse_area_codelist, + run, +) + +_FIXTURES = Path(__file__).parent.parent.parent / "fixtures" / "oecd" +_MAPPINGS = ( + Path(__file__).parent.parent.parent.parent + / "src" + / "oda_reader" + / "schemas" + / "mappings" +) + + +def _load_fixture(filename: str) -> bytes: + path = _FIXTURES / filename + if not path.exists(): + pytest.skip( + f"Fixture {filename} not yet captured — run --capture-fixtures first" + ) + return path.read_bytes() + + +def _load_committed(name: str) -> dict[str, str]: + """Load a committed mapping JSON file and return it as {str: str}.""" + return json.loads((_MAPPINGS / name).read_text(encoding="utf-8")) + + +# --------------------------------------------------------------------------- +# Inline envelope helpers (no fixtures needed) +# --------------------------------------------------------------------------- + + +def _envelope(name: str, *items: dict) -> bytes: + """Wrap codelist-item dicts in the OECD JSON envelope shape.""" + return json.dumps( + { + "codelists": { + "date-last-modified": "2026-01-01", + "codelist": [ + {"name": name, "codelist-items": {"codelist-item": list(items)}} + ], + } + } + ).encode() + + +_ACTIVE_COUNTRY = { + "status": "Active", + "code": "1", + "name": {"narrative": ["Austria", {"xml:lang": "fr", "#text": "Autriche"}]}, + "type": "DAC member", + "iso-alpha-3-code": "AUT", + "dotstatcode": "AUT", +} +_ACTIVE_ORG = { + "status": "Active", + "code": "807", + "name": {"narrative": ["UNEP", {"xml:lang": "fr", "#text": "PNUE"}]}, + "type": "Multilateral donor", + "dotstatcode": "1UN016", + # no iso-alpha-3-code — should fall back to dotstatcode +} +_INACTIVE = { + "status": "Inactive", + "code": "99", + "name": {"narrative": ["Old Country"]}, + "iso-alpha-3-code": "OLD", +} +_NO_CODE = { + "status": "Active", + "code": "888", + "name": {"narrative": ["No Code"]}, + # neither iso-alpha-3-code nor dotstatcode +} + + +# --------------------------------------------------------------------------- +# parse_area_codelist — unit tests (inline envelopes) +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_parse_returns_str_str_dict() -> None: + raw = _envelope("Providers", _ACTIVE_COUNTRY) + result = parse_area_codelist(raw) + assert isinstance(result, dict) + for k, v in result.items(): + assert isinstance(k, str) + assert isinstance(v, str) + + +@pytest.mark.unit +def test_parse_status_filter_case_insensitive() -> None: + """Both "Active" (providers) and "active" (recipients) must be included.""" + raw = _envelope( + "Mixed", + {**_ACTIVE_COUNTRY, "status": "Active"}, + {**_ACTIVE_COUNTRY, "code": "2", "iso-alpha-3-code": "BEL", "status": "active"}, + _INACTIVE, + ) + result = parse_area_codelist(raw) + assert "1" in result + assert "2" in result + assert "99" not in result + + +@pytest.mark.unit +def test_parse_org_row_uses_dotstatcode() -> None: + """Org rows (no iso3) should be projected via dotstatcode.""" + raw = _envelope("Providers", _ACTIVE_ORG) + result = parse_area_codelist(raw) + assert result.get("807") == "1UN016" + + +@pytest.mark.unit +def test_parse_dotstatcode_preferred_over_iso3() -> None: + """When iso3 and dotstatcode diverge, the .stat code (dotstatcode) wins. + + Kosovo is the real-world case: iso3 ``XKX`` vs dotstatcode ``XKV``; the .stat + schema value is ``XKV``, so the incoming data maps correctly. + """ + row = { + **_ACTIVE_COUNTRY, + "code": "57", + "iso-alpha-3-code": "XKX", + "dotstatcode": "XKV", + } + raw = _envelope("Recipients", row) + result = parse_area_codelist(raw) + assert result.get("57") == "XKV" + + +@pytest.mark.unit +def test_parse_rows_with_no_code_field_dropped() -> None: + """Rows with neither iso3 nor dotstatcode must be dropped.""" + raw = _envelope("Providers", _NO_CODE) + result = parse_area_codelist(raw) + assert "888" not in result + + +# --------------------------------------------------------------------------- +# parse_area_codelist — fixture-backed tests +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_parse_providers_fixture_shape() -> None: + raw = _load_fixture("codelist_5.json") + result = parse_area_codelist(raw) + assert len(result) >= 100, f"Expected >=100 active providers, got {len(result)}" + assert result.get("1") == "AUT", "Provider 1 should map to AUT" + assert result.get("801") == "AUS", "Provider 801 should map to AUS" + assert result.get("742") == "KOR", "Provider 742 should map to KOR" + assert result.get("807") == "1UN016", "Provider 807 (UNEP) should map to 1UN016" + + +@pytest.mark.unit +def test_parse_recipients_fixture_shape() -> None: + raw = _load_fixture("codelist_13.json") + result = parse_area_codelist(raw) + assert len(result) >= 100, f"Expected >=100 active recipients, got {len(result)}" + + +# --------------------------------------------------------------------------- +# build_area_map — unit tests (inline envelopes) +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_build_area_map_dac1_int_sorted_passthrough_last() -> None: + """dumps_canonical of build_area_map output must be digit-sorted with (.*) last.""" + raw5 = _envelope("Providers", _ACTIVE_COUNTRY, _ACTIVE_ORG) + raw13 = _envelope( + "Recipients", {**_ACTIVE_COUNTRY, "code": "55", "iso-alpha-3-code": "TUR"} + ) + result = build_area_map( + target="dac1", raw_by_id={"5": raw5, "13": raw13}, committed={} + ) + # build_area_map returns raw digit-keyed dict; dumps_canonical adds passthrough + rendered = json.loads(dumps_canonical(result)) + keys = list(rendered.keys()) + assert keys[-1] == "(.*)", "Passthrough must be the last key" + digit_keys = [k for k in keys if k != "(.*)"] + assert digit_keys == sorted(digit_keys, key=int), "Digit keys must be int-sorted" + + +@pytest.mark.unit +def test_build_area_map_providers_win_intra_live_collision() -> None: + """When the same code appears in both live codelists, the provider value wins.""" + shared_code = "55" + raw5 = _envelope( + "Providers", + {**_ACTIVE_COUNTRY, "code": shared_code, "dotstatcode": "FROM5"}, + ) + raw13 = _envelope( + "Recipients", + {**_ACTIVE_COUNTRY, "code": shared_code, "dotstatcode": "FROM13"}, + ) + result = build_area_map( + target="dac2", raw_by_id={"5": raw5, "13": raw13}, committed={} + ) + assert result[shared_code] == "FROM5", ( + "Providers (codelist 5) must win on intra-live collision" + ) + + +@pytest.mark.unit +def test_build_area_map_live_wins_over_committed_on_conflict() -> None: + """When live and committed disagree on a code's value, the live value wins. + + Modelled on EU Institutions (918): the committed base carries a stale .stat + code that the live codelist has since superseded. + """ + code = "918" + raw5 = _envelope( + "Providers", + {**_ACTIVE_COUNTRY, "code": code, "dotstatcode": "4EU001", "status": "active"}, + ) + raw13 = _envelope( + "Recipients", {**_ACTIVE_COUNTRY, "code": "55", "dotstatcode": "TUR"} + ) + committed = {code: "4EU003"} # stale committed value + result = build_area_map( + target="dac1", raw_by_id={"5": raw5, "13": raw13}, committed=committed + ) + assert result[code] == "4EU001", ( + "Live value must win over the stale committed value" + ) + + +@pytest.mark.unit +def test_build_area_map_historical_codes_preserved() -> None: + """Historical committed codes absent from live must appear in the proposed map.""" + historical_code = "376" # Anguilla — not in current live OECD lists + raw5 = _envelope("Providers", _ACTIVE_COUNTRY) + raw13 = _envelope( + "Recipients", {**_ACTIVE_COUNTRY, "code": "55", "iso-alpha-3-code": "TUR"} + ) + committed = {"1": "AUT", historical_code: "AIA"} + result = build_area_map( + target="dac1", raw_by_id={"5": raw5, "13": raw13}, committed=committed + ) + assert result.get(historical_code) == "AIA", ( + f"Historical code {historical_code} must be preserved from committed" + ) + + +@pytest.mark.unit +def test_build_area_map_unknown_target_raises() -> None: + with pytest.raises(ValueError, match="unknown target"): + build_area_map(target="bogus", raw_by_id={}, committed={}) + + +# --------------------------------------------------------------------------- +# build_area_map — fixture-backed additive-superset gate tests +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_build_area_map_dac1_superset_of_committed() -> None: + """dac1 result must be a superset of every committed digit code (additive guarantee).""" + raw5 = _load_fixture("codelist_5.json") + raw13 = _load_fixture("codelist_13.json") + raw_by_id = {"5": raw5, "13": raw13} + committed_full = _load_committed("dac1_codes_area.json") + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + result = build_area_map( + target="dac1", raw_by_id=raw_by_id, committed=committed_digits + ) + result_digits = {k: v for k, v in result.items() if k.isdigit()} + + missing = [k for k in committed_digits if k not in result_digits] + assert not missing, ( + f"build_area_map(dac1) dropped {len(missing)} committed historical codes: " + f"{missing[:10]}{'...' if len(missing) > 10 else ''}" + ) + + +@pytest.mark.unit +def test_build_area_map_dac2_superset_of_committed() -> None: + """dac2 result must be a superset of every committed digit code (additive guarantee).""" + raw5 = _load_fixture("codelist_5.json") + raw13 = _load_fixture("codelist_13.json") + raw_by_id = {"5": raw5, "13": raw13} + committed_full = _load_committed("dac2_codes_area.json") + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + result = build_area_map( + target="dac2", raw_by_id=raw_by_id, committed=committed_digits + ) + result_digits = {k: v for k, v in result.items() if k.isdigit()} + + missing = [k for k in committed_digits if k not in result_digits] + assert not missing, ( + f"build_area_map(dac2) dropped {len(missing)} committed historical codes: " + f"{missing[:10]}{'...' if len(missing) > 10 else ''}" + ) + + +@pytest.mark.unit +def test_build_area_map_dac1_kosovo_stays_xkv_no_false_conflict() -> None: + """Kosovo (57) must stay XKV — dotstatcode preference avoids a spurious XKX change. + + The live codelist carries iso3 ``XKX`` and dotstatcode ``XKV`` for Kosovo; + preferring dotstatcode keeps the value identical to committed, so the refresh + does NOT propose a (breaking) change to the .stat code. + """ + raw5 = _load_fixture("codelist_5.json") + raw13 = _load_fixture("codelist_13.json") + committed_full = _load_committed("dac1_codes_area.json") + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + result = build_area_map( + target="dac1", raw_by_id={"5": raw5, "13": raw13}, committed=committed_digits + ) + assert committed_digits.get("57") == "XKV", "Test pre-condition: committed has XKV" + assert result.get("57") == "XKV", ( + f"Code 57 (Kosovo) should remain XKV, got {result.get('57')!r}" + ) + + +@pytest.mark.unit +def test_build_area_map_dac1_no_value_conflicts_vs_committed() -> None: + """A refreshed committed file must be value-stable: build introduces no changes. + + After the refresh is applied, every committed code's value matches the live + .stat code (e.g. EU Institutions 918 → 4EU001), so a re-run proposes no value + changes — only the additive guarantee remains. Guards against a regression that + reintroduces a spurious change (the Kosovo dotstatcode trap). + """ + raw5 = _load_fixture("codelist_5.json") + raw13 = _load_fixture("codelist_13.json") + committed_full = _load_committed("dac1_codes_area.json") + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + result = build_area_map( + target="dac1", raw_by_id={"5": raw5, "13": raw13}, committed=committed_digits + ) + changed = { + k: (committed_digits[k], result[k]) + for k in committed_digits + if k in result and committed_digits[k] != result[k] + } + assert not changed, f"Refreshed file should have no value changes, got {changed}" + assert committed_digits.get("918") == "4EU001" + assert committed_digits.get("57") == "XKV" + + +@pytest.mark.unit +def test_build_area_map_dac1_spot_values_and_sort() -> None: + """Spot-check key spot values, sort order, and passthrough sentinel in rendered output.""" + raw5 = _load_fixture("codelist_5.json") + raw13 = _load_fixture("codelist_13.json") + raw_by_id = {"5": raw5, "13": raw13} + committed_full = _load_committed("dac1_codes_area.json") + committed_digits = {k: v for k, v in committed_full.items() if k.isdigit()} + + result = build_area_map( + target="dac1", raw_by_id=raw_by_id, committed=committed_digits + ) + assert result.get("801") == "AUS" + assert result.get("1") == "AUT" + assert result.get("742") == "KOR" + assert result.get("807") == "1UN016" + # dumps_canonical unconditionally appends (.*) + rendered = json.loads(dumps_canonical(result)) + assert rendered.get("(.*)") == "\\1", "Passthrough sentinel must be present" + keys = list(rendered.keys()) + assert keys[-1] == "(.*)" + digit_keys = [k for k in keys if k != "(.*)"] + assert digit_keys == sorted(digit_keys, key=int) + + +# --------------------------------------------------------------------------- +# dumps_canonical — renderer tests +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_dumps_canonical_int_sorted() -> None: + """Digit keys must be int-sorted ascending; passthrough always appended last.""" + mapping = {"10": "X", "2": "Y", "1": "A"} + result = dumps_canonical(mapping) + parsed = json.loads(result) + keys = list(parsed.keys()) + # dumps_canonical unconditionally appends (.*) + assert keys == ["1", "2", "10", "(.*)"] + + +@pytest.mark.unit +def test_dumps_canonical_passthrough_last() -> None: + mapping = {"10": "X", "(.*)": "\\1", "1": "A"} + result = dumps_canonical(mapping) + keys = list(json.loads(result).keys()) + assert keys[-1] == "(.*)" + + +@pytest.mark.unit +def test_dumps_canonical_trailing_newline() -> None: + result = dumps_canonical({"1": "A"}) + assert result.endswith("\n") + + +@pytest.mark.unit +def test_dumps_canonical_ensure_ascii() -> None: + result = dumps_canonical({"1": "Ä"}) + # Non-ASCII characters must be escaped + assert "\\u" in result + + +# --------------------------------------------------------------------------- +# Static-constant guard (G4) +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_static_prices_matches_committed_file() -> None: + """DAC1_PRICES must equal dac1_codes_prices.json.""" + path = _MAPPINGS / "dac1_codes_prices.json" + committed = json.loads(path.read_text(encoding="utf-8")) + assert committed == DAC1_PRICES, ( + f"DAC1_PRICES diverges from committed file.\n" + f" constant: {DAC1_PRICES}\n" + f" file: {committed}" + ) + + +@pytest.mark.unit +def test_static_flow_types_matches_committed_file() -> None: + """DAC1_FLOW_TYPES must equal dac1_codes_flow_types.json.""" + path = _MAPPINGS / "dac1_codes_flow_types.json" + committed = json.loads(path.read_text(encoding="utf-8")) + assert committed == DAC1_FLOW_TYPES, ( + f"DAC1_FLOW_TYPES diverges from committed file.\n" + f" constant: {DAC1_FLOW_TYPES}\n" + f" file: {committed}" + ) + + +@pytest.mark.unit +def test_area_passthrough_in_committed_area_file() -> None: + """AREA_PASSTHROUGH sentinel must appear as the last entry of dac1_codes_area.json.""" + path = _MAPPINGS / "dac1_codes_area.json" + committed = json.loads(path.read_text(encoding="utf-8")) + last_key = list(committed.keys())[-1] + last_val = list(committed.values())[-1] + assert last_key == "(.*)", ( + f"Last key in dac1_codes_area.json should be '(.*)', got {last_key!r}" + ) + assert last_val == AREA_PASSTHROUGH["(.*)"], ( + f"Last value should be {AREA_PASSTHROUGH['(.*)']!r}, got {last_val!r}" + ) + + +# --------------------------------------------------------------------------- +# Diff / write tests (monkeypatched, no network) +# --------------------------------------------------------------------------- + + +def _mock_fetch_codelist( + codelist_id: str, *, standard: str = "0", timeout: int = 30 +) -> bytes: + """Return minimal inline envelopes for both codelists.""" + items: dict[str, list[dict]] = { + "5": [_ACTIVE_COUNTRY, _ACTIVE_ORG], + "13": [ + { + **_ACTIVE_COUNTRY, + "code": "55", + "iso-alpha-3-code": "TUR", + "dotstatcode": "TUR", + }, + ], + } + return _envelope("Test", *items.get(codelist_id, [])) + + +@pytest.mark.unit +def test_run_prints_diff_when_different( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture +) -> None: + """run() should print a unified diff when proposed != existing.""" + import scripts.data_maintenance.refresh_dac_codelists as mod + + fake_mappings = tmp_path / "mappings" + fake_mappings.mkdir() + # Start with a committed file that differs from what the mock fetch would produce + (fake_mappings / "dac1_codes_area.json").write_text( + '{"1": "OLD"}\n', encoding="utf-8" + ) + + monkeypatch.setattr(mod.ImporterPaths, "mappings", fake_mappings) + monkeypatch.setattr(mod, "fetch_codelist_json", _mock_fetch_codelist) + + rc = run(settings=RefreshSettings(target="dac1")) + assert rc == 0 + + captured = capsys.readouterr() + assert "--- dac1_codes_area.json (current)" in captured.out + assert "+++ dac1_codes_area.json (proposed)" in captured.out + # File must NOT be written in diff-only mode + assert (fake_mappings / "dac1_codes_area.json").read_text() == '{"1": "OLD"}\n' + + +@pytest.mark.unit +def test_run_no_changes_when_identical( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture +) -> None: + """run() should report 'No changes detected.' when proposed == existing.""" + import scripts.data_maintenance.refresh_dac_codelists as mod + + monkeypatch.setattr(mod, "fetch_codelist_json", _mock_fetch_codelist) + + fake_mappings = tmp_path / "mappings" + fake_mappings.mkdir() + + # Build what the tool would write for this mock: + # committed = {"1": "AUT"} (from mock codelist 5), live also yields "1"→"AUT", + # so proposed = dumps_canonical({"1": "AUT", "55": "TUR", "807": "1UN016"}) + committed_digits = {"1": "AUT"} + live5 = parse_area_codelist(_mock_fetch_codelist("5")) + live13 = parse_area_codelist(_mock_fetch_codelist("13")) + live_union = dict(live5) + for k, v in live13.items(): + live_union.setdefault(k, v) + merged = dict(committed_digits) + merged.update(live_union) + proposed_text = dumps_canonical(merged) + (fake_mappings / "dac1_codes_area.json").write_text(proposed_text, encoding="utf-8") + + monkeypatch.setattr(mod.ImporterPaths, "mappings", fake_mappings) + + rc = run(settings=RefreshSettings(target="dac1")) + assert rc == 0 + + captured = capsys.readouterr() + assert captured.out == "", "No diff output expected when identical" + assert "No changes detected." in captured.err + + +@pytest.mark.unit +def test_run_check_returns_1_on_drift( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """--check must exit non-zero when the live source differs from committed.""" + import scripts.data_maintenance.refresh_dac_codelists as mod + + fake_mappings = tmp_path / "mappings" + fake_mappings.mkdir() + (fake_mappings / "dac1_codes_area.json").write_text( + '{"1": "OLD"}\n', encoding="utf-8" + ) + monkeypatch.setattr(mod.ImporterPaths, "mappings", fake_mappings) + monkeypatch.setattr(mod, "fetch_codelist_json", _mock_fetch_codelist) + + rc = run(settings=RefreshSettings(target="dac1", check=True)) + assert rc == 1, "--check must return 1 when committed is out of date" + # diff-only: the tracked file must be left untouched + assert (fake_mappings / "dac1_codes_area.json").read_text() == '{"1": "OLD"}\n' + + +@pytest.mark.unit +def test_run_check_returns_0_when_in_sync( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """--check must exit zero when committed already matches the live source.""" + import scripts.data_maintenance.refresh_dac_codelists as mod + + monkeypatch.setattr(mod, "fetch_codelist_json", _mock_fetch_codelist) + fake_mappings = tmp_path / "mappings" + fake_mappings.mkdir() + + live5 = parse_area_codelist(_mock_fetch_codelist("5")) + live13 = parse_area_codelist(_mock_fetch_codelist("13")) + live_union = dict(live5) + for k, v in live13.items(): + live_union.setdefault(k, v) + (fake_mappings / "dac1_codes_area.json").write_text( + dumps_canonical(live_union), encoding="utf-8" + ) + monkeypatch.setattr(mod.ImporterPaths, "mappings", fake_mappings) + + rc = run(settings=RefreshSettings(target="dac1", check=True)) + assert rc == 0, "--check must return 0 when committed is in sync" + + +@pytest.mark.unit +def test_run_write_updates_file( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture +) -> None: + """--write should overwrite the area file with the canonical proposal.""" + import scripts.data_maintenance.refresh_dac_codelists as mod + + monkeypatch.setattr(mod, "fetch_codelist_json", _mock_fetch_codelist) + monkeypatch.setattr(mod, "_PROVENANCE_PATH", tmp_path / "_provenance.json") + + fake_mappings = tmp_path / "mappings" + fake_mappings.mkdir() + (fake_mappings / "dac1_codes_area.json").write_text( + '{"1": "OLD"}\n', encoding="utf-8" + ) + + monkeypatch.setattr(mod.ImporterPaths, "mappings", fake_mappings) + + rc = run(settings=RefreshSettings(target="dac1", write=True)) + assert rc == 0 + + written = json.loads((fake_mappings / "dac1_codes_area.json").read_text()) + # "1" comes from live (AUT) which overlays committed "OLD" + assert written.get("1") == "AUT" + # Historical committed code "1" (now replaced by live "AUT") is present + assert list(written.keys())[-1] == "(.*)" + + +@pytest.mark.unit +def test_run_unknown_target_returns_error(capsys: pytest.CaptureFixture) -> None: + """An unknown --target must return exit code 1.""" + rc = run(settings=RefreshSettings(target="bogus")) + assert rc == 1 + captured = capsys.readouterr() + assert "error" in captured.err.lower() diff --git a/tests/schemas/unit/test_translation_compat.py b/tests/schemas/unit/test_translation_compat.py new file mode 100644 index 0000000..eeac252 --- /dev/null +++ b/tests/schemas/unit/test_translation_compat.py @@ -0,0 +1,174 @@ +"""Characterization tests for the runtime translation consumers. + +These tests pin the output of area_code_mapping, prices_mapping, and the +schema_tools mapping functions so that future refactors cannot silently +change their behaviour. They test the mapping layer directly rather than +the full convert_* pipeline (which requires a richer DataFrame structure +not relevant to this characterization). + +All tests are @pytest.mark.unit and have no external dependencies. +""" + +from __future__ import annotations + +import pandas as pd +import pytest + +# --------------------------------------------------------------------------- +# helpers — build minimal frames for schema_tools map functions +# --------------------------------------------------------------------------- + + +def _area_frame(codes: list[str]) -> pd.DataFrame: + return pd.DataFrame({"donor_code": pd.array(codes, dtype="string[pyarrow]")}) + + +def _recipient_frame(donor: list[str], recipient: list[str]) -> pd.DataFrame: + return pd.DataFrame( + { + "donor_code": pd.array(donor, dtype="string[pyarrow]"), + "recipient_code": pd.array(recipient, dtype="string[pyarrow]"), + } + ) + + +def _prices_frame(codes: list[str], col: str = "amounttype_code") -> pd.DataFrame: + return pd.DataFrame({col: pd.array(codes, dtype="string[pyarrow]")}) + + +# --------------------------------------------------------------------------- +# dac1_translation — mapping accessors +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_dac1_area_mapping_returns_int_keyed_dict() -> None: + """area_code_mapping must return {int: str} with integer keys.""" + from oda_reader.schemas.dac1_translation import area_code_mapping + + m = area_code_mapping() + assert isinstance(m, dict) + assert len(m) > 400, f"Expected >400 entries, got {len(m)}" + assert isinstance(next(iter(m)), int), "Keys must be integers" + for v in m.values(): + assert isinstance(v, str) + + +@pytest.mark.unit +def test_dac1_area_mapping_spot_values() -> None: + """Spot-check critical dac1 area code mappings.""" + from oda_reader.schemas.dac1_translation import area_code_mapping + + m = area_code_mapping() + cases = {1: "AUT", 801: "AUS", 742: "KOR", 4: "FRA"} + for dac_code, expected in cases.items(): + assert m.get(dac_code) == expected, ( + f"Expected m[{dac_code}]={expected!r}, got {m.get(dac_code)!r}" + ) + + +@pytest.mark.unit +def test_dac1_prices_mapping() -> None: + """Prices mapping: V→A, Q→D.""" + from oda_reader.schemas.dac1_translation import prices_mapping + + m = prices_mapping() + assert m["V"] == "A" + assert m["Q"] == "D" + + +@pytest.mark.unit +def test_dac1_flow_types_mapping() -> None: + """Flow types mapping must include 115→C, 112→D, and the regex passthrough.""" + from oda_reader.schemas.dac1_translation import flow_types_mapping + + m = flow_types_mapping() + assert m["115"] == "C" + assert m["112"] == "D" + assert m["(.*)"] == "\\1" + + +# --------------------------------------------------------------------------- +# crs_translation — mapping accessors +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_crs_area_mapping_keys_are_integers() -> None: + """CRS area_code_mapping must return int-keyed dict.""" + from oda_reader.schemas.crs_translation import area_code_mapping + + m = area_code_mapping() + assert len(m) > 400 + for k in m: + assert isinstance(k, int), f"Expected int key, got {type(k).__name__}: {k!r}" + + +@pytest.mark.unit +def test_crs_area_mapping_spot_values() -> None: + """CRS area mapping must share dac2's area values for AUT and AUS.""" + from oda_reader.schemas.crs_translation import area_code_mapping + + m = area_code_mapping() + assert m.get(1) == "AUT" + assert m.get(801) == "AUS" + + +# --------------------------------------------------------------------------- +# schema_tools map functions — direct characterization +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_map_area_codes_inverts_mapping() -> None: + """map_area_codes inverts {dac_int: iso3} to {iso3: dac_int} and maps the column.""" + from oda_reader.schemas.dac1_translation import area_code_mapping + from oda_reader.schemas.schema_tools import map_area_codes + + m = area_code_mapping() + df = _area_frame(["AUT"]) + result = map_area_codes(df, area_code_mapping=m) + assert int(result["donor_code"].iloc[0]) == 1 + + +@pytest.mark.unit +def test_map_area_codes_australia() -> None: + """Australia (AUS → 801) must map correctly.""" + from oda_reader.schemas.dac1_translation import area_code_mapping + from oda_reader.schemas.schema_tools import map_area_codes + + m = area_code_mapping() + df = _area_frame(["AUS"]) + result = map_area_codes(df, area_code_mapping=m) + assert int(result["donor_code"].iloc[0]) == 801 + + +@pytest.mark.unit +def test_map_amount_type_codes_prices() -> None: + """map_amount_type_codes applies prices_mapping directly: V→A and Q→D.""" + from oda_reader.schemas.dac1_translation import prices_mapping + from oda_reader.schemas.schema_tools import map_amount_type_codes + + # prices_mapping = {"V": "A", "Q": "D"} — maps old DAC codes to .stat codes + m = prices_mapping() + df = _prices_frame(["V", "Q"]) + result = map_amount_type_codes(df, prices_mapping=m) + assert result["amounttype_code"].iloc[0] == "A" + assert result["amounttype_code"].iloc[1] == "D" + + +@pytest.mark.unit +def test_map_area_codes_recipient_column() -> None: + """map_area_codes with source/target=recipient_code maps recipients correctly.""" + from oda_reader.schemas.crs_translation import area_code_mapping + from oda_reader.schemas.schema_tools import map_area_codes + + m = area_code_mapping() + df = _recipient_frame(["AUT"], ["AUS"]) + result = map_area_codes( + df, + area_code_mapping=m, + source_column="recipient_code", + target_column="recipient_code", + ) + assert int(result["recipient_code"].iloc[0]) == 801