// packages/core/src/js/data.ts
var rawCountryData = [
  [
    "af",
    // Afghanistan
    "93",
    0,
    null,
    "0"
  ],
  [
    "ax",
    // Åland Islands (AKA Aland Islands)
    "358",
    1,
    ["18", "4"],
    // (4 is a mobile range shared with FI)
    // NOTE: https://en.wikipedia.org/wiki/Telephone%20numbers%20in%20%C3%85land says some 4XXX ranges (e.g. 4570) are specific to AX, but LPN doesn't respect this (https://libphonenumber.appspot.com/phonenumberparser?number=%2B3584570123456 says region=FI) so we won't either. Also it's too much of a maintenance burden to keep track of. Keep the 4 area code range here so that if the user selects AX and types this kind of number, we wont change the flag to FI. Whereas if they type a FI-only range then we will.
    "0"
  ],
  [
    "al",
    // Albania
    "355",
    0,
    null,
    "0"
  ],
  [
    "dz",
    // Algeria
    "213",
    0,
    null,
    "0"
  ],
  [
    "as",
    // American Samoa
    "1",
    5,
    ["684"],
    "1"
  ],
  [
    "ad",
    // Andorra
    "376"
  ],
  [
    "ao",
    // Angola
    "244"
  ],
  [
    "ai",
    // Anguilla
    "1",
    6,
    ["264"],
    "1"
  ],
  [
    "ag",
    // Antigua and Barbuda
    "1",
    7,
    ["268"],
    "1"
  ],
  [
    "ar",
    // Argentina
    "54",
    0,
    null,
    "0"
  ],
  [
    "am",
    // Armenia
    "374",
    0,
    null,
    "0"
  ],
  [
    "aw",
    // Aruba
    "297"
  ],
  [
    "ac",
    // Ascension Island
    "247"
  ],
  [
    "au",
    // Australia
    "61",
    0,
    ["4"],
    // (mobile range shared with CX and CC)
    "0"
  ],
  [
    "at",
    // Austria
    "43",
    0,
    null,
    "0"
  ],
  [
    "az",
    // Azerbaijan
    "994",
    0,
    null,
    "0"
  ],
  [
    "bs",
    // Bahamas
    "1",
    8,
    ["242"],
    "1"
  ],
  [
    "bh",
    // Bahrain
    "973"
  ],
  [
    "bd",
    // Bangladesh
    "880",
    0,
    null,
    "0"
  ],
  [
    "bb",
    // Barbados
    "1",
    9,
    ["246"],
    "1"
  ],
  [
    "by",
    // Belarus
    "375",
    0,
    null,
    "8"
  ],
  [
    "be",
    // Belgium
    "32",
    0,
    null,
    "0"
  ],
  [
    "bz",
    // Belize
    "501"
  ],
  [
    "bj",
    // Benin
    "229"
  ],
  [
    "bm",
    // Bermuda
    "1",
    10,
    ["441"],
    "1"
  ],
  [
    "bt",
    // Bhutan
    "975"
  ],
  [
    "bo",
    // Bolivia
    "591",
    0,
    null,
    "0"
  ],
  [
    "ba",
    // Bosnia and Herzegovina
    "387",
    0,
    null,
    "0"
  ],
  [
    "bw",
    // Botswana
    "267"
  ],
  [
    "br",
    // Brazil
    "55",
    0,
    null,
    "0"
  ],
  [
    "io",
    // British Indian Ocean Territory
    "246"
  ],
  [
    "vg",
    // British Virgin Islands
    "1",
    11,
    ["284"],
    "1"
  ],
  [
    "bn",
    // Brunei
    "673"
  ],
  [
    "bg",
    // Bulgaria
    "359",
    0,
    null,
    "0"
  ],
  [
    "bf",
    // Burkina Faso
    "226"
  ],
  [
    "bi",
    // Burundi
    "257"
  ],
  [
    "kh",
    // Cambodia
    "855",
    0,
    null,
    "0"
  ],
  [
    "cm",
    // Cameroon
    "237"
  ],
  [
    "ca",
    // Canada
    "1",
    1,
    [
      "204",
      "226",
      "236",
      "249",
      "250",
      "257",
      "263",
      "289",
      "306",
      "343",
      "354",
      "365",
      "367",
      "368",
      "382",
      "403",
      "416",
      "418",
      "428",
      "431",
      "437",
      "438",
      "450",
      "468",
      "474",
      "506",
      "514",
      "519",
      "548",
      "579",
      "581",
      "584",
      "587",
      "604",
      "613",
      "639",
      "647",
      "672",
      "683",
      "705",
      "709",
      "742",
      "753",
      "778",
      "780",
      "782",
      "807",
      "819",
      "825",
      "867",
      "873",
      "879",
      "902",
      "905",
      "942"
    ],
    "1"
  ],
  [
    "cv",
    // Cape Verde
    "238"
  ],
  [
    "bq",
    // Caribbean Netherlands
    "599",
    1,
    ["3", "4", "7"]
  ],
  [
    "ky",
    // Cayman Islands
    "1",
    12,
    ["345"],
    "1"
  ],
  [
    "cf",
    // Central African Republic
    "236"
  ],
  [
    "td",
    // Chad
    "235"
  ],
  [
    "cl",
    // Chile
    "56"
  ],
  [
    "cn",
    // China
    "86",
    0,
    null,
    "0"
  ],
  [
    "cx",
    // Christmas Island
    "61",
    2,
    ["4", "89164"],
    // (4 is a mobile range shared with AU and CC)
    "0"
  ],
  [
    "cc",
    // Cocos (Keeling) Islands
    "61",
    1,
    ["4", "89162"],
    // (4 is a mobile range shared with AU and CX)
    "0"
  ],
  [
    "co",
    // Colombia
    "57",
    0,
    null,
    "0"
  ],
  [
    "km",
    // Comoros
    "269"
  ],
  [
    "cg",
    // Congo (Brazzaville)
    "242"
  ],
  [
    "cd",
    // Congo (Kinshasa)
    "243",
    0,
    null,
    "0"
  ],
  [
    "ck",
    // Cook Islands
    "682"
  ],
  [
    "cr",
    // Costa Rica
    "506"
  ],
  [
    "ci",
    // Côte d'Ivoire
    "225"
  ],
  [
    "hr",
    // Croatia
    "385",
    0,
    null,
    "0"
  ],
  [
    "cu",
    // Cuba
    "53",
    0,
    null,
    "0"
  ],
  [
    "cw",
    // Curaçao
    "599",
    0
  ],
  [
    "cy",
    // Cyprus
    "357"
  ],
  [
    "cz",
    // Czech Republic
    "420"
  ],
  [
    "dk",
    // Denmark
    "45"
  ],
  [
    "dj",
    // Djibouti
    "253"
  ],
  [
    "dm",
    // Dominica
    "1",
    13,
    ["767"],
    "1"
  ],
  [
    "do",
    // Dominican Republic
    "1",
    2,
    ["809", "829", "849"],
    "1"
  ],
  [
    "ec",
    // Ecuador
    "593",
    0,
    null,
    "0"
  ],
  [
    "eg",
    // Egypt
    "20",
    0,
    null,
    "0"
  ],
  [
    "sv",
    // El Salvador
    "503"
  ],
  [
    "gq",
    // Equatorial Guinea
    "240"
  ],
  [
    "er",
    // Eritrea
    "291",
    0,
    null,
    "0"
  ],
  [
    "ee",
    // Estonia
    "372"
  ],
  [
    "sz",
    // Eswatini
    "268"
  ],
  [
    "et",
    // Ethiopia
    "251",
    0,
    null,
    "0"
  ],
  [
    "fk",
    // Falkland Islands (Malvinas)
    "500"
  ],
  [
    "fo",
    // Faroe Islands
    "298"
  ],
  [
    "fj",
    // Fiji
    "679"
  ],
  [
    "fi",
    // Finland
    "358",
    0,
    ["4"],
    // (mobile range shared with AX)
    "0"
  ],
  [
    "fr",
    // France
    "33",
    0,
    null,
    "0"
  ],
  [
    "gf",
    // French Guiana
    "594",
    0,
    null,
    "0"
  ],
  [
    "pf",
    // French Polynesia
    "689"
  ],
  [
    "ga",
    // Gabon
    "241"
  ],
  [
    "gm",
    // Gambia
    "220"
  ],
  [
    "ge",
    // Georgia
    "995",
    0,
    null,
    "0"
  ],
  [
    "de",
    // Germany
    "49",
    0,
    null,
    "0"
  ],
  [
    "gh",
    // Ghana
    "233",
    0,
    null,
    "0"
  ],
  [
    "gi",
    // Gibraltar
    "350"
  ],
  [
    "gr",
    // Greece
    "30"
  ],
  [
    "gl",
    // Greenland
    "299"
  ],
  [
    "gd",
    // Grenada
    "1",
    14,
    ["473"],
    "1"
  ],
  [
    "gp",
    // Guadeloupe
    "590",
    0,
    null,
    "0"
  ],
  [
    "gu",
    // Guam
    "1",
    15,
    ["671"],
    "1"
  ],
  [
    "gt",
    // Guatemala
    "502"
  ],
  [
    "gg",
    // Guernsey
    "44",
    1,
    ["1481", "7781", "7839", "7911"],
    "0"
  ],
  [
    "gn",
    // Guinea
    "224"
  ],
  [
    "gw",
    // Guinea-Bissau
    "245"
  ],
  [
    "gy",
    // Guyana
    "592"
  ],
  [
    "ht",
    // Haiti
    "509"
  ],
  [
    "hn",
    // Honduras
    "504"
  ],
  [
    "hk",
    // Hong Kong SAR China
    "852"
  ],
  [
    "hu",
    // Hungary
    "36",
    0,
    null,
    "06"
  ],
  [
    "is",
    // Iceland
    "354"
  ],
  [
    "in",
    // India
    "91",
    0,
    null,
    "0"
  ],
  [
    "id",
    // Indonesia
    "62",
    0,
    null,
    "0"
  ],
  [
    "ir",
    // Iran
    "98",
    0,
    null,
    "0"
  ],
  [
    "iq",
    // Iraq
    "964",
    0,
    null,
    "0"
  ],
  [
    "ie",
    // Ireland
    "353",
    0,
    null,
    "0"
  ],
  [
    "im",
    // Isle of Man
    "44",
    2,
    ["1624", "74576", "7524", "7624", "7924"],
    "0"
  ],
  [
    "il",
    // Israel
    "972",
    0,
    null,
    "0"
  ],
  [
    "it",
    // Italy
    "39",
    0,
    ["3"]
    // (mobile range shared with VA)
  ],
  [
    "jm",
    // Jamaica
    "1",
    4,
    ["658", "876"],
    "1"
  ],
  [
    "jp",
    // Japan
    "81",
    0,
    null,
    "0"
  ],
  [
    "je",
    // Jersey
    "44",
    3,
    ["1534", "7509", "7700", "7797", "7829", "7937"],
    "0"
  ],
  [
    "jo",
    // Jordan
    "962",
    0,
    null,
    "0"
  ],
  [
    "kz",
    // Kazakhstan
    "7",
    1,
    ["33", "7"],
    // (33 is shared with RU)
    "8"
  ],
  [
    "ke",
    // Kenya
    "254",
    0,
    null,
    "0"
  ],
  [
    "ki",
    // Kiribati
    "686",
    0,
    null,
    "0"
  ],
  [
    "xk",
    // Kosovo
    "383",
    0,
    null,
    "0"
  ],
  [
    "kw",
    // Kuwait
    "965"
  ],
  [
    "kg",
    // Kyrgyzstan
    "996",
    0,
    null,
    "0"
  ],
  [
    "la",
    // Laos
    "856",
    0,
    null,
    "0"
  ],
  [
    "lv",
    // Latvia
    "371"
  ],
  [
    "lb",
    // Lebanon
    "961",
    0,
    null,
    "0"
  ],
  [
    "ls",
    // Lesotho
    "266"
  ],
  [
    "lr",
    // Liberia
    "231",
    0,
    null,
    "0"
  ],
  [
    "ly",
    // Libya
    "218",
    0,
    null,
    "0"
  ],
  [
    "li",
    // Liechtenstein
    "423",
    0,
    null,
    "0"
  ],
  [
    "lt",
    // Lithuania
    "370",
    0,
    null,
    "0"
  ],
  [
    "lu",
    // Luxembourg
    "352"
  ],
  [
    "mo",
    // Macao SAR China
    "853"
  ],
  [
    "mg",
    // Madagascar
    "261",
    0,
    null,
    "0"
  ],
  [
    "mw",
    // Malawi
    "265",
    0,
    null,
    "0"
  ],
  [
    "my",
    // Malaysia
    "60",
    0,
    null,
    "0"
  ],
  [
    "mv",
    // Maldives
    "960"
  ],
  [
    "ml",
    // Mali
    "223"
  ],
  [
    "mt",
    // Malta
    "356"
  ],
  [
    "mh",
    // Marshall Islands
    "692",
    0,
    null,
    "1"
  ],
  [
    "mq",
    // Martinique
    "596",
    0,
    null,
    "0"
  ],
  [
    "mr",
    // Mauritania
    "222"
  ],
  [
    "mu",
    // Mauritius
    "230"
  ],
  [
    "yt",
    // Mayotte
    "262",
    1,
    ["269", "639"],
    "0"
  ],
  [
    "mx",
    // Mexico
    "52"
  ],
  [
    "fm",
    // Micronesia
    "691"
  ],
  [
    "md",
    // Moldova
    "373",
    0,
    null,
    "0"
  ],
  [
    "mc",
    // Monaco
    "377",
    0,
    null,
    "0"
  ],
  [
    "mn",
    // Mongolia
    "976",
    0,
    null,
    "0"
  ],
  [
    "me",
    // Montenegro
    "382",
    0,
    null,
    "0"
  ],
  [
    "ms",
    // Montserrat
    "1",
    16,
    ["664"],
    "1"
  ],
  [
    "ma",
    // Morocco
    "212",
    0,
    ["6", "7"],
    // (mobile ranges shared with EH)
    "0"
  ],
  [
    "mz",
    // Mozambique
    "258"
  ],
  [
    "mm",
    // Myanmar (Burma)
    "95",
    0,
    null,
    "0"
  ],
  [
    "na",
    // Namibia
    "264",
    0,
    null,
    "0"
  ],
  [
    "nr",
    // Nauru
    "674"
  ],
  [
    "np",
    // Nepal
    "977",
    0,
    null,
    "0"
  ],
  [
    "nl",
    // Netherlands
    "31",
    0,
    null,
    "0"
  ],
  [
    "nc",
    // New Caledonia
    "687"
  ],
  [
    "nz",
    // New Zealand
    "64",
    0,
    null,
    "0"
  ],
  [
    "ni",
    // Nicaragua
    "505"
  ],
  [
    "ne",
    // Niger
    "227"
  ],
  [
    "ng",
    // Nigeria
    "234",
    0,
    null,
    "0"
  ],
  [
    "nu",
    // Niue
    "683"
  ],
  [
    "nf",
    // Norfolk Island
    "672"
  ],
  [
    "kp",
    // North Korea
    "850",
    0,
    null,
    "0"
  ],
  [
    "mk",
    // North Macedonia
    "389",
    0,
    null,
    "0"
  ],
  [
    "mp",
    // Northern Mariana Islands
    "1",
    17,
    ["670"],
    "1"
  ],
  [
    "no",
    // Norway
    "47",
    0,
    ["4", "9"]
    // (mobile ranges shared with SJ)
  ],
  [
    "om",
    // Oman
    "968"
  ],
  [
    "pk",
    // Pakistan
    "92",
    0,
    null,
    "0"
  ],
  [
    "pw",
    // Palau
    "680"
  ],
  [
    "ps",
    // Palestinian Territories
    "970",
    0,
    null,
    "0"
  ],
  [
    "pa",
    // Panama
    "507"
  ],
  [
    "pg",
    // Papua New Guinea
    "675"
  ],
  [
    "py",
    // Paraguay
    "595",
    0,
    null,
    "0"
  ],
  [
    "pe",
    // Peru
    "51",
    0,
    null,
    "0"
  ],
  [
    "ph",
    // Philippines
    "63",
    0,
    null,
    "0"
  ],
  [
    "pl",
    // Poland
    "48"
  ],
  [
    "pt",
    // Portugal
    "351"
  ],
  [
    "pr",
    // Puerto Rico
    "1",
    3,
    ["787", "939"],
    "1"
  ],
  [
    "qa",
    // Qatar
    "974"
  ],
  [
    "re",
    // Réunion
    "262",
    0,
    null,
    "0"
  ],
  [
    "ro",
    // Romania
    "40",
    0,
    null,
    "0"
  ],
  [
    "ru",
    // Russia
    "7",
    0,
    ["33"],
    // (shared with KZ)
    "8"
  ],
  [
    "rw",
    // Rwanda
    "250",
    0,
    null,
    "0"
  ],
  [
    "ws",
    // Samoa
    "685"
  ],
  [
    "sm",
    // San Marino
    "378"
  ],
  [
    "st",
    // São Tomé & Príncipe
    "239"
  ],
  [
    "sa",
    // Saudi Arabia
    "966",
    0,
    null,
    "0"
  ],
  [
    "sn",
    // Senegal
    "221"
  ],
  [
    "rs",
    // Serbia
    "381",
    0,
    null,
    "0"
  ],
  [
    "sc",
    // Seychelles
    "248"
  ],
  [
    "sl",
    // Sierra Leone
    "232",
    0,
    null,
    "0"
  ],
  [
    "sg",
    // Singapore
    "65"
  ],
  [
    "sx",
    // Sint Maarten
    "1",
    21,
    ["721"],
    "1"
  ],
  [
    "sk",
    // Slovakia
    "421",
    0,
    null,
    "0"
  ],
  [
    "si",
    // Slovenia
    "386",
    0,
    null,
    "0"
  ],
  [
    "sb",
    // Solomon Islands
    "677"
  ],
  [
    "so",
    // Somalia
    "252",
    0,
    null,
    "0"
  ],
  [
    "za",
    // South Africa
    "27",
    0,
    null,
    "0"
  ],
  [
    "kr",
    // South Korea
    "82",
    0,
    null,
    "0"
  ],
  [
    "ss",
    // South Sudan
    "211",
    0,
    null,
    "0"
  ],
  [
    "es",
    // Spain
    "34"
  ],
  [
    "lk",
    // Sri Lanka
    "94",
    0,
    null,
    "0"
  ],
  [
    "bl",
    // St. Barthélemy
    "590",
    1,
    null,
    "0"
  ],
  [
    "sh",
    // St. Helena
    "290"
  ],
  [
    "kn",
    // St. Kitts & Nevis
    "1",
    18,
    ["869"],
    "1"
  ],
  [
    "lc",
    // St. Lucia
    "1",
    19,
    ["758"],
    "1"
  ],
  [
    "mf",
    // St. Martin
    "590",
    2,
    null,
    "0"
  ],
  [
    "pm",
    // St. Pierre & Miquelon
    "508",
    0,
    null,
    "0"
  ],
  [
    "vc",
    // St. Vincent & Grenadines
    "1",
    20,
    ["784"],
    "1"
  ],
  [
    "sd",
    // Sudan
    "249",
    0,
    null,
    "0"
  ],
  [
    "sr",
    // Suriname
    "597"
  ],
  [
    "sj",
    // Svalbard & Jan Mayen
    "47",
    1,
    ["4", "79", "9"]
    // (4 and 9 are mobile ranges shared with NO)
  ],
  [
    "se",
    // Sweden
    "46",
    0,
    null,
    "0"
  ],
  [
    "ch",
    // Switzerland
    "41",
    0,
    null,
    "0"
  ],
  [
    "sy",
    // Syria
    "963",
    0,
    null,
    "0"
  ],
  [
    "tw",
    // Taiwan
    "886",
    0,
    null,
    "0"
  ],
  [
    "tj",
    // Tajikistan
    "992"
  ],
  [
    "tz",
    // Tanzania
    "255",
    0,
    null,
    "0"
  ],
  [
    "th",
    // Thailand
    "66",
    0,
    null,
    "0"
  ],
  [
    "tl",
    // Timor-Leste
    "670"
  ],
  [
    "tg",
    // Togo
    "228"
  ],
  [
    "tk",
    // Tokelau
    "690"
  ],
  [
    "to",
    // Tonga
    "676"
  ],
  [
    "tt",
    // Trinidad & Tobago
    "1",
    22,
    ["868"],
    "1"
  ],
  [
    "tn",
    // Tunisia
    "216"
  ],
  [
    "tr",
    // Turkey
    "90",
    0,
    null,
    "0"
  ],
  [
    "tm",
    // Turkmenistan
    "993",
    0,
    null,
    "8"
  ],
  [
    "tc",
    // Turks & Caicos Islands
    "1",
    23,
    ["649"],
    "1"
  ],
  [
    "tv",
    // Tuvalu
    "688"
  ],
  [
    "vi",
    // U.S. Virgin Islands
    "1",
    24,
    ["340"],
    "1"
  ],
  [
    "ug",
    // Uganda
    "256",
    0,
    null,
    "0"
  ],
  [
    "ua",
    // Ukraine
    "380",
    0,
    null,
    "0"
  ],
  [
    "ae",
    // United Arab Emirates
    "971",
    0,
    null,
    "0"
  ],
  [
    "gb",
    // United Kingdom
    "44",
    0,
    null,
    "0"
  ],
  [
    "us",
    // United States
    "1",
    0,
    null,
    "1"
  ],
  [
    "uy",
    // Uruguay
    "598",
    0,
    null,
    "0"
  ],
  [
    "uz",
    // Uzbekistan
    "998"
  ],
  [
    "vu",
    // Vanuatu
    "678"
  ],
  [
    "va",
    // Vatican City
    "39",
    1,
    ["06698", "3"]
    // (3 is a mobile range shared with IT)
  ],
  [
    "ve",
    // Venezuela
    "58",
    0,
    null,
    "0"
  ],
  [
    "vn",
    // Vietnam
    "84",
    0,
    null,
    "0"
  ],
  [
    "wf",
    // Wallis & Futuna
    "681"
  ],
  [
    "eh",
    // Western Sahara
    "212",
    1,
    ["5288", "5289", "6", "7"],
    // (6 and 7 are mobile ranges shared with MA)
    "0"
  ],
  [
    "ye",
    // Yemen
    "967",
    0,
    null,
    "0"
  ],
  [
    "zm",
    // Zambia
    "260",
    0,
    null,
    "0"
  ],
  [
    "zw",
    // Zimbabwe
    "263",
    0,
    null,
    "0"
  ]
];
var allCountries = [];
for (const c of rawCountryData) {
  allCountries.push({
    name: "",
    // populated in the core library
    iso2: c[0],
    dialCode: c[1],
    priority: c[2] || 0,
    areaCodes: c[3] || null,
    nationalPrefix: c[4] || null
  });
}
var iso2Set = new Set(allCountries.map((c) => c.iso2));
var isIso2 = (val) => iso2Set.has(val);
var data_default = allCountries;

