Merge pull request #80 from googlei18n/update_country_info
(AUTOMATIC) exporting changes for github
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/AddressDataKey.java b/common/src/main/java/com/google/i18n/addressinput/common/AddressDataKey.java
index b1bd52a..a74a699 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/AddressDataKey.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/AddressDataKey.java
@@ -110,7 +110,7 @@
* matches.
*/
static AddressDataKey get(String keyname) {
- return ADDRESS_KEY_NAME_MAP.get(keyname.toLowerCase());
+ return ADDRESS_KEY_NAME_MAP.get(Util.toLowerCaseLocaleIndependent(keyname));
}
private static final Map<String, AddressDataKey> ADDRESS_KEY_NAME_MAP =
@@ -119,7 +119,7 @@
static {
// Populates the map of enums against their lower-cased string values for easy look-up.
for (AddressDataKey field : values()) {
- ADDRESS_KEY_NAME_MAP.put(field.toString().toLowerCase(), field);
+ ADDRESS_KEY_NAME_MAP.put(Util.toLowerCaseLocaleIndependent(field.toString()), field);
}
}
}
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/AddressProblemType.java b/common/src/main/java/com/google/i18n/addressinput/common/AddressProblemType.java
index 7caae40..5afdbe9 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/AddressProblemType.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/AddressProblemType.java
@@ -70,6 +70,6 @@
* Returns a unique string identifying this problem (for use in a message catalog).
*/
public String keyname() {
- return name().toLowerCase();
+ return Util.toLowerCaseLocaleIndependent(name());
}
}
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/CacheData.java b/common/src/main/java/com/google/i18n/addressinput/common/CacheData.java
index 76ce2f7..24f5c83 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/CacheData.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/CacheData.java
@@ -195,7 +195,7 @@
}
JSONObject json = map;
- String idKey = AddressDataKey.ID.name().toLowerCase();
+ String idKey = Util.toLowerCaseLocaleIndependent(AddressDataKey.ID.name());
if (!json.has(idKey)) {
logger.warning("invalid or empty data returned for key: " + key);
badKeys.add(key);
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/ClientData.java b/common/src/main/java/com/google/i18n/addressinput/common/ClientData.java
index 5b42aaf..2b0578d 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/ClientData.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/ClientData.java
@@ -114,7 +114,7 @@
continue;
}
- String value = jso.get(key.toString().toLowerCase());
+ String value = jso.get(Util.toLowerCaseLocaleIndependent(key.toString()));
map.put(key, value);
} catch (JSONException e) {
// This should not happen - we should not be fetching a key from outside the bounds
@@ -241,8 +241,8 @@
@Override
public void dataLoadingEnd() {
- final String subKeys = AddressDataKey.SUB_KEYS.name().toLowerCase();
- final String subMores = AddressDataKey.SUB_MORES.name().toLowerCase();
+ final String subKeys = Util.toLowerCaseLocaleIndependent(AddressDataKey.SUB_KEYS.name());
+ final String subMores = Util.toLowerCaseLocaleIndependent(AddressDataKey.SUB_MORES.name());
JsoMap map = cacheData.getObj(key);
// It is entirely possible that data loading failed and that the map is null.
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/FieldVerifier.java b/common/src/main/java/com/google/i18n/addressinput/common/FieldVerifier.java
index 9d96ae3..a281797 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/FieldVerifier.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/FieldVerifier.java
@@ -184,7 +184,8 @@
// TODO: We should have a class that knows how to get information about the data, rather than
// getting the node and extracting keys here.
LookupKey lookupKey =
- new LookupKey.Builder(KeyType.DATA.name().toLowerCase() + KEY_NODE_DELIMITER
+ new LookupKey.Builder(Util.toLowerCaseLocaleIndependent(KeyType.DATA.name())
+ + KEY_NODE_DELIMITER
+ regionCode).build();
AddressVerificationNodeData countryNode = dataSource.getDefaultData(lookupKey.toString());
String languages = countryNode.get(AddressDataKey.LANGUAGES);
@@ -337,7 +338,8 @@
String trimmedValue = Util.trimToNull(value);
Util.checkNotNull(trimmedValue);
if (script == null) {
- return (candidateValues == null || candidateValues.containsKey(trimmedValue.toLowerCase()));
+ return (candidateValues == null || candidateValues.containsKey(
+ Util.toLowerCaseLocaleIndependent(trimmedValue)));
}
// Otherwise, if we know the script, we want to restrict the candidates to only names in
// that script.
@@ -345,12 +347,12 @@
Set<String> candidates = new HashSet<String>();
if (namesToConsider != null) {
for (String name : namesToConsider) {
- candidates.add(name.toLowerCase());
+ candidates.add(Util.toLowerCaseLocaleIndependent(name));
}
}
if (keys != null) {
for (String name : keys) {
- candidates.add(name.toLowerCase());
+ candidates.add(Util.toLowerCaseLocaleIndependent(name));
}
}
@@ -358,7 +360,7 @@
return true;
}
- return candidates.contains(value.toLowerCase());
+ return candidates.contains(Util.toLowerCaseLocaleIndependent(value));
}
/**
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java b/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
index 89c9bef..0d63816 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
@@ -140,7 +140,7 @@
throw new NullPointerException();
}
// TODO(addresswidget-team): Add region code validation against RegionDataConstants.
- blacklistedRegions.add(regionCode.toUpperCase(Locale.ENGLISH));
+ blacklistedRegions.add(Util.toUpperCaseLocaleIndependent(regionCode));
return this;
}
@@ -183,7 +183,7 @@
}
boolean isBlacklistedRegion(String regionCode) {
- return blacklistedRegions.contains(regionCode.toUpperCase(Locale.ENGLISH));
+ return blacklistedRegions.contains(Util.toUpperCaseLocaleIndependent(regionCode));
}
}
}
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/FormatInterpreter.java b/common/src/main/java/com/google/i18n/addressinput/common/FormatInterpreter.java
index 104d9dc..1c7673e 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/FormatInterpreter.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/FormatInterpreter.java
@@ -270,12 +270,12 @@
try {
JSONObject jsonObj = new JSONObject(new JSONTokener(jsonString));
- if (!jsonObj.has(key.name().toLowerCase())) {
+ if (!jsonObj.has(Util.toLowerCaseLocaleIndependent(key.name()))) {
// Key not found. Return null.
return null;
}
// Gets the string for this key.
- String parsedJsonString = jsonObj.getString(key.name().toLowerCase());
+ String parsedJsonString = jsonObj.getString(Util.toLowerCaseLocaleIndependent(key.name()));
return parsedJsonString;
} catch (JSONException e) {
throw new RuntimeException("Invalid json for region code " + regionCode + ": " + jsonString);
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/LookupKey.java b/common/src/main/java/com/google/i18n/addressinput/common/LookupKey.java
index e58451a..8c502c1 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/LookupKey.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/LookupKey.java
@@ -205,7 +205,7 @@
* Creates the string format of the given key. E.g., "data/US/CA".
*/
private String createKeyString() {
- StringBuilder keyBuilder = new StringBuilder(keyType.name().toLowerCase());
+ StringBuilder keyBuilder = new StringBuilder(Util.toLowerCaseLocaleIndependent(keyType.name()));
if (keyType == KeyType.DATA) {
for (AddressField field : HIERARCHY) {
@@ -224,7 +224,7 @@
keyBuilder.append(SLASH_DELIM)
.append(nodes.get(AddressField.COUNTRY))
.append(SLASH_DELIM)
- .append(scriptType.name().toLowerCase())
+ .append(Util.toLowerCaseLocaleIndependent(scriptType.name()))
.append(SLASH_DELIM)
.append(DEFAULT_LANGUAGE);
}
@@ -260,7 +260,7 @@
static boolean hasValidKeyPrefix(String key) {
for (KeyType type : KeyType.values()) {
- if (key.startsWith(type.name().toLowerCase())) {
+ if (key.startsWith(Util.toLowerCaseLocaleIndependent(type.name()))) {
return true;
}
}
@@ -315,8 +315,8 @@
*/
public Builder(String keyString) {
String[] parts = keyString.split(SLASH_DELIM);
- if (!parts[0].equals(KeyType.DATA.name().toLowerCase())
- && !parts[0].equals(KeyType.EXAMPLES.name().toLowerCase())) {
+ if (!parts[0].equals(Util.toLowerCaseLocaleIndependent(KeyType.DATA.name()))
+ && !parts[0].equals(Util.toLowerCaseLocaleIndependent(KeyType.EXAMPLES.name()))) {
throw new RuntimeException("Wrong key type: " + parts[0]);
}
if (parts.length > HIERARCHY.length + 1) {
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/RegionDataConstants.java b/common/src/main/java/com/google/i18n/addressinput/common/RegionDataConstants.java
index c0e5a40..4fd6b3e 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/RegionDataConstants.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/RegionDataConstants.java
@@ -40,7 +40,6 @@
"lang", "ca",
"languages", "ca",
"fmt", "%N%n%O%n%A%n%Z %C",
- "require", "A",
}),
AE(new String[]{
"name", "UNITED ARAB EMIRATES",
@@ -48,7 +47,7 @@
"languages", "ar",
"fmt", "%N%n%O%n%A%n%S",
"lfmt", "%N%n%O%n%A%n%S",
- "require", "A",
+ "require", "AS",
"state_name_type", "emirate",
}),
AF(new String[]{
@@ -561,6 +560,11 @@
"require", "ACS",
"upper", "CS",
}),
+ IR(new String[]{
+ "name", "IRAN",
+ "fmt", "%O%n%N%n%S%n%C, %D%n%A%n%Z",
+ "sublocality_name_type", "neighborhood",
+ }),
IS(new String[]{
"name", "ICELAND",
"fmt", "%N%n%O%n%A%n%Z %C",
@@ -748,6 +752,10 @@
ML(new String[]{
"name", "MALI",
}),
+ MM(new String[]{
+ "name", "MYANMAR",
+ "fmt", "%N%n%O%n%A%n%C, %Z",
+ }),
MN(new String[]{
"name", "MONGOLIA",
"fmt", "%N%n%O%n%A%n%S %C-%X%n%Z",
@@ -1070,13 +1078,13 @@
"fmt", "%N%n%O%n%A%n%C %X%n%S",
"upper", "AS",
}),
+ SS(new String[]{
+ "name", "SOUTH SUDAN",
+ }),
ST(new String[]{
"name", "SAO TOME AND PRINCIPE",
"fmt", "%N%n%O%n%A%n%C %X",
}),
- SX(new String[]{
- "name", "SINT MAARTEN"
- }),
SV(new String[]{
"name", "EL SALVADOR",
"lang", "es",
@@ -1085,6 +1093,9 @@
"require", "ACS",
"upper", "CSZ",
}),
+ SX(new String[]{
+ "name", "SINT MAARTEN",
+ }),
SZ(new String[]{
"name", "SWAZILAND",
"fmt", "%N%n%O%n%A%n%C%n%Z",
@@ -1169,9 +1180,9 @@
"name", "TANZANIA (UNITED REP.)",
}),
UA(new String[]{
+ "name", "UKRAINE",
"lang", "uk",
"languages", "uk",
- "name", "UKRAINE",
"fmt", "%N%n%O%n%A%n%C%n%S%n%Z",
"lfmt", "%N%n%O%n%A%n%C%n%S%n%Z",
"require", "ACZ",
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/Util.java b/common/src/main/java/com/google/i18n/addressinput/common/Util.java
index f816186..c63d93e 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/Util.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/Util.java
@@ -69,7 +69,7 @@
*/
public static boolean isExplicitLatinScript(String languageCode) {
// Convert to upper-case for easier comparison.
- languageCode = languageCode.toUpperCase();
+ languageCode = toUpperCaseLocaleIndependent(languageCode);
// Check to see if the language code contains a script modifier.
final Pattern languageCodePattern = Pattern.compile("\\w{2,3}[-_](\\w{4})");
Matcher m = languageCodePattern.matcher(languageCode);
@@ -91,7 +91,7 @@
final Pattern languageCodePattern = Pattern.compile("(\\w{2,3})(?:[-_]\\w{4})?(?:[-_]\\w{2})?");
Matcher m = languageCodePattern.matcher(languageCode);
if (m.matches()) {
- return m.group(1).toLowerCase();
+ return toLowerCaseLocaleIndependent(m.group(1));
}
return "und";
}
@@ -160,7 +160,7 @@
int keyLength = keys.length;
for (String k : keys) {
- nameToKeyMap.put(k.toLowerCase(), k);
+ nameToKeyMap.put(toLowerCaseLocaleIndependent(k), k);
}
if (names != null) {
if (names.length > keyLength) {
@@ -173,7 +173,7 @@
// behave differently in the default case. Since missing names are fine, we opt to
// be more robust here.
if (i < names.length && names[i].length() > 0) {
- nameToKeyMap.put(names[i].toLowerCase(), keys[i]);
+ nameToKeyMap.put(toLowerCaseLocaleIndependent(names[i]), keys[i]);
}
}
}
@@ -184,7 +184,7 @@
}
for (int i = 0; i < keyLength; i++) {
if (i < lnames.length && lnames[i].length() > 0) {
- nameToKeyMap.put(lnames[i].toLowerCase(), keys[i]);
+ nameToKeyMap.put(toLowerCaseLocaleIndependent(lnames[i]), keys[i]);
}
}
}
@@ -203,7 +203,7 @@
* "en-US").
*/
public static String getWidgetCompatibleLanguageCode(Locale language, String currentCountry) {
- String country = currentCountry.toUpperCase();
+ String country = toUpperCaseLocaleIndependent(currentCountry);
// Only do something if the country is one of those where we have names in the local
// language as well as in latin script.
if (nonLatinLocalLanguageCountries.containsKey(country)) {
@@ -226,4 +226,22 @@
}
return language.toString();
}
+
+ /**
+ * Converts all of the characters in this String to lower case using the rules of English. This is
+ * equivalent to calling toLowerCase(Locale.ENGLISH). Thus avoiding locale-sensitive case folding
+ * such as the Turkish i, which could mess e.g. with lookup keys and country codes.
+ */
+ public static String toLowerCaseLocaleIndependent(String value) {
+ return (value != null) ? value.toLowerCase(Locale.ENGLISH) : null;
+ }
+
+ /**
+ * Converts all of the characters in this String to upper case using the rules of English. This is
+ * equivalent to calling toUpperCase(Locale.ENGLISH). Thus avoiding locale-sensitive case folding
+ * such as the Turkish i, which could mess e.g. with lookup keys and country codes.
+ */
+ public static String toUpperCaseLocaleIndependent(String value) {
+ return (value != null) ? value.toUpperCase(Locale.ENGLISH) : null;
+ }
}
diff --git a/common/src/test/java/com/google/i18n/addressinput/testing/countryinfo.txt b/common/src/test/java/com/google/i18n/addressinput/testing/countryinfo.txt
index aa4086a..e8bb4a4 100644
--- a/common/src/test/java/com/google/i18n/addressinput/testing/countryinfo.txt
+++ b/common/src/test/java/com/google/i18n/addressinput/testing/countryinfo.txt
@@ -1,4 +1,4 @@
-data={"id":"data","countries":"AC~AD~AE~AF~AG~AI~AL~AM~AN~AO~AQ~AR~AS~AT~AU~AW~AX~AZ~BA~BB~BD~BE~BF~BG~BH~BI~BJ~BL~BM~BN~BO~BR~BS~BT~BV~BW~BY~BZ~CA~CC~CD~CF~CG~CH~CI~CK~CL~CM~CN~CO~CR~CS~CV~CX~CY~CZ~DE~DJ~DK~DM~DO~DZ~EC~EE~EG~EH~ER~ES~ET~FI~FJ~FK~FM~FO~FR~GA~GB~GD~GE~GF~GG~GH~GI~GL~GM~GN~GP~GQ~GR~GS~GT~GU~GW~GY~HK~HM~HN~HR~HT~HU~ID~IE~IL~IM~IN~IO~IQ~IR~IS~IT~JE~JM~JO~JP~KE~KG~KH~KI~KM~KN~KR~KW~KY~KZ~LA~LB~LC~LI~LK~LR~LS~LT~LU~LV~LY~MA~MC~MD~ME~MF~MG~MH~MK~ML~MM~MN~MO~MP~MQ~MR~MS~MT~MU~MV~MW~MX~MY~MZ~NA~NC~NE~NF~NG~NI~NL~NO~NP~NR~NU~NZ~OM~PA~PE~PF~PG~PH~PK~PL~PM~PN~PR~PS~PT~PW~PY~QA~RE~RO~RS~RU~RW~SA~SB~SC~SE~SG~SH~SI~SJ~SK~SL~SM~SN~SO~SR~SS~ST~SV~SZ~TA~TC~TD~TF~TG~TH~TJ~TK~TL~TM~TN~TO~TR~TT~TV~TW~TZ~UA~UG~UM~US~UY~UZ~VA~VC~VE~VG~VI~VN~VU~WF~WS~XK~YE~YT~ZA~ZM~ZW"}
+data={"id":"data","countries":"AC~AD~AE~AF~AG~AI~AL~AM~AO~AQ~AR~AS~AT~AU~AW~AX~AZ~BA~BB~BD~BE~BF~BG~BH~BI~BJ~BL~BM~BN~BO~BR~BS~BT~BV~BW~BY~BZ~CA~CC~CD~CF~CG~CH~CI~CK~CL~CM~CN~CO~CR~CV~CX~CY~CZ~DE~DJ~DK~DM~DO~DZ~EC~EE~EG~EH~ER~ES~ET~FI~FJ~FK~FM~FO~FR~GA~GB~GD~GE~GF~GG~GH~GI~GL~GM~GN~GP~GQ~GR~GS~GT~GU~GW~GY~HK~HM~HN~HR~HT~HU~ID~IE~IL~IM~IN~IO~IQ~IR~IS~IT~JE~JM~JO~JP~KE~KG~KH~KI~KM~KN~KR~KW~KY~KZ~LA~LB~LC~LI~LK~LR~LS~LT~LU~LV~LY~MA~MC~MD~ME~MF~MG~MH~MK~ML~MM~MN~MO~MP~MQ~MR~MS~MT~MU~MV~MW~MX~MY~MZ~NA~NC~NE~NF~NG~NI~NL~NO~NP~NR~NU~NZ~OM~PA~PE~PF~PG~PH~PK~PL~PM~PN~PR~PS~PT~PW~PY~QA~RE~RO~RS~RU~RW~SA~SB~SC~SE~SG~SH~SI~SJ~SK~SL~SM~SN~SO~SR~SS~ST~SV~SZ~TA~TC~TD~TF~TG~TH~TJ~TK~TL~TM~TN~TO~TR~TT~TV~TW~TZ~UA~UG~UM~US~UY~UZ~VA~VC~VE~VG~VI~VN~VU~WF~WS~XK~YE~YT~ZA~ZM~ZW"}
data/AC={"id":"data/AC","key":"AC","name":"ASCENSION ISLAND","zip":"ASCN 1ZZ","zipex":"ASCN 1ZZ"}
data/AD={"id":"data/AD","key":"AD","name":"ANDORRA","lang":"ca","languages":"ca","fmt":"%N%n%O%n%A%n%Z %S","require":"AS","upper":"S","zip":"AD[1-7]0\\d","zipex":"AD100,AD501,AD700","posturl":"http://www.correos.es/comun/CodigosPostales/1010_s-CodPostal.asp?Provincia=","state_name_type":"parish","sub_keys":"ANDORRA LA VELLA~CANILLO~ENCAMP~ESCALDES ENGORDANY~LAMASSANA~ORDINO~SANT JULIA DE LORIA","sub_names":"Andorra la Vella~Canillo~Encamp~Escaldes Engordany~Lamassana~Ordino~Sant Julia de Loria","sub_zips":"AD50[01]~AD10[01]~AD20[01]~AD70[01]~AD40[01]~AD30[01]~AD60[01]","sub_zipexs":"AD500~AD100~AD200~AD700~AD400~AD300~AD600","sub_isoids":"07~02~03~08~04~05~06"}
data/AD/ANDORRA LA VELLA={"id":"data/AD/ANDORRA LA VELLA","key":"ANDORRA LA VELLA","name":"Andorra la Vella","lang":"ca","zip":"AD50[01]","zipex":"AD500","isoid":"07"}
@@ -25,7 +25,6 @@
data/AM/Սյունիք={"id":"data/AM/Սյունիք","key":"Սյունիք","lang":"hy","lname":"Syunik","zip":"3[2-5]","zipex":"3201,3519","isoid":"SU"}
data/AM/Վայոց ձոր={"id":"data/AM/Վայոց ձոր","key":"Վայոց ձոր","lang":"hy","lname":"Vayots Dzor","zip":"3[6-8]","zipex":"3601,3810","isoid":"VD"}
data/AM/Տավուշ={"id":"data/AM/Տավուշ","key":"Տավուշ","lang":"hy","lname":"Tavush","zip":"39|4[0-2]","zipex":"3901,4216","isoid":"TV"}
-data/AN={"id":"data/AN","key":"AN","name":"NETHERLANDS ANTILLES"}
data/AO={"id":"data/AO","key":"AO","name":"ANGOLA"}
data/AQ={"id":"data/AQ","key":"AQ","name":"ANTARCTICA"}
data/AR={"id":"data/AR","key":"AR","name":"ARGENTINA","lang":"es","languages":"es","fmt":"%N%n%O%n%A%n%Z %C%n%S","upper":"ACZ","zip":"([A-HJ-NP-Z])?\\d{4}([A-Z]{3})?","zipex":"C1070AAM,C1000WAM,B1000TBU,X5187XAB","posturl":"http://www.correoargentino.com.ar/cpa","state_name_type":"state","sub_keys":"Buenos Aires~Capital Federal~Catamarca~Chaco~Chubut~Córdoba~Corrientes~Entre Ríos~Formosa~Jujuy~La Pampa~La Rioja~Mendoza~Misiones~Neuquén~Río Negro~Salta~San Juan~San Luis~Santa Cruz~Santa Fe~Santiago del Estero~Tierra del Fuego~Tucumán","sub_names":"Buenos Aires~Capital Federal~Catamarca~Chaco~Chubut~Córdoba~Corrientes~Entre Ríos~Formosa~Jujuy~La Pampa~La Rioja~Mendoza~Misiones~Neuquén~Río Negro~Salta~San Juan~San Luis~Santa Cruz~Santa Fe~Santiago del Estero~Tierra del Fuego~Tucumán","sub_zips":"B?[1-36-8]~C?1~K?[45]~H?3~U?[89]~X?[235-8]~W?3~E?[1-3]~P?[37]~Y?4~L?[3568]~F?5~M?[56]~N?3~Q?[38]~R?[89]~A?[34]~J?5~D?[4-6]~Z?[89]~S?[2368]~G?[2-5]~V?9~T?[45]","sub_isoids":"B~C~K~H~U~X~W~E~P~Y~L~F~M~N~Q~R~A~J~D~Z~S~G~V~T"}
@@ -7306,7 +7305,7 @@
data/CN/安徽省/黄山市/祁门县={"id":"data/CN/安徽省/黄山市/祁门县","key":"祁门县","lang":"zh-hans","lname":"Qimen Xian","zipex":"245600"}
data/CN/安徽省/黄山市/黄山区={"id":"data/CN/安徽省/黄山市/黄山区","key":"黄山区","lang":"zh-hans","lname":"Huangshan Qu","zipex":"242700"}
data/CN/安徽省/黄山市/黟县={"id":"data/CN/安徽省/黄山市/黟县","key":"黟县","lang":"zh-hans","lname":"Yi Xian","zipex":"245500"}
-data/CN/山东省={"id":"data/CN/山东省","key":"山东省","lang":"zh-hans","lname":"Shandong Sheng","isoid":"37","sub_keys":"滨州市~德州市~东营市~菏泽市~济南市~济宁市~莱芜市~聊城市~临沂市~青岛市~日照市~泰安市~威海市~潍坊市~烟台市~枣庄市~淄博市","sub_lnames":"Binzhou shi~Dezhou Shi~Dongying Shi~Heze Shi~Jinan Shi~Jining Shi~Laiwu Shi~Liaocheng Shi~Linyi Shi~Qingdao Shi~Rizhao Shi~Tai'an Shi~Wehai Shi~Weifang shi~Yantai Shi~Zaozhuang Shi~Zibo Shi","sub_zipexs":"256619~253012~257093~274020~250001~272119~271100~252052~276001~266001~276800~271000~264200~261041~264001~277101~255039","sub_mores":"true~true~true~true~true~true~true~true~true~true~true~true~true~true~true~true~true"}
+data/CN/山东省={"id":"data/CN/山东省","key":"山东省","lang":"zh-hans","lname":"Shandong Sheng","isoid":"37","sub_keys":"滨州市~德州市~东营市~菏泽市~济南市~济宁市~莱芜市~聊城市~临沂市~青岛市~日照市~泰安市~威海市~潍坊市~烟台市~枣庄市~淄博市","sub_lnames":"Binzhou shi~Dezhou Shi~Dongying Shi~Heze Shi~Jinan Shi~Jining Shi~Laiwu Shi~Liaocheng Shi~Linyi Shi~Qingdao Shi~Rizhao Shi~Tai'an Shi~Weihai Shi~Weifang shi~Yantai Shi~Zaozhuang Shi~Zibo Shi","sub_zipexs":"256619~253012~257093~274020~250001~272119~271100~252052~276001~266001~276800~271000~264200~261041~264001~277101~255039","sub_mores":"true~true~true~true~true~true~true~true~true~true~true~true~true~true~true~true~true"}
data/CN/山东省/东营市={"id":"data/CN/山东省/东营市","key":"东营市","lang":"zh-hans","lname":"Dongying Shi","zipex":"257093","sub_keys":"东营区~广饶县~河口区~垦利县~利津县","sub_lnames":"Dongying Qu~Guangrao Xian~Hekou Qu~Kenli Xian~Lijin Xian","sub_zipexs":"257029~257300~257200~257500~257400"}
data/CN/山东省/东营市/东营区={"id":"data/CN/山东省/东营市/东营区","key":"东营区","lang":"zh-hans","lname":"Dongying Qu","zipex":"257029"}
data/CN/山东省/东营市/利津县={"id":"data/CN/山东省/东营市/利津县","key":"利津县","lang":"zh-hans","lname":"Lijin Xian","zipex":"257400"}
@@ -7326,7 +7325,7 @@
data/CN/山东省/临沂市/蒙阴县={"id":"data/CN/山东省/临沂市/蒙阴县","key":"蒙阴县","lang":"zh-hans","lname":"Mengyin Xian","zipex":"276200"}
data/CN/山东省/临沂市/费县={"id":"data/CN/山东省/临沂市/费县","key":"费县","lang":"zh-hans","lname":"Fei Xian","zipex":"273400"}
data/CN/山东省/临沂市/郯城县={"id":"data/CN/山东省/临沂市/郯城县","key":"郯城县","lang":"zh-hans","lname":"Tancheng Xian","zipex":"276100"}
-data/CN/山东省/威海市={"id":"data/CN/山东省/威海市","key":"威海市","lang":"zh-hans","lname":"Wehai Shi","zipex":"264200","sub_keys":"环翠区~荣成市~乳山市~文登市","sub_lnames":"Huancui Qu~Rongcheng Shi~Rushan Shi~Wendeng Shi","sub_zipexs":"264200~264300~264500~264400"}
+data/CN/山东省/威海市={"id":"data/CN/山东省/威海市","key":"威海市","lang":"zh-hans","lname":"Weihai Shi","zipex":"264200","sub_keys":"环翠区~荣成市~乳山市~文登市","sub_lnames":"Huancui Qu~Rongcheng Shi~Rushan Shi~Wendeng Shi","sub_zipexs":"264200~264300~264500~264400"}
data/CN/山东省/威海市/乳山市={"id":"data/CN/山东省/威海市/乳山市","key":"乳山市","lang":"zh-hans","lname":"Rushan Shi","zipex":"264500"}
data/CN/山东省/威海市/文登市={"id":"data/CN/山东省/威海市/文登市","key":"文登市","lang":"zh-hans","lname":"Wendeng Shi","zipex":"264400"}
data/CN/山东省/威海市/环翠区={"id":"data/CN/山东省/威海市/环翠区","key":"环翠区","lang":"zh-hans","lname":"Huancui Qu","zipex":"264200"}
@@ -7737,7 +7736,7 @@
data/CN/广东省/韶关市/武江区={"id":"data/CN/广东省/韶关市/武江区","key":"武江区","lang":"zh-hans","lname":"Wujiang Qu","zipex":"512025"}
data/CN/广东省/韶关市/浈江区={"id":"data/CN/广东省/韶关市/浈江区","key":"浈江区","lang":"zh-hans","lname":"Zhenjiang Qu","zipex":"512023"}
data/CN/广东省/韶关市/翁源县={"id":"data/CN/广东省/韶关市/翁源县","key":"翁源县","lang":"zh-hans","lname":"Wengyuan Xian","zipex":"512600"}
-data/CN/广西壮族自治区={"id":"data/CN/广西壮族自治区","key":"广西壮族自治区","lang":"zh-hans","lname":"Guangxi Zhuangzuzizhiqu","isoid":"45","sub_keys":"百色市~北海市~崇左市~防城港市~贵港市~桂林市~河池市~贺州市~来宾市~柳州市~南宁市~钦州市~梧州市~玉林市","sub_lnames":"Bose Shi~Beihai Shi~Chongzuo Shi~Fangchenggang Shi~Guigang Shi~Guilin Shi~Hechi Shi~Hezhou Shi~Laibin Shi~Liuzhou Shi~Nanning Shi~Qinzhou Shi~Wuzhou Shi~Yulin Shi","sub_zipexs":"533000~536000~532200~538001~537100~541002~547000~542800~546100~545001~530012~535000~543000~537000","sub_mores":"true~true~true~true~true~true~true~true~true~true~true~true~true~true"}
+data/CN/广西壮族自治区={"id":"data/CN/广西壮族自治区","key":"广西壮族自治区","lang":"zh-hans","lname":"Guangxi Zhuangzuzizhiqu","isoid":"45","sub_keys":"百色市~北海市~崇左市~防城港市~贵港市~桂林市~河池市~贺州市~来宾市~柳州市~南宁市~钦州市~梧州市~玉林市","sub_lnames":"Baise Shi~Beihai Shi~Chongzuo Shi~Fangchenggang Shi~Guigang Shi~Guilin Shi~Hechi Shi~Hezhou Shi~Laibin Shi~Liuzhou Shi~Nanning Shi~Qinzhou Shi~Wuzhou Shi~Yulin Shi","sub_zipexs":"533000~536000~532200~538001~537100~541002~547000~542800~546100~545001~530012~535000~543000~537000","sub_mores":"true~true~true~true~true~true~true~true~true~true~true~true~true~true"}
data/CN/广西壮族自治区/北海市={"id":"data/CN/广西壮族自治区/北海市","key":"北海市","lang":"zh-hans","lname":"Beihai Shi","zipex":"536000","sub_keys":"海城区~合浦县~铁山港区~银海区","sub_lnames":"Haicheng Qu~Hepu Xian~Tieshangang Qu~Yinhai Qu","sub_zipexs":"536000~536100~536017~536000"}
data/CN/广西壮族自治区/北海市/合浦县={"id":"data/CN/广西壮族自治区/北海市/合浦县","key":"合浦县","lang":"zh-hans","lname":"Hepu Xian","zipex":"536100"}
data/CN/广西壮族自治区/北海市/海城区={"id":"data/CN/广西壮族自治区/北海市/海城区","key":"海城区","lang":"zh-hans","lname":"Haicheng Qu","zipex":"536000"}
@@ -7827,7 +7826,7 @@
data/CN/广西壮族自治区/玉林市/容县={"id":"data/CN/广西壮族自治区/玉林市/容县","key":"容县","lang":"zh-hans","lname":"Rong Xian","zipex":"537500"}
data/CN/广西壮族自治区/玉林市/玉州区={"id":"data/CN/广西壮族自治区/玉林市/玉州区","key":"玉州区","lang":"zh-hans","lname":"Yuzhou Qu","zipex":"537000"}
data/CN/广西壮族自治区/玉林市/陆川县={"id":"data/CN/广西壮族自治区/玉林市/陆川县","key":"陆川县","lang":"zh-hans","lname":"Luchuan Xian","zipex":"537700"}
-data/CN/广西壮族自治区/百色市={"id":"data/CN/广西壮族自治区/百色市","key":"百色市","lang":"zh-hans","lname":"Bose Shi","zipex":"533000","sub_keys":"德保县~靖西县~乐业县~凌云县~隆林各族自治县~那坡县~平果县~田东县~田林县~田阳县~西林县~右江区","sub_lnames":"Debao Xian~Jingxi Xian~Leye Xian~Lingyun Xian~Longlin Xian~Napo Xian~Pingguo Xian~Tiandong Xian~Tianlin Xian~Tianyang Xian~Xilin Xian~Youjiang Qu","sub_zipexs":"533700~533800~533200~533100~533500~533900~531400~531500~533300~533600~533500~533000","sub_lfnames":"~~~~Longlin Gezu Zizhixian~~~~~~~"}
+data/CN/广西壮族自治区/百色市={"id":"data/CN/广西壮族自治区/百色市","key":"百色市","lang":"zh-hans","lname":"Baise Shi","zipex":"533000","sub_keys":"德保县~靖西县~乐业县~凌云县~隆林各族自治县~那坡县~平果县~田东县~田林县~田阳县~西林县~右江区","sub_lnames":"Debao Xian~Jingxi Xian~Leye Xian~Lingyun Xian~Longlin Xian~Napo Xian~Pingguo Xian~Tiandong Xian~Tianlin Xian~Tianyang Xian~Xilin Xian~Youjiang Qu","sub_zipexs":"533700~533800~533200~533100~533500~533900~531400~531500~533300~533600~533500~533000","sub_lfnames":"~~~~Longlin Gezu Zizhixian~~~~~~~"}
data/CN/广西壮族自治区/百色市/乐业县={"id":"data/CN/广西壮族自治区/百色市/乐业县","key":"乐业县","lang":"zh-hans","lname":"Leye Xian","zipex":"533200"}
data/CN/广西壮族自治区/百色市/凌云县={"id":"data/CN/广西壮族自治区/百色市/凌云县","key":"凌云县","lang":"zh-hans","lname":"Lingyun Xian","zipex":"533100"}
data/CN/广西壮族自治区/百色市/右江区={"id":"data/CN/广西壮族自治区/百色市/右江区","key":"右江区","lang":"zh-hans","lname":"Youjiang Qu","zipex":"533000"}
@@ -8663,7 +8662,7 @@
data/CN/浙江省/金华市/浦江县={"id":"data/CN/浙江省/金华市/浦江县","key":"浦江县","lang":"zh-hans","lname":"Pujiang Xian","zipex":"322200"}
data/CN/浙江省/金华市/磐安县={"id":"data/CN/浙江省/金华市/磐安县","key":"磐安县","lang":"zh-hans","lname":"Pan'an Xian","zipex":"322300"}
data/CN/浙江省/金华市/金东区={"id":"data/CN/浙江省/金华市/金东区","key":"金东区","lang":"zh-hans","lname":"Jindong Qu","zipex":"321000"}
-data/CN/海南省={"id":"data/CN/海南省","key":"海南省","lang":"zh-hans","lname":"Hainan Sheng","isoid":"46","sub_keys":"白沙黎族自治县~保亭黎族苗族自治县~昌江黎族自治县~澄迈县~儋州市~定安县~东方市~海口市~乐东黎族自治县~临高县~陵水黎族自治县~南沙群岛~琼海市~琼中黎族苗族自治县~三亚市~屯昌县~万宁市~文昌市~五指山市~西沙群岛~中沙群岛的岛礁及其海域","sub_lnames":"Baisha Xian~Baoting Xian~Changjiang Xian~Chengmai Xian~Danzhou Shi~Ding'an Xian~Dongfang Shi~Haikou Shi~Ledong Xian~Lingao Xian~Lingshui Xian~Nansha Qundao~Qionghai Shi~Qiongzhong Xian~Sanya Shi~Tunchang Xian~Wanning Shi~Qiongshan Shi~Wuzhishan Shi~Xisha Qundao~Zhongsha Qundao","sub_zipexs":"572800~572300~572700~571900~571700~571200~572600~570102~572500~571800~572400~~571400~572900~572002~571600~571500~571300~572200~~","sub_mores":"false~false~false~false~false~false~false~true~false~false~false~false~false~false~false~false~false~false~false~false~false","sub_lfnames":"Baisha Lizu Zizhixian~Baoting Lizu Miaozu Zizhixian~Changjiang Lizu Zizhixian~~~~~~Ledong Lizu Zizhixian~~Lingshui Lizu Zizhixian~~~Qiongzhong Lizu Miaozu Zizhixian~~~~~~~Zhongsha Qundao de Daojiao Jiqi Haiyu"}
+data/CN/海南省={"id":"data/CN/海南省","key":"海南省","lang":"zh-hans","lname":"Hainan Sheng","isoid":"46","sub_keys":"白沙黎族自治县~保亭黎族苗族自治县~昌江黎族自治县~澄迈县~儋州市~定安县~东方市~海口市~乐东黎族自治县~临高县~陵水黎族自治县~南沙群岛~琼海市~琼中黎族苗族自治县~三亚市~屯昌县~万宁市~文昌市~五指山市~西沙群岛~中沙群岛的岛礁及其海域","sub_lnames":"Baisha Xian~Baoting Xian~Changjiang Xian~Chengmai Xian~Danzhou Shi~Ding'an Xian~Dongfang Shi~Haikou Shi~Ledong Xian~Lingao Xian~Lingshui Xian~Nansha Qundao~Qionghai Shi~Qiongzhong Xian~Sanya Shi~Tunchang Xian~Wanning Shi~Wenchang Shi~Wuzhishan Shi~Xisha Qundao~Zhongsha Qundao","sub_zipexs":"572800~572300~572700~571900~571700~571200~572600~570102~572500~571800~572400~~571400~572900~572002~571600~571500~571300~572200~~","sub_mores":"false~false~false~false~false~false~false~true~false~false~false~false~false~false~false~false~false~false~false~false~false","sub_lfnames":"Baisha Lizu Zizhixian~Baoting Lizu Miaozu Zizhixian~Changjiang Lizu Zizhixian~~~~~~Ledong Lizu Zizhixian~~Lingshui Lizu Zizhixian~~~Qiongzhong Lizu Miaozu Zizhixian~~~~~~~Zhongsha Qundao de Daojiao Jiqi Haiyu"}
data/CN/海南省/万宁市={"id":"data/CN/海南省/万宁市","key":"万宁市","lang":"zh-hans","lname":"Wanning Shi","zipex":"571500"}
data/CN/海南省/三亚市={"id":"data/CN/海南省/三亚市","key":"三亚市","lang":"zh-hans","lname":"Sanya Shi","zipex":"572002"}
data/CN/海南省/东方市={"id":"data/CN/海南省/东方市","key":"东方市","lang":"zh-hans","lname":"Dongfang Shi","zipex":"572600"}
@@ -8676,7 +8675,7 @@
data/CN/海南省/南沙群岛={"id":"data/CN/海南省/南沙群岛","key":"南沙群岛","lang":"zh-hans","lname":"Nansha Qundao"}
data/CN/海南省/定安县={"id":"data/CN/海南省/定安县","key":"定安县","lang":"zh-hans","lname":"Ding'an Xian","zipex":"571200"}
data/CN/海南省/屯昌县={"id":"data/CN/海南省/屯昌县","key":"屯昌县","lang":"zh-hans","lname":"Tunchang Xian","zipex":"571600"}
-data/CN/海南省/文昌市={"id":"data/CN/海南省/文昌市","key":"文昌市","lang":"zh-hans","lname":"Qiongshan Shi","zipex":"571300"}
+data/CN/海南省/文昌市={"id":"data/CN/海南省/文昌市","key":"文昌市","lang":"zh-hans","lname":"Wenchang Shi","zipex":"571300"}
data/CN/海南省/昌江黎族自治县={"id":"data/CN/海南省/昌江黎族自治县","key":"昌江黎族自治县","lang":"zh-hans","lname":"Changjiang Xian","zipex":"572700","lfname":"Changjiang Lizu Zizhixian"}
data/CN/海南省/海口市={"id":"data/CN/海南省/海口市","key":"海口市","lang":"zh-hans","lname":"Haikou Shi","zipex":"570102","sub_keys":"龙华区~美兰区~琼山区~秀英区","sub_lnames":"Longhua Qu~Meilan Qu~Qiongshan Qu~Xiuying Qu","sub_zipexs":"570105~570203~571100~570311"}
data/CN/海南省/海口市/琼山区={"id":"data/CN/海南省/海口市/琼山区","key":"琼山区","lang":"zh-hans","lname":"Qiongshan Qu","zipex":"571100"}
@@ -9795,7 +9794,6 @@
data/CN/黑龙江省/齐齐哈尔市/龙沙区={"id":"data/CN/黑龙江省/齐齐哈尔市/龙沙区","key":"龙沙区","lang":"zh-hans","lname":"Longsha Qu","zipex":"161000"}
data/CO={"id":"data/CO","key":"CO","name":"COLOMBIA","fmt":"%N%n%O%n%A%n%C, %S","zip":"\\d{6}","zipex":"111221,130001,760011","posturl":"http://www.codigopostal4-72.com.co/codigosPostales/"}
data/CR={"id":"data/CR","key":"CR","name":"COSTA RICA","fmt":"%N%n%O%n%A%n%Z %C","zip":"\\d{4,5}|\\d{3}-\\d{4}","zipex":"1000,2010,1001","posturl":"https://www.correos.go.cr/nosotros/codigopostal/busqueda.html"}
-data/CS={"id":"data/CS","key":"CS","name":"SERBIA AND MONTENEGRO","fmt":"%N%n%O%n%A%n%Z %C","zip":"\\d{5}","zipex":"11001"}
data/CV={"id":"data/CV","key":"CV","name":"CAPE VERDE","lang":"pt","languages":"pt","fmt":"%N%n%O%n%A%n%Z %C%n%S","zip":"\\d{4}","zipex":"7600","state_name_type":"island","sub_keys":"BOA VISTA~BRAVA~FOGO~MAIO~SAL~SANTIAGO~SANTO ANTÃO~SÃO NICOLAU~SÃO VICENTE","sub_isoids":"BV~BR~~MA~SL~~~SN~SV"}
data/CV/BOA VISTA={"id":"data/CV/BOA VISTA","key":"BOA VISTA","lang":"pt","isoid":"BV"}
data/CV/BRAVA={"id":"data/CV/BRAVA","key":"BRAVA","lang":"pt","isoid":"BR"}
@@ -10707,15 +10705,15 @@
data/MX/VER={"id":"data/MX/VER","key":"VER","name":"Veracruz","lang":"es","zip":"9[1-6]","zipex":"91000,96999","isoid":"VER"}
data/MX/YUC={"id":"data/MX/YUC","key":"YUC","name":"Yucatán","lang":"es","zip":"97","zipex":"97000,97999","isoid":"YUC"}
data/MX/ZAC={"id":"data/MX/ZAC","key":"ZAC","name":"Zacatecas","lang":"es","zip":"9[89]","zipex":"98000,99999","isoid":"ZAC"}
-data/MY={"id":"data/MY","key":"MY","name":"MALAYSIA","lang":"ms","languages":"ms","fmt":"%N%n%O%n%A%n%Z %C, %S","require":"ACZ","upper":"CS","zip":"\\d{5}","zipex":"43000,50754,88990,50670","posturl":"http://www.pos.com.my/pos/homepage.aspx","state_name_type":"state","sub_keys":"JOHOR~KEDAH~KELANTAN~KUALA LUMPUR~LABUAN~MELAKA~NEGERI SEMBILAN~PAHANG~PERAK~PERLIS~PULAU PINANG~PUTRAJAYA~SABAH~SARAWAK~SELANGOR~TERENGGANU","sub_zips":"8[0-6]~0[5-9]|34950~1[5-9]~5|60~87~7[5-9]~7[0-4]~2[5-8]|39|49|69~3[0-6]|39000~0[12]~1[0-4]~62~8[89]|9[01]~9[3-8]~4[0-8]|6[3-8]~2[0-4]","sub_zipexs":"80000,86999~05000,09999:34950~15000,18599~50000,60000~87000,87999~75000,78399~70000,73599~25000,28999:39000,39999:49000:69000~30000,36899:39000~01000,02799~10000,14999~62000,62999~88000,91999~93000,98999~40000,48999:63000,68199~20000,24999","sub_isoids":"01~02~03~14~15~04~05~06~08~09~07~16~12~13~10~11"}
-data/MY/JOHOR={"id":"data/MY/JOHOR","key":"JOHOR","lang":"ms","zip":"8[0-6]","zipex":"80000,86999","isoid":"01"}
+data/MY={"id":"data/MY","key":"MY","name":"MALAYSIA","lang":"ms","languages":"ms","fmt":"%N%n%O%n%A%n%D%n%Z %C%n%S","require":"ACZ","upper":"CS","zip":"\\d{5}","zipex":"43000,50754,88990,50670","posturl":"http://www.pos.com.my/pos/homepage.aspx","state_name_type":"state","sublocality_name_type":"village_township","sub_keys":"JOHOR~KEDAH~KELANTAN~KUALA LUMPUR~LABUAN~MELAKA~NEGERI SEMBILAN~PAHANG~PERAK~PERLIS~PULAU PINANG~PUTRAJAYA~SABAH~SARAWAK~SELANGOR~TERENGGANU","sub_zips":"79|8[0-6]~0[5-9]|34950~1[5-9]~[56]0~87~7[5-8]~7[0-4]~2[5-8]|[346]9~3[0-6]|39000~0[12]~1[0-4]~62~8[89]|9[01]~9[3-8]~4[0-8]|6[3-8]~2[0-4]","sub_zipexs":"79000:86999~05000,09999:34950~15000,18599~50000,60000~87000,87999~75000,78399~70000,73599~25000,28999:39000,39999:49000:69000~30000,36899:39000~01000,02799~10000,14999~62000,62999~88000,91999~93000,98999~40000,48999:63000,68199~20000,24999","sub_isoids":"01~02~03~14~15~04~05~06~08~09~07~16~12~13~10~11"}
+data/MY/JOHOR={"id":"data/MY/JOHOR","key":"JOHOR","lang":"ms","zip":"79|8[0-6]","zipex":"79000:86999","isoid":"01"}
data/MY/KEDAH={"id":"data/MY/KEDAH","key":"KEDAH","lang":"ms","zip":"0[5-9]|34950","zipex":"05000,09999:34950","isoid":"02"}
data/MY/KELANTAN={"id":"data/MY/KELANTAN","key":"KELANTAN","lang":"ms","zip":"1[5-9]","zipex":"15000,18599","isoid":"03"}
-data/MY/KUALA LUMPUR={"id":"data/MY/KUALA LUMPUR","key":"KUALA LUMPUR","lang":"ms","zip":"5|60","zipex":"50000,60000","isoid":"14"}
+data/MY/KUALA LUMPUR={"id":"data/MY/KUALA LUMPUR","key":"KUALA LUMPUR","lang":"ms","zip":"[56]0","zipex":"50000,60000","isoid":"14"}
data/MY/LABUAN={"id":"data/MY/LABUAN","key":"LABUAN","lang":"ms","zip":"87","zipex":"87000,87999","isoid":"15"}
-data/MY/MELAKA={"id":"data/MY/MELAKA","key":"MELAKA","lang":"ms","zip":"7[5-9]","zipex":"75000,78399","isoid":"04"}
+data/MY/MELAKA={"id":"data/MY/MELAKA","key":"MELAKA","lang":"ms","zip":"7[5-8]","zipex":"75000,78399","isoid":"04"}
data/MY/NEGERI SEMBILAN={"id":"data/MY/NEGERI SEMBILAN","key":"NEGERI SEMBILAN","lang":"ms","zip":"7[0-4]","zipex":"70000,73599","isoid":"05"}
-data/MY/PAHANG={"id":"data/MY/PAHANG","key":"PAHANG","lang":"ms","zip":"2[5-8]|39|49|69","zipex":"25000,28999:39000,39999:49000:69000","isoid":"06"}
+data/MY/PAHANG={"id":"data/MY/PAHANG","key":"PAHANG","lang":"ms","zip":"2[5-8]|[346]9","zipex":"25000,28999:39000,39999:49000:69000","isoid":"06"}
data/MY/PERAK={"id":"data/MY/PERAK","key":"PERAK","lang":"ms","zip":"3[0-6]|39000","zipex":"30000,36899:39000","isoid":"08"}
data/MY/PERLIS={"id":"data/MY/PERLIS","key":"PERLIS","lang":"ms","zip":"0[12]","zipex":"01000,02799","isoid":"09"}
data/MY/PULAU PINANG={"id":"data/MY/PULAU PINANG","key":"PULAU PINANG","lang":"ms","zip":"1[0-4]","zipex":"10000,14999","isoid":"07"}
diff --git a/cpp/src/region_data_constants.cc b/cpp/src/region_data_constants.cc
index 33bfc32..59de2a7 100644
--- a/cpp/src/region_data_constants.cc
+++ b/cpp/src/region_data_constants.cc
@@ -45,7 +45,6 @@
"}"));
region_data.insert(std::make_pair("AD", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
- "\"require\":\"A\","
"\"zipex\":\"AD100,AD501,AD700\","
"\"posturl\":\"http://www.correos.es/comun/CodigosPostales/1010_s-CodPostal.asp\?Provincia=\","
"\"languages\":\"ca\""
@@ -53,7 +52,7 @@
region_data.insert(std::make_pair("AE", "{"
"\"fmt\":\"%N%n%O%n%A%n%S\","
"\"lfmt\":\"%N%n%O%n%A%n%S\","
- "\"require\":\"A\","
+ "\"require\":\"AS\","
"\"state_name_type\":\"emirate\","
"\"languages\":\"ar\""
"}"));
@@ -200,7 +199,7 @@
"\"languages\":\"es~qu~ay\""
"}"));
region_data.insert(std::make_pair("BQ", "{"
- "\"languages\":\"pap~nl\""
+ "\"languages\":\"nl\""
"}"));
region_data.insert(std::make_pair("BR", "{"
"\"fmt\":\"%O%n%N%n%A%n%D%n%C-%S%n%Z\","
@@ -208,7 +207,7 @@
"\"state_name_type\":\"state\","
"\"sublocality_name_type\":\"neighborhood\","
"\"zipex\":\"40301-110,70002-900\","
- "\"posturl\":\"http://www.correios.com.br/servicos/cep/cep_default.cfm\","
+ "\"posturl\":\"http://www.buscacep.correios.com.br/\","
"\"languages\":\"pt\""
"}"));
region_data.insert(std::make_pair("BS", "{"
@@ -256,7 +255,7 @@
"\"languages\":\"fr~sg\""
"}"));
region_data.insert(std::make_pair("CG", "{"
- "\"languages\":\"fr~ln\""
+ "\"languages\":\"fr\""
"}"));
region_data.insert(std::make_pair("CH", "{"
"\"fmt\":\"%O%n%N%n%A%nCH-%Z %C\","
@@ -361,7 +360,7 @@
region_data.insert(std::make_pair("EC", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z%n%C\","
"\"zipex\":\"090105,EC090112,H0103C,P0133B,P0133A,P0133V\","
- "\"languages\":\"es\""
+ "\"languages\":\"es~qu\""
"}"));
region_data.insert(std::make_pair("EE", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
@@ -403,7 +402,7 @@
"\"languages\":\"fi~sv\""
"}"));
region_data.insert(std::make_pair("FJ", "{"
- "\"languages\":\"en~fj\""
+ "\"languages\":\"en~hif-Deva~fj\""
"}"));
region_data.insert(std::make_pair("FK", "{"
"\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
@@ -418,7 +417,7 @@
"\"state_name_type\":\"state\","
"\"zipex\":\"96941,96944\","
"\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
- "\"languages\":\"chk~pon~kos~yap~en~uli\""
+ "\"languages\":\"en\""
"}"));
region_data.insert(std::make_pair("FO", "{"
"\"fmt\":\"%N%n%O%n%A%nFO%Z %C\","
@@ -481,7 +480,7 @@
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
"\"require\":\"ACZ\","
"\"zipex\":\"3900,3950,3911\","
- "\"languages\":\"kl~da\""
+ "\"languages\":\"kl\""
"}"));
region_data.insert(std::make_pair("GM", "{"
"\"languages\":\"en\""
@@ -618,9 +617,10 @@
"\"languages\":\"ar\""
"}"));
region_data.insert(std::make_pair("IR", "{"
- "\"languages\":\"fa\","
"\"fmt\":\"%O%n%N%n%S%n%C, %D%n%A%n%Z\","
- "\"sublocality_name_type\":\"neighborhood\""
+ "\"sublocality_name_type\":\"neighborhood\","
+ "\"zipex\":\"11936-12345\","
+ "\"languages\":\"fa\""
"}"));
region_data.insert(std::make_pair("IS", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
@@ -821,12 +821,14 @@
region_data.insert(std::make_pair("MK", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
"\"zipex\":\"1314,1321,1443,1062\","
- "\"languages\":\"mk~sq\""
+ "\"languages\":\"mk\""
"}"));
region_data.insert(std::make_pair("ML", "{"
"\"languages\":\"fr\""
"}"));
region_data.insert(std::make_pair("MM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %Z\","
+ "\"zipex\":\"11181\","
"\"languages\":\"my\""
"}"));
region_data.insert(std::make_pair("MN", "{"
@@ -871,7 +873,7 @@
"}"));
region_data.insert(std::make_pair("MU", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z%n%C\","
- "\"zipex\":\"742CU001\","
+ "\"zipex\":\"42602\","
"\"languages\":\"en~fr\""
"}"));
region_data.insert(std::make_pair("MV", "{"
@@ -1093,7 +1095,7 @@
"\"lfmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
"\"require\":\"ACZ\","
"\"state_name_type\":\"oblast\","
- "\"zipex\":\"125075,247112,103375\","
+ "\"zipex\":\"247112,103375,188300\","
"\"posturl\":\"http://info.russianpost.ru/servlet/department\","
"\"languages\":\"ru\""
"}"));
@@ -1164,7 +1166,7 @@
region_data.insert(std::make_pair("SN", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
"\"zipex\":\"12500,46024,16556,10000\","
- "\"languages\":\"fr~wo\""
+ "\"languages\":\"wo~fr\""
"}"));
region_data.insert(std::make_pair("SO", "{"
"\"fmt\":\"%N%n%O%n%A%n%C, %S %Z\","
@@ -1322,7 +1324,7 @@
region_data.insert(std::make_pair("VA", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
"\"zipex\":\"00120\","
- "\"languages\":\"la\""
+ "\"languages\":\"it~la\""
"}"));
region_data.insert(std::make_pair("VC", "{"
"\"zipex\":\"VC0100,VC0110,VC0400\","
@@ -1389,7 +1391,7 @@
"\"require\":\"ACZ\","
"\"zipex\":\"0083,1451,0001\","
"\"posturl\":\"http://www.postoffice.co.za/tools/postalcode.html\","
- "\"languages\":\"en~zu~xh~af~nso~tn~st~ts~ss~ve~nr\""
+ "\"languages\":\"en\""
"}"));
region_data.insert(std::make_pair("ZM", "{"
"\"fmt\":\"%N%n%O%n%A%n%Z %C\","
diff --git a/testdata/countryinfo.txt b/testdata/countryinfo.txt
index 4ce5f08..e8bb4a4 100644
--- a/testdata/countryinfo.txt
+++ b/testdata/countryinfo.txt
@@ -1,4 +1,4 @@
-data={"id":"data","countries":"AC~AD~AE~AF~AG~AI~AL~AM~AN~AO~AQ~AR~AS~AT~AU~AW~AX~AZ~BA~BB~BD~BE~BF~BG~BH~BI~BJ~BL~BM~BN~BO~BR~BS~BT~BV~BW~BY~BZ~CA~CC~CD~CF~CG~CH~CI~CK~CL~CM~CN~CO~CR~CS~CV~CX~CY~CZ~DE~DJ~DK~DM~DO~DZ~EC~EE~EG~EH~ER~ES~ET~FI~FJ~FK~FM~FO~FR~GA~GB~GD~GE~GF~GG~GH~GI~GL~GM~GN~GP~GQ~GR~GS~GT~GU~GW~GY~HK~HM~HN~HR~HT~HU~ID~IE~IL~IM~IN~IO~IQ~IR~IS~IT~JE~JM~JO~JP~KE~KG~KH~KI~KM~KN~KR~KW~KY~KZ~LA~LB~LC~LI~LK~LR~LS~LT~LU~LV~LY~MA~MC~MD~ME~MF~MG~MH~MK~ML~MM~MN~MO~MP~MQ~MR~MS~MT~MU~MV~MW~MX~MY~MZ~NA~NC~NE~NF~NG~NI~NL~NO~NP~NR~NU~NZ~OM~PA~PE~PF~PG~PH~PK~PL~PM~PN~PR~PS~PT~PW~PY~QA~RE~RO~RS~RU~RW~SA~SB~SC~SE~SG~SH~SI~SJ~SK~SL~SM~SN~SO~SR~SS~ST~SV~SZ~TA~TC~TD~TF~TG~TH~TJ~TK~TL~TM~TN~TO~TR~TT~TV~TW~TZ~UA~UG~UM~US~UY~UZ~VA~VC~VE~VG~VI~VN~VU~WF~WS~XK~YE~YT~ZA~ZM~ZW"}
+data={"id":"data","countries":"AC~AD~AE~AF~AG~AI~AL~AM~AO~AQ~AR~AS~AT~AU~AW~AX~AZ~BA~BB~BD~BE~BF~BG~BH~BI~BJ~BL~BM~BN~BO~BR~BS~BT~BV~BW~BY~BZ~CA~CC~CD~CF~CG~CH~CI~CK~CL~CM~CN~CO~CR~CV~CX~CY~CZ~DE~DJ~DK~DM~DO~DZ~EC~EE~EG~EH~ER~ES~ET~FI~FJ~FK~FM~FO~FR~GA~GB~GD~GE~GF~GG~GH~GI~GL~GM~GN~GP~GQ~GR~GS~GT~GU~GW~GY~HK~HM~HN~HR~HT~HU~ID~IE~IL~IM~IN~IO~IQ~IR~IS~IT~JE~JM~JO~JP~KE~KG~KH~KI~KM~KN~KR~KW~KY~KZ~LA~LB~LC~LI~LK~LR~LS~LT~LU~LV~LY~MA~MC~MD~ME~MF~MG~MH~MK~ML~MM~MN~MO~MP~MQ~MR~MS~MT~MU~MV~MW~MX~MY~MZ~NA~NC~NE~NF~NG~NI~NL~NO~NP~NR~NU~NZ~OM~PA~PE~PF~PG~PH~PK~PL~PM~PN~PR~PS~PT~PW~PY~QA~RE~RO~RS~RU~RW~SA~SB~SC~SE~SG~SH~SI~SJ~SK~SL~SM~SN~SO~SR~SS~ST~SV~SZ~TA~TC~TD~TF~TG~TH~TJ~TK~TL~TM~TN~TO~TR~TT~TV~TW~TZ~UA~UG~UM~US~UY~UZ~VA~VC~VE~VG~VI~VN~VU~WF~WS~XK~YE~YT~ZA~ZM~ZW"}
data/AC={"id":"data/AC","key":"AC","name":"ASCENSION ISLAND","zip":"ASCN 1ZZ","zipex":"ASCN 1ZZ"}
data/AD={"id":"data/AD","key":"AD","name":"ANDORRA","lang":"ca","languages":"ca","fmt":"%N%n%O%n%A%n%Z %S","require":"AS","upper":"S","zip":"AD[1-7]0\\d","zipex":"AD100,AD501,AD700","posturl":"http://www.correos.es/comun/CodigosPostales/1010_s-CodPostal.asp?Provincia=","state_name_type":"parish","sub_keys":"ANDORRA LA VELLA~CANILLO~ENCAMP~ESCALDES ENGORDANY~LAMASSANA~ORDINO~SANT JULIA DE LORIA","sub_names":"Andorra la Vella~Canillo~Encamp~Escaldes Engordany~Lamassana~Ordino~Sant Julia de Loria","sub_zips":"AD50[01]~AD10[01]~AD20[01]~AD70[01]~AD40[01]~AD30[01]~AD60[01]","sub_zipexs":"AD500~AD100~AD200~AD700~AD400~AD300~AD600","sub_isoids":"07~02~03~08~04~05~06"}
data/AD/ANDORRA LA VELLA={"id":"data/AD/ANDORRA LA VELLA","key":"ANDORRA LA VELLA","name":"Andorra la Vella","lang":"ca","zip":"AD50[01]","zipex":"AD500","isoid":"07"}
@@ -25,7 +25,6 @@
data/AM/Սյունիք={"id":"data/AM/Սյունիք","key":"Սյունիք","lang":"hy","lname":"Syunik","zip":"3[2-5]","zipex":"3201,3519","isoid":"SU"}
data/AM/Վայոց ձոր={"id":"data/AM/Վայոց ձոր","key":"Վայոց ձոր","lang":"hy","lname":"Vayots Dzor","zip":"3[6-8]","zipex":"3601,3810","isoid":"VD"}
data/AM/Տավուշ={"id":"data/AM/Տավուշ","key":"Տավուշ","lang":"hy","lname":"Tavush","zip":"39|4[0-2]","zipex":"3901,4216","isoid":"TV"}
-data/AN={"id":"data/AN","key":"AN","name":"NETHERLANDS ANTILLES"}
data/AO={"id":"data/AO","key":"AO","name":"ANGOLA"}
data/AQ={"id":"data/AQ","key":"AQ","name":"ANTARCTICA"}
data/AR={"id":"data/AR","key":"AR","name":"ARGENTINA","lang":"es","languages":"es","fmt":"%N%n%O%n%A%n%Z %C%n%S","upper":"ACZ","zip":"([A-HJ-NP-Z])?\\d{4}([A-Z]{3})?","zipex":"C1070AAM,C1000WAM,B1000TBU,X5187XAB","posturl":"http://www.correoargentino.com.ar/cpa","state_name_type":"state","sub_keys":"Buenos Aires~Capital Federal~Catamarca~Chaco~Chubut~Córdoba~Corrientes~Entre Ríos~Formosa~Jujuy~La Pampa~La Rioja~Mendoza~Misiones~Neuquén~Río Negro~Salta~San Juan~San Luis~Santa Cruz~Santa Fe~Santiago del Estero~Tierra del Fuego~Tucumán","sub_names":"Buenos Aires~Capital Federal~Catamarca~Chaco~Chubut~Córdoba~Corrientes~Entre Ríos~Formosa~Jujuy~La Pampa~La Rioja~Mendoza~Misiones~Neuquén~Río Negro~Salta~San Juan~San Luis~Santa Cruz~Santa Fe~Santiago del Estero~Tierra del Fuego~Tucumán","sub_zips":"B?[1-36-8]~C?1~K?[45]~H?3~U?[89]~X?[235-8]~W?3~E?[1-3]~P?[37]~Y?4~L?[3568]~F?5~M?[56]~N?3~Q?[38]~R?[89]~A?[34]~J?5~D?[4-6]~Z?[89]~S?[2368]~G?[2-5]~V?9~T?[45]","sub_isoids":"B~C~K~H~U~X~W~E~P~Y~L~F~M~N~Q~R~A~J~D~Z~S~G~V~T"}
@@ -9795,7 +9794,6 @@
data/CN/黑龙江省/齐齐哈尔市/龙沙区={"id":"data/CN/黑龙江省/齐齐哈尔市/龙沙区","key":"龙沙区","lang":"zh-hans","lname":"Longsha Qu","zipex":"161000"}
data/CO={"id":"data/CO","key":"CO","name":"COLOMBIA","fmt":"%N%n%O%n%A%n%C, %S","zip":"\\d{6}","zipex":"111221,130001,760011","posturl":"http://www.codigopostal4-72.com.co/codigosPostales/"}
data/CR={"id":"data/CR","key":"CR","name":"COSTA RICA","fmt":"%N%n%O%n%A%n%Z %C","zip":"\\d{4,5}|\\d{3}-\\d{4}","zipex":"1000,2010,1001","posturl":"https://www.correos.go.cr/nosotros/codigopostal/busqueda.html"}
-data/CS={"id":"data/CS","key":"CS","name":"SERBIA AND MONTENEGRO","fmt":"%N%n%O%n%A%n%Z %C","zip":"\\d{5}","zipex":"11001"}
data/CV={"id":"data/CV","key":"CV","name":"CAPE VERDE","lang":"pt","languages":"pt","fmt":"%N%n%O%n%A%n%Z %C%n%S","zip":"\\d{4}","zipex":"7600","state_name_type":"island","sub_keys":"BOA VISTA~BRAVA~FOGO~MAIO~SAL~SANTIAGO~SANTO ANTÃO~SÃO NICOLAU~SÃO VICENTE","sub_isoids":"BV~BR~~MA~SL~~~SN~SV"}
data/CV/BOA VISTA={"id":"data/CV/BOA VISTA","key":"BOA VISTA","lang":"pt","isoid":"BV"}
data/CV/BRAVA={"id":"data/CV/BRAVA","key":"BRAVA","lang":"pt","isoid":"BR"}
@@ -10707,15 +10705,15 @@
data/MX/VER={"id":"data/MX/VER","key":"VER","name":"Veracruz","lang":"es","zip":"9[1-6]","zipex":"91000,96999","isoid":"VER"}
data/MX/YUC={"id":"data/MX/YUC","key":"YUC","name":"Yucatán","lang":"es","zip":"97","zipex":"97000,97999","isoid":"YUC"}
data/MX/ZAC={"id":"data/MX/ZAC","key":"ZAC","name":"Zacatecas","lang":"es","zip":"9[89]","zipex":"98000,99999","isoid":"ZAC"}
-data/MY={"id":"data/MY","key":"MY","name":"MALAYSIA","lang":"ms","languages":"ms","fmt":"%N%n%O%n%A%n%Z %C, %S","require":"ACZ","upper":"CS","zip":"\\d{5}","zipex":"43000,50754,88990,50670","posturl":"http://www.pos.com.my/pos/homepage.aspx","state_name_type":"state","sub_keys":"JOHOR~KEDAH~KELANTAN~KUALA LUMPUR~LABUAN~MELAKA~NEGERI SEMBILAN~PAHANG~PERAK~PERLIS~PULAU PINANG~PUTRAJAYA~SABAH~SARAWAK~SELANGOR~TERENGGANU","sub_zips":"8[0-6]~0[5-9]|34950~1[5-9]~5|60~87~7[5-9]~7[0-4]~2[5-8]|39|49|69~3[0-6]|39000~0[12]~1[0-4]~62~8[89]|9[01]~9[3-8]~4[0-8]|6[3-8]~2[0-4]","sub_zipexs":"80000,86999~05000,09999:34950~15000,18599~50000,60000~87000,87999~75000,78399~70000,73599~25000,28999:39000,39999:49000:69000~30000,36899:39000~01000,02799~10000,14999~62000,62999~88000,91999~93000,98999~40000,48999:63000,68199~20000,24999","sub_isoids":"01~02~03~14~15~04~05~06~08~09~07~16~12~13~10~11"}
-data/MY/JOHOR={"id":"data/MY/JOHOR","key":"JOHOR","lang":"ms","zip":"8[0-6]","zipex":"80000,86999","isoid":"01"}
+data/MY={"id":"data/MY","key":"MY","name":"MALAYSIA","lang":"ms","languages":"ms","fmt":"%N%n%O%n%A%n%D%n%Z %C%n%S","require":"ACZ","upper":"CS","zip":"\\d{5}","zipex":"43000,50754,88990,50670","posturl":"http://www.pos.com.my/pos/homepage.aspx","state_name_type":"state","sublocality_name_type":"village_township","sub_keys":"JOHOR~KEDAH~KELANTAN~KUALA LUMPUR~LABUAN~MELAKA~NEGERI SEMBILAN~PAHANG~PERAK~PERLIS~PULAU PINANG~PUTRAJAYA~SABAH~SARAWAK~SELANGOR~TERENGGANU","sub_zips":"79|8[0-6]~0[5-9]|34950~1[5-9]~[56]0~87~7[5-8]~7[0-4]~2[5-8]|[346]9~3[0-6]|39000~0[12]~1[0-4]~62~8[89]|9[01]~9[3-8]~4[0-8]|6[3-8]~2[0-4]","sub_zipexs":"79000:86999~05000,09999:34950~15000,18599~50000,60000~87000,87999~75000,78399~70000,73599~25000,28999:39000,39999:49000:69000~30000,36899:39000~01000,02799~10000,14999~62000,62999~88000,91999~93000,98999~40000,48999:63000,68199~20000,24999","sub_isoids":"01~02~03~14~15~04~05~06~08~09~07~16~12~13~10~11"}
+data/MY/JOHOR={"id":"data/MY/JOHOR","key":"JOHOR","lang":"ms","zip":"79|8[0-6]","zipex":"79000:86999","isoid":"01"}
data/MY/KEDAH={"id":"data/MY/KEDAH","key":"KEDAH","lang":"ms","zip":"0[5-9]|34950","zipex":"05000,09999:34950","isoid":"02"}
data/MY/KELANTAN={"id":"data/MY/KELANTAN","key":"KELANTAN","lang":"ms","zip":"1[5-9]","zipex":"15000,18599","isoid":"03"}
-data/MY/KUALA LUMPUR={"id":"data/MY/KUALA LUMPUR","key":"KUALA LUMPUR","lang":"ms","zip":"5|60","zipex":"50000,60000","isoid":"14"}
+data/MY/KUALA LUMPUR={"id":"data/MY/KUALA LUMPUR","key":"KUALA LUMPUR","lang":"ms","zip":"[56]0","zipex":"50000,60000","isoid":"14"}
data/MY/LABUAN={"id":"data/MY/LABUAN","key":"LABUAN","lang":"ms","zip":"87","zipex":"87000,87999","isoid":"15"}
-data/MY/MELAKA={"id":"data/MY/MELAKA","key":"MELAKA","lang":"ms","zip":"7[5-9]","zipex":"75000,78399","isoid":"04"}
+data/MY/MELAKA={"id":"data/MY/MELAKA","key":"MELAKA","lang":"ms","zip":"7[5-8]","zipex":"75000,78399","isoid":"04"}
data/MY/NEGERI SEMBILAN={"id":"data/MY/NEGERI SEMBILAN","key":"NEGERI SEMBILAN","lang":"ms","zip":"7[0-4]","zipex":"70000,73599","isoid":"05"}
-data/MY/PAHANG={"id":"data/MY/PAHANG","key":"PAHANG","lang":"ms","zip":"2[5-8]|39|49|69","zipex":"25000,28999:39000,39999:49000:69000","isoid":"06"}
+data/MY/PAHANG={"id":"data/MY/PAHANG","key":"PAHANG","lang":"ms","zip":"2[5-8]|[346]9","zipex":"25000,28999:39000,39999:49000:69000","isoid":"06"}
data/MY/PERAK={"id":"data/MY/PERAK","key":"PERAK","lang":"ms","zip":"3[0-6]|39000","zipex":"30000,36899:39000","isoid":"08"}
data/MY/PERLIS={"id":"data/MY/PERLIS","key":"PERLIS","lang":"ms","zip":"0[12]","zipex":"01000,02799","isoid":"09"}
data/MY/PULAU PINANG={"id":"data/MY/PULAU PINANG","key":"PULAU PINANG","lang":"ms","zip":"1[0-4]","zipex":"10000,14999","isoid":"07"}