diff --git a/Networking/Networking.xcodeproj/project.pbxproj b/Networking/Networking.xcodeproj/project.pbxproj index e51e859ed55..3d84f96b742 100644 --- a/Networking/Networking.xcodeproj/project.pbxproj +++ b/Networking/Networking.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 748D424A210F92EA00CF7D1B /* OrderStatsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 748D4249210F92EA00CF7D1B /* OrderStatsItem.swift */; }; 748D424C210FA34400CF7D1B /* OrderStatsMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 748D424B210FA34400CF7D1B /* OrderStatsMapper.swift */; }; 748D424E210FB1F500CF7D1B /* order-stats-day.json in Resources */ = {isa = PBXBuildFile; fileRef = 748D424D210FB1F500CF7D1B /* order-stats-day.json */; }; + 7492FAE3217FBDBC00ED2C69 /* settings-general-alt.json in Resources */ = {isa = PBXBuildFile; fileRef = 7492FAE2217FBDBC00ED2C69 /* settings-general-alt.json */; }; 7497376A2141F2BE0008C490 /* top-performers-week-alt.json in Resources */ = {isa = PBXBuildFile; fileRef = 749737692141F2BE0008C490 /* top-performers-week-alt.json */; }; 74A1196C2110F4BB00E1E5F0 /* OrderStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74A1196B2110F4BB00E1E5F0 /* OrderStats.swift */; }; 74A1D263211898F000931DFA /* site-visits-day.json in Resources */ = {isa = PBXBuildFile; fileRef = 74A1D25F211898F000931DFA /* site-visits-day.json */; }; @@ -148,6 +149,7 @@ 748D4249210F92EA00CF7D1B /* OrderStatsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStatsItem.swift; sourceTree = ""; }; 748D424B210FA34400CF7D1B /* OrderStatsMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStatsMapper.swift; sourceTree = ""; }; 748D424D210FB1F500CF7D1B /* order-stats-day.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "order-stats-day.json"; sourceTree = ""; }; + 7492FAE2217FBDBC00ED2C69 /* settings-general-alt.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "settings-general-alt.json"; sourceTree = ""; }; 749737692141F2BE0008C490 /* top-performers-week-alt.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "top-performers-week-alt.json"; sourceTree = ""; }; 74A1196B2110F4BB00E1E5F0 /* OrderStats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStats.swift; sourceTree = ""; }; 74A1D25F211898F000931DFA /* site-visits-day.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-visits-day.json"; sourceTree = ""; }; @@ -468,6 +470,7 @@ B58D10C52114D1F100107ED4 /* order-stats.json */, 7412A51021702E9700994370 /* order-stats-alt.json */, 74046E20217A73D0007DD7BF /* settings-general.json */, + 7492FAE2217FBDBC00ED2C69 /* settings-general-alt.json */, B56C1EB920EA7D2C00D749F9 /* sites.json */, 74A1D25F211898F000931DFA /* site-visits-day.json */, 74A1D260211898F000931DFA /* site-visits-week.json */, @@ -684,6 +687,7 @@ 74A1D265211898F000931DFA /* site-visits-month.json in Resources */, B58D10C62114D1F200107ED4 /* order-stats.json in Resources */, 74ABA1C5213F17AA00FFAD30 /* top-performers-day.json in Resources */, + 7492FAE3217FBDBC00ED2C69 /* settings-general-alt.json in Resources */, 74C8F07020EEC3A800B6EDC9 /* broken-notes.json in Resources */, 74E30951216E8DCE00ABCE4C /* site-visits-alt.json in Resources */, ); diff --git a/Networking/Networking/Model/SiteSetting.swift b/Networking/Networking/Model/SiteSetting.swift index 85d59472a0c..f41dd4be793 100644 --- a/Networking/Networking/Model/SiteSetting.swift +++ b/Networking/Networking/Model/SiteSetting.swift @@ -74,6 +74,11 @@ extension SiteSetting: Comparable { return lhs.settingID < rhs.settingID || (lhs.settingID == rhs.settingID && lhs.label < rhs.label) } + + public static func > (lhs: SiteSetting, rhs: SiteSetting) -> Bool { + return lhs.settingID > rhs.settingID || + (lhs.settingID == rhs.settingID && lhs.label > rhs.label) + } } diff --git a/Networking/NetworkingTests/Responses/settings-general-alt.json b/Networking/NetworkingTests/Responses/settings-general-alt.json new file mode 100644 index 00000000000..4212ce1b3fe --- /dev/null +++ b/Networking/NetworkingTests/Responses/settings-general-alt.json @@ -0,0 +1,2768 @@ +{ + "data": [ + { + "id": "woocommerce_store_address", + "label": "Address line 1", + "description": "The street address for your business location.", + "type": "text", + "default": "", + "tip": "The street address for your business location.", + "value": "", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_store_address" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_store_address_2", + "label": "Address line 2", + "description": "An additional, optional address line for your business location.", + "type": "text", + "default": "", + "tip": "An additional, optional address line for your business location.", + "value": "", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_store_address_2" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_store_city", + "label": "City", + "description": "The city in which your business is located.", + "type": "text", + "default": "", + "tip": "The city in which your business is located.", + "value": "Auburn", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_store_city" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_default_country", + "label": "Country / State", + "description": "The country and state or province, if any, in which your business is located.", + "type": "select", + "default": "GB", + "tip": "The country and state or province, if any, in which your business is located.", + "value": "US:NY", + "options": { + "AX": "Åland Islands", + "AF": "Afghanistan", + "AL": "Albania", + "DZ": "Algeria", + "AS": "American Samoa", + "AD": "Andorra", + "AO:BGO": "Angola - Bengo", + "AO:BLU": "Angola - Benguela", + "AO:BIE": "Angola - Bié", + "AO:CAB": "Angola - Cabinda", + "AO:CNN": "Angola - Cunene", + "AO:HUA": "Angola - Huambo", + "AO:HUI": "Angola - Huíla", + "AO:CCU": "Angola - Kuando Kubango", + "AO:CNO": "Angola - Kwanza-Norte", + "AO:CUS": "Angola - Kwanza-Sul", + "AO:LUA": "Angola - Luanda", + "AO:LNO": "Angola - Lunda-Norte", + "AO:LSU": "Angola - Lunda-Sul", + "AO:MAL": "Angola - Malanje", + "AO:MOX": "Angola - Moxico", + "AO:NAM": "Angola - Namibe", + "AO:UIG": "Angola - Uíge", + "AO:ZAI": "Angola - Zaire", + "AI": "Anguilla", + "AQ": "Antarctica", + "AG": "Antigua and Barbuda", + "AR:C": "Argentina - Ciudad Autónoma de Buenos Aires", + "AR:B": "Argentina - Buenos Aires", + "AR:K": "Argentina - Catamarca", + "AR:H": "Argentina - Chaco", + "AR:U": "Argentina - Chubut", + "AR:X": "Argentina - Córdoba", + "AR:W": "Argentina - Corrientes", + "AR:E": "Argentina - Entre Ríos", + "AR:P": "Argentina - Formosa", + "AR:Y": "Argentina - Jujuy", + "AR:L": "Argentina - La Pampa", + "AR:F": "Argentina - La Rioja", + "AR:M": "Argentina - Mendoza", + "AR:N": "Argentina - Misiones", + "AR:Q": "Argentina - Neuquén", + "AR:R": "Argentina - Río Negro", + "AR:A": "Argentina - Salta", + "AR:J": "Argentina - San Juan", + "AR:D": "Argentina - San Luis", + "AR:Z": "Argentina - Santa Cruz", + "AR:S": "Argentina - Santa Fe", + "AR:G": "Argentina - Santiago del Estero", + "AR:V": "Argentina - Tierra del Fuego", + "AR:T": "Argentina - Tucumán", + "AM": "Armenia", + "AW": "Aruba", + "AU:ACT": "Australia - Australian Capital Territory", + "AU:NSW": "Australia - New South Wales", + "AU:NT": "Australia - Northern Territory", + "AU:QLD": "Australia - Queensland", + "AU:SA": "Australia - South Australia", + "AU:TAS": "Australia - Tasmania", + "AU:VIC": "Australia - Victoria", + "AU:WA": "Australia - Western Australia", + "AT": "Austria", + "AZ": "Azerbaijan", + "BS": "Bahamas", + "BH": "Bahrain", + "BD:BD-05": "Bangladesh - Bagerhat", + "BD:BD-01": "Bangladesh - Bandarban", + "BD:BD-02": "Bangladesh - Barguna", + "BD:BD-06": "Bangladesh - Barishal", + "BD:BD-07": "Bangladesh - Bhola", + "BD:BD-03": "Bangladesh - Bogura", + "BD:BD-04": "Bangladesh - Brahmanbaria", + "BD:BD-09": "Bangladesh - Chandpur", + "BD:BD-10": "Bangladesh - Chattogram", + "BD:BD-12": "Bangladesh - Chuadanga", + "BD:BD-11": "Bangladesh - Cox's Bazar", + "BD:BD-08": "Bangladesh - Cumilla", + "BD:BD-13": "Bangladesh - Dhaka", + "BD:BD-14": "Bangladesh - Dinajpur", + "BD:BD-15": "Bangladesh - Faridpur ", + "BD:BD-16": "Bangladesh - Feni", + "BD:BD-19": "Bangladesh - Gaibandha", + "BD:BD-18": "Bangladesh - Gazipur", + "BD:BD-17": "Bangladesh - Gopalganj", + "BD:BD-20": "Bangladesh - Habiganj", + "BD:BD-21": "Bangladesh - Jamalpur", + "BD:BD-22": "Bangladesh - Jashore", + "BD:BD-25": "Bangladesh - Jhalokati", + "BD:BD-23": "Bangladesh - Jhenaidah", + "BD:BD-24": "Bangladesh - Joypurhat", + "BD:BD-29": "Bangladesh - Khagrachhari", + "BD:BD-27": "Bangladesh - Khulna", + "BD:BD-26": "Bangladesh - Kishoreganj", + "BD:BD-28": "Bangladesh - Kurigram", + "BD:BD-30": "Bangladesh - Kushtia", + "BD:BD-31": "Bangladesh - Lakshmipur", + "BD:BD-32": "Bangladesh - Lalmonirhat", + "BD:BD-36": "Bangladesh - Madaripur", + "BD:BD-37": "Bangladesh - Magura", + "BD:BD-33": "Bangladesh - Manikganj ", + "BD:BD-39": "Bangladesh - Meherpur", + "BD:BD-38": "Bangladesh - Moulvibazar", + "BD:BD-35": "Bangladesh - Munshiganj", + "BD:BD-34": "Bangladesh - Mymensingh", + "BD:BD-48": "Bangladesh - Naogaon", + "BD:BD-43": "Bangladesh - Narail", + "BD:BD-40": "Bangladesh - Narayanganj", + "BD:BD-42": "Bangladesh - Narsingdi", + "BD:BD-44": "Bangladesh - Natore", + "BD:BD-45": "Bangladesh - Nawabganj", + "BD:BD-41": "Bangladesh - Netrakona", + "BD:BD-46": "Bangladesh - Nilphamari", + "BD:BD-47": "Bangladesh - Noakhali", + "BD:BD-49": "Bangladesh - Pabna", + "BD:BD-52": "Bangladesh - Panchagarh", + "BD:BD-51": "Bangladesh - Patuakhali", + "BD:BD-50": "Bangladesh - Pirojpur", + "BD:BD-53": "Bangladesh - Rajbari", + "BD:BD-54": "Bangladesh - Rajshahi", + "BD:BD-56": "Bangladesh - Rangamati", + "BD:BD-55": "Bangladesh - Rangpur", + "BD:BD-58": "Bangladesh - Satkhira", + "BD:BD-62": "Bangladesh - Shariatpur", + "BD:BD-57": "Bangladesh - Sherpur", + "BD:BD-59": "Bangladesh - Sirajganj", + "BD:BD-61": "Bangladesh - Sunamganj", + "BD:BD-60": "Bangladesh - Sylhet", + "BD:BD-63": "Bangladesh - Tangail", + "BD:BD-64": "Bangladesh - Thakurgaon", + "BB": "Barbados", + "BY": "Belarus", + "PW": "Belau", + "BE": "Belgium", + "BZ": "Belize", + "BJ": "Benin", + "BM": "Bermuda", + "BT": "Bhutan", + "BO:B": "Bolivia - Chuquisaca", + "BO:H": "Bolivia - Beni", + "BO:C": "Bolivia - Cochabamba", + "BO:L": "Bolivia - La Paz", + "BO:O": "Bolivia - Oruro", + "BO:N": "Bolivia - Pando", + "BO:P": "Bolivia - Potosí", + "BO:S": "Bolivia - Santa Cruz", + "BO:T": "Bolivia - Tarija", + "BQ": "Bonaire, Saint Eustatius and Saba", + "BA": "Bosnia and Herzegovina", + "BW": "Botswana", + "BV": "Bouvet Island", + "BR:AC": "Brazil - Acre", + "BR:AL": "Brazil - Alagoas", + "BR:AP": "Brazil - Amapá", + "BR:AM": "Brazil - Amazonas", + "BR:BA": "Brazil - Bahia", + "BR:CE": "Brazil - Ceará", + "BR:DF": "Brazil - Distrito Federal", + "BR:ES": "Brazil - Espírito Santo", + "BR:GO": "Brazil - Goiás", + "BR:MA": "Brazil - Maranhão", + "BR:MT": "Brazil - Mato Grosso", + "BR:MS": "Brazil - Mato Grosso do Sul", + "BR:MG": "Brazil - Minas Gerais", + "BR:PA": "Brazil - Pará", + "BR:PB": "Brazil - Paraíba", + "BR:PR": "Brazil - Paraná", + "BR:PE": "Brazil - Pernambuco", + "BR:PI": "Brazil - Piauí", + "BR:RJ": "Brazil - Rio de Janeiro", + "BR:RN": "Brazil - Rio Grande do Norte", + "BR:RS": "Brazil - Rio Grande do Sul", + "BR:RO": "Brazil - Rondônia", + "BR:RR": "Brazil - Roraima", + "BR:SC": "Brazil - Santa Catarina", + "BR:SP": "Brazil - São Paulo", + "BR:SE": "Brazil - Sergipe", + "BR:TO": "Brazil - Tocantins", + "IO": "British Indian Ocean Territory", + "VG": "British Virgin Islands", + "BN": "Brunei", + "BG:BG-01": "Bulgaria - Blagoevgrad", + "BG:BG-02": "Bulgaria - Burgas", + "BG:BG-08": "Bulgaria - Dobrich", + "BG:BG-07": "Bulgaria - Gabrovo", + "BG:BG-26": "Bulgaria - Haskovo", + "BG:BG-09": "Bulgaria - Kardzhali", + "BG:BG-10": "Bulgaria - Kyustendil", + "BG:BG-11": "Bulgaria - Lovech", + "BG:BG-12": "Bulgaria - Montana", + "BG:BG-13": "Bulgaria - Pazardzhik", + "BG:BG-14": "Bulgaria - Pernik", + "BG:BG-15": "Bulgaria - Pleven", + "BG:BG-16": "Bulgaria - Plovdiv", + "BG:BG-17": "Bulgaria - Razgrad", + "BG:BG-18": "Bulgaria - Ruse", + "BG:BG-27": "Bulgaria - Shumen", + "BG:BG-19": "Bulgaria - Silistra", + "BG:BG-20": "Bulgaria - Sliven", + "BG:BG-21": "Bulgaria - Smolyan", + "BG:BG-23": "Bulgaria - Sofia", + "BG:BG-22": "Bulgaria - Sofia-Grad", + "BG:BG-24": "Bulgaria - Stara Zagora", + "BG:BG-25": "Bulgaria - Targovishte", + "BG:BG-03": "Bulgaria - Varna", + "BG:BG-04": "Bulgaria - Veliko Tarnovo", + "BG:BG-05": "Bulgaria - Vidin", + "BG:BG-06": "Bulgaria - Vratsa", + "BG:BG-28": "Bulgaria - Yambol", + "BF": "Burkina Faso", + "BI": "Burundi", + "KH": "Cambodia", + "CM": "Cameroon", + "CA:AB": "Canada - Alberta", + "CA:BC": "Canada - British Columbia", + "CA:MB": "Canada - Manitoba", + "CA:NB": "Canada - New Brunswick", + "CA:NL": "Canada - Newfoundland and Labrador", + "CA:NT": "Canada - Northwest Territories", + "CA:NS": "Canada - Nova Scotia", + "CA:NU": "Canada - Nunavut", + "CA:ON": "Canada - Ontario", + "CA:PE": "Canada - Prince Edward Island", + "CA:QC": "Canada - Quebec", + "CA:SK": "Canada - Saskatchewan", + "CA:YT": "Canada - Yukon Territory", + "CV": "Cape Verde", + "KY": "Cayman Islands", + "CF": "Central African Republic", + "TD": "Chad", + "CL": "Chile", + "CN:CN1": "China - Yunnan / 云南", + "CN:CN2": "China - Beijing / 北京", + "CN:CN3": "China - Tianjin / 天津", + "CN:CN4": "China - Hebei / 河北", + "CN:CN5": "China - Shanxi / 山西", + "CN:CN6": "China - Inner Mongolia / 內蒙古", + "CN:CN7": "China - Liaoning / 辽宁", + "CN:CN8": "China - Jilin / 吉林", + "CN:CN9": "China - Heilongjiang / 黑龙江", + "CN:CN10": "China - Shanghai / 上海", + "CN:CN11": "China - Jiangsu / 江苏", + "CN:CN12": "China - Zhejiang / 浙江", + "CN:CN13": "China - Anhui / 安徽", + "CN:CN14": "China - Fujian / 福建", + "CN:CN15": "China - Jiangxi / 江西", + "CN:CN16": "China - Shandong / 山东", + "CN:CN17": "China - Henan / 河南", + "CN:CN18": "China - Hubei / 湖北", + "CN:CN19": "China - Hunan / 湖南", + "CN:CN20": "China - Guangdong / 广东", + "CN:CN21": "China - Guangxi Zhuang / 广西壮族", + "CN:CN22": "China - Hainan / 海南", + "CN:CN23": "China - Chongqing / 重庆", + "CN:CN24": "China - Sichuan / 四川", + "CN:CN25": "China - Guizhou / 贵州", + "CN:CN26": "China - Shaanxi / 陕西", + "CN:CN27": "China - Gansu / 甘肃", + "CN:CN28": "China - Qinghai / 青海", + "CN:CN29": "China - Ningxia Hui / 宁夏", + "CN:CN30": "China - Macau / 澳门", + "CN:CN31": "China - Tibet / 西藏", + "CN:CN32": "China - Xinjiang / 新疆", + "CX": "Christmas Island", + "CC": "Cocos (Keeling) Islands", + "CO": "Colombia", + "KM": "Comoros", + "CG": "Congo (Brazzaville)", + "CD": "Congo (Kinshasa)", + "CK": "Cook Islands", + "CR": "Costa Rica", + "HR": "Croatia", + "CU": "Cuba", + "CW": "Curaçao", + "CY": "Cyprus", + "CZ": "Czech Republic", + "DK": "Denmark", + "DJ": "Djibouti", + "DM": "Dominica", + "DO": "Dominican Republic", + "EC": "Ecuador", + "EG": "Egypt", + "SV": "El Salvador", + "GQ": "Equatorial Guinea", + "ER": "Eritrea", + "EE": "Estonia", + "ET": "Ethiopia", + "FK": "Falkland Islands", + "FO": "Faroe Islands", + "FJ": "Fiji", + "FI": "Finland", + "FR": "France", + "GF": "French Guiana", + "PF": "French Polynesia", + "TF": "French Southern Territories", + "GA": "Gabon", + "GM": "Gambia", + "GE": "Georgia", + "DE": "Germany", + "GH": "Ghana", + "GI": "Gibraltar", + "GR:I": "Greece - Αττική", + "GR:A": "Greece - Ανατολική Μακεδονία και Θράκη", + "GR:B": "Greece - Κεντρική Μακεδονία", + "GR:C": "Greece - Δυτική Μακεδονία", + "GR:D": "Greece - Ήπειρος", + "GR:E": "Greece - Θεσσαλία", + "GR:F": "Greece - Ιόνιοι Νήσοι", + "GR:G": "Greece - Δυτική Ελλάδα", + "GR:H": "Greece - Στερεά Ελλάδα", + "GR:J": "Greece - Πελοπόννησος", + "GR:K": "Greece - Βόρειο Αιγαίο", + "GR:L": "Greece - Νότιο Αιγαίο", + "GR:M": "Greece - Κρήτη", + "GL": "Greenland", + "GD": "Grenada", + "GP": "Guadeloupe", + "GU": "Guam", + "GT": "Guatemala", + "GG": "Guernsey", + "GN": "Guinea", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HT": "Haiti", + "HM": "Heard Island and McDonald Islands", + "HN": "Honduras", + "HK:HONG KONG": "Hong Kong - Hong Kong Island", + "HK:KOWLOON": "Hong Kong - Kowloon", + "HK:NEW TERRITORIES": "Hong Kong - New Territories", + "HU:BK": "Hungary - Bács-Kiskun", + "HU:BE": "Hungary - Békés", + "HU:BA": "Hungary - Baranya", + "HU:BZ": "Hungary - Borsod-Abaúj-Zemplén", + "HU:BU": "Hungary - Budapest", + "HU:CS": "Hungary - Csongrád", + "HU:FE": "Hungary - Fejér", + "HU:GS": "Hungary - Győr-Moson-Sopron", + "HU:HB": "Hungary - Hajdú-Bihar", + "HU:HE": "Hungary - Heves", + "HU:JN": "Hungary - Jász-Nagykun-Szolnok", + "HU:KE": "Hungary - Komárom-Esztergom", + "HU:NO": "Hungary - Nógrád", + "HU:PE": "Hungary - Pest", + "HU:SO": "Hungary - Somogy", + "HU:SZ": "Hungary - Szabolcs-Szatmár-Bereg", + "HU:TO": "Hungary - Tolna", + "HU:VA": "Hungary - Vas", + "HU:VE": "Hungary - Veszprém", + "HU:ZA": "Hungary - Zala", + "IS": "Iceland", + "IN:AP": "India - Andhra Pradesh", + "IN:AR": "India - Arunachal Pradesh", + "IN:AS": "India - Assam", + "IN:BR": "India - Bihar", + "IN:CT": "India - Chhattisgarh", + "IN:GA": "India - Goa", + "IN:GJ": "India - Gujarat", + "IN:HR": "India - Haryana", + "IN:HP": "India - Himachal Pradesh", + "IN:JK": "India - Jammu and Kashmir", + "IN:JH": "India - Jharkhand", + "IN:KA": "India - Karnataka", + "IN:KL": "India - Kerala", + "IN:MP": "India - Madhya Pradesh", + "IN:MH": "India - Maharashtra", + "IN:MN": "India - Manipur", + "IN:ML": "India - Meghalaya", + "IN:MZ": "India - Mizoram", + "IN:NL": "India - Nagaland", + "IN:OR": "India - Orissa", + "IN:PB": "India - Punjab", + "IN:RJ": "India - Rajasthan", + "IN:SK": "India - Sikkim", + "IN:TN": "India - Tamil Nadu", + "IN:TS": "India - Telangana", + "IN:TR": "India - Tripura", + "IN:UK": "India - Uttarakhand", + "IN:UP": "India - Uttar Pradesh", + "IN:WB": "India - West Bengal", + "IN:AN": "India - Andaman and Nicobar Islands", + "IN:CH": "India - Chandigarh", + "IN:DN": "India - Dadra and Nagar Haveli", + "IN:DD": "India - Daman and Diu", + "IN:DL": "India - Delhi", + "IN:LD": "India - Lakshadeep", + "IN:PY": "India - Pondicherry (Puducherry)", + "ID:AC": "Indonesia - Daerah Istimewa Aceh", + "ID:SU": "Indonesia - Sumatera Utara", + "ID:SB": "Indonesia - Sumatera Barat", + "ID:RI": "Indonesia - Riau", + "ID:KR": "Indonesia - Kepulauan Riau", + "ID:JA": "Indonesia - Jambi", + "ID:SS": "Indonesia - Sumatera Selatan", + "ID:BB": "Indonesia - Bangka Belitung", + "ID:BE": "Indonesia - Bengkulu", + "ID:LA": "Indonesia - Lampung", + "ID:JK": "Indonesia - DKI Jakarta", + "ID:JB": "Indonesia - Jawa Barat", + "ID:BT": "Indonesia - Banten", + "ID:JT": "Indonesia - Jawa Tengah", + "ID:JI": "Indonesia - Jawa Timur", + "ID:YO": "Indonesia - Daerah Istimewa Yogyakarta", + "ID:BA": "Indonesia - Bali", + "ID:NB": "Indonesia - Nusa Tenggara Barat", + "ID:NT": "Indonesia - Nusa Tenggara Timur", + "ID:KB": "Indonesia - Kalimantan Barat", + "ID:KT": "Indonesia - Kalimantan Tengah", + "ID:KI": "Indonesia - Kalimantan Timur", + "ID:KS": "Indonesia - Kalimantan Selatan", + "ID:KU": "Indonesia - Kalimantan Utara", + "ID:SA": "Indonesia - Sulawesi Utara", + "ID:ST": "Indonesia - Sulawesi Tengah", + "ID:SG": "Indonesia - Sulawesi Tenggara", + "ID:SR": "Indonesia - Sulawesi Barat", + "ID:SN": "Indonesia - Sulawesi Selatan", + "ID:GO": "Indonesia - Gorontalo", + "ID:MA": "Indonesia - Maluku", + "ID:MU": "Indonesia - Maluku Utara", + "ID:PA": "Indonesia - Papua", + "ID:PB": "Indonesia - Papua Barat", + "IR:KHZ": "Iran - Khuzestan (خوزستان)", + "IR:THR": "Iran - Tehran (تهران)", + "IR:ILM": "Iran - Ilaam (ایلام)", + "IR:BHR": "Iran - Bushehr (بوشهر)", + "IR:ADL": "Iran - Ardabil (اردبیل)", + "IR:ESF": "Iran - Isfahan (اصفهان)", + "IR:YZD": "Iran - Yazd (یزد)", + "IR:KRH": "Iran - Kermanshah (کرمانشاه)", + "IR:KRN": "Iran - Kerman (کرمان)", + "IR:HDN": "Iran - Hamadan (همدان)", + "IR:GZN": "Iran - Ghazvin (قزوین)", + "IR:ZJN": "Iran - Zanjan (زنجان)", + "IR:LRS": "Iran - Luristan (لرستان)", + "IR:ABZ": "Iran - Alborz (البرز)", + "IR:EAZ": "Iran - East Azarbaijan (آذربایجان شرقی)", + "IR:WAZ": "Iran - West Azarbaijan (آذربایجان غربی)", + "IR:CHB": "Iran - Chaharmahal and Bakhtiari (چهارمحال و بختیاری)", + "IR:SKH": "Iran - South Khorasan (خراسان جنوبی)", + "IR:RKH": "Iran - Razavi Khorasan (خراسان رضوی)", + "IR:NKH": "Iran - North Khorasan (خراسان شمالی)", + "IR:SMN": "Iran - Semnan (سمنان)", + "IR:FRS": "Iran - Fars (فارس)", + "IR:QHM": "Iran - Qom (قم)", + "IR:KRD": "Iran - Kurdistan / کردستان)", + "IR:KBD": "Iran - Kohgiluyeh and BoyerAhmad (کهگیلوییه و بویراحمد)", + "IR:GLS": "Iran - Golestan (گلستان)", + "IR:GIL": "Iran - Gilan (گیلان)", + "IR:MZN": "Iran - Mazandaran (مازندران)", + "IR:MKZ": "Iran - Markazi (مرکزی)", + "IR:HRZ": "Iran - Hormozgan (هرمزگان)", + "IR:SBN": "Iran - Sistan and Baluchestan (سیستان و بلوچستان)", + "IQ": "Iraq", + "IE:CW": "Ireland - Carlow", + "IE:CN": "Ireland - Cavan", + "IE:CE": "Ireland - Clare", + "IE:CO": "Ireland - Cork", + "IE:DL": "Ireland - Donegal", + "IE:D": "Ireland - Dublin", + "IE:G": "Ireland - Galway", + "IE:KY": "Ireland - Kerry", + "IE:KE": "Ireland - Kildare", + "IE:KK": "Ireland - Kilkenny", + "IE:LS": "Ireland - Laois", + "IE:LM": "Ireland - Leitrim", + "IE:LK": "Ireland - Limerick", + "IE:LD": "Ireland - Longford", + "IE:LH": "Ireland - Louth", + "IE:MO": "Ireland - Mayo", + "IE:MH": "Ireland - Meath", + "IE:MN": "Ireland - Monaghan", + "IE:OY": "Ireland - Offaly", + "IE:RN": "Ireland - Roscommon", + "IE:SO": "Ireland - Sligo", + "IE:TA": "Ireland - Tipperary", + "IE:WD": "Ireland - Waterford", + "IE:WH": "Ireland - Westmeath", + "IE:WX": "Ireland - Wexford", + "IE:WW": "Ireland - Wicklow", + "IM": "Isle of Man", + "IL": "Israel", + "IT:AG": "Italy - Agrigento", + "IT:AL": "Italy - Alessandria", + "IT:AN": "Italy - Ancona", + "IT:AO": "Italy - Aosta", + "IT:AR": "Italy - Arezzo", + "IT:AP": "Italy - Ascoli Piceno", + "IT:AT": "Italy - Asti", + "IT:AV": "Italy - Avellino", + "IT:BA": "Italy - Bari", + "IT:BT": "Italy - Barletta-Andria-Trani", + "IT:BL": "Italy - Belluno", + "IT:BN": "Italy - Benevento", + "IT:BG": "Italy - Bergamo", + "IT:BI": "Italy - Biella", + "IT:BO": "Italy - Bologna", + "IT:BZ": "Italy - Bolzano", + "IT:BS": "Italy - Brescia", + "IT:BR": "Italy - Brindisi", + "IT:CA": "Italy - Cagliari", + "IT:CL": "Italy - Caltanissetta", + "IT:CB": "Italy - Campobasso", + "IT:CI": "Italy - Carbonia-Iglesias", + "IT:CE": "Italy - Caserta", + "IT:CT": "Italy - Catania", + "IT:CZ": "Italy - Catanzaro", + "IT:CH": "Italy - Chieti", + "IT:CO": "Italy - Como", + "IT:CS": "Italy - Cosenza", + "IT:CR": "Italy - Cremona", + "IT:KR": "Italy - Crotone", + "IT:CN": "Italy - Cuneo", + "IT:EN": "Italy - Enna", + "IT:FM": "Italy - Fermo", + "IT:FE": "Italy - Ferrara", + "IT:FI": "Italy - Firenze", + "IT:FG": "Italy - Foggia", + "IT:FC": "Italy - Forlì-Cesena", + "IT:FR": "Italy - Frosinone", + "IT:GE": "Italy - Genova", + "IT:GO": "Italy - Gorizia", + "IT:GR": "Italy - Grosseto", + "IT:IM": "Italy - Imperia", + "IT:IS": "Italy - Isernia", + "IT:SP": "Italy - La Spezia", + "IT:AQ": "Italy - L'Aquila", + "IT:LT": "Italy - Latina", + "IT:LE": "Italy - Lecce", + "IT:LC": "Italy - Lecco", + "IT:LI": "Italy - Livorno", + "IT:LO": "Italy - Lodi", + "IT:LU": "Italy - Lucca", + "IT:MC": "Italy - Macerata", + "IT:MN": "Italy - Mantova", + "IT:MS": "Italy - Massa-Carrara", + "IT:MT": "Italy - Matera", + "IT:ME": "Italy - Messina", + "IT:MI": "Italy - Milano", + "IT:MO": "Italy - Modena", + "IT:MB": "Italy - Monza e della Brianza", + "IT:NA": "Italy - Napoli", + "IT:NO": "Italy - Novara", + "IT:NU": "Italy - Nuoro", + "IT:OT": "Italy - Olbia-Tempio", + "IT:OR": "Italy - Oristano", + "IT:PD": "Italy - Padova", + "IT:PA": "Italy - Palermo", + "IT:PR": "Italy - Parma", + "IT:PV": "Italy - Pavia", + "IT:PG": "Italy - Perugia", + "IT:PU": "Italy - Pesaro e Urbino", + "IT:PE": "Italy - Pescara", + "IT:PC": "Italy - Piacenza", + "IT:PI": "Italy - Pisa", + "IT:PT": "Italy - Pistoia", + "IT:PN": "Italy - Pordenone", + "IT:PZ": "Italy - Potenza", + "IT:PO": "Italy - Prato", + "IT:RG": "Italy - Ragusa", + "IT:RA": "Italy - Ravenna", + "IT:RC": "Italy - Reggio Calabria", + "IT:RE": "Italy - Reggio Emilia", + "IT:RI": "Italy - Rieti", + "IT:RN": "Italy - Rimini", + "IT:RM": "Italy - Roma", + "IT:RO": "Italy - Rovigo", + "IT:SA": "Italy - Salerno", + "IT:VS": "Italy - Medio Campidano", + "IT:SS": "Italy - Sassari", + "IT:SV": "Italy - Savona", + "IT:SI": "Italy - Siena", + "IT:SR": "Italy - Siracusa", + "IT:SO": "Italy - Sondrio", + "IT:TA": "Italy - Taranto", + "IT:TE": "Italy - Teramo", + "IT:TR": "Italy - Terni", + "IT:TO": "Italy - Torino", + "IT:OG": "Italy - Ogliastra", + "IT:TP": "Italy - Trapani", + "IT:TN": "Italy - Trento", + "IT:TV": "Italy - Treviso", + "IT:TS": "Italy - Trieste", + "IT:UD": "Italy - Udine", + "IT:VA": "Italy - Varese", + "IT:VE": "Italy - Venezia", + "IT:VB": "Italy - Verbano-Cusio-Ossola", + "IT:VC": "Italy - Vercelli", + "IT:VR": "Italy - Verona", + "IT:VV": "Italy - Vibo Valentia", + "IT:VI": "Italy - Vicenza", + "IT:VT": "Italy - Viterbo", + "CI": "Ivory Coast", + "JM": "Jamaica", + "JP:JP01": "Japan - Hokkaido", + "JP:JP02": "Japan - Aomori", + "JP:JP03": "Japan - Iwate", + "JP:JP04": "Japan - Miyagi", + "JP:JP05": "Japan - Akita", + "JP:JP06": "Japan - Yamagata", + "JP:JP07": "Japan - Fukushima", + "JP:JP08": "Japan - Ibaraki", + "JP:JP09": "Japan - Tochigi", + "JP:JP10": "Japan - Gunma", + "JP:JP11": "Japan - Saitama", + "JP:JP12": "Japan - Chiba", + "JP:JP13": "Japan - Tokyo", + "JP:JP14": "Japan - Kanagawa", + "JP:JP15": "Japan - Niigata", + "JP:JP16": "Japan - Toyama", + "JP:JP17": "Japan - Ishikawa", + "JP:JP18": "Japan - Fukui", + "JP:JP19": "Japan - Yamanashi", + "JP:JP20": "Japan - Nagano", + "JP:JP21": "Japan - Gifu", + "JP:JP22": "Japan - Shizuoka", + "JP:JP23": "Japan - Aichi", + "JP:JP24": "Japan - Mie", + "JP:JP25": "Japan - Shiga", + "JP:JP26": "Japan - Kyoto", + "JP:JP27": "Japan - Osaka", + "JP:JP28": "Japan - Hyogo", + "JP:JP29": "Japan - Nara", + "JP:JP30": "Japan - Wakayama", + "JP:JP31": "Japan - Tottori", + "JP:JP32": "Japan - Shimane", + "JP:JP33": "Japan - Okayama", + "JP:JP34": "Japan - Hiroshima", + "JP:JP35": "Japan - Yamaguchi", + "JP:JP36": "Japan - Tokushima", + "JP:JP37": "Japan - Kagawa", + "JP:JP38": "Japan - Ehime", + "JP:JP39": "Japan - Kochi", + "JP:JP40": "Japan - Fukuoka", + "JP:JP41": "Japan - Saga", + "JP:JP42": "Japan - Nagasaki", + "JP:JP43": "Japan - Kumamoto", + "JP:JP44": "Japan - Oita", + "JP:JP45": "Japan - Miyazaki", + "JP:JP46": "Japan - Kagoshima", + "JP:JP47": "Japan - Okinawa", + "JE": "Jersey", + "JO": "Jordan", + "KZ": "Kazakhstan", + "KE": "Kenya", + "KI": "Kiribati", + "KW": "Kuwait", + "KG": "Kyrgyzstan", + "LA": "Laos", + "LV": "Latvia", + "LB": "Lebanon", + "LS": "Lesotho", + "LR:BM": "Liberia - Bomi", + "LR:BN": "Liberia - Bong", + "LR:GA": "Liberia - Gbarpolu", + "LR:GB": "Liberia - Grand Bassa", + "LR:GC": "Liberia - Grand Cape Mount", + "LR:GG": "Liberia - Grand Gedeh", + "LR:GK": "Liberia - Grand Kru", + "LR:LO": "Liberia - Lofa", + "LR:MA": "Liberia - Margibi", + "LR:MY": "Liberia - Maryland", + "LR:MO": "Liberia - Montserrado", + "LR:NM": "Liberia - Nimba", + "LR:RV": "Liberia - Rivercess", + "LR:RG": "Liberia - River Gee", + "LR:SN": "Liberia - Sinoe", + "LY": "Libya", + "LI": "Liechtenstein", + "LT": "Lithuania", + "LU": "Luxembourg", + "MO": "Macao S.A.R., China", + "MK": "Macedonia", + "MG": "Madagascar", + "MW": "Malawi", + "MY:JHR": "Malaysia - Johor", + "MY:KDH": "Malaysia - Kedah", + "MY:KTN": "Malaysia - Kelantan", + "MY:LBN": "Malaysia - Labuan", + "MY:MLK": "Malaysia - Malacca (Melaka)", + "MY:NSN": "Malaysia - Negeri Sembilan", + "MY:PHG": "Malaysia - Pahang", + "MY:PNG": "Malaysia - Penang (Pulau Pinang)", + "MY:PRK": "Malaysia - Perak", + "MY:PLS": "Malaysia - Perlis", + "MY:SBH": "Malaysia - Sabah", + "MY:SWK": "Malaysia - Sarawak", + "MY:SGR": "Malaysia - Selangor", + "MY:TRG": "Malaysia - Terengganu", + "MY:PJY": "Malaysia - Putrajaya", + "MY:KUL": "Malaysia - Kuala Lumpur", + "MV": "Maldives", + "ML": "Mali", + "MT": "Malta", + "MH": "Marshall Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MU": "Mauritius", + "YT": "Mayotte", + "MX:DF": "Mexico - Ciudad de México", + "MX:JA": "Mexico - Jalisco", + "MX:NL": "Mexico - Nuevo León", + "MX:AG": "Mexico - Aguascalientes", + "MX:BC": "Mexico - Baja California", + "MX:BS": "Mexico - Baja California Sur", + "MX:CM": "Mexico - Campeche", + "MX:CS": "Mexico - Chiapas", + "MX:CH": "Mexico - Chihuahua", + "MX:CO": "Mexico - Coahuila", + "MX:CL": "Mexico - Colima", + "MX:DG": "Mexico - Durango", + "MX:GT": "Mexico - Guanajuato", + "MX:GR": "Mexico - Guerrero", + "MX:HG": "Mexico - Hidalgo", + "MX:MX": "Mexico - Estado de México", + "MX:MI": "Mexico - Michoacán", + "MX:MO": "Mexico - Morelos", + "MX:NA": "Mexico - Nayarit", + "MX:OA": "Mexico - Oaxaca", + "MX:PU": "Mexico - Puebla", + "MX:QT": "Mexico - Querétaro", + "MX:QR": "Mexico - Quintana Roo", + "MX:SL": "Mexico - San Luis Potosí", + "MX:SI": "Mexico - Sinaloa", + "MX:SO": "Mexico - Sonora", + "MX:TB": "Mexico - Tabasco", + "MX:TM": "Mexico - Tamaulipas", + "MX:TL": "Mexico - Tlaxcala", + "MX:VE": "Mexico - Veracruz", + "MX:YU": "Mexico - Yucatán", + "MX:ZA": "Mexico - Zacatecas", + "FM": "Micronesia", + "MD:C": "Moldova - Chișinău", + "MD:BL": "Moldova - Bălți", + "MD:AN": "Moldova - Anenii Noi", + "MD:BS": "Moldova - Basarabeasca", + "MD:BR": "Moldova - Briceni", + "MD:CH": "Moldova - Cahul", + "MD:CT": "Moldova - Cantemir", + "MD:CL": "Moldova - Călărași", + "MD:CS": "Moldova - Căușeni", + "MD:CM": "Moldova - Cimișlia", + "MD:CR": "Moldova - Criuleni", + "MD:DN": "Moldova - Dondușeni", + "MD:DR": "Moldova - Drochia", + "MD:DB": "Moldova - Dubăsari", + "MD:ED": "Moldova - Edineț", + "MD:FL": "Moldova - Fălești", + "MD:FR": "Moldova - Florești", + "MD:GE": "Moldova - UTA Găgăuzia", + "MD:GL": "Moldova - Glodeni", + "MD:HN": "Moldova - Hîncești", + "MD:IL": "Moldova - Ialoveni", + "MD:LV": "Moldova - Leova", + "MD:NS": "Moldova - Nisporeni", + "MD:OC": "Moldova - Ocnița", + "MD:OR": "Moldova - Orhei", + "MD:RZ": "Moldova - Rezina", + "MD:RS": "Moldova - Rîșcani", + "MD:SG": "Moldova - Sîngerei", + "MD:SR": "Moldova - Soroca", + "MD:ST": "Moldova - Strășeni", + "MD:SD": "Moldova - Șoldănești", + "MD:SV": "Moldova - Ștefan Vodă", + "MD:TR": "Moldova - Taraclia", + "MD:TL": "Moldova - Telenești", + "MD:UN": "Moldova - Ungheni", + "MC": "Monaco", + "MN": "Mongolia", + "ME": "Montenegro", + "MS": "Montserrat", + "MA": "Morocco", + "MZ": "Mozambique", + "MM": "Myanmar", + "NA": "Namibia", + "NR": "Nauru", + "NP:BAG": "Nepal - Bagmati", + "NP:BHE": "Nepal - Bheri", + "NP:DHA": "Nepal - Dhaulagiri", + "NP:GAN": "Nepal - Gandaki", + "NP:JAN": "Nepal - Janakpur", + "NP:KAR": "Nepal - Karnali", + "NP:KOS": "Nepal - Koshi", + "NP:LUM": "Nepal - Lumbini", + "NP:MAH": "Nepal - Mahakali", + "NP:MEC": "Nepal - Mechi", + "NP:NAR": "Nepal - Narayani", + "NP:RAP": "Nepal - Rapti", + "NP:SAG": "Nepal - Sagarmatha", + "NP:SET": "Nepal - Seti", + "NL": "Netherlands", + "NC": "New Caledonia", + "NZ:NL": "New Zealand - Northland", + "NZ:AK": "New Zealand - Auckland", + "NZ:WA": "New Zealand - Waikato", + "NZ:BP": "New Zealand - Bay of Plenty", + "NZ:TK": "New Zealand - Taranaki", + "NZ:GI": "New Zealand - Gisborne", + "NZ:HB": "New Zealand - Hawke’s Bay", + "NZ:MW": "New Zealand - Manawatu-Wanganui", + "NZ:WE": "New Zealand - Wellington", + "NZ:NS": "New Zealand - Nelson", + "NZ:MB": "New Zealand - Marlborough", + "NZ:TM": "New Zealand - Tasman", + "NZ:WC": "New Zealand - West Coast", + "NZ:CT": "New Zealand - Canterbury", + "NZ:OT": "New Zealand - Otago", + "NZ:SL": "New Zealand - Southland", + "NI": "Nicaragua", + "NE": "Niger", + "NG:AB": "Nigeria - Abia", + "NG:FC": "Nigeria - Abuja", + "NG:AD": "Nigeria - Adamawa", + "NG:AK": "Nigeria - Akwa Ibom", + "NG:AN": "Nigeria - Anambra", + "NG:BA": "Nigeria - Bauchi", + "NG:BY": "Nigeria - Bayelsa", + "NG:BE": "Nigeria - Benue", + "NG:BO": "Nigeria - Borno", + "NG:CR": "Nigeria - Cross River", + "NG:DE": "Nigeria - Delta", + "NG:EB": "Nigeria - Ebonyi", + "NG:ED": "Nigeria - Edo", + "NG:EK": "Nigeria - Ekiti", + "NG:EN": "Nigeria - Enugu", + "NG:GO": "Nigeria - Gombe", + "NG:IM": "Nigeria - Imo", + "NG:JI": "Nigeria - Jigawa", + "NG:KD": "Nigeria - Kaduna", + "NG:KN": "Nigeria - Kano", + "NG:KT": "Nigeria - Katsina", + "NG:KE": "Nigeria - Kebbi", + "NG:KO": "Nigeria - Kogi", + "NG:KW": "Nigeria - Kwara", + "NG:LA": "Nigeria - Lagos", + "NG:NA": "Nigeria - Nasarawa", + "NG:NI": "Nigeria - Niger", + "NG:OG": "Nigeria - Ogun", + "NG:ON": "Nigeria - Ondo", + "NG:OS": "Nigeria - Osun", + "NG:OY": "Nigeria - Oyo", + "NG:PL": "Nigeria - Plateau", + "NG:RI": "Nigeria - Rivers", + "NG:SO": "Nigeria - Sokoto", + "NG:TA": "Nigeria - Taraba", + "NG:YO": "Nigeria - Yobe", + "NG:ZA": "Nigeria - Zamfara", + "NU": "Niue", + "NF": "Norfolk Island", + "KP": "North Korea", + "MP": "Northern Mariana Islands", + "NO": "Norway", + "OM": "Oman", + "PK:JK": "Pakistan - Azad Kashmir", + "PK:BA": "Pakistan - Balochistan", + "PK:TA": "Pakistan - FATA", + "PK:GB": "Pakistan - Gilgit Baltistan", + "PK:IS": "Pakistan - Islamabad Capital Territory", + "PK:KP": "Pakistan - Khyber Pakhtunkhwa", + "PK:PB": "Pakistan - Punjab", + "PK:SD": "Pakistan - Sindh", + "PS": "Palestinian Territory", + "PA": "Panama", + "PG": "Papua New Guinea", + "PY": "Paraguay", + "PE:CAL": "Peru - El Callao", + "PE:LMA": "Peru - Municipalidad Metropolitana de Lima", + "PE:AMA": "Peru - Amazonas", + "PE:ANC": "Peru - Ancash", + "PE:APU": "Peru - Apurímac", + "PE:ARE": "Peru - Arequipa", + "PE:AYA": "Peru - Ayacucho", + "PE:CAJ": "Peru - Cajamarca", + "PE:CUS": "Peru - Cusco", + "PE:HUV": "Peru - Huancavelica", + "PE:HUC": "Peru - Huánuco", + "PE:ICA": "Peru - Ica", + "PE:JUN": "Peru - Junín", + "PE:LAL": "Peru - La Libertad", + "PE:LAM": "Peru - Lambayeque", + "PE:LIM": "Peru - Lima", + "PE:LOR": "Peru - Loreto", + "PE:MDD": "Peru - Madre de Dios", + "PE:MOQ": "Peru - Moquegua", + "PE:PAS": "Peru - Pasco", + "PE:PIU": "Peru - Piura", + "PE:PUN": "Peru - Puno", + "PE:SAM": "Peru - San Martín", + "PE:TAC": "Peru - Tacna", + "PE:TUM": "Peru - Tumbes", + "PE:UCA": "Peru - Ucayali", + "PH:ABR": "Philippines - Abra", + "PH:AGN": "Philippines - Agusan del Norte", + "PH:AGS": "Philippines - Agusan del Sur", + "PH:AKL": "Philippines - Aklan", + "PH:ALB": "Philippines - Albay", + "PH:ANT": "Philippines - Antique", + "PH:APA": "Philippines - Apayao", + "PH:AUR": "Philippines - Aurora", + "PH:BAS": "Philippines - Basilan", + "PH:BAN": "Philippines - Bataan", + "PH:BTN": "Philippines - Batanes", + "PH:BTG": "Philippines - Batangas", + "PH:BEN": "Philippines - Benguet", + "PH:BIL": "Philippines - Biliran", + "PH:BOH": "Philippines - Bohol", + "PH:BUK": "Philippines - Bukidnon", + "PH:BUL": "Philippines - Bulacan", + "PH:CAG": "Philippines - Cagayan", + "PH:CAN": "Philippines - Camarines Norte", + "PH:CAS": "Philippines - Camarines Sur", + "PH:CAM": "Philippines - Camiguin", + "PH:CAP": "Philippines - Capiz", + "PH:CAT": "Philippines - Catanduanes", + "PH:CAV": "Philippines - Cavite", + "PH:CEB": "Philippines - Cebu", + "PH:COM": "Philippines - Compostela Valley", + "PH:NCO": "Philippines - Cotabato", + "PH:DAV": "Philippines - Davao del Norte", + "PH:DAS": "Philippines - Davao del Sur", + "PH:DAC": "Philippines - Davao Occidental", + "PH:DAO": "Philippines - Davao Oriental", + "PH:DIN": "Philippines - Dinagat Islands", + "PH:EAS": "Philippines - Eastern Samar", + "PH:GUI": "Philippines - Guimaras", + "PH:IFU": "Philippines - Ifugao", + "PH:ILN": "Philippines - Ilocos Norte", + "PH:ILS": "Philippines - Ilocos Sur", + "PH:ILI": "Philippines - Iloilo", + "PH:ISA": "Philippines - Isabela", + "PH:KAL": "Philippines - Kalinga", + "PH:LUN": "Philippines - La Union", + "PH:LAG": "Philippines - Laguna", + "PH:LAN": "Philippines - Lanao del Norte", + "PH:LAS": "Philippines - Lanao del Sur", + "PH:LEY": "Philippines - Leyte", + "PH:MAG": "Philippines - Maguindanao", + "PH:MAD": "Philippines - Marinduque", + "PH:MAS": "Philippines - Masbate", + "PH:MSC": "Philippines - Misamis Occidental", + "PH:MSR": "Philippines - Misamis Oriental", + "PH:MOU": "Philippines - Mountain Province", + "PH:NEC": "Philippines - Negros Occidental", + "PH:NER": "Philippines - Negros Oriental", + "PH:NSA": "Philippines - Northern Samar", + "PH:NUE": "Philippines - Nueva Ecija", + "PH:NUV": "Philippines - Nueva Vizcaya", + "PH:MDC": "Philippines - Occidental Mindoro", + "PH:MDR": "Philippines - Oriental Mindoro", + "PH:PLW": "Philippines - Palawan", + "PH:PAM": "Philippines - Pampanga", + "PH:PAN": "Philippines - Pangasinan", + "PH:QUE": "Philippines - Quezon", + "PH:QUI": "Philippines - Quirino", + "PH:RIZ": "Philippines - Rizal", + "PH:ROM": "Philippines - Romblon", + "PH:WSA": "Philippines - Samar", + "PH:SAR": "Philippines - Sarangani", + "PH:SIQ": "Philippines - Siquijor", + "PH:SOR": "Philippines - Sorsogon", + "PH:SCO": "Philippines - South Cotabato", + "PH:SLE": "Philippines - Southern Leyte", + "PH:SUK": "Philippines - Sultan Kudarat", + "PH:SLU": "Philippines - Sulu", + "PH:SUN": "Philippines - Surigao del Norte", + "PH:SUR": "Philippines - Surigao del Sur", + "PH:TAR": "Philippines - Tarlac", + "PH:TAW": "Philippines - Tawi-Tawi", + "PH:ZMB": "Philippines - Zambales", + "PH:ZAN": "Philippines - Zamboanga del Norte", + "PH:ZAS": "Philippines - Zamboanga del Sur", + "PH:ZSI": "Philippines - Zamboanga Sibugay", + "PH:00": "Philippines - Metro Manila", + "PN": "Pitcairn", + "PL": "Poland", + "PT": "Portugal", + "PR": "Puerto Rico", + "QA": "Qatar", + "RE": "Reunion", + "RO:AB": "Romania - Alba", + "RO:AR": "Romania - Arad", + "RO:AG": "Romania - Argeș", + "RO:BC": "Romania - Bacău", + "RO:BH": "Romania - Bihor", + "RO:BN": "Romania - Bistrița-Năsăud", + "RO:BT": "Romania - Botoșani", + "RO:BR": "Romania - Brăila", + "RO:BV": "Romania - Brașov", + "RO:B": "Romania - București", + "RO:BZ": "Romania - Buzău", + "RO:CL": "Romania - Călărași", + "RO:CS": "Romania - Caraș-Severin", + "RO:CJ": "Romania - Cluj", + "RO:CT": "Romania - Constanța", + "RO:CV": "Romania - Covasna", + "RO:DB": "Romania - Dâmbovița", + "RO:DJ": "Romania - Dolj", + "RO:GL": "Romania - Galați", + "RO:GR": "Romania - Giurgiu", + "RO:GJ": "Romania - Gorj", + "RO:HR": "Romania - Harghita", + "RO:HD": "Romania - Hunedoara", + "RO:IL": "Romania - Ialomița", + "RO:IS": "Romania - Iași", + "RO:IF": "Romania - Ilfov", + "RO:MM": "Romania - Maramureș", + "RO:MH": "Romania - Mehedinți", + "RO:MS": "Romania - Mureș", + "RO:NT": "Romania - Neamț", + "RO:OT": "Romania - Olt", + "RO:PH": "Romania - Prahova", + "RO:SJ": "Romania - Sălaj", + "RO:SM": "Romania - Satu Mare", + "RO:SB": "Romania - Sibiu", + "RO:SV": "Romania - Suceava", + "RO:TR": "Romania - Teleorman", + "RO:TM": "Romania - Timiș", + "RO:TL": "Romania - Tulcea", + "RO:VL": "Romania - Vâlcea", + "RO:VS": "Romania - Vaslui", + "RO:VN": "Romania - Vrancea", + "RU": "Russia", + "RW": "Rwanda", + "ST": "São Tomé and Príncipe", + "BL": "Saint Barthélemy", + "SH": "Saint Helena", + "KN": "Saint Kitts and Nevis", + "LC": "Saint Lucia", + "SX": "Saint Martin (Dutch part)", + "MF": "Saint Martin (French part)", + "PM": "Saint Pierre and Miquelon", + "VC": "Saint Vincent and the Grenadines", + "WS": "Samoa", + "SM": "San Marino", + "SA": "Saudi Arabia", + "SN": "Senegal", + "RS": "Serbia", + "SC": "Seychelles", + "SL": "Sierra Leone", + "SG": "Singapore", + "SK": "Slovakia", + "SI": "Slovenia", + "SB": "Solomon Islands", + "SO": "Somalia", + "ZA:EC": "South Africa - Eastern Cape", + "ZA:FS": "South Africa - Free State", + "ZA:GP": "South Africa - Gauteng", + "ZA:KZN": "South Africa - KwaZulu-Natal", + "ZA:LP": "South Africa - Limpopo", + "ZA:MP": "South Africa - Mpumalanga", + "ZA:NC": "South Africa - Northern Cape", + "ZA:NW": "South Africa - North West", + "ZA:WC": "South Africa - Western Cape", + "GS": "South Georgia/Sandwich Islands", + "KR": "South Korea", + "SS": "South Sudan", + "ES:C": "Spain - A Coruña", + "ES:VI": "Spain - Araba/Álava", + "ES:AB": "Spain - Albacete", + "ES:A": "Spain - Alicante", + "ES:AL": "Spain - Almería", + "ES:O": "Spain - Asturias", + "ES:AV": "Spain - Ávila", + "ES:BA": "Spain - Badajoz", + "ES:PM": "Spain - Baleares", + "ES:B": "Spain - Barcelona", + "ES:BU": "Spain - Burgos", + "ES:CC": "Spain - Cáceres", + "ES:CA": "Spain - Cádiz", + "ES:S": "Spain - Cantabria", + "ES:CS": "Spain - Castellón", + "ES:CE": "Spain - Ceuta", + "ES:CR": "Spain - Ciudad Real", + "ES:CO": "Spain - Córdoba", + "ES:CU": "Spain - Cuenca", + "ES:GI": "Spain - Girona", + "ES:GR": "Spain - Granada", + "ES:GU": "Spain - Guadalajara", + "ES:SS": "Spain - Gipuzkoa", + "ES:H": "Spain - Huelva", + "ES:HU": "Spain - Huesca", + "ES:J": "Spain - Jaén", + "ES:LO": "Spain - La Rioja", + "ES:GC": "Spain - Las Palmas", + "ES:LE": "Spain - León", + "ES:L": "Spain - Lleida", + "ES:LU": "Spain - Lugo", + "ES:M": "Spain - Madrid", + "ES:MA": "Spain - Málaga", + "ES:ML": "Spain - Melilla", + "ES:MU": "Spain - Murcia", + "ES:NA": "Spain - Navarra", + "ES:OR": "Spain - Ourense", + "ES:P": "Spain - Palencia", + "ES:PO": "Spain - Pontevedra", + "ES:SA": "Spain - Salamanca", + "ES:TF": "Spain - Santa Cruz de Tenerife", + "ES:SG": "Spain - Segovia", + "ES:SE": "Spain - Sevilla", + "ES:SO": "Spain - Soria", + "ES:T": "Spain - Tarragona", + "ES:TE": "Spain - Teruel", + "ES:TO": "Spain - Toledo", + "ES:V": "Spain - Valencia", + "ES:VA": "Spain - Valladolid", + "ES:BI": "Spain - Bizkaia", + "ES:ZA": "Spain - Zamora", + "ES:Z": "Spain - Zaragoza", + "LK": "Sri Lanka", + "SD": "Sudan", + "SR": "Suriname", + "SJ": "Svalbard and Jan Mayen", + "SZ": "Swaziland", + "SE": "Sweden", + "CH:AG": "Switzerland - Aargau", + "CH:AR": "Switzerland - Appenzell Ausserrhoden", + "CH:AI": "Switzerland - Appenzell Innerrhoden", + "CH:BL": "Switzerland - Basel-Landschaft", + "CH:BS": "Switzerland - Basel-Stadt", + "CH:BE": "Switzerland - Bern", + "CH:FR": "Switzerland - Fribourg", + "CH:GE": "Switzerland - Geneva", + "CH:GL": "Switzerland - Glarus", + "CH:GR": "Switzerland - Graubünden", + "CH:JU": "Switzerland - Jura", + "CH:LU": "Switzerland - Luzern", + "CH:NE": "Switzerland - Neuchâtel", + "CH:NW": "Switzerland - Nidwalden", + "CH:OW": "Switzerland - Obwalden", + "CH:SH": "Switzerland - Schaffhausen", + "CH:SZ": "Switzerland - Schwyz", + "CH:SO": "Switzerland - Solothurn", + "CH:SG": "Switzerland - St. Gallen", + "CH:TG": "Switzerland - Thurgau", + "CH:TI": "Switzerland - Ticino", + "CH:UR": "Switzerland - Uri", + "CH:VS": "Switzerland - Valais", + "CH:VD": "Switzerland - Vaud", + "CH:ZG": "Switzerland - Zug", + "CH:ZH": "Switzerland - Zürich", + "SY": "Syria", + "TW": "Taiwan", + "TJ": "Tajikistan", + "TZ:TZ01": "Tanzania - Arusha", + "TZ:TZ02": "Tanzania - Dar es Salaam", + "TZ:TZ03": "Tanzania - Dodoma", + "TZ:TZ04": "Tanzania - Iringa", + "TZ:TZ05": "Tanzania - Kagera", + "TZ:TZ06": "Tanzania - Pemba North", + "TZ:TZ07": "Tanzania - Zanzibar North", + "TZ:TZ08": "Tanzania - Kigoma", + "TZ:TZ09": "Tanzania - Kilimanjaro", + "TZ:TZ10": "Tanzania - Pemba South", + "TZ:TZ11": "Tanzania - Zanzibar South", + "TZ:TZ12": "Tanzania - Lindi", + "TZ:TZ13": "Tanzania - Mara", + "TZ:TZ14": "Tanzania - Mbeya", + "TZ:TZ15": "Tanzania - Zanzibar West", + "TZ:TZ16": "Tanzania - Morogoro", + "TZ:TZ17": "Tanzania - Mtwara", + "TZ:TZ18": "Tanzania - Mwanza", + "TZ:TZ19": "Tanzania - Coast", + "TZ:TZ20": "Tanzania - Rukwa", + "TZ:TZ21": "Tanzania - Ruvuma", + "TZ:TZ22": "Tanzania - Shinyanga", + "TZ:TZ23": "Tanzania - Singida", + "TZ:TZ24": "Tanzania - Tabora", + "TZ:TZ25": "Tanzania - Tanga", + "TZ:TZ26": "Tanzania - Manyara", + "TZ:TZ27": "Tanzania - Geita", + "TZ:TZ28": "Tanzania - Katavi", + "TZ:TZ29": "Tanzania - Njombe", + "TZ:TZ30": "Tanzania - Simiyu", + "TH:TH-37": "Thailand - Amnat Charoen", + "TH:TH-15": "Thailand - Ang Thong", + "TH:TH-14": "Thailand - Ayutthaya", + "TH:TH-10": "Thailand - Bangkok", + "TH:TH-38": "Thailand - Bueng Kan", + "TH:TH-31": "Thailand - Buri Ram", + "TH:TH-24": "Thailand - Chachoengsao", + "TH:TH-18": "Thailand - Chai Nat", + "TH:TH-36": "Thailand - Chaiyaphum", + "TH:TH-22": "Thailand - Chanthaburi", + "TH:TH-50": "Thailand - Chiang Mai", + "TH:TH-57": "Thailand - Chiang Rai", + "TH:TH-20": "Thailand - Chonburi", + "TH:TH-86": "Thailand - Chumphon", + "TH:TH-46": "Thailand - Kalasin", + "TH:TH-62": "Thailand - Kamphaeng Phet", + "TH:TH-71": "Thailand - Kanchanaburi", + "TH:TH-40": "Thailand - Khon Kaen", + "TH:TH-81": "Thailand - Krabi", + "TH:TH-52": "Thailand - Lampang", + "TH:TH-51": "Thailand - Lamphun", + "TH:TH-42": "Thailand - Loei", + "TH:TH-16": "Thailand - Lopburi", + "TH:TH-58": "Thailand - Mae Hong Son", + "TH:TH-44": "Thailand - Maha Sarakham", + "TH:TH-49": "Thailand - Mukdahan", + "TH:TH-26": "Thailand - Nakhon Nayok", + "TH:TH-73": "Thailand - Nakhon Pathom", + "TH:TH-48": "Thailand - Nakhon Phanom", + "TH:TH-30": "Thailand - Nakhon Ratchasima", + "TH:TH-60": "Thailand - Nakhon Sawan", + "TH:TH-80": "Thailand - Nakhon Si Thammarat", + "TH:TH-55": "Thailand - Nan", + "TH:TH-96": "Thailand - Narathiwat", + "TH:TH-39": "Thailand - Nong Bua Lam Phu", + "TH:TH-43": "Thailand - Nong Khai", + "TH:TH-12": "Thailand - Nonthaburi", + "TH:TH-13": "Thailand - Pathum Thani", + "TH:TH-94": "Thailand - Pattani", + "TH:TH-82": "Thailand - Phang Nga", + "TH:TH-93": "Thailand - Phatthalung", + "TH:TH-56": "Thailand - Phayao", + "TH:TH-67": "Thailand - Phetchabun", + "TH:TH-76": "Thailand - Phetchaburi", + "TH:TH-66": "Thailand - Phichit", + "TH:TH-65": "Thailand - Phitsanulok", + "TH:TH-54": "Thailand - Phrae", + "TH:TH-83": "Thailand - Phuket", + "TH:TH-25": "Thailand - Prachin Buri", + "TH:TH-77": "Thailand - Prachuap Khiri Khan", + "TH:TH-85": "Thailand - Ranong", + "TH:TH-70": "Thailand - Ratchaburi", + "TH:TH-21": "Thailand - Rayong", + "TH:TH-45": "Thailand - Roi Et", + "TH:TH-27": "Thailand - Sa Kaeo", + "TH:TH-47": "Thailand - Sakon Nakhon", + "TH:TH-11": "Thailand - Samut Prakan", + "TH:TH-74": "Thailand - Samut Sakhon", + "TH:TH-75": "Thailand - Samut Songkhram", + "TH:TH-19": "Thailand - Saraburi", + "TH:TH-91": "Thailand - Satun", + "TH:TH-17": "Thailand - Sing Buri", + "TH:TH-33": "Thailand - Sisaket", + "TH:TH-90": "Thailand - Songkhla", + "TH:TH-64": "Thailand - Sukhothai", + "TH:TH-72": "Thailand - Suphan Buri", + "TH:TH-84": "Thailand - Surat Thani", + "TH:TH-32": "Thailand - Surin", + "TH:TH-63": "Thailand - Tak", + "TH:TH-92": "Thailand - Trang", + "TH:TH-23": "Thailand - Trat", + "TH:TH-34": "Thailand - Ubon Ratchathani", + "TH:TH-41": "Thailand - Udon Thani", + "TH:TH-61": "Thailand - Uthai Thani", + "TH:TH-53": "Thailand - Uttaradit", + "TH:TH-95": "Thailand - Yala", + "TH:TH-35": "Thailand - Yasothon", + "TL": "Timor-Leste", + "TG": "Togo", + "TK": "Tokelau", + "TO": "Tonga", + "TT": "Trinidad and Tobago", + "TN": "Tunisia", + "TR:TR01": "Turkey - Adana", + "TR:TR02": "Turkey - Adıyaman", + "TR:TR03": "Turkey - Afyon", + "TR:TR04": "Turkey - Ağrı", + "TR:TR05": "Turkey - Amasya", + "TR:TR06": "Turkey - Ankara", + "TR:TR07": "Turkey - Antalya", + "TR:TR08": "Turkey - Artvin", + "TR:TR09": "Turkey - Aydın", + "TR:TR10": "Turkey - Balıkesir", + "TR:TR11": "Turkey - Bilecik", + "TR:TR12": "Turkey - Bingöl", + "TR:TR13": "Turkey - Bitlis", + "TR:TR14": "Turkey - Bolu", + "TR:TR15": "Turkey - Burdur", + "TR:TR16": "Turkey - Bursa", + "TR:TR17": "Turkey - Çanakkale", + "TR:TR18": "Turkey - Çankırı", + "TR:TR19": "Turkey - Çorum", + "TR:TR20": "Turkey - Denizli", + "TR:TR21": "Turkey - Diyarbakır", + "TR:TR22": "Turkey - Edirne", + "TR:TR23": "Turkey - Elazığ", + "TR:TR24": "Turkey - Erzincan", + "TR:TR25": "Turkey - Erzurum", + "TR:TR26": "Turkey - Eskişehir", + "TR:TR27": "Turkey - Gaziantep", + "TR:TR28": "Turkey - Giresun", + "TR:TR29": "Turkey - Gümüşhane", + "TR:TR30": "Turkey - Hakkari", + "TR:TR31": "Turkey - Hatay", + "TR:TR32": "Turkey - Isparta", + "TR:TR33": "Turkey - İçel", + "TR:TR34": "Turkey - İstanbul", + "TR:TR35": "Turkey - İzmir", + "TR:TR36": "Turkey - Kars", + "TR:TR37": "Turkey - Kastamonu", + "TR:TR38": "Turkey - Kayseri", + "TR:TR39": "Turkey - Kırklareli", + "TR:TR40": "Turkey - Kırşehir", + "TR:TR41": "Turkey - Kocaeli", + "TR:TR42": "Turkey - Konya", + "TR:TR43": "Turkey - Kütahya", + "TR:TR44": "Turkey - Malatya", + "TR:TR45": "Turkey - Manisa", + "TR:TR46": "Turkey - Kahramanmaraş", + "TR:TR47": "Turkey - Mardin", + "TR:TR48": "Turkey - Muğla", + "TR:TR49": "Turkey - Muş", + "TR:TR50": "Turkey - Nevşehir", + "TR:TR51": "Turkey - Niğde", + "TR:TR52": "Turkey - Ordu", + "TR:TR53": "Turkey - Rize", + "TR:TR54": "Turkey - Sakarya", + "TR:TR55": "Turkey - Samsun", + "TR:TR56": "Turkey - Siirt", + "TR:TR57": "Turkey - Sinop", + "TR:TR58": "Turkey - Sivas", + "TR:TR59": "Turkey - Tekirdağ", + "TR:TR60": "Turkey - Tokat", + "TR:TR61": "Turkey - Trabzon", + "TR:TR62": "Turkey - Tunceli", + "TR:TR63": "Turkey - Şanlıurfa", + "TR:TR64": "Turkey - Uşak", + "TR:TR65": "Turkey - Van", + "TR:TR66": "Turkey - Yozgat", + "TR:TR67": "Turkey - Zonguldak", + "TR:TR68": "Turkey - Aksaray", + "TR:TR69": "Turkey - Bayburt", + "TR:TR70": "Turkey - Karaman", + "TR:TR71": "Turkey - Kırıkkale", + "TR:TR72": "Turkey - Batman", + "TR:TR73": "Turkey - Şırnak", + "TR:TR74": "Turkey - Bartın", + "TR:TR75": "Turkey - Ardahan", + "TR:TR76": "Turkey - Iğdır", + "TR:TR77": "Turkey - Yalova", + "TR:TR78": "Turkey - Karabük", + "TR:TR79": "Turkey - Kilis", + "TR:TR80": "Turkey - Osmaniye", + "TR:TR81": "Turkey - Düzce", + "TM": "Turkmenistan", + "TC": "Turks and Caicos Islands", + "TV": "Tuvalu", + "UG": "Uganda", + "UA": "Ukraine", + "AE": "United Arab Emirates", + "GB": "United Kingdom (UK)", + "US:AL": "United States (US) - Alabama", + "US:AK": "United States (US) - Alaska", + "US:AZ": "United States (US) - Arizona", + "US:AR": "United States (US) - Arkansas", + "US:CA": "United States (US) - California", + "US:CO": "United States (US) - Colorado", + "US:CT": "United States (US) - Connecticut", + "US:DE": "United States (US) - Delaware", + "US:DC": "United States (US) - District Of Columbia", + "US:FL": "United States (US) - Florida", + "US:GA": "United States (US) - Georgia", + "US:HI": "United States (US) - Hawaii", + "US:ID": "United States (US) - Idaho", + "US:IL": "United States (US) - Illinois", + "US:IN": "United States (US) - Indiana", + "US:IA": "United States (US) - Iowa", + "US:KS": "United States (US) - Kansas", + "US:KY": "United States (US) - Kentucky", + "US:LA": "United States (US) - Louisiana", + "US:ME": "United States (US) - Maine", + "US:MD": "United States (US) - Maryland", + "US:MA": "United States (US) - Massachusetts", + "US:MI": "United States (US) - Michigan", + "US:MN": "United States (US) - Minnesota", + "US:MS": "United States (US) - Mississippi", + "US:MO": "United States (US) - Missouri", + "US:MT": "United States (US) - Montana", + "US:NE": "United States (US) - Nebraska", + "US:NV": "United States (US) - Nevada", + "US:NH": "United States (US) - New Hampshire", + "US:NJ": "United States (US) - New Jersey", + "US:NM": "United States (US) - New Mexico", + "US:NY": "United States (US) - New York", + "US:NC": "United States (US) - North Carolina", + "US:ND": "United States (US) - North Dakota", + "US:OH": "United States (US) - Ohio", + "US:OK": "United States (US) - Oklahoma", + "US:OR": "United States (US) - Oregon", + "US:PA": "United States (US) - Pennsylvania", + "US:RI": "United States (US) - Rhode Island", + "US:SC": "United States (US) - South Carolina", + "US:SD": "United States (US) - South Dakota", + "US:TN": "United States (US) - Tennessee", + "US:TX": "United States (US) - Texas", + "US:UT": "United States (US) - Utah", + "US:VT": "United States (US) - Vermont", + "US:VA": "United States (US) - Virginia", + "US:WA": "United States (US) - Washington", + "US:WV": "United States (US) - West Virginia", + "US:WI": "United States (US) - Wisconsin", + "US:WY": "United States (US) - Wyoming", + "US:AA": "United States (US) - Armed Forces (AA)", + "US:AE": "United States (US) - Armed Forces (AE)", + "US:AP": "United States (US) - Armed Forces (AP)", + "UM": "United States (US) Minor Outlying Islands", + "VI": "United States (US) Virgin Islands", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VU": "Vanuatu", + "VA": "Vatican", + "VE": "Venezuela", + "VN": "Vietnam", + "WF": "Wallis and Futuna", + "EH": "Western Sahara", + "YE": "Yemen", + "ZM": "Zambia", + "ZW": "Zimbabwe" + }, + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_default_country" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_store_postcode", + "label": "Postcode / ZIP", + "description": "The postal code, if any, in which your business is located.", + "type": "text", + "default": "", + "tip": "The postal code, if any, in which your business is located.", + "value": "13021", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_store_postcode" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_allowed_countries", + "label": "Selling location(s)", + "description": "This option lets you limit which countries you are willing to sell to.", + "type": "select", + "default": "all", + "options": { + "all": "Sell to all countries", + "all_except": "Sell to all countries, except for…", + "specific": "Sell to specific countries" + }, + "tip": "This option lets you limit which countries you are willing to sell to.", + "value": "all", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_allowed_countries" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_all_except_countries", + "label": "Sell to all countries, except for…", + "description": "", + "type": "multiselect", + "default": "", + "value": [], + "options": { + "AX": "Åland Islands", + "AF": "Afghanistan", + "AL": "Albania", + "DZ": "Algeria", + "AS": "American Samoa", + "AD": "Andorra", + "AO": "Angola", + "AI": "Anguilla", + "AQ": "Antarctica", + "AG": "Antigua and Barbuda", + "AR": "Argentina", + "AM": "Armenia", + "AW": "Aruba", + "AU": "Australia", + "AT": "Austria", + "AZ": "Azerbaijan", + "BS": "Bahamas", + "BH": "Bahrain", + "BD": "Bangladesh", + "BB": "Barbados", + "BY": "Belarus", + "PW": "Belau", + "BE": "Belgium", + "BZ": "Belize", + "BJ": "Benin", + "BM": "Bermuda", + "BT": "Bhutan", + "BO": "Bolivia", + "BQ": "Bonaire, Saint Eustatius and Saba", + "BA": "Bosnia and Herzegovina", + "BW": "Botswana", + "BV": "Bouvet Island", + "BR": "Brazil", + "IO": "British Indian Ocean Territory", + "VG": "British Virgin Islands", + "BN": "Brunei", + "BG": "Bulgaria", + "BF": "Burkina Faso", + "BI": "Burundi", + "KH": "Cambodia", + "CM": "Cameroon", + "CA": "Canada", + "CV": "Cape Verde", + "KY": "Cayman Islands", + "CF": "Central African Republic", + "TD": "Chad", + "CL": "Chile", + "CN": "China", + "CX": "Christmas Island", + "CC": "Cocos (Keeling) Islands", + "CO": "Colombia", + "KM": "Comoros", + "CG": "Congo (Brazzaville)", + "CD": "Congo (Kinshasa)", + "CK": "Cook Islands", + "CR": "Costa Rica", + "HR": "Croatia", + "CU": "Cuba", + "CW": "Curaçao", + "CY": "Cyprus", + "CZ": "Czech Republic", + "DK": "Denmark", + "DJ": "Djibouti", + "DM": "Dominica", + "DO": "Dominican Republic", + "EC": "Ecuador", + "EG": "Egypt", + "SV": "El Salvador", + "GQ": "Equatorial Guinea", + "ER": "Eritrea", + "EE": "Estonia", + "ET": "Ethiopia", + "FK": "Falkland Islands", + "FO": "Faroe Islands", + "FJ": "Fiji", + "FI": "Finland", + "FR": "France", + "GF": "French Guiana", + "PF": "French Polynesia", + "TF": "French Southern Territories", + "GA": "Gabon", + "GM": "Gambia", + "GE": "Georgia", + "DE": "Germany", + "GH": "Ghana", + "GI": "Gibraltar", + "GR": "Greece", + "GL": "Greenland", + "GD": "Grenada", + "GP": "Guadeloupe", + "GU": "Guam", + "GT": "Guatemala", + "GG": "Guernsey", + "GN": "Guinea", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HT": "Haiti", + "HM": "Heard Island and McDonald Islands", + "HN": "Honduras", + "HK": "Hong Kong", + "HU": "Hungary", + "IS": "Iceland", + "IN": "India", + "ID": "Indonesia", + "IR": "Iran", + "IQ": "Iraq", + "IE": "Ireland", + "IM": "Isle of Man", + "IL": "Israel", + "IT": "Italy", + "CI": "Ivory Coast", + "JM": "Jamaica", + "JP": "Japan", + "JE": "Jersey", + "JO": "Jordan", + "KZ": "Kazakhstan", + "KE": "Kenya", + "KI": "Kiribati", + "KW": "Kuwait", + "KG": "Kyrgyzstan", + "LA": "Laos", + "LV": "Latvia", + "LB": "Lebanon", + "LS": "Lesotho", + "LR": "Liberia", + "LY": "Libya", + "LI": "Liechtenstein", + "LT": "Lithuania", + "LU": "Luxembourg", + "MO": "Macao S.A.R., China", + "MK": "Macedonia", + "MG": "Madagascar", + "MW": "Malawi", + "MY": "Malaysia", + "MV": "Maldives", + "ML": "Mali", + "MT": "Malta", + "MH": "Marshall Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MU": "Mauritius", + "YT": "Mayotte", + "MX": "Mexico", + "FM": "Micronesia", + "MD": "Moldova", + "MC": "Monaco", + "MN": "Mongolia", + "ME": "Montenegro", + "MS": "Montserrat", + "MA": "Morocco", + "MZ": "Mozambique", + "MM": "Myanmar", + "NA": "Namibia", + "NR": "Nauru", + "NP": "Nepal", + "NL": "Netherlands", + "NC": "New Caledonia", + "NZ": "New Zealand", + "NI": "Nicaragua", + "NE": "Niger", + "NG": "Nigeria", + "NU": "Niue", + "NF": "Norfolk Island", + "KP": "North Korea", + "MP": "Northern Mariana Islands", + "NO": "Norway", + "OM": "Oman", + "PK": "Pakistan", + "PS": "Palestinian Territory", + "PA": "Panama", + "PG": "Papua New Guinea", + "PY": "Paraguay", + "PE": "Peru", + "PH": "Philippines", + "PN": "Pitcairn", + "PL": "Poland", + "PT": "Portugal", + "PR": "Puerto Rico", + "QA": "Qatar", + "RE": "Reunion", + "RO": "Romania", + "RU": "Russia", + "RW": "Rwanda", + "ST": "São Tomé and Príncipe", + "BL": "Saint Barthélemy", + "SH": "Saint Helena", + "KN": "Saint Kitts and Nevis", + "LC": "Saint Lucia", + "SX": "Saint Martin (Dutch part)", + "MF": "Saint Martin (French part)", + "PM": "Saint Pierre and Miquelon", + "VC": "Saint Vincent and the Grenadines", + "WS": "Samoa", + "SM": "San Marino", + "SA": "Saudi Arabia", + "SN": "Senegal", + "RS": "Serbia", + "SC": "Seychelles", + "SL": "Sierra Leone", + "SG": "Singapore", + "SK": "Slovakia", + "SI": "Slovenia", + "SB": "Solomon Islands", + "SO": "Somalia", + "ZA": "South Africa", + "GS": "South Georgia/Sandwich Islands", + "KR": "South Korea", + "SS": "South Sudan", + "ES": "Spain", + "LK": "Sri Lanka", + "SD": "Sudan", + "SR": "Suriname", + "SJ": "Svalbard and Jan Mayen", + "SZ": "Swaziland", + "SE": "Sweden", + "CH": "Switzerland", + "SY": "Syria", + "TW": "Taiwan", + "TJ": "Tajikistan", + "TZ": "Tanzania", + "TH": "Thailand", + "TL": "Timor-Leste", + "TG": "Togo", + "TK": "Tokelau", + "TO": "Tonga", + "TT": "Trinidad and Tobago", + "TN": "Tunisia", + "TR": "Turkey", + "TM": "Turkmenistan", + "TC": "Turks and Caicos Islands", + "TV": "Tuvalu", + "UG": "Uganda", + "UA": "Ukraine", + "AE": "United Arab Emirates", + "GB": "United Kingdom (UK)", + "US": "United States (US)", + "UM": "United States (US) Minor Outlying Islands", + "VI": "United States (US) Virgin Islands", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VU": "Vanuatu", + "VA": "Vatican", + "VE": "Venezuela", + "VN": "Vietnam", + "WF": "Wallis and Futuna", + "EH": "Western Sahara", + "YE": "Yemen", + "ZM": "Zambia", + "ZW": "Zimbabwe" + }, + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_all_except_countries" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_specific_allowed_countries", + "label": "Sell to specific countries", + "description": "", + "type": "multiselect", + "default": "", + "value": [], + "options": { + "AX": "Åland Islands", + "AF": "Afghanistan", + "AL": "Albania", + "DZ": "Algeria", + "AS": "American Samoa", + "AD": "Andorra", + "AO": "Angola", + "AI": "Anguilla", + "AQ": "Antarctica", + "AG": "Antigua and Barbuda", + "AR": "Argentina", + "AM": "Armenia", + "AW": "Aruba", + "AU": "Australia", + "AT": "Austria", + "AZ": "Azerbaijan", + "BS": "Bahamas", + "BH": "Bahrain", + "BD": "Bangladesh", + "BB": "Barbados", + "BY": "Belarus", + "PW": "Belau", + "BE": "Belgium", + "BZ": "Belize", + "BJ": "Benin", + "BM": "Bermuda", + "BT": "Bhutan", + "BO": "Bolivia", + "BQ": "Bonaire, Saint Eustatius and Saba", + "BA": "Bosnia and Herzegovina", + "BW": "Botswana", + "BV": "Bouvet Island", + "BR": "Brazil", + "IO": "British Indian Ocean Territory", + "VG": "British Virgin Islands", + "BN": "Brunei", + "BG": "Bulgaria", + "BF": "Burkina Faso", + "BI": "Burundi", + "KH": "Cambodia", + "CM": "Cameroon", + "CA": "Canada", + "CV": "Cape Verde", + "KY": "Cayman Islands", + "CF": "Central African Republic", + "TD": "Chad", + "CL": "Chile", + "CN": "China", + "CX": "Christmas Island", + "CC": "Cocos (Keeling) Islands", + "CO": "Colombia", + "KM": "Comoros", + "CG": "Congo (Brazzaville)", + "CD": "Congo (Kinshasa)", + "CK": "Cook Islands", + "CR": "Costa Rica", + "HR": "Croatia", + "CU": "Cuba", + "CW": "Curaçao", + "CY": "Cyprus", + "CZ": "Czech Republic", + "DK": "Denmark", + "DJ": "Djibouti", + "DM": "Dominica", + "DO": "Dominican Republic", + "EC": "Ecuador", + "EG": "Egypt", + "SV": "El Salvador", + "GQ": "Equatorial Guinea", + "ER": "Eritrea", + "EE": "Estonia", + "ET": "Ethiopia", + "FK": "Falkland Islands", + "FO": "Faroe Islands", + "FJ": "Fiji", + "FI": "Finland", + "FR": "France", + "GF": "French Guiana", + "PF": "French Polynesia", + "TF": "French Southern Territories", + "GA": "Gabon", + "GM": "Gambia", + "GE": "Georgia", + "DE": "Germany", + "GH": "Ghana", + "GI": "Gibraltar", + "GR": "Greece", + "GL": "Greenland", + "GD": "Grenada", + "GP": "Guadeloupe", + "GU": "Guam", + "GT": "Guatemala", + "GG": "Guernsey", + "GN": "Guinea", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HT": "Haiti", + "HM": "Heard Island and McDonald Islands", + "HN": "Honduras", + "HK": "Hong Kong", + "HU": "Hungary", + "IS": "Iceland", + "IN": "India", + "ID": "Indonesia", + "IR": "Iran", + "IQ": "Iraq", + "IE": "Ireland", + "IM": "Isle of Man", + "IL": "Israel", + "IT": "Italy", + "CI": "Ivory Coast", + "JM": "Jamaica", + "JP": "Japan", + "JE": "Jersey", + "JO": "Jordan", + "KZ": "Kazakhstan", + "KE": "Kenya", + "KI": "Kiribati", + "KW": "Kuwait", + "KG": "Kyrgyzstan", + "LA": "Laos", + "LV": "Latvia", + "LB": "Lebanon", + "LS": "Lesotho", + "LR": "Liberia", + "LY": "Libya", + "LI": "Liechtenstein", + "LT": "Lithuania", + "LU": "Luxembourg", + "MO": "Macao S.A.R., China", + "MK": "Macedonia", + "MG": "Madagascar", + "MW": "Malawi", + "MY": "Malaysia", + "MV": "Maldives", + "ML": "Mali", + "MT": "Malta", + "MH": "Marshall Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MU": "Mauritius", + "YT": "Mayotte", + "MX": "Mexico", + "FM": "Micronesia", + "MD": "Moldova", + "MC": "Monaco", + "MN": "Mongolia", + "ME": "Montenegro", + "MS": "Montserrat", + "MA": "Morocco", + "MZ": "Mozambique", + "MM": "Myanmar", + "NA": "Namibia", + "NR": "Nauru", + "NP": "Nepal", + "NL": "Netherlands", + "NC": "New Caledonia", + "NZ": "New Zealand", + "NI": "Nicaragua", + "NE": "Niger", + "NG": "Nigeria", + "NU": "Niue", + "NF": "Norfolk Island", + "KP": "North Korea", + "MP": "Northern Mariana Islands", + "NO": "Norway", + "OM": "Oman", + "PK": "Pakistan", + "PS": "Palestinian Territory", + "PA": "Panama", + "PG": "Papua New Guinea", + "PY": "Paraguay", + "PE": "Peru", + "PH": "Philippines", + "PN": "Pitcairn", + "PL": "Poland", + "PT": "Portugal", + "PR": "Puerto Rico", + "QA": "Qatar", + "RE": "Reunion", + "RO": "Romania", + "RU": "Russia", + "RW": "Rwanda", + "ST": "São Tomé and Príncipe", + "BL": "Saint Barthélemy", + "SH": "Saint Helena", + "KN": "Saint Kitts and Nevis", + "LC": "Saint Lucia", + "SX": "Saint Martin (Dutch part)", + "MF": "Saint Martin (French part)", + "PM": "Saint Pierre and Miquelon", + "VC": "Saint Vincent and the Grenadines", + "WS": "Samoa", + "SM": "San Marino", + "SA": "Saudi Arabia", + "SN": "Senegal", + "RS": "Serbia", + "SC": "Seychelles", + "SL": "Sierra Leone", + "SG": "Singapore", + "SK": "Slovakia", + "SI": "Slovenia", + "SB": "Solomon Islands", + "SO": "Somalia", + "ZA": "South Africa", + "GS": "South Georgia/Sandwich Islands", + "KR": "South Korea", + "SS": "South Sudan", + "ES": "Spain", + "LK": "Sri Lanka", + "SD": "Sudan", + "SR": "Suriname", + "SJ": "Svalbard and Jan Mayen", + "SZ": "Swaziland", + "SE": "Sweden", + "CH": "Switzerland", + "SY": "Syria", + "TW": "Taiwan", + "TJ": "Tajikistan", + "TZ": "Tanzania", + "TH": "Thailand", + "TL": "Timor-Leste", + "TG": "Togo", + "TK": "Tokelau", + "TO": "Tonga", + "TT": "Trinidad and Tobago", + "TN": "Tunisia", + "TR": "Turkey", + "TM": "Turkmenistan", + "TC": "Turks and Caicos Islands", + "TV": "Tuvalu", + "UG": "Uganda", + "UA": "Ukraine", + "AE": "United Arab Emirates", + "GB": "United Kingdom (UK)", + "US": "United States (US)", + "UM": "United States (US) Minor Outlying Islands", + "VI": "United States (US) Virgin Islands", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VU": "Vanuatu", + "VA": "Vatican", + "VE": "Venezuela", + "VN": "Vietnam", + "WF": "Wallis and Futuna", + "EH": "Western Sahara", + "YE": "Yemen", + "ZM": "Zambia", + "ZW": "Zimbabwe" + }, + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_specific_allowed_countries" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_ship_to_countries", + "label": "Shipping location(s)", + "description": "Choose which countries you want to ship to, or choose to ship to all locations you sell to.", + "type": "select", + "default": "", + "options": { + "all": "Ship to all countries", + "specific": "Ship to specific countries only", + "disabled": "Disable shipping & shipping calculations" + }, + "tip": "Choose which countries you want to ship to, or choose to ship to all locations you sell to.", + "value": "all", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_ship_to_countries" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_specific_ship_to_countries", + "label": "Ship to specific countries", + "description": "", + "type": "multiselect", + "default": "", + "value": [], + "options": { + "AX": "Åland Islands", + "AF": "Afghanistan", + "AL": "Albania", + "DZ": "Algeria", + "AS": "American Samoa", + "AD": "Andorra", + "AO": "Angola", + "AI": "Anguilla", + "AQ": "Antarctica", + "AG": "Antigua and Barbuda", + "AR": "Argentina", + "AM": "Armenia", + "AW": "Aruba", + "AU": "Australia", + "AT": "Austria", + "AZ": "Azerbaijan", + "BS": "Bahamas", + "BH": "Bahrain", + "BD": "Bangladesh", + "BB": "Barbados", + "BY": "Belarus", + "PW": "Belau", + "BE": "Belgium", + "BZ": "Belize", + "BJ": "Benin", + "BM": "Bermuda", + "BT": "Bhutan", + "BO": "Bolivia", + "BQ": "Bonaire, Saint Eustatius and Saba", + "BA": "Bosnia and Herzegovina", + "BW": "Botswana", + "BV": "Bouvet Island", + "BR": "Brazil", + "IO": "British Indian Ocean Territory", + "VG": "British Virgin Islands", + "BN": "Brunei", + "BG": "Bulgaria", + "BF": "Burkina Faso", + "BI": "Burundi", + "KH": "Cambodia", + "CM": "Cameroon", + "CA": "Canada", + "CV": "Cape Verde", + "KY": "Cayman Islands", + "CF": "Central African Republic", + "TD": "Chad", + "CL": "Chile", + "CN": "China", + "CX": "Christmas Island", + "CC": "Cocos (Keeling) Islands", + "CO": "Colombia", + "KM": "Comoros", + "CG": "Congo (Brazzaville)", + "CD": "Congo (Kinshasa)", + "CK": "Cook Islands", + "CR": "Costa Rica", + "HR": "Croatia", + "CU": "Cuba", + "CW": "Curaçao", + "CY": "Cyprus", + "CZ": "Czech Republic", + "DK": "Denmark", + "DJ": "Djibouti", + "DM": "Dominica", + "DO": "Dominican Republic", + "EC": "Ecuador", + "EG": "Egypt", + "SV": "El Salvador", + "GQ": "Equatorial Guinea", + "ER": "Eritrea", + "EE": "Estonia", + "ET": "Ethiopia", + "FK": "Falkland Islands", + "FO": "Faroe Islands", + "FJ": "Fiji", + "FI": "Finland", + "FR": "France", + "GF": "French Guiana", + "PF": "French Polynesia", + "TF": "French Southern Territories", + "GA": "Gabon", + "GM": "Gambia", + "GE": "Georgia", + "DE": "Germany", + "GH": "Ghana", + "GI": "Gibraltar", + "GR": "Greece", + "GL": "Greenland", + "GD": "Grenada", + "GP": "Guadeloupe", + "GU": "Guam", + "GT": "Guatemala", + "GG": "Guernsey", + "GN": "Guinea", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HT": "Haiti", + "HM": "Heard Island and McDonald Islands", + "HN": "Honduras", + "HK": "Hong Kong", + "HU": "Hungary", + "IS": "Iceland", + "IN": "India", + "ID": "Indonesia", + "IR": "Iran", + "IQ": "Iraq", + "IE": "Ireland", + "IM": "Isle of Man", + "IL": "Israel", + "IT": "Italy", + "CI": "Ivory Coast", + "JM": "Jamaica", + "JP": "Japan", + "JE": "Jersey", + "JO": "Jordan", + "KZ": "Kazakhstan", + "KE": "Kenya", + "KI": "Kiribati", + "KW": "Kuwait", + "KG": "Kyrgyzstan", + "LA": "Laos", + "LV": "Latvia", + "LB": "Lebanon", + "LS": "Lesotho", + "LR": "Liberia", + "LY": "Libya", + "LI": "Liechtenstein", + "LT": "Lithuania", + "LU": "Luxembourg", + "MO": "Macao S.A.R., China", + "MK": "Macedonia", + "MG": "Madagascar", + "MW": "Malawi", + "MY": "Malaysia", + "MV": "Maldives", + "ML": "Mali", + "MT": "Malta", + "MH": "Marshall Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MU": "Mauritius", + "YT": "Mayotte", + "MX": "Mexico", + "FM": "Micronesia", + "MD": "Moldova", + "MC": "Monaco", + "MN": "Mongolia", + "ME": "Montenegro", + "MS": "Montserrat", + "MA": "Morocco", + "MZ": "Mozambique", + "MM": "Myanmar", + "NA": "Namibia", + "NR": "Nauru", + "NP": "Nepal", + "NL": "Netherlands", + "NC": "New Caledonia", + "NZ": "New Zealand", + "NI": "Nicaragua", + "NE": "Niger", + "NG": "Nigeria", + "NU": "Niue", + "NF": "Norfolk Island", + "KP": "North Korea", + "MP": "Northern Mariana Islands", + "NO": "Norway", + "OM": "Oman", + "PK": "Pakistan", + "PS": "Palestinian Territory", + "PA": "Panama", + "PG": "Papua New Guinea", + "PY": "Paraguay", + "PE": "Peru", + "PH": "Philippines", + "PN": "Pitcairn", + "PL": "Poland", + "PT": "Portugal", + "PR": "Puerto Rico", + "QA": "Qatar", + "RE": "Reunion", + "RO": "Romania", + "RU": "Russia", + "RW": "Rwanda", + "ST": "São Tomé and Príncipe", + "BL": "Saint Barthélemy", + "SH": "Saint Helena", + "KN": "Saint Kitts and Nevis", + "LC": "Saint Lucia", + "SX": "Saint Martin (Dutch part)", + "MF": "Saint Martin (French part)", + "PM": "Saint Pierre and Miquelon", + "VC": "Saint Vincent and the Grenadines", + "WS": "Samoa", + "SM": "San Marino", + "SA": "Saudi Arabia", + "SN": "Senegal", + "RS": "Serbia", + "SC": "Seychelles", + "SL": "Sierra Leone", + "SG": "Singapore", + "SK": "Slovakia", + "SI": "Slovenia", + "SB": "Solomon Islands", + "SO": "Somalia", + "ZA": "South Africa", + "GS": "South Georgia/Sandwich Islands", + "KR": "South Korea", + "SS": "South Sudan", + "ES": "Spain", + "LK": "Sri Lanka", + "SD": "Sudan", + "SR": "Suriname", + "SJ": "Svalbard and Jan Mayen", + "SZ": "Swaziland", + "SE": "Sweden", + "CH": "Switzerland", + "SY": "Syria", + "TW": "Taiwan", + "TJ": "Tajikistan", + "TZ": "Tanzania", + "TH": "Thailand", + "TL": "Timor-Leste", + "TG": "Togo", + "TK": "Tokelau", + "TO": "Tonga", + "TT": "Trinidad and Tobago", + "TN": "Tunisia", + "TR": "Turkey", + "TM": "Turkmenistan", + "TC": "Turks and Caicos Islands", + "TV": "Tuvalu", + "UG": "Uganda", + "UA": "Ukraine", + "AE": "United Arab Emirates", + "GB": "United Kingdom (UK)", + "US": "United States (US)", + "UM": "United States (US) Minor Outlying Islands", + "VI": "United States (US) Virgin Islands", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VU": "Vanuatu", + "VA": "Vatican", + "VE": "Venezuela", + "VN": "Vietnam", + "WF": "Wallis and Futuna", + "EH": "Western Sahara", + "YE": "Yemen", + "ZM": "Zambia", + "ZW": "Zimbabwe" + }, + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_specific_ship_to_countries" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_default_customer_address", + "label": "Default customer location", + "description": "", + "type": "select", + "default": "geolocation", + "options": { + "base": "Shop base address", + "geolocation": "Geolocate", + "geolocation_ajax": "Geolocate (with page caching support)" + }, + "tip": "This option determines a customers default location. The MaxMind GeoLite Database will be periodically downloaded to your wp-content directory if using geolocation.", + "value": "geolocation", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_default_customer_address" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_calc_taxes", + "label": "Enable taxes", + "description": "Enable tax rates and calculations", + "type": "checkbox", + "default": "no", + "tip": "Rates will be configurable and taxes will be calculated during checkout.", + "value": "yes", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_calc_taxes" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_enable_coupons", + "label": "Enable coupons", + "description": "Enable the use of coupon codes", + "type": "checkbox", + "default": "yes", + "tip": "Coupons can be applied from the cart and checkout pages.", + "value": "yes", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_enable_coupons" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_calc_discounts_sequentially", + "label": "", + "description": "Calculate coupon discounts sequentially", + "type": "checkbox", + "default": "no", + "tip": "When applying multiple coupons, apply the first coupon to the full price and the second coupon to the discounted price and so on.", + "value": "no", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_calc_discounts_sequentially" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_currency", + "label": "Currency!", + "description": "This controls what currency prices are listed!", + "type": "select", + "default": "GBP", + "options": { + "AED": "United Arab Emirates dirham (د.إ)", + "AFN": "Afghan afghani (؋)", + "ALL": "Albanian lek (L)", + "AMD": "Armenian dram (AMD)", + "ANG": "Netherlands Antillean guilder (ƒ)", + "AOA": "Angolan kwanza (Kz)", + "ARS": "Argentine peso ($)", + "AUD": "Australian dollar ($)", + "AWG": "Aruban florin (Afl.)", + "AZN": "Azerbaijani manat (AZN)", + "BAM": "Bosnia and Herzegovina convertible mark (KM)", + "BBD": "Barbadian dollar ($)", + "BDT": "Bangladeshi taka (৳ )", + "BGN": "Bulgarian lev (лв.)", + "BHD": "Bahraini dinar (.د.ب)", + "BIF": "Burundian franc (Fr)", + "BMD": "Bermudian dollar ($)", + "BND": "Brunei dollar ($)", + "BOB": "Bolivian boliviano (Bs.)", + "BRL": "Brazilian real (R$)", + "BSD": "Bahamian dollar ($)", + "BTC": "Bitcoin (฿)", + "BTN": "Bhutanese ngultrum (Nu.)", + "BWP": "Botswana pula (P)", + "BYR": "Belarusian ruble (old) (Br)", + "BYN": "Belarusian ruble (Br)", + "BZD": "Belize dollar ($)", + "CAD": "Canadian dollar ($)", + "CDF": "Congolese franc (Fr)", + "CHF": "Swiss franc (CHF)", + "CLP": "Chilean peso ($)", + "CNY": "Chinese yuan (¥)", + "COP": "Colombian peso ($)", + "CRC": "Costa Rican colón (₡)", + "CUC": "Cuban convertible peso ($)", + "CUP": "Cuban peso ($)", + "CVE": "Cape Verdean escudo ($)", + "CZK": "Czech koruna (Kč)", + "DJF": "Djiboutian franc (Fr)", + "DKK": "Danish krone (DKK)", + "DOP": "Dominican peso (RD$)", + "DZD": "Algerian dinar (د.ج)", + "EGP": "Egyptian pound (EGP)", + "ERN": "Eritrean nakfa (Nfk)", + "ETB": "Ethiopian birr (Br)", + "EUR": "Euro (€)", + "FJD": "Fijian dollar ($)", + "FKP": "Falkland Islands pound (£)", + "GBP": "Pound sterling (£)", + "GEL": "Georgian lari (₾)", + "GGP": "Guernsey pound (£)", + "GHS": "Ghana cedi (₵)", + "GIP": "Gibraltar pound (£)", + "GMD": "Gambian dalasi (D)", + "GNF": "Guinean franc (Fr)", + "GTQ": "Guatemalan quetzal (Q)", + "GYD": "Guyanese dollar ($)", + "HKD": "Hong Kong dollar ($)", + "HNL": "Honduran lempira (L)", + "HRK": "Croatian kuna (Kn)", + "HTG": "Haitian gourde (G)", + "HUF": "Hungarian forint (Ft)", + "IDR": "Indonesian rupiah (Rp)", + "ILS": "Israeli new shekel (₪)", + "IMP": "Manx pound (£)", + "INR": "Indian rupee (₹)", + "IQD": "Iraqi dinar (ع.د)", + "IRR": "Iranian rial (﷼)", + "IRT": "Iranian toman (تومان)", + "ISK": "Icelandic króna (kr.)", + "JEP": "Jersey pound (£)", + "JMD": "Jamaican dollar ($)", + "JOD": "Jordanian dinar (د.ا)", + "JPY": "Japanese yen (¥)", + "KES": "Kenyan shilling (KSh)", + "KGS": "Kyrgyzstani som (сом)", + "KHR": "Cambodian riel (៛)", + "KMF": "Comorian franc (Fr)", + "KPW": "North Korean won (₩)", + "KRW": "South Korean won (₩)", + "KWD": "Kuwaiti dinar (د.ك)", + "KYD": "Cayman Islands dollar ($)", + "KZT": "Kazakhstani tenge (KZT)", + "LAK": "Lao kip (₭)", + "LBP": "Lebanese pound (ل.ل)", + "LKR": "Sri Lankan rupee (රු)", + "LRD": "Liberian dollar ($)", + "LSL": "Lesotho loti (L)", + "LYD": "Libyan dinar (ل.د)", + "MAD": "Moroccan dirham (د.م.)", + "MDL": "Moldovan leu (MDL)", + "MGA": "Malagasy ariary (Ar)", + "MKD": "Macedonian denar (ден)", + "MMK": "Burmese kyat (Ks)", + "MNT": "Mongolian tögrög (₮)", + "MOP": "Macanese pataca (P)", + "MRO": "Mauritanian ouguiya (UM)", + "MUR": "Mauritian rupee (₨)", + "MVR": "Maldivian rufiyaa (.ރ)", + "MWK": "Malawian kwacha (MK)", + "MXN": "Mexican peso ($)", + "MYR": "Malaysian ringgit (RM)", + "MZN": "Mozambican metical (MT)", + "NAD": "Namibian dollar ($)", + "NGN": "Nigerian naira (₦)", + "NIO": "Nicaraguan córdoba (C$)", + "NOK": "Norwegian krone (kr)", + "NPR": "Nepalese rupee (₨)", + "NZD": "New Zealand dollar ($)", + "OMR": "Omani rial (ر.ع.)", + "PAB": "Panamanian balboa (B/.)", + "PEN": "Peruvian nuevo sol (S/.)", + "PGK": "Papua New Guinean kina (K)", + "PHP": "Philippine peso (₱)", + "PKR": "Pakistani rupee (₨)", + "PLN": "Polish złoty (zł)", + "PRB": "Transnistrian ruble (р.)", + "PYG": "Paraguayan guaraní (₲)", + "QAR": "Qatari riyal (ر.ق)", + "RON": "Romanian leu (lei)", + "RSD": "Serbian dinar (дин.)", + "RUB": "Russian ruble (₽)", + "RWF": "Rwandan franc (Fr)", + "SAR": "Saudi riyal (ر.س)", + "SBD": "Solomon Islands dollar ($)", + "SCR": "Seychellois rupee (₨)", + "SDG": "Sudanese pound (ج.س.)", + "SEK": "Swedish krona (kr)", + "SGD": "Singapore dollar ($)", + "SHP": "Saint Helena pound (£)", + "SLL": "Sierra Leonean leone (Le)", + "SOS": "Somali shilling (Sh)", + "SRD": "Surinamese dollar ($)", + "SSP": "South Sudanese pound (£)", + "STD": "São Tomé and Príncipe dobra (Db)", + "SYP": "Syrian pound (ل.س)", + "SZL": "Swazi lilangeni (L)", + "THB": "Thai baht (฿)", + "TJS": "Tajikistani somoni (ЅМ)", + "TMT": "Turkmenistan manat (m)", + "TND": "Tunisian dinar (د.ت)", + "TOP": "Tongan paʻanga (T$)", + "TRY": "Turkish lira (₺)", + "TTD": "Trinidad and Tobago dollar ($)", + "TWD": "New Taiwan dollar (NT$)", + "TZS": "Tanzanian shilling (Sh)", + "UAH": "Ukrainian hryvnia (₴)", + "UGX": "Ugandan shilling (UGX)", + "USD": "United States (US) dollar ($)", + "UYU": "Uruguayan peso ($)", + "UZS": "Uzbekistani som (UZS)", + "VEF": "Venezuelan bolívar (Bs F)", + "VND": "Vietnamese đồng (₫)", + "VUV": "Vanuatu vatu (Vt)", + "WST": "Samoan tālā (T)", + "XAF": "Central African CFA franc (CFA)", + "XCD": "East Caribbean dollar ($)", + "XOF": "West African CFA franc (CFA)", + "XPF": "CFP franc (Fr)", + "YER": "Yemeni rial (﷼)", + "ZAR": "South African rand (R)", + "ZMW": "Zambian kwacha (ZK)" + }, + "tip": "This controls what currency prices are listed at in the catalog and which currency gateways will take payments in.", + "value": "GBP", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_currency" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_currency_pos", + "label": "Currency position", + "description": "This controls the position of the currency symbol.", + "type": "select", + "default": "left", + "options": { + "left": "Left", + "right": "Right", + "left_space": "Left with space", + "right_space": "Right with space" + }, + "tip": "This controls the position of the currency symbol.", + "value": "left", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_currency_pos" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_price_thousand_sep", + "label": "Thousand separator!!", + "description": "This sets the thousand separator!!", + "type": "text", + "default": ",", + "tip": "This sets the thousand separator of displayed prices.", + "value": "~", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_price_thousand_sep" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_price_decimal_sep", + "label": "Decimal separator", + "description": "This sets the decimal separator of displayed prices.", + "type": "text", + "default": ".", + "tip": "This sets the decimal separator of displayed prices.", + "value": ".", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_price_decimal_sep" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_price_num_decimals", + "label": "Number of decimals", + "description": "This sets the number of decimal points shown in displayed prices.", + "type": "number", + "default": "2", + "tip": "This sets the number of decimal points shown in displayed prices.", + "value": "2", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_price_num_decimals" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + }, + { + "id": "woocommerce_bookings_tz_calculation", + "label": "Enable Bookings Timezone calculation", + "description": "Schedule Bookings events, such as reminder emails and auto-completions of bookings, using your site’s configured timezone.", + "type": "checkbox", + "default": "no", + "value": "no", + "_links": { + "self": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general/woocommerce_bookings_tz_calculation" + } + ], + "collection": [ + { + "href": "https://jamosova3.mystagingwebsite.com/wp-json/wc/v2/settings/general" + } + ] + } + } + ] +} diff --git a/Networking/NetworkingTests/Responses/settings-general.json b/Networking/NetworkingTests/Responses/settings-general.json index 029d7893227..5e6e72cc00c 100644 --- a/Networking/NetworkingTests/Responses/settings-general.json +++ b/Networking/NetworkingTests/Responses/settings-general.json @@ -2765,4 +2765,4 @@ } } ] -} \ No newline at end of file +} diff --git a/Storage/Storage.xcodeproj/project.pbxproj b/Storage/Storage.xcodeproj/project.pbxproj index 8d8561a7607..043aeab04d5 100644 --- a/Storage/Storage.xcodeproj/project.pbxproj +++ b/Storage/Storage.xcodeproj/project.pbxproj @@ -23,6 +23,8 @@ 7471A515216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7471A511216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataProperties.swift */; }; 7471A516216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7471A512216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataClass.swift */; }; 7471A517216CF0FE00219F7E /* SiteVisitStats+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7471A513216CF0FE00219F7E /* SiteVisitStats+CoreDataProperties.swift */; }; + 7492FAD6217FA9C100ED2C69 /* SiteSetting+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FAD4217FA9C100ED2C69 /* SiteSetting+CoreDataClass.swift */; }; + 7492FAD7217FA9C100ED2C69 /* SiteSetting+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FAD5217FA9C100ED2C69 /* SiteSetting+CoreDataProperties.swift */; }; 74938EC8216FA9B200540BA1 /* OrderStatsItem+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74938EC4216FA9B200540BA1 /* OrderStatsItem+CoreDataClass.swift */; }; 74938EC9216FA9B200540BA1 /* OrderStatsItem+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74938EC5216FA9B200540BA1 /* OrderStatsItem+CoreDataProperties.swift */; }; 74938ECA216FA9B200540BA1 /* OrderStats+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74938EC6216FA9B200540BA1 /* OrderStats+CoreDataClass.swift */; }; @@ -83,6 +85,9 @@ 7471A511216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SiteVisitStatsItem+CoreDataProperties.swift"; sourceTree = ""; }; 7471A512216CF0FE00219F7E /* SiteVisitStatsItem+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SiteVisitStatsItem+CoreDataClass.swift"; sourceTree = ""; }; 7471A513216CF0FE00219F7E /* SiteVisitStats+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SiteVisitStats+CoreDataProperties.swift"; sourceTree = ""; }; + 7492FAD3217FA88E00ED2C69 /* Model 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Model 5.xcdatamodel"; sourceTree = ""; }; + 7492FAD4217FA9C100ED2C69 /* SiteSetting+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SiteSetting+CoreDataClass.swift"; sourceTree = ""; }; + 7492FAD5217FA9C100ED2C69 /* SiteSetting+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SiteSetting+CoreDataProperties.swift"; sourceTree = ""; }; 74938EC4216FA9B200540BA1 /* OrderStatsItem+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderStatsItem+CoreDataClass.swift"; sourceTree = ""; }; 74938EC5216FA9B200540BA1 /* OrderStatsItem+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderStatsItem+CoreDataProperties.swift"; sourceTree = ""; }; 74938EC6216FA9B200540BA1 /* OrderStats+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderStats+CoreDataClass.swift"; sourceTree = ""; }; @@ -292,6 +297,8 @@ B505F6D820BEEA3100BB1B69 /* Account+CoreDataProperties.swift */, B5B914C320EFF03500F2F832 /* Site+CoreDataClass.swift */, B5B914C420EFF03500F2F832 /* Site+CoreDataProperties.swift */, + 7492FAD4217FA9C100ED2C69 /* SiteSetting+CoreDataClass.swift */, + 7492FAD5217FA9C100ED2C69 /* SiteSetting+CoreDataProperties.swift */, 7426A04320F68F27002A4E07 /* Order+CoreDataClass.swift */, 7426A04420F68F27002A4E07 /* Order+CoreDataProperties.swift */, 7426A04E20F69D00002A4E07 /* OrderCoupon+CoreDataClass.swift */, @@ -513,6 +520,7 @@ B52B0F7920AA287C00477698 /* StorageManagerType.swift in Sources */, 7471A517216CF0FE00219F7E /* SiteVisitStats+CoreDataProperties.swift in Sources */, 7426A05420F69DA4002A4E07 /* OrderItem+CoreDataClass.swift in Sources */, + 7492FAD6217FA9C100ED2C69 /* SiteSetting+CoreDataClass.swift in Sources */, B505F6E020BEEA8100BB1B69 /* StorageType.swift in Sources */, 746A9D22214078080013F6FF /* TopEarnerStats+CoreDataProperties.swift in Sources */, B54CA5C920A4C17800F38CD1 /* NSObject+Storage.swift in Sources */, @@ -524,6 +532,7 @@ 7426A05020F69D00002A4E07 /* OrderCoupon+CoreDataClass.swift in Sources */, 746A9D23214078080013F6FF /* TopEarnerStatsItem+CoreDataClass.swift in Sources */, B505F6DE20BEEA4F00BB1B69 /* CoreDataManager.swift in Sources */, + 7492FAD7217FA9C100ED2C69 /* SiteSetting+CoreDataProperties.swift in Sources */, 746A9D24214078080013F6FF /* TopEarnerStatsItem+CoreDataProperties.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -817,12 +826,13 @@ B59E11D820A9D00C004121A4 /* WooCommerce.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + 7492FAD3217FA88E00ED2C69 /* Model 5.xcdatamodel */, 7471A50F216CEEA900219F7E /* Model 4.xcdatamodel */, 74B053702153090F0068EB85 /* Model 3.xcdatamodel */, 746A9D14214071F90013F6FF /* Model 2.xcdatamodel */, B59E11D920A9D00C004121A4 /* Model.xcdatamodel */, ); - currentVersion = 7471A50F216CEEA900219F7E /* Model 4.xcdatamodel */; + currentVersion = 7492FAD3217FA88E00ED2C69 /* Model 5.xcdatamodel */; path = WooCommerce.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/Storage/Storage/Model/MIGRATIONS.md b/Storage/Storage/Model/MIGRATIONS.md index 7e5b4925942..5b03f49f05f 100644 --- a/Storage/Storage/Model/MIGRATIONS.md +++ b/Storage/Storage/Model/MIGRATIONS.md @@ -2,19 +2,23 @@ This file documents changes in the extensions data model. Please explain any changes to the data model as well as any custom migrations. +## Model 5 +- @bummytime 2018-10-23 + - Added new entity: `SiteSetting`, to encapsulate all of the site settings + ## Model 4 - @bummytime 2018-10-09 -- Added new entity: `SiteVisitStats`, to encapsulate all of the visitor stats for a given site & granularity -- Added new entity: `SiteVisitStatsItem`, to encapsulate all the visitor stats for a specific period -- Added new entity: `OrderStats`, to encapsulate all of the order stats for a given site & granularity -- Added new entity: `OrderStatsItem`, to encapsulate all the order stats for a specific period + - Added new entity: `SiteVisitStats`, to encapsulate all of the visitor stats for a given site & granularity + - Added new entity: `SiteVisitStatsItem`, to encapsulate all the visitor stats for a specific period + - Added new entity: `OrderStats`, to encapsulate all of the order stats for a given site & granularity + - Added new entity: `OrderStatsItem`, to encapsulate all the order stats for a specific period ## Model 3 - @bummytime 2018-09-19 -- Widened `quantity` attribute on `OrderItem` from Int16 to Int64 -- Widened `quantity` attribute on `TopEarnerStatsItem` from Int16 to Int64 + - Widened `quantity` attribute on `OrderItem` from Int16 to Int64 + - Widened `quantity` attribute on `TopEarnerStatsItem` from Int16 to Int64 ## Model 2 - @bummytime 2018-09-05 -- Added new entity: `TopEarnerStats`, to encapsulate all of the top earner stats for a given site & granularity -- Added new entity: `TopEarnerStatsItem`, to encapsulate all the top earner stats for a specific product + - Added new entity: `TopEarnerStats`, to encapsulate all of the top earner stats for a given site & granularity + - Added new entity: `TopEarnerStatsItem`, to encapsulate all the top earner stats for a specific product diff --git a/Storage/Storage/Model/SiteSetting+CoreDataClass.swift b/Storage/Storage/Model/SiteSetting+CoreDataClass.swift new file mode 100644 index 00000000000..666f40c98cc --- /dev/null +++ b/Storage/Storage/Model/SiteSetting+CoreDataClass.swift @@ -0,0 +1,7 @@ +import Foundation +import CoreData + +@objc(SiteSetting) +public class SiteSetting: NSManagedObject { + +} diff --git a/Storage/Storage/Model/SiteSetting+CoreDataProperties.swift b/Storage/Storage/Model/SiteSetting+CoreDataProperties.swift new file mode 100644 index 00000000000..9af7dbd8886 --- /dev/null +++ b/Storage/Storage/Model/SiteSetting+CoreDataProperties.swift @@ -0,0 +1,17 @@ +import Foundation +import CoreData + + +extension SiteSetting { + + @nonobjc public class func fetchRequest() -> NSFetchRequest { + return NSFetchRequest(entityName: "SiteSetting") + } + + @NSManaged public var siteID: Int64 + @NSManaged public var settingID: String? + @NSManaged public var label: String? + @NSManaged public var settingDescription: String? + @NSManaged public var value: String? + +} diff --git a/Storage/Storage/Model/WooCommerce.xcdatamodeld/.xccurrentversion b/Storage/Storage/Model/WooCommerce.xcdatamodeld/.xccurrentversion index ea1cf0bc1af..fe638601856 100644 --- a/Storage/Storage/Model/WooCommerce.xcdatamodeld/.xccurrentversion +++ b/Storage/Storage/Model/WooCommerce.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - Model 4.xcdatamodel + Model 5.xcdatamodel diff --git a/Storage/Storage/Model/WooCommerce.xcdatamodeld/Model 5.xcdatamodel/contents b/Storage/Storage/Model/WooCommerce.xcdatamodeld/Model 5.xcdatamodel/contents new file mode 100644 index 00000000000..55757459a0d --- /dev/null +++ b/Storage/Storage/Model/WooCommerce.xcdatamodeld/Model 5.xcdatamodel/contents @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Storage/Storage/Tools/StorageType+Extensions.swift b/Storage/Storage/Tools/StorageType+Extensions.swift index 8597dcf34a0..f0c7731b4ff 100644 --- a/Storage/Storage/Tools/StorageType+Extensions.swift +++ b/Storage/Storage/Tools/StorageType+Extensions.swift @@ -74,4 +74,19 @@ public extension StorageType { let predicate = NSPredicate(format: "period ==[c] %@", period) return firstObject(ofType: OrderStatsItem.self, matching: predicate) } + + /// Retrieves all of the Stored SiteSettings for the provided siteID. + /// + public func loadSiteSettings(siteID: Int) -> [SiteSetting]? { + let predicate = NSPredicate(format: "siteID = %ld", siteID) + let descriptor = NSSortDescriptor(keyPath: \SiteSetting.settingID, ascending: false) + return allObjects(ofType: SiteSetting.self, matching: predicate, sortedBy: [descriptor]) + } + + /// Retrieves the Stored SiteSetting. + /// + public func loadSiteSetting(siteID: Int, settingID: String) -> SiteSetting? { + let predicate = NSPredicate(format: "siteID = %ld AND settingID ==[c] %@", siteID, settingID) + return firstObject(ofType: SiteSetting.self, matching: predicate) + } } diff --git a/Yosemite/Yosemite.xcodeproj/project.pbxproj b/Yosemite/Yosemite.xcodeproj/project.pbxproj index 5ddc0f3c2b7..9fe33a4c2ce 100644 --- a/Yosemite/Yosemite.xcodeproj/project.pbxproj +++ b/Yosemite/Yosemite.xcodeproj/project.pbxproj @@ -16,6 +16,11 @@ 7455D4692141B59E00FA8C1F /* TopEarnerStatsItem+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7455D4682141B59E00FA8C1F /* TopEarnerStatsItem+ReadOnlyConvertible.swift */; }; 74685D4E20F7EFA7008958C1 /* OrderItem+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74685D4D20F7EFA7008958C1 /* OrderItem+ReadOnlyConvertible.swift */; }; 74685D5020F7F3CE008958C1 /* OrderCoupon+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74685D4F20F7F3CE008958C1 /* OrderCoupon+ReadOnlyConvertible.swift */; }; + 7492FAD9217FAD1000ED2C69 /* SiteSetting+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FAD8217FAD1000ED2C69 /* SiteSetting+ReadOnlyConvertible.swift */; }; + 7492FADB217FAE4D00ED2C69 /* SiteSetting+ReadOnlyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FADA217FAE4D00ED2C69 /* SiteSetting+ReadOnlyType.swift */; }; + 7492FADD217FAF5C00ED2C69 /* SettingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FADC217FAF5C00ED2C69 /* SettingStore.swift */; }; + 7492FADF217FB11D00ED2C69 /* SettingAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FADE217FB11D00ED2C69 /* SettingAction.swift */; }; + 7492FAE1217FB87100ED2C69 /* SettingStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7492FAE0217FB87100ED2C69 /* SettingStoreTests.swift */; }; 7495C5292114979D00CDD33B /* StatsStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7495C5282114979D00CDD33B /* StatsStoreTests.swift */; }; 749737672141CC8C0008C490 /* TopEarnerStats+ReadOnlyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 749737662141CC8B0008C490 /* TopEarnerStats+ReadOnlyType.swift */; }; 7499936420EFBC1B00CF01CD /* OrderNoteAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7499936320EFBC1A00CF01CD /* OrderNoteAction.swift */; }; @@ -86,6 +91,11 @@ 7455D4682141B59E00FA8C1F /* TopEarnerStatsItem+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TopEarnerStatsItem+ReadOnlyConvertible.swift"; sourceTree = ""; }; 74685D4D20F7EFA7008958C1 /* OrderItem+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OrderItem+ReadOnlyConvertible.swift"; sourceTree = ""; }; 74685D4F20F7F3CE008958C1 /* OrderCoupon+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OrderCoupon+ReadOnlyConvertible.swift"; sourceTree = ""; }; + 7492FAD8217FAD1000ED2C69 /* SiteSetting+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SiteSetting+ReadOnlyConvertible.swift"; sourceTree = ""; }; + 7492FADA217FAE4D00ED2C69 /* SiteSetting+ReadOnlyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SiteSetting+ReadOnlyType.swift"; sourceTree = ""; }; + 7492FADC217FAF5C00ED2C69 /* SettingStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingStore.swift; sourceTree = ""; }; + 7492FADE217FB11D00ED2C69 /* SettingAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingAction.swift; sourceTree = ""; }; + 7492FAE0217FB87100ED2C69 /* SettingStoreTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingStoreTests.swift; sourceTree = ""; }; 7495C5282114979D00CDD33B /* StatsStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsStoreTests.swift; sourceTree = ""; }; 749737662141CC8B0008C490 /* TopEarnerStats+ReadOnlyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TopEarnerStats+ReadOnlyType.swift"; sourceTree = ""; }; 7499936320EFBC1A00CF01CD /* OrderNoteAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderNoteAction.swift; sourceTree = ""; }; @@ -190,6 +200,7 @@ 74FD596C216FB6ED00A5AE83 /* OrderStats+ReadOnlyConvertible.swift */, 74FD596D216FB6ED00A5AE83 /* OrderStatsItem+ReadOnlyConvertible.swift */, B505254B20EE6491008090F5 /* Site+ReadOnlyConvertible.swift */, + 7492FAD8217FAD1000ED2C69 /* SiteSetting+ReadOnlyConvertible.swift */, 744A3216216D55F80051439B /* SiteVisitStats+ReadOnlyConvertible.swift */, 744A3217216D55F80051439B /* SiteVisitStatsItem+ReadOnlyConvertible.swift */, 7455D4662141B57600FA8C1F /* TopEarnerStats+ReadOnlyConvertible.swift */, @@ -205,6 +216,7 @@ B52E0031211A440D00700FDE /* Order+ReadOnlyType.swift */, 74FD596A216FB65900A5AE83 /* OrderStats+ReadOnlyType.swift */, B52E0033211A449600700FDE /* Site+ReadOnlyType.swift */, + 7492FADA217FAE4D00ED2C69 /* SiteSetting+ReadOnlyType.swift */, 744A321A216D57D30051439B /* SiteVisitStats+ReadOnlyType.swift */, 749737662141CC8B0008C490 /* TopEarnerStats+ReadOnlyType.swift */, ); @@ -239,6 +251,7 @@ B5BC736420D1A98500B5B6FA /* AccountStore.swift */, 74A7688B20D45EBA00F9D437 /* OrderStore.swift */, 7499936520EFBC7200CF01CD /* OrderNoteStore.swift */, + 7492FADC217FAF5C00ED2C69 /* SettingStore.swift */, 74A18C552113827E00DCF8A8 /* StatsStore.swift */, ); path = Stores; @@ -250,6 +263,7 @@ B5BC736720D1AA8F00B5B6FA /* AccountStoreTests.swift */, 74A7688D20D45ED400F9D437 /* OrderStoreTests.swift */, 7499936720EFC0ED00CF01CD /* OrderNoteStoreTests.swift */, + 7492FAE0217FB87100ED2C69 /* SettingStoreTests.swift */, 7495C5282114979D00CDD33B /* StatsStoreTests.swift */, ); path = Stores; @@ -369,6 +383,7 @@ B5DC3CB020D1B8720063AC41 /* AccountAction.swift */, 74A7688F20D45F9300F9D437 /* OrderAction.swift */, 7499936320EFBC1A00CF01CD /* OrderNoteAction.swift */, + 7492FADE217FB11D00ED2C69 /* SettingAction.swift */, 74A18C57211382A000DCF8A8 /* StatsAction.swift */, ); path = Actions; @@ -567,6 +582,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7492FADD217FAF5C00ED2C69 /* SettingStore.swift in Sources */, B52E0032211A440D00700FDE /* Order+ReadOnlyType.swift in Sources */, B5C9DE152087FF0E006B910A /* Dispatcher.swift in Sources */, B52E0030211A439E00700FDE /* Account+ReadOnlyType.swift in Sources */, @@ -577,6 +593,7 @@ B5631ECD2114DF8C008D3535 /* EntityListener.swift in Sources */, B5DC3CB120D1B8720063AC41 /* AccountAction.swift in Sources */, B5BC736520D1A98500B5B6FA /* AccountStore.swift in Sources */, + 7492FAD9217FAD1000ED2C69 /* SiteSetting+ReadOnlyConvertible.swift in Sources */, 744A3219216D55F80051439B /* SiteVisitStatsItem+ReadOnlyConvertible.swift in Sources */, B56C1EC220EAE2E500D749F9 /* ReadOnlyConvertible.swift in Sources */, 74A18C562113827E00DCF8A8 /* StatsStore.swift in Sources */, @@ -601,10 +618,12 @@ B5EED1A820F4F3CF00652449 /* Account+ReadOnlyConvertible.swift in Sources */, 74FD596B216FB65900A5AE83 /* OrderStats+ReadOnlyType.swift in Sources */, B5F2AE9720EBB54A00FEDC59 /* FetchedResultsControllerDelegateWrapper.swift in Sources */, + 7492FADF217FB11D00ED2C69 /* SettingAction.swift in Sources */, 749737672141CC8C0008C490 /* TopEarnerStats+ReadOnlyType.swift in Sources */, 74A18C58211382A000DCF8A8 /* StatsAction.swift in Sources */, 7499936420EFBC1B00CF01CD /* OrderNoteAction.swift in Sources */, 7455D4692141B59E00FA8C1F /* TopEarnerStatsItem+ReadOnlyConvertible.swift in Sources */, + 7492FADB217FAE4D00ED2C69 /* SiteSetting+ReadOnlyType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -615,6 +634,7 @@ 7495C5292114979D00CDD33B /* StatsStoreTests.swift in Sources */, 74A7688E20D45ED400F9D437 /* OrderStoreTests.swift in Sources */, B5C9DE272087FF20006B910A /* MockupAcount.swift in Sources */, + 7492FAE1217FB87100ED2C69 /* SettingStoreTests.swift in Sources */, B5C9DE222087FF20006B910A /* DispatcherTests.swift in Sources */, B53A56A0211245E0000776C9 /* MockupStorage+Sample.swift in Sources */, B5A01CA120D19C4700E3207E /* MockupStorage.swift in Sources */, diff --git a/Yosemite/Yosemite/Actions/SettingAction.swift b/Yosemite/Yosemite/Actions/SettingAction.swift new file mode 100644 index 00000000000..104f3c7c194 --- /dev/null +++ b/Yosemite/Yosemite/Actions/SettingAction.swift @@ -0,0 +1,9 @@ +import Foundation +import Networking + + +// MARK: - SettingAction: Defines all of the Actions supported by the SettingStore. +// +public enum SettingAction: Action { + case retrieveSiteSettings(siteID: Int, onCompletion: (Error?) -> Void) +} diff --git a/Yosemite/Yosemite/Model/Model.swift b/Yosemite/Yosemite/Model/Model.swift index ea919d89749..853284677c1 100644 --- a/Yosemite/Yosemite/Model/Model.swift +++ b/Yosemite/Yosemite/Model/Model.swift @@ -18,6 +18,7 @@ public typealias OrderStats = Networking.OrderStats public typealias OrderStatsItem = Networking.OrderStatsItem public typealias StatGranularity = Networking.StatGranularity public typealias Site = Networking.Site +public typealias SiteSetting = Networking.SiteSetting public typealias SiteVisitStats = Networking.SiteVisitStats public typealias SiteVisitStatsItem = Networking.SiteVisitStatsItem public typealias TopEarnerStats = Networking.TopEarnerStats @@ -27,10 +28,11 @@ public typealias TopEarnerStatsItem = Networking.TopEarnerStatsItem // MARK: - Exported Storage Symbols public typealias StorageAccount = Storage.Account -public typealias StorageSite = Storage.Site public typealias StorageOrder = Storage.Order public typealias StorageOrderStats = Storage.OrderStats public typealias StorageOrderStatsItem = Storage.OrderStatsItem +public typealias StorageSite = Storage.Site +public typealias StorageSiteSetting = Storage.SiteSetting public typealias StorageSiteVisitStats = Storage.SiteVisitStats public typealias StorageSiteVisitStatsItem = Storage.SiteVisitStatsItem public typealias StorageTopEarnerStats = Storage.TopEarnerStats diff --git a/Yosemite/Yosemite/Model/ReadOnly/SiteSetting+ReadOnlyType.swift b/Yosemite/Yosemite/Model/ReadOnly/SiteSetting+ReadOnlyType.swift new file mode 100644 index 00000000000..90a6c6d1a38 --- /dev/null +++ b/Yosemite/Yosemite/Model/ReadOnly/SiteSetting+ReadOnlyType.swift @@ -0,0 +1,19 @@ +import Foundation +import Storage + + +// MARK: - Yosemite.SiteSetting: ReadOnlyType +// +extension Yosemite.SiteSetting: ReadOnlyType { + + /// Indicates if the receiver is the Storage.Entity, backing up the specified ReadOnly.Entity. + /// + public func isReadOnlyRepresentation(of storageEntity: Any) -> Bool { + guard let storageSiteSiteSetting = storageEntity as? Storage.SiteSetting else { + return false + } + + return siteID == Int(storageSiteSiteSetting.siteID) && + storageSiteSiteSetting.settingID == settingID + } +} diff --git a/Yosemite/Yosemite/Model/Storage/SiteSetting+ReadOnlyConvertible.swift b/Yosemite/Yosemite/Model/Storage/SiteSetting+ReadOnlyConvertible.swift new file mode 100644 index 00000000000..4321aa7e254 --- /dev/null +++ b/Yosemite/Yosemite/Model/Storage/SiteSetting+ReadOnlyConvertible.swift @@ -0,0 +1,28 @@ +import Foundation +import Storage + + +// Storage.SiteSetting: ReadOnlyConvertible Conformance. +// +extension Storage.SiteSetting: ReadOnlyConvertible { + + /// Updates the Storage.SiteSetting with the a ReadOnly. + /// + public func update(with setting: Yosemite.SiteSetting) { + siteID = Int64(setting.siteID) + settingID = setting.settingID + label = setting.label + settingDescription = setting.settingDescription + value = setting.value + } + + /// Returns a ReadOnly version of the receiver. + /// + public func toReadOnly() -> Yosemite.SiteSetting { + return SiteSetting(siteID: Int(siteID), + settingID: settingID ?? "", + label: label ?? "", + description: settingDescription ?? "", + value: value ?? "") + } +} diff --git a/Yosemite/Yosemite/Stores/SettingStore.swift b/Yosemite/Yosemite/Stores/SettingStore.swift new file mode 100644 index 00000000000..c49dff0758c --- /dev/null +++ b/Yosemite/Yosemite/Stores/SettingStore.swift @@ -0,0 +1,85 @@ +import Foundation +import Networking +import Storage +import CocoaLumberjack + + +// MARK: - SettingStore +// +public class SettingStore: Store { + + /// Registers for supported Actions. + /// + override public func registerSupportedActions(in dispatcher: Dispatcher) { + dispatcher.register(processor: self, for: OrderNoteAction.self) + } + + /// Receives and executes Actions. + /// + override public func onAction(_ action: Action) { + guard let action = action as? SettingAction else { + assertionFailure("SettingStore received an unsupported action") + return + } + + switch action { + case .retrieveSiteSettings(let siteID, let onCompletion): + retrieveSiteSettings(siteID: siteID, onCompletion: onCompletion) + } + } +} + + +// MARK: - Services! +// +private extension SettingStore { + + /// Retrieves the site settings associated with the provided Site ID (if any!). + /// + func retrieveSiteSettings(siteID: Int, onCompletion: @escaping (Error?) -> Void) { + let remote = SiteSettingsRemote(network: network) + remote.loadGeneralSettings(for: siteID) { [weak self] (settings, error) in + guard let settings = settings else { + onCompletion(error) + return + } + + self?.upsertStoredSiteSettings(siteID: siteID, readOnlySiteSettings: settings) + onCompletion(nil) + } + } +} + + +// MARK: - Persistence +// +extension SettingStore { + + /// Updates (OR Inserts) the specified ReadOnly SiteSetting Entities into the Storage Layer. + /// + func upsertStoredSiteSettings(siteID: Int, readOnlySiteSettings: [Networking.SiteSetting]) { + assert(Thread.isMainThread) + let storage = storageManager.viewStorage + + // Upsert the settings from the read-only site settings + for readOnlyItem in readOnlySiteSettings { + if let existingStorageItem = storage.loadSiteSetting(siteID: siteID, settingID: readOnlyItem.settingID) { + existingStorageItem.update(with: readOnlyItem) + } else { + let newStorageItem = storage.insertNewObject(ofType: Storage.SiteSetting.self) + newStorageItem.update(with: readOnlyItem) + } + } + + // Now, remove any objects that exist in storageSiteSettings but not in readOnlySiteSettings + if let storageSiteSettings = storage.loadSiteSettings(siteID: siteID) { + storageSiteSettings.forEach({ storageItem in + if readOnlySiteSettings.first(where: { $0.settingID == storageItem.settingID } ) == nil { + storage.deleteObject(storageItem) + } + }) + } + + storage.saveIfNeeded() + } +} diff --git a/Yosemite/YosemiteTests/Stores/SettingStoreTests.swift b/Yosemite/YosemiteTests/Stores/SettingStoreTests.swift new file mode 100644 index 00000000000..08e43120927 --- /dev/null +++ b/Yosemite/YosemiteTests/Stores/SettingStoreTests.swift @@ -0,0 +1,235 @@ +import XCTest +@testable import Yosemite +@testable import Networking +@testable import Storage + + +/// SettingStoreTests Unit Tests +/// +class SettingStoreTests: XCTestCase { + + /// Mockup Dispatcher! + /// + private var dispatcher: Dispatcher! + + /// Mockup Network: Allows us to inject predefined responses! + /// + private var network: MockupNetwork! + + /// Mockup Storage: InMemory + /// + private var storageManager: MockupStorageManager! + + /// Convenience Property: Returns the StorageType associated with the main thread. + /// + private var viewStorage: StorageType { + return storageManager.viewStorage + } + + /// Dummy Site ID + /// + private let sampleSiteID = 123 + + + override func setUp() { + super.setUp() + dispatcher = Dispatcher() + storageManager = MockupStorageManager() + network = MockupNetwork() + } + + + // MARK: - SettingAction.retrieveSiteSettings + + + /// Verifies that `SettingAction.retrieveSiteSettings` effectively persists any retrieved SiteSettings. + /// + func testRetrieveSiteSettingsEffectivelyPersistsRetrievedSettings() { + let expectation = self.expectation(description: "Persist site settings") + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + network.simulateResponse(requestUrlSuffix: "settings/general", filename: "settings-general") + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + + let action = SettingAction.retrieveSiteSettings(siteID: sampleSiteID) { (error) in + XCTAssertNil(error) + XCTAssertEqual(self.viewStorage.countObjects(ofType: Storage.SiteSetting.self), 20) + + let readOnlySiteSetting = self.viewStorage.loadSiteSetting(siteID: self.sampleSiteID, settingID: self.sampleSiteSetting().settingID) + XCTAssertEqual(readOnlySiteSetting?.toReadOnly(), self.sampleSiteSetting()) + + let readOnlySiteSetting2 = self.viewStorage.loadSiteSetting(siteID: self.sampleSiteID, settingID: self.sampleSiteSetting2().settingID) + XCTAssertEqual(readOnlySiteSetting2?.toReadOnly(), self.sampleSiteSetting2()) + + expectation.fulfill() + } + + settingStore.onAction(action) + wait(for: [expectation], timeout: Constants.expectationTimeout) + } + + /// Verifies that `SettingAction.retrieveSiteSettings` effectively persists any updated SiteSettings. + /// + func testRetrieveSiteSettingsEffectivelyPersistsUpdatedSettings() { + let expectation = self.expectation(description: "Persist updated site settings") + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting(), sampleSiteSetting2()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + + network.simulateResponse(requestUrlSuffix: "settings/general", filename: "settings-general-alt") + let action = SettingAction.retrieveSiteSettings(siteID: sampleSiteID) { (error) in + XCTAssertNil(error) + XCTAssertEqual(self.viewStorage.countObjects(ofType: Storage.SiteSetting.self), 20) + + let readOnlySiteSetting = self.viewStorage.loadSiteSetting(siteID: self.sampleSiteID, settingID: self.sampleSiteSetting().settingID) + XCTAssertEqual(readOnlySiteSetting?.toReadOnly(), self.sampleSiteSettingMutated()) + + let readOnlySiteSetting2 = self.viewStorage.loadSiteSetting(siteID: self.sampleSiteID, settingID: self.sampleSiteSetting2().settingID) + XCTAssertEqual(readOnlySiteSetting2?.toReadOnly(), self.sampleSiteSetting2Mutated()) + expectation.fulfill() + } + + settingStore.onAction(action) + wait(for: [expectation], timeout: Constants.expectationTimeout) + } + + /// Verifies that `SettingAction.retrieveSiteSettings` returns an error whenever there is an error response from the backend. + /// + func testRetrieveSiteSettingsReturnsErrorUponReponseError() { + let expectation = self.expectation(description: "Retrieve site settings error response") + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + network.simulateResponse(requestUrlSuffix: "settings/general", filename: "generic_error") + let action = SettingAction.retrieveSiteSettings(siteID: sampleSiteID) { (error) in + XCTAssertNotNil(error) + expectation.fulfill() + } + + settingStore.onAction(action) + wait(for: [expectation], timeout: Constants.expectationTimeout) + } + + /// Verifies that `SettingAction.retrieveSiteSettings` returns an error whenever there is no backend response. + /// + func testRetrieveSiteSettingsReturnsErrorUponEmptyResponse() { + let expectation = self.expectation(description: "Retrieve site settings empty response") + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + let action = SettingAction.retrieveSiteSettings(siteID: sampleSiteID) { (error) in + XCTAssertNotNil(error) + expectation.fulfill() + } + + settingStore.onAction(action) + wait(for: [expectation], timeout: Constants.expectationTimeout) + } + + /// Verifies that `upsertStoredSiteSettings` effectively inserts a new SiteSetting, with the specified payload. + /// + func testUpsertStoredSiteSettingsEffectivelyPersistsNewSiteSettings() { + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + let remoteSiteSettings = [sampleSiteSetting(), sampleSiteSetting2()].sorted() + + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting(), sampleSiteSetting2()]) + + let storageSiteSettings = viewStorage.loadSiteSettings(siteID: sampleSiteID) + XCTAssertNotNil(storageSiteSettings) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + XCTAssertEqual(storageSiteSettings?.map({ $0.toReadOnly() }).sorted(), remoteSiteSettings) + } + + /// Verifies that `upsertStoredSiteSettings` does not produce duplicate entries. + /// + func testUpsertStoredSiteSettingsEffectivelyUpdatesPreexistantSiteSettings() { + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 1) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSettingMutated()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 1) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSettingMutated(), sampleSiteSetting2()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSettingMutated(), sampleSiteSetting2Mutated()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + + let expectedSiteSetting = sampleSiteSettingMutated() + let storageSiteSetting = viewStorage.loadSiteSetting(siteID: sampleSiteID, settingID: sampleSiteSettingMutated().settingID) + XCTAssertEqual(storageSiteSetting?.toReadOnly(), expectedSiteSetting) + + let expectedSiteSetting2 = sampleSiteSetting2Mutated() + let storageSiteSetting2 = viewStorage.loadSiteSetting(siteID: sampleSiteID, settingID: sampleSiteSetting2Mutated().settingID) + XCTAssertEqual(storageSiteSetting2?.toReadOnly(), expectedSiteSetting2) + } + + /// Verifies that `upsertStoredSiteSettings` removes previously stored SiteSettings correctly. + /// + func testUpsertStoredSiteSettingsEffectivelyRemovesInvalidSiteSettings() { + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting(), sampleSiteSetting2()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting2Mutated()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 1) + + let expectedSiteSetting = sampleSiteSetting2Mutated() + let storageSiteSetting = viewStorage.loadSiteSetting(siteID: sampleSiteID, settingID: sampleSiteSetting2Mutated().settingID) + XCTAssertEqual(storageSiteSetting?.toReadOnly(), expectedSiteSetting) + } + + /// Verifies that `upsertStoredSiteSettings` removes previously stored SiteSettings correctly if an empty read-only array is passed in. + /// + func testUpsertStoredSiteSettingsEffectivelyRemovesSiteSettings() { + let settingStore = SettingStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: [sampleSiteSetting(), sampleSiteSetting2()]) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 2) + settingStore.upsertStoredSiteSettings(siteID: sampleSiteID, readOnlySiteSettings: []) + XCTAssertEqual(viewStorage.countObjects(ofType: Storage.SiteSetting.self), 0) + } +} + + +// MARK: - Private Methods +// +private extension SettingStoreTests { + + // MARK: - SiteSetting Samples + + func sampleSiteSetting() -> Networking.SiteSetting { + return SiteSetting(siteID: sampleSiteID, + settingID: "woocommerce_currency", + label: "Currency", + description: "This controls what currency prices are listed at in the catalog and which currency gateways will take payments in.", + value: "USD") + } + + func sampleSiteSettingMutated() -> Networking.SiteSetting { + return SiteSetting(siteID: sampleSiteID, + settingID: "woocommerce_currency", + label: "Currency!", + description: "This controls what currency prices are listed!", + value: "GBP") + } + + func sampleSiteSetting2() -> Networking.SiteSetting { + return SiteSetting(siteID: sampleSiteID, + settingID: "woocommerce_price_thousand_sep", + label: "Thousand separator", + description: "This sets the thousand separator of displayed prices.", + value: ",") + } + + func sampleSiteSetting2Mutated() -> Networking.SiteSetting { + return SiteSetting(siteID: sampleSiteID, + settingID: "woocommerce_price_thousand_sep", + label: "Thousand separator!!", + description: "This sets the thousand separator!!", + value: "~") + } +}