// packages/core/src/js/constants.ts
var EVENTS = {
  OPEN_COUNTRY_DROPDOWN: "open:countrydropdown",
  CLOSE_COUNTRY_DROPDOWN: "close:countrydropdown",
  COUNTRY_CHANGE: "countrychange",
  INPUT: "input",
  // used for synthetic input trigger
  STRICT_REJECT: "strict:reject"
};
var CLASSES = {
  HIDE: "iti__hide",
  V_HIDE: "iti__v-hide",
  ARROW_UP: "iti__arrow--up",
  GLOBE: "iti__globe",
  FLAG: "iti__flag",
  LOADING: "iti__loading",
  COUNTRY_ITEM: "iti__country",
  HIGHLIGHT: "iti__highlight",
  STRICT_REJECT_ANIMATION: "iti__strict-reject-animation"
};
var KEYS = {
  ARROW_UP: "ArrowUp",
  ARROW_DOWN: "ArrowDown",
  SPACE: " ",
  ENTER: "Enter",
  ESC: "Escape",
  TAB: "Tab"
};
var INPUT_TYPES = {
  PASTE: "insertFromPaste",
  DELETE_FORWARD: "deleteContentForward"
};
var REGEX = {
  ALPHA_UNICODE: /\p{L}/u,
  // any kind of letter from any language
  NON_PLUS_NUMERIC: /[^+0-9]/,
  // chars that are NOT + or digit
  NON_PLUS_NUMERIC_GLOBAL: /[^+0-9]/g,
  // chars that are NOT + or digit (global)
  HIDDEN_SEARCH_CHAR: /^[a-zA-ZÀ-ÿа-яА-Я ]$/
  // single acceptable hidden-search char
};
var TIMINGS = {
  SEARCH_DEBOUNCE_MS: 100,
  HIDDEN_SEARCH_RESET_MS: 1e3,
  NEXT_TICK: 0
};
var LAYOUT = {
  NARROW_VIEWPORT_WIDTH: 500,
  // keep in sync with .iti__country-list CSS media query
  FALLBACK_SELECTED_WITH_DIAL_WIDTH: 78,
  // px width fallback when separateDialCode enabled
  FALLBACK_SELECTED_NO_DIAL_WIDTH: 42,
  // px width fallback when no separate dial code
  INPUT_PADDING_EXTRA_LEFT: 6,
  // px gap between selected country container and input text
  DROPDOWN_MARGIN: 3,
  // px margin between dropdown and tel input
  FALLBACK_DROPDOWN_HEIGHT: 200
  // px height fallback for dropdown
};
var DIAL_CODE = {
  PLUS: "+",
  NANP: "1"
  // North American Numbering Plan
};
var UK = {
  ISO2: "gb",
  DIAL_CODE: "44",
  // +44 United Kingdom
  MOBILE_PREFIX: "7",
  // UK mobile numbers start with 7 after national trunk (0) or core section
  MOBILE_CORE_LENGTH: 10
  // core number length (excluding dial code / national prefix) for mobiles
};
var US = {
  ISO2: "us",
  DIAL_CODE: "1"
  // +1 United States
};
var PLACEHOLDER_MODES = {
  AGGRESSIVE: "aggressive",
  POLITE: "polite",
  OFF: "off"
};
var INITIAL_COUNTRY = {
  AUTO: "auto"
};
var NUMBER_FORMATS = [
  "E164",
  "INTERNATIONAL",
  "NATIONAL",
  "RFC3966"
];
var NUMBER_TYPES = [
  "FIXED_LINE",
  "MOBILE",
  "FIXED_LINE_OR_MOBILE",
  "TOLL_FREE",
  "PREMIUM_RATE",
  "SHARED_COST",
  "VOIP",
  "PERSONAL_NUMBER",
  "PAGER",
  "UAN",
  "VOICEMAIL",
  "UNKNOWN"
];
var VALIDATION_ERRORS = [
  "IS_POSSIBLE",
  "INVALID_COUNTRY_CODE",
  "TOO_SHORT",
  "TOO_LONG",
  "IS_POSSIBLE_LOCAL_ONLY",
  "INVALID_LENGTH"
];
var toEnumObject = (arr) => Object.fromEntries(arr.map((v) => [v, v]));
var NUMBER_FORMAT = toEnumObject(NUMBER_FORMATS);
var NUMBER_TYPE = toEnumObject(NUMBER_TYPES);
var VALIDATION_ERROR = toEnumObject(VALIDATION_ERRORS);
var DATA_KEYS = {
  // e.g. <li data-iso2="us"> for country items in dropdown
  ISO2: "iso2",
  DIAL_CODE: "dialCode",
  // e.g. <input data-intl-tel-input-id="0"> on the input element
  INSTANCE_ID: "intlTelInputId"
};
var ARIA = {
  EXPANDED: "aria-expanded",
  LABEL: "aria-label",
  SELECTED: "aria-selected",
  ACTIVE_DESCENDANT: "aria-activedescendant",
  HASPOPUP: "aria-haspopup",
  CONTROLS: "aria-controls",
  HIDDEN: "aria-hidden",
  AUTOCOMPLETE: "aria-autocomplete",
  MODAL: "aria-modal"
};

// packages/core/src/js/i18n/en.ts
var interfaceTranslations = {
  selectedCountryAriaLabel: "Change country for phone number, currently selected ${countryName} (${dialCode})",
  noCountrySelected: "Select country for phone number",
  countryListAriaLabel: "List of countries",
  searchPlaceholder: "Search",
  clearSearchAriaLabel: "Clear search",
  searchEmptyState: "No results found",
  searchSummaryAria(count) {
    if (count === 0) {
      return "No results found";
    }
    if (count === 1) {
      return "1 result found";
    }
    return `${count} results found`;
  }
};
var en_default = interfaceTranslations;

