Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Documentation for this module may be created at Module:LegalStatus/doc

-- Module:LegalStatus
-- Renders a color-coded legal status table + choropleth map for substance articles.
-- Usage in articles:
--   {{#invoke:LegalStatus|render | de=grey | de_note=NpSG grey area | ru=unscheduled }}

local p = {}

-- Maps lowercase ISO 3166-1 alpha-2 param name โ†’ { display name, flag emoji, GeoJSON ISO key }
-- The GeoJSON ISO key matches what geojson_to_lua.py writes into Module:CountryGeoJSON.
local COUNTRIES = {
    af = { "Afghanistan",            "๐Ÿ‡ฆ๐Ÿ‡ซ", "AF" },
    al = { "Albania",                "๐Ÿ‡ฆ๐Ÿ‡ฑ", "AL" },
    dz = { "Algeria",                "๐Ÿ‡ฉ๐Ÿ‡ฟ", "DZ" },
    ad = { "Andorra",                "๐Ÿ‡ฆ๐Ÿ‡ฉ", "AD" },
    ao = { "Angola",                 "๐Ÿ‡ฆ๐Ÿ‡ด", "AO" },
    ar = { "Argentina",              "๐Ÿ‡ฆ๐Ÿ‡ท", "AR" },
    am = { "Armenia",                "๐Ÿ‡ฆ๐Ÿ‡ฒ", "AM" },
    au = { "Australia",              "๐Ÿ‡ฆ๐Ÿ‡บ", "AU" },
    at = { "Austria",                "๐Ÿ‡ฆ๐Ÿ‡น", "AT" },
    az = { "Azerbaijan",             "๐Ÿ‡ฆ๐Ÿ‡ฟ", "AZ" },
    bs = { "Bahamas",                "๐Ÿ‡ง๐Ÿ‡ธ", "BS" },
    bh = { "Bahrain",                "๐Ÿ‡ง๐Ÿ‡ญ", "BH" },
    bd = { "Bangladesh",             "๐Ÿ‡ง๐Ÿ‡ฉ", "BD" },
    bb = { "Barbados",               "๐Ÿ‡ง๐Ÿ‡ง", "BB" },
    by = { "Belarus",                "๐Ÿ‡ง๐Ÿ‡พ", "BY" },
    be = { "Belgium",                "๐Ÿ‡ง๐Ÿ‡ช", "BE" },
    bz = { "Belize",                 "๐Ÿ‡ง๐Ÿ‡ฟ", "BZ" },
    bj = { "Benin",                  "๐Ÿ‡ง๐Ÿ‡ฏ", "BJ" },
    bt = { "Bhutan",                 "๐Ÿ‡ง๐Ÿ‡น", "BT" },
    bo = { "Bolivia",                "๐Ÿ‡ง๐Ÿ‡ด", "BO" },
    ba = { "Bosnia and Herzegovina", "๐Ÿ‡ง๐Ÿ‡ฆ", "BA" },
    bw = { "Botswana",               "๐Ÿ‡ง๐Ÿ‡ผ", "BW" },
    br = { "Brazil",                 "๐Ÿ‡ง๐Ÿ‡ท", "BR" },
    bn = { "Brunei",                 "๐Ÿ‡ง๐Ÿ‡ณ", "BN" },
    bg = { "Bulgaria",               "๐Ÿ‡ง๐Ÿ‡ฌ", "BG" },
    bf = { "Burkina Faso",           "๐Ÿ‡ง๐Ÿ‡ซ", "BF" },
    bi = { "Burundi",                "๐Ÿ‡ง๐Ÿ‡ฎ", "BI" },
    cv = { "Cabo Verde",             "๐Ÿ‡จ๐Ÿ‡ป", "CV" },
    kh = { "Cambodia",               "๐Ÿ‡ฐ๐Ÿ‡ญ", "KH" },
    cm = { "Cameroon",               "๐Ÿ‡จ๐Ÿ‡ฒ", "CM" },
    ca = { "Canada",                 "๐Ÿ‡จ๐Ÿ‡ฆ", "CA" },
    cf = { "Central African Republic","๐Ÿ‡จ๐Ÿ‡ซ","CF" },
    td = { "Chad",                   "๐Ÿ‡น๐Ÿ‡ฉ", "TD" },
    cl = { "Chile",                  "๐Ÿ‡จ๐Ÿ‡ฑ", "CL" },
    cn = { "China",                  "๐Ÿ‡จ๐Ÿ‡ณ", "CN" },
    co = { "Colombia",               "๐Ÿ‡จ๐Ÿ‡ด", "CO" },
    km = { "Comoros",                "๐Ÿ‡ฐ๐Ÿ‡ฒ", "KM" },
    cg = { "Republic of the Congo",  "๐Ÿ‡จ๐Ÿ‡ฌ", "CG" },
    cd = { "DR Congo",               "๐Ÿ‡จ๐Ÿ‡ฉ", "CD" },
    cr = { "Costa Rica",             "๐Ÿ‡จ๐Ÿ‡ท", "CR" },
    hr = { "Croatia",                "๐Ÿ‡ญ๐Ÿ‡ท", "HR" },
    cu = { "Cuba",                   "๐Ÿ‡จ๐Ÿ‡บ", "CU" },
    cy = { "Cyprus",                 "๐Ÿ‡จ๐Ÿ‡พ", "CY" },
    cz = { "Czech Republic",         "๐Ÿ‡จ๐Ÿ‡ฟ", "CZ" },
    dk = { "Denmark",                "๐Ÿ‡ฉ๐Ÿ‡ฐ", "DK" },
    dj = { "Djibouti",               "๐Ÿ‡ฉ๐Ÿ‡ฏ", "DJ" },
    ["do"] = { "Dominican Republic", "๐Ÿ‡ฉ๐Ÿ‡ด", "DO" },
    ec = { "Ecuador",                "๐Ÿ‡ช๐Ÿ‡จ", "EC" },
    eg = { "Egypt",                  "๐Ÿ‡ช๐Ÿ‡ฌ", "EG" },
    sv = { "El Salvador",            "๐Ÿ‡ธ๐Ÿ‡ป", "SV" },
    gq = { "Equatorial Guinea",      "๐Ÿ‡ฌ๐Ÿ‡ถ", "GQ" },
    er = { "Eritrea",                "๐Ÿ‡ช๐Ÿ‡ท", "ER" },
    ee = { "Estonia",                "๐Ÿ‡ช๐Ÿ‡ช", "EE" },
    sz = { "Eswatini",               "๐Ÿ‡ธ๐Ÿ‡ฟ", "SZ" },
    et = { "Ethiopia",               "๐Ÿ‡ช๐Ÿ‡น", "ET" },
    fj = { "Fiji",                   "๐Ÿ‡ซ๐Ÿ‡ฏ", "FJ" },
    fi = { "Finland",                "๐Ÿ‡ซ๐Ÿ‡ฎ", "FI" },
    fr = { "France",                 "๐Ÿ‡ซ๐Ÿ‡ท", "FR" },
    ga = { "Gabon",                  "๐Ÿ‡ฌ๐Ÿ‡ฆ", "GA" },
    gm = { "Gambia",                 "๐Ÿ‡ฌ๐Ÿ‡ฒ", "GM" },
    ge = { "Georgia",                "๐Ÿ‡ฌ๐Ÿ‡ช", "GE" },
    de = { "Germany",                "๐Ÿ‡ฉ๐Ÿ‡ช", "DE" },
    gh = { "Ghana",                  "๐Ÿ‡ฌ๐Ÿ‡ญ", "GH" },
    gr = { "Greece",                 "๐Ÿ‡ฌ๐Ÿ‡ท", "GR" },
    gd = { "Grenada",                "๐Ÿ‡ฌ๐Ÿ‡ฉ", "GD" },
    gt = { "Guatemala",              "๐Ÿ‡ฌ๐Ÿ‡น", "GT" },
    gn = { "Guinea",                 "๐Ÿ‡ฌ๐Ÿ‡ณ", "GN" },
    gw = { "Guinea-Bissau",          "๐Ÿ‡ฌ๐Ÿ‡ผ", "GW" },
    gy = { "Guyana",                 "๐Ÿ‡ฌ๐Ÿ‡พ", "GY" },
    ht = { "Haiti",                  "๐Ÿ‡ญ๐Ÿ‡น", "HT" },
    hn = { "Honduras",               "๐Ÿ‡ญ๐Ÿ‡ณ", "HN" },
    hu = { "Hungary",                "๐Ÿ‡ญ๐Ÿ‡บ", "HU" },
    is = { "Iceland",                "๐Ÿ‡ฎ๐Ÿ‡ธ", "IS" },
    ["in"] = { "India",              "๐Ÿ‡ฎ๐Ÿ‡ณ", "IN" },
    id = { "Indonesia",              "๐Ÿ‡ฎ๐Ÿ‡ฉ", "ID" },
    ir = { "Iran",                   "๐Ÿ‡ฎ๐Ÿ‡ท", "IR" },
    iq = { "Iraq",                   "๐Ÿ‡ฎ๐Ÿ‡ถ", "IQ" },
    ie = { "Ireland",                "๐Ÿ‡ฎ๐Ÿ‡ช", "IE" },
    il = { "Israel",                 "๐Ÿ‡ฎ๐Ÿ‡ฑ", "IL" },
    it = { "Italy",                  "๐Ÿ‡ฎ๐Ÿ‡น", "IT" },
    jm = { "Jamaica",                "๐Ÿ‡ฏ๐Ÿ‡ฒ", "JM" },
    jp = { "Japan",                  "๐Ÿ‡ฏ๐Ÿ‡ต", "JP" },
    jo = { "Jordan",                 "๐Ÿ‡ฏ๐Ÿ‡ด", "JO" },
    kz = { "Kazakhstan",             "๐Ÿ‡ฐ๐Ÿ‡ฟ", "KZ" },
    ke = { "Kenya",                  "๐Ÿ‡ฐ๐Ÿ‡ช", "KE" },
    ki = { "Kiribati",               "๐Ÿ‡ฐ๐Ÿ‡ฎ", "KI" },
    kp = { "North Korea",            "๐Ÿ‡ฐ๐Ÿ‡ต", "KP" },
    kr = { "South Korea",            "๐Ÿ‡ฐ๐Ÿ‡ท", "KR" },
    kw = { "Kuwait",                 "๐Ÿ‡ฐ๐Ÿ‡ผ", "KW" },
    kg = { "Kyrgyzstan",             "๐Ÿ‡ฐ๐Ÿ‡ฌ", "KG" },
    la = { "Laos",                   "๐Ÿ‡ฑ๐Ÿ‡ฆ", "LA" },
    lv = { "Latvia",                 "๐Ÿ‡ฑ๐Ÿ‡ป", "LV" },
    lb = { "Lebanon",                "๐Ÿ‡ฑ๐Ÿ‡ง", "LB" },
    ls = { "Lesotho",                "๐Ÿ‡ฑ๐Ÿ‡ธ", "LS" },
    lr = { "Liberia",                "๐Ÿ‡ฑ๐Ÿ‡ท", "LR" },
    ly = { "Libya",                  "๐Ÿ‡ฑ๐Ÿ‡พ", "LY" },
    li = { "Liechtenstein",          "๐Ÿ‡ฑ๐Ÿ‡ฎ", "LI" },
    lt = { "Lithuania",              "๐Ÿ‡ฑ๐Ÿ‡น", "LT" },
    lu = { "Luxembourg",             "๐Ÿ‡ฑ๐Ÿ‡บ", "LU" },
    mg = { "Madagascar",             "๐Ÿ‡ฒ๐Ÿ‡ฌ", "MG" },
    mw = { "Malawi",                 "๐Ÿ‡ฒ๐Ÿ‡ผ", "MW" },
    my = { "Malaysia",               "๐Ÿ‡ฒ๐Ÿ‡พ", "MY" },
    mv = { "Maldives",               "๐Ÿ‡ฒ๐Ÿ‡ป", "MV" },
    ml = { "Mali",                   "๐Ÿ‡ฒ๐Ÿ‡ฑ", "ML" },
    mt = { "Malta",                  "๐Ÿ‡ฒ๐Ÿ‡น", "MT" },
    mr = { "Mauritania",             "๐Ÿ‡ฒ๐Ÿ‡ท", "MR" },
    mu = { "Mauritius",              "๐Ÿ‡ฒ๐Ÿ‡บ", "MU" },
    mx = { "Mexico",                 "๐Ÿ‡ฒ๐Ÿ‡ฝ", "MX" },
    fm = { "Micronesia",             "๐Ÿ‡ซ๐Ÿ‡ฒ", "FM" },
    md = { "Moldova",                "๐Ÿ‡ฒ๐Ÿ‡ฉ", "MD" },
    mc = { "Monaco",                 "๐Ÿ‡ฒ๐Ÿ‡จ", "MC" },
    mn = { "Mongolia",               "๐Ÿ‡ฒ๐Ÿ‡ณ", "MN" },
    me = { "Montenegro",             "๐Ÿ‡ฒ๐Ÿ‡ช", "ME" },
    ma = { "Morocco",                "๐Ÿ‡ฒ๐Ÿ‡ฆ", "MA" },
    mz = { "Mozambique",             "๐Ÿ‡ฒ๐Ÿ‡ฟ", "MZ" },
    mm = { "Myanmar",                "๐Ÿ‡ฒ๐Ÿ‡ฒ", "MM" },
    na = { "Namibia",                "๐Ÿ‡ณ๐Ÿ‡ฆ", "NA" },
    nr = { "Nauru",                  "๐Ÿ‡ณ๐Ÿ‡ท", "NR" },
    np = { "Nepal",                  "๐Ÿ‡ณ๐Ÿ‡ต", "NP" },
    nl = { "Netherlands",            "๐Ÿ‡ณ๐Ÿ‡ฑ", "NL" },
    nz = { "New Zealand",            "๐Ÿ‡ณ๐Ÿ‡ฟ", "NZ" },
    ni = { "Nicaragua",              "๐Ÿ‡ณ๐Ÿ‡ฎ", "NI" },
    ne = { "Niger",                  "๐Ÿ‡ณ๐Ÿ‡ช", "NE" },
    ng = { "Nigeria",                "๐Ÿ‡ณ๐Ÿ‡ฌ", "NG" },
    mk = { "North Macedonia",        "๐Ÿ‡ฒ๐Ÿ‡ฐ", "MK" },
    no = { "Norway",                 "๐Ÿ‡ณ๐Ÿ‡ด", "NO" },
    om = { "Oman",                   "๐Ÿ‡ด๐Ÿ‡ฒ", "OM" },
    pk = { "Pakistan",               "๐Ÿ‡ต๐Ÿ‡ฐ", "PK" },
    pw = { "Palau",                  "๐Ÿ‡ต๐Ÿ‡ผ", "PW" },
    pa = { "Panama",                 "๐Ÿ‡ต๐Ÿ‡ฆ", "PA" },
    pg = { "Papua New Guinea",       "๐Ÿ‡ต๐Ÿ‡ฌ", "PG" },
    py = { "Paraguay",               "๐Ÿ‡ต๐Ÿ‡พ", "PY" },
    pe = { "Peru",                   "๐Ÿ‡ต๐Ÿ‡ช", "PE" },
    ph = { "Philippines",            "๐Ÿ‡ต๐Ÿ‡ญ", "PH" },
    pl = { "Poland",                 "๐Ÿ‡ต๐Ÿ‡ฑ", "PL" },
    pt = { "Portugal",               "๐Ÿ‡ต๐Ÿ‡น", "PT" },
    qa = { "Qatar",                  "๐Ÿ‡ถ๐Ÿ‡ฆ", "QA" },
    ro = { "Romania",                "๐Ÿ‡ท๐Ÿ‡ด", "RO" },
    ru = { "Russia",                 "๐Ÿ‡ท๐Ÿ‡บ", "RU" },
    rw = { "Rwanda",                 "๐Ÿ‡ท๐Ÿ‡ผ", "RW" },
    kn = { "Saint Kitts and Nevis",  "๐Ÿ‡ฐ๐Ÿ‡ณ", "KN" },
    lc = { "Saint Lucia",            "๐Ÿ‡ฑ๐Ÿ‡จ", "LC" },
    vc = { "Saint Vincent",          "๐Ÿ‡ป๐Ÿ‡จ", "VC" },
    ws = { "Samoa",                  "๐Ÿ‡ผ๐Ÿ‡ธ", "WS" },
    sm = { "San Marino",             "๐Ÿ‡ธ๐Ÿ‡ฒ", "SM" },
    st = { "Sรฃo Tomรฉ and Prรญncipe",  "๐Ÿ‡ธ๐Ÿ‡น", "ST" },
    sa = { "Saudi Arabia",           "๐Ÿ‡ธ๐Ÿ‡ฆ", "SA" },
    sn = { "Senegal",                "๐Ÿ‡ธ๐Ÿ‡ณ", "SN" },
    rs = { "Serbia",                 "๐Ÿ‡ท๐Ÿ‡ธ", "RS" },
    sc = { "Seychelles",             "๐Ÿ‡ธ๐Ÿ‡จ", "SC" },
    sl = { "Sierra Leone",           "๐Ÿ‡ธ๐Ÿ‡ฑ", "SL" },
    sg = { "Singapore",              "๐Ÿ‡ธ๐Ÿ‡ฌ", "SG" },
    sk = { "Slovakia",               "๐Ÿ‡ธ๐Ÿ‡ฐ", "SK" },
    si = { "Slovenia",               "๐Ÿ‡ธ๐Ÿ‡ฎ", "SI" },
    sb = { "Solomon Islands",        "๐Ÿ‡ธ๐Ÿ‡ง", "SB" },
    so = { "Somalia",                "๐Ÿ‡ธ๐Ÿ‡ด", "SO" },
    za = { "South Africa",           "๐Ÿ‡ฟ๐Ÿ‡ฆ", "ZA" },
    ss = { "South Sudan",            "๐Ÿ‡ธ๐Ÿ‡ธ", "SS" },
    es = { "Spain",                  "๐Ÿ‡ช๐Ÿ‡ธ", "ES" },
    lk = { "Sri Lanka",              "๐Ÿ‡ฑ๐Ÿ‡ฐ", "LK" },
    sd = { "Sudan",                  "๐Ÿ‡ธ๐Ÿ‡ฉ", "SD" },
    sr = { "Suriname",               "๐Ÿ‡ธ๐Ÿ‡ท", "SR" },
    se = { "Sweden",                 "๐Ÿ‡ธ๐Ÿ‡ช", "SE" },
    ch = { "Switzerland",            "๐Ÿ‡จ๐Ÿ‡ญ", "CH" },
    sy = { "Syria",                  "๐Ÿ‡ธ๐Ÿ‡พ", "SY" },
    tw = { "Taiwan",                 "๐Ÿ‡น๐Ÿ‡ผ", "TW" },
    tj = { "Tajikistan",             "๐Ÿ‡น๐Ÿ‡ฏ", "TJ" },
    tz = { "Tanzania",               "๐Ÿ‡น๐Ÿ‡ฟ", "TZ" },
    th = { "Thailand",               "๐Ÿ‡น๐Ÿ‡ญ", "TH" },
    tl = { "Timor-Leste",            "๐Ÿ‡น๐Ÿ‡ฑ", "TL" },
    tg = { "Togo",                   "๐Ÿ‡น๐Ÿ‡ฌ", "TG" },
    to = { "Tonga",                  "๐Ÿ‡น๐Ÿ‡ด", "TO" },
    tt = { "Trinidad and Tobago",    "๐Ÿ‡น๐Ÿ‡น", "TT" },
    tn = { "Tunisia",                "๐Ÿ‡น๐Ÿ‡ณ", "TN" },
    tr = { "Turkey",                 "๐Ÿ‡น๐Ÿ‡ท", "TR" },
    tm = { "Turkmenistan",           "๐Ÿ‡น๐Ÿ‡ฒ", "TM" },
    tv = { "Tuvalu",                 "๐Ÿ‡น๐Ÿ‡ป", "TV" },
    ug = { "Uganda",                 "๐Ÿ‡บ๐Ÿ‡ฌ", "UG" },
    ua = { "Ukraine",                "๐Ÿ‡บ๐Ÿ‡ฆ", "UA" },
    ae = { "United Arab Emirates",   "๐Ÿ‡ฆ๐Ÿ‡ช", "AE" },
    uk = { "United Kingdom",         "๐Ÿ‡ฌ๐Ÿ‡ง", "GB" },
    us = { "United States",          "๐Ÿ‡บ๐Ÿ‡ธ", "US" },
    uy = { "Uruguay",                "๐Ÿ‡บ๐Ÿ‡พ", "UY" },
    uz = { "Uzbekistan",             "๐Ÿ‡บ๐Ÿ‡ฟ", "UZ" },
    vu = { "Vanuatu",                "๐Ÿ‡ป๐Ÿ‡บ", "VU" },
    ve = { "Venezuela",              "๐Ÿ‡ป๐Ÿ‡ช", "VE" },
    vn = { "Vietnam",                "๐Ÿ‡ป๐Ÿ‡ณ", "VN" },
    ye = { "Yemen",                  "๐Ÿ‡พ๐Ÿ‡ช", "YE" },
    zm = { "Zambia",                 "๐Ÿ‡ฟ๐Ÿ‡ฒ", "ZM" },
    zw = { "Zimbabwe",               "๐Ÿ‡ฟ๐Ÿ‡ผ", "ZW" },
}

local STATUS_LABEL = {
    unscheduled  = "Unscheduled",
    scheduled    = "Scheduled",
    grey         = "Grey area",
    prescription = "Prescription only",
    unknown      = "Unknown",
}

local STATUS_CSS = {
    unscheduled  = "unscheduled",
    scheduled    = "scheduled",
    grey         = "grey",
    prescription = "prescription",
    unknown      = "unknown",
}

-- Fill colors match the CSS badge palette (common-css.css)
local STATUS_FILL = {
    unscheduled  = "#28a745",
    scheduled    = "#dc3545",
    grey         = "#e6a817",
    prescription = "#0d6efd",
    unknown      = "#adb5bd",
}

local function parseArgs(args)
    local result = {}
    for k, v in pairs(args) do
        k = mw.text.trim(tostring(k))
        v = mw.text.trim(tostring(v))
        if COUNTRIES[k] and v ~= "" and not k:find("_note$") then
            table.insert(result, {
                code   = k,
                status = v,
                note   = mw.text.trim(args[k .. "_note"] or ""),
                meta   = COUNTRIES[k],
            })
        end
    end
    table.sort(result, function(a, b) return a.meta[1] < b.meta[1] end)
    return result
end

local function buildTable(countries)
    local t = mw.html.create("table"):addClass("legal-status-table")
    for _, c in ipairs(countries) do
        local label  = STATUS_LABEL[c.status]  or "Unknown"
        local css    = STATUS_CSS[c.status]    or "unknown"
        local tr = t:tag("tr")
        tr:tag("td"):addClass("legal-status-table__country")
          :wikitext(c.meta[2] .. "\u{00A0}" .. c.meta[1])
        tr:tag("td")
          :wikitext('<span class="legal-status-badge legal-status-badge--' .. css .. '">'
                    .. label .. '</span>')
        tr:tag("td"):addClass("legal-status-table__note"):wikitext(c.note)
    end
    return tostring(t)
end

local function buildMap(frame, countries)
    local ok, geoData = pcall(mw.loadData, "Module:CountryGeoJSON")
    if not ok then
        -- Map is optional; table still renders without it
        return ""
    end

    local features = {}
    for _, c in ipairs(countries) do
        local iso = c.meta[3]
        local geo = geoData[iso]
        if geo then
            table.insert(features, {
                type = "Feature",
                properties = {
                    ["fill"]           = STATUS_FILL[c.status] or STATUS_FILL.unknown,
                    ["fill-opacity"]   = 0.65,
                    ["stroke"]         = "#444444",
                    ["stroke-width"]   = 1,
                    ["stroke-opacity"] = 0.6,
                    title              = c.meta[1],
                    description        = STATUS_LABEL[c.status] or "Unknown",
                },
                geometry = {
                    type        = geo.t,
                    coordinates = geo.c,
                },
            })
        end
    end

    if #features == 0 then return "" end

    local geojson = mw.text.jsonEncode({
        type     = "FeatureCollection",
        features = features,
    })

    local mapHtml = frame:callParserFunction("#display_map", {
        geojson = geojson,
        width   = "100%",
        height  = "260",
        zoom    = "1",
    })

    return mapHtml
end

function p.render(frame)
    local args = frame.args
    local countries = parseArgs(args)
    if #countries == 0 then return "" end

    local mapHtml   = buildMap(frame, countries)
    local tableHtml = buildTable(countries)
    return mapHtml .. "\n" .. tableHtml
end

return p