// packages/core/src/js/core/options.ts
var mediaQuery = (q) => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches;
var isNarrowViewport = () => mediaQuery(`(max-width: ${LAYOUT.NARROW_VIEWPORT_WIDTH}px)`);
var computeDefaultUseFullscreenPopup = () => {
  if (typeof navigator !== "undefined" && typeof window !== "undefined") {
    const isShortViewport = mediaQuery("(max-height: 600px)");
    const isCoarsePointer = mediaQuery("(pointer: coarse)");
    return isNarrowViewport() || isCoarsePointer && isShortViewport;
  }
  return false;
};
var defaults = {
  //* Whether or not to allow the dropdown.
  allowDropdown: true,
  //* The number type to enforce during validation.
  allowedNumberTypes: [NUMBER_TYPE.MOBILE, NUMBER_TYPE.FIXED_LINE],
  //* Whether or not to allow extensions after the main number.
  allowNumberExtensions: false,
  // Allow alphanumeric "phonewords" (e.g. +1 800 FLOWERS) as valid numbers
  allowPhonewords: false,
  //* Add a placeholder in the input with an example number for the selected country.
  autoPlaceholder: PLACEHOLDER_MODES.POLITE,
  //* Add a custom class to the (injected) container element.
  containerClass: "",
  //* Locale for localising country names via Intl.DisplayNames.
  countryNameLocale: "en",
  //* Override individual country names by iso2 code.
  countryNameOverrides: {},
  //* The order of the countries in the dropdown. Defaults to alphabetical.
  countryOrder: null,
  //* Add a country search input at the top of the dropdown.
  countrySearch: true,
  //* Modify the auto placeholder.
  customPlaceholder: null,
  //* Always show the dropdown
  dropdownAlwaysOpen: false,
  //* Append menu to specified element.
  dropdownContainer: null,
  //* Don't display these countries.
  excludeCountries: null,
  //* Fix the dropdown width to the input width (rather than being as wide as the longest country name).
  fixDropdownWidth: true,
  //* Format the number as the user types
  formatAsYouType: true,
  //* Format the input value during initialisation and on setNumber.
  formatOnDisplay: true,
  //* geoIp lookup function.
  geoIpLookup: null,
  //* Inject a hidden input with the name returned from this function, and on submit, populate it with the result of getNumber.
  hiddenInput: null,
  //* Internationalise the core library text e.g. search input placeholder, country names.
  i18n: {},
  //* Initial country.
  initialCountry: "",
  //* A function to load the utils script.
  loadUtils: null,
  //* National vs international formatting for numbers e.g. placeholders and displaying existing numbers.
  nationalMode: false,
  //* Display only these countries.
  onlyCountries: null,
  //* Number type to use for placeholders.
  placeholderNumberType: NUMBER_TYPE.MOBILE,
  //* Add custom classes to the search input element.
  searchInputClass: "",
  //* Display the international dial code next to the selected flag.
  separateDialCode: true,
  //* When strictMode rejects a key (etc), play a short feedback animation
  strictRejectAnimation: true,
  //* Show flags - for both the selected country, and in the country dropdown
  showFlags: true,
  //* Only allow certain chars e.g. a plus followed by numeric digits, and cap at max valid length.
  strictMode: true,
  //* Use full screen popup instead of dropdown for country list.
  useFullscreenPopup: computeDefaultUseFullscreenPopup()
};
var toString = (val) => JSON.stringify(val);
var isPlainObject = (val) => Boolean(val) && typeof val === "object" && !Array.isArray(val);
var isFunction = (val) => typeof val === "function";
var isElLike = (val) => {
  if (!val || typeof val !== "object") {
    return false;
  }
  const v = val;
  return v.nodeType === 1 && typeof v.tagName === "string" && typeof v.appendChild === "function";
};
var placeholderModeSet = new Set(Object.values(PLACEHOLDER_MODES));
var warn = (message) => {
  console.warn(`[intl-tel-input] ${message}`);
};
var warnOption = (optionName, expectedType, actualValue) => {
  warn(
    `Option '${optionName}' must be ${expectedType}; got ${toString(actualValue)}. Ignoring.`
  );
};
var validateIso2Array = (key, value) => {
  const expectedType = "an array of iso2 country code strings";
  if (!Array.isArray(value)) {
    warnOption(key, expectedType, value);
    return false;
  }
  const valid = [];
  for (const v of value) {
    if (typeof v !== "string") {
      warnOption(key, expectedType, value);
      return false;
    }
    const lower = v.toLowerCase();
    if (!isIso2(lower)) {
      warn(`Invalid iso2 code in '${key}': '${v}'. Skipping.`);
    } else {
      valid.push(v);
    }
  }
  return valid;
};
var validateOptions = (customOptions) => {
  if (customOptions === void 0) {
    return {};
  }
  if (!isPlainObject(customOptions)) {
    const error = `The second argument must be an options object; got ${toString(customOptions)}. Using defaults.`;
    warn(error);
    return {};
  }
  const validatedOptions = {};
  for (const [key, value] of Object.entries(customOptions)) {
    if (!Object.hasOwn(defaults, key)) {
      warn(`Unknown option '${key}'. Ignoring.`);
      continue;
    }
    switch (key) {
      case "allowDropdown":
      case "allowNumberExtensions":
      case "allowPhonewords":
      case "countrySearch":
      case "dropdownAlwaysOpen":
      case "fixDropdownWidth":
      case "formatAsYouType":
      case "formatOnDisplay":
      case "nationalMode":
      case "showFlags":
      case "separateDialCode":
      case "strictMode":
      case "strictRejectAnimation":
      case "useFullscreenPopup":
        if (typeof value !== "boolean") {
          warnOption(key, "a boolean", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "autoPlaceholder":
        if (typeof value !== "string" || !placeholderModeSet.has(value)) {
          const validModes = Array.from(placeholderModeSet).join(", ");
          warnOption("autoPlaceholder", `one of ${validModes}`, value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "containerClass":
      case "searchInputClass":
      case "countryNameLocale":
        if (typeof value !== "string") {
          warnOption(key, "a string", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "countryOrder": {
        if (value === null) {
          validatedOptions[key] = value;
        } else {
          const filtered = validateIso2Array(key, value);
          if (filtered !== false) {
            validatedOptions[key] = filtered;
          }
        }
        break;
      }
      case "customPlaceholder":
      case "geoIpLookup":
      case "hiddenInput":
      case "loadUtils":
        if (value !== null && !isFunction(value)) {
          warnOption(key, "a function or null", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "dropdownContainer":
        if (value !== null && !isElLike(value)) {
          warnOption("dropdownContainer", "an HTMLElement or null", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "excludeCountries":
      case "onlyCountries": {
        if (value === null) {
          validatedOptions[key] = value;
        } else {
          const filtered = validateIso2Array(key, value);
          if (filtered !== false) {
            validatedOptions[key] = filtered;
          }
        }
        break;
      }
      case "i18n":
        if (value && !isPlainObject(value)) {
          warnOption("i18n", "an object", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "countryNameOverrides":
        if (value && !isPlainObject(value)) {
          warnOption("countryNameOverrides", "an object", value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "initialCountry": {
        if (typeof value !== "string") {
          warnOption("initialCountry", "a string", value);
          break;
        }
        const lower = value.toLowerCase();
        if (lower && lower !== INITIAL_COUNTRY.AUTO && !isIso2(lower)) {
          warnOption(
            "initialCountry",
            "a valid iso2 country code or 'auto'",
            value
          );
          break;
        }
        validatedOptions[key] = value;
        break;
      }
      case "placeholderNumberType":
        if (typeof value !== "string" || !NUMBER_TYPES.includes(value)) {
          const validTypes = NUMBER_TYPES.join(", ");
          warnOption("placeholderNumberType", `one of ${validTypes}`, value);
          break;
        }
        validatedOptions[key] = value;
        break;
      case "allowedNumberTypes":
        if (value !== null) {
          if (!Array.isArray(value)) {
            warnOption(
              "allowedNumberTypes",
              "an array of number types or null",
              value
            );
            break;
          }
          let allValid = true;
          for (const v of value) {
            if (typeof v !== "string" || !NUMBER_TYPES.includes(v)) {
              const validTypes = NUMBER_TYPES.join(", ");
              warnOption(
                "allowedNumberTypes",
                `an array of valid number types (${validTypes})`,
                v
              );
              allValid = false;
              break;
            }
          }
          if (allValid) {
            validatedOptions[key] = value;
          }
        } else {
          validatedOptions[key] = null;
        }
        break;
    }
  }
  return validatedOptions;
};
var normaliseOptions = (o) => {
  if (o.initialCountry) {
    o.initialCountry = o.initialCountry.toLowerCase();
  }
  if (o.onlyCountries?.length) {
    o.onlyCountries = o.onlyCountries.map((c) => c.toLowerCase());
  }
  if (o.excludeCountries?.length) {
    o.excludeCountries = o.excludeCountries.map((c) => c.toLowerCase());
  }
  if (o.countryOrder) {
    o.countryOrder = o.countryOrder.map((c) => c.toLowerCase());
  }
};
var applyOptionSideEffects = (o) => {
  if (o.dropdownAlwaysOpen) {
    o.useFullscreenPopup = false;
    o.allowDropdown = true;
  }
  if (o.useFullscreenPopup) {
    o.fixDropdownWidth = false;
  } else {
    if (isNarrowViewport()) {
      o.fixDropdownWidth = true;
    }
  }
  if (o.onlyCountries?.length === 1) {
    o.initialCountry = o.onlyCountries[0];
  }
  if (o.separateDialCode) {
    o.nationalMode = false;
  }
  if (o.allowDropdown && !o.showFlags && !o.separateDialCode) {
    o.nationalMode = false;
  }
  if (o.useFullscreenPopup && !o.dropdownContainer) {
    o.dropdownContainer = document.body;
  }
  o.i18n = { ...en_default, ...o.i18n };
};

// packages/core/src/js/helpers/string.ts
var getNumeric = (s) => s.replace(/\D/g, "");
var normaliseString = (s = "") => s.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();

// packages/core/src/js/helpers/dom.ts
var buildClassNames = (flags) => Object.keys(flags).filter((k) => Boolean(flags[k])).join(" ");
var createEl = (tagName, attrs, container) => {
  const el = document.createElement(tagName);
  if (attrs) {
    Object.entries(attrs).forEach(
      ([key, value]) => el.setAttribute(key, value)
    );
  }
  if (container) {
    container.appendChild(el);
  }
  return el;
};

// packages/core/src/js/core/icons.ts
var SVG_NS = "http://www.w3.org/2000/svg";
var buildSvg = ([tag, attrs, children]) => {
  const el = document.createElementNS(SVG_NS, tag);
  if (attrs) {
    for (const k in attrs) {
      el.setAttribute(k, String(attrs[k]));
    }
  }
  if (children) {
    for (const c of children) {
      el.appendChild(buildSvg(c));
    }
  }
  return el;
};
var buildSearchIcon = () => buildSvg(
  ["svg", { class: "iti__search-icon-svg", width: 14, height: 14, viewBox: "0 0 24 24", focusable: "false", [ARIA.HIDDEN]: "true" }, [
    ["circle", { cx: 11, cy: 11, r: 7 }],
    ["line", { x1: 21, y1: 21, x2: 16.65, y2: 16.65 }]
  ]]
);
var buildClearIcon = (id) => {
  const maskId = `iti-${id}-clear-mask`;
  return buildSvg(
    ["svg", { class: "iti__search-clear-svg", width: 12, height: 12, viewBox: "0 0 16 16", [ARIA.HIDDEN]: "true", focusable: "false" }, [
      ["mask", { id: maskId, maskUnits: "userSpaceOnUse" }, [
        ["rect", { width: 16, height: 16, fill: "white" }],
        ["path", { d: "M5.2 5.2 L10.8 10.8 M10.8 5.2 L5.2 10.8", stroke: "black", "stroke-linecap": "round", class: "iti__search-clear-x" }]
      ]],
      ["circle", { cx: 8, cy: 8, r: 8, class: "iti__search-clear-bg", mask: `url(#${maskId})` }]
    ]]
  );
};
var buildCheckIcon = () => buildSvg(
  ["svg", { class: "iti__country-check-svg", width: 14, height: 14, viewBox: "0 0 16 16", fill: "currentColor", focusable: "false", [ARIA.HIDDEN]: "true" }, [
    ["path", { d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" }]
  ]]
);
var buildGlobeIcon = () => buildSvg(
  ["svg", { width: 256, height: 256, viewBox: "0 0 512 512", class: "iti__globe-svg" }, [
    ["path", { d: "M508 213a240 240 0 0 0-449-87l-2 5-2 5c-8 14-13 30-17 46a65 65 0 0 1 56 4c16-10 35-19 56-27l9-3c-6 23-10 48-10 74h-16l4 6c3 4 5 8 6 13h6c0 22 3 44 8 65l2 10-25-10-4 5 12 18 9 3 6 2 8 3 9 26 1 2 16-7h1l-5-13-1-2c24 6 49 9 75 10v26l11 10 7 7v-30l1-13c22 0 44-3 65-8l10-2-21 48-1 1a317 317 0 0 1-14 23l-21 5h-2c6 16 7 33 1 50a240 240 0 0 0 211-265m-401-56-11 6c19-44 54-79 98-98-11 20-21 44-29 69-21 6-40 15-58 23m154 182v4c-29-1-57-6-81-13-7-25-12-52-13-81h94zm0-109h-94c1-29 6-56 13-81 24-7 52-12 81-13zm0-112c-22 1-44 4-65 8l-10 2 12-30 9-17 1-2a332 332 0 0 1 13-23c13-4 26-6 40-7zm187 69 6 4c4 12 6 25 6 38v1h-68c-1-26-4-51-10-74l48 20 1 1 14 8zm-14-44 10 20c-20-11-43-21-68-29-8-25-18-49-29-69 37 16 67 44 87 78M279 49h1c13 1 27 3 39 7l14 23 1 2a343 343 0 0 1 12 26l2 5 6 16c-23-6-48-9-74-10h-1zm0 87h1c29 1 56 6 81 13 7 24 12 51 12 80v1h-94zm2 207h-2v-94h95c-1 29-6 56-13 81-24 7-51 12-80 13m86 60-20 10c11-20 21-43 29-68 25-8 48-18 68-29-16 37-43 67-77 87m87-115-7 5-16 9-2 1a337 337 0 0 1-47 21c6-24 9-49 10-75h68c0 13-2 27-6 39" }],
    ["path", { d: "m261 428-2-2-22-21a40 40 0 0 0-32-11h-1a37 37 0 0 0-18 8l-1 1-4 2-2 2-5 4c-9-3-36-31-47-44s-32-45-34-55l3-2a151 151 0 0 0 11-9v-1a39 39 0 0 0 5-48l-3-3-11-19-3-4-5-7h-1l-3-3-4-3-5-2a35 35 0 0 0-16-3h-5c-4 1-14 5-24 11l-4 2-4 3-4 2c-9 8-17 17-18 27a380 380 0 0 0 212 259h3c12 0 25-10 36-21l10-12 6-11a39 39 0 0 0-8-40" }]
  ]]
);

// packages/core/src/js/core/countrySearch.ts
var normaliseName = (s) => normaliseString(s).replace(/[^\p{L}]+/gu, " ").trim();
var buildSearchTokens = (countries) => {
  const tokens = /* @__PURE__ */ new Map();
  for (const c of countries) {
    const normalisedName = normaliseName(c.name);
    const words = normalisedName.split(" ").filter(Boolean);
    const initials = words.map((w) => w[0] || "").join("");
    tokens.set(c.iso2, {
      normalisedName,
      words,
      initials,
      dialCodePlus: `+${c.dialCode}`
    });
  }
  return tokens;
};
var getMatchedCountries = (countries, searchTokens, query) => {
  const lowerQuery = normaliseString(query);
  const nameQuery = normaliseName(query);
  const skipNameBuckets = lowerQuery !== "" && nameQuery === "";
  const iso2Matches = [];
  const nameStartsWith = [];
  const nameContains = [];
  const dialCodeMatches = [];
  const dialCodeContains = [];
  const initialsMatches = [];
  const wordMatches = [];
  for (const c of countries) {
    const t = searchTokens.get(c.iso2);
    if (c.iso2 === lowerQuery) {
      iso2Matches.push(c);
    } else if (!skipNameBuckets && t.normalisedName.startsWith(nameQuery)) {
      nameStartsWith.push(c);
    } else if (!skipNameBuckets && t.normalisedName.includes(nameQuery)) {
      nameContains.push(c);
    } else if (lowerQuery === c.dialCode || lowerQuery === t.dialCodePlus) {
      dialCodeMatches.push(c);
    } else if (t.dialCodePlus.includes(lowerQuery)) {
      dialCodeContains.push(c);
    } else if (t.initials.includes(lowerQuery)) {
      initialsMatches.push(c);
    }
  }
  const queryWords = nameQuery.split(" ").filter(Boolean);
  if (queryWords.length > 1 && iso2Matches.length === 0 && nameStartsWith.length === 0 && nameContains.length === 0) {
    const claimed = /* @__PURE__ */ new Set([
      ...dialCodeMatches.map((c) => c.iso2),
      ...dialCodeContains.map((c) => c.iso2),
      ...initialsMatches.map((c) => c.iso2)
    ]);
    for (const c of countries) {
      if (claimed.has(c.iso2)) {
        continue;
      }
      const t = searchTokens.get(c.iso2);
      if (queryWords.some((qw) => t.words.some((sw) => sw.startsWith(qw)))) {
        wordMatches.push(c);
      }
    }
  }
  const sortByPriority = (a, b) => a.priority - b.priority;
  return [
    ...iso2Matches,
    ...nameStartsWith,
    ...nameContains,
    // priority sort is only relevant when showing multiple countries with the same dial code (that's what the priority field is used to distinguish between)
    ...dialCodeMatches.sort(sortByPriority),
    ...dialCodeContains.sort(sortByPriority),
    ...initialsMatches,
    ...wordMatches
  ];
};
var findFirstCountryStartingWith = (countries, searchTokens, query) => {
  const nameQuery = normaliseName(query);
  for (const c of countries) {
    const { normalisedName } = searchTokens.get(c.iso2);
    if (normalisedName.startsWith(nameQuery)) {
      return c;
    }
  }
  return null;
};

// packages/core/src/js/core/numerals.ts
var Numerals = class _Numerals {
  #userNumeralSet;
  //* Stateless conversion of any Arabic-Indic / Persian digits to ASCII 0-9.
  //* Use this when you need to normalise digits without affecting any instance's tracked numeral set (e.g. for the country-search query).
  static toAscii(str) {
    if (!str) {
      return "";
    }
    return str.replace(
      /[٠-٩]/g,
      (ch) => String.fromCharCode(48 + (ch.charCodeAt(0) - 1632))
    ).replace(
      /[۰-۹]/g,
      (ch) => String.fromCharCode(48 + (ch.charCodeAt(0) - 1776))
    );
  }
  constructor(initialValue) {
    if (initialValue) {
      this.#updateNumeralSet(initialValue);
    }
  }
  // If any Arabic-Indic digits, then label it as that set. Same for Persian. Otherwise assume ASCII.
  #updateNumeralSet(str) {
    if (/[٠-٩]/.test(str)) {
      this.#userNumeralSet = "arabic-indic";
    } else if (/[۰-۹]/.test(str)) {
      this.#userNumeralSet = "persian";
    } else {
      this.#userNumeralSet = "ascii";
    }
  }
  // Denormalise ASCII 0-9 to the user's numeral set. If not yet known, return as-is.
  // NOTE: normalise is always called before this, so it should be impossible for the numeral set to be unknown at this point.
  denormalise(str) {
    if (!this.#userNumeralSet || this.#userNumeralSet === "ascii") {
      return str;
    }
    const base = this.#userNumeralSet === "arabic-indic" ? 1632 : 1776;
    return str.replace(/[0-9]/g, (d) => String.fromCharCode(base + Number(d)));
  }
  // Normalize Eastern Arabic (U+0660-0669) and Persian/Extended Arabic-Indic (U+06F0-06F9) numerals to ASCII 0-9.
  // Tracks the user's numeral set as a side effect so denormalise can mirror it back.
  normalise(str) {
    if (!str) {
      return "";
    }
    this.#updateNumeralSet(str);
    if (this.#userNumeralSet === "ascii") {
      return str;
    }
    return _Numerals.toAscii(str);
  }
  isAscii() {
    return !this.#userNumeralSet || this.#userNumeralSet === "ascii";
  }
};

// packages/core/src/js/core/ui.ts
var UI = class _UI {
  // private
  #options;
  #id;
  #isRTL;
  #originalPaddingLeft = "";
  #countries;
  #searchTokens;
  #searchDebounceTimer = null;
  #inlineDropdownHeight;
  #countryContainerEl;
  #selectedCountryEl;
  #selectedFlagEl;
  #selectedDialCodeEl;
  #dropdownArrowEl;
  #dropdownContentEl;
  #searchIconEl;
  #searchInputEl;
  #searchClearButtonEl;
  #countryListEl;
  #hiddenInputPhoneEl;
  #hiddenInputCountryEl;
  #noResultsMessageEl;
  #searchResultsLiveRegionEl;
  #detachedDropdownEl;
  #selectedListItemEl = null;
  #highlightedListItemEl = null;
  #listItemByIso2 = /* @__PURE__ */ new Map();
  #dropdownAbortController = null;
  #resizeObserver;
  // public
  telInputEl;
  hadInitialPlaceholder;
  constructor(input, options, id) {
    input.dataset[DATA_KEYS.INSTANCE_ID] = id.toString();
    this.telInputEl = input;
    this.#options = options;
    this.#id = id;
    this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder"));
    this.#isRTL = !!this.telInputEl.closest("[dir=rtl]");
    this.#originalPaddingLeft = this.telInputEl.style.paddingLeft;
  }
  // Validate that the provided element is an HTMLInputElement.
  static validateInput(input) {
    const tagName = input?.tagName;
    const isInputEl = Boolean(input) && typeof input === "object" && tagName === "INPUT" && typeof input.setAttribute === "function";
    if (!isInputEl) {
      const type = Object.prototype.toString.call(input);
      throw new TypeError(
        `The first argument must be an HTMLInputElement, not ${type}`
      );
    }
  }
  //* Generate all of the markup for the core library: the selected country overlay, and the dropdown.
  buildMarkup(countries, searchTokens) {
    this.#countries = countries;
    this.#searchTokens = searchTokens;
    this.telInputEl.classList.add("iti__tel-input");
    if (!this.telInputEl.hasAttribute("type")) {
      this.telInputEl.setAttribute("type", "tel");
    }
    if (!this.telInputEl.hasAttribute("autocomplete")) {
      this.telInputEl.setAttribute("autocomplete", "tel");
    }
    if (!this.telInputEl.hasAttribute("inputmode")) {
      this.telInputEl.setAttribute("inputmode", "tel");
    }
    const wrapper = this.#createWrapperAndInsert();
    this.#buildCountryContainer(wrapper);
    wrapper.appendChild(this.telInputEl);
    this.#updateInputPaddingAndReveal();
    this.#observeSelectedCountryResize();
    this.#buildHiddenInputs(wrapper);
    this.ensureDropdownWidthSet();
  }
  #createWrapperAndInsert() {
    const { allowDropdown, showFlags, containerClass, useFullscreenPopup } = this.#options;
    const parentClasses = buildClassNames({
      iti: true,
      "iti--input-container": true,
      "iti--allow-dropdown": allowDropdown,
      "iti--show-flags": showFlags,
      "iti--inline-dropdown": !useFullscreenPopup,
      [containerClass]: Boolean(containerClass)
    });
    const wrapper = createEl("div", { class: parentClasses });
    if (this.#isRTL) {
      wrapper.setAttribute("dir", "ltr");
    }
    this.telInputEl.before(wrapper);
    return wrapper;
  }
  #buildCountryContainer(wrapper) {
    const { allowDropdown, separateDialCode, showFlags } = this.#options;
    if (!allowDropdown && !showFlags && !separateDialCode) {
      return;
    }
    this.#countryContainerEl = createEl(
      "div",
      // visibly hidden until we measure its width to set the input padding correctly
      { class: `iti__country-container ${CLASSES.V_HIDE}` },
      wrapper
    );
    if (allowDropdown) {
      this.#selectedCountryEl = createEl(
        "button",
        {
          type: "button",
          class: "iti__selected-country",
          [ARIA.EXPANDED]: "false",
          [ARIA.LABEL]: this.#options.i18n.noCountrySelected,
          [ARIA.HASPOPUP]: "dialog",
          [ARIA.CONTROLS]: `iti-${this.#id}__dropdown-content`
        },
        this.#countryContainerEl
      );
      if (this.telInputEl.disabled) {
        this.#selectedCountryEl.setAttribute("disabled", "true");
      }
    } else {
      this.#selectedCountryEl = createEl(
        "div",
        { class: "iti__selected-country" },
        this.#countryContainerEl
      );
    }
    const selectedCountryPrimary = createEl(
      "div",
      { class: "iti__selected-country-primary" },
      this.#selectedCountryEl
    );
    this.#selectedFlagEl = createEl(
      "div",
      { class: CLASSES.FLAG },
      selectedCountryPrimary
    );
    if (allowDropdown) {
      this.#dropdownArrowEl = createEl(
        "div",
        { class: "iti__arrow", [ARIA.HIDDEN]: "true" },
        selectedCountryPrimary
      );
    }
    if (separateDialCode) {
      this.#selectedDialCodeEl = createEl(
        "div",
        { class: "iti__selected-dial-code" },
        this.#selectedCountryEl
      );
    }
    if (allowDropdown) {
      this.#buildDropdownContent();
    }
  }
  ensureDropdownWidthSet() {
    const { fixDropdownWidth, allowDropdown } = this.#options;
    if (!allowDropdown || !fixDropdownWidth || this.#dropdownContentEl.style.width) {
      return;
    }
    const inputWidth = this.telInputEl.offsetWidth;
    if (inputWidth > 0) {
      this.#dropdownContentEl.style.width = `${inputWidth}px`;
    }
  }
  #buildDropdownContent() {
    const {
      fixDropdownWidth,
      useFullscreenPopup,
      countrySearch,
      i18n,
      dropdownContainer,
      containerClass
    } = this.#options;
    const extraClasses = fixDropdownWidth ? "" : "iti--flexible-dropdown-width";
    this.#dropdownContentEl = createEl("div", {
      id: `iti-${this.#id}__dropdown-content`,
      class: `iti__dropdown-content ${CLASSES.HIDE} ${extraClasses}`,
      role: "dialog",
      [ARIA.MODAL]: "true"
    });
    if (this.#isRTL) {
      this.#dropdownContentEl.setAttribute("dir", "rtl");
    }
    if (countrySearch) {
      this.#buildSearchUI();
    }
    this.#countryListEl = createEl(
      "ul",
      {
        class: "iti__country-list",
        id: `iti-${this.#id}__country-listbox`,
        role: "listbox",
        [ARIA.LABEL]: i18n.countryListAriaLabel
      },
      this.#dropdownContentEl
    );
    this.#appendListItems();
    if (countrySearch) {
      this.#updateSearchResultsA11yText();
    }
    if (!useFullscreenPopup) {
      this.#inlineDropdownHeight = this.#getHiddenInlineDropdownHeight();
      if (countrySearch) {
        this.#dropdownContentEl.style.height = `${this.#inlineDropdownHeight}px`;
      }
    }
    if (dropdownContainer) {
      const dropdownClasses = buildClassNames({
        iti: true,
        "iti--container": true,
        "iti--fullscreen-popup": useFullscreenPopup,
        "iti--inline-dropdown": !useFullscreenPopup,
        [containerClass]: Boolean(containerClass)
      });
      this.#detachedDropdownEl = createEl("div", { class: dropdownClasses });
      this.#detachedDropdownEl.appendChild(this.#dropdownContentEl);
    } else {
      this.#countryContainerEl.appendChild(this.#dropdownContentEl);
    }
  }
  #buildSearchUI() {
    const { i18n, searchInputClass } = this.#options;
    const searchWrapper = createEl(
      "div",
      { class: "iti__search-input-wrapper" },
      this.#dropdownContentEl
    );
    this.#searchIconEl = createEl(
      "span",
      {
        class: "iti__search-icon",
        [ARIA.HIDDEN]: "true"
      },
      searchWrapper
    );
    this.#searchIconEl.appendChild(buildSearchIcon());
    this.#searchInputEl = createEl(
      "input",
      {
        id: `iti-${this.#id}__search-input`,
        // Chrome says inputs need either a name or an id
        type: "search",
        class: `iti__search-input ${searchInputClass}`,
        placeholder: i18n.searchPlaceholder,
        // role=combobox + aria-autocomplete=list + aria-activedescendant allows maintaining focus on the search input while allowing users to navigate search results with up/down keyboard keys
        role: "combobox",
        [ARIA.EXPANDED]: "true",
        [ARIA.LABEL]: i18n.searchPlaceholder,
        [ARIA.CONTROLS]: `iti-${this.#id}__country-listbox`,
        [ARIA.AUTOCOMPLETE]: "list",
        autocomplete: "off"
      },
      searchWrapper
    );
    this.#searchClearButtonEl = createEl(
      "button",
      {
        type: "button",
        class: `iti__search-clear ${CLASSES.HIDE}`,
        [ARIA.LABEL]: i18n.clearSearchAriaLabel,
        tabindex: "-1"
      },
      searchWrapper
    );
    this.#searchClearButtonEl.appendChild(buildClearIcon(this.#id));
    this.#searchResultsLiveRegionEl = createEl(
      "span",
      { class: "iti__a11y-text" },
      this.#dropdownContentEl
    );
    this.#noResultsMessageEl = createEl(
      "div",
      {
        class: `iti__no-results ${CLASSES.HIDE}`,
        [ARIA.HIDDEN]: "true"
        // all a11y messaging happens in this.#searchResultsLiveRegionEl
      },
      this.#dropdownContentEl
    );
    this.#noResultsMessageEl.textContent = i18n.searchEmptyState ?? null;
  }
  #updateInputPaddingAndReveal() {
    if (!this.#countryContainerEl) {
      return;
    }
    this.#updateInputPadding();
    this.#countryContainerEl.classList.remove(CLASSES.V_HIDE);
  }
  #buildHiddenInputs(wrapper) {
    const { hiddenInput } = this.#options;
    if (!hiddenInput) {
      return;
    }
    const telInputName = this.telInputEl.getAttribute("name") || "";
    const names = hiddenInput(telInputName);
    if (names.phone) {
      const existingInput = this.telInputEl.form?.querySelector(
        `input[name="${names.phone}"]`
      );
      if (existingInput) {
        this.#hiddenInputPhoneEl = existingInput;
      } else {
        this.#hiddenInputPhoneEl = createEl("input", {
          type: "hidden",
          name: names.phone
        });
        wrapper.appendChild(this.#hiddenInputPhoneEl);
      }
    }
    if (names.country) {
      const existingInput = this.telInputEl.form?.querySelector(
        `input[name="${names.country}"]`
      );
      if (existingInput) {
        this.#hiddenInputCountryEl = existingInput;
      } else {
        this.#hiddenInputCountryEl = createEl("input", {
          type: "hidden",
          name: names.country
        });
        wrapper.appendChild(this.#hiddenInputCountryEl);
      }
    }
  }
  //* For each country: add a country list item <li> to the countryList <ul> container.
  #appendListItems() {
    const frag = document.createDocumentFragment();
    for (let i = 0; i < this.#countries.length; i++) {
      const c = this.#countries[i];
      const liClass = buildClassNames({
        [CLASSES.COUNTRY_ITEM]: true
      });
      const listItem = createEl("li", {
        id: `iti-${this.#id}__item-${c.iso2}`,
        class: liClass,
        tabindex: "-1",
        role: "option",
        [ARIA.SELECTED]: "false"
      });
      listItem.dataset[DATA_KEYS.DIAL_CODE] = c.dialCode;
      listItem.dataset[DATA_KEYS.ISO2] = c.iso2;
      this.#listItemByIso2.set(c.iso2, listItem);
      if (this.#options.showFlags) {
        createEl("div", { class: `${CLASSES.FLAG} iti__${c.iso2}` }, listItem);
      }
      const nameEl = createEl("span", { class: "iti__country-name" }, listItem);
      nameEl.textContent = `${c.name} `;
      const dialEl = createEl("span", { class: "iti__dial-code" }, nameEl);
      if (this.#isRTL) {
        dialEl.setAttribute("dir", "ltr");
      }
      dialEl.textContent = `(+${c.dialCode})`;
      frag.appendChild(listItem);
    }
    this.#countryListEl.appendChild(frag);
  }
  //* Update the input padding to make space for (1) the selected country/globe, (2) the arrow, and (3) the separate dial code, all of which are optional, hence handling this in the JS rather than CSS.
  #updateInputPadding() {
    if (this.#selectedCountryEl) {
      const fallbackWidth = this.#options.separateDialCode ? LAYOUT.FALLBACK_SELECTED_WITH_DIAL_WIDTH : LAYOUT.FALLBACK_SELECTED_NO_DIAL_WIDTH;
      const selectedCountryWidth = this.#selectedCountryEl.offsetWidth || this.#getHiddenSelectedCountryWidth() || fallbackWidth;
      const inputPadding = selectedCountryWidth + LAYOUT.INPUT_PADDING_EXTRA_LEFT;
      this.telInputEl.style.paddingLeft = `${inputPadding}px`;
    }
  }
  //* Keep the input padding in sync when the selected country's rendered width changes — e.g. responsive font-size shifts that change the dial code text width. Skip while hidden (offsetWidth === 0) so we don't waste work or clobber the padding using a fallback constant.
  #observeSelectedCountryResize() {
    if (!this.#selectedCountryEl || typeof ResizeObserver === "undefined") {
      return;
    }
    this.#resizeObserver = new ResizeObserver(() => {
      if (this.#selectedCountryEl?.offsetWidth) {
        this.#updateInputPadding();
      }
    });
    this.#resizeObserver.observe(this.#selectedCountryEl);
  }
  static #getBody() {
    let body;
    try {
      body = window.top.document.body;
    } catch (e) {
      body = document.body;
    }
    return body;
  }
  //* When input is in a hidden container during init, we cannot calculate the selected country width.
  //* Fix: clone the markup, make it invisible, add it to the end of the DOM, and then measure it's width.
  //* To get the right styling to apply, all we need is a shallow clone of the container,
  //* and then to inject a deep clone of the selectedCountryEl element.
  #getHiddenSelectedCountryWidth() {
    if (!this.telInputEl.parentNode) {
      return 0;
    }
    const body = _UI.#getBody();
    const containerClone = this.telInputEl.parentNode.cloneNode(
      false
    );
    containerClone.style.visibility = "hidden";
    body.appendChild(containerClone);
    const countryContainerClone = this.#countryContainerEl.cloneNode();
    containerClone.appendChild(countryContainerClone);
    const selectedCountryClone = this.#selectedCountryEl.cloneNode(
      true
    );
    countryContainerClone.appendChild(selectedCountryClone);
    const width = selectedCountryClone.offsetWidth;
    body.removeChild(containerClone);
    return width;
  }
  // Get the dropdown height (before it is added to the DOM)
  #getHiddenInlineDropdownHeight() {
    const body = _UI.#getBody();
    this.#dropdownContentEl.classList.remove(CLASSES.HIDE);
    const tempContainer = createEl("div", {
      class: "iti iti--inline-dropdown"
    });
    tempContainer.appendChild(this.#dropdownContentEl);
    tempContainer.style.visibility = "hidden";
    body.appendChild(tempContainer);
    const height = this.#dropdownContentEl.offsetHeight;
    body.removeChild(tempContainer);
    tempContainer.style.visibility = "";
    this.#dropdownContentEl.classList.add(CLASSES.HIDE);
    return height > 0 ? height : LAYOUT.FALLBACK_DROPDOWN_HEIGHT;
  }
  //* Update search results text (for a11y).
  #updateSearchResultsA11yText() {
    const { i18n } = this.#options;
    const count = this.#countryListEl.childElementCount;
    this.#searchResultsLiveRegionEl.textContent = i18n.searchSummaryAria(count);
  }
  //* Country search: Filter the countries according to the search query.
  #filterCountriesByQuery(query) {
    let matchedCountries;
    if (query === "") {
      matchedCountries = this.#countries;
    } else {
      const normalisedQuery = Numerals.toAscii(query);
      matchedCountries = getMatchedCountries(
        this.#countries,
        this.#searchTokens,
        normalisedQuery
      );
    }
    this.#showFilteredCountries(matchedCountries);
  }
  //* Pre-fill the search input with "+" and show all countries
  //* (used when user types "+" in the phone input to open the dropdown).
  //* Explicitly focus the search input (openDropdown skips this when
  //* dropdownAlwaysOpen, but here we need focus to redirect subsequent keystrokes).
  prefillSearchWithPlus() {
    this.#searchInputEl.value = "+";
    this.#searchInputEl.focus();
    this.#filterCountriesByQuery("");
  }
  // Search input handlers
  #applySearchFilter() {
    const inputQuery = this.#searchInputEl.value.trim();
    this.#filterCountriesByQuery(inputQuery);
    if (this.#searchInputEl.value) {
      this.#searchClearButtonEl.classList.remove(CLASSES.HIDE);
    } else {
      this.#searchClearButtonEl.classList.add(CLASSES.HIDE);
    }
  }
  #handleSearchChange() {
    if (this.#searchDebounceTimer) {
      clearTimeout(this.#searchDebounceTimer);
    }
    this.#searchDebounceTimer = setTimeout(() => {
      this.#applySearchFilter();
      this.#searchDebounceTimer = null;
    }, TIMINGS.SEARCH_DEBOUNCE_MS);
  }
  #handleSearchClear() {
    this.#searchInputEl.value = "";
    this.#searchInputEl.focus();
    this.#applySearchFilter();
  }
  //* Check if a country list item element is visible within it's container (the country list), else scroll until it is.
  #scrollCountryListToItem(element) {
    const container = this.#countryListEl;
    const containerRect = container.getBoundingClientRect();
    const elementRect = element.getBoundingClientRect();
    const offsetTop = elementRect.top - containerRect.top + container.scrollTop;
    if (elementRect.top < containerRect.top) {
      container.scrollTop = offsetTop;
    } else if (elementRect.bottom > containerRect.bottom) {
      container.scrollTop = offsetTop - containerRect.height + elementRect.height;
    }
  }
  //* Remove highlighting from the previous list item and highlight the new one.
  #highlightListItem(listItem, doScroll = true) {
    this.#highlightedListItemEl?.classList.remove(CLASSES.HIGHLIGHT);
    if (listItem) {
      listItem.classList.add(CLASSES.HIGHLIGHT);
      if (this.#options.countrySearch) {
        const activeDescendant = listItem.getAttribute("id") || "";
        this.#searchInputEl.setAttribute(
          ARIA.ACTIVE_DESCENDANT,
          activeDescendant
        );
      }
      if (doScroll) {
        this.#scrollCountryListToItem(listItem);
      }
      this.#highlightedListItemEl = listItem;
    } else {
      this.#highlightedListItemEl = null;
    }
  }
  //* Bind a form-submit listener that syncs the hidden inputs with the current phone number
  //* and country iso2. No-op if there are no hidden inputs or the input is not in a form.
  bindHiddenInputSubmitListener(signal, getPhone, getCountryIso2) {
    const form = this.telInputEl.form;
    if (!form || !this.#hiddenInputPhoneEl && !this.#hiddenInputCountryEl) {
      return;
    }
    form.addEventListener(
      "submit",
      () => {
        if (this.#hiddenInputPhoneEl) {
          this.#hiddenInputPhoneEl.value = getPhone();
        }
        if (this.#hiddenInputCountryEl) {
          this.#hiddenInputCountryEl.value = getCountryIso2();
        }
      },
      { signal }
    );
  }
  //* Wire up triggers that open/close the dropdown: label click (focus input or swallow repeat click),
  //* selected-country click (open), and keydown on countryContainer (open on arrow/space/enter, close on tab).
  bindAllInitialDropdownListeners(signal, onOpen, onClose) {
    const label = this.telInputEl.closest("label");
    if (label) {
      label.addEventListener(
        "click",
        (e) => {
          if (!this.isDropdownOpen()) {
            this.telInputEl.focus();
          } else {
            e.preventDefault();
          }
        },
        { signal }
      );
    }
    this.#selectedCountryEl.addEventListener(
      "click",
      () => {
        if (!this.isDropdownOpen() && !this.telInputEl.disabled && !this.telInputEl.readOnly) {
          onOpen();
        }
      },
      { signal }
    );
    this.#countryContainerEl.addEventListener(
      "keydown",
      (e) => {
        const openKeys = [
          KEYS.ARROW_UP,
          KEYS.ARROW_DOWN,
          KEYS.SPACE,
          KEYS.ENTER
        ];
        if (!this.isDropdownOpen() && openKeys.includes(e.key)) {
          e.preventDefault();
          e.stopPropagation();
          onOpen();
        }
        if (e.key === KEYS.TAB) {
          onClose();
        }
      },
      { signal }
    );
  }
  //* Open the dropdown: create a fresh AbortController, do the DOM work, and wire up all
  //* dropdown-open listeners (which invoke the caller's onSelect / onClose callbacks).
  openDropdown(onSelect, onClose) {
    const { countrySearch, dropdownAlwaysOpen, dropdownContainer } = this.#options;
    this.#dropdownAbortController = new AbortController();
    this.ensureDropdownWidthSet();
    if (dropdownContainer) {
      this.#injectAndPositionDetachedDropdown();
    } else {
      const positionBelow = this.#shouldPositionInlineDropdownBelowInput();
      const distance = this.telInputEl.offsetHeight + LAYOUT.DROPDOWN_MARGIN;
      if (positionBelow) {
        this.#dropdownContentEl.style.top = `${distance}px`;
      } else {
        this.#dropdownContentEl.style.bottom = `${distance}px`;
      }
    }
    this.#dropdownContentEl.classList.remove(CLASSES.HIDE);
    this.#selectedCountryEl.setAttribute(ARIA.EXPANDED, "true");
    const itemToHighlight = this.#selectedListItemEl ?? this.#countryListEl.firstElementChild;
    if (itemToHighlight) {
      this.#highlightListItem(itemToHighlight);
    }
    if (countrySearch && !dropdownAlwaysOpen) {
      this.#searchInputEl.focus();
    }
    if (this.#options.useFullscreenPopup && this.#detachedDropdownEl && window.visualViewport) {
      window.visualViewport.addEventListener(
        "resize",
        () => {
          this.#adjustFullscreenPopupToViewport();
          if (this.#highlightedListItemEl) {
            this.#scrollCountryListToItem(this.#highlightedListItemEl);
          }
        },
        { signal: this.#dropdownAbortController.signal }
      );
    }
    this.#dropdownArrowEl.classList.add(CLASSES.ARROW_UP);
    this.#bindDropdownOpenListeners(onSelect, onClose);
  }
  //* Wire up all listeners needed while the dropdown is open: list-item hover (highlight),
  //* list-item click & enter key (select), click-off & escape (close), search input (filter),
  //* (when countrySearch disabled) typed-char hidden search, and (when dropdown is in an external
  //* container) close on window scroll.
  #bindDropdownOpenListeners(onSelect, onClose) {
    const signal = this.#dropdownAbortController.signal;
    this.#bindListItemHover(signal);
    this.#bindListItemClick(signal, onSelect);
    if (!this.#options.dropdownAlwaysOpen) {
      this.#bindOutsideClickToClose(signal, onClose);
    }
    this.#bindDropdownKeydownListener(signal, onSelect, onClose);
    if (this.#options.countrySearch) {
      this.#bindSearchInputListener(signal);
    }
    if (!this.#options.useFullscreenPopup && this.#options.dropdownContainer) {
      window.addEventListener("scroll", onClose, { signal });
    }
  }
  //* When mouse over a list item, just highlight that one (so if they hit "enter" we know which to select).
  #bindListItemHover(signal) {
    this.#countryListEl.addEventListener(
      "mouseover",
      (e) => {
        const listItem = e.target?.closest(
          `.${CLASSES.COUNTRY_ITEM}`
        );
        if (listItem) {
          this.#highlightListItem(listItem, false);
        }
      },
      { signal }
    );
  }
  //* Delegate clicks on the country list to the caller's onSelect callback, passing the clicked list item.
  #bindListItemClick(signal, onSelect) {
    this.#countryListEl.addEventListener(
      "click",
      (e) => {
        const listItem = e.target?.closest(
          `.${CLASSES.COUNTRY_ITEM}`
        );
        if (listItem) {
          onSelect(listItem);
        }
      },
      { signal }
    );
  }
  //* Invoke onClickOff when the user clicks anywhere outside the dropdown.
  #bindOutsideClickToClose(signal, onClickOff) {
    setTimeout(() => {
      document.documentElement.addEventListener(
        "click",
        (e) => {
          if (!this.#dropdownContentEl.contains(e.target)) {
            onClickOff();
          }
        },
        { signal }
      );
    }, 0);
  }
  //* Keyboard navigation while the dropdown is open: arrow keys navigate, hidden-search keys filter,
  //* and enter/escape invoke the caller's callbacks (which handle country selection / dropdown close).
  //* Uses keydown rather than keypress so non-char keys (arrow, esc) fire and so holding a key repeats.
  #bindDropdownKeydownListener(signal, onEnter, onEscape) {
    let query = "";
    let queryTimer = null;
    const handleKeydown = (e) => {
      const allowedKeys = [
        KEYS.ARROW_UP,
        KEYS.ARROW_DOWN,
        KEYS.ENTER,
        KEYS.ESC
      ];
      if (allowedKeys.includes(e.key)) {
        e.preventDefault();
        e.stopPropagation();
        if (e.key === KEYS.ARROW_UP || e.key === KEYS.ARROW_DOWN) {
          this.#handleUpDownKey(e.key);
        } else if (e.key === KEYS.ENTER && !e.isComposing) {
          onEnter(this.#highlightedListItemEl);
        } else if (e.key === KEYS.ESC) {
          onEscape();
          this.#selectedCountryEl.focus();
        }
      }
      if (!this.#options.countrySearch && REGEX.HIDDEN_SEARCH_CHAR.test(e.key)) {
        e.stopPropagation();
        if (queryTimer) {
          clearTimeout(queryTimer);
        }
        query += e.key.toLowerCase();
        this.#searchForCountry(query);
        queryTimer = setTimeout(() => {
          query = "";
        }, TIMINGS.HIDDEN_SEARCH_RESET_MS);
      }
    };
    this.#selectedCountryEl?.addEventListener("keydown", handleKeydown, { signal });
    this.#dropdownContentEl?.addEventListener("keydown", handleKeydown, { signal });
  }
  //* Wire up country search input listener: typing filters the list, the clear button resets it.
  #bindSearchInputListener(signal) {
    this.#searchInputEl.addEventListener(
      "input",
      () => this.#handleSearchChange(),
      { signal }
    );
    this.#searchClearButtonEl.addEventListener(
      "click",
      () => this.#handleSearchClear(),
      { signal }
    );
  }
  //* Hidden search (countrySearch disabled): jump to the first list item whose name starts with the query.
  #searchForCountry(query) {
    const match = findFirstCountryStartingWith(
      this.#countries,
      this.#searchTokens,
      query
    );
    if (match) {
      const listItem = this.#listItemByIso2.get(match.iso2);
      this.#highlightListItem(listItem);
    }
  }
  //* Highlight the next/prev item in the list (and ensure it is visible).
  #handleUpDownKey(key) {
    let next = key === KEYS.ARROW_UP ? this.#highlightedListItemEl?.previousElementSibling : this.#highlightedListItemEl?.nextElementSibling;
    if (!next && this.#countryListEl.childElementCount > 1) {
      next = key === KEYS.ARROW_UP ? this.#countryListEl.lastElementChild : this.#countryListEl.firstElementChild;
    }
    if (next) {
      this.#highlightListItem(next);
    }
  }
  // Update the selected list item in the dropdown
  #updateSelectedListItem(iso2) {
    if (this.#selectedListItemEl && this.#selectedListItemEl.dataset[DATA_KEYS.ISO2] !== iso2) {
      this.#selectedListItemEl.setAttribute(ARIA.SELECTED, "false");
      this.#selectedListItemEl.querySelector(".iti__country-check")?.remove();
      this.#selectedListItemEl = null;
    }
    if (iso2 && !this.#selectedListItemEl) {
      const newListItem = this.#countryListEl.querySelector(
        `[data-iso2="${iso2}"]`
      );
      if (newListItem) {
        newListItem.setAttribute(ARIA.SELECTED, "true");
        const checkIcon = createEl(
          "span",
          { class: "iti__country-check", [ARIA.HIDDEN]: "true" },
          newListItem
        );
        checkIcon.appendChild(buildCheckIcon());
        this.#selectedListItemEl = newListItem;
        if (this.#options.dropdownAlwaysOpen) {
          this.#highlightListItem(newListItem);
        }
      }
    }
  }
  //* Country search: Filter the country list to the given array of countries.
  #showFilteredCountries(matchedCountries) {
    this.#countryListEl.replaceChildren();
    let noCountriesAddedYet = true;
    for (const c of matchedCountries) {
      const listItem = this.#listItemByIso2.get(c.iso2);
      if (listItem) {
        this.#countryListEl.appendChild(listItem);
        if (noCountriesAddedYet) {
          this.#highlightListItem(listItem, false);
          noCountriesAddedYet = false;
        }
      }
    }
    if (noCountriesAddedYet) {
      this.#highlightListItem(null);
      if (this.#noResultsMessageEl) {
        this.#noResultsMessageEl.classList.remove(CLASSES.HIDE);
      }
    } else if (this.#noResultsMessageEl) {
      this.#noResultsMessageEl.classList.add(CLASSES.HIDE);
    }
    this.#countryListEl.scrollTop = 0;
    this.#updateSearchResultsA11yText();
  }
  // UI: Close the dropdown (DOM + abort dropdown-scoped listeners).
  closeDropdown() {
    const { countrySearch, dropdownContainer } = this.#options;
    this.#dropdownAbortController.abort();
    this.#dropdownAbortController = null;
    this.#dropdownContentEl.classList.add(CLASSES.HIDE);
    this.#selectedCountryEl.setAttribute(ARIA.EXPANDED, "false");
    if (countrySearch) {
      this.#searchInputEl.removeAttribute(ARIA.ACTIVE_DESCENDANT);
      this.#searchInputEl.value = "";
      this.#applySearchFilter();
      if (this.#highlightedListItemEl) {
        this.#highlightedListItemEl.classList.remove(CLASSES.HIGHLIGHT);
        this.#highlightedListItemEl = null;
      }
    }
    this.#dropdownArrowEl.classList.remove(CLASSES.ARROW_UP);
    if (dropdownContainer) {
      this.#detachedDropdownEl.remove();
      this.#detachedDropdownEl.style.top = "";
      this.#detachedDropdownEl.style.bottom = "";
      this.#detachedDropdownEl.style.paddingLeft = "";
      this.#detachedDropdownEl.style.paddingRight = "";
    } else {
      this.#dropdownContentEl.style.top = "";
      this.#dropdownContentEl.style.bottom = "";
    }
  }
  #shouldPositionInlineDropdownBelowInput() {
    if (this.#options.dropdownAlwaysOpen) {
      return true;
    }
    const inputPos = this.telInputEl.getBoundingClientRect();
    const spaceAbove = inputPos.top;
    const spaceBelow = window.innerHeight - inputPos.bottom;
    return spaceBelow >= this.#inlineDropdownHeight || spaceBelow >= spaceAbove;
  }
  // inject dropdown into container and apply positioning styles
  #injectAndPositionDetachedDropdown() {
    const { dropdownContainer, useFullscreenPopup } = this.#options;
    if (useFullscreenPopup) {
      if (window.innerWidth >= LAYOUT.NARROW_VIEWPORT_WIDTH) {
        const inputPos = this.telInputEl.getBoundingClientRect();
        this.#detachedDropdownEl.style.paddingLeft = `${inputPos.left}px`;
        this.#detachedDropdownEl.style.paddingRight = `${window.innerWidth - inputPos.right}px`;
      }
    } else {
      const inputPos = this.telInputEl.getBoundingClientRect();
      this.#detachedDropdownEl.style.left = `${inputPos.left}px`;
      const positionBelow = this.#shouldPositionInlineDropdownBelowInput();
      if (positionBelow) {
        this.#detachedDropdownEl.style.top = `${inputPos.bottom + LAYOUT.DROPDOWN_MARGIN}px`;
      } else {
        this.#detachedDropdownEl.style.top = "unset";
        this.#detachedDropdownEl.style.bottom = `${window.innerHeight - inputPos.top + LAYOUT.DROPDOWN_MARGIN}px`;
      }
    }
    dropdownContainer.appendChild(this.#detachedDropdownEl);
  }
  // Adjust the fullscreen popup dimensions to match the visual viewport,
  // so it stays above the virtual keyboard on mobile devices.
  #adjustFullscreenPopupToViewport() {
    const vv = window.visualViewport;
    if (!vv || !this.#detachedDropdownEl) {
      return;
    }
    const virtualKeyboardHeight = window.innerHeight - vv.height;
    this.#detachedDropdownEl.style.bottom = `${virtualKeyboardHeight}px`;
  }
  // UI: Whether the dropdown is currently open (visible).
  isDropdownOpen() {
    return !this.#dropdownContentEl.classList.contains(CLASSES.HIDE);
  }
  // Toggle the loading spinner on the selected flag (used during auto-country geoIP lookup).
  setLoading(isLoading) {
    this.#selectedFlagEl.classList.toggle(CLASSES.LOADING, isLoading);
  }
  //* Play the strict-reject animation (shake, or background-colour flash under prefers-reduced-motion) on the wrapper.
  //* Called when strictMode rejects the whole input (keystroke, or whole paste).
  //* Uses the wrapper (not the input) so any separateDialCode / country button move together with the input.
  playStrictRejectAnimation() {
    if (!this.#options.strictRejectAnimation) {
      return;
    }
    const wrapperEl = this.telInputEl.parentElement;
    if (!wrapperEl) {
      return;
    }
    wrapperEl.classList.remove(CLASSES.STRICT_REJECT_ANIMATION);
    void wrapperEl.offsetWidth;
    wrapperEl.classList.add(CLASSES.STRICT_REJECT_ANIMATION);
    wrapperEl.addEventListener(
      "animationend",
      () => wrapperEl.classList.remove(CLASSES.STRICT_REJECT_ANIMATION),
      { once: true }
    );
  }
  isLoading() {
    return this.#selectedFlagEl.classList.contains(CLASSES.LOADING);
  }
  // Set the disabled state of the input and dropdown.
  setDisabled(disabled) {
    this.telInputEl.disabled = disabled;
    if (this.#selectedCountryEl) {
      if (disabled) {
        this.#selectedCountryEl.setAttribute("disabled", "true");
      } else {
        this.#selectedCountryEl.removeAttribute("disabled");
      }
    }
  }
  // Set the readonly state of the input and dropdown.
  setReadonly(readonly) {
    this.telInputEl.readOnly = readonly;
    if (this.#selectedCountryEl) {
      if (readonly) {
        this.#selectedCountryEl.setAttribute("disabled", "true");
      } else {
        this.#selectedCountryEl.removeAttribute("disabled");
      }
    }
  }
  setCountry(selectedCountryData) {
    const { allowDropdown, showFlags, separateDialCode, i18n } = this.#options;
    const name = selectedCountryData?.name;
    const dialCode = selectedCountryData?.dialCode;
    const iso2 = selectedCountryData?.iso2 ?? "";
    if (allowDropdown) {
      this.#updateSelectedListItem(iso2);
    }
    if (this.#selectedCountryEl) {
      const flagClass = iso2 && showFlags ? `${CLASSES.FLAG} iti__${iso2}` : `${CLASSES.FLAG} ${CLASSES.GLOBE}`;
      let ariaLabel, title;
      let flagContent = null;
      if (iso2) {
        title = name;
        ariaLabel = i18n.selectedCountryAriaLabel.replace("${countryName}", name).replace("${dialCode}", `+${dialCode}`);
        if (!showFlags) {
          flagContent = buildGlobeIcon();
        }
      } else {
        title = i18n.noCountrySelected;
        ariaLabel = i18n.noCountrySelected;
        flagContent = buildGlobeIcon();
      }
      this.#selectedFlagEl.className = flagClass;
      this.#selectedCountryEl.setAttribute("title", title);
      this.#selectedCountryEl.setAttribute(ARIA.LABEL, ariaLabel);
      if (flagContent) {
        this.#selectedFlagEl.replaceChildren(flagContent);
      } else {
        this.#selectedFlagEl.replaceChildren();
      }
    }
    if (separateDialCode) {
      const fullDialCode = dialCode ? `+${dialCode}` : "";
      this.#selectedDialCodeEl.textContent = fullDialCode;
      this.#updateInputPadding();
    }
  }
  destroy() {
    this.telInputEl.iti = void 0;
    delete this.telInputEl.dataset[DATA_KEYS.INSTANCE_ID];
    this.#resizeObserver?.disconnect();
    this.telInputEl.style.paddingLeft = this.#originalPaddingLeft;
    const wrapper = this.telInputEl.parentNode;
    if (wrapper) {
      wrapper.before(this.telInputEl);
      wrapper.remove();
    }
    this.#listItemByIso2.clear();
  }
};

// packages/core/src/js/data/country-data.ts
var processAllCountries = (options) => {
  const { onlyCountries, excludeCountries } = options;
  if (onlyCountries?.length) {
    return data_default.filter(
      (country) => onlyCountries.includes(country.iso2)
    );
  } else if (excludeCountries?.length) {
    return data_default.filter(
      (country) => !excludeCountries.includes(country.iso2)
    );
  }
  return [...data_default];
};
var generateCountryNames = (countries, options) => {
  const { countryNameLocale, countryNameOverrides } = options;
  let displayNames;
  try {
    const hasDisplayNames = typeof Intl !== "undefined" && typeof Intl.DisplayNames === "function";
    if (hasDisplayNames) {
      displayNames = new Intl.DisplayNames(countryNameLocale, {
        type: "region"
      });
    } else {
      displayNames = null;
    }
  } catch (e) {
    console.error(e);
    displayNames = null;
  }
  for (const c of countries) {
    c.name = countryNameOverrides[c.iso2] || displayNames?.of(c.iso2.toUpperCase()) || "";
  }
};
var processDialCodes = (countries) => {
  const dialCodes = /* @__PURE__ */ new Set();
  let dialCodeMaxLength = 0;
  const dialCodeToIso2Map = {};
  const addToDialCodeMap = (iso2, dialCode) => {
    if (!iso2 || !dialCode) {
      return;
    }
    if (dialCode.length > dialCodeMaxLength) {
      dialCodeMaxLength = dialCode.length;
    }
    if (!Object.hasOwn(dialCodeToIso2Map, dialCode)) {
      dialCodeToIso2Map[dialCode] = [];
    }
    const iso2List = dialCodeToIso2Map[dialCode];
    if (iso2List.includes(iso2)) {
      return;
    }
    iso2List.push(iso2);
  };
  const countriesSortedByPriority = [...countries].sort(
    (a, b) => a.priority - b.priority
  );
  for (const c of countriesSortedByPriority) {
    if (!dialCodes.has(c.dialCode)) {
      dialCodes.add(c.dialCode);
    }
    for (let k = 1; k < c.dialCode.length; k++) {
      const partialDialCode = c.dialCode.substring(0, k);
      addToDialCodeMap(c.iso2, partialDialCode);
    }
    addToDialCodeMap(c.iso2, c.dialCode);
    if (c.areaCodes) {
      const rootIso2Code = dialCodeToIso2Map[c.dialCode][0];
      for (const areaCode of c.areaCodes) {
        for (let k = 1; k < areaCode.length; k++) {
          const partialAreaCode = areaCode.substring(0, k);
          const partialDialCode = c.dialCode + partialAreaCode;
          addToDialCodeMap(rootIso2Code, partialDialCode);
          addToDialCodeMap(c.iso2, partialDialCode);
        }
        addToDialCodeMap(c.iso2, c.dialCode + areaCode);
      }
    }
  }
  return { dialCodes, dialCodeMaxLength, dialCodeToIso2Map };
};
var sortCountries = (countries, options) => {
  const { countryOrder } = options;
  countries.sort((a, b) => {
    if (countryOrder) {
      const aIndex = countryOrder.indexOf(a.iso2);
      const bIndex = countryOrder.indexOf(b.iso2);
      const aIndexExists = aIndex > -1;
      const bIndexExists = bIndex > -1;
      if (aIndexExists || bIndexExists) {
        if (aIndexExists && bIndexExists) {
          return aIndex - bIndex;
        }
        return aIndexExists ? -1 : 1;
      }
    }
    return a.name.localeCompare(b.name);
  });
};

// packages/core/src/js/data/intl-regionless.ts
var regionlessDialCodes = /* @__PURE__ */ new Set([
  "800",
  "808",
  "870",
  "881",
  "882",
  "883",
  "888",
  "979"
]);
var hasRegionlessDialCode = (number) => {
  const dialCode = getNumeric(number).slice(0, 3);
  return number.startsWith("+") && regionlessDialCodes.has(dialCode);
};

// packages/core/src/js/format/formatting.ts
var stripSeparateDialCode = (fullNumber, hasValidDialCode, separateDialCode, selectedCountryData) => {
  if (!separateDialCode || !hasValidDialCode) {
    return fullNumber;
  }
  const dialCode = `+${selectedCountryData.dialCode}`;
  const start = fullNumber[dialCode.length] === " " || fullNumber[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
  return fullNumber.substring(start);
};
var formatNumberAsYouType = (fullNumber, telInputValue, utils, selectedCountryData, separateDialCode) => {
  const result = utils ? utils.formatNumberAsYouType(fullNumber, selectedCountryData?.iso2) : fullNumber;
  const dialCode = selectedCountryData?.dialCode;
  if (separateDialCode && telInputValue.charAt(0) !== "+" && result.includes(`+${dialCode}`)) {
    const afterDialCode = result.split(`+${dialCode}`)[1] || "";
    return afterDialCode.trim();
  }
  return result;
};

// packages/core/src/js/format/caret.ts
var computeNewCaretPosition = (relevantChars, formattedValue, prevCaretPos, isDeleteForwards) => {
  if (prevCaretPos === 0 && !isDeleteForwards) {
    return 0;
  }
  let relevantCharCount = 0;
  for (let i = 0; i < formattedValue.length; i++) {
    if (/[+0-9]/.test(formattedValue[i])) {
      relevantCharCount++;
    }
    if (relevantCharCount === relevantChars && !isDeleteForwards) {
      return i + 1;
    }
    if (isDeleteForwards && relevantCharCount === relevantChars + 1) {
      return i;
    }
  }
  return formattedValue.length;
};

// packages/core/src/js/data/nanp-regionless.ts
var regionlessNanpAreaCodes = /* @__PURE__ */ new Set([
  "800",
  "822",
  "833",
  "844",
  "855",
  "866",
  "877",
  "880",
  "881",
  "882",
  "883",
  "884",
  "885",
  "886",
  "887",
  "888",
  "889"
]);
var isRegionlessNanp = (number) => {
  const numeric = getNumeric(number);
  if (numeric.startsWith(DIAL_CODE.NANP) && numeric.length >= 4) {
    const areaCode = numeric.substring(1, 4);
    return regionlessNanpAreaCodes.has(areaCode);
  }
  return false;
};

// packages/core/src/js/intlTelInput.ts
var nextId = 0;
var ensureUtils = (methodName) => {
  if (!intlTelInput.utils) {
    throw new Error(
      `intlTelInput.utils is required for ${methodName}(). See: https://intl-tel-input.com/docs/utils`
    );
  }
};
var createDeferred = () => {
  let resolve;
  let reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return { promise, resolve, reject };
};
var Iti = class _Iti {
  //* PUBLIC FIELDS - READONLY
  //* Can't be private as it's called from intlTelInput convenience wrapper.
  id;
  // accessed externally via iti.promise.then(...)
  promise;
  //* PRIVATE FIELDS
  #ui;
  #options;
  #isAndroid;
  // country data
  #countries;
  #dialCodeMaxLength;
  #dialCodeToIso2Map;
  #dialCodes;
  #countryByIso2;
  #searchTokens;
  #selectedCountry = null;
  #maxCoreNumberLength = null;
  #fallbackCountryIso2;
  // is this instance still active (not destroyed)
  #isActive = true;
  #abortController;
  #numerals;
  //* Tracks whether the user has typed/pasted their own formatting chars, so AYT-formatting should back off.
  #userOverrideFormatting = false;
  #strictPasteSnapshot = null;
  #autoCountryDeferred;
  #utilsDeferred;
  constructor(input, customOptions = {}) {
    this.id = nextId++;
    UI.validateInput(input);
    const validatedOptions = validateOptions(customOptions);
    this.#options = { ...defaults, ...validatedOptions };
    normaliseOptions(this.#options);
    applyOptionSideEffects(this.#options);
    this.#ui = new UI(input, this.#options, this.id);
    this.#isAndroid = typeof navigator !== "undefined" && /Android/i.test(navigator.userAgent);
    this.#numerals = new Numerals(input.value);
    this.promise = this.#createInitPromise(this.#options);
    this.#countries = processAllCountries(this.#options);
    const { dialCodes, dialCodeMaxLength, dialCodeToIso2Map } = processDialCodes(this.#countries);
    this.#dialCodes = dialCodes;
    this.#dialCodeMaxLength = dialCodeMaxLength;
    this.#dialCodeToIso2Map = dialCodeToIso2Map;
    this.#countryByIso2 = new Map(this.#countries.map((c) => [c.iso2, c]));
    this.#init();
  }
  #getTelInputValue() {
    const inputValue = this.#ui.telInputEl.value.trim();
    return this.#numerals.normalise(inputValue);
  }
  #setTelInputValue(asciiValue) {
    this.#ui.telInputEl.value = this.#numerals.denormalise(asciiValue);
  }
  #createInitPromise(options) {
    const { initialCountry, geoIpLookup, loadUtils } = options;
    const needsAutoCountryDeferred = initialCountry === INITIAL_COUNTRY.AUTO && Boolean(geoIpLookup);
    const needsUtilsDeferred = Boolean(loadUtils) && !intlTelInput.utils;
    if (needsAutoCountryDeferred) {
      this.#autoCountryDeferred = createDeferred();
    }
    if (needsUtilsDeferred) {
      this.#utilsDeferred = createDeferred();
    }
    return Promise.all([
      this.#autoCountryDeferred?.promise,
      this.#utilsDeferred?.promise
    ]).then(() => {
    });
  }
  #init() {
    this.#abortController = new AbortController();
    this.#processCountryData();
    this.#ui.buildMarkup(this.#countries, this.#searchTokens);
    this.#setInitialState();
    this.#initListeners();
    this.#startAsyncLoads();
    if (this.#options.dropdownAlwaysOpen) {
      this.#openDropdown();
    }
  }
  //********************
  //*  PRIVATE METHODS
  //********************
  //* Prepare all of the country data, including onlyCountries, excludeCountries, countryOrder options.
  #processCountryData() {
    generateCountryNames(this.#countries, this.#options);
    sortCountries(this.#countries, this.#options);
    this.#searchTokens = buildSearchTokens(this.#countries);
  }
  //* Set the initial state of the input value and the selected country by:
  //* 1. Extracting a dial code from the given number
  //* 2. Using explicit initialCountry
  #setInitialState(overrideAutoCountry = false) {
    const attributeValueRaw = this.#ui.telInputEl.getAttribute("value");
    const attributeValue = this.#numerals.normalise(attributeValueRaw ?? "");
    const inputValue = this.#getTelInputValue();
    const useAttribute = attributeValue && attributeValue.startsWith("+") && (!inputValue || !inputValue.startsWith("+"));
    const value = useAttribute ? attributeValue : inputValue;
    const dialCode = this.#getDialCode(value);
    const isRegionlessNanpNumber = isRegionlessNanp(value);
    const { initialCountry, geoIpLookup } = this.#options;
    const isAutoCountry = initialCountry === INITIAL_COUNTRY.AUTO && geoIpLookup;
    const resolvedInitialCountry = isAutoCountry && intlTelInput.autoCountry ? intlTelInput.autoCountry : initialCountry;
    const doingAutoCountryLookup = isAutoCountry && !overrideAutoCountry && !intlTelInput.autoCountry;
    const isValidInitialCountry = isIso2(resolvedInitialCountry);
    if (dialCode) {
      if (isRegionlessNanpNumber) {
        if (isValidInitialCountry) {
          this.#updateSelectedCountry(resolvedInitialCountry);
        } else if (!doingAutoCountryLookup) {
          this.#updateSelectedCountry(US.ISO2);
        }
      } else {
        if (isValidInitialCountry) {
          this.#updateSelectedCountry(resolvedInitialCountry);
        }
        this.#updateCountryFromNumber(value);
      }
    } else if (isValidInitialCountry) {
      this.#updateSelectedCountry(resolvedInitialCountry);
    } else if (!doingAutoCountryLookup) {
      this.#updateSelectedCountry("");
    }
    if (value) {
      this.#updateValueFromNumber(value);
    }
  }
  //* Initialise the main event listeners: input keyup, and click selected country.
  #initListeners() {
    this.#bindAllTelInputListeners();
    if (this.#options.allowDropdown) {
      this.#ui.bindAllInitialDropdownListeners(
        this.#abortController.signal,
        () => this.#openDropdown(),
        () => this.#closeDropdown()
      );
    }
    this.#ui.bindHiddenInputSubmitListener(
      this.#abortController.signal,
      () => this.getNumber(),
      () => this.#selectedCountry?.iso2 || ""
    );
  }
  //* Init requests: utils script / geo ip lookup.
  #startAsyncLoads() {
    if (this.#utilsDeferred) {
      const { loadUtils } = this.#options;
      const doAttachUtils = () => {
        intlTelInput.attachUtils(loadUtils).catch(() => {
        });
      };
      if (intlTelInput.documentReady()) {
        doAttachUtils();
      } else {
        window.addEventListener("load", doAttachUtils, {
          signal: this.#abortController.signal
        });
      }
    }
    if (this.#autoCountryDeferred) {
      if (this.#selectedCountry) {
        this.#autoCountryDeferred.resolve();
      } else {
        this.#loadAutoCountry();
      }
    }
  }
  //* Perform the geo ip lookup.
  async #loadAutoCountry() {
    if (intlTelInput.autoCountry) {
      this.#handleAutoCountryLoaded();
      return;
    }
    this.#ui.setLoading(true);
    if (intlTelInput.startedLoadingAutoCountry) {
      return;
    }
    intlTelInput.startedLoadingAutoCountry = true;
    if (typeof this.#options.geoIpLookup === "function") {
      let timeoutId;
      try {
        const iso2 = await Promise.race([
          this.#options.geoIpLookup(),
          new Promise((_, reject) => {
            timeoutId = setTimeout(
              () => reject(new Error("intl-tel-input: geoIpLookup timed out after 10s")),
              1e4
            );
          })
        ]);
        const iso2Lower = typeof iso2 === "string" ? iso2.toLowerCase() : "";
        if (!isIso2(iso2Lower)) {
          intlTelInput.startedLoadingAutoCountry = false;
          _Iti.forEachInstance("handleAutoCountryFailure");
          return;
        }
        intlTelInput.autoCountry = iso2Lower;
        setTimeout(() => _Iti.forEachInstance("handleAutoCountryLoaded"));
      } catch {
        intlTelInput.startedLoadingAutoCountry = false;
        _Iti.forEachInstance("handleAutoCountryFailure");
      } finally {
        if (timeoutId !== void 0) {
          clearTimeout(timeoutId);
        }
      }
    }
  }
  #openDropdownWithPlus() {
    this.#openDropdown();
    this.#ui.prefillSearchWithPlus();
  }
  //* Delete the character just typed (the one immediately before the caret). Used by Android workarounds where we can't preventDefault on keydown.
  #removeJustTypedChar(inputValue) {
    const currentCaretPos = this.#ui.telInputEl.selectionStart || 0;
    const valueBeforeCaret = inputValue.substring(0, currentCaretPos - 1);
    const valueAfterCaret = inputValue.substring(currentCaretPos);
    this.#setTelInputValue(valueBeforeCaret + valueAfterCaret);
    return currentCaretPos - 1;
  }
  //* Initialize the tel input listeners.
  #bindAllTelInputListeners() {
    this.#bindInputListener();
    this.#bindKeydownListener();
    this.#bindStrictPasteListener();
  }
  //* Android workaround for handling plus when separateDialCode enabled (as impossible to handle with keydown/keyup, for which e.key always returns "Unidentified", see https://stackoverflow.com/q/59584061/217866)
  #handleAndroidPlusKey(inputValue) {
    this.#removeJustTypedChar(inputValue);
    this.#openDropdownWithPlus();
  }
  //* Android strictMode workaround: the keydown-based filter can't block these because e.key is "Unidentified" on Android virtual keyboards, so strip them here on input.
  #handleAndroidStrictReject(inputValue, rejectedInput) {
    const newCaretPos = this.#removeJustTypedChar(inputValue);
    this.#ui.telInputEl.setSelectionRange(newCaretPos, newCaretPos);
    this.#ui.playStrictRejectAnimation();
    this.#dispatchEvent(EVENTS.STRICT_REJECT, {
      source: "key",
      rejectedInput,
      reason: "invalid"
    });
  }
  //* Format the input value using libphonenumber's AYT formatter, preserving caret position (called after an input event).
  #formatAsYouType(inputValue, isDeleteForwards) {
    const currentCaretPos = this.#ui.telInputEl.selectionStart || 0;
    const valueBeforeCaret = inputValue.substring(0, currentCaretPos);
    const relevantCharsBeforeCaret = valueBeforeCaret.replace(
      REGEX.NON_PLUS_NUMERIC_GLOBAL,
      ""
    ).length;
    const fullNumber = this.#getFullNumber();
    const formattedValue = formatNumberAsYouType(
      fullNumber,
      inputValue,
      intlTelInput.utils,
      this.#selectedCountry,
      this.#options.separateDialCode
    );
    const newCaretPos = computeNewCaretPosition(
      relevantCharsBeforeCaret,
      formattedValue,
      currentCaretPos,
      isDeleteForwards
    );
    this.#setTelInputValue(formattedValue);
    this.#ui.telInputEl.setSelectionRange(newCaretPos, newCaretPos);
  }
  //* If separateDialCode AND typed dial code (e.g. from paste or autofill, or from typing a dial code when countrySearch disabled), then remove the typed dial code.
  //* Only strip when a full dial code is actually present — otherwise a lone typed "+" (or partial prefix) would get erased.
  #stripTypedDialCode(inputValue) {
    if (inputValue.startsWith("+") && this.#selectedCountry && this.#getDialCode(inputValue)) {
      const cleanNumber = stripSeparateDialCode(
        inputValue,
        true,
        true,
        this.#selectedCountry
      );
      this.#setTelInputValue(cleanNumber);
    }
  }
  #bindInputListener() {
    this.#userOverrideFormatting = REGEX.ALPHA_UNICODE.test(
      this.#getTelInputValue()
    );
    this.#ui.telInputEl.addEventListener(
      "input",
      this.#handleInputEvent,
      {
        signal: this.#abortController.signal
      }
    );
  }
  //* On input event: (1) Update selected country, (2) Format-as-you-type.
  //* Note that this fires AFTER the input is updated.
  #handleInputEvent = (e) => {
    const {
      strictMode,
      formatAsYouType,
      separateDialCode,
      allowDropdown,
      countrySearch
    } = this.#options;
    const detail = e?.detail;
    if (detail?.["isCountryChange"]) {
      return;
    }
    let inputValue = this.#getTelInputValue();
    const isPaste = e?.inputType === INPUT_TYPES.PASTE;
    const isStrictPaste = strictMode && isPaste;
    if (this.#isAndroid && !isPaste && e?.data === "+" && separateDialCode && allowDropdown && countrySearch) {
      this.#handleAndroidPlusKey(inputValue);
      return;
    }
    if (this.#isAndroid && !isPaste && strictMode && (e?.data === " " || e?.data === "-" || e?.data === ".")) {
      this.#handleAndroidStrictReject(inputValue, e.data);
      return;
    }
    if (isStrictPaste) {
      const didRejectPaste = this.#handleStrictPasteInputEvent();
      if (didRejectPaste) {
        return;
      }
      inputValue = this.#getTelInputValue();
    }
    if (this.#updateCountryFromNumber(inputValue)) {
      this.#dispatchCountryChangeEvent();
    }
    const isFormattingChar = !isStrictPaste && e?.data && REGEX.NON_PLUS_NUMERIC.test(e.data);
    const isNonStrictPaste = isPaste && inputValue && !strictMode;
    if (isFormattingChar || isNonStrictPaste) {
      this.#userOverrideFormatting = true;
    } else if (!REGEX.NON_PLUS_NUMERIC.test(inputValue)) {
      this.#userOverrideFormatting = false;
    }
    if (formatAsYouType && !this.#userOverrideFormatting && !detail?.["isSetNumber"] && this.#numerals.isAscii()) {
      this.#formatAsYouType(
        inputValue,
        e?.inputType === INPUT_TYPES.DELETE_FORWARD
      );
    }
    if (separateDialCode) {
      this.#stripTypedDialCode(inputValue);
    }
  };
  #bindKeydownListener() {
    const { strictMode, separateDialCode } = this.#options;
    if (!strictMode && !separateDialCode) {
      return;
    }
    this.#ui.telInputEl.addEventListener("keydown", this.#handleKeydownEvent, {
      signal: this.#abortController.signal
    });
  }
  //* On keydown event: (1) if strictMode then prevent invalid characters, (2) if separateDialCode then handle plus key
  //* Note that this fires BEFORE the input is updated.
  #handleKeydownEvent = (e) => {
    const { strictMode, separateDialCode, allowDropdown, countrySearch } = this.#options;
    if (!e.key || e.key.length !== 1 || e.altKey || e.ctrlKey || e.metaKey) {
      return;
    }
    if (separateDialCode && allowDropdown && countrySearch && e.key === "+") {
      e.preventDefault();
      this.#openDropdownWithPlus();
      return;
    }
    if (!strictMode) {
      return;
    }
    const inputValue = this.#getTelInputValue();
    const alreadyHasPlus = inputValue.startsWith("+");
    const isInitialPlus = !alreadyHasPlus && this.#ui.telInputEl.selectionStart === 0 && e.key === "+";
    const normalisedKey = this.#numerals.normalise(e.key);
    const isNumeric = /^[0-9]$/.test(normalisedKey);
    const isAllowedChar = separateDialCode ? isNumeric : isInitialPlus || isNumeric;
    const input = this.#ui.telInputEl;
    const selStart = input.selectionStart;
    const selEnd = input.selectionEnd;
    const before = inputValue.slice(0, selStart ?? void 0);
    const after = inputValue.slice(selEnd ?? void 0);
    const newValue = before + normalisedKey + after;
    const newFullNumber = this.#buildFullNumber(newValue);
    let hasExceededMaxLength = false;
    if (intlTelInput.utils && this.#maxCoreNumberLength) {
      const coreNumber = intlTelInput.utils.getCoreNumber(
        newFullNumber,
        this.#selectedCountry?.iso2
      );
      hasExceededMaxLength = coreNumber.length > this.#maxCoreNumberLength;
    }
    const newCountry = this.#resolveCountryChangeFromNumber(newFullNumber);
    const isChangingDialCode = newCountry !== null;
    if (!isAllowedChar || hasExceededMaxLength && !isChangingDialCode && !isInitialPlus) {
      this.#ui.playStrictRejectAnimation();
      this.#dispatchEvent(EVENTS.STRICT_REJECT, {
        source: "key",
        rejectedInput: e.key,
        reason: !isAllowedChar ? "invalid" : "max-length"
      });
      e.preventDefault();
    }
  };
  #bindStrictPasteListener() {
    if (!this.#options.strictMode) {
      return;
    }
    this.#ui.telInputEl.addEventListener("paste", this.#handleStrictPasteEvent, {
      signal: this.#abortController.signal
    });
  }
  // In strict mode, remember paste details before the browser inserts the pasted text.
  // The actual sanitisation runs on the following input event so native paste stays enabled.
  #handleStrictPasteEvent = (e) => {
    const input = this.#ui.telInputEl;
    const inputValue = this.#getTelInputValue();
    this.#strictPasteSnapshot = {
      pastedRaw: e.clipboardData?.getData("text") ?? "",
      value: inputValue,
      selectionStart: input.selectionStart ?? inputValue.length,
      selectionEnd: input.selectionEnd ?? inputValue.length
    };
  };
  // Handle paste input events when strictMode is enabled by sanitising the pasted content after
  // the browser inserts it, and rejecting it entirely if it would result in an invalid number.
  #handleStrictPasteInputEvent() {
    const input = this.#ui.telInputEl;
    const pasteSnapshot = this.#strictPasteSnapshot;
    this.#strictPasteSnapshot = null;
    if (!pasteSnapshot) {
      return false;
    }
    const pastedRaw = pasteSnapshot.pastedRaw;
    const originalValue = pasteSnapshot.value;
    const selStart = pasteSnapshot.selectionStart;
    const selEnd = pasteSnapshot.selectionEnd;
    const before = originalValue.slice(0, selStart);
    const after = originalValue.slice(selEnd);
    const iso2 = this.#selectedCountry?.iso2;
    const pasted = this.#numerals.normalise(pastedRaw);
    const initialCharSelected = selStart === 0 && selEnd > 0;
    const allowLeadingPlus = !originalValue.startsWith("+") || initialCharSelected;
    const allowedChars = pasted.replace(REGEX.NON_PLUS_NUMERIC_GLOBAL, "");
    const hasLeadingPlus = allowedChars.startsWith("+");
    const numerics = allowedChars.replace(/\+/g, "");
    const sanitised = hasLeadingPlus && allowLeadingPlus ? `+${numerics}` : numerics;
    let newValue = before + sanitised + after;
    let rejectReason = sanitised !== pasted ? "invalid" : null;
    if (newValue.length > 30) {
      this.#ui.playStrictRejectAnimation();
      this.#dispatchEvent(EVENTS.STRICT_REJECT, {
        source: "paste",
        rejectedInput: pastedRaw,
        reason: "max-length"
      });
      this.#restoreValueBeforeStrictPaste(pasteSnapshot);
      return true;
    }
    if (newValue.length > 5 && intlTelInput.utils) {
      let coreNumber = intlTelInput.utils.getCoreNumber(newValue, iso2);
      while (coreNumber.length === 0 && newValue.length > 0) {
        newValue = newValue.slice(0, -1);
        coreNumber = intlTelInput.utils.getCoreNumber(newValue, iso2);
      }
      if (!coreNumber) {
        this.#ui.playStrictRejectAnimation();
        this.#dispatchEvent(EVENTS.STRICT_REJECT, {
          source: "paste",
          rejectedInput: pastedRaw,
          reason: "max-length"
        });
        this.#restoreValueBeforeStrictPaste(pasteSnapshot);
        return true;
      }
      if (this.#maxCoreNumberLength && coreNumber.length > this.#maxCoreNumberLength) {
        if (selEnd === originalValue.length) {
          const trimLength = coreNumber.length - this.#maxCoreNumberLength;
          newValue = newValue.slice(0, newValue.length - trimLength);
          rejectReason = "max-length";
        } else {
          this.#ui.playStrictRejectAnimation();
          this.#dispatchEvent(EVENTS.STRICT_REJECT, {
            source: "paste",
            rejectedInput: pastedRaw,
            reason: "max-length"
          });
          this.#restoreValueBeforeStrictPaste(pasteSnapshot);
          return true;
        }
      }
    }
    this.#setTelInputValue(newValue);
    const caretPos = selStart + sanitised.length;
    input.setSelectionRange(caretPos, caretPos);
    if (rejectReason) {
      if (pasted.length > 0 && sanitised.length === 0) {
        this.#ui.playStrictRejectAnimation();
      }
      this.#dispatchEvent(EVENTS.STRICT_REJECT, {
        source: "paste",
        rejectedInput: pastedRaw,
        reason: rejectReason
      });
    }
    return false;
  }
  #restoreValueBeforeStrictPaste(pasteSnapshot) {
    this.#setTelInputValue(pasteSnapshot.value);
    this.#ui.telInputEl.setSelectionRange(
      pasteSnapshot.selectionStart,
      pasteSnapshot.selectionEnd
    );
  }
  //* Adhere to the input's maxlength attr.
  #truncateToMaxLength(number) {
    const max = Number(this.#ui.telInputEl.getAttribute("maxlength"));
    return max && number.length > max ? number.substring(0, max) : number;
  }
  //* Trigger a custom event on the input (typed via ItiEventMap).
  #dispatchEvent(name, detailProps = {}) {
    const e = new CustomEvent(name, {
      bubbles: true,
      cancelable: true,
      detail: detailProps
    });
    this.#ui.telInputEl.dispatchEvent(e);
  }
  //* Open the dropdown. Bail if already open — otherwise the existing AbortController gets overwritten
  //* and its listeners leak. Reachable via openDropdownWithPlus when dropdownAlwaysOpen is set
  #openDropdown() {
    if (this.#ui.isDropdownOpen()) {
      return;
    }
    this.#ui.openDropdown(
      (li) => this.#selectListItem(li),
      () => this.#closeDropdown()
    );
    this.#dispatchEvent(EVENTS.OPEN_COUNTRY_DROPDOWN);
  }
  //* Update the input's value to the given number (format first if possible)
  //* NOTE: this is called from setInitialState, handleUtilsLoaded and setNumber.
  #updateValueFromNumber(fullNumber) {
    const { formatOnDisplay, nationalMode, separateDialCode } = this.#options;
    let number = fullNumber;
    if (formatOnDisplay && intlTelInput.utils && this.#selectedCountry) {
      const isRegionless = hasRegionlessDialCode(fullNumber);
      const useNational = nationalMode && !isRegionless || !number.startsWith("+") && !separateDialCode;
      const format = useNational ? NUMBER_FORMAT.NATIONAL : NUMBER_FORMAT.INTERNATIONAL;
      number = intlTelInput.utils.formatNumber(
        number,
        this.#selectedCountry?.iso2,
        format
      );
    }
    number = this.#prepareNumberForInput(number);
    this.#setTelInputValue(number);
  }
  //* Check if need to select a new country based on the given number
  //* Note: called from setInitialState, keyup handler, setNumber.
  #updateCountryFromNumber(fullNumber) {
    const iso2 = this.#resolveCountryChangeFromNumber(fullNumber);
    if (iso2 !== null) {
      return this.#updateSelectedCountry(iso2);
    }
    return false;
  }
  // if there is a selected country, and the number doesn't start with a dial code, then add it
  #withDialCodePrefix(number) {
    const dialCode = this.#selectedCountry?.dialCode;
    const nationalPrefix = this.#selectedCountry?.nationalPrefix;
    const alreadyHasPlus = number.startsWith("+");
    if (alreadyHasPlus || !dialCode) {
      return number;
    }
    const hasPrefix = nationalPrefix && number.startsWith(nationalPrefix) && !this.#options.separateDialCode;
    const cleanNumber = hasPrefix ? number.substring(1) : number;
    return `+${dialCode}${cleanNumber}`;
  }
  //* Get the new country iso2 (or "" for empty/globe state) based on the input number, or return null if no change.
  #resolveCountryChangeFromNumber(fullNumber) {
    const plusIndex = fullNumber.indexOf("+");
    let number = plusIndex > 0 ? fullNumber.substring(plusIndex) : fullNumber;
    const selectedIso2 = this.#selectedCountry?.iso2;
    number = this.#withDialCodePrefix(number);
    const dialCodeMatch = this.#getDialCode(number, true);
    const numeric = getNumeric(number);
    if (dialCodeMatch) {
      const dialCodeMatchNumeric = getNumeric(dialCodeMatch);
      const iso2Codes = this.#dialCodeToIso2Map[dialCodeMatchNumeric];
      if (iso2Codes.length === 1) {
        if (iso2Codes[0] === selectedIso2) {
          return null;
        }
        return iso2Codes[0];
      }
      return this.#resolveCountryChangeFromMultiMatch(
        iso2Codes,
        dialCodeMatchNumeric,
        numeric
      );
    } else if (number.startsWith("+") && numeric.length) {
      const currentDial = this.#selectedCountry?.dialCode || "";
      if (currentDial && currentDial.startsWith(numeric)) {
        return null;
      }
      return "";
    } else if ((!number || number === "+") && !selectedIso2 && this.#fallbackCountryIso2) {
      return this.#fallbackCountryIso2;
    }
    return null;
  }
  //* Resolve the country when multiple countries share the matched dial code.
  #resolveCountryChangeFromMultiMatch(iso2Codes, dialCodeMatchNumeric, numeric) {
    const selectedIso2 = this.#selectedCountry?.iso2;
    const selectedDialCode = this.#selectedCountry?.dialCode;
    if (!selectedIso2 && this.#fallbackCountryIso2 && iso2Codes.includes(this.#fallbackCountryIso2)) {
      return this.#fallbackCountryIso2;
    }
    const isRegionlessNanpNumber = selectedDialCode === DIAL_CODE.NANP && isRegionlessNanp(numeric);
    if (isRegionlessNanpNumber) {
      return null;
    }
    const areaCodes = this.#selectedCountry?.areaCodes;
    const priority = this.#selectedCountry?.priority;
    if (areaCodes) {
      const dialCodeAreaCodes = areaCodes.map(
        (areaCode) => `${selectedDialCode}${areaCode}`
      );
      for (const dialCodeAreaCode of dialCodeAreaCodes) {
        if (numeric.startsWith(dialCodeAreaCode)) {
          return null;
        }
      }
    }
    const isMainCountry = priority === 0;
    const hasAreaCodesButNoneMatched = areaCodes && !isMainCountry && numeric.length > dialCodeMatchNumeric.length;
    const isValidSelection = selectedIso2 && iso2Codes.includes(selectedIso2) && !hasAreaCodesButNoneMatched;
    const alreadySelected = selectedIso2 === iso2Codes[0];
    if (!isValidSelection && !alreadySelected) {
      return iso2Codes[0];
    }
    return null;
  }
  //* Update the selected country, dial code (if separateDialCode), placeholder, title, and selected list item.
  //* Note: called from setInitialState, updateCountryFromNumber, selectListItem, setCountry.
  #updateSelectedCountry(iso2) {
    const prevIso2 = this.#selectedCountry?.iso2 || "";
    this.#selectedCountry = iso2 ? this.#countryByIso2.get(iso2) : null;
    if (this.#selectedCountry) {
      this.#fallbackCountryIso2 = this.#selectedCountry.iso2;
    }
    this.#ui.setCountry(this.#selectedCountry);
    this.#updatePlaceholder();
    this.#updateMaxCoreNumberLength();
    return prevIso2 !== iso2;
  }
  //* Update the maximum valid number length for the currently selected country.
  #updateMaxCoreNumberLength() {
    const { strictMode, placeholderNumberType, allowedNumberTypes } = this.#options;
    if (!strictMode || !intlTelInput.utils) {
      return;
    }
    const iso2 = this.#selectedCountry?.iso2;
    if (!iso2) {
      this.#maxCoreNumberLength = null;
      return;
    }
    let exampleNumber = intlTelInput.utils.getExampleNumber(
      iso2,
      false,
      placeholderNumberType,
      true
    );
    let validNumber = exampleNumber;
    while (intlTelInput.utils.isPossibleNumber(
      exampleNumber,
      iso2,
      allowedNumberTypes
    )) {
      validNumber = exampleNumber;
      exampleNumber += "0";
    }
    const coreNumber = intlTelInput.utils.getCoreNumber(validNumber, iso2);
    this.#maxCoreNumberLength = coreNumber.length;
    if (iso2 === "by") {
      this.#maxCoreNumberLength = coreNumber.length + 1;
    }
  }
  //* Update the input placeholder to an example number from the currently selected country.
  #updatePlaceholder() {
    const {
      autoPlaceholder,
      placeholderNumberType,
      nationalMode,
      customPlaceholder
    } = this.#options;
    const shouldSetPlaceholder = autoPlaceholder === PLACEHOLDER_MODES.AGGRESSIVE || !this.#ui.hadInitialPlaceholder && autoPlaceholder === PLACEHOLDER_MODES.POLITE;
    if (!intlTelInput.utils || !shouldSetPlaceholder) {
      return;
    }
    let placeholder = this.#selectedCountry ? intlTelInput.utils.getExampleNumber(
      this.#selectedCountry.iso2,
      nationalMode,
      placeholderNumberType
    ) : "";
    placeholder = this.#prepareNumberForInput(placeholder);
    if (typeof customPlaceholder === "function") {
      placeholder = customPlaceholder(placeholder, this.#selectedCountry);
    }
    this.#ui.telInputEl.setAttribute("placeholder", placeholder);
  }
  //* Called when the user selects a list item from the dropdown (no-op if listItem is null).
  #selectListItem(listItem) {
    if (!listItem) {
      return;
    }
    const iso2 = listItem.dataset[DATA_KEYS.ISO2];
    const countryChanged = this.#updateSelectedCountry(iso2);
    this.#closeDropdown();
    const dialCode = listItem.dataset[DATA_KEYS.DIAL_CODE];
    this.#updateDialCode(dialCode);
    if (this.#options.formatOnDisplay) {
      const inputValue = this.#getTelInputValue();
      this.#updateValueFromNumber(inputValue);
    }
    this.#ui.telInputEl.focus();
    if (countryChanged) {
      this.#dispatchCountryChangeEvent();
      this.#dispatchEvent(EVENTS.INPUT, { isCountryChange: true });
    }
  }
  //* Close the dropdown and unbind any listeners.
  #closeDropdown(isDestroy) {
    if (!this.#ui.isDropdownOpen() || this.#options.dropdownAlwaysOpen && !isDestroy) {
      return;
    }
    this.#ui.closeDropdown();
    this.#dispatchEvent(EVENTS.CLOSE_COUNTRY_DROPDOWN);
  }
  //* Replace any existing dial code with the new one
  //* Note: called from selectListItem and setCountry
  #updateDialCode(newDialCodeDigits) {
    const inputValue = this.#getTelInputValue();
    if (!inputValue.startsWith("+")) {
      return;
    }
    const newDialCode = `+${newDialCodeDigits}`;
    const prevDialCode = this.#getDialCode(inputValue);
    let newNumber;
    if (prevDialCode) {
      newNumber = inputValue.replace(prevDialCode, newDialCode);
    } else {
      newNumber = newDialCode;
    }
    this.#setTelInputValue(newNumber);
  }
  //* Try and extract a valid international dial code from a full telephone number.
  //* Note: returns the raw string inc plus character and any whitespace/dots etc.
  #getDialCode(number, includeAreaCode) {
    if (!number.startsWith("+")) {
      return "";
    }
    let dialCode = "";
    let numericChars = "";
    let foundBaseDialCode = false;
    for (let i = 0; i < number.length; i++) {
      const c = number.charAt(i);
      if (!/[0-9]/.test(c)) {
        continue;
      }
      numericChars += c;
      const hasMapEntry = Boolean(this.#dialCodeToIso2Map[numericChars]);
      if (!hasMapEntry) {
        break;
      }
      if (this.#dialCodes.has(numericChars)) {
        dialCode = number.substring(0, i + 1);
        foundBaseDialCode = true;
        if (!includeAreaCode) {
          break;
        }
      } else if (includeAreaCode && foundBaseDialCode) {
        dialCode = number.substring(0, i + 1);
      }
      if (numericChars.length === this.#dialCodeMaxLength) {
        break;
      }
    }
    return dialCode;
  }
  //* Build a full number from an already-normalised value, adding the dial code if separateDialCode is enabled.
  #buildFullNumber(value) {
    const dialCode = this.#selectedCountry?.dialCode;
    const numericValue = getNumeric(value);
    const usePrefix = this.#options.separateDialCode && !value.startsWith("+") && dialCode && numericValue;
    return (usePrefix ? `+${dialCode}` : "") + value;
  }
  //* Get the input value as a full number, adding the dial code if separateDialCode is enabled.
  #getFullNumber() {
    const value = this.#getTelInputValue();
    return this.#buildFullNumber(value);
  }
  //* Remove the dial code if separateDialCode is enabled also cap the length if the input has a maxlength attribute
  #prepareNumberForInput(fullNumber) {
    const hasValidDialCode = Boolean(this.#getDialCode(fullNumber));
    const number = stripSeparateDialCode(
      fullNumber,
      hasValidDialCode,
      this.#options.separateDialCode,
      this.#selectedCountry
    );
    return this.#truncateToMaxLength(number);
  }
  //* Dispatch the 'countrychange' event.
  #dispatchCountryChangeEvent() {
    this.#dispatchEvent(EVENTS.COUNTRY_CHANGE, this.#selectedCountry ?? null);
  }
  //**************************
  //*  INTERNAL METHODS
  //**************************
  //* Called when the geoip call returns.
  #handleAutoCountryLoaded() {
    if (!this.#autoCountryDeferred || !intlTelInput.autoCountry) {
      return;
    }
    if (!this.#isActive) {
      this.#autoCountryDeferred.resolve();
      return;
    }
    if (this.#ui.isLoading()) {
      this.setCountry(intlTelInput.autoCountry);
    } else {
      this.#fallbackCountryIso2 = intlTelInput.autoCountry;
    }
    this.#ui.setLoading(false);
    this.#autoCountryDeferred.resolve();
  }
  //* Called when the geoip call fails or times out.
  #handleAutoCountryFailure() {
    if (!this.#isActive) {
      this.#autoCountryDeferred?.reject();
      return;
    }
    this.#setInitialState(true);
    this.#ui.setLoading(false);
    this.#autoCountryDeferred?.reject();
  }
  //* Called when the utils request completes.
  #handleUtilsLoaded() {
    if (!this.#isActive) {
      this.#utilsDeferred?.resolve();
      return;
    }
    if (!intlTelInput.utils) {
      this.#utilsDeferred?.resolve();
      return;
    }
    const inputValue = this.#getTelInputValue();
    if (inputValue) {
      this.#updateValueFromNumber(inputValue);
    }
    if (this.#selectedCountry) {
      this.#updatePlaceholder();
      this.#updateMaxCoreNumberLength();
    }
    this.#utilsDeferred?.resolve();
  }
  //* Called when the utils request fails or times out.
  #handleUtilsFailure(error) {
    if (!this.#isActive) {
      this.#utilsDeferred?.reject(error);
      return;
    }
    this.#utilsDeferred?.reject(error);
  }
  //********************
  //*  PUBLIC METHODS
  //********************
  //* Remove core library.
  destroy() {
    if (!this.#isActive) {
      return;
    }
    this.#isActive = false;
    if (this.#options.allowDropdown) {
      this.#closeDropdown(true);
    }
    this.#abortController.abort();
    this.#ui.destroy();
    intlTelInput.instances.delete(String(this.id));
  }
  // check if the instance is still valid (not destroyed)
  isActive() {
    return this.#isActive;
  }
  //* Get the extension from the current number.
  getExtension() {
    if (!this.#isActive) {
      return "";
    }
    ensureUtils("getExtension");
    return intlTelInput.utils.getExtension(
      this.#getFullNumber(),
      this.#selectedCountry?.iso2
    );
  }
  //* Format the number to the given format (defaults to "E164").
  getNumber(format) {
    if (!this.#isActive) {
      return "";
    }
    ensureUtils("getNumber");
    const iso2 = this.#selectedCountry?.iso2;
    const fullNumber = this.#getFullNumber();
    const formattedNumber = intlTelInput.utils.formatNumber(
      fullNumber,
      iso2,
      format
    );
    return this.#numerals.denormalise(formattedNumber);
  }
  //* Get the type of the entered number e.g. "FIXED_LINE" / "MOBILE", or null if it can't be determined / instance is destroyed.
  getNumberType() {
    if (!this.#isActive) {
      return null;
    }
    ensureUtils("getNumberType");
    return intlTelInput.utils.getNumberType(
      this.#getFullNumber(),
      this.#selectedCountry?.iso2
    );
  }
  //* Get the country data for the currently selected country.
  getSelectedCountryData() {
    return this.#selectedCountry ?? null;
  }
  //* Get the validation error e.g. "TOO_SHORT" / "TOO_LONG", or null if it can't be determined / instance is destroyed.
  getValidationError() {
    if (!this.#isActive) {
      return null;
    }
    ensureUtils("getValidationError");
    const iso2 = this.#selectedCountry?.iso2;
    return intlTelInput.utils.getValidationError(this.#getFullNumber(), iso2);
  }
  //* Validate the input value using number length only
  isValidNumber() {
    if (!this.#isActive) {
      return null;
    }
    ensureUtils("isValidNumber");
    const dialCode = this.#selectedCountry?.dialCode;
    const iso2 = this.#selectedCountry?.iso2;
    const number = this.#getFullNumber();
    const coreNumber = intlTelInput.utils.getCoreNumber(number, iso2);
    if (coreNumber) {
      if (dialCode === UK.DIAL_CODE) {
        if (coreNumber[0] === UK.MOBILE_PREFIX && coreNumber.length !== UK.MOBILE_CORE_LENGTH) {
          return false;
        }
      }
      const hasAlphaChar = REGEX.ALPHA_UNICODE.test(number);
      if (!hasAlphaChar && dialCode) {
        const nationalPortion = number.startsWith("+") ? number.slice(1 + dialCode.length) : number;
        const nationalDigitCount = getNumeric(nationalPortion).length;
        if (coreNumber.length > nationalDigitCount) {
          return false;
        }
      }
    }
    return this.#validateNumber("possible");
  }
  //* Validate the input value with precise validation
  isValidNumberPrecise() {
    if (!this.#isActive) {
      return null;
    }
    ensureUtils("isValidNumberPrecise");
    return this.#validateNumber("precise");
  }
  //* Shared internal validation logic to handle alpha character extension rules.
  #validateNumber(mode) {
    const { allowNumberExtensions, allowPhonewords, allowedNumberTypes } = this.#options;
    const iso2 = this.#selectedCountry?.iso2;
    const value = this.#getFullNumber();
    if (!this.#selectedCountry && !hasRegionlessDialCode(value)) {
      return false;
    }
    const check = mode === "precise" ? intlTelInput.utils.isValidNumber : intlTelInput.utils.isPossibleNumber;
    if (!check(value, iso2, allowedNumberTypes)) {
      return false;
    }
    if (REGEX.ALPHA_UNICODE.test(value)) {
      const hasExtension = Boolean(
        intlTelInput.utils.getExtension(value, iso2)
      );
      return hasExtension ? allowNumberExtensions : allowPhonewords;
    }
    return true;
  }
  //* Update the selected country, and update the input value accordingly.
  setCountry(iso2) {
    if (!this.#isActive) {
      return;
    }
    const iso2Lower = iso2?.toLowerCase();
    if (!isIso2(iso2Lower)) {
      throw new Error(`Invalid iso2 code: '${iso2Lower}'`);
    }
    const currentCountry = this.#selectedCountry?.iso2;
    const isCountryChange = iso2 && iso2Lower !== currentCountry || !iso2 && currentCountry;
    if (!isCountryChange) {
      return;
    }
    this.#updateSelectedCountry(iso2Lower);
    this.#updateDialCode(this.#selectedCountry?.dialCode || "");
    if (this.#options.formatOnDisplay) {
      const inputValue = this.#getTelInputValue();
      this.#updateValueFromNumber(inputValue);
    }
    this.#dispatchCountryChangeEvent();
    this.#dispatchEvent(EVENTS.INPUT, { isCountryChange: true });
  }
  //* Set the input value and update the country.
  setNumber(number) {
    if (!this.#isActive) {
      return;
    }
    const normalisedNumber = this.#numerals.normalise(number);
    const countryChanged = this.#updateCountryFromNumber(normalisedNumber);
    this.#updateValueFromNumber(normalisedNumber);
    if (countryChanged) {
      this.#dispatchCountryChangeEvent();
    }
    this.#dispatchEvent(EVENTS.INPUT, { isSetNumber: true });
  }
  //* Set the placeholder number type
  setPlaceholderNumberType(type) {
    if (!this.#isActive) {
      return;
    }
    this.#options.placeholderNumberType = type;
    this.#updatePlaceholder();
  }
  // Set the disabled state of the input and dropdown.
  setDisabled(disabled) {
    if (!this.#isActive) {
      return;
    }
    this.#ui.setDisabled(disabled);
  }
  // Set the readonly state of the input and dropdown.
  setReadonly(readonly) {
    if (!this.#isActive) {
      return;
    }
    this.#ui.setReadonly(readonly);
  }
  //********************
  //*  STATIC METHODS
  //********************
  // Internal instance notification used by utils/geoip loaders.
  // Kept public so module-level helpers (e.g. attachUtils) can call it, while still allowing
  // access to private instance methods.
  static forEachInstance(method, ...args) {
    const values = [...intlTelInput.instances.values()];
    const arg = args[0];
    values.forEach((instance) => {
      if (!(instance instanceof _Iti)) {
        return;
      }
      switch (method) {
        case "handleUtilsLoaded":
          instance.#handleUtilsLoaded();
          break;
        case "handleUtilsFailure":
          instance.#handleUtilsFailure(arg);
          break;
        case "handleAutoCountryLoaded":
          instance.#handleAutoCountryLoaded();
          break;
        case "handleAutoCountryFailure":
          instance.#handleAutoCountryFailure();
          break;
      }
    });
  }
};
var attachUtils = async (source) => {
  if (intlTelInput.utils || intlTelInput.startedLoadingUtils) {
    return null;
  }
  if (typeof source !== "function") {
    throw new TypeError(
      `The argument passed to attachUtils must be a function that returns a promise for the utils module, not ${typeof source}`
    );
  }
  intlTelInput.startedLoadingUtils = true;
  try {
    const module = await source();
    const utils = module?.default;
    if (!utils || typeof utils !== "object") {
      throw new TypeError(
        "The loader function passed to attachUtils did not resolve to a module object with utils as its default export."
      );
    }
    intlTelInput.utils = utils;
    Iti.forEachInstance("handleUtilsLoaded");
    return true;
  } catch (error) {
    Iti.forEachInstance("handleUtilsFailure", error);
    throw error;
  }
};
var intlTelInput = Object.assign(
  (input, options) => {
    const iti = new Iti(input, options);
    intlTelInput.instances.set(String(iti.id), iti);
    input.iti = iti;
    return iti;
  },
  {
    defaults,
    //* Using a static var like this allows us to mock it in the tests.
    documentReady: () => document.readyState === "complete",
    //* Get the country data object.
    getCountryData: () => data_default,
    //* A getter for the core library instance.
    getInstance: (input) => {
      const id = input.dataset[DATA_KEYS.INSTANCE_ID];
      return id ? intlTelInput.instances.get(id) ?? null : null;
    },
    //* A map from instance ID to instance object.
    instances: /* @__PURE__ */ new Map(),
    attachUtils,
    startedLoadingUtils: false,
    startedLoadingAutoCountry: false,
    version: "28.1.0",
    NUMBER_FORMAT,
    NUMBER_TYPE,
    VALIDATION_ERROR
  }
);
var intlTelInput_default = intlTelInput;
export {
  Iti,
  NUMBER_FORMAT,
  NUMBER_TYPE,
  VALIDATION_ERROR,
  intlTelInput_default as default
};
