'??',
'lookup_mode' => '??',
'cache' => false,
];
private $allowed_options = [
'api_key', 'auto_update', 'database', 'debug_log_enabled', 'download_ipv4_only', 'enable_region_redirect', 'enabled', 'first_redirect', 'first_redirect_cookie_lifetime', 'ignore_query_string', 'ip_whitelist', 'lookup_mode', 'noredirect_enabled', 'private_key', 'real_ip_header', 'rules', 'session_message', 'skip_admins', 'skip_bots', 'skip_ai_bots', 'token', 'trust_x_forwarded_for'
];
private $debug_log = '';
public function __construct()
{
// Set priority
$this->set_priority();
// Check for IP2Location BIN directory.
if (!file_exists(IP2LOCATION_DIR)) {
wp_mkdir_p(IP2LOCATION_DIR);
}
// Check for cache directory.
if (!file_exists(IP2LOCATION_DIR . 'caches')) {
wp_mkdir_p(IP2LOCATION_DIR . 'caches');
}
$this->debug_log = 'debug_' . md5($this->get_option('private_key') . get_site_url() . get_option('admin_email')) . '.log';
add_action('admin_menu', [$this, 'add_admin_menu']);
}
public function set_locale()
{
load_plugin_textdomain('ip2location_redirection', false, IPLR_ROOT . '/languages/');
}
public function add_admin_menu()
{
add_menu_page(__('Redirection', 'ip2location-redirection'), __('Redirection', 'ip2location-redirection'), 'manage_options', 'ip2location-redirection', [$this, 'rules_page'], 'dashicons-admin-ip2location', 31);
add_submenu_page('ip2location-redirection', __('Rules', 'ip2location-redirection'), __('Rules', 'ip2location-redirection'), 'manage_options', 'ip2location-redirection', [$this, 'rules_page']);
add_submenu_page('ip2location-redirection', __('IP Lookup', 'ip2location-redirection'), __('IP Lookup', 'ip2location-redirection'), 'manage_options', 'ip2location-redirection-ip-lookup', [$this, 'ip_lookup_page']);
add_submenu_page('ip2location-redirection', __('Settings', 'ip2location-redirection'), __('Settings', 'ip2location-redirection'), 'manage_options', 'ip2location-redirection-settings', [$this, 'settings_page']);
$this->cache_clear();
}
public function admin_init()
{
if ($this->post('action') === 'download_ip2location_redirection_backup') {
if (!current_user_can('administrator')) {
exit;
}
check_admin_referer('backup');
$results = $this->wpdb_get_results("SELECT option_name, option_value FROM {$GLOBALS['wpdb']->prefix}options WHERE option_name LIKE 'ip2location_redirection_%'");
if ($results) {
$options = [];
foreach ($results as $result) {
$options[$result->option_name] = $result->option_value;
}
ob_end_flush();
header('Content-type: application/json');
header('Content-Disposition: attachment; filename="ip2location_redirection.json"');
exit(json_encode($options));
}
}
}
public function restore()
{
header('Content-Type: application/json');
if (!current_user_can('administrator')) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Permission denied.', 'ip2location-redirection'),
]));
}
check_admin_referer('restore', '__nonce');
if (!isset($_FILES['restore_file']) || $_FILES['restore_file']['error'] !== UPLOAD_ERR_OK) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('File upload error.', 'ip2location-redirection')
]));
}
$rows = json_decode(file_get_contents($_FILES['restore_file']['tmp_name']));
if ($rows === null) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Invalid file format.', 'ip2location-redirection'),
]));
}
foreach ($rows as $key => $value) {
// Skip invalid options
if (!in_array(str_replace('ip2location_redirection_', '', $key), $this->allowed_options)) {
continue;
}
update_option($key, ((is_array($value)) ? $this->sanitize_array($value) : sanitize_text_field($value)));
}
$this->update_option('session_message', 'Restore completed.');
exit(json_encode([
'status' => 'OK',
]));
}
public function show_notice()
{
if ($this->is_setup_completed()) {
return;
}
echo '
' . sprintf(__('IP2Location Redirection requires the IP2Location BIN database to work. %1$sSetup your database%2$s now.', 'ip2location-redirection'), '', ' ') . '
';
}
public function plugin_enqueues($hook)
{
// Deactivation feedback modal on the Plugins screen (only those assets).
if ($hook == 'plugins.php') {
wp_enqueue_script('jquery-ui-dialog');
wp_enqueue_style('wp-jquery-ui-dialog');
wp_enqueue_style('iplr-styles', untrailingslashit(plugins_url('/', __FILE__)) . '/assets/css/styles.css');
wp_enqueue_script('iplr-feedback-js', plugins_url('/assets/js/feedback.js', __FILE__), ['jquery'], null, true);
return;
}
// Identify the page from the menu slug (the hook suffix is locale-dependent).
$page = $this->get('page');
$pages = [
'ip2location-redirection' => 'rules',
'ip2location-redirection-ip-lookup' => 'ip-lookup',
'ip2location-redirection-settings' => 'settings',
];
if (!isset($pages[$page])) {
return;
}
$page = $pages[$page];
// Shared stylesheet, scoped to the plugin's own pages only.
wp_enqueue_style('iplr-styles', untrailingslashit(plugins_url('/', __FILE__)) . '/assets/css/styles.css');
switch ($page) {
case 'rules':
wp_enqueue_script('iplr-rules-js', plugins_url('/assets/js/rules.js?t=' . microtime(true), __FILE__), ['jquery'], null, true);
wp_enqueue_script('iplr-chosen-js', plugins_url('/assets/js/chosen.jquery.min.js', __FILE__), ['jquery'], null, true);
wp_enqueue_script('iplr-tagsinput-js', plugins_url('/assets/js/jquery.tagsinput.min.js', __FILE__), ['jquery'], null, true);
wp_enqueue_script('iplr-jquery-ui', plugins_url('/assets/js/jquery-ui.min.js', __FILE__), ['jquery'], null, true);
wp_enqueue_style('iplr-chosen-css', plugins_url('/assets/css/chosen.min.css', __FILE__), [], null);
wp_enqueue_style('iplr-tagsinput-css', plugins_url('/assets/css/jquery.tagsinput.min.css', __FILE__), [], null);
wp_enqueue_style('iplr-custom-styles', untrailingslashit(plugins_url('/', __FILE__)) . '/assets/css/customs.css');
break;
case 'ip-lookup':
break;
case 'settings':
wp_enqueue_script('jquery-form');
wp_enqueue_script('iplr-jquery-upload-file-js', plugins_url('/assets/js/jquery.uploadfile.min.js', __FILE__), ['jquery', 'jquery-form'], null, true);
wp_enqueue_style('iplr-jquery-upload-file-css', plugins_url('/assets/css/uploadfile.min.css', __FILE__), [], null);
wp_enqueue_script('iplr_admin_script_js', plugins_url('/assets/js/settings.js', __FILE__), ['jquery', 'iplr-jquery-upload-file-js'], null, true);
break;
}
}
public function set_default_values()
{
// Initial default settings
add_option('ip2location_redirection_api_key', '');
add_option('ip2location_redirection_database', '');
add_option('ip2location_redirection_debug_log_enabled', '0');
add_option('ip2location_redirection_download_ipv4_only', '0');
add_option('ip2location_redirection_enable_region_redirect', '0');
add_option('ip2location_redirection_enabled', '1');
add_option('ip2location_redirection_first_redirect', '0');
add_option('ip2location_redirection_ignore_query_string', '1');
add_option('ip2location_redirection_first_redirect_cookie_lifetime', '1 day');
add_option('ip2location_redirection_ip_whitelist', '');
add_option('ip2location_redirection_lookup_mode', 'bin');
add_option('ip2location_redirection_noredirect_enabled', '0');
add_option('ip2location_redirection_private_key', '');
add_option('ip2location_redirection_real_ip_header', '');
add_option('ip2location_redirection_trust_x_forwarded_for', '0');
add_option('ip2location_redirection_rules', '[]');
add_option('ip2location_redirection_session_message', '');
add_option('ip2location_redirection_skip_admins', '1');
add_option('ip2location_redirection_skip_bots', '0');
add_option('ip2location_redirection_skip_ai_bots', '0');
add_option('ip2location_redirection_token', '');
// Create scheduled task.
$this->schedule_events();
}
public function update_ip2location_database()
{
check_admin_referer('update_database', '__nonce');
@set_time_limit(300);
header('Content-Type: application/json');
if (!current_user_can('administrator')) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Permission denied.', 'ip2location-redirection'),
]));
}
try {
$token = $this->post('token');
$enable_region = $this->is_checked('enable_region');
$ipv4_only = $this->post('ipv4_only') === 'true';
$this->perform_database_update($token, $enable_region, $ipv4_only);
exit(json_encode([
'status' => 'OK',
'message' => '',
]));
} catch (Exception $e) {
exit(json_encode([
'status' => 'ERROR',
'message' => $e->getMessage(),
]));
}
}
private function perform_database_update($token, $enable_region, $ipv4_only)
{
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
global $wp_filesystem;
$ipv6 = ($ipv4_only) ? '' : 'IPV6';
if ($enable_region) {
$code = 'DB3BIN' . $ipv6;
} else {
$code = 'DB1BIN' . $ipv6;
}
$working_dir = IP2LOCATION_DIR . 'working' . \DIRECTORY_SEPARATOR;
$zip_file = $working_dir . 'database.zip';
// Remove existing working directory
$wp_filesystem->delete($working_dir, true);
// Create working directory
$wp_filesystem->mkdir($working_dir);
if (!class_exists('WP_Http')) {
include_once ABSPATH . WPINC . '/class-http.php';
}
$request = new WP_Http();
// Check download permission
$response = $request->request('https://www.ip2location.com/download-info?' . http_build_query([
'package' => $code,
'token' => $token,
'source' => 'wp_redirection',
]));
$parts = explode(';', $response['body']);
if ($parts[0] != 'OK') {
// Download LITE version
if ($enable_region) {
$code = 'DB3LITEBIN' . $ipv6;
} else {
$code = 'DB1LITEBIN' . $ipv6;
}
$response = $request->request('https://www.ip2location.com/download-info?' . http_build_query([
'package' => $code,
'token' => $token,
'source' => 'wp_redirection',
]));
$parts = explode(';', $response['body']);
if ($parts[0] != 'OK') {
throw new Exception(__('You do not have permission to download this database.', 'ip2location-redirection'));
}
}
// Start downloading BIN database from IP2Location website
$response = $request->request('https://www.ip2location.com/download?' . http_build_query([
'file' => $code,
'token' => $token,
'source' => 'wp_redirection',
]), [
'timeout' => 300,
'follow_redirects' => true,
]);
if ((isset($response->errors)) || (!in_array('200', $response['response']))) {
$wp_filesystem->delete($working_dir, true);
throw new Exception(__('Connection timed out while downloading database.', 'ip2location-redirection'));
}
// Save downloaded package.
$fp = fopen($zip_file, 'w');
if (!$fp) {
throw new Exception(__('No permission to write into file system.', 'ip2location-redirection'));
}
fwrite($fp, $response['body']);
fclose($fp);
if (filesize($zip_file) < 51200) {
$message = file_get_contents($zip_file);
$wp_filesystem->delete($working_dir, true);
throw new Exception(__('Downloaded database is corrupted. Please try again later.', 'ip2location-redirection'));
}
// Unzip the package to working directory
$result = unzip_file($zip_file, $working_dir);
// Once extracted, delete the package.
unlink($zip_file);
if (is_wp_error($result)) {
$wp_filesystem->delete($working_dir, true);
throw new Exception(__('There is problem when decompress the database.', 'ip2location-redirection'));
}
// File the BIN database
$bin_database = '';
$files = scandir($working_dir);
foreach ($files as $file) {
if (strtoupper(substr($file, -4)) == '.BIN') {
$bin_database = $file;
break;
}
}
// Move file to IP2Location directory
$wp_filesystem->move($working_dir . $bin_database, IP2LOCATION_DIR . $bin_database, true);
$this->update_option('lookup_mode', 'bin');
$this->update_option('database', $bin_database);
$this->update_option('token', $token);
$this->update_option('download_ipv4_only', ($ipv4_only) ? 1 : 0);
$this->update_option('enable_region_redirect', ($enable_region) ? 1 : 0);
// Remove working directory
$wp_filesystem->delete($working_dir, true);
// Flush caches
$this->cache_flush();
}
public function validate_token()
{
check_admin_referer('validate_token', '__nonce');
header('Content-Type: application/json');
try {
$token = $this->post('token');
// Check download permission
$response = wp_remote_get('https://www.ip2location.com/download-info?' . http_build_query([
'package' => 'DB1BIN',
'token' => $token,
'source' => 'wp_redirection',
]));
if (is_wp_error($response)) {
exit(json_encode([
'status' => 'ERROR',
'message' => $response->get_error_message(),
]));
}
$parts = explode(';', $response['body']);
if ($parts[0] != 'OK') {
$response = wp_remote_get('https://www.ip2location.com/download-info?' . http_build_query([
'package' => 'DB1LITEBIN',
'token' => $token,
'source' => 'wp_redirection',
]));
$parts = explode(';', $response['body']);
if ($parts[0] != 'OK') {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Invalid download token.', 'ip2location-redirection'),
]));
}
}
$this->update_option('token', $token);
exit(json_encode([
'status' => 'OK',
'message' => '',
]));
} catch (Exception $e) {
exit(json_encode([
'status' => 'ERROR',
'message' => $e->getMessage(),
]));
}
}
public function validate_api_key()
{
header('Content-Type: application/json');
check_admin_referer('validate_api_key', '__nonce');
if (!current_user_can('administrator')) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Permission denied.', 'ip2location-redirection'),
]));
}
try {
$apiKey = $this->post('key');
if (empty($apiKey)) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Invalid API key.', 'ip2location-redirection'),
]));
}
// Check download permission
$response = wp_remote_get('https://api.ip2location.io/?' . http_build_query([
'key' => $apiKey,
'source' => 'wp_redirection',
]));
if (is_wp_error($response)) {
exit(json_encode([
'status' => 'ERROR',
'message' => $response->get_error_message(),
]));
}
if (!isset($response['response']['code'])) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Remote server is not responding. Please try again later.', 'ip2location-redirection'),
]));
}
if ($response['response']['code'] != 200) {
exit(json_encode([
'status' => 'ERROR',
'message' => __('Invalid API key.', 'ip2location-redirection'),
]));
}
$this->update_option('lookup_mode', 'ws');
$this->update_option('api_key', $apiKey);
exit(json_encode([
'status' => 'OK',
'message' => '',
]));
} catch (Exception $e) {
exit(json_encode([
'status' => 'ERROR',
'message' => $e->getMessage(),
]));
}
}
public function search_post()
{
check_admin_referer('search_post', '__nonce');
header('Content-Type: application/json');
$keyword = $this->post('search');
$results = [];
if (mb_strlen($keyword) < 3) {
$results[] = [
'id' => '',
'name' => 'No result',
];
exit(json_encode($results));
}
$rows = $this->wpdb_get_results("SELECT `ID`, `post_type`, `post_title` FROM `{$GLOBALS['wpdb']->prefix}posts` WHERE `post_title` LIKE %s AND `post_status` = 'publish' AND `post_type` IN ('post', 'page', 'product') LIMIT 25", [
'%' . $keyword . '%'
]);
if (count($rows) > 0) {
foreach ($rows as $row) {
$results[] = [
'id' => (($row->post_type == 'page') ? 'page-' : 'post-') . $row->ID,
'name' => (($row->post_type == 'page') ? 'Page' : 'Post') . ' → ' . $row->post_title,
];
}
} else {
$results[] = [
'id' => '',
'name' => 'No result',
];
}
exit(json_encode($results));
}
public function submit_feedback()
{
if (!current_user_can('deactivate_plugins')) {
exit;
}
check_admin_referer('submit_feedback', '__nonce');
$feedback = $this->post('feedback');
$others = $this->post('others');
$options = [
1 => __('I no longer need the plugin', 'ip2location-redirection'),
2 => __('I couldn\'t get the plugin to work', 'ip2location-redirection'),
3 => __('The plugin doesn\'t meet my requirements', 'ip2location-redirection'),
4 => __('Other concerns', 'ip2location-redirection') . (($others) ? (' - ' . $others) : ''),
4];
if (isset($options[$feedback])) {
wp_remote_get('https://www.ip2location.com/wp-plugin-feedback?' . http_build_query([
'name' => 'ip2location-redirection',
'message' => $options[$feedback],
]), ['timeout' => 5]);
}
}
public function rules_page()
{
$general_status = '';
$cache_warning = '';
$rules = [];
$wpml_settings = get_option('icl_sitepress_settings');
if (($name = $this->cache_plugin_detected()) !== false) {
$cache_warning = '
It appears that you are currently using ' . $name . ' , which is not fully compatible with the IP2Location Redirection. This may lead to unintended issues. We recommend disabling and uninstalling the cache plugin.
';
}
$enable_redirection = $this->is_checked('enable_redirection', $this->get_option('enabled'));
$first_redirect = $this->is_checked('first_redirect', $this->get_option('first_redirect'));
$enable_noredirect = $this->is_checked('enable_noredirect', $this->get_option('noredirect_enabled'));
$ignore_query_string = $this->is_checked('ignore_query_string', $this->get_option('ignore_query_string'));
$skip_bots = $this->is_checked('skip_bots', $this->get_option('skip_bots'));
$skip_ai_bots = $this->is_checked('skip_ai_bots', $this->get_option('skip_ai_bots'));
$skip_admins = $this->is_checked('skip_admins', $this->get_option('skip_admins'));
$ip_whitelist = $this->post('ip_whitelist', $this->get_option('ip_whitelist'));
$cookie_lifetime = $this->post('first_redirect_cookie_lifetime', $this->get_option('first_redirect_cookie_lifetime'));
$cookie_lifetime_options = [
'1 day' => __('1 day', 'ip2location-redirection'),
'1 week' => __('1 week', 'ip2location-redirection'),
'1 month' => __('1 month', 'ip2location-redirection'),
'1 year' => __('1 year', 'ip2location-redirection'),
];
if (!isset($cookie_lifetime_options[$cookie_lifetime])) {
$cookie_lifetime = '1 day';
}
$cookie_lifetime_select = '';
foreach ($cookie_lifetime_options as $value => $label) {
$cookie_lifetime_select .= '' . esc_html($label) . ' ';
}
$cookie_lifetime_select .= ' ';
if ($this->post('submit')) {
check_admin_referer('save_rules');
if (is_array($this->post('country_codes'))) {
$index = 0;
foreach ($this->post('country_codes') as $country_codes) {
$country_codes = explode(',', $country_codes);
$rule_status = $this->post('rule_status')[$index] ?? '';
$status_code = $this->post('status_code')[$index] ?? '';
$wpml_code = $this->post('wpml_code')[$index] ?? '';
$from = $this->post('from')[$index] ?? '';
$to = $this->post('to')[$index] ?? '';
$post_from = $this->post('post_from')[$index] ?? '';
$post_to = $this->post('post_to')[$index] ?? '';
$url_from = $this->post('url_from')[$index] ?? '';
$url_to = $this->post('url_to')[$index] ?? '';
$path_mode = $this->post('path_mode')[$index] ?? '';
$path_keyword = $this->post('path_keyword')[$index] ?? '';
$new_parameter = $this->post('new_parameter')[$index] ?? '';
$domain_from = $this->post('domain_from')[$index] ?? '';
$domain_to = $this->post('domain_to')[$index] ?? '';
$keep_query = $this->post('keep_query')[$index] ?? '';
$dialog_message = $this->post('dialog_message')[$index] ?? '';
$total_hits = $this->post('total_hits')[$index] ?? 0;
$last_access = $this->post('last_access')[$index] ?? '';
// Domain redirection must redirect from domain to domain
if (($from == 'domain' && $to != 'domain') || ($to == 'domain' && $from != 'domain')) {
++$index;
continue;
}
// Destination cannot be empty
if (empty($to)) {
++$index;
continue;
}
if ($from != 'url') {
$url_from = '';
}
if ($to != 'url') {
$url_to = '';
}
if ($from != 'domain' || $to != 'domain') {
$domain_from = '';
$domain_to = '';
}
if ($from != 'post') {
$post_from = '';
}
if ($to != 'post') {
$post_to = '';
}
// Validate domain name
if ($from == 'domain' && !preg_match('/^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,20}$/', $domain_from)) {
$general_status .= '
' . sprintf(__('%1$s is not a domain name.', 'ip2location-redirection'), '' . esc_html($domain_from) . ' ') . '
';
break;
}
if ($to == 'domain' && !preg_match('/^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,20}$/', $domain_to)) {
$general_status .= '
' . sprintf(__('%1$s is not a domain name.', 'ip2location-redirection'), '' . esc_html($domain_to) . ' ') . '
';
break;
}
// Both URL from and to cannot be same.
if ($from == 'url' && $to == 'url' && $url_from == $url_to) {
$general_status .= '
' . __('Target URL and destination URL cannot be same.', 'ip2location-redirection') . '
';
break;
}
// Both domain from and to cannot be same.
if ($from == 'domain' && $to == 'domain' && $domain_from == $domain_to) {
$general_status .= '
' . sprintf(__('Target domain and destination domain %1$s cannot be same.', 'ip2location-redirection'), '' . esc_html($domain_from) . ' ') . '
';
break;
}
if ($from == 'url' && !filter_var($url_from, \FILTER_VALIDATE_URL)) {
$general_status .= '
' . sprintf(__('%1$s is not a valid URL.', 'ip2location-redirection'), '' . esc_html($this->post('url_form')[$index]) . ' ') . '
';
break;
}
if ($to == 'url' && !filter_var($url_to, \FILTER_VALIDATE_URL)) {
$general_status .= '
' . sprintf(__('%1$s is not a valid URL.', 'ip2location-redirection'), '' . esc_html($url_to) . ' ') . '
';
break;
}
// Both post/page from and to cannot be same.
if ($from == 'post' && $to == 'post' && $post_from == $post_to) {
$general_status .= '
' . __('Target post and destination post cannot be same.', 'ip2location-redirection') . '
';
break;
}
$idx = 0;
foreach ($country_codes as $country_code) {
if ($this->post('exclude')[$index]) {
$country_codes[$idx] = (substr($country_code, 0, 1) == '-') ? $country_code : ('-' . $country_code);
} else {
$country_codes[$idx] = (substr($country_code, 0, 1) == '-') ? substr($country_code, 1) : $country_code;
}
++$idx;
}
if ($from == 'domain') {
$url_from = $domain_from;
$url_to = $domain_to;
if ($keep_query) {
$url_from = '*' . $url_from;
}
}
$dialog_message = ($status_code != 'dialog') ? '' : $dialog_message;
$rules[] = [
'is_active' => ($rule_status == '1'),
'country_codes' => $country_codes,
'page_from' => ($from == 'post') ? $post_from : $from,
'page_to' => ($to == 'post') ? $post_to : $to,
'url_from' => $url_from,
'url_to' => $url_to,
'path_mode' => $path_mode,
'path_keyword' => $path_keyword,
'new_parameter' => $new_parameter,
'language_code' => $wpml_code,
'http_code' => $status_code,
'dialog_message' => $dialog_message,
'total_hits' => $total_hits,
'last_access' => $last_access,
];
++$index;
}
}
if ($ip_whitelist) {
$ip_whitelist = $this->sanitize_list($ip_whitelist);
}
if (empty($general_status)) {
$this->update_option('enabled', $enable_redirection);
$this->update_option('first_redirect', $first_redirect);
$this->update_option('rules', json_encode($rules));
$this->update_option('first_redirect_cookie_lifetime', $cookie_lifetime);
$this->update_option('noredirect_enabled', $enable_noredirect);
$this->update_option('ignore_query_string', $ignore_query_string);
$this->update_option('skip_bots', $skip_bots);
$this->update_option('skip_ai_bots', $skip_ai_bots);
$this->update_option('skip_admins', $skip_admins);
$this->update_option('ip_whitelist', $ip_whitelist);
$general_status = '
' . __('Changes saved.', 'ip2location-redirection') . '
';
}
}
echo '
' . __('Rules', 'ip2location-redirection') . '
' . $cache_warning . '
' . $general_status . '
';
if (($records = json_decode($this->get_option('rules'))) !== null) {
if (!isset($records[0]->is_active)) {
$list = [];
foreach ($records as $values) {
if (count($values) == 5) {
$list[] = [
'is_active' => true,
'country_codes' => explode(';', $values[0]),
'page_from' => $values[1],
'page_to' => $values[2],
'url_from' => '',
'url_to' => $values[3],
'new_parameter' => '',
'language_code' => '',
'http_code' => $values[4],
];
} elseif (count($values) == 7) {
$list[] = [
'is_active' => (bool) $values[6],
'country_codes' => explode(';', $values[0]),
'page_from' => $values[1],
'page_to' => $values[2],
'url_from' => $values[3],
'url_to' => $values[4],
'new_parameter' => '',
'language_code' => '',
'http_code' => $values[5],
];
} elseif (count($values) == 8) {
$list[] = [
'is_active' => (bool) $values[7],
'country_codes' => explode(';', $values[0]),
'page_from' => $values[1],
'page_to' => $values[2],
'url_from' => $values[3],
'url_to' => $values[4],
'new_parameter' => '',
'language_code' => $values[5],
'http_code' => $values[6],
];
} else {
$list[] = [
'is_active' => (bool) $values[8],
'country_codes' => explode(';', $values[0]),
'page_from' => $values[1],
'page_to' => $values[2],
'url_from' => $values[3],
'url_to' => $values[4],
'new_parameter' => $values[5],
'language_code' => $values[6],
'http_code' => $values[7],
];
}
}
$this->update_option('rules', json_encode($list));
}
}
$rules = json_decode((string) $this->get_option('rules'));
if ($rules) {
for ($i = 0; $i < count($rules); ++$i) {
if (substr($rules[$i]->page_from, 0, 4) == 'page') {
$rules[$i]->page_from .= ';Page → ' . $this->get_post_title(substr($rules[$i]->page_from, 5));
}
if (substr($rules[$i]->page_from, 0, 4) == 'post') {
$rules[$i]->page_from .= ';Post → ' . $this->get_post_title(substr($rules[$i]->page_from, 5));
}
if (substr($rules[$i]->page_to, 0, 4) == 'page') {
$rules[$i]->page_to .= ';Page → ' . $this->get_post_title(substr($rules[$i]->page_to, 5));
}
if (substr($rules[$i]->page_to, 0, 4) == 'post') {
$rules[$i]->page_to .= ';Post → ' . $this->get_post_title(substr($rules[$i]->page_to, 5));
}
if (!isset($rules[$i]->total_hits)) {
$rules[$i]->total_hits = 0;
}
if (!isset($rules[$i]->last_access)) {
$rules[$i]->last_access = null;
}
}
}
$scripts = [];
$scripts[] = '';
$scripts[] = '';
echo implode("\n", $scripts);
if (!$this->is_setup_completed()) {
echo '
' . sprintf(__('%1$sIP2Location Redirection%2$s is a plugin designed to redirect visitors or traffic based on their geolocation determined by their IP address.', 'ip2location-redirection'), '', ' ') . '
' . __('Please follow these steps to complete the setup.', 'ip2location-redirection') . '
';
if (!extension_loaded('bcmath')) {
echo '
' . sprintf(__('IP2Location requires %1$s PHP extension enabled. Please enable this extension in your %2$s.', 'ip2location-redirection'), '
bcmath ', '
php.ini ') . '
' . __('Get Started', 'ip2location-redirection') . '
';
} else {
echo '
' . __('Get Started', 'ip2location-redirection') . '
';
}
echo '
' . __('Next', 'ip2location-redirection') . ' »
« ' . __('Previous', 'ip2location-redirection') . '
' . __('Next', 'ip2location-redirection') . ' »
« ' . __('Previous', 'ip2location-redirection') . '
' . __('Next', 'ip2location-redirection') . ' »
' . __('Finish', 'ip2location-redirection') . '
' . __('Set Up IP2Location.io IP Geolocation Service', 'ip2location-redirection') . '
' . __('Step 1', 'ip2location-redirection') . '
' . __('Step 2', 'ip2location-redirection') . '
« ' . __('Previous', 'ip2location-redirection') . '
' . __('Next', 'ip2location-redirection') . ' »
' . __('Configure The Rules', 'ip2location-redirection') . '
' . __('Step 1', 'ip2location-redirection') . '
' . __('Step 2', 'ip2location-redirection') . '
' . __('Finish', 'ip2location-redirection') . '
';
}
}
public function ip_lookup_page()
{
$disabled = (!$this->is_setup_completed());
$ip_lookup_status = '';
$ip_address = $this->post('ip_address', $this->ip());
if ($this->post('submit')) {
if (!filter_var($ip_address, \FILTER_VALIDATE_IP, \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE)) {
$ip_lookup_status = '
' . __('ERROR', 'ip2location-redirection') . ' :
' . __('Please enter a valid IP address.', 'ip2location-redirection') . '
';
} else {
$result = $this->get_location($ip_address);
if (empty($result['country_code'])) {
$ip_lookup_status = '
' . __('ERROR', 'ip2location-redirection') . ' :
' . sprintf(__('Unable to lookup IP address %1$s.', 'ip2location-redirection'), '' . esc_html($ip_address) . ' ') . '
';
} else {
$ip_lookup_status = '
' . sprintf(__('IP address %1$s belongs to %2$s.', 'ip2location-redirection'), '' . esc_html($ip_address) . '', '' . $result['country_name'] . ' (' . $result['country_code'] . ')' . (($result['region_name']) ? (', ' . $result['region_name']) : '') . ' ') . '
';
}
}
}
echo '
' . __('IP Lookup', 'ip2location-redirection') . '
' . $ip_lookup_status . '
';
}
public function settings_page()
{
$disabled = (!$this->is_setup_completed());
$settings_status = '';
$real_ip_headers = [
'REMOTE_ADDR',
'HTTP_CF_CONNECTING_IP',
'HTTP_CLIENT_IP',
'HTTP_FORWARDED',
'HTTP_INCAP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'HTTP_X_SUCURI_CLIENTIP',
];
$lookup_mode = $this->post('lookup_mode', $this->get_option('lookup_mode'));
$api_key = $this->post('api_key', $this->get_option('api_key'));
$download_token = $this->post('download_token', $this->get_option('token'));
$enable_region_redirection = $this->is_checked('enable_region_redirection', $this->get_option('enable_region_redirect'));
$download_ipv4_only = $this->is_checked('download_ipv4_only', $this->get_option('download_ipv4_only'));
$enable_debug_log = $this->is_checked('enable_debug_log', $this->get_option('debug_log_enabled'));
$real_ip_header = $this->post('real_ip_header', $this->get_option('real_ip_header'));
$trust_x_forwarded_for = $this->is_checked('trust_x_forwarded_for', $this->get_option('trust_x_forwarded_for'));
$enable_auto_update = $this->is_checked('enable_auto_update', $this->get_option('auto_update'));
if (!in_array($real_ip_header, array_values($real_ip_headers))) {
$real_ip_header = '';
}
if (!$this->is_region_supported()) {
$enable_region_redirection = 0;
}
if ($this->post('cache_nonce')) {
check_admin_referer('cache', 'cache_nonce');
$this->cache_flush();
$settings_status = '
' . __('All cache has been flushed.', 'ip2location-redirection') . '
';
}
if ($this->post('submit')) {
check_admin_referer('save_settings');
if ($lookup_mode == 'ws') {
if (!empty($api_key)) {
$response = wp_remote_get('https://api.ip2location.io/?' . http_build_query([
'key' => $api_key,
'check' => 1,
'source' => 'wordpress-wzdir',
]), ['timeout' => 3]);
$json = json_decode($response['body']);
if (isset($json->error)) {
$response = wp_remote_get('https://api.ip2location.com/v2/?' . http_build_query([
'key' => $api_key,
'check' => 1,
]));
$json = json_decode($response['body']);
if (empty($json)) {
$settings_status = '
' . __('ERROR', 'ip2location-redirection') . ' :
' . __('Error when accessing IP2Location web service gateway.', 'ip2location-redirection') . '
';
} else {
if (!preg_match('/^[0-9]+$/', $json->response)) {
$settings_status = '
' . __('ERROR', 'ip2location-redirection') . ' :
' . __('Invalid IP2Location API key.', 'ip2location-redirection') . '
';
} else {
$this->update_option('api_key', $api_key);
}
}
} else {
if (!preg_match('/^[0-9]+$/', $json->response)) {
$settings_status = '
' . __('ERROR', 'ip2location-redirection') . ' :
' . __('Invalid IP2Location API key.', 'ip2location-redirection') . '
';
} else {
$this->update_option('api_key', $api_key);
}
}
} else {
$this->update_option('api_key', '');
}
}
if (empty($settings_status)) {
if (!$enable_debug_log) {
if (file_exists(IP2LOCATION_DIR . $this->debug_log)) {
@unlink(IP2LOCATION_DIR . $this->debug_log);
}
} else {
if (!$this->get_option('private_key')) {
add_option('ip2location_redirection_private_key', hash('sha256', microtime(true) . get_site_url() . get_option('admin_email')));
}
}
$this->update_option('lookup_mode', $lookup_mode);
$this->update_option('enable_region_redirect', $enable_region_redirection);
$this->update_option('token', $download_token);
$this->update_option('debug_log_enabled', $enable_debug_log);
$this->update_option('download_ipv4_only', $download_ipv4_only);
$this->update_option('real_ip_header', $real_ip_header);
$this->update_option('trust_x_forwarded_for', $trust_x_forwarded_for);
$this->update_option('auto_update', $enable_auto_update);
$settings_status .= '
' . __('Changes saved.', 'ip2location-redirection') . '
';
}
}
$date = $this->get_database_date();
echo '
' . __('Settings', 'ip2location-redirection') . '
' . $settings_status;
if ($this->get_option('session_message')) {
echo '
' . $this->get_option('session_message') . '
';
$this->update_option('session_message', '');
}
echo '
';
}
public function redirect()
{
// Disable redirection for WP-CLI
if (defined('WP_CLI') && WP_CLI) {
return;
}
// Disable redirection on admin pages
if (is_admin() && $this->get_option('skip_admins')) {
$this->write_debug_log('Redirection skipped for administrators.');
return;
}
// Disable redirection on administrator session
if (current_user_can('administrator') && $this->get_option('skip_admins')) {
$this->write_debug_log('Redirection skipped for administrators.');
return;
}
// Disable redirection on admin pages
if (substr($_SERVER['REQUEST_URI'], 0, 9) == '/wp-login' || substr($_SERVER['REQUEST_URI'], 0, 9) == '/wp-admin') {
return;
}
// Ignore static files
if (preg_match('/\.(7z|apk|avi|avif|bin|bmp|bz2|class|css|csv|dmg|doc|docx|ejs|eot|eps|exe|flac|gif|gz|ico|iso|jar|jpeg|jpg|js|mid|midi|mkv|mp3|mp4|ogg|otf|pdf|pict|pls|png|ppt|pptx|ps|rar|svg|svgz|swf|tar|tif|tiff|ttf|webm|webp|woff|woff2|xls|xlsx|zip|zst)$/i', $_SERVER['REQUEST_URI'])) {
return;
}
// Ignore internal XHR calls
if (preg_match('/wp-json|admin-ajax|wc-ajax|jm-ajax|doing_wp_cron/', $_SERVER['REQUEST_URI'])) {
return;
}
if (!$this->get_option('enabled')) {
$this->write_debug_log(__('Redirection disabled.', 'ip2location-redirection'));
return;
}
// Overwrite headers to prevent content being cached
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
if ($this->get_option('ip_whitelist')) {
$records = explode(';', $this->get_option('ip_whitelist'));
foreach ($records as $record) {
// CIDR notation
if (strpos($record, '/') !== false) {
if ($this->cidr_match($this->ip(), $record)) {
$this->write_debug_log('IP is in whitelist.');
return;
}
} else {
if ($this->ip() == $record) {
$this->write_debug_log('IP is in whitelist.');
return;
}
}
}
}
if ($this->get_option('skip_bots') && $this->is_bot()) {
$this->write_debug_log('Web crawler detected.');
return;
}
if ($this->get_option('skip_ai_bots') && $this->is_ai_bot()) {
$this->write_debug_log('AI crawler detected.');
return;
}
if ($this->get_option('noredirect_enabled')) {
if ($this->get('noredirect') === 'true') {
$this->write_debug_log('"noredirect" parameter is found.');
return;
}
}
if ($this->get_option('first_redirect')) {
if (isset($_COOKIE['ip2location_redirection_first_visit']) && strpos($_COOKIE['ip2location_redirection_first_visit'], ';') !== false) {
list($time, $hash) = explode(';', $_COOKIE['ip2location_redirection_first_visit']);
if (md5($time . 'a09f0749-6683-5ada-882c-eb3263a252d3') == $hash) {
$this->write_debug_log('Non-first visits.');
return;
}
}
}
$time = time();
$expires = strtotime($this->get_option('first_redirect_cookie_lifetime') ?: '1 day');
setcookie('ip2location_redirection_first_visit', $time . ';' . md5($time . 'a09f0749-6683-5ada-882c-eb3263a252d3'), $expires, '/', '', true, true);
if (($rules = json_decode($this->get_option('rules'))) !== null) {
$result = $this->get_location($this->ip());
if (empty($result['country_code'])) {
$this->write_debug_log('Cannot identify location.', 'ERROR');
return;
}
for ($i = 0; $i < count($rules); $i++) {
$is_active = (bool) $rules[$i]->is_active ?? false;
$country_codes = $rules[$i]->country_codes ?? [];
$page_from = $rules[$i]->page_from ?? '';
$page_to = $rules[$i]->page_to ?? '';
$url_from = $rules[$i]->url_from ?? '';
$url_to = $rules[$i]->url_to ?? '';
$path_mode = $rules[$i]->path_mode ?? 'exact';
$path_keyword = $rules[$i]->path_keyword ?? '';
$new_parameter = $rules[$i]->new_parameter ?? '';
$wpml_code = $rules[$i]->language_code ?? '';
$http_code = $rules[$i]->http_code ?? 302;
$dialog_message = $rules[$i]->dialog_message ?? '';
if (!$is_active) {
continue;
}
if ($this->is_country_match($result, $country_codes)) {
$this->write_debug_log('"' . $result['country_code'] . '" is listed in [' . implode(', ', $country_codes) . ']', 'MATCHED');
if ($page_from == 'path') {
$trigger = false;
$parts = parse_url($this->get_current_url());
$path = $parts['path'] ?? '';
switch ($path_mode) {
case 'exact':
if ($path == $path_keyword) {
$trigger = true;
$this->write_debug_log('Path "' . $path . '" matched "' . $path_keyword . '".', 'MATCHED');
}
break;
case 'contains':
if (strpos($path, $path_keyword) !== false) {
$trigger = true;
$this->write_debug_log('Path "' . $path . '" contains "' . $path_keyword . '".', 'MATCHED');
}
break;
case 'not_contains':
if (strpos($path, $path_keyword) === false) {
$trigger = true;
$this->write_debug_log('Path "' . $path . '" does not contain "' . $path_keyword . '".', 'MATCHED');
}
break;
case 'begin':
if (str_starts_with($path, $path_keyword)) {
$trigger = true;
$this->write_debug_log('Path "' . $path . '" starts with "' . $path_keyword . '".', 'MATCHED');
}
break;
case 'end':
if (str_ends_with($path, $path_keyword)) {
$trigger = true;
$this->write_debug_log('Path "' . $path . '" ends with "' . $path_keyword . '".', 'MATCHED');
}
break;
}
if ($trigger) {
if ($page_to == 'url') {
if ($_SERVER['QUERY_STRING']) {
parse_str($_SERVER['QUERY_STRING'], $query_string);
unset($query_string['page_id'], $query_string['p']);
$parts = parse_url($url_to);
$post_query = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $post_query);
}
$path = (isset($parts['path'])) ? $parts['path'] : '';
$queries = array_merge($query_string, $post_query);
unset($queries['p']);
$extra_queries = [];
if (!empty($new_parameter)) {
parse_str($new_parameter, $extra_queries);
}
$target_url = $this->build_url($parts['scheme'], $parts['host'], $path, array_merge($queries, $extra_queries));
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($url_to)) {
return;
}
$this->redirect_to($url_to, $http_code, $i, $dialog_message);
}
list($page_type, $page_id) = explode('-', $page_to);
// Prevent infinite redirect to same page
if ($page_id === $this->get_page_id() && !$wpml_code) {
return;
}
$target_url = $this->get_permalink($page_id);
if ($wpml_code) {
$translated_id = apply_filters('wpml_object_id', $page_id, get_post_type($page_id), true, $wpml_code);
if ($translated_id) {
$target_url = $this->get_permalink($translated_id);
$wpml_settings = get_option('icl_sitepress_settings');
if (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 1 && $wpml_code !== ($wpml_settings['default_language'] ?? '')) {
if (strpos($target_url, '://') === false) {
$target_url = '/' . $wpml_code . $target_url;
} else {
$parts = parse_url($target_url);
$parts['path'] = '/' . $wpml_code . ($parts['path'] ?? '/');
$target_url = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], []);
}
} elseif (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 3) {
$target_url .= ((strpos($target_url, '?') === false) ? '?' : '&') . 'lang=' . $wpml_code;
}
}
}
// Normalize to full URL
if (strpos($target_url, '://') === false && $this->http_host()) {
$parts = parse_url($this->get_current_url());
$target_url = $this->build_url($parts['scheme'], $parts['host'], $target_url, []);
}
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
}
if ($page_from == 'domain') {
// Keep query string
if (substr($url_from, 0, 1) == '*') {
if (substr($url_from, 1) == $this->http_host()) {
$this->write_debug_log('Domain "' . $url_from . '" matched "' . $this->http_host() . '".', 'MATCHED');
$target_url = str_replace(substr($url_from, 1), $url_to . ((!empty($new_parameter) ? (((strpos($url_to, '?') === false) ? '?' : '&') . $new_parameter) : '')), $this->get_current_url());
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
} else {
$this->write_debug_log('Domain "' . $url_from . '" not match "' . $this->http_host() . '".');
}
} else {
if ($url_from == $this->http_host()) {
$this->write_debug_log('Domain "' . $url_from . '" matched "' . $this->http_host() . '".', 'MATCHED');
$target_url = str_replace($url_from, $url_to . ((!empty($new_parameter) ? ('?' . $new_parameter) : '')), $this->get_current_url(false));
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
} else {
$this->write_debug_log('Domain "' . $url_from . '" not match "' . $this->http_host() . '".');
}
}
}
if ($this->get_option('ignore_query_string') && strpos($this->get_current_url(), '?') !== false) {
// Remove query string
$current_url = trim(substr($this->get_current_url(), 0, strpos($this->get_current_url(), '?')), '/');
} else {
$current_url = trim($this->get_current_url(), '/');
}
if ($page_from == 'any' || ($page_from == 'home' && $this->is_home()) || ($page_from == 'url' && $current_url == trim($url_from, '/'))) {
if ($page_to == 'url') {
if ($_SERVER['QUERY_STRING']) {
parse_str($_SERVER['QUERY_STRING'], $query_string);
unset($query_string['page_id'], $query_string['p']);
$parts = parse_url($url_to);
$post_query = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $post_query);
}
$path = (isset($parts['path'])) ? $parts['path'] : '';
$queries = array_merge($query_string, $post_query);
unset($queries['p']);
$extra_queries = [];
if (!empty($new_parameter)) {
parse_str($new_parameter, $extra_queries);
}
$target_url = $this->build_url($parts['scheme'], $parts['host'], $path, array_merge($queries, $extra_queries));
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($url_to)) {
return;
}
$this->redirect_to($url_to, $http_code, $i, $dialog_message);
}
list($page_type, $page_id) = explode('-', $page_to);
// Prevent infinite redirect to same page
if ($page_id === $this->get_page_id() && !$wpml_code) {
return;
}
$target_url = $this->get_permalink($page_id);
if ($wpml_code) {
$translated_id = apply_filters('wpml_object_id', $page_id, get_post_type($page_id), true, $wpml_code);
if ($translated_id) {
$target_url = $this->get_permalink($translated_id);
$wpml_settings = get_option('icl_sitepress_settings');
if (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 1 && $wpml_code !== ($wpml_settings['default_language'] ?? '')) {
if (strpos($target_url, '://') === false) {
$target_url = '/' . $wpml_code . $target_url;
} else {
$parts = parse_url($target_url);
$parts['path'] = '/' . $wpml_code . ($parts['path'] ?? '/');
$target_url = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], []);
}
} elseif (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 3) {
$target_url .= ((strpos($target_url, '?') === false) ? '?' : '&') . 'lang=' . $wpml_code;
}
}
}
// Normalize to full URL
if (strpos($target_url, '://') === false && $this->http_host()) {
$parts = parse_url($this->get_current_url());
$target_url = $this->build_url($parts['scheme'], $parts['host'], $target_url, []);
}
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
if ($page_from == 'home') {
$page_id = get_option('page_on_front');
} else {
if (strpos($page_from, '-') === false) {
if ($page_from == 'url') {
$this->write_debug_log('URL "' . $this->get_current_url() . '" not match "' . $url_from . '".');
} else {
$this->write_debug_log('Invalid page "' . $page_from . '".');
}
continue;
}
list($page_type, $page_id) = explode('-', $page_from);
}
if ($page_id === $this->get_page_id()) {
if ($page_to == 'url') {
if ($_SERVER['QUERY_STRING']) {
parse_str($_SERVER['QUERY_STRING'], $query_string);
unset($query_string['page_id'], $query_string['p'], $query_string['add-to-cart']);
$parts = parse_url($url_to);
$post_query = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $post_query);
}
$queries = array_merge($post_query, $query_string);
unset($queries['p']);
$extra_queries = [];
if (!empty($new_parameter)) {
parse_str($new_parameter, $extra_queries);
}
$target_url = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], array_merge($queries, $extra_queries));
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($url_to)) {
return;
}
$this->redirect_to($url_to, $http_code, $i, $dialog_message);
}
list($page_type, $page_id) = explode('-', $page_to);
// Prevent infinite redirect to same page
if ($page_id === $this->get_page_id() && !$wpml_code) {
return;
}
if ($_SERVER['QUERY_STRING']) {
parse_str($_SERVER['QUERY_STRING'], $query_string);
unset($query_string['page_id'], $query_string['p'], $query_string['add-to-cart']);
$post_url = $this->get_permalink($page_id);
if ($wpml_code) {
$translated_id = apply_filters('wpml_object_id', $page_id, get_post_type($page_id), true, $wpml_code);
if ($translated_id) {
$post_url = $this->get_permalink($translated_id);
$wpml_settings = get_option('icl_sitepress_settings');
if (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 1 && $wpml_code !== ($wpml_settings['default_language'] ?? '')) {
if (strpos($post_url, '://') === false) {
$post_url = '/' . $wpml_code . $post_url;
} else {
$parts = parse_url($post_url);
$parts['path'] = '/' . $wpml_code . ($parts['path'] ?? '/');
$post_url = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], []);
}
} elseif (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 3) {
$post_url .= ((strpos($post_url, '?') === false) ? '?' : '&') . 'lang=' . $wpml_code;
}
}
}
$parts = parse_url($post_url);
$post_query = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $post_query);
}
$queries = array_merge($post_query, $query_string);
$extra_queries = [];
if (!empty($new_parameter)) {
parse_str($new_parameter, $extra_queries);
}
$target_url = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], array_merge($queries, $extra_queries));
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($target_url)) {
return;
}
$this->redirect_to($target_url, $http_code, $i, $dialog_message);
}
$link = $this->get_permalink($page_id);
if ($wpml_code) {
$translated_id = apply_filters('wpml_object_id', $page_id, get_post_type($page_id), true, $wpml_code);
if ($translated_id) {
$link = $this->get_permalink($translated_id);
$wpml_settings = get_option('icl_sitepress_settings');
if (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 1 && $wpml_code !== ($wpml_settings['default_language'] ?? '')) {
if (strpos($link, '://') === false) {
$link = '/' . $wpml_code . $link;
} else {
$parts = parse_url($link);
$parts['path'] = '/' . $wpml_code . ($parts['path'] ?? '/');
$link = $this->build_url($parts['scheme'], $parts['host'], $parts['path'], []);
}
} elseif (isset($wpml_settings['language_negotiation_type']) && $wpml_settings['language_negotiation_type'] == 3) {
$link .= ((strpos($link, '?') === false) ? '?' : '&') . 'lang=' . $wpml_code;
}
}
}
if (!empty($new_parameter)) {
$link .= ((strpos($link, '?') === false) ? '?' : '&') . $new_parameter;
}
// Normalize to full URL
if (strpos($link, '://') === false && $this->http_host()) {
$parts = parse_url($this->get_current_url());
$link = $this->build_url($parts['scheme'], $parts['host'], $link, []);
}
// Prevent infinite loop
if ($this->normalize_url($this->get_current_url()) === $this->normalize_url($link)) {
return;
}
$this->redirect_to($link, $http_code, $i, $dialog_message);
}
$this->write_debug_log('Page is not matched.');
} else {
$this->write_debug_log('"' . $result['country_code'] . '" is NOT listed in [' . implode(', ', $country_codes) . ']');
}
}
}
}
public function footer()
{
echo "\n";
}
public function write_debug_log($message, $action = 'ABORTED')
{
if (!$this->get_option('debug_log_enabled')) {
return;
}
error_log(json_encode([
'time' => gmdate('Y-m-d H:i:s'),
'client_ip' => $this->ip(),
'location' => $this->session['location'],
'lookup_by' => $this->session['lookup_mode'],
'cache' => $this->session['cache'],
'uri' => $this->get_current_url(),
'message' => $message,
'action' => $action,
]) . "\n", 3, IP2LOCATION_DIR . $this->debug_log);
}
public function admin_footer_text($footer_text)
{
global $pagenow;
$current_screen = get_current_screen();
if ($current_screen && strpos($current_screen->id, 'ip2location-redirection') !== false) {
$footer_text .= sprintf(
__('Enjoyed %1$s? Please leave us a %2$s rating. A huge thanks in advance!', 'ip2location-redirection'),
'' . __('IP2Location Redirection', 'ip2location-redirection') . ' ',
'★★★★★ '
);
}
if ($pagenow == 'plugins.php') {
return $footer_text . '
';
}
return $footer_text;
}
// Register the maintenance cron (in case it was lost).
public function schedule_events()
{
if (!wp_next_scheduled('ip2location_redirection_hourly_event')) {
wp_schedule_event(time(), 'hourly', 'ip2location_redirection_hourly_event');
}
if (!wp_next_scheduled('ip2location_redirection_daily_event')) {
wp_schedule_event(time(), 'daily', 'ip2location_redirection_daily_event');
}
}
// Fallback cleanup when WP-Cron never runs.
public function prune_cache()
{
if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
return;
}
if (get_transient('ip2location_redirection_cache_prune')) {
return;
}
set_transient('ip2location_redirection_cache_prune', 1, HOUR_IN_SECONDS);
$this->cache_clear(self::CACHE_TTL_HOURS, 2000);
}
public function hourly_event()
{
$this->cache_clear();
$this->set_priority();
}
public function daily_event()
{
// Do not run update if lookup mode is not bin
if ($this->get_option('lookup_mode') != 'bin') {
return;
}
// Do not run update if auto update is disabled
if (!$this->get_option('auto_update')) {
return;
}
$token = $this->get_option('token');
$enable_region = $this->get_option('enable_region_redirect');
$ipv4_only = $this->get_option('download_ipv4_only');
if (empty($token)) {
return;
}
// Do not perform updates if the database date is less than 29 days
if (strtotime((string) $this->get_database_date()) > strtotime('-29 days')) {
return;
}
try {
$this->perform_database_update($token, $enable_region, $ipv4_only);
$this->write_debug_log('IP2Location BIN Database updated via cron job.', 'SUCCESS');
} catch (Exception $e) {
$this->write_debug_log('IP2Location BIN Database update failed: ' . $e->getMessage(), 'ERROR');
}
}
private function normalize_url($url)
{
// Convert relative URLs to absolute for comparison
if (strpos($url, '://') === false) {
$parts = parse_url($this->get_current_url());
if ($parts === false || !isset($parts['scheme']) || !isset($parts['host'])) {
return $url;
}
$url = $parts['scheme'] . '://' . $parts['host'] . '/' . ltrim($url, '/');
}
$parsed = parse_url($url);
if ($parsed === false || !isset($parsed['host'])) {
return $url;
}
$scheme = $parsed['scheme'] ?? 'https';
$host = $parsed['host'];
$path = $parsed['path'] ?? '/';
return rtrim($scheme . '://' . $host . $path, '/');
}
private function wpdb_query($query, ...$args)
{
if (count(func_get_args()) > 1) {
return $GLOBALS['wpdb']->query($GLOBALS['wpdb']->prepare($query, ...$args));
}
return $GLOBALS['wpdb']->query($query);
}
private function wpdb_get_value($query, ...$args)
{
if (count(func_get_args()) > 1) {
return $GLOBALS['wpdb']->get_var($GLOBALS['wpdb']->prepare($query, ...$args));
}
return $GLOBALS['wpdb']->get_var($query);
}
private function wpdb_get_results($query, ...$args)
{
if (count(func_get_args()) > 1) {
return $GLOBALS['wpdb']->get_results($GLOBALS['wpdb']->prepare($query, ...$args));
}
return $GLOBALS['wpdb']->get_results($query);
}
private function post($key, $default = '', $checkbox = false)
{
return (isset($_POST[$key])) ? ((is_array($_POST[$key])) ? $this->sanitize_array($_POST[$key]) : sanitize_text_field($_POST[$key])) : $default;
}
private function get($key, $default = '', $checkbox = false)
{
return (isset($_GET[$key])) ? ((is_array($_GET[$key])) ? $this->sanitize_array($_GET[$key]) : sanitize_text_field($_GET[$key])) : $default;
}
private function is_checked($key, $default = 0)
{
return ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST[$key])) ? 0 : ((isset($_POST[$key])) ? 1 : (int) $default);
}
private function update_option($key, $value)
{
if (!in_array($key, $this->allowed_options)) {
return false;
}
return update_option('ip2location_redirection_' . $key, $value);
}
private function get_option($key)
{
return get_option('ip2location_redirection_' . $key);
}
private function cache_plugin_detected()
{
$plugins = [
'Breeze' => 'breeze/breeze.php',
'Cache Enabler' => 'cache-enabler/cache-enabler.php',
'LiteSpeed Cache' => 'litespeed-cache/litespeed-cache.php',
'Super Page Cache' => 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php',
'W3 Total Cache' => 'w3-total-cache/w3-total-cache.php',
'WP Fastest Cache' => 'wp-fastest-cache/wpFastestCache.php',
'WP Optimizer' => 'wp-optimize/wp-optimize.php',
'WP Rocket' => 'wp-rocket/wp-rocket.php',
'WP Super Cache' => 'wp-super-cache/wp-cache.php',
];
foreach ($plugins as $name => $path) {
if (is_plugin_active($path)) {
return $name;
}
}
return false;
}
private function set_priority()
{
global $pagenow;
// Do not do this in plugins page to prevent deactivation issues.
if ($pagenow != 'plugins.php') {
// Make sure this plugin loaded as first priority.
$this_plugin = plugin_basename(trim(preg_replace('/(.*)plugins\/(.*)$/', WP_PLUGIN_DIR . '/$2', __FILE__)));
$active_plugins = get_option('active_plugins');
if (!is_array($active_plugins)) {
return;
}
// Remove all existing occurrences first to avoid duplicate entries
$expected = array_values(array_diff($active_plugins, [$this_plugin]));
array_unshift($expected, $this_plugin);
if ($expected !== $active_plugins) {
update_option('active_plugins', $expected);
}
}
}
private function is_country_match($result, $codes)
{
$country_code = $result['country_code'];
$region_code = $result['region_code'];
if (is_array($codes)) {
// Check for "Any Country" option
if (in_array('ANY', $codes)) {
return true;
}
$index = 0;
foreach ($codes as $country) {
if ($country_code == $country) {
return true;
}
if (strpos($country, '.') !== false) {
if ($region_code == $country) {
return true;
}
}
if (strpos($country, '.') !== false) {
if (substr($country, 0, 1) == '-' && substr($country, 1) != $region_code) {
++$index;
}
} else {
if (substr($country, 0, 1) == '-' && substr($country, 1) != $country_code) {
++$index;
}
}
if ($index == count($codes)) {
return true;
}
}
return false;
}
if ($country_code == $codes) {
return true;
}
if (substr($codes, 0, 1) == '-' && substr($codes, 1) != $country_code) {
return true;
}
return false;
}
private function is_bot()
{
return preg_match('/baidu|bingbot|facebookexternalhit|googlebot|-google|ia_archiver|msnbot|naverbot|pingdom|seznambot|slurp|teoma|twitter|yandex|yeti|linkedinbot|pinterest/i', $this->user_agent());
}
private function is_ai_bot()
{
$ai_bots = [
'GPTBot', // OpenAI web crawler for training
'ChatGPT-User', // ChatGPT web browsing plugin
'OAI-SearchBot', // OpenAI Search
'anthropic-ai', // Anthropic (Claude)
'ClaudeBot', // Anthropic (Claude) general bot
'Claude-Web', // Anthropic (Claude) web bot
'Google-Extended', // Google's AI training crawler (Gemini)
'PerplexityBot', // Perplexity AI search
'cohere-ai', // Cohere AI
'omgili', // Webhose/Omgili (Often used for AI datasets)
'omgilibot', // Webhose/Omgili
'Diffbot', // Diffbot (Visual AI scraping)
'Bytespider', // ByteDance (TikTok/Douyin AI crawler)
'CCBot', // Common Crawl (Primary data source for many LLMs)
'Amazonbot', // Amazon's general crawler (often used for Alexa/AI)
'Applebot-Extended', // Apple's AI training bot
'meta-externalagent', // Meta (Facebook) AI crawler
'mistral-ai', // Mistral AI
'ImagesiftBot', // Image scraper often used for AI vision training
'PetalBot', // Petal Search (Huawei), sometimes used for AI
'Scrapy', // General Python scraper framework (often used for AI scraping)
'YouBot' // You.com AI search engine
];
return preg_match('/(' . implode('|', array_map('preg_quote', $ai_bots)) . ')/i', $this->user_agent());
}
private function user_agent()
{
return $_SERVER['HTTP_USER_AGENT'] ?? '';
}
private function ip()
{
// Trust forwarded headers only when explicitly enabled.
if ($this->get_option('trust_x_forwarded_for') !== '1') {
return $_SERVER['REMOTE_ADDR'];
}
if ($this->get_option('real_ip_header')) {
return $_SERVER[$this->get_option('real_ip_header')] ?? $_SERVER['REMOTE_ADDR'];
}
// Possible using CloudFlare service
if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)) {
// Make sure originated IP is coming from CloudFlare network
$networks = [
'173.245.48.0/20',
'103.21.244.0/22',
'103.22.200.0/22',
'103.31.4.0/22',
'141.101.64.0/18',
'108.162.192.0/18',
'190.93.240.0/20',
'188.114.96.0/20',
'197.234.240.0/22',
'198.41.128.0/17',
'162.158.0.0/15',
'104.16.0.0/13',
'104.24.0.0/14',
'172.64.0.0/13',
'131.0.72.0/22',
'2400:cb00::/32',
'2606:4700::/32',
'2803:f800::/32',
'2405:b500::/32',
'2405:8100::/32',
'2a06:98c0::/29',
'2c0f:f248::/32',
];
foreach ($networks as $network) {
if ($this->cidr_match($_SERVER['REMOTE_ADDR'], $network)) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
}
}
// Possible Securi Firewall
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
// Make sure originated IP is coming from Securi network
$networks = [
'192.88.134.0/23',
'185.93.228.0/22',
'66.248.200.0/22',
'208.109.0.0/22',
'2a02:fe80::/29',
];
foreach ($networks as $network) {
if ($this->cidr_match($_SERVER['REMOTE_ADDR'], $network)) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
}
}
// Possible local reverse proxy server
if (!filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
if (isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], \FILTER_VALIDATE_IP, \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE)) {
return $_SERVER['HTTP_X_REAL_IP'];
}
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// Get server IP address
$server_ip = (isset($_SERVER['SERVER_ADDR'])) ? $_SERVER['SERVER_ADDR'] : '';
$ip = trim(current(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])));
if (filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE) && $ip != $server_ip) {
return $ip;
}
}
}
return $_SERVER['REMOTE_ADDR'];
}
private function is_home()
{
if (isset($_SERVER['REQUEST_URI']) && preg_replace('/\?[^$]*/', '', $_SERVER['REQUEST_URI']) == '/') {
return true;
}
return is_home();
}
private function build_url($scheme, $host, $path, $queries)
{
if (!$host) {
return $path . (($queries) ? ('?' . http_build_query($queries)) : '');
}
return $scheme . '://' . $host . (($path) ?: '/') . (($queries) ? ('?' . http_build_query($queries)) : '');
}
private function get_current_url($add_query = true)
{
if (empty($this->http_host())) {
return '';
}
$current_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $this->http_host() . $_SERVER['REQUEST_URI'];
$parts = parse_url($current_url);
$queries = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $queries);
}
return $this->build_url($parts['scheme'], $parts['host'], (isset($parts['path'])) ? $parts['path'] : '', ($add_query) ? $queries : []);
}
private function redirect_to($url, $mode, $rule_index, $message = '')
{
if (preg_match('/page_id=([0-9]+)$/', $url, $matches)) {
$url = $this->get_permalink($matches[1]);
}
$url = preg_replace('/^\/+/', '/', $url);
switch ($mode) {
case 'dialog':
$escaped_message = esc_html($message);
$escaped_url = esc_url($url);
echo <<< HTML
Redirection
Redirection
{$escaped_message}
Go to Destination
HTML;
$this->write_debug_log('Destination: ' . $url, 'DIALOG DISPLAYED');
break;
case '301':
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $url, true, 301);
$this->write_debug_log('Destination: ' . $url, 'REDIRECTED');
break;
case '302':
header('HTTP/1.1 302 Found');
header('Location: ' . $url, true, 302);
$this->write_debug_log('Destination: ' . $url, 'REDIRECTED');
break;
}
$rules = json_decode($this->get_option('rules'));
$rules[$rule_index]->total_hits++;
$rules[$rule_index]->last_access = date('Y-m-d H:i:s');
$this->update_option('rules', json_encode($rules));
exit;
}
private function get_location($ip)
{
// Read result from cache to prevent duplicate lookup.
if ($data = $this->cache_get($ip)) {
$this->session['location'] = $data->country_code . (($data->region_code) ? (', ' . $data->region_code) : '');
$this->session['lookup_mode'] = 'Cache';
$this->session['cache'] = true;
return [
'country_code' => $data->country_code,
'country_name' => $data->country_name,
'region_code' => $data->region_code,
'region_name' => $data->region_name,
];
}
switch ($this->get_option('lookup_mode')) {
// IP2Location Web Service
case 'ws':
$this->session['lookup_mode'] = 'WS';
$response = wp_remote_get('https://api.ip2location.io/?' . http_build_query([
'key' => $this->get_option('api_key'),
'ip' => $ip,
'source' => 'wp-redirection',
]));
$json = json_decode($response['body']);
if (isset($json->error)) {
$response = wp_remote_get('https://api.ip2location.com/v2/?' . http_build_query([
'key' => $this->get_option('api_key'),
'ip' => $ip,
'package' => ($this->get_option('enable_region_redirect')) ? 'WS3' : 'WS1',
]));
$json = json_decode($response['body']);
if (empty($json)) {
$this->write_debug_log('Web service timed out.', 'ERROR');
return [
'country_code' => '',
'country_name' => '',
'region_code' => '',
'region_name' => '',
];
} elseif ($json->response != 'OK') {
$this->write_debug_log($json->response, 'ERROR');
return [
'country_code' => '',
'country_name' => '',
'region_code' => '',
'region_name' => '',
];
}
}
// Store result into cache for later use.
$caches = [
'country_code' => $json->country_code,
'country_name' => $this->get_country_name($json->country_code),
'region_code' => $this->get_region_code($json->country_code, $json->region_name),
'region_name' => $json->region_name,
];
$this->cache_add($ip, $caches);
$this->session['location'] = $caches['country_code'] . (($caches['region_code']) ? (', ' . $caches['region_code']) : '');
return [
'country_code' => $caches['country_code'],
'country_name' => $caches['country_name'],
'region_code' => $caches['region_code'],
'region_name' => $caches['region_name'],
];
// Local BIN database
default:
case 'bin':
$this->session['lookup_mode'] = 'BIN';
// Make sure IP2Location database is exist.
if (!is_file(IP2LOCATION_DIR . $this->get_option('database'))) {
$this->write_debug_log('Database not found.', 'ERROR');
return [
'country_code' => '',
'country_name' => '',
'region_code' => '',
'region_name' => '',
];
}
// Create IP2Location object.
$db = new \IP2Location\Database(IP2LOCATION_DIR . $this->get_option('database'), \IP2Location\Database::FILE_IO);
// Get geolocation by IP address.
$response = $db->lookup($ip, \IP2Location\Database::ALL);
if (!isset($response['countryCode'])) {
return [
'country_code' => '',
'country_name' => '',
'region_code' => '',
'region_name' => '',
];
}
// Store result into cache for later use.
$caches = [
'country_code' => $response['countryCode'],
'country_name' => $response['countryName'],
'region_code' => '',
'region_name' => '',
];
if (!preg_match('/unavailable/', $response['regionName'])) {
$caches['region_code'] = $this->get_region_code($response['countryCode'], $response['regionName']);
$caches['region_name'] = $response['regionName'];
}
$this->cache_add($ip, $caches);
$this->session['location'] = $caches['country_code'] . (($caches['region_code']) ? (', ' . $caches['region_code']) : '');
return [
'country_code' => $caches['country_code'],
'country_name' => $caches['country_name'],
'region_code' => $caches['region_code'],
'region_name' => $caches['region_name'],
];
}
}
private function get_country_name($code)
{
$countries = ['AF' => 'Afghanistan', 'AX' => 'Aland Islands', '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', 'BE' => 'Belgium', 'BZ' => 'Belize', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BT' => 'Bhutan', 'BO' => 'Bolivia (Plurinational State of)', 'BQ' => 'Bonaire, Sint Eustatius and Saba', 'BA' => 'Bosnia and Herzegovina', 'BW' => 'Botswana', 'BV' => 'Bouvet Island', 'BR' => 'Brazil', 'IO' => 'British Indian Ocean Territory', 'BN' => 'Brunei Darussalam', 'BG' => 'Bulgaria', 'BF' => 'Burkina Faso', 'BI' => 'Burundi', 'CV' => 'Cabo Verde', 'KH' => 'Cambodia', 'CM' => 'Cameroon', 'CA' => 'Canada', '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', 'CD' => 'Congo (Democratic Republic of the)', 'CK' => 'Cook Islands', 'CR' => 'Costa Rica', 'CI' => 'Cote D\'ivoire', 'HR' => 'Croatia', 'CU' => 'Cuba', 'CW' => 'Curacao', 'CY' => 'Cyprus', 'CZ' => 'Czechia', '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 (Malvinas)', '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', 'VA' => 'Holy See', 'HN' => 'Honduras', 'HK' => 'Hong Kong', 'HU' => 'Hungary', 'IS' => 'Iceland', 'IN' => 'India', 'ID' => 'Indonesia', 'IR' => 'Iran (Islamic Republic of)', 'IQ' => 'Iraq', 'IE' => 'Ireland', 'IM' => 'Isle of Man', 'IL' => 'Israel', 'IT' => 'Italy', 'JM' => 'Jamaica', 'JP' => 'Japan', 'JE' => 'Jersey', 'JO' => 'Jordan', 'KZ' => 'Kazakhstan', 'KE' => 'Kenya', 'KI' => 'Kiribati', 'KP' => 'Korea (Democratic People\'s Republic of)', 'KR' => 'Korea (Republic of)', 'KW' => 'Kuwait', 'KG' => 'Kyrgyzstan', 'LA' => 'Lao People\'s Democratic Republic', 'LV' => 'Latvia', 'LB' => 'Lebanon', 'LS' => 'Lesotho', 'LR' => 'Liberia', 'LY' => 'Libya', 'LI' => 'Liechtenstein', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'MO' => 'Macao', 'MK' => 'North 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 (Federated States of)', 'MD' => 'Moldova (Republic of)', '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', 'MP' => 'Northern Mariana Islands', 'NO' => 'Norway', 'OM' => 'Oman', 'PK' => 'Pakistan', 'PW' => 'Palau', 'PS' => 'Palestine, State of', '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' => 'Russian Federation', 'RW' => 'Rwanda', 'BL' => 'Saint Barthelemy', 'SH' => 'Saint Helena, Ascension and Tristan da Cunha', 'KN' => 'Saint Kitts and Nevis', 'LC' => 'Saint Lucia', 'MF' => 'Saint Martin (French Part)', 'PM' => 'Saint Pierre and Miquelon', 'VC' => 'Saint Vincent and The Grenadines', 'WS' => 'Samoa', 'SM' => 'San Marino', 'ST' => 'Sao Tome and Principe', 'SA' => 'Saudi Arabia', 'SN' => 'Senegal', 'RS' => 'Serbia', 'SC' => 'Seychelles', 'SL' => 'Sierra Leone', 'SG' => 'Singapore', 'SX' => 'Sint Maarten (Dutch Part)', 'SK' => 'Slovakia', 'SI' => 'Slovenia', 'SB' => 'Solomon Islands', 'SO' => 'Somalia', 'ZA' => 'South Africa', 'GS' => 'South Georgia and The South Sandwich Islands', 'SS' => 'South Sudan', 'ES' => 'Spain', 'LK' => 'Sri Lanka', 'SD' => 'Sudan', 'SR' => 'Suriname', 'SJ' => 'Svalbard and Jan Mayen', 'SZ' => 'Eswatini', 'SE' => 'Sweden', 'CH' => 'Switzerland', 'SY' => 'Syrian Arab Republic', 'TW' => 'Taiwan (Province of China)', 'TJ' => 'Tajikistan', 'TZ' => 'Tanzania, United Republic of', '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 of Great Britain and Northern Ireland', 'US' => 'United States', 'UM' => 'United States Minor Outlying Islands', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VU' => 'Vanuatu', 'VE' => 'Venezuela (Bolivarian Republic of)', 'VN' => 'Viet Nam', 'VG' => 'Virgin Islands (British)', 'VI' => 'Virgin Islands (U.S.)', 'WF' => 'Wallis and Futuna', 'EH' => 'Western Sahara', 'YE' => 'Yemen', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe'];
return (isset($countries[$code])) ? $countries[$code] : '';
}
private function get_region_code($country_code, $region_name)
{
$regions = [
'AD' => ['AD.07' => 'Andorra la Vella', 'AD.02' => 'Canillo', 'AD.03' => 'Encamp', 'AD.08' => 'Escaldes-Engordany', 'AD.04' => 'La Massana', 'AD.05' => 'Ordino', 'AD.06' => 'Sant Julia de Loria'],
'AE' => ['AE.AJ' => '\'Ajman', 'AE.AZ' => 'Abu Zaby', 'AE.FU' => 'Al Fujayrah', 'AE.SH' => 'Ash Shariqah', 'AE.DU' => 'Dubayy', 'AE.RK' => 'Ra\'s al Khaymah', 'AE.UQ' => 'Umm al Qaywayn'],
'AF' => ['AF.BDS' => 'Badakhshan', 'AF.BDG' => 'Badghis', 'AF.BGL' => 'Baghlan', 'AF.BAL' => 'Balkh', 'AF.BAM' => 'Bamyan', 'AF.DAY' => 'Daykundi', 'AF.FRA' => 'Farah', 'AF.FYB' => 'Faryab', 'AF.GHA' => 'Ghazni', 'AF.GHO' => 'Ghor', 'AF.HEL' => 'Helmand', 'AF.HER' => 'Herat', 'AF.JOW' => 'Jowzjan', 'AF.KAB' => 'Kabul', 'AF.KAN' => 'Kandahar', 'AF.KAP' => 'Kapisa', 'AF.KHO' => 'Khost', 'AF.KNR' => 'Kunar', 'AF.KDZ' => 'Kunduz', 'AF.LAG' => 'Laghman', 'AF.LOG' => 'Logar', 'AF.NAN' => 'Nangarhar', 'AF.NIM' => 'Nimroz', 'AF.NUR' => 'Nuristan', 'AF.PKA' => 'Paktika', 'AF.PIA' => 'Paktiya', 'AF.PAN' => 'Panjshayr', 'AF.PAR' => 'Parwan', 'AF.SAM' => 'Samangan', 'AF.SAR' => 'Sar-e Pul', 'AF.TAK' => 'Takhar', 'AF.URU' => 'Uruzgan', 'AF.WAR' => 'Wardak', 'AF.ZAB' => 'Zabul'],
'AG' => ['AG.10' => 'Barbuda', 'AG.11' => 'Redonda', 'AG.03' => 'Saint George', 'AG.04' => 'Saint John', 'AG.05' => 'Saint Mary', 'AG.06' => 'Saint Paul', 'AG.07' => 'Saint Peter', 'AG.08' => 'Saint Philip'],
'AL' => ['AL.01' => 'Berat', 'AL.09' => 'Diber', 'AL.02' => 'Durres', 'AL.03' => 'Elbasan', 'AL.04' => 'Fier', 'AL.05' => 'Gjirokaster', 'AL.06' => 'Korce', 'AL.07' => 'Kukes', 'AL.08' => 'Lezhe', 'AL.10' => 'Shkoder', 'AL.11' => 'Tirane', 'AL.12' => 'Vlore'],
'AM' => ['AM.AG' => 'Aragacotn', 'AM.AR' => 'Ararat', 'AM.AV' => 'Armavir', 'AM.ER' => 'Erevan', 'AM.GR' => 'Gegark\'unik\'', 'AM.KT' => 'Kotayk\'', 'AM.LO' => 'Lori', 'AM.SH' => 'Sirak', 'AM.SU' => 'Syunik\'', 'AM.TV' => 'Tavus', 'AM.VD' => 'Vayoc Jor'],
'AO' => ['AO.BGO' => 'Bengo', 'AO.BGU' => 'Benguela', 'AO.BIE' => 'Bie', 'AO.CAB' => 'Cabinda', 'AO.CCU' => 'Cuando Cubango', 'AO.CNO' => 'Cuanza-Norte', 'AO.CUS' => 'Cuanza-Sul', 'AO.CNN' => 'Cunene', 'AO.HUA' => 'Huambo', 'AO.HUI' => 'Huila', 'AO.LUA' => 'Luanda', 'AO.LNO' => 'Lunda-Norte', 'AO.LSU' => 'Lunda-Sul', 'AO.MAL' => 'Malange', 'AO.MOX' => 'Moxico', 'AO.NAM' => 'Namibe', 'AO.UIG' => 'Uige', 'AO.ZAI' => 'Zaire'],
'AR' => ['AR.B' => 'Buenos Aires', 'AR.K' => 'Catamarca', 'AR.H' => 'Chaco', 'AR.U' => 'Chubut', 'AR.C' => 'Ciudad Autonoma de Buenos Aires', 'AR.X' => 'Cordoba', 'AR.W' => 'Corrientes', 'AR.E' => 'Entre Rios', 'AR.P' => 'Formosa', 'AR.Y' => 'Jujuy', 'AR.L' => 'La Pampa', 'AR.F' => 'La Rioja', 'AR.M' => 'Mendoza', 'AR.N' => 'Misiones', 'AR.Q' => 'Neuquen', 'AR.R' => 'Rio Negro', 'AR.A' => 'Salta', 'AR.J' => 'San Juan', 'AR.D' => 'San Luis', 'AR.Z' => 'Santa Cruz', 'AR.S' => 'Santa Fe', 'AR.G' => 'Santiago del Estero', 'AR.V' => 'Tierra del Fuego', 'AR.T' => 'Tucuman'],
'AT' => ['AT.1' => 'Burgenland', 'AT.2' => 'Karnten', 'AT.3' => 'Niederosterreich', 'AT.4' => 'Oberosterreich', 'AT.5' => 'Salzburg', 'AT.6' => 'Steiermark', 'AT.7' => 'Tirol', 'AT.8' => 'Vorarlberg', 'AT.9' => 'Wien'],
'AU' => ['AU.ACT' => 'Australian Capital Territory', 'AU.NSW' => 'New South Wales', 'AU.NT' => 'Northern Territory', 'AU.QLD' => 'Queensland', 'AU.SA' => 'South Australia', 'AU.TAS' => 'Tasmania', 'AU.VIC' => 'Victoria', 'AU.WA' => 'Western Australia'],
'AZ' => ['AZ.ABS' => 'Abseron', 'AZ.AGC' => 'Agcabadi', 'AZ.AGM' => 'Agdam', 'AZ.AGS' => 'Agdas', 'AZ.AGA' => 'Agstafa', 'AZ.AGU' => 'Agsu', 'AZ.AST' => 'Astara', 'AZ.BA' => 'Baki', 'AZ.BAL' => 'Balakan', 'AZ.BAR' => 'Barda', 'AZ.BEY' => 'Beylaqan', 'AZ.BIL' => 'Bilasuvar', 'AZ.CAB' => 'Cabrayil', 'AZ.CAL' => 'Calilabad', 'AZ.CUL' => 'Culfa', 'AZ.DAS' => 'Daskasan', 'AZ.FUZ' => 'Fuzuli', 'AZ.GAD' => 'Gadabay', 'AZ.GA' => 'Ganca', 'AZ.GOR' => 'Goranboy', 'AZ.GOY' => 'Goycay', 'AZ.GYG' => 'Goygol', 'AZ.HAC' => 'Haciqabul', 'AZ.IMI' => 'Imisli', 'AZ.ISM' => 'Ismayilli', 'AZ.KAL' => 'Kalbacar', 'AZ.KAN' => 'Kangarli', 'AZ.KUR' => 'Kurdamir', 'AZ.LAC' => 'Lacin', 'AZ.LA' => 'Lankaran', 'AZ.LER' => 'Lerik', 'AZ.MAS' => 'Masalli', 'AZ.MI' => 'Mingacevir', 'AZ.NA' => 'Naftalan', 'AZ.NX' => 'Naxcivan', 'AZ.NEF' => 'Neftcala', 'AZ.OGU' => 'Oguz', 'AZ.ORD' => 'Ordubad', 'AZ.QAB' => 'Qabala', 'AZ.QAX' => 'Qax', 'AZ.QAZ' => 'Qazax', 'AZ.QOB' => 'Qobustan', 'AZ.QBA' => 'Quba', 'AZ.QBI' => 'Qubadli', 'AZ.QUS' => 'Qusar', 'AZ.SAT' => 'Saatli', 'AZ.SAB' => 'Sabirabad', 'AZ.SBN' => 'Sabran', 'AZ.SAD' => 'Sadarak', 'AZ.SAH' => 'Sahbuz', 'AZ.SAK' => 'Saki', 'AZ.SAL' => 'Salyan', 'AZ.SMI' => 'Samaxi', 'AZ.SKR' => 'Samkir', 'AZ.SMX' => 'Samux', 'AZ.SAR' => 'Sharur', 'AZ.SR' => 'Sirvan', 'AZ.SIY' => 'Siyazan', 'AZ.SM' => 'Sumqayit', 'AZ.SUS' => 'Susa', 'AZ.TAR' => 'Tartar', 'AZ.TOV' => 'Tovuz', 'AZ.UCA' => 'Ucar', 'AZ.XAC' => 'Xacmaz', 'AZ.XA' => 'Xankandi', 'AZ.XIZ' => 'Xizi', 'AZ.XCI' => 'Xocali', 'AZ.XVD' => 'Xocavand', 'AZ.YAR' => 'Yardimli', 'AZ.YEV' => 'Yevlax', 'AZ.ZAN' => 'Zangilan', 'AZ.ZAQ' => 'Zaqatala', 'AZ.ZAR' => 'Zardab'],
'BA' => ['BA.BRC' => 'Brcko distrikt', 'BA.BIH' => 'Federacija Bosne i Hercegovine', 'BA.SRP' => 'Republika Srpska'],
'BB' => ['BB.01' => 'Christ Church', 'BB.02' => 'Saint Andrew', 'BB.03' => 'Saint George', 'BB.04' => 'Saint James', 'BB.05' => 'Saint John', 'BB.06' => 'Saint Joseph', 'BB.07' => 'Saint Lucy', 'BB.08' => 'Saint Michael', 'BB.09' => 'Saint Peter', 'BB.10' => 'Saint Philip', 'BB.11' => 'Saint Thomas'],
'BD' => ['BD.A' => 'Barisal', 'BD.B' => 'Chittagong', 'BD.C' => 'Dhaka', 'BD.D' => 'Khulna', 'BD.E' => 'Rajshahi', 'BD.F' => 'Rangpur', 'BD.G' => 'Sylhet'],
'BE' => ['BE.VAN' => 'Antwerpen', 'BE.WBR' => 'Brabant wallon', 'BE.BRU' => 'Brussels Hoofdstedelijk Gewest', 'BE.WHT' => 'Hainaut', 'BE.WLG' => 'Liege', 'BE.VLI' => 'Limburg', 'BE.WLX' => 'Luxembourg', 'BE.WNA' => 'Namur', 'BE.VOV' => 'Oost-Vlaanderen', 'BE.VLG' => 'Vlaams Gewest', 'BE.VBR' => 'Vlaams-Brabant', 'BE.VWV' => 'West-Vlaanderen', 'BE.WAL' => 'wallonne, Region'],
'BF' => ['BF.BAL' => 'Bale', 'BF.BAM' => 'Bam', 'BF.BAN' => 'Banwa', 'BF.BAZ' => 'Bazega', 'BF.BGR' => 'Bougouriba', 'BF.BLG' => 'Boulgou', 'BF.BLK' => 'Boulkiemde', 'BF.COM' => 'Comoe', 'BF.GAN' => 'Ganzourgou', 'BF.GNA' => 'Gnagna', 'BF.GOU' => 'Gourma', 'BF.HOU' => 'Houet', 'BF.IOB' => 'Ioba', 'BF.KAD' => 'Kadiogo', 'BF.KEN' => 'Kenedougou', 'BF.KMD' => 'Komondjari', 'BF.KMP' => 'Kompienga', 'BF.KOS' => 'Kossi', 'BF.KOP' => 'Koulpelogo', 'BF.KOT' => 'Kouritenga', 'BF.KOW' => 'Kourweogo', 'BF.LER' => 'Leraba', 'BF.LOR' => 'Loroum', 'BF.MOU' => 'Mouhoun', 'BF.NAO' => 'Nahouri', 'BF.NAM' => 'Namentenga', 'BF.NAY' => 'Nayala', 'BF.NOU' => 'Noumbiel', 'BF.OUB' => 'Oubritenga', 'BF.OUD' => 'Oudalan', 'BF.PAS' => 'Passore', 'BF.PON' => 'Poni', 'BF.SNG' => 'Sanguie', 'BF.SMT' => 'Sanmatenga', 'BF.SEN' => 'Seno', 'BF.SIS' => 'Sissili', 'BF.SOM' => 'Soum', 'BF.SOR' => 'Sourou', 'BF.TAP' => 'Tapoa', 'BF.TUI' => 'Tuy', 'BF.YAG' => 'Yagha', 'BF.YAT' => 'Yatenga', 'BF.ZIR' => 'Ziro', 'BF.ZON' => 'Zondoma', 'BF.ZOU' => 'Zoundweogo'],
'BG' => ['BG.01' => 'Blagoevgrad', 'BG.02' => 'Burgas', 'BG.08' => 'Dobrich', 'BG.07' => 'Gabrovo', 'BG.26' => 'Haskovo', 'BG.09' => 'Kardzhali', 'BG.10' => 'Kyustendil', 'BG.11' => 'Lovech', 'BG.12' => 'Montana', 'BG.13' => 'Pazardzhik', 'BG.14' => 'Pernik', 'BG.15' => 'Pleven', 'BG.16' => 'Plovdiv', 'BG.17' => 'Razgrad', 'BG.18' => 'Ruse', 'BG.27' => 'Shumen', 'BG.19' => 'Silistra', 'BG.20' => 'Sliven', 'BG.21' => 'Smolyan', 'BG.23' => 'Sofia', 'BG.22' => 'Sofia (stolitsa)', 'BG.24' => 'Stara Zagora', 'BG.25' => 'Targovishte', 'BG.03' => 'Varna', 'BG.04' => 'Veliko Tarnovo', 'BG.05' => 'Vidin', 'BG.06' => 'Vratsa', 'BG.28' => 'Yambol'],
'BH' => ['BH.13' => 'Al \'Asimah', 'BH.14' => 'Al Janubiyah', 'BH.15' => 'Al Muharraq', 'BH.17' => 'Ash Shamaliyah'],
'BI' => ['BI.BB' => 'Bubanza', 'BI.BM' => 'Bujumbura Mairie', 'BI.BL' => 'Bujumbura Rural', 'BI.BR' => 'Bururi', 'BI.CA' => 'Cankuzo', 'BI.CI' => 'Cibitoke', 'BI.GI' => 'Gitega', 'BI.KR' => 'Karuzi', 'BI.KY' => 'Kayanza', 'BI.KI' => 'Kirundo', 'BI.MA' => 'Makamba', 'BI.MU' => 'Muramvya', 'BI.MY' => 'Muyinga', 'BI.MW' => 'Mwaro', 'BI.NG' => 'Ngozi', 'BI.RM' => 'Rumonge', 'BI.RT' => 'Rutana', 'BI.RY' => 'Ruyigi'],
'BJ' => ['BJ.AL' => 'Alibori', 'BJ.AK' => 'Atacora', 'BJ.AQ' => 'Atlantique', 'BJ.BO' => 'Borgou', 'BJ.CO' => 'Collines', 'BJ.KO' => 'Couffo', 'BJ.DO' => 'Donga', 'BJ.LI' => 'Littoral', 'BJ.MO' => 'Mono', 'BJ.OU' => 'Oueme', 'BJ.PL' => 'Plateau', 'BJ.ZO' => 'Zou'],
'BN' => ['BN.BE' => 'Belait', 'BN.BM' => 'Brunei-Muara', 'BN.TE' => 'Temburong', 'BN.TU' => 'Tutong'],
'BO' => ['BO.H' => 'Chuquisaca', 'BO.C' => 'Cochabamba', 'BO.B' => 'El Beni', 'BO.L' => 'La Paz', 'BO.O' => 'Oruro', 'BO.N' => 'Pando', 'BO.P' => 'Potosi', 'BO.S' => 'Santa Cruz', 'BO.T' => 'Tarija'],
'BQ' => ['BQ.BO' => 'Bonaire', 'BQ.SA' => 'Saba', 'BQ.SE' => 'Sint Eustatius'],
'BR' => ['BR.AC' => 'Acre', 'BR.AL' => 'Alagoas', 'BR.AP' => 'Amapa', 'BR.AM' => 'Amazonas', 'BR.BA' => 'Bahia', 'BR.CE' => 'Ceara', 'BR.DF' => 'Distrito Federal', 'BR.ES' => 'Espirito Santo', 'BR.GO' => 'Goias', 'BR.MA' => 'Maranhao', 'BR.MT' => 'Mato Grosso', 'BR.MS' => 'Mato Grosso do Sul', 'BR.MG' => 'Minas Gerais', 'BR.PA' => 'Para', 'BR.PB' => 'Paraiba', 'BR.PR' => 'Parana', 'BR.PE' => 'Pernambuco', 'BR.PI' => 'Piaui', 'BR.RN' => 'Rio Grande do Norte', 'BR.RS' => 'Rio Grande do Sul', 'BR.RJ' => 'Rio de Janeiro', 'BR.RO' => 'Rondonia', 'BR.RR' => 'Roraima', 'BR.SC' => 'Santa Catarina', 'BR.SP' => 'Sao Paulo', 'BR.SE' => 'Sergipe', 'BR.TO' => 'Tocantins'],
'BS' => ['BS.AK' => 'Acklins', 'BS.BY' => 'Berry Islands', 'BS.BI' => 'Bimini', 'BS.BP' => 'Black Point', 'BS.CI' => 'Cat Island', 'BS.CO' => 'Central Abaco', 'BS.CS' => 'Central Andros', 'BS.CE' => 'Central Eleuthera', 'BS.FP' => 'City of Freeport', 'BS.CK' => 'Crooked Island and Long Cay', 'BS.EG' => 'East Grand Bahama', 'BS.EX' => 'Exuma', 'BS.GC' => 'Grand Cay', 'BS.HI' => 'Harbour Island', 'BS.HT' => 'Hope Town', 'BS.IN' => 'Inagua', 'BS.LI' => 'Long Island', 'BS.MC' => 'Mangrove Cay', 'BS.MG' => 'Mayaguana', 'BS.MI' => 'Moore\'s Island', 'BS.NP' => 'New Providence', 'BS.NO' => 'North Abaco', 'BS.NS' => 'North Andros', 'BS.NE' => 'North Eleuthera', 'BS.RI' => 'Ragged Island', 'BS.RC' => 'Rum Cay', 'BS.SS' => 'San Salvador', 'BS.SO' => 'South Abaco', 'BS.SA' => 'South Andros', 'BS.SE' => 'South Eleuthera', 'BS.SW' => 'Spanish Wells', 'BS.WG' => 'West Grand Bahama'],
'BT' => ['BT.33' => 'Bumthang', 'BT.12' => 'Chhukha', 'BT.22' => 'Dagana', 'BT.GA' => 'Gasa', 'BT.13' => 'Haa', 'BT.44' => 'Lhuentse', 'BT.42' => 'Monggar', 'BT.11' => 'Paro', 'BT.43' => 'Pema Gatshel', 'BT.23' => 'Punakha', 'BT.45' => 'Samdrup Jongkhar', 'BT.14' => 'Samtse', 'BT.31' => 'Sarpang', 'BT.15' => 'Thimphu', 'BT.TY' => 'Trashi Yangtse', 'BT.41' => 'Trashigang', 'BT.32' => 'Trongsa', 'BT.21' => 'Tsirang', 'BT.24' => 'Wangdue Phodrang', 'BT.34' => 'Zhemgang'],
'BW' => ['BW.CE' => 'Central', 'BW.CH' => 'Chobe', 'BW.GH' => 'Ghanzi', 'BW.KG' => 'Kgalagadi', 'BW.KL' => 'Kgatleng', 'BW.KW' => 'Kweneng', 'BW.NE' => 'North East', 'BW.NW' => 'North West', 'BW.SE' => 'South East', 'BW.SO' => 'Southern'],
'BY' => ['BY.BR' => 'Brestskaya voblasts\'', 'BY.HO' => 'Homyel\'skaya voblasts\'', 'BY.HM' => 'Horad Minsk', 'BY.HR' => 'Hrodzenskaya voblasts\'', 'BY.MA' => 'Mahilyowskaya voblasts\'', 'BY.MI' => 'Minskaya voblasts\'', 'BY.VI' => 'Vitsyebskaya voblasts\''],
'BZ' => ['BZ.BZ' => 'Belize', 'BZ.CY' => 'Cayo', 'BZ.CZL' => 'Corozal', 'BZ.OW' => 'Orange Walk', 'BZ.SC' => 'Stann Creek', 'BZ.TOL' => 'Toledo'],
'CA' => ['CA.AB' => 'Alberta', 'CA.BC' => 'British Columbia', 'CA.MB' => 'Manitoba', 'CA.NB' => 'New Brunswick', 'CA.NL' => 'Newfoundland and Labrador', 'CA.NT' => 'Northwest Territories', 'CA.NS' => 'Nova Scotia', 'CA.NU' => 'Nunavut', 'CA.ON' => 'Ontario', 'CA.PE' => 'Prince Edward Island', 'CA.QC' => 'Quebec', 'CA.SK' => 'Saskatchewan', 'CA.YT' => 'Yukon'],
'CD' => ['CD.BU' => 'Bas-Uele', 'CD.EQ' => 'Equateur', 'CD.HK' => 'Haut-Katanga', 'CD.HL' => 'Haut-Lomami', 'CD.HU' => 'Haut-Uele', 'CD.IT' => 'Ituri', 'CD.KS' => 'Kasai', 'CD.KC' => 'Kasai Central', 'CD.KE' => 'Kasai Oriental', 'CD.KN' => 'Kinshasa', 'CD.BC' => 'Kongo Central', 'CD.KG' => 'Kwango', 'CD.KL' => 'Kwilu', 'CD.LO' => 'Lomami', 'CD.LU' => 'Lualaba', 'CD.MN' => 'Mai-Ndombe', 'CD.MA' => 'Maniema', 'CD.MO' => 'Mongala', 'CD.NK' => 'NorD.Kivu', 'CD.NU' => 'NorD.Ubangi', 'CD.SA' => 'Sankuru', 'CD.SK' => 'SuD.Kivu', 'CD.SU' => 'SuD.Ubangi', 'CD.TA' => 'Tanganyika', 'CD.TO' => 'Tshopo', 'CD.TU' => 'Tshuapa'],
'CF' => ['CF.BB' => 'Bamingui-Bangoran', 'CF.BGF' => 'Bangui', 'CF.BK' => 'Basse-Kotto', 'CF.KB' => 'Gribingui', 'CF.HM' => 'Haut-Mbomou', 'CF.HK' => 'Haute-Kotto', 'CF.KG' => 'Kemo-Gribingui', 'CF.LB' => 'Lobaye', 'CF.HS' => 'Mambere-Kadei', 'CF.MB' => 'Mbomou', 'CF.NM' => 'Nana-Mambere', 'CF.MP' => 'Ombella-Mpoko', 'CF.UK' => 'Ouaka', 'CF.AC' => 'Ouham', 'CF.OP' => 'Ouham-Pende', 'CF.SE' => 'Sangha', 'CF.VK' => 'Vakaga'],
'CG' => ['CG.11' => 'Bouenza', 'CG.BZV' => 'Brazzaville', 'CG.8' => 'Cuvette', 'CG.15' => 'Cuvette-Ouest', 'CG.5' => 'Kouilou', 'CG.2' => 'Lekoumou', 'CG.7' => 'Likouala', 'CG.9' => 'Niari', 'CG.14' => 'Plateaux', 'CG.16' => 'Pointe-Noire', 'CG.12' => 'Pool', 'CG.13' => 'Sangha'],
'CH' => ['CH.AG' => 'Aargau', 'CH.AR' => 'Appenzell Ausserrhoden', 'CH.AI' => 'Appenzell Innerrhoden', 'CH.BL' => 'Basel-Landschaft', 'CH.BS' => 'Basel-Stadt', 'CH.BE' => 'Bern', 'CH.FR' => 'Fribourg', 'CH.GE' => 'Geneve', 'CH.GL' => 'Glarus', 'CH.GR' => 'Graubunden', 'CH.JU' => 'Jura', 'CH.LU' => 'Luzern', 'CH.NE' => 'Neuchatel', 'CH.NW' => 'Nidwalden', 'CH.OW' => 'Obwalden', 'CH.SG' => 'Sankt Gallen', 'CH.SH' => 'Schaffhausen', 'CH.SZ' => 'Schwyz', 'CH.SO' => 'Solothurn', 'CH.TG' => 'Thurgau', 'CH.TI' => 'Ticino', 'CH.UR' => 'Uri', 'CH.VS' => 'Valais', 'CH.VD' => 'Vaud', 'CH.ZG' => 'Zug', 'CH.ZH' => 'Zurich'],
'CI' => ['CI.AB' => 'Abidjan', 'CI.BS' => 'Bas-Sassandra', 'CI.CM' => 'Comoe', 'CI.DN' => 'Denguele', 'CI.GD' => 'Goh-Djiboua', 'CI.LC' => 'Lacs', 'CI.LG' => 'Lagunes', 'CI.MG' => 'Montagnes', 'CI.SM' => 'Sassandra-Marahoue', 'CI.SV' => 'Savanes', 'CI.VB' => 'Vallee du Bandama', 'CI.WR' => 'Woroba', 'CI.YM' => 'Yamoussoukro', 'CI.ZZ' => 'Zanzan'],
'CL' => ['CL.AI' => 'Aisen del General Carlos Ibanez del Campo', 'CL.AN' => 'Antofagasta', 'CL.AP' => 'Arica y Parinacota', 'CL.AT' => 'Atacama', 'CL.BI' => 'Biobio', 'CL.CO' => 'Coquimbo', 'CL.AR' => 'La Araucania', 'CL.LI' => 'Libertador General Bernardo O\'Higgins', 'CL.LL' => 'Los Lagos', 'CL.LR' => 'Los Rios', 'CL.MA' => 'Magallanes', 'CL.ML' => 'Maule', 'CL.NB' => 'Nuble', 'CL.RM' => 'Region Metropolitana de Santiago', 'CL.TA' => 'Tarapaca', 'CL.VS' => 'Valparaiso'],
'CM' => ['CM.AD' => 'Adamaoua', 'CM.CE' => 'Centre', 'CM.ES' => 'Est', 'CM.EN' => 'Extreme-Nord', 'CM.LT' => 'Littoral', 'CM.NO' => 'Nord', 'CM.NW' => 'Nord-Ouest', 'CM.OU' => 'Ouest', 'CM.SU' => 'Sud', 'CM.SW' => 'Sud-Ouest'],
'CN' => ['CN.AH' => 'Anhui', 'CN.BJ' => 'Beijing', 'CN.CQ' => 'Chongqing', 'CN.FJ' => 'Fujian', 'CN.GS' => 'Gansu', 'CN.GD' => 'Guangdong', 'CN.GX' => 'Guangxi', 'CN.GZ' => 'Guizhou', 'CN.HI' => 'Hainan', 'CN.HE' => 'Hebei', 'CN.HL' => 'Heilongjiang', 'CN.HA' => 'Henan', 'CN.HB' => 'Hubei', 'CN.HN' => 'Hunan', 'CN.JS' => 'Jiangsu', 'CN.JX' => 'Jiangxi', 'CN.JL' => 'Jilin', 'CN.LN' => 'Liaoning', 'CN.NM' => 'Nei Mongol', 'CN.NX' => 'Ningxia', 'CN.QH' => 'Qinghai', 'CN.SN' => 'Shaanxi', 'CN.SD' => 'Shandong', 'CN.SH' => 'Shanghai', 'CN.SX' => 'Shanxi', 'CN.SC' => 'Sichuan', 'CN.TJ' => 'Tianjin', 'CN.XJ' => 'Xinjiang', 'CN.XZ' => 'Xizang', 'CN.YN' => 'Yunnan', 'CN.ZJ' => 'Zhejiang'],
'CO' => ['CO.AMA' => 'Amazonas', 'CO.ANT' => 'Antioquia', 'CO.ARA' => 'Arauca', 'CO.ATL' => 'Atlantico', 'CO.BOL' => 'Bolivar', 'CO.BOY' => 'Boyaca', 'CO.CAL' => 'Caldas', 'CO.CAQ' => 'Caqueta', 'CO.CAS' => 'Casanare', 'CO.CAU' => 'Cauca', 'CO.CES' => 'Cesar', 'CO.CHO' => 'Choco', 'CO.COR' => 'Cordoba', 'CO.CUN' => 'Cundinamarca', 'CO.DC' => 'Distrito Capital de Bogota', 'CO.GUA' => 'Guainia', 'CO.GUV' => 'Guaviare', 'CO.HUI' => 'Huila', 'CO.LAG' => 'La Guajira', 'CO.MAG' => 'Magdalena', 'CO.MET' => 'Meta', 'CO.NAR' => 'Narino', 'CO.NSA' => 'Norte de Santander', 'CO.PUT' => 'Putumayo', 'CO.QUI' => 'Quindio', 'CO.RIS' => 'Risaralda', 'CO.SAP' => 'San Andres, Providencia y Santa Catalina', 'CO.SAN' => 'Santander', 'CO.SUC' => 'Sucre', 'CO.TOL' => 'Tolima', 'CO.VAC' => 'Valle del Cauca', 'CO.VAU' => 'Vaupes', 'CO.VID' => 'Vichada'],
'CR' => ['CR.A' => 'Alajuela', 'CR.C' => 'Cartago', 'CR.G' => 'Guanacaste', 'CR.H' => 'Heredia', 'CR.L' => 'Limon', 'CR.P' => 'Puntarenas', 'CR.SJ' => 'San Jose'],
'CU' => ['CU.15' => 'Artemisa', 'CU.09' => 'Camaguey', 'CU.08' => 'Ciego de Avila', 'CU.06' => 'Cienfuegos', 'CU.12' => 'Granma', 'CU.14' => 'Guantanamo', 'CU.11' => 'Holguin', 'CU.99' => 'Isla de la Juventud', 'CU.03' => 'La Habana', 'CU.10' => 'Las Tunas', 'CU.04' => 'Matanzas', 'CU.16' => 'Mayabeque', 'CU.01' => 'Pinar del Rio', 'CU.07' => 'Sancti Spiritus', 'CU.13' => 'Santiago de Cuba', 'CU.05' => 'Villa Clara'],
'CV' => ['CV.BV' => 'Boa Vista', 'CV.BR' => 'Brava', 'CV.MA' => 'Maio', 'CV.MO' => 'Mosteiros', 'CV.PA' => 'Paul', 'CV.PN' => 'Porto Novo', 'CV.PR' => 'Praia', 'CV.RB' => 'Ribeira Brava', 'CV.RG' => 'Ribeira Grande', 'CV.RS' => 'Ribeira Grande de Santiago', 'CV.SL' => 'Sal', 'CV.CA' => 'Santa Catarina', 'CV.CF' => 'Santa Catarina do Fogo', 'CV.CR' => 'Santa Cruz', 'CV.SD' => 'Sao Domingos', 'CV.SF' => 'Sao Filipe', 'CV.SO' => 'Sao Lourenco dos Orgaos', 'CV.SM' => 'Sao Miguel', 'CV.SS' => 'Sao Salvador do Mundo', 'CV.SV' => 'Sao Vicente', 'CV.TA' => 'Tarrafal', 'CV.TS' => 'Tarrafal de Sao Nicolau'],
'CY' => ['CY.04' => 'Ammochostos', 'CY.06' => 'Keryneia', 'CY.03' => 'Larnaka', 'CY.01' => 'Lefkosia', 'CY.02' => 'Lemesos', 'CY.05' => 'Pafos'],
'CZ' => ['CZ.31' => 'Jihocesky kraj', 'CZ.64' => 'Jihomoravsky kraj', 'CZ.41' => 'Karlovarsky kraj', 'CZ.63' => 'Kraj Vysocina', 'CZ.52' => 'Kralovehradecky kraj', 'CZ.51' => 'Liberecky kraj', 'CZ.80' => 'Moravskoslezsky kraj', 'CZ.71' => 'Olomoucky kraj', 'CZ.53' => 'Pardubicky kraj', 'CZ.32' => 'Plzensky kraj', 'CZ.10' => 'Praha, Hlavni mesto', 'CZ.20' => 'Stredocesky kraj', 'CZ.42' => 'Ustecky kraj', 'CZ.72' => 'Zlinsky kraj'],
'DE' => ['DE.BW' => 'Baden-Wurttemberg', 'DE.BY' => 'Bayern', 'DE.BE' => 'Berlin', 'DE.BB' => 'Brandenburg', 'DE.HB' => 'Bremen', 'DE.HH' => 'Hamburg', 'DE.HE' => 'Hessen', 'DE.MV' => 'Mecklenburg-Vorpommern', 'DE.NI' => 'Niedersachsen', 'DE.NW' => 'Nordrhein-Westfalen', 'DE.RP' => 'Rheinland-Pfalz', 'DE.SL' => 'Saarland', 'DE.SN' => 'Sachsen', 'DE.ST' => 'Sachsen-Anhalt', 'DE.SH' => 'Schleswig-Holstein', 'DE.TH' => 'Thuringen'],
'DJ' => ['DJ.AS' => 'Ali Sabieh', 'DJ.AR' => 'Arta', 'DJ.DI' => 'Dikhil', 'DJ.DJ' => 'Djibouti', 'DJ.OB' => 'Obock', 'DJ.TA' => 'Tadjourah'],
'DK' => ['DK.84' => 'Hovedstaden', 'DK.82' => 'Midtjylland', 'DK.81' => 'Nordjylland', 'DK.85' => 'Sjaelland', 'DK.83' => 'Syddanmark'],
'DM' => ['DM.02' => 'Saint Andrew', 'DM.03' => 'Saint David', 'DM.04' => 'Saint George', 'DM.05' => 'Saint John', 'DM.06' => 'Saint Joseph', 'DM.07' => 'Saint Luke', 'DM.08' => 'Saint Mark', 'DM.09' => 'Saint Patrick', 'DM.10' => 'Saint Paul', 'DM.11' => 'Saint Peter'],
'DO' => ['DO.02' => 'Azua', 'DO.03' => 'Baoruco', 'DO.04' => 'Barahona', 'DO.05' => 'Dajabon', 'DO.01' => 'Distrito Nacional (Santo Domingo)', 'DO.06' => 'Duarte', 'DO.08' => 'El Seibo', 'DO.07' => 'Elias Pina', 'DO.09' => 'Espaillat', 'DO.30' => 'Hato Mayor', 'DO.19' => 'Hermanas Mirabal', 'DO.10' => 'Independencia', 'DO.11' => 'La Altagracia', 'DO.12' => 'La Romana', 'DO.13' => 'La Vega', 'DO.14' => 'Maria Trinidad Sanchez', 'DO.28' => 'Monsenor Nouel', 'DO.15' => 'Monte Cristi', 'DO.29' => 'Monte Plata', 'DO.16' => 'Pedernales', 'DO.17' => 'Peravia', 'DO.18' => 'Puerto Plata', 'DO.20' => 'Samana', 'DO.21' => 'San Cristobal', 'DO.31' => 'San Jose de Ocoa', 'DO.22' => 'San Juan', 'DO.23' => 'San Pedro de Macoris', 'DO.24' => 'Sanchez Ramirez', 'DO.25' => 'Santiago', 'DO.26' => 'Santiago Rodriguez', 'DO.32' => 'Santo Domingo', 'DO.27' => 'Valverde'],
'DZ' => ['DZ.01' => 'Adrar', 'DZ.44' => 'Ain Defla', 'DZ.46' => 'Ain Temouchent', 'DZ.16' => 'Alger', 'DZ.23' => 'Annaba', 'DZ.05' => 'Batna', 'DZ.08' => 'Bechar', 'DZ.06' => 'Bejaia', 'DZ.52' => 'Beni Abbes', 'DZ.07' => 'Biskra', 'DZ.09' => 'Blida', 'DZ.50' => 'Bordj Badji Mokhtar', 'DZ.34' => 'Bordj Bou Arreridj', 'DZ.10' => 'Bouira', 'DZ.35' => 'Boumerdes', 'DZ.02' => 'Chlef', 'DZ.25' => 'Constantine', 'DZ.56' => 'Djanet', 'DZ.17' => 'Djelfa', 'DZ.32' => 'El Bayadh', 'DZ.57' => 'El Meghaier', 'DZ.58' => 'El Meniaa', 'DZ.39' => 'El Oued', 'DZ.36' => 'El Tarf', 'DZ.47' => 'Ghardaia', 'DZ.24' => 'Guelma', 'DZ.33' => 'Illizi', 'DZ.54' => 'In Guezzam', 'DZ.53' => 'In Salah', 'DZ.18' => 'Jijel', 'DZ.40' => 'Khenchela', 'DZ.03' => 'Laghouat', 'DZ.28' => 'M\'sila', 'DZ.29' => 'Mascara', 'DZ.26' => 'Medea', 'DZ.43' => 'Mila', 'DZ.27' => 'Mostaganem', 'DZ.45' => 'Naama', 'DZ.31' => 'Oran', 'DZ.30' => 'Ouargla', 'DZ.51' => 'Ouled Djellal', 'DZ.04' => 'Oum el Bouaghi', 'DZ.48' => 'Relizane', 'DZ.20' => 'Saida', 'DZ.19' => 'Setif', 'DZ.22' => 'Sidi Bel Abbes', 'DZ.21' => 'Skikda', 'DZ.41' => 'Souk Ahras', 'DZ.11' => 'Tamanrasset', 'DZ.12' => 'Tebessa', 'DZ.14' => 'Tiaret', 'DZ.49' => 'Timimoun', 'DZ.37' => 'Tindouf', 'DZ.42' => 'Tipaza', 'DZ.38' => 'Tissemsilt', 'DZ.15' => 'Tizi Ouzou', 'DZ.13' => 'Tlemcen', 'DZ.55' => 'Touggourt'],
'EC' => ['EC.A' => 'Azuay', 'EC.B' => 'Bolivar', 'EC.F' => 'Canar', 'EC.C' => 'Carchi', 'EC.H' => 'Chimborazo', 'EC.X' => 'Cotopaxi', 'EC.O' => 'El Oro', 'EC.E' => 'Esmeraldas', 'EC.W' => 'Galapagos', 'EC.G' => 'Guayas', 'EC.I' => 'Imbabura', 'EC.L' => 'Loja', 'EC.R' => 'Los Rios', 'EC.M' => 'Manabi', 'EC.S' => 'Morona Santiago', 'EC.N' => 'Napo', 'EC.D' => 'Orellana', 'EC.Y' => 'Pastaza', 'EC.P' => 'Pichincha', 'EC.SE' => 'Santa Elena', 'EC.SD' => 'Santo Domingo de los Tsachilas', 'EC.U' => 'Sucumbios', 'EC.T' => 'Tungurahua', 'EC.Z' => 'Zamora Chinchipe'],
'EE' => ['EE.37' => 'Harjumaa', 'EE.39' => 'Hiiumaa', 'EE.44' => 'Ida-Virumaa', 'EE.51' => 'Jarvamaa', 'EE.49' => 'Jogevamaa', 'EE.59' => 'Laane-Virumaa', 'EE.57' => 'Laanemaa', 'EE.67' => 'Parnumaa', 'EE.65' => 'Polvamaa', 'EE.70' => 'Raplamaa', 'EE.74' => 'Saaremaa', 'EE.78' => 'Tartumaa', 'EE.82' => 'Valgamaa', 'EE.84' => 'Viljandimaa', 'EE.86' => 'Vorumaa'],
'EG' => ['EG.DK' => 'Ad Daqahliyah', 'EG.BA' => 'Al Bahr al Ahmar', 'EG.BH' => 'Al Buhayrah', 'EG.FYM' => 'Al Fayyum', 'EG.GH' => 'Al Gharbiyah', 'EG.ALX' => 'Al Iskandariyah', 'EG.IS' => 'Al Isma\'iliyah', 'EG.GZ' => 'Al Jizah', 'EG.MNF' => 'Al Minufiyah', 'EG.MN' => 'Al Minya', 'EG.C' => 'Al Qahirah', 'EG.KB' => 'Al Qalyubiyah', 'EG.LX' => 'Al Uqsur', 'EG.WAD' => 'Al Wadi al Jadid', 'EG.SUZ' => 'As Suways', 'EG.SHR' => 'Ash Sharqiyah', 'EG.ASN' => 'Aswan', 'EG.AST' => 'Asyut', 'EG.BNS' => 'Bani Suwayf', 'EG.PTS' => 'Bur Sa\'id', 'EG.DT' => 'Dumyat', 'EG.JS' => 'Janub Sina\'', 'EG.KFS' => 'Kafr ash Shaykh', 'EG.MT' => 'Matruh', 'EG.KN' => 'Qina', 'EG.SIN' => 'Shamal Sina\'', 'EG.SHG' => 'Suhaj'],
'ER' => ['ER.MA' => 'Al Awsat', 'ER.DU' => 'Al Janubi', 'ER.AN' => 'Ansaba', 'ER.DK' => 'Janubi al Bahri al Ahmar', 'ER.GB' => 'Qash-Barkah', 'ER.SK' => 'Shimali al Bahri al Ahmar'],
'ES' => ['ES.AN' => 'Andalucia', 'ES.AR' => 'Aragon', 'ES.AS' => 'Asturias, Principado de', 'ES.CN' => 'Canarias', 'ES.CB' => 'Cantabria', 'ES.CL' => 'Castilla y Leon', 'ES.CM' => 'Castilla-La Mancha', 'ES.CT' => 'Catalunya', 'ES.CE' => 'Ceuta', 'ES.EX' => 'Extremadura', 'ES.GA' => 'Galicia', 'ES.IB' => 'Illes Balears', 'ES.RI' => 'La Rioja', 'ES.MD' => 'Madrid, Comunidad de', 'ES.ML' => 'Melilla', 'ES.MC' => 'Murcia, Region de', 'ES.NC' => 'Navarra, Comunidad Foral de', 'ES.PV' => 'Pais Vasco', 'ES.VC' => 'Valenciana, Comunidad'],
'ET' => ['ET.AA' => 'Addis Ababa', 'ET.AF' => 'Afar', 'ET.AM' => 'Amara', 'ET.BE' => 'Benshangul-Gumaz', 'ET.DD' => 'Dire Dawa', 'ET.GA' => 'Gambela Peoples', 'ET.HA' => 'Harari People', 'ET.OR' => 'Oromia', 'ET.SI' => 'Sidama', 'ET.SO' => 'Somali', 'ET.SN' => 'Southern Nations, Nationalities and Peoples', 'ET.SW' => 'Southwest Ethiopia Peoples', 'ET.TI' => 'Tigrai'],
'FI' => ['FI.01' => 'Ahvenanmaan maakunta', 'FI.02' => 'Etela-Karjala', 'FI.03' => 'Etela-Pohjanmaa', 'FI.04' => 'Etela-Savo', 'FI.05' => 'Kainuu', 'FI.06' => 'Kanta-Hame', 'FI.07' => 'Keski-Pohjanmaa', 'FI.08' => 'Keski-Suomi', 'FI.09' => 'Kymenlaakso', 'FI.10' => 'Lappi', 'FI.16' => 'Paijat-Hame', 'FI.11' => 'Pirkanmaa', 'FI.12' => 'Pohjanmaa', 'FI.13' => 'Pohjois-Karjala', 'FI.14' => 'Pohjois-Pohjanmaa', 'FI.15' => 'Pohjois-Savo', 'FI.17' => 'Satakunta', 'FI.18' => 'Uusimaa', 'FI.19' => 'Varsinais-Suomi'],
'FJ' => ['FJ.C' => 'Central', 'FJ.E' => 'Eastern', 'FJ.N' => 'Northern', 'FJ.R' => 'Rotuma', 'FJ.W' => 'Western'],
'FM' => ['FM.TRK' => 'Chuuk', 'FM.KSA' => 'Kosrae', 'FM.PNI' => 'Pohnpei', 'FM.YAP' => 'Yap'],
'FR' => ['FR.ARA' => 'Auvergne-Rhone-Alpes', 'FR.BFC' => 'Bourgogne-Franche-Comte', 'FR.BRE' => 'Bretagne', 'FR.CVL' => 'Centre-Val de Loire', 'FR.COR' => 'Corse', 'FR.GES' => 'Grand-Est', 'FR.HDF' => 'Hauts-de-France', 'FR.IDF' => 'Ile-de-France', 'FR.NOR' => 'Normandie', 'FR.NAQ' => 'Nouvelle-Aquitaine', 'FR.OCC' => 'Occitanie', 'FR.PDL' => 'Pays-de-la-Loire', 'FR.PAC' => 'Provence-Alpes-Cote-d\'Azur'],
'GA' => ['GA.1' => 'Estuaire', 'GA.2' => 'Haut-Ogooue', 'GA.3' => 'Moyen-Ogooue', 'GA.4' => 'Ngounie', 'GA.5' => 'Nyanga', 'GA.6' => 'Ogooue-Ivindo', 'GA.7' => 'Ogooue-Lolo', 'GA.8' => 'Ogooue-Maritime', 'GA.9' => 'Woleu-Ntem'],
'GB' => ['GB.ENG' => 'England', 'GB.NIR' => 'Northern Ireland', 'GB.SCT' => 'Scotland', 'GB.WLS' => 'Wales'],
'GD' => ['GD.01' => 'Saint Andrew', 'GD.02' => 'Saint David', 'GD.03' => 'Saint George', 'GD.04' => 'Saint John', 'GD.05' => 'Saint Mark', 'GD.06' => 'Saint Patrick', 'GD.10' => 'Southern Grenadine Islands'],
'GE' => ['GE.AB' => 'Abkhazia', 'GE.AJ' => 'Ajaria', 'GE.GU' => 'Guria', 'GE.IM' => 'Imereti', 'GE.KA' => 'K\'akheti', 'GE.KK' => 'Kvemo Kartli', 'GE.MM' => 'Mtskheta-Mtianeti', 'GE.RL' => 'Rach\'a-Lechkhumi-Kvemo Svaneti', 'GE.SZ' => 'Samegrelo-Zemo Svaneti', 'GE.SJ' => 'Samtskhe-Javakheti', 'GE.SK' => 'Shida Kartli', 'GE.TB' => 'Tbilisi'],
'GH' => ['GH.AF' => 'Ahafo', 'GH.AH' => 'Ashanti', 'GH.BO' => 'Bono', 'GH.BE' => 'Bono East', 'GH.CP' => 'Central', 'GH.EP' => 'Eastern', 'GH.AA' => 'Greater Accra', 'GH.NP' => 'Northern', 'GH.OT' => 'Oti', 'GH.SV' => 'Savannah', 'GH.UE' => 'Upper East', 'GH.UW' => 'Upper West', 'GH.TV' => 'Volta', 'GH.WP' => 'Western', 'GH.WN' => 'Western North'],
'GL' => ['GL.AV' => 'Avannaata Kommunia', 'GL.KU' => 'Kommune Kujalleq', 'GL.QT' => 'Kommune Qeqertalik', 'GL.SM' => 'Kommuneqarfik Sermersooq', 'GL.QE' => 'Qeqqata Kommunia'],
'GM' => ['GM.B' => 'Banjul', 'GM.M' => 'Central River', 'GM.L' => 'Lower River', 'GM.N' => 'North Bank', 'GM.U' => 'Upper River', 'GM.W' => 'Western'],
'GN' => ['GN.BE' => 'Beyla', 'GN.BF' => 'Boffa', 'GN.B' => 'Boke', 'GN.C' => 'Conakry', 'GN.CO' => 'Coyah', 'GN.DB' => 'Dabola', 'GN.DL' => 'Dalaba', 'GN.DI' => 'Dinguiraye', 'GN.DU' => 'Dubreka', 'GN.F' => 'Faranah', 'GN.FA' => 'Faranah', 'GN.FO' => 'Forecariah', 'GN.FR' => 'Fria', 'GN.GA' => 'Gaoual', 'GN.GU' => 'Guekedou', 'GN.K' => 'Kankan', 'GN.KE' => 'Kerouane', 'GN.D' => 'Kindia', 'GN.KS' => 'Kissidougou', 'GN.KB' => 'Koubia', 'GN.KN' => 'Koundara', 'GN.KO' => 'Kouroussa', 'GN.L' => 'Labe', 'GN.LA' => 'Labe', 'GN.LE' => 'Lelouma', 'GN.LO' => 'Lola', 'GN.MC' => 'Macenta', 'GN.ML' => 'Mali', 'GN.M' => 'Mamou', 'GN.MD' => 'Mandiana', 'GN.N' => 'Nzerekore', 'GN.PI' => 'Pita', 'GN.SI' => 'Siguiri', 'GN.TE' => 'Telimele', 'GN.TO' => 'Tougue', 'GN.YO' => 'Yomou'],
'GQ' => ['GQ.AN' => 'Annobon', 'GQ.BN' => 'Bioko Norte', 'GQ.BS' => 'Bioko Sur', 'GQ.CS' => 'Centro Sur', 'GQ.DJ' => 'Djibloho', 'GQ.KN' => 'Kie-Ntem', 'GQ.LI' => 'Litoral', 'GQ.WN' => 'Wele-Nzas'],
'GR' => ['GR.69' => 'Agion Oros', 'GR.A' => 'Anatoliki Makedonia kai Thraki', 'GR.I' => 'Attiki', 'GR.G' => 'Dytiki Ellada', 'GR.C' => 'Dytiki Makedonia', 'GR.F' => 'Ionia Nisia', 'GR.D' => 'Ipeiros', 'GR.B' => 'Kentriki Makedonia', 'GR.M' => 'Kriti', 'GR.L' => 'Notio Aigaio', 'GR.J' => 'Peloponnisos', 'GR.H' => 'Sterea Ellada', 'GR.E' => 'Thessalia', 'GR.K' => 'Voreio Aigaio'],
'GT' => ['GT.AV' => 'Alta Verapaz', 'GT.BV' => 'Baja Verapaz', 'GT.CM' => 'Chimaltenango', 'GT.CQ' => 'Chiquimula', 'GT.PR' => 'El Progreso', 'GT.ES' => 'Escuintla', 'GT.GU' => 'Guatemala', 'GT.HU' => 'Huehuetenango', 'GT.IZ' => 'Izabal', 'GT.JA' => 'Jalapa', 'GT.JU' => 'Jutiapa', 'GT.PE' => 'Peten', 'GT.QZ' => 'Quetzaltenango', 'GT.QC' => 'Quiche', 'GT.RE' => 'Retalhuleu', 'GT.SA' => 'Sacatepequez', 'GT.SM' => 'San Marcos', 'GT.SR' => 'Santa Rosa', 'GT.SO' => 'Solola', 'GT.SU' => 'Suchitepequez', 'GT.TO' => 'Totonicapan', 'GT.ZA' => 'Zacapa'],
'GW' => ['GW.BA' => 'Bafata', 'GW.BM' => 'Biombo', 'GW.BS' => 'Bissau', 'GW.BL' => 'Bolama', 'GW.CA' => 'Cacheu', 'GW.GA' => 'Gabu', 'GW.OI' => 'Oio', 'GW.QU' => 'Quinara', 'GW.TO' => 'Tombali'],
'GY' => ['GY.BA' => 'Barima-Waini', 'GY.CU' => 'Cuyuni-Mazaruni', 'GY.DE' => 'Demerara-Mahaica', 'GY.EB' => 'East Berbice-Corentyne', 'GY.ES' => 'Essequibo Islands-West Demerara', 'GY.MA' => 'Mahaica-Berbice', 'GY.PM' => 'Pomeroon-Supenaam', 'GY.PT' => 'Potaro-Siparuni', 'GY.UD' => 'Upper Demerara-Berbice', 'GY.UT' => 'Upper Takutu-Upper Essequibo'],
'HN' => ['HN.AT' => 'Atlantida', 'HN.CH' => 'Choluteca', 'HN.CL' => 'Colon', 'HN.CM' => 'Comayagua', 'HN.CP' => 'Copan', 'HN.CR' => 'Cortes', 'HN.EP' => 'El Paraiso', 'HN.FM' => 'Francisco Morazan', 'HN.GD' => 'Gracias a Dios', 'HN.IN' => 'Intibuca', 'HN.IB' => 'Islas de la Bahia', 'HN.LP' => 'La Paz', 'HN.LE' => 'Lempira', 'HN.OC' => 'Ocotepeque', 'HN.OL' => 'Olancho', 'HN.SB' => 'Santa Barbara', 'HN.VA' => 'Valle', 'HN.YO' => 'Yoro'],
'HR' => ['HR.07' => 'Bjelovarsko-bilogorska zupanija', 'HR.12' => 'Brodsko-posavska zupanija', 'HR.19' => 'Dubrovacko-neretvanska zupanija', 'HR.21' => 'Grad Zagreb', 'HR.18' => 'Istarska zupanija', 'HR.04' => 'Karlovacka zupanija', 'HR.06' => 'Koprivnicko-krizevacka zupanija', 'HR.02' => 'Krapinsko-zagorska zupanija', 'HR.09' => 'Licko-senjska zupanija', 'HR.20' => 'Medimurska zupanija', 'HR.14' => 'Osjecko-baranjska zupanija', 'HR.11' => 'Pozesko-slavonska zupanija', 'HR.08' => 'Primorsko-goranska zupanija', 'HR.15' => 'Sibensko-kninska zupanija', 'HR.03' => 'Sisacko-moslavacka zupanija', 'HR.17' => 'Splitsko-dalmatinska zupanija', 'HR.05' => 'Varazdinska zupanija', 'HR.10' => 'Viroviticko-podravska zupanija', 'HR.16' => 'Vukovarsko-srijemska zupanija', 'HR.13' => 'Zadarska zupanija', 'HR.01' => 'Zagrebacka zupanija'],
'HT' => ['HT.AR' => 'Artibonite', 'HT.CE' => 'Centre', 'HT.GA' => 'Grande\'Anse', 'HT.NI' => 'Nippes', 'HT.ND' => 'Nord', 'HT.NE' => 'Nord-Est', 'HT.NO' => 'Nord-Ouest', 'HT.OU' => 'Ouest', 'HT.SD' => 'Sud', 'HT.SE' => 'Sud-Est'],
'HU' => ['HU.BK' => 'Bacs-Kiskun', 'HU.BA' => 'Baranya', 'HU.BE' => 'Bekes', 'HU.BZ' => 'Borsod-Abauj-Zemplen', 'HU.BU' => 'Budapest', 'HU.CS' => 'Csongrad', 'HU.FE' => 'Fejer', 'HU.GS' => 'Gyor-Moson-Sopron', 'HU.HB' => 'Hajdu-Bihar', 'HU.HE' => 'Heves', 'HU.JN' => 'Jasz-Nagykun-Szolnok', 'HU.KE' => 'Komarom-Esztergom', 'HU.NO' => 'Nograd', 'HU.PE' => 'Pest', 'HU.SO' => 'Somogy', 'HU.SZ' => 'Szabolcs-Szatmar-Bereg', 'HU.TO' => 'Tolna', 'HU.VA' => 'Vas', 'HU.VE' => 'Veszprem', 'HU.ZA' => 'Zala'],
'ID' => ['ID.AC' => 'Aceh', 'ID.BA' => 'Bali', 'ID.BT' => 'Banten', 'ID.BE' => 'Bengkulu', 'ID.GO' => 'Gorontalo', 'ID.JK' => 'Jakarta Raya', 'ID.JA' => 'Jambi', 'ID.JB' => 'Jawa Barat', 'ID.JT' => 'Jawa Tengah', 'ID.JI' => 'Jawa Timur', 'ID.KB' => 'Kalimantan Barat', 'ID.KS' => 'Kalimantan Selatan', 'ID.KT' => 'Kalimantan Tengah', 'ID.KI' => 'Kalimantan Timur', 'ID.KU' => 'Kalimantan Utara', 'ID.BB' => 'Kepulauan Bangka Belitung', 'ID.KR' => 'Kepulauan Riau', 'ID.LA' => 'Lampung', 'ID.ML' => 'Maluku', 'ID.MU' => 'Maluku Utara', 'ID.NB' => 'Nusa Tenggara Barat', 'ID.NT' => 'Nusa Tenggara Timur', 'ID.PP' => 'Papua', 'ID.PB' => 'Papua Barat', 'ID.PE' => 'Papua Pengunungan', 'ID.PS' => 'Papua Selatan', 'ID.PT' => 'Papua Tengah', 'ID.RI' => 'Riau', 'ID.SR' => 'Sulawesi Barat', 'ID.SN' => 'Sulawesi Selatan', 'ID.ST' => 'Sulawesi Tengah', 'ID.SG' => 'Sulawesi Tenggara', 'ID.SA' => 'Sulawesi Utara', 'ID.SB' => 'Sumatera Barat', 'ID.SS' => 'Sumatera Selatan', 'ID.SU' => 'Sumatera Utara', 'ID.YO' => 'Yogyakarta'],
'IE' => ['IE.CW' => 'Carlow', 'IE.CN' => 'Cavan', 'IE.CE' => 'Clare', 'IE.CO' => 'Cork', 'IE.DL' => 'Donegal', 'IE.D' => 'Dublin', 'IE.G' => 'Galway', 'IE.KY' => 'Kerry', 'IE.KE' => 'Kildare', 'IE.KK' => 'Kilkenny', 'IE.LS' => 'Laois', 'IE.LM' => 'Leitrim', 'IE.LK' => 'Limerick', 'IE.LD' => 'Longford', 'IE.LH' => 'Louth', 'IE.MO' => 'Mayo', 'IE.MH' => 'Meath', 'IE.MN' => 'Monaghan', 'IE.OY' => 'Offaly', 'IE.RN' => 'Roscommon', 'IE.SO' => 'Sligo', 'IE.TA' => 'Tipperary', 'IE.WD' => 'Waterford', 'IE.WH' => 'Westmeath', 'IE.WX' => 'Wexford', 'IE.WW' => 'Wicklow'],
'IL' => ['IL.D' => 'HaDarom', 'IL.M' => 'HaMerkaz', 'IL.Z' => 'HaTsafon', 'IL.HA' => 'Hefa', 'IL.TA' => 'Tel Aviv', 'IL.JM' => 'Yerushalayim'],
'IN' => ['IN.AN' => 'Andaman and Nicobar Islands', 'IN.AP' => 'Andhra Pradesh', 'IN.AR' => 'Arunachal Pradesh', 'IN.AS' => 'Assam', 'IN.BR' => 'Bihar', 'IN.CH' => 'Chandigarh', 'IN.CT' => 'Chhattisgarh', 'IN.DN' => 'Dadra and Nagar Haveli', 'IN.DH' => 'Dadra and Nagar Haveli and Daman and Diu', 'IN.DL' => 'Delhi', 'IN.GA' => 'Goa', 'IN.GJ' => 'Gujarat', 'IN.HR' => 'Haryana', 'IN.HP' => 'Himachal Pradesh', 'IN.JK' => 'Jammu and Kashmir', 'IN.JH' => 'Jharkhand', 'IN.KA' => 'Karnataka', 'IN.KL' => 'Kerala', 'IN.LA' => 'Ladakh', 'IN.LD' => 'Lakshadweep', 'IN.MP' => 'Madhya Pradesh', 'IN.MH' => 'Maharashtra', 'IN.MN' => 'Manipur', 'IN.ML' => 'Meghalaya', 'IN.MZ' => 'Mizoram', 'IN.NL' => 'Nagaland', 'IN.OR' => 'Odisha', 'IN.PY' => 'Puducherry', 'IN.PB' => 'Punjab', 'IN.RJ' => 'Rajasthan', 'IN.SK' => 'Sikkim', 'IN.TN' => 'Tamil Nadu', 'IN.TG' => 'Telangana', 'IN.TR' => 'Tripura', 'IN.UP' => 'Uttar Pradesh', 'IN.UT' => 'Uttarakhand', 'IN.WB' => 'West Bengal'],
'IQ' => ['IQ.AN' => 'Al Anbar', 'IQ.BA' => 'Al Basrah', 'IQ.MU' => 'Al Muthanna', 'IQ.QA' => 'Al Qadisiyah', 'IQ.NA' => 'An Najaf', 'IQ.AR' => 'Arbil', 'IQ.SU' => 'As Sulaymaniyah', 'IQ.BB' => 'Babil', 'IQ.BG' => 'Baghdad', 'IQ.DA' => 'Dahuk', 'IQ.DQ' => 'Dhi Qar', 'IQ.DI' => 'Diyala', 'IQ.KA' => 'Karbala\'', 'IQ.KI' => 'Kirkuk', 'IQ.MA' => 'Maysan', 'IQ.NI' => 'Ninawa', 'IQ.SD' => 'Salah ad Din', 'IQ.WA' => 'Wasit'],
'IR' => ['IR.32' => 'Alborz', 'IR.03' => 'Ardabil', 'IR.02' => 'Azarbayjan-e Gharbi', 'IR.01' => 'Azarbayjan-e Sharqi', 'IR.06' => 'Bushehr', 'IR.08' => 'Chahar Mahal va Bakhtiari', 'IR.04' => 'Esfahan', 'IR.14' => 'Fars', 'IR.19' => 'Gilan', 'IR.27' => 'Golestan', 'IR.24' => 'Hamadan', 'IR.23' => 'Hormozgan', 'IR.05' => 'Ilam', 'IR.15' => 'Kerman', 'IR.17' => 'Kermanshah', 'IR.29' => 'Khorasan-e Jonubi', 'IR.30' => 'Khorasan-e Razavi', 'IR.31' => 'Khorasan-e Shomali', 'IR.10' => 'Khuzestan', 'IR.18' => 'Kohgiluyeh va Bowyer Ahmad', 'IR.16' => 'Kordestan', 'IR.20' => 'Lorestan', 'IR.22' => 'Markazi', 'IR.21' => 'Mazandaran', 'IR.28' => 'Qazvin', 'IR.26' => 'Qom', 'IR.12' => 'Semnan', 'IR.13' => 'Sistan va Baluchestan', 'IR.07' => 'Tehran', 'IR.25' => 'Yazd', 'IR.11' => 'Zanjan'],
'IS' => ['IS.7' => 'Austurland', 'IS.1' => 'Hofudborgarsvaedi', 'IS.6' => 'Nordurland eystra', 'IS.5' => 'Nordurland vestra', 'IS.8' => 'Sudurland', 'IS.2' => 'Sudurnes', 'IS.4' => 'Vestfirdir', 'IS.3' => 'Vesturland'],
'IT' => ['IT.65' => 'Abruzzo', 'IT.77' => 'Basilicata', 'IT.78' => 'Calabria', 'IT.72' => 'Campania', 'IT.45' => 'Emilia-Romagna', 'IT.36' => 'Friuli-Venezia Giulia', 'IT.62' => 'Lazio', 'IT.42' => 'Liguria', 'IT.25' => 'Lombardia', 'IT.57' => 'Marche', 'IT.67' => 'Molise', 'IT.21' => 'Piemonte', 'IT.75' => 'Puglia', 'IT.88' => 'Sardegna', 'IT.82' => 'Sicilia', 'IT.52' => 'Toscana', 'IT.32' => 'Trentino-Alto Adige', 'IT.55' => 'Umbria', 'IT.23' => 'Valle d\'Aosta', 'IT.34' => 'Veneto'],
'JM' => ['JM.13' => 'Clarendon', 'JM.09' => 'Hanover', 'JM.01' => 'Kingston', 'JM.12' => 'Manchester', 'JM.04' => 'Portland', 'JM.02' => 'Saint Andrew', 'JM.06' => 'Saint Ann', 'JM.14' => 'Saint Catherine', 'JM.11' => 'Saint Elizabeth', 'JM.08' => 'Saint James', 'JM.05' => 'Saint Mary', 'JM.03' => 'Saint Thomas', 'JM.07' => 'Trelawny', 'JM.10' => 'Westmoreland'],
'JO' => ['JO.AJ' => '\'Ajlun', 'JO.AQ' => 'Al \'Aqabah', 'JO.AM' => 'Al \'Asimah', 'JO.BA' => 'Al Balqa\'', 'JO.KA' => 'Al Karak', 'JO.MA' => 'Al Mafraq', 'JO.AT' => 'At Tafilah', 'JO.AZ' => 'Az Zarqa\'', 'JO.IR' => 'Irbid', 'JO.JA' => 'Jarash', 'JO.MN' => 'Ma\'an', 'JO.MD' => 'Madaba'],
'JP' => ['JP.23' => 'Aichi', 'JP.05' => 'Akita', 'JP.02' => 'Aomori', 'JP.12' => 'Chiba', 'JP.38' => 'Ehime', 'JP.18' => 'Fukui', 'JP.40' => 'Fukuoka', 'JP.07' => 'Fukushima', 'JP.21' => 'Gifu', 'JP.10' => 'Gunma', 'JP.34' => 'Hiroshima', 'JP.01' => 'Hokkaido', 'JP.28' => 'Hyogo', 'JP.08' => 'Ibaraki', 'JP.17' => 'Ishikawa', 'JP.03' => 'Iwate', 'JP.37' => 'Kagawa', 'JP.46' => 'Kagoshima', 'JP.14' => 'Kanagawa', 'JP.39' => 'Kochi', 'JP.43' => 'Kumamoto', 'JP.26' => 'Kyoto', 'JP.24' => 'Mie', 'JP.04' => 'Miyagi', 'JP.45' => 'Miyazaki', 'JP.20' => 'Nagano', 'JP.42' => 'Nagasaki', 'JP.29' => 'Nara', 'JP.15' => 'Niigata', 'JP.44' => 'Oita', 'JP.33' => 'Okayama', 'JP.47' => 'Okinawa', 'JP.27' => 'Osaka', 'JP.41' => 'Saga', 'JP.11' => 'Saitama', 'JP.25' => 'Shiga', 'JP.32' => 'Shimane', 'JP.22' => 'Shizuoka', 'JP.09' => 'Tochigi', 'JP.36' => 'Tokushima', 'JP.13' => 'Tokyo', 'JP.31' => 'Tottori', 'JP.16' => 'Toyama', 'JP.30' => 'Wakayama', 'JP.06' => 'Yamagata', 'JP.35' => 'Yamaguchi', 'JP.19' => 'Yamanashi'],
'KE' => ['KE.01' => 'Baringo', 'KE.02' => 'Bomet', 'KE.03' => 'Bungoma', 'KE.04' => 'Busia', 'KE.05' => 'Elgeyo/Marakwet', 'KE.06' => 'Embu', 'KE.07' => 'Garissa', 'KE.08' => 'Homa Bay', 'KE.09' => 'Isiolo', 'KE.10' => 'Kajiado', 'KE.11' => 'Kakamega', 'KE.12' => 'Kericho', 'KE.13' => 'Kiambu', 'KE.14' => 'Kilifi', 'KE.15' => 'Kirinyaga', 'KE.16' => 'Kisii', 'KE.17' => 'Kisumu', 'KE.18' => 'Kitui', 'KE.19' => 'Kwale', 'KE.20' => 'Laikipia', 'KE.21' => 'Lamu', 'KE.22' => 'Machakos', 'KE.23' => 'Makueni', 'KE.24' => 'Mandera', 'KE.25' => 'Marsabit', 'KE.26' => 'Meru', 'KE.27' => 'Migori', 'KE.28' => 'Mombasa', 'KE.29' => 'Murang\'a', 'KE.30' => 'Nairobi City', 'KE.31' => 'Nakuru', 'KE.32' => 'Nandi', 'KE.33' => 'Narok', 'KE.34' => 'Nyamira', 'KE.35' => 'Nyandarua', 'KE.36' => 'Nyeri', 'KE.37' => 'Samburu', 'KE.38' => 'Siaya', 'KE.39' => 'Taita/Taveta', 'KE.40' => 'Tana River', 'KE.41' => 'Tharaka-Nithi', 'KE.42' => 'Trans Nzoia', 'KE.43' => 'Turkana', 'KE.44' => 'Uasin Gishu', 'KE.45' => 'Vihiga', 'KE.46' => 'Wajir', 'KE.47' => 'West Pokot'],
'KG' => ['KG.B' => 'Batken', 'KG.GB' => 'Bishkek Shaary', 'KG.C' => 'Chuy', 'KG.J' => 'Jalal-Abad', 'KG.N' => 'Naryn', 'KG.GO' => 'Osh Shaary', 'KG.T' => 'Talas', 'KG.Y' => 'Ysyk-Kol'],
'KH' => ['KH.2' => 'Baat Dambang', 'KH.1' => 'Banteay Mean Choay', 'KH.23' => 'Kaeb', 'KH.3' => 'Kampong Chaam', 'KH.4' => 'Kampong Chhnang', 'KH.5' => 'Kampong Spueu', 'KH.6' => 'Kampong Thum', 'KH.7' => 'Kampot', 'KH.8' => 'Kandaal', 'KH.9' => 'Kaoh Kong', 'KH.10' => 'Kracheh', 'KH.11' => 'Mondol Kiri', 'KH.22' => 'Otdar Mean Chey', 'KH.24' => 'Pailin', 'KH.12' => 'Phnom Penh', 'KH.15' => 'Pousaat', 'KH.18' => 'Preah Sihanouk', 'KH.13' => 'Preah Vihear', 'KH.14' => 'Prey Veaeng', 'KH.16' => 'Rotanak Kiri', 'KH.17' => 'Siem Reab', 'KH.19' => 'Stueng Traeng', 'KH.20' => 'Svaay Rieng', 'KH.21' => 'Taakaev', 'KH.25' => 'Tbong Khmum'],
'KI' => ['KI.G' => 'Gilbert Islands', 'KI.L' => 'Line Islands', 'KI.P' => 'Phoenix Islands'],
'KM' => ['KM.A' => 'Anjouan', 'KM.G' => 'Grande Comore', 'KM.M' => 'Moheli'],
'KN' => ['KN.01' => 'Christ Church Nichola Town', 'KN.02' => 'Saint Anne Sandy Point', 'KN.03' => 'Saint George Basseterre', 'KN.04' => 'Saint George Gingerland', 'KN.05' => 'Saint James Windward', 'KN.06' => 'Saint John Capisterre', 'KN.07' => 'Saint John Figtree', 'KN.08' => 'Saint Mary Cayon', 'KN.09' => 'Saint Paul Capisterre', 'KN.10' => 'Saint Paul Charlestown', 'KN.11' => 'Saint Peter Basseterre', 'KN.12' => 'Saint Thomas Lowland', 'KN.13' => 'Saint Thomas Middle Island', 'KN.15' => 'Trinity Palmetto Point'],
'KP' => ['KP.04' => 'Chagang-do', 'KP.09' => 'Hamgyong-bukto', 'KP.08' => 'Hamgyong-namdo', 'KP.06' => 'Hwanghae-bukto', 'KP.05' => 'Hwanghae-namdo', 'KP.07' => 'Kangwon-do', 'KP.03' => 'P\'yongan-bukto', 'KP.02' => 'P\'yongan-namdo', 'KP.01' => 'P\'yongyang', 'KP.13' => 'Rason', 'KP.10' => 'Ryanggang-do'],
'KR' => ['KR.26' => 'Busan-gwangyeoksi', 'KR.43' => 'Chungcheongbuk-do', 'KR.44' => 'Chungcheongnam-do', 'KR.27' => 'Daegu-gwangyeoksi', 'KR.30' => 'Daejeon-gwangyeoksi', 'KR.42' => 'Gangwon-do', 'KR.29' => 'Gwangju-gwangyeoksi', 'KR.41' => 'Gyeonggi-do', 'KR.47' => 'Gyeongsangbuk-do', 'KR.48' => 'Gyeongsangnam-do', 'KR.28' => 'Incheon-gwangyeoksi', 'KR.49' => 'Jeju-teukbyeoljachido', 'KR.45' => 'Jeollabuk-do', 'KR.46' => 'Jeollanam-do', 'KR.11' => 'Seoul-teukbyeolsi', 'KR.31' => 'Ulsan-gwangyeoksi'],
'KW' => ['KW.KU' => 'Al \'Asimah', 'KW.AH' => 'Al Ahmadi', 'KW.FA' => 'Al Farwaniyah', 'KW.JA' => 'Al Jahra\'', 'KW.HA' => 'Hawalli', 'KW.MU' => 'Mubarak al Kabir'],
'KZ' => ['KZ.10' => 'Abay oblysy', 'KZ.75' => 'Almaty', 'KZ.19' => 'Almaty oblysy', 'KZ.11' => 'Aqmola oblysy', 'KZ.15' => 'Aqtobe oblysy', 'KZ.71' => 'Astana', 'KZ.23' => 'Atyrau oblysy', 'KZ.27' => 'Batys Qazaqstan oblysy', 'KZ.47' => 'Mangghystau oblysy', 'KZ.55' => 'Pavlodar oblysy', 'KZ.35' => 'Qaraghandy oblysy', 'KZ.39' => 'Qostanay oblysy', 'KZ.43' => 'Qyzylorda oblysy', 'KZ.63' => 'Shyghys Qazaqstan oblysy', 'KZ.79' => 'Shymkent', 'KZ.59' => 'Soltustik Qazaqstan oblysy', 'KZ.61' => 'Turkistan oblysy', 'KZ.62' => 'Ulytau oblysy', 'KZ.31' => 'Zhambyl oblysy', 'KZ.33' => 'Zhetisu oblysy'],
'LA' => ['LA.AT' => 'Attapu', 'LA.BK' => 'Bokeo', 'LA.BL' => 'Bolikhamxai', 'LA.CH' => 'Champasak', 'LA.HO' => 'Houaphan', 'LA.KH' => 'Khammouan', 'LA.LM' => 'Louang Namtha', 'LA.LP' => 'Louangphabang', 'LA.OU' => 'Oudomxai', 'LA.PH' => 'Phongsali', 'LA.SL' => 'Salavan', 'LA.SV' => 'Savannakhet', 'LA.VI' => 'Viangchan', 'LA.XA' => 'Xaignabouli', 'LA.XS' => 'Xaisomboun', 'LA.XE' => 'Xekong', 'LA.XI' => 'Xiangkhouang'],
'LB' => ['LB.AK' => 'Aakkar', 'LB.BH' => 'Baalbek-Hermel', 'LB.BI' => 'Beqaa', 'LB.BA' => 'Beyrouth', 'LB.AS' => 'Liban-Nord', 'LB.JA' => 'Liban-Sud', 'LB.JL' => 'Mont-Liban', 'LB.NA' => 'Nabatiye'],
'LC' => ['LC.01' => 'Anse la Raye', 'LC.12' => 'Canaries', 'LC.02' => 'Castries', 'LC.03' => 'Choiseul', 'LC.05' => 'Dennery', 'LC.06' => 'Gros Islet', 'LC.07' => 'Laborie', 'LC.08' => 'Micoud', 'LC.10' => 'Soufriere', 'LC.11' => 'Vieux Fort'],
'LI' => ['LI.01' => 'Balzers', 'LI.02' => 'Eschen', 'LI.03' => 'Gamprin', 'LI.04' => 'Mauren', 'LI.05' => 'Planken', 'LI.06' => 'Ruggell', 'LI.07' => 'Schaan', 'LI.08' => 'Schellenberg', 'LI.09' => 'Triesen', 'LI.10' => 'Triesenberg', 'LI.11' => 'Vaduz'],
'LK' => ['LK.2' => 'Central Province', 'LK.5' => 'Eastern Province', 'LK.7' => 'North Central Province', 'LK.6' => 'North Western Province', 'LK.4' => 'Northern Province', 'LK.9' => 'Sabaragamuwa Province', 'LK.3' => 'Southern Province', 'LK.8' => 'Uva Province', 'LK.1' => 'Western Province'],
'LR' => ['LR.BM' => 'Bomi', 'LR.BG' => 'Bong', 'LR.GP' => 'Gbarpolu', 'LR.GB' => 'Grand Bassa', 'LR.CM' => 'Grand Cape Mount', 'LR.GG' => 'Grand Gedeh', 'LR.GK' => 'Grand Kru', 'LR.LO' => 'Lofa', 'LR.MG' => 'Margibi', 'LR.MY' => 'Maryland', 'LR.MO' => 'Montserrado', 'LR.NI' => 'Nimba', 'LR.RI' => 'River Cess', 'LR.RG' => 'River Gee', 'LR.SI' => 'Sinoe'],
'LS' => ['LS.D' => 'Berea', 'LS.B' => 'Botha-Bothe', 'LS.C' => 'Leribe', 'LS.E' => 'Mafeteng', 'LS.A' => 'Maseru', 'LS.F' => 'Mohale\'s Hoek', 'LS.J' => 'Mokhotlong', 'LS.H' => 'Qacha\'s Nek', 'LS.G' => 'Quthing', 'LS.K' => 'Thaba-Tseka'],
'LT' => ['LT.AL' => 'Alytaus apskritis', 'LT.KU' => 'Kauno apskritis', 'LT.KL' => 'Klaipedos apskritis', 'LT.MR' => 'Marijampoles apskritis', 'LT.PN' => 'Panevezio apskritis', 'LT.SA' => 'Siauliu apskritis', 'LT.TA' => 'Taurages apskritis', 'LT.TE' => 'Telsiu apskritis', 'LT.UT' => 'Utenos apskritis', 'LT.VL' => 'Vilniaus apskritis'],
'LU' => ['LU.CA' => 'Capellen', 'LU.CL' => 'Clervaux', 'LU.DI' => 'Diekirch', 'LU.EC' => 'Echternach', 'LU.ES' => 'Esch-sur-Alzette', 'LU.GR' => 'Grevenmacher', 'LU.LU' => 'Luxembourg', 'LU.ME' => 'Mersch', 'LU.RD' => 'Redange', 'LU.RM' => 'Remich', 'LU.VD' => 'Vianden', 'LU.WI' => 'Wiltz'],
'LV' => ['LV.011' => 'Adazu novads', 'LV.002' => 'Aizkraukles novads', 'LV.007' => 'Aluksnes novads', 'LV.111' => 'Augsdaugavas novads', 'LV.015' => 'Balvu novads', 'LV.016' => 'Bauskas novads', 'LV.022' => 'Cesu novads', 'LV.DGV' => 'Daugavpils', 'LV.112' => 'Dienvidkurzemes novads', 'LV.026' => 'Dobeles novads', 'LV.033' => 'Gulbenes novads', 'LV.042' => 'Jekabpils novads', 'LV.JEL' => 'Jelgava', 'LV.041' => 'Jelgavas novads', 'LV.JUR' => 'Jurmala', 'LV.052' => 'Kekavas novads', 'LV.047' => 'Kraslavas novads', 'LV.050' => 'Kuldigas novads', 'LV.LPX' => 'Liepaja', 'LV.054' => 'Limbazu novads', 'LV.056' => 'Livanu novads', 'LV.058' => 'Ludzas novads', 'LV.059' => 'Madonas novads', 'LV.062' => 'Marupes novads', 'LV.067' => 'Ogres novads', 'LV.068' => 'Olaines novads', 'LV.073' => 'Preilu novads', 'LV.REZ' => 'Rezekne', 'LV.077' => 'Rezeknes novads', 'LV.RIX' => 'Riga', 'LV.080' => 'Ropazu novads', 'LV.087' => 'Salaspils novads', 'LV.088' => 'Saldus novads', 'LV.089' => 'Saulkrastu novads', 'LV.091' => 'Siguldas novads', 'LV.094' => 'Smiltenes novads', 'LV.097' => 'Talsu novads', 'LV.099' => 'Tukuma novads', 'LV.101' => 'Valkas novads', 'LV.113' => 'Valmieras novads', 'LV.102' => 'Varaklanu novads', 'LV.VEN' => 'Ventspils', 'LV.106' => 'Ventspils novads'],
'LY' => ['LY.BU' => 'Al Butnan', 'LY.JA' => 'Al Jabal al Akhdar', 'LY.JG' => 'Al Jabal al Gharbi', 'LY.JI' => 'Al Jafarah', 'LY.JU' => 'Al Jufrah', 'LY.KF' => 'Al Kufrah', 'LY.MJ' => 'Al Marj', 'LY.MB' => 'Al Marqab', 'LY.WA' => 'Al Wahat', 'LY.NQ' => 'An Nuqat al Khams', 'LY.ZA' => 'Az Zawiyah', 'LY.BA' => 'Banghazi', 'LY.DR' => 'Darnah', 'LY.GT' => 'Ghat', 'LY.MI' => 'Misratah', 'LY.MQ' => 'Murzuq', 'LY.NL' => 'Nalut', 'LY.SB' => 'Sabha', 'LY.SR' => 'Surt', 'LY.TB' => 'Tarabulus', 'LY.WD' => 'Wadi al Hayat', 'LY.WS' => 'Wadi ash Shati\''],
'MA' => ['MA.05' => 'Beni-Mellal-Khenifra', 'MA.06' => 'Casablanca-Settat', 'MA.12' => 'Dakhla-Oued Ed-Dahab (EH)', 'MA.08' => 'Draa-Tafilalet', 'MA.03' => 'Fes- Meknes', 'MA.10' => 'Guelmim-Oued Noun (EH-partial)', 'MA.02' => 'L\'Oriental', 'MA.11' => 'Laayoune-Sakia El Hamra (EH-partial)', 'MA.07' => 'Marrakech-Safi', 'MA.04' => 'Rabat-Sale-Kenitra', 'MA.09' => 'Souss-Massa', 'MA.01' => 'Tanger-Tetouan-Al Hoceima'],
'MC' => ['MC.FO' => 'Fontvieille', 'MC.JE' => 'Jardin Exotique', 'MC.CL' => 'La Colle', 'MC.CO' => 'La Condamine', 'MC.GA' => 'La Gare', 'MC.SO' => 'La Source', 'MC.LA' => 'Larvotto', 'MC.MA' => 'Malbousquet', 'MC.MO' => 'Monaco-Ville', 'MC.MG' => 'Moneghetti', 'MC.MC' => 'Monte-Carlo', 'MC.MU' => 'Moulins', 'MC.PH' => 'Port-Hercule', 'MC.SR' => 'Saint-Roman', 'MC.SD' => 'Sainte-Devote', 'MC.SP' => 'Spelugues', 'MC.VR' => 'Vallon de la Rousse'],
'MD' => ['MD.AN' => 'Anenii Noi', 'MD.BA' => 'Balti', 'MD.BS' => 'Basarabeasca', 'MD.BD' => 'Bender', 'MD.BR' => 'Briceni', 'MD.CA' => 'Cahul', 'MD.CL' => 'Calarasi', 'MD.CT' => 'Cantemir', 'MD.CS' => 'Causeni', 'MD.CU' => 'Chisinau', 'MD.CM' => 'Cimislia', 'MD.CR' => 'Criuleni', 'MD.DO' => 'Donduseni', 'MD.DR' => 'Drochia', 'MD.DU' => 'Dubasari', 'MD.ED' => 'Edinet', 'MD.FA' => 'Falesti', 'MD.FL' => 'Floresti', 'MD.GA' => 'Gagauzia, Unitatea teritoriala autonoma', 'MD.GL' => 'Glodeni', 'MD.HI' => 'Hincesti', 'MD.IA' => 'Ialoveni', 'MD.LE' => 'Leova', 'MD.NI' => 'Nisporeni', 'MD.OC' => 'Ocnita', 'MD.OR' => 'Orhei', 'MD.RE' => 'Rezina', 'MD.RI' => 'Riscani', 'MD.SI' => 'Singerei', 'MD.SD' => 'Soldanesti', 'MD.SO' => 'Soroca', 'MD.SV' => 'Stefan Voda', 'MD.SN' => 'Stinga Nistrului, unitatea teritoriala din', 'MD.ST' => 'Straseni', 'MD.TA' => 'Taraclia', 'MD.TE' => 'Telenesti', 'MD.UN' => 'Ungheni'],
'ME' => ['ME.01' => 'Andrijevica', 'ME.02' => 'Bar', 'ME.03' => 'Berane', 'ME.04' => 'Bijelo Polje', 'ME.05' => 'Budva', 'ME.06' => 'Cetinje', 'ME.07' => 'Danilovgrad', 'ME.22' => 'Gusinje', 'ME.08' => 'Herceg-Novi', 'ME.09' => 'Kolasin', 'ME.10' => 'Kotor', 'ME.11' => 'Mojkovac', 'ME.12' => 'Niksic', 'ME.23' => 'Petnjica', 'ME.13' => 'Plav', 'ME.14' => 'Pljevlja', 'ME.15' => 'Pluzine', 'ME.16' => 'Podgorica', 'ME.17' => 'Rozaje', 'ME.18' => 'Savnik', 'ME.19' => 'Tivat', 'ME.24' => 'Tuzi', 'ME.20' => 'Ulcinj', 'ME.21' => 'Zabljak'],
'MG' => ['MG.T' => 'Antananarivo', 'MG.D' => 'Antsiranana', 'MG.F' => 'Fianarantsoa', 'MG.M' => 'Mahajanga', 'MG.A' => 'Toamasina', 'MG.U' => 'Toliara'],
'MH' => ['MH.ALL' => 'Ailinglaplap', 'MH.ALK' => 'Ailuk', 'MH.ARN' => 'Arno', 'MH.AUR' => 'Aur', 'MH.KIL' => 'Bikini & Kili', 'MH.EBO' => 'Ebon', 'MH.ENI' => 'Enewetak & Ujelang', 'MH.JAB' => 'Jabat', 'MH.JAL' => 'Jaluit', 'MH.KWA' => 'Kwajalein', 'MH.LAE' => 'Lae', 'MH.LIB' => 'Lib', 'MH.LIK' => 'Likiep', 'MH.MAJ' => 'Majuro', 'MH.MAL' => 'Maloelap', 'MH.MEJ' => 'Mejit', 'MH.MIL' => 'Mili', 'MH.NMK' => 'Namdrik', 'MH.NMU' => 'Namu', 'MH.RON' => 'Rongelap', 'MH.UJA' => 'Ujae', 'MH.UTI' => 'Utrik', 'MH.WTH' => 'Wotho', 'MH.WTJ' => 'Wotje'],
'MK' => ['MK.801' => 'Aerodrom', 'MK.802' => 'Aracinovo', 'MK.201' => 'Berovo', 'MK.501' => 'Bitola', 'MK.401' => 'Bogdanci', 'MK.601' => 'Bogovinje', 'MK.402' => 'Bosilovo', 'MK.602' => 'Brvenica', 'MK.803' => 'Butel', 'MK.815' => 'Cair', 'MK.109' => 'Caska', 'MK.814' => 'Centar', 'MK.313' => 'Centar Zupa', 'MK.210' => 'Cesinovo-Oblesevo', 'MK.816' => 'Cucer Sandevo', 'MK.303' => 'Debar', 'MK.304' => 'Debarca', 'MK.203' => 'Delcevo', 'MK.502' => 'Demir Hisar', 'MK.103' => 'Demir Kapija', 'MK.406' => 'Dojran', 'MK.503' => 'Dolneni', 'MK.804' => 'Gazi Baba', 'MK.405' => 'Gevgelija', 'MK.805' => 'Gjorce Petrov', 'MK.604' => 'Gostivar', 'MK.102' => 'Gradsko', 'MK.807' => 'Ilinden', 'MK.606' => 'Jegunovce', 'MK.205' => 'Karbinci', 'MK.808' => 'Karpos', 'MK.104' => 'Kavadarci', 'MK.307' => 'Kicevo', 'MK.809' => 'Kisela Voda', 'MK.206' => 'Kocani', 'MK.407' => 'Konce', 'MK.701' => 'Kratovo', 'MK.702' => 'Kriva Palanka', 'MK.504' => 'Krivogastani', 'MK.505' => 'Krusevo', 'MK.703' => 'Kumanovo', 'MK.704' => 'Lipkovo', 'MK.105' => 'Lozovo', 'MK.207' => 'Makedonska Kamenica', 'MK.308' => 'Makedonski Brod', 'MK.607' => 'Mavrovo i Rostusa', 'MK.506' => 'Mogila', 'MK.106' => 'Negotino', 'MK.507' => 'Novaci', 'MK.408' => 'Novo Selo', 'MK.310' => 'Ohrid', 'MK.208' => 'Pehcevo', 'MK.810' => 'Petrovec', 'MK.311' => 'Plasnica', 'MK.508' => 'Prilep', 'MK.209' => 'Probistip', 'MK.409' => 'Radovis', 'MK.705' => 'Rankovce', 'MK.509' => 'Resen', 'MK.107' => 'Rosoman', 'MK.811' => 'Saraj', 'MK.812' => 'Sopiste', 'MK.706' => 'Staro Nagoricane', 'MK.211' => 'Stip', 'MK.312' => 'Struga', 'MK.410' => 'Strumica', 'MK.813' => 'Studenicani', 'MK.817' => 'Suto Orizari', 'MK.108' => 'Sveti Nikole', 'MK.608' => 'Tearce', 'MK.609' => 'Tetovo', 'MK.403' => 'Valandovo', 'MK.404' => 'Vasilevo', 'MK.101' => 'Veles', 'MK.301' => 'Vevcani', 'MK.202' => 'Vinica', 'MK.603' => 'Vrapciste', 'MK.806' => 'Zelenikovo', 'MK.605' => 'Zelino', 'MK.204' => 'Zrnovci'],
'ML' => ['ML.BKO' => 'Bamako', 'ML.7' => 'Gao', 'ML.1' => 'Kayes', 'ML.8' => 'Kidal', 'ML.2' => 'Koulikoro', 'ML.9' => 'Menaka', 'ML.5' => 'Mopti', 'ML.4' => 'Segou', 'ML.3' => 'Sikasso', 'ML.10' => 'Taoudenit', 'ML.6' => 'Tombouctou'],
'MM' => ['MM.07' => 'Ayeyarwady', 'MM.02' => 'Bago', 'MM.14' => 'Chin', 'MM.11' => 'Kachin', 'MM.12' => 'Kayah', 'MM.13' => 'Kayin', 'MM.03' => 'Magway', 'MM.04' => 'Mandalay', 'MM.15' => 'Mon', 'MM.18' => 'Nay Pyi Taw', 'MM.16' => 'Rakhine', 'MM.01' => 'Sagaing', 'MM.17' => 'Shan', 'MM.05' => 'Tanintharyi', 'MM.06' => 'Yangon'],
'MN' => ['MN.073' => 'Arhangay', 'MN.071' => 'Bayan-Olgiy', 'MN.069' => 'Bayanhongor', 'MN.067' => 'Bulgan', 'MN.037' => 'Darhan uul', 'MN.061' => 'Dornod', 'MN.063' => 'Dornogovi', 'MN.059' => 'Dundgovi', 'MN.057' => 'Dzavhan', 'MN.065' => 'Govi-Altay', 'MN.064' => 'Govi-Sumber', 'MN.039' => 'Hentiy', 'MN.043' => 'Hovd', 'MN.041' => 'Hovsgol', 'MN.053' => 'Omnogovi', 'MN.035' => 'Orhon', 'MN.055' => 'Ovorhangay', 'MN.049' => 'Selenge', 'MN.051' => 'Suhbaatar', 'MN.047' => 'Tov', 'MN.1' => 'Ulaanbaatar', 'MN.046' => 'Uvs'],
'MR' => ['MR.07' => 'Adrar', 'MR.03' => 'Assaba', 'MR.05' => 'Brakna', 'MR.08' => 'Dakhlet Nouadhibou', 'MR.04' => 'Gorgol', 'MR.10' => 'Guidimaka', 'MR.01' => 'Hodh ech Chargui', 'MR.02' => 'Hodh el Gharbi', 'MR.12' => 'Inchiri', 'MR.13' => 'Nouakchott Ouest', 'MR.15' => 'Nouakchott Sud', 'MR.09' => 'Tagant', 'MR.11' => 'Tiris Zemmour', 'MR.06' => 'Trarza'],
'MT' => ['MT.01' => 'Attard', 'MT.02' => 'Balzan', 'MT.03' => 'Birgu', 'MT.04' => 'Birkirkara', 'MT.05' => 'Birzebbuga', 'MT.06' => 'Bormla', 'MT.07' => 'Dingli', 'MT.08' => 'Fgura', 'MT.09' => 'Floriana', 'MT.10' => 'Fontana', 'MT.13' => 'Ghajnsielem', 'MT.14' => 'Gharb', 'MT.15' => 'Gharghur', 'MT.16' => 'Ghasri', 'MT.17' => 'Ghaxaq', 'MT.11' => 'Gudja', 'MT.12' => 'Gzira', 'MT.18' => 'Hamrun', 'MT.19' => 'Iklin', 'MT.20' => 'Isla', 'MT.21' => 'Kalkara', 'MT.22' => 'Kercem', 'MT.23' => 'Kirkop', 'MT.24' => 'Lija', 'MT.25' => 'Luqa', 'MT.26' => 'Marsa', 'MT.27' => 'Marsaskala', 'MT.28' => 'Marsaxlokk', 'MT.29' => 'Mdina', 'MT.30' => 'Mellieha', 'MT.31' => 'Mgarr', 'MT.32' => 'Mosta', 'MT.33' => 'Mqabba', 'MT.34' => 'Msida', 'MT.35' => 'Mtarfa', 'MT.36' => 'Munxar', 'MT.37' => 'Nadur', 'MT.38' => 'Naxxar', 'MT.39' => 'Paola', 'MT.40' => 'Pembroke', 'MT.41' => 'Pieta', 'MT.42' => 'Qala', 'MT.43' => 'Qormi', 'MT.44' => 'Qrendi', 'MT.45' => 'Rabat Gozo', 'MT.46' => 'Rabat Malta', 'MT.47' => 'Safi', 'MT.49' => 'Saint John', 'MT.48' => 'Saint Julian\'s', 'MT.50' => 'Saint Lawrence', 'MT.53' => 'Saint Lucia\'s', 'MT.51' => 'Saint Paul\'s Bay', 'MT.52' => 'Sannat', 'MT.54' => 'Santa Venera', 'MT.55' => 'Siggiewi', 'MT.56' => 'Sliema', 'MT.57' => 'Swieqi', 'MT.58' => 'Ta\' Xbiex', 'MT.59' => 'Tarxien', 'MT.60' => 'Valletta', 'MT.61' => 'Xaghra', 'MT.62' => 'Xewkija', 'MT.63' => 'Xghajra', 'MT.64' => 'Zabbar', 'MT.65' => 'Zebbug Gozo', 'MT.66' => 'Zebbug Malta', 'MT.67' => 'Zejtun', 'MT.68' => 'Zurrieq'],
'MU' => ['MU.AG' => 'Agalega Islands', 'MU.BL' => 'Black River', 'MU.CC' => 'Cargados Carajos Shoals', 'MU.FL' => 'Flacq', 'MU.GP' => 'Grand Port', 'MU.MO' => 'Moka', 'MU.PA' => 'Pamplemousses', 'MU.PW' => 'Plaines Wilhems', 'MU.PL' => 'Port Louis', 'MU.RR' => 'Riviere du Rempart', 'MU.RO' => 'Rodrigues Islands', 'MU.SA' => 'Savanne'],
'MV' => ['MV.01' => 'Addu City', 'MV.03' => 'Faadhippolhu', 'MV.04' => 'Felidhu Atoll', 'MV.29' => 'Fuvammulah', 'MV.05' => 'Hahdhunmathi', 'MV.08' => 'Kolhumadulu', 'MV.MLE' => 'Male', 'MV.12' => 'Mulaku Atoll', 'MV.02' => 'North Ari Atoll', 'MV.27' => 'North Huvadhu Atoll', 'MV.13' => 'North Maalhosmadulu', 'MV.24' => 'North Miladhunmadulu', 'MV.14' => 'North Nilandhe Atoll', 'MV.07' => 'North Thiladhunmathi', 'MV.00' => 'South Ari Atoll', 'MV.28' => 'South Huvadhu Atoll', 'MV.20' => 'South Maalhosmadulu', 'MV.25' => 'South Miladhunmadulu', 'MV.17' => 'South Nilandhe Atoll', 'MV.23' => 'South Thiladhunmathi'],
'MW' => ['MW.BA' => 'Balaka', 'MW.BL' => 'Blantyre', 'MW.CK' => 'Chikwawa', 'MW.CR' => 'Chiradzulu', 'MW.CT' => 'Chitipa', 'MW.DE' => 'Dedza', 'MW.DO' => 'Dowa', 'MW.KR' => 'Karonga', 'MW.KS' => 'Kasungu', 'MW.LK' => 'Likoma', 'MW.LI' => 'Lilongwe', 'MW.MH' => 'Machinga', 'MW.MG' => 'Mangochi', 'MW.MC' => 'Mchinji', 'MW.MU' => 'Mulanje', 'MW.MW' => 'Mwanza', 'MW.MZ' => 'Mzimba', 'MW.NE' => 'Neno', 'MW.NB' => 'Nkhata Bay', 'MW.NK' => 'Nkhotakota', 'MW.NS' => 'Nsanje', 'MW.NU' => 'Ntcheu', 'MW.NI' => 'Ntchisi', 'MW.PH' => 'Phalombe', 'MW.RU' => 'Rumphi', 'MW.SA' => 'Salima', 'MW.TH' => 'Thyolo', 'MW.ZO' => 'Zomba'],
'MX' => ['MX.AGU' => 'Aguascalientes', 'MX.BCN' => 'Baja California', 'MX.BCS' => 'Baja California Sur', 'MX.CAM' => 'Campeche', 'MX.CHP' => 'Chiapas', 'MX.CHH' => 'Chihuahua', 'MX.CMX' => 'Ciudad de Mexico', 'MX.COA' => 'Coahuila de Zaragoza', 'MX.COL' => 'Colima', 'MX.DUR' => 'Durango', 'MX.GUA' => 'Guanajuato', 'MX.GRO' => 'Guerrero', 'MX.HID' => 'Hidalgo', 'MX.JAL' => 'Jalisco', 'MX.MEX' => 'Mexico', 'MX.MIC' => 'Michoacan de Ocampo', 'MX.MOR' => 'Morelos', 'MX.NAY' => 'Nayarit', 'MX.NLE' => 'Nuevo Leon', 'MX.OAX' => 'Oaxaca', 'MX.PUE' => 'Puebla', 'MX.QUE' => 'Queretaro', 'MX.ROO' => 'Quintana Roo', 'MX.SLP' => 'San Luis Potosi', 'MX.SIN' => 'Sinaloa', 'MX.SON' => 'Sonora', 'MX.TAB' => 'Tabasco', 'MX.TAM' => 'Tamaulipas', 'MX.TLA' => 'Tlaxcala', 'MX.VER' => 'Veracruz de Ignacio de la Llave', 'MX.YUC' => 'Yucatan', 'MX.ZAC' => 'Zacatecas'],
'MY' => ['MY.01' => 'Johor', 'MY.02' => 'Kedah', 'MY.03' => 'Kelantan', 'MY.04' => 'Melaka', 'MY.05' => 'Negeri Sembilan', 'MY.06' => 'Pahang', 'MY.08' => 'Perak', 'MY.09' => 'Perlis', 'MY.07' => 'Pulau Pinang', 'MY.12' => 'Sabah', 'MY.13' => 'Sarawak', 'MY.10' => 'Selangor', 'MY.11' => 'Terengganu', 'MY.14' => 'Wilayah Persekutuan Kuala Lumpur', 'MY.15' => 'Wilayah Persekutuan Labuan', 'MY.16' => 'Wilayah Persekutuan Putrajaya'],
'MZ' => ['MZ.P' => 'Cabo Delgado', 'MZ.G' => 'Gaza', 'MZ.I' => 'Inhambane', 'MZ.B' => 'Manica', 'MZ.L' => 'Maputo', 'MZ.N' => 'Nampula', 'MZ.A' => 'Niassa', 'MZ.S' => 'Sofala', 'MZ.T' => 'Tete', 'MZ.Q' => 'Zambezia'],
'NA' => ['NA.ER' => 'Erongo', 'NA.HA' => 'Hardap', 'NA.KA' => 'Karas', 'NA.KE' => 'Kavango East', 'NA.KW' => 'Kavango West', 'NA.KH' => 'Khomas', 'NA.KU' => 'Kunene', 'NA.OW' => 'Ohangwena', 'NA.OH' => 'Omaheke', 'NA.OS' => 'Omusati', 'NA.ON' => 'Oshana', 'NA.OT' => 'Oshikoto', 'NA.OD' => 'Otjozondjupa', 'NA.CA' => 'Zambezi'],
'NE' => ['NE.1' => 'Agadez', 'NE.2' => 'Diffa', 'NE.3' => 'Dosso', 'NE.4' => 'Maradi', 'NE.8' => 'Niamey', 'NE.5' => 'Tahoua', 'NE.6' => 'Tillaberi', 'NE.7' => 'Zinder'],
'NG' => ['NG.AB' => 'Abia', 'NG.FC' => 'Abuja Federal Capital Territory', 'NG.AD' => 'Adamawa', 'NG.AK' => 'Akwa Ibom', 'NG.AN' => 'Anambra', 'NG.BA' => 'Bauchi', 'NG.BY' => 'Bayelsa', 'NG.BE' => 'Benue', 'NG.BO' => 'Borno', 'NG.CR' => 'Cross River', 'NG.DE' => 'Delta', 'NG.EB' => 'Ebonyi', 'NG.ED' => 'Edo', 'NG.EK' => 'Ekiti', 'NG.EN' => 'Enugu', 'NG.GO' => 'Gombe', 'NG.IM' => 'Imo', 'NG.JI' => 'Jigawa', 'NG.KD' => 'Kaduna', 'NG.KN' => 'Kano', 'NG.KT' => 'Katsina', 'NG.KE' => 'Kebbi', 'NG.KO' => 'Kogi', 'NG.KW' => 'Kwara', 'NG.LA' => 'Lagos', 'NG.NA' => 'Nasarawa', 'NG.NI' => 'Niger', 'NG.OG' => 'Ogun', 'NG.ON' => 'Ondo', 'NG.OS' => 'Osun', 'NG.OY' => 'Oyo', 'NG.PL' => 'Plateau', 'NG.RI' => 'Rivers', 'NG.SO' => 'Sokoto', 'NG.TA' => 'Taraba', 'NG.YO' => 'Yobe', 'NG.ZA' => 'Zamfara'],
'NI' => ['NI.BO' => 'Boaco', 'NI.CA' => 'Carazo', 'NI.CI' => 'Chinandega', 'NI.CO' => 'Chontales', 'NI.AN' => 'Costa Caribe Norte', 'NI.AS' => 'Costa Caribe Sur', 'NI.ES' => 'Esteli', 'NI.GR' => 'Granada', 'NI.JI' => 'Jinotega', 'NI.LE' => 'Leon', 'NI.MD' => 'Madriz', 'NI.MN' => 'Managua', 'NI.MS' => 'Masaya', 'NI.MT' => 'Matagalpa', 'NI.NS' => 'Nueva Segovia', 'NI.SJ' => 'Rio San Juan', 'NI.RI' => 'Rivas'],
'NL' => ['NL.DR' => 'Drenthe', 'NL.FL' => 'Flevoland', 'NL.FR' => 'Fryslan', 'NL.GE' => 'Gelderland', 'NL.GR' => 'Groningen', 'NL.LI' => 'Limburg', 'NL.NB' => 'Noord-Brabant', 'NL.NH' => 'Noord-Holland', 'NL.OV' => 'Overijssel', 'NL.UT' => 'Utrecht', 'NL.ZE' => 'Zeeland', 'NL.ZH' => 'Zuid-Holland'],
'NO' => ['NO.42' => 'Agder', 'NO.34' => 'Innlandet', 'NO.22' => 'Jan Mayen (Arctic Region)', 'NO.15' => 'More og Romsdal', 'NO.18' => 'Nordland', 'NO.03' => 'Oslo', 'NO.11' => 'Rogaland', 'NO.21' => 'Svalbard (Arctic Region)', 'NO.50' => 'Troendelag', 'NO.54' => 'Troms og Finnmark', 'NO.50' => 'Trondelag', 'NO.38' => 'Vestfold og Telemark', 'NO.46' => 'Vestland', 'NO.30' => 'Viken'],
'NP' => ['NP.BA' => 'Bagmati', 'NP.BH' => 'Bheri', 'NP.DH' => 'Dhawalagiri', 'NP.GA' => 'Gandaki', 'NP.JA' => 'Janakpur', 'NP.KA' => 'Karnali', 'NP.KO' => 'Kosi', 'NP.LU' => 'Lumbini', 'NP.MA' => 'Mahakali', 'NP.ME' => 'Mechi', 'NP.NA' => 'Narayani', 'NP.RA' => 'Rapti', 'NP.SA' => 'Sagarmatha', 'NP.SE' => 'Seti'],
'NR' => ['NR.01' => 'Aiwo', 'NR.02' => 'Anabar', 'NR.03' => 'Anetan', 'NR.04' => 'Anibare', 'NR.05' => 'Baitsi', 'NR.06' => 'Boe', 'NR.07' => 'Buada', 'NR.08' => 'Denigomodu', 'NR.09' => 'Ewa', 'NR.10' => 'Ijuw', 'NR.11' => 'Meneng', 'NR.12' => 'Nibok', 'NR.13' => 'Uaboe', 'NR.14' => 'Yaren'],
'NZ' => ['NZ.AUK' => 'Auckland', 'NZ.BOP' => 'Bay of Plenty', 'NZ.CAN' => 'Canterbury', 'NZ.CIT' => 'Chatham Islands Territory', 'NZ.GIS' => 'Gisborne', 'NZ.HKB' => 'Hawke\'s Bay', 'NZ.MWT' => 'Manawatu-Wanganui', 'NZ.MBH' => 'Marlborough', 'NZ.NSN' => 'Nelson', 'NZ.NTL' => 'Northland', 'NZ.OTA' => 'Otago', 'NZ.STL' => 'Southland', 'NZ.TKI' => 'Taranaki', 'NZ.TAS' => 'Tasman', 'NZ.WKO' => 'Waikato', 'NZ.WGN' => 'Wellington', 'NZ.WTC' => 'West Coast'],
'OM' => ['OM.DA' => 'Ad Dakhiliyah', 'OM.BU' => 'Al Buraymi', 'OM.WU' => 'Al Wusta', 'OM.ZA' => 'Az Zahirah', 'OM.BJ' => 'Janub al Batinah', 'OM.SJ' => 'Janub ash Sharqiyah', 'OM.MA' => 'Masqat', 'OM.MU' => 'Musandam', 'OM.BS' => 'Shamal al Batinah', 'OM.SS' => 'Shamal ash Sharqiyah', 'OM.ZU' => 'Zufar'],
'PA' => ['PA.1' => 'Bocas del Toro', 'PA.4' => 'Chiriqui', 'PA.2' => 'Cocle', 'PA.3' => 'Colon', 'PA.5' => 'Darien', 'PA.EM' => 'Embera', 'PA.KY' => 'Guna Yala', 'PA.6' => 'Herrera', 'PA.7' => 'Los Santos', 'PA.NT' => 'Naso Tjer Di', 'PA.NB' => 'Ngobe-Bugle', 'PA.8' => 'Panama', 'PA.10' => 'Panama Oeste', 'PA.9' => 'Veraguas'],
'PE' => ['PE.AMA' => 'Amazonas', 'PE.ANC' => 'Ancash', 'PE.APU' => 'Apurimac', 'PE.ARE' => 'Arequipa', 'PE.AYA' => 'Ayacucho', 'PE.CAJ' => 'Cajamarca', 'PE.CUS' => 'Cusco', 'PE.CAL' => 'El Callao', 'PE.HUV' => 'Huancavelica', 'PE.HUC' => 'Huanuco', 'PE.ICA' => 'Ica', 'PE.JUN' => 'Junin', 'PE.LAL' => 'La Libertad', 'PE.LAM' => 'Lambayeque', 'PE.LIM' => 'Lima', 'PE.LOR' => 'Loreto', 'PE.MDD' => 'Madre de Dios', 'PE.MOQ' => 'Moquegua', 'PE.PAS' => 'Pasco', 'PE.PIU' => 'Piura', 'PE.PUN' => 'Puno', 'PE.SAM' => 'San Martin', 'PE.TAC' => 'Tacna', 'PE.TUM' => 'Tumbes', 'PE.UCA' => 'Ucayali'],
'PG' => ['PG.NSB' => 'Bougainville', 'PG.CPM' => 'Central', 'PG.CPK' => 'Chimbu', 'PG.EBR' => 'East New Britain', 'PG.ESW' => 'East Sepik', 'PG.EHG' => 'Eastern Highlands', 'PG.EPW' => 'Enga', 'PG.GPK' => 'Gulf', 'PG.HLA' => 'Hela', 'PG.JWK' => 'Jiwaka', 'PG.MPM' => 'Madang', 'PG.MRL' => 'Manus', 'PG.MBA' => 'Milne Bay', 'PG.MPL' => 'Morobe', 'PG.NCD' => 'National Capital District (Port Moresby)', 'PG.NIK' => 'New Ireland', 'PG.NPP' => 'Northern', 'PG.SHM' => 'Southern Highlands', 'PG.WBK' => 'West New Britain', 'PG.SAN' => 'West Sepik', 'PG.WPD' => 'Western', 'PG.WHM' => 'Western Highlands'],
'PH' => ['PH.ABR' => 'Abra', 'PH.AGN' => 'Agusan del Norte', 'PH.AGS' => 'Agusan del Sur', 'PH.AKL' => 'Aklan', 'PH.ALB' => 'Albay', 'PH.ANT' => 'Antique', 'PH.APA' => 'Apayao', 'PH.AUR' => 'Aurora', 'PH.BAS' => 'Basilan', 'PH.BAN' => 'Bataan', 'PH.BTN' => 'Batanes', 'PH.BTG' => 'Batangas', 'PH.BEN' => 'Benguet', 'PH.BIL' => 'Biliran', 'PH.BOH' => 'Bohol', 'PH.BUK' => 'Bukidnon', 'PH.BUL' => 'Bulacan', 'PH.CAG' => 'Cagayan', 'PH.CAN' => 'Camarines Norte', 'PH.CAS' => 'Camarines Sur', 'PH.CAM' => 'Camiguin', 'PH.CAP' => 'Capiz', 'PH.CAT' => 'Catanduanes', 'PH.CAV' => 'Cavite', 'PH.CEB' => 'Cebu', 'PH.NCO' => 'Cotabato', 'PH.DVO' => 'Davao Occidental', 'PH.DAO' => 'Davao Oriental', 'PH.COM' => 'Davao de Oro', 'PH.DAV' => 'Davao del Norte', 'PH.DAS' => 'Davao del Sur', 'PH.DIN' => 'Dinagat Islands', 'PH.EAS' => 'Eastern Samar', 'PH.GUI' => 'Guimaras', 'PH.IFU' => 'Ifugao', 'PH.ILN' => 'Ilocos Norte', 'PH.ILS' => 'Ilocos Sur', 'PH.ILI' => 'Iloilo', 'PH.ISA' => 'Isabela', 'PH.KAL' => 'Kalinga', 'PH.LUN' => 'La Union', 'PH.LAG' => 'Laguna', 'PH.LAN' => 'Lanao del Norte', 'PH.LAS' => 'Lanao del Sur', 'PH.LEY' => 'Leyte', 'PH.MAG' => 'Maguindanao', 'PH.MAD' => 'Marinduque', 'PH.MAS' => 'Masbate', 'PH.MDC' => 'Mindoro Occidental', 'PH.MDR' => 'Mindoro Oriental', 'PH.MSC' => 'Misamis Occidental', 'PH.MSR' => 'Misamis Oriental', 'PH.MOU' => 'Mountain Province', 'PH.00' => 'National Capital Region', 'PH.NEC' => 'Negros Occidental', 'PH.NER' => 'Negros Oriental', 'PH.NSA' => 'Northern Samar', 'PH.NUE' => 'Nueva Ecija', 'PH.NUV' => 'Nueva Vizcaya', 'PH.PLW' => 'Palawan', 'PH.PAM' => 'Pampanga', 'PH.PAN' => 'Pangasinan', 'PH.QUE' => 'Quezon', 'PH.QUI' => 'Quirino', 'PH.RIZ' => 'Rizal', 'PH.ROM' => 'Romblon', 'PH.WSA' => 'Samar', 'PH.SAR' => 'Sarangani', 'PH.SIG' => 'Siquijor', 'PH.SOR' => 'Sorsogon', 'PH.SCO' => 'South Cotabato', 'PH.SLE' => 'Southern Leyte', 'PH.SUK' => 'Sultan Kudarat', 'PH.SLU' => 'Sulu', 'PH.SUN' => 'Surigao del Norte', 'PH.SUR' => 'Surigao del Sur', 'PH.TAR' => 'Tarlac', 'PH.TAW' => 'Tawi-Tawi', 'PH.ZMB' => 'Zambales', 'PH.ZSI' => 'Zamboanga Sibugay', 'PH.ZAN' => 'Zamboanga del Norte', 'PH.ZAS' => 'Zamboanga del Sur'],
'PK' => ['PK.JK' => 'Azad Jammu and Kashmir', 'PK.BA' => 'Balochistan', 'PK.GB' => 'Gilgit-Baltistan', 'PK.IS' => 'Islamabad', 'PK.KP' => 'Khyber Pakhtunkhwa', 'PK.PB' => 'Punjab', 'PK.SD' => 'Sindh'],
'PL' => ['PL.02' => 'Dolnoslaskie', 'PL.04' => 'Kujawsko-pomorskie', 'PL.10' => 'Lodzkie', 'PL.06' => 'Lubelskie', 'PL.08' => 'Lubuskie', 'PL.12' => 'Malopolskie', 'PL.14' => 'Mazowieckie', 'PL.16' => 'Opolskie', 'PL.18' => 'Podkarpackie', 'PL.20' => 'Podlaskie', 'PL.22' => 'Pomorskie', 'PL.24' => 'Slaskie', 'PL.26' => 'Swietokrzyskie', 'PL.28' => 'Warminsko-mazurskie', 'PL.30' => 'Wielkopolskie', 'PL.32' => 'Zachodniopomorskie'],
'PS' => ['PS.BTH' => 'Bethlehem', 'PS.DEB' => 'Deir El Balah', 'PS.GZA' => 'Gaza', 'PS.HBN' => 'Hebron', 'PS.JEN' => 'Jenin', 'PS.JRH' => 'Jericho and Al Aghwar', 'PS.JEM' => 'Jerusalem', 'PS.KYS' => 'Khan Yunis', 'PS.NBS' => 'Nablus', 'PS.NGZ' => 'North Gaza', 'PS.QQA' => 'Qalqilya', 'PS.RFH' => 'Rafah', 'PS.RBH' => 'Ramallah', 'PS.SLT' => 'Salfit', 'PS.TBS' => 'Tubas', 'PS.TKM' => 'Tulkarm'],
'PT' => ['PT.01' => 'Aveiro', 'PT.02' => 'Beja', 'PT.03' => 'Braga', 'PT.04' => 'Braganca', 'PT.05' => 'Castelo Branco', 'PT.06' => 'Coimbra', 'PT.07' => 'Evora', 'PT.08' => 'Faro', 'PT.09' => 'Guarda', 'PT.10' => 'Leiria', 'PT.11' => 'Lisboa', 'PT.12' => 'Portalegre', 'PT.13' => 'Porto', 'PT.30' => 'Regiao Autonoma da Madeira', 'PT.20' => 'Regiao Autonoma dos Acores', 'PT.14' => 'Santarem', 'PT.15' => 'Setubal', 'PT.16' => 'Viana do Castelo', 'PT.17' => 'Vila Real', 'PT.18' => 'Viseu'],
'PW' => ['PW.002' => 'Aimeliik', 'PW.004' => 'Airai', 'PW.010' => 'Angaur', 'PW.050' => 'Hatohobei', 'PW.100' => 'Kayangel', 'PW.150' => 'Koror', 'PW.212' => 'Melekeok', 'PW.214' => 'Ngaraard', 'PW.218' => 'Ngarchelong', 'PW.222' => 'Ngardmau', 'PW.224' => 'Ngatpang', 'PW.226' => 'Ngchesar', 'PW.227' => 'Ngeremlengui', 'PW.228' => 'Ngiwal', 'PW.350' => 'Peleliu', 'PW.370' => 'Sonsorol'],
'PY' => ['PY.16' => 'Alto Paraguay', 'PY.10' => 'Alto Parana', 'PY.13' => 'Amambay', 'PY.ASU' => 'Asuncion', 'PY.19' => 'Boqueron', 'PY.5' => 'Caaguazu', 'PY.6' => 'Caazapa', 'PY.14' => 'Canindeyu', 'PY.11' => 'Central', 'PY.1' => 'Concepcion', 'PY.3' => 'Cordillera', 'PY.4' => 'Guaira', 'PY.7' => 'Itapua', 'PY.8' => 'Misiones', 'PY.12' => 'Neembucu', 'PY.9' => 'Paraguari', 'PY.15' => 'Presidente Hayes', 'PY.2' => 'San Pedro'],
'QA' => ['QA.DA' => 'Ad Dawhah', 'QA.KH' => 'Al Khawr wa adh Dhakhirah', 'QA.WA' => 'Al Wakrah', 'QA.RA' => 'Ar Rayyan', 'QA.MS' => 'Ash Shamal', 'QA.SH' => 'Ash Shihaniyah', 'QA.ZA' => 'Az Za\'ayin', 'QA.US' => 'Umm Salal'],
'RO' => ['RO.AB' => 'Alba', 'RO.AR' => 'Arad', 'RO.AG' => 'Arges', 'RO.BC' => 'Bacau', 'RO.BH' => 'Bihor', 'RO.BN' => 'Bistrita-Nasaud', 'RO.BT' => 'Botosani', 'RO.BR' => 'Braila', 'RO.BV' => 'Brasov', 'RO.B' => 'Bucuresti', 'RO.BZ' => 'Buzau', 'RO.CL' => 'Calarasi', 'RO.CS' => 'Caras-Severin', 'RO.CJ' => 'Cluj', 'RO.CT' => 'Constanta', 'RO.CV' => 'Covasna', 'RO.DB' => 'Dambovita', 'RO.DJ' => 'Dolj', 'RO.GL' => 'Galati', 'RO.GR' => 'Giurgiu', 'RO.GJ' => 'Gorj', 'RO.HR' => 'Harghita', 'RO.HD' => 'Hunedoara', 'RO.IL' => 'Ialomita', 'RO.IS' => 'Iasi', 'RO.IF' => 'Ilfov', 'RO.MM' => 'Maramures', 'RO.MH' => 'Mehedinti', 'RO.MS' => 'Mures', 'RO.NT' => 'Neamt', 'RO.OT' => 'Olt', 'RO.PH' => 'Prahova', 'RO.SJ' => 'Salaj', 'RO.SM' => 'Satu Mare', 'RO.SB' => 'Sibiu', 'RO.SV' => 'Suceava', 'RO.TR' => 'Teleorman', 'RO.TM' => 'Timis', 'RO.TL' => 'Tulcea', 'RO.VL' => 'Valcea', 'RO.VS' => 'Vaslui', 'RO.VN' => 'Vrancea'],
'RS' => ['RS.00' => 'Beograd', 'RS.14' => 'Borski okrug', 'RS.11' => 'Branicevski okrug', 'RS.23' => 'Jablanicki okrug', 'RS.06' => 'Juznobacki okrug', 'RS.04' => 'Juznobanatski okrug', 'RS.09' => 'Kolubarski okrug', 'RS.25' => 'Kosovski okrug', 'RS.28' => 'Kosovsko-Mitrovacki okrug', 'RS.29' => 'Kosovsko-Pomoravski okrug', 'RS.08' => 'Macvanski okrug', 'RS.17' => 'Moravicki okrug', 'RS.20' => 'Nisavski okrug', 'RS.24' => 'Pcinjski okrug', 'RS.26' => 'Pecki okrug', 'RS.22' => 'Pirotski okrug', 'RS.10' => 'Podunavski okrug', 'RS.13' => 'Pomoravski okrug', 'RS.27' => 'Prizrenski okrug', 'RS.19' => 'Rasinski okrug', 'RS.18' => 'Raski okrug', 'RS.01' => 'Severnobacki okrug', 'RS.03' => 'Severnobanatski okrug', 'RS.02' => 'Srednjebanatski okrug', 'RS.07' => 'Sremski okrug', 'RS.12' => 'Sumadijski okrug', 'RS.21' => 'Toplicki okrug', 'RS.15' => 'Zajecarski okrug', 'RS.05' => 'Zapadnobacki okrug', 'RS.16' => 'Zlatiborski okrug'],
'RU' => ['RU.AD' => 'Adygeya, Respublika', 'RU.AL' => 'Altay, Respublika', 'RU.ALT' => 'Altayskiy kray', 'RU.AMU' => 'Amurskaya oblast\'', 'RU.ARK' => 'Arkhangel\'skaya oblast\'', 'RU.AST' => 'Astrakhanskaya oblast\'', 'RU.BA' => 'Bashkortostan, Respublika', 'RU.BEL' => 'Belgorodskaya oblast\'', 'RU.BRY' => 'Bryanskaya oblast\'', 'RU.BU' => 'Buryatiya, Respublika', 'RU.CE' => 'Chechenskaya Respublika', 'RU.CHE' => 'Chelyabinskaya oblast\'', 'RU.CHU' => 'Chukotskiy avtonomnyy okrug', 'RU.CU' => 'Chuvashskaya Respublika', 'RU.DA' => 'Dagestan, Respublika', 'RU.IN' => 'Ingushetiya, Respublika', 'RU.IRK' => 'Irkutskaya oblast\'', 'RU.IVA' => 'Ivanovskaya oblast\'', 'RU.KB' => 'Kabardino-Balkarskaya Respublika', 'RU.KGD' => 'Kaliningradskaya oblast\'', 'RU.KL' => 'Kalmykiya, Respublika', 'RU.KLU' => 'Kaluzhskaya oblast\'', 'RU.KAM' => 'Kamchatskiy kray', 'RU.KC' => 'Karachayevo-Cherkesskaya Respublika', 'RU.KR' => 'Kareliya, Respublika', 'RU.KEM' => 'Kemerovskaya oblast\'', 'RU.KHA' => 'Khabarovskiy kray', 'RU.KK' => 'Khakasiya, Respublika', 'RU.KHM' => 'Khanty-Mansiyskiy avtonomnyy okrug', 'RU.KIR' => 'Kirovskaya oblast\'', 'RU.KO' => 'Komi, Respublika', 'RU.KOS' => 'Kostromskaya oblast\'', 'RU.KDA' => 'Krasnodarskiy kray', 'RU.KYA' => 'Krasnoyarskiy kray', 'RU.KGN' => 'Kurganskaya oblast\'', 'RU.KRS' => 'Kurskaya oblast\'', 'RU.LEN' => 'Leningradskaya oblast\'', 'RU.LIP' => 'Lipetskaya oblast\'', 'RU.MAG' => 'Magadanskaya oblast\'', 'RU.ME' => 'Mariy El, Respublika', 'RU.MO' => 'Mordoviya, Respublika', 'RU.MOS' => 'Moskovskaya oblast\'', 'RU.MOW' => 'Moskva', 'RU.MUR' => 'Murmanskaya oblast\'', 'RU.NEN' => 'Nenetskiy avtonomnyy okrug', 'RU.NIZ' => 'Nizhegorodskaya oblast\'', 'RU.NGR' => 'Novgorodskaya oblast\'', 'RU.NVS' => 'Novosibirskaya oblast\'', 'RU.OMS' => 'Omskaya oblast\'', 'RU.ORE' => 'Orenburgskaya oblast\'', 'RU.ORL' => 'Orlovskaya oblast\'', 'RU.PNZ' => 'Penzenskaya oblast\'', 'RU.PER' => 'Permskiy kray', 'RU.PRI' => 'Primorskiy kray', 'RU.PSK' => 'Pskovskaya oblast\'', 'RU.ROS' => 'Rostovskaya oblast\'', 'RU.RYA' => 'Ryazanskaya oblast\'', 'RU.SA' => 'Saha, Respublika', 'RU.SAK' => 'Sakhalinskaya oblast\'', 'RU.SAM' => 'Samarskaya oblast\'', 'RU.SPE' => 'Sankt-Peterburg', 'RU.SAR' => 'Saratovskaya oblast\'', 'RU.SE' => 'Severnaya Osetiya, Respublika', 'RU.SMO' => 'Smolenskaya oblast\'', 'RU.STA' => 'Stavropol\'skiy kray', 'RU.SVE' => 'Sverdlovskaya oblast\'', 'RU.TAM' => 'Tambovskaya oblast\'', 'RU.TA' => 'Tatarstan, Respublika', 'RU.TOM' => 'Tomskaya oblast\'', 'RU.TUL' => 'Tul\'skaya oblast\'', 'RU.TVE' => 'Tverskaya oblast\'', 'RU.TYU' => 'Tyumenskaya oblast\'', 'RU.TY' => 'Tyva, Respublika', 'RU.UD' => 'Udmurtskaya Respublika', 'RU.ULY' => 'Ul\'yanovskaya oblast\'', 'RU.VLA' => 'Vladimirskaya oblast\'', 'RU.VGG' => 'Volgogradskaya oblast\'', 'RU.VLG' => 'Vologodskaya oblast\'', 'RU.VOR' => 'Voronezhskaya oblast\'', 'RU.YAN' => 'Yamalo-Nenetskiy avtonomnyy okrug', 'RU.YAR' => 'Yaroslavskaya oblast\'', 'RU.YEV' => 'Yevreyskaya avtonomnaya oblast\'', 'RU.ZAB' => 'Zabaykal\'skiy kray'],
'RW' => ['RW.02' => 'Est', 'RW.03' => 'Nord', 'RW.04' => 'Ouest', 'RW.05' => 'Sud', 'RW.01' => 'Ville de Kigali'],
'SA' => ['SA.14' => '\'Asir', 'SA.11' => 'Al Bahah', 'SA.08' => 'Al Hudud ash Shamaliyah', 'SA.12' => 'Al Jawf', 'SA.03' => 'Al Madinah al Munawwarah', 'SA.05' => 'Al Qasim', 'SA.01' => 'Ar Riyad', 'SA.04' => 'Ash Sharqiyah', 'SA.06' => 'Ha\'il', 'SA.09' => 'Jazan', 'SA.02' => 'Makkah al Mukarramah', 'SA.10' => 'Najran', 'SA.07' => 'Tabuk'],
'SB' => ['SB.CT' => 'Capital Territory (Honiara)', 'SB.CE' => 'Central', 'SB.CH' => 'Choiseul', 'SB.GU' => 'Guadalcanal', 'SB.IS' => 'Isabel', 'SB.MK' => 'Makira-Ulawa', 'SB.ML' => 'Malaita', 'SB.RB' => 'Rennell and Bellona', 'SB.TE' => 'Temotu', 'SB.WE' => 'Western'],
'SC' => ['SC.02' => 'Anse Boileau', 'SC.03' => 'Anse Etoile', 'SC.05' => 'Anse Royale', 'SC.01' => 'Anse aux Pins', 'SC.04' => 'Au Cap', 'SC.06' => 'Baie Lazare', 'SC.07' => 'Baie Sainte Anne', 'SC.08' => 'Beau Vallon', 'SC.09' => 'Bel Air', 'SC.10' => 'Bel Ombre', 'SC.11' => 'Cascade', 'SC.16' => 'English River', 'SC.12' => 'Glacis', 'SC.13' => 'Grand Anse Mahe', 'SC.14' => 'Grand Anse Praslin', 'SC.26' => 'Ile Perseverance I', 'SC.27' => 'Ile Perseverance II', 'SC.15' => 'La Digue', 'SC.24' => 'Les Mamelles', 'SC.17' => 'Mont Buxton', 'SC.18' => 'Mont Fleuri', 'SC.19' => 'Plaisance', 'SC.20' => 'Pointe Larue', 'SC.21' => 'Port Glaud', 'SC.25' => 'Roche Caiman', 'SC.22' => 'Saint Louis', 'SC.23' => 'Takamaka'],
'SD' => ['SD.NB' => 'Blue Nile', 'SD.DC' => 'Central Darfur', 'SD.DE' => 'East Darfur', 'SD.GD' => 'Gedaref', 'SD.GZ' => 'Gezira', 'SD.KA' => 'Kassala', 'SD.KH' => 'Khartoum', 'SD.DN' => 'North Darfur', 'SD.KN' => 'North Kordofan', 'SD.NO' => 'Northern', 'SD.RS' => 'Red Sea', 'SD.NR' => 'River Nile', 'SD.SI' => 'Sennar', 'SD.DS' => 'South Darfur', 'SD.KS' => 'South Kordofan', 'SD.DW' => 'West Darfur', 'SD.GK' => 'West Kordofan', 'SD.NW' => 'White Nile'],
'SE' => ['SE.K' => 'Blekinge lan', 'SE.W' => 'Dalarnas lan', 'SE.X' => 'Gavleborgs lan', 'SE.I' => 'Gotlands lan', 'SE.N' => 'Hallands lan', 'SE.Z' => 'Jamtlands lan', 'SE.F' => 'Jonkopings lan', 'SE.H' => 'Kalmar lan', 'SE.G' => 'Kronobergs lan', 'SE.BD' => 'Norrbottens lan', 'SE.T' => 'Orebro lan', 'SE.E' => 'Ostergotlands lan', 'SE.M' => 'Skane lan', 'SE.D' => 'Sodermanlands lan', 'SE.AB' => 'Stockholms lan', 'SE.C' => 'Uppsala lan', 'SE.S' => 'Varmlands lan', 'SE.AC' => 'Vasterbottens lan', 'SE.Y' => 'Vasternorrlands lan', 'SE.U' => 'Vastmanlands lan', 'SE.O' => 'Vastra Gotalands lan'],
'SH' => ['SH.AC' => 'Ascension', 'SH.HL' => 'Saint Helena', 'SH.TA' => 'Tristan da Cunha'],
'SI' => ['SI.001' => 'Ajdovscina', 'SI.213' => 'Ankaran', 'SI.195' => 'Apace', 'SI.002' => 'Beltinci', 'SI.148' => 'Benedikt', 'SI.149' => 'Bistrica ob Sotli', 'SI.003' => 'Bled', 'SI.150' => 'Bloke', 'SI.004' => 'Bohinj', 'SI.005' => 'Borovnica', 'SI.006' => 'Bovec', 'SI.151' => 'Braslovce', 'SI.007' => 'Brda', 'SI.009' => 'Brezice', 'SI.008' => 'Brezovica', 'SI.152' => 'Cankova', 'SI.011' => 'Celje', 'SI.012' => 'Cerklje na Gorenjskem', 'SI.013' => 'Cerknica', 'SI.014' => 'Cerkno', 'SI.153' => 'Cerkvenjak', 'SI.196' => 'Cirkulane', 'SI.015' => 'Crensovci', 'SI.016' => 'Crna na Koroskem', 'SI.017' => 'Crnomelj', 'SI.018' => 'Destrnik', 'SI.019' => 'Divaca', 'SI.154' => 'Dobje', 'SI.020' => 'Dobrepolje', 'SI.155' => 'Dobrna', 'SI.021' => 'Dobrova-Polhov Gradec', 'SI.156' => 'Dobrovnik', 'SI.022' => 'Dol pri Ljubljani', 'SI.157' => 'Dolenjske Toplice', 'SI.023' => 'Domzale', 'SI.024' => 'Dornava', 'SI.025' => 'Dravograd', 'SI.026' => 'Duplek', 'SI.027' => 'Gorenja vas-Poljane', 'SI.028' => 'Gorisnica', 'SI.207' => 'Gorje', 'SI.029' => 'Gornja Radgona', 'SI.030' => 'Gornji Grad', 'SI.031' => 'Gornji Petrovci', 'SI.158' => 'Grad', 'SI.032' => 'Grosuplje', 'SI.159' => 'Hajdina', 'SI.160' => 'Hoce-Slivnica', 'SI.161' => 'Hodos', 'SI.162' => 'Horjul', 'SI.034' => 'Hrastnik', 'SI.035' => 'Hrpelje-Kozina', 'SI.036' => 'Idrija', 'SI.037' => 'Ig', 'SI.038' => 'Ilirska Bistrica', 'SI.039' => 'Ivancna Gorica', 'SI.040' => 'Izola', 'SI.041' => 'Jesenice', 'SI.163' => 'Jezersko', 'SI.042' => 'Jursinci', 'SI.043' => 'Kamnik', 'SI.044' => 'Kanal', 'SI.045' => 'Kidricevo', 'SI.046' => 'Kobarid', 'SI.047' => 'Kobilje', 'SI.048' => 'Kocevje', 'SI.049' => 'Komen', 'SI.164' => 'Komenda', 'SI.050' => 'Koper', 'SI.197' => 'Kosanjevica na Krki', 'SI.165' => 'Kostel', 'SI.051' => 'Kozje', 'SI.052' => 'Kranj', 'SI.053' => 'Kranjska Gora', 'SI.166' => 'Krizevci', 'SI.054' => 'Krsko', 'SI.055' => 'Kungota', 'SI.056' => 'Kuzma', 'SI.057' => 'Lasko', 'SI.058' => 'Lenart', 'SI.059' => 'Lendava', 'SI.060' => 'Litija', 'SI.061' => 'Ljubljana', 'SI.062' => 'Ljubno', 'SI.063' => 'Ljutomer', 'SI.208' => 'Log-Dragomer', 'SI.064' => 'Logatec', 'SI.065' => 'Loska dolina', 'SI.066' => 'Loski Potok', 'SI.167' => 'Lovrenc na Pohorju', 'SI.067' => 'Luce', 'SI.068' => 'Lukovica', 'SI.069' => 'Majsperk', 'SI.198' => 'Makole', 'SI.070' => 'Maribor', 'SI.168' => 'Markovci', 'SI.071' => 'Medvode', 'SI.072' => 'Menges', 'SI.073' => 'Metlika', 'SI.074' => 'Mezica', 'SI.169' => 'Miklavz na Dravskem polju', 'SI.075' => 'Miren-Kostanjevica', 'SI.212' => 'Mirna', 'SI.170' => 'Mirna Pec', 'SI.076' => 'Mislinja', 'SI.199' => 'Mokronog-Trebelno', 'SI.077' => 'Moravce', 'SI.078' => 'Moravske Toplice', 'SI.079' => 'Mozirje', 'SI.080' => 'Murska Sobota', 'SI.081' => 'Muta', 'SI.082' => 'Naklo', 'SI.083' => 'Nazarje', 'SI.084' => 'Nova Gorica', 'SI.085' => 'Novo Mesto', 'SI.086' => 'Odranci', 'SI.171' => 'Oplotnica', 'SI.087' => 'Ormoz', 'SI.088' => 'Osilnica', 'SI.089' => 'Pesnica', 'SI.090' => 'Piran', 'SI.091' => 'Pivka', 'SI.092' => 'Podcetrtek', 'SI.172' => 'Podlehnik', 'SI.093' => 'Podvelka', 'SI.200' => 'Poljcane', 'SI.173' => 'Polzela', 'SI.094' => 'Postojna', 'SI.174' => 'Prebold', 'SI.095' => 'Preddvor', 'SI.175' => 'Prevalje', 'SI.096' => 'Ptuj', 'SI.097' => 'Puconci', 'SI.098' => 'Race-Fram', 'SI.099' => 'Radece', 'SI.100' => 'Radenci', 'SI.101' => 'Radlje ob Dravi', 'SI.102' => 'Radovljica', 'SI.103' => 'Ravne na Koroskem', 'SI.176' => 'Razkrizje', 'SI.209' => 'Recica ob Savinji', 'SI.201' => 'Rence-Vogrsko', 'SI.104' => 'Ribnica', 'SI.177' => 'Ribnica na Pohorju', 'SI.106' => 'Rogaska Slatina', 'SI.105' => 'Rogasovci', 'SI.107' => 'Rogatec', 'SI.108' => 'Ruse', 'SI.033' => 'Salovci', 'SI.178' => 'Selnica ob Dravi', 'SI.109' => 'Semic', 'SI.183' => 'Sempeter-Vrtojba', 'SI.117' => 'Sencur', 'SI.118' => 'Sentilj', 'SI.119' => 'Sentjernej', 'SI.120' => 'Sentjur', 'SI.211' => 'Sentrupert', 'SI.110' => 'Sevnica', 'SI.111' => 'Sezana', 'SI.121' => 'Skocjan', 'SI.122' => 'Skofja Loka', 'SI.123' => 'Skofljica', 'SI.112' => 'Slovenj Gradec', 'SI.113' => 'Slovenska Bistrica', 'SI.114' => 'Slovenske Konjice', 'SI.124' => 'Smarje pri Jelsah', 'SI.206' => 'Smarjeske Toplice', 'SI.125' => 'Smartno ob Paki', 'SI.194' => 'Smartno pri Litiji', 'SI.179' => 'Sodrazica', 'SI.180' => 'Solcava', 'SI.126' => 'Sostanj', 'SI.202' => 'Sredisce ob Dravi', 'SI.115' => 'Starse', 'SI.127' => 'Store', 'SI.203' => 'Straza', 'SI.181' => 'Sveta Ana', 'SI.204' => 'Sveta Trojica v Slovenskih goricah', 'SI.182' => 'Sveti Andraz v Slovenskih Goricah', 'SI.116' => 'Sveti Jurij ob Scavnici', 'SI.210' => 'Sveti Jurij v Slovenskih goricah', 'SI.205' => 'Sveti Tomaz', 'SI.184' => 'Tabor', 'SI.010' => 'Tisina', 'SI.128' => 'Tolmin', 'SI.129' => 'Trbovlje', 'SI.130' => 'Trebnje', 'SI.185' => 'Trnovska Vas', 'SI.131' => 'Trzic', 'SI.186' => 'Trzin', 'SI.132' => 'Turnisce', 'SI.133' => 'Velenje', 'SI.187' => 'Velika Polana', 'SI.134' => 'Velike Lasce', 'SI.188' => 'Verzej', 'SI.135' => 'Videm', 'SI.136' => 'Vipava', 'SI.137' => 'Vitanje', 'SI.138' => 'Vodice', 'SI.139' => 'Vojnik', 'SI.189' => 'Vransko', 'SI.140' => 'Vrhnika', 'SI.141' => 'Vuzenica', 'SI.142' => 'Zagorje ob Savi', 'SI.190' => 'Zalec', 'SI.143' => 'Zavrc', 'SI.146' => 'Zelezniki', 'SI.191' => 'Zetale', 'SI.147' => 'Ziri', 'SI.192' => 'Zirovnica', 'SI.144' => 'Zrece', 'SI.193' => 'Zuzemberk'],
'SK' => ['SK.BC' => 'Banskobystricky kraj', 'SK.BL' => 'Bratislavsky kraj', 'SK.KI' => 'Kosicky kraj', 'SK.NI' => 'Nitriansky kraj', 'SK.PV' => 'Presovsky kraj', 'SK.TC' => 'Trenciansky kraj', 'SK.TA' => 'Trnavsky kraj', 'SK.ZI' => 'Zilinsky kraj'],
'SL' => ['SL.E' => 'Eastern', 'SL.NW' => 'North Western', 'SL.N' => 'Northern', 'SL.S' => 'Southern', 'SL.W' => 'Western Area'],
'SM' => ['SM.01' => 'Acquaviva', 'SM.06' => 'Borgo Maggiore', 'SM.02' => 'Chiesanuova', 'SM.07' => 'Citta di San Marino', 'SM.03' => 'Domagnano', 'SM.04' => 'Faetano', 'SM.05' => 'Fiorentino', 'SM.08' => 'Montegiardino', 'SM.09' => 'Serravalle'],
'SN' => ['SN.DK' => 'Dakar', 'SN.DB' => 'Diourbel', 'SN.FK' => 'Fatick', 'SN.KA' => 'Kaffrine', 'SN.KL' => 'Kaolack', 'SN.KE' => 'Kedougou', 'SN.KD' => 'Kolda', 'SN.LG' => 'Louga', 'SN.MT' => 'Matam', 'SN.SL' => 'Saint-Louis', 'SN.SE' => 'Sedhiou', 'SN.TC' => 'Tambacounda', 'SN.TH' => 'Thies', 'SN.ZG' => 'Ziguinchor'],
'SO' => ['SO.AW' => 'Awdal', 'SO.BK' => 'Bakool', 'SO.BN' => 'Banaadir', 'SO.BR' => 'Bari', 'SO.BY' => 'Bay', 'SO.GA' => 'Galguduud', 'SO.GE' => 'Gedo', 'SO.HI' => 'Hiiraan', 'SO.JD' => 'Jubbada Dhexe', 'SO.JH' => 'Jubbada Hoose', 'SO.MU' => 'Mudug', 'SO.NU' => 'Nugaal', 'SO.SA' => 'Sanaag', 'SO.SD' => 'Shabeellaha Dhexe', 'SO.SH' => 'Shabeellaha Hoose', 'SO.SO' => 'Sool', 'SO.TO' => 'Togdheer', 'SO.WO' => 'Woqooyi Galbeed'],
'SR' => ['SR.BR' => 'Brokopondo', 'SR.CM' => 'Commewijne', 'SR.CR' => 'Coronie', 'SR.MA' => 'Marowijne', 'SR.NI' => 'Nickerie', 'SR.PR' => 'Para', 'SR.PM' => 'Paramaribo', 'SR.SA' => 'Saramacca', 'SR.SI' => 'Sipaliwini', 'SR.WA' => 'Wanica'],
'SS' => ['SS.EC' => 'Central Equatoria', 'SS.EE' => 'Eastern Equatoria', 'SS.JG' => 'Jonglei', 'SS.LK' => 'Lakes', 'SS.BN' => 'Northern Bahr el Ghazal', 'SS.UY' => 'Unity', 'SS.NU' => 'Upper Nile', 'SS.WR' => 'Warrap', 'SS.BW' => 'Western Bahr el Ghazal', 'SS.EW' => 'Western Equatoria'],
'ST' => ['ST.01' => 'Agua Grande', 'ST.02' => 'Cantagalo', 'ST.03' => 'Caue', 'ST.04' => 'Lemba', 'ST.05' => 'Lobata', 'ST.06' => 'Me-Zochi', 'ST.P' => 'Principe'],
'SV' => ['SV.AH' => 'Ahuachapan', 'SV.CA' => 'Cabanas', 'SV.CH' => 'Chalatenango', 'SV.CU' => 'Cuscatlan', 'SV.LI' => 'La Libertad', 'SV.PA' => 'La Paz', 'SV.UN' => 'La Union', 'SV.MO' => 'Morazan', 'SV.SM' => 'San Miguel', 'SV.SS' => 'San Salvador', 'SV.SV' => 'San Vicente', 'SV.SA' => 'Santa Ana', 'SV.SO' => 'Sonsonate', 'SV.US' => 'Usulutan'],
'SY' => ['SY.HA' => 'Al Hasakah', 'SY.LA' => 'Al Ladhiqiyah', 'SY.QU' => 'Al Qunaytirah', 'SY.RA' => 'Ar Raqqah', 'SY.SU' => 'As Suwayda\'', 'SY.DR' => 'Dar\'a', 'SY.DY' => 'Dayr az Zawr', 'SY.DI' => 'Dimashq', 'SY.HL' => 'Halab', 'SY.HM' => 'Hamah', 'SY.HI' => 'Hims', 'SY.ID' => 'Idlib', 'SY.RD' => 'Rif Dimashq', 'SY.TA' => 'Tartus'],
'SZ' => ['SZ.HH' => 'Hhohho', 'SZ.LU' => 'Lubombo', 'SZ.MA' => 'Manzini', 'SZ.SH' => 'Shiselweni'],
'TD' => ['TD.BG' => 'Bahr el Ghazal', 'TD.BA' => 'Batha', 'TD.BO' => 'Borkou', 'TD.CB' => 'Chari-Baguirmi', 'TD.EE' => 'Ennedi-Est', 'TD.EO' => 'Ennedi-Ouest', 'TD.GR' => 'Guera', 'TD.HL' => 'Hadjer Lamis', 'TD.KA' => 'Kanem', 'TD.LC' => 'Lac', 'TD.LO' => 'Logone-Occidental', 'TD.LR' => 'Logone-Oriental', 'TD.MA' => 'Mandoul', 'TD.ME' => 'Mayo-Kebbi-Est', 'TD.MO' => 'Mayo-Kebbi-Ouest', 'TD.MC' => 'Moyen-Chari', 'TD.OD' => 'Ouaddai', 'TD.SA' => 'Salamat', 'TD.SI' => 'Sila', 'TD.TA' => 'Tandjile', 'TD.TI' => 'Tibesti', 'TD.ND' => 'Ville de Ndjamena', 'TD.WF' => 'Wadi Fira'],
'TG' => ['TG.C' => 'Centrale', 'TG.K' => 'Kara', 'TG.M' => 'Maritime', 'TG.P' => 'Plateaux', 'TG.S' => 'Savanes'],
'TH' => ['TH.37' => 'Amnat Charoen', 'TH.15' => 'Ang Thong', 'TH.38' => 'Bueng Kan', 'TH.31' => 'Buri Ram', 'TH.24' => 'Chachoengsao', 'TH.18' => 'Chai Nat', 'TH.36' => 'Chaiyaphum', 'TH.22' => 'Chanthaburi', 'TH.50' => 'Chiang Mai', 'TH.57' => 'Chiang Rai', 'TH.20' => 'Chon Buri', 'TH.86' => 'Chumphon', 'TH.46' => 'Kalasin', 'TH.62' => 'Kamphaeng Phet', 'TH.71' => 'Kanchanaburi', 'TH.40' => 'Khon Kaen', 'TH.81' => 'Krabi', 'TH.10' => 'Krung Thep Maha Nakhon', 'TH.52' => 'Lampang', 'TH.51' => 'Lamphun', 'TH.42' => 'Loei', 'TH.16' => 'Lop Buri', 'TH.58' => 'Mae Hong Son', 'TH.44' => 'Maha Sarakham', 'TH.49' => 'Mukdahan', 'TH.26' => 'Nakhon Nayok', 'TH.73' => 'Nakhon Pathom', 'TH.48' => 'Nakhon Phanom', 'TH.30' => 'Nakhon Ratchasima', 'TH.60' => 'Nakhon Sawan', 'TH.80' => 'Nakhon Si Thammarat', 'TH.55' => 'Nan', 'TH.96' => 'Narathiwat', 'TH.39' => 'Nong Bua Lam Phu', 'TH.43' => 'Nong Khai', 'TH.12' => 'Nonthaburi', 'TH.13' => 'Pathum Thani', 'TH.94' => 'Pattani', 'TH.82' => 'Phangnga', 'TH.93' => 'Phatthalung', 'TH.56' => 'Phayao', 'TH.67' => 'Phetchabun', 'TH.76' => 'Phetchaburi', 'TH.66' => 'Phichit', 'TH.65' => 'Phitsanulok', 'TH.14' => 'Phra Nakhon Si Ayutthaya', 'TH.54' => 'Phrae', 'TH.83' => 'Phuket', 'TH.25' => 'Prachin Buri', 'TH.77' => 'Prachuap Khiri Khan', 'TH.85' => 'Ranong', 'TH.70' => 'Ratchaburi', 'TH.21' => 'Rayong', 'TH.45' => 'Roi Et', 'TH.27' => 'Sa Kaeo', 'TH.47' => 'Sakon Nakhon', 'TH.11' => 'Samut Prakan', 'TH.74' => 'Samut Sakhon', 'TH.75' => 'Samut Songkhram', 'TH.19' => 'Saraburi', 'TH.91' => 'Satun', 'TH.33' => 'Si Sa Ket', 'TH.17' => 'Sing Buri', 'TH.90' => 'Songkhla', 'TH.64' => 'Sukhothai', 'TH.72' => 'Suphan Buri', 'TH.84' => 'Surat Thani', 'TH.32' => 'Surin', 'TH.63' => 'Tak', 'TH.92' => 'Trang', 'TH.23' => 'Trat', 'TH.34' => 'Ubon Ratchathani', 'TH.41' => 'Udon Thani', 'TH.61' => 'Uthai Thani', 'TH.53' => 'Uttaradit', 'TH.95' => 'Yala', 'TH.35' => 'Yasothon'],
'TJ' => ['TJ.DU' => 'Dushanbe', 'TJ.KT' => 'Khatlon', 'TJ.GB' => 'Kuhistoni Badakhshon', 'TJ.RA' => 'Nohiyahoi Tobei Jumhuri', 'TJ.SU' => 'Sughd'],
'TL' => ['TL.AL' => 'Aileu', 'TL.AN' => 'Ainaro', 'TL.BA' => 'Baucau', 'TL.BO' => 'Bobonaro', 'TL.CO' => 'Cova Lima', 'TL.DI' => 'Dili', 'TL.ER' => 'Ermera', 'TL.LA' => 'Lautem', 'TL.LI' => 'Liquica', 'TL.MT' => 'Manatuto', 'TL.MF' => 'Manufahi', 'TL.OE' => 'Oecussi', 'TL.VI' => 'Viqueque'],
'TM' => ['TM.A' => 'Ahal', 'TM.B' => 'Balkan', 'TM.D' => 'Dasoguz', 'TM.L' => 'Lebap', 'TM.M' => 'Mary'],
'TN' => ['TN.31' => 'Beja', 'TN.13' => 'Ben Arous', 'TN.23' => 'Bizerte', 'TN.81' => 'Gabes', 'TN.71' => 'Gafsa', 'TN.32' => 'Jendouba', 'TN.41' => 'Kairouan', 'TN.42' => 'Kasserine', 'TN.73' => 'Kebili', 'TN.12' => 'L\'Ariana', 'TN.14' => 'La Manouba', 'TN.33' => 'Le Kef', 'TN.53' => 'Mahdia', 'TN.82' => 'Medenine', 'TN.52' => 'Monastir', 'TN.21' => 'Nabeul', 'TN.61' => 'Sfax', 'TN.43' => 'Sidi Bouzid', 'TN.34' => 'Siliana', 'TN.51' => 'Sousse', 'TN.83' => 'Tataouine', 'TN.72' => 'Tozeur', 'TN.11' => 'Tunis', 'TN.22' => 'Zaghouan'],
'TO' => ['TO.01' => '\'Eua', 'TO.02' => 'Ha\'apai', 'TO.03' => 'Niuas', 'TO.04' => 'Tongatapu', 'TO.05' => 'Vava\'u'],
'TR' => ['TR.01' => 'Adana', 'TR.02' => 'Adiyaman', 'TR.03' => 'Afyonkarahisar', 'TR.04' => 'Agri', 'TR.68' => 'Aksaray', 'TR.05' => 'Amasya', 'TR.06' => 'Ankara', 'TR.07' => 'Antalya', 'TR.75' => 'Ardahan', 'TR.08' => 'Artvin', 'TR.09' => 'Aydin', 'TR.10' => 'Balikesir', 'TR.74' => 'Bartin', 'TR.72' => 'Batman', 'TR.69' => 'Bayburt', 'TR.11' => 'Bilecik', 'TR.12' => 'Bingol', 'TR.13' => 'Bitlis', 'TR.14' => 'Bolu', 'TR.15' => 'Burdur', 'TR.16' => 'Bursa', 'TR.17' => 'Canakkale', 'TR.18' => 'Cankiri', 'TR.19' => 'Corum', 'TR.20' => 'Denizli', 'TR.21' => 'Diyarbakir', 'TR.81' => 'Duzce', 'TR.22' => 'Edirne', 'TR.23' => 'Elazig', 'TR.24' => 'Erzincan', 'TR.25' => 'Erzurum', 'TR.26' => 'Eskisehir', 'TR.27' => 'Gaziantep', 'TR.28' => 'Giresun', 'TR.29' => 'Gumushane', 'TR.30' => 'Hakkari', 'TR.31' => 'Hatay', 'TR.76' => 'Igdir', 'TR.32' => 'Isparta', 'TR.34' => 'Istanbul', 'TR.35' => 'Izmir', 'TR.46' => 'Kahramanmaras', 'TR.78' => 'Karabuk', 'TR.70' => 'Karaman', 'TR.36' => 'Kars', 'TR.37' => 'Kastamonu', 'TR.38' => 'Kayseri', 'TR.79' => 'Kilis', 'TR.71' => 'Kirikkale', 'TR.39' => 'Kirklareli', 'TR.40' => 'Kirsehir', 'TR.41' => 'Kocaeli', 'TR.42' => 'Konya', 'TR.43' => 'Kutahya', 'TR.44' => 'Malatya', 'TR.45' => 'Manisa', 'TR.47' => 'Mardin', 'TR.33' => 'Mersin', 'TR.48' => 'Mugla', 'TR.49' => 'Mus', 'TR.50' => 'Nevsehir', 'TR.51' => 'Nigde', 'TR.52' => 'Ordu', 'TR.80' => 'Osmaniye', 'TR.53' => 'Rize', 'TR.54' => 'Sakarya', 'TR.55' => 'Samsun', 'TR.63' => 'Sanliurfa', 'TR.56' => 'Siirt', 'TR.57' => 'Sinop', 'TR.73' => 'Sirnak', 'TR.58' => 'Sivas', 'TR.59' => 'Tekirdag', 'TR.60' => 'Tokat', 'TR.61' => 'Trabzon', 'TR.62' => 'Tunceli', 'TR.64' => 'Usak', 'TR.65' => 'Van', 'TR.77' => 'Yalova', 'TR.66' => 'Yozgat', 'TR.67' => 'Zonguldak'],
'TT' => ['TT.ARI' => 'Arima', 'TT.CHA' => 'Chaguanas', 'TT.CTT' => 'Couva-Tabaquite-Talparo', 'TT.DMN' => 'Diego Martin', 'TT.MRC' => 'Mayaro-Rio Claro', 'TT.PED' => 'Penal-Debe', 'TT.PTF' => 'Point Fortin', 'TT.POS' => 'Port of Spain', 'TT.PRT' => 'Princes Town', 'TT.SFO' => 'San Fernando', 'TT.SJL' => 'San Juan-Laventille', 'TT.SGE' => 'Sangre Grande', 'TT.SIP' => 'Siparia', 'TT.TOB' => 'Tobago', 'TT.TUP' => 'Tunapuna-Piarco'],
'TV' => ['TV.FUN' => 'Funafuti', 'TV.NMG' => 'Nanumaga', 'TV.NMA' => 'Nanumea', 'TV.NIT' => 'Niutao', 'TV.NUI' => 'Nui', 'TV.NKF' => 'Nukufetau', 'TV.NKL' => 'Nukulaelae', 'TV.VAI' => 'Vaitupu'],
'TW' => ['TW.CHA' => 'Changhua', 'TW.CYQ' => 'Chiayi', 'TW.HSQ' => 'Hsinchu', 'TW.HUA' => 'Hualien', 'TW.KHH' => 'Kaohsiung', 'TW.KEE' => 'Keelung', 'TW.KIN' => 'Kinmen', 'TW.LIE' => 'Lienchiang', 'TW.MIA' => 'Miaoli', 'TW.NAN' => 'Nantou', 'TW.NWT' => 'New Taipei', 'TW.PEN' => 'Penghu', 'TW.PIF' => 'Pingtung', 'TW.TXG' => 'Taichung', 'TW.TNN' => 'Tainan', 'TW.TPE' => 'Taipei', 'TW.TTT' => 'Taitung', 'TW.TAO' => 'Taoyuan', 'TW.ILA' => 'Yilan', 'TW.YUN' => 'Yunlin'],
'TZ' => ['TZ.01' => 'Arusha', 'TZ.02' => 'Dar es Salaam', 'TZ.03' => 'Dodoma', 'TZ.27' => 'Geita', 'TZ.04' => 'Iringa', 'TZ.05' => 'Kagera', 'TZ.06' => 'Kaskazini Pemba', 'TZ.07' => 'Kaskazini Unguja', 'TZ.28' => 'Katavi', 'TZ.08' => 'Kigoma', 'TZ.09' => 'Kilimanjaro', 'TZ.10' => 'Kusini Pemba', 'TZ.11' => 'Kusini Unguja', 'TZ.12' => 'Lindi', 'TZ.26' => 'Manyara', 'TZ.13' => 'Mara', 'TZ.14' => 'Mbeya', 'TZ.15' => 'Mjini Magharibi', 'TZ.16' => 'Morogoro', 'TZ.17' => 'Mtwara', 'TZ.18' => 'Mwanza', 'TZ.29' => 'Njombe', 'TZ.19' => 'Pwani', 'TZ.20' => 'Rukwa', 'TZ.21' => 'Ruvuma', 'TZ.22' => 'Shinyanga', 'TZ.30' => 'Simiyu', 'TZ.23' => 'Singida', 'TZ.31' => 'Songwe', 'TZ.24' => 'Tabora', 'TZ.25' => 'Tanga'],
'UA' => ['UA.43' => 'Avtonomna Respublika Krym', 'UA.71' => 'Cherkaska oblast', 'UA.74' => 'Chernihivska oblast', 'UA.77' => 'Chernivetska oblast', 'UA.12' => 'Dnipropetrovska oblast', 'UA.14' => 'Donetska oblast', 'UA.26' => 'Ivano-Frankivska oblast', 'UA.63' => 'Kharkivska oblast', 'UA.65' => 'Khersonska oblast', 'UA.68' => 'Khmelnytska oblast', 'UA.35' => 'Kirovohradska oblast', 'UA.30' => 'Kyiv', 'UA.32' => 'Kyivska oblast', 'UA.09' => 'Luhanska oblast', 'UA.46' => 'Lvivska oblast', 'UA.48' => 'Mykolaivska oblast', 'UA.51' => 'Odeska oblast', 'UA.53' => 'Poltavska oblast', 'UA.56' => 'Rivnenska oblast', 'UA.40' => 'Sevastopol', 'UA.59' => 'Sumska oblast', 'UA.61' => 'Ternopilska oblast', 'UA.05' => 'Vinnytska oblast', 'UA.07' => 'Volynska oblast', 'UA.21' => 'Zakarpatska oblast', 'UA.23' => 'Zaporizka oblast', 'UA.18' => 'Zhytomyrska oblast'],
'UG' => ['UG.314' => 'Abim', 'UG.301' => 'Adjumani', 'UG.322' => 'Agago', 'UG.323' => 'Alebtong', 'UG.315' => 'Amolatar', 'UG.324' => 'Amudat', 'UG.216' => 'Amuria', 'UG.316' => 'Amuru', 'UG.302' => 'Apac', 'UG.303' => 'Arua', 'UG.217' => 'Budaka', 'UG.218' => 'Bududa', 'UG.201' => 'Bugiri', 'UG.235' => 'Bugweri', 'UG.420' => 'Buhweju', 'UG.117' => 'Buikwe', 'UG.219' => 'Bukedea', 'UG.118' => 'Bukomansibi', 'UG.220' => 'Bukwo', 'UG.225' => 'Bulambuli', 'UG.416' => 'Buliisa', 'UG.401' => 'Bundibugyo', 'UG.430' => 'Bunyangabu', 'UG.402' => 'Bushenyi', 'UG.202' => 'Busia', 'UG.221' => 'Butaleja', 'UG.119' => 'Butambala', 'UG.233' => 'Butebo', 'UG.120' => 'Buvuma', 'UG.226' => 'Buyende', 'UG.317' => 'Dokolo', 'UG.121' => 'Gomba', 'UG.304' => 'Gulu', 'UG.403' => 'Hoima', 'UG.417' => 'Ibanda', 'UG.203' => 'Iganga', 'UG.418' => 'Isingiro', 'UG.204' => 'Jinja', 'UG.318' => 'Kaabong', 'UG.404' => 'Kabale', 'UG.405' => 'Kabarole', 'UG.213' => 'Kaberamaido', 'UG.427' => 'Kagadi', 'UG.428' => 'Kakumiro', 'UG.237' => 'Kalaki', 'UG.101' => 'Kalangala', 'UG.222' => 'Kaliro', 'UG.122' => 'Kalungu', 'UG.102' => 'Kampala', 'UG.205' => 'Kamuli', 'UG.413' => 'Kamwenge', 'UG.414' => 'Kanungu', 'UG.206' => 'Kapchorwa', 'UG.236' => 'Kapelebyong', 'UG.335' => 'Karenga', 'UG.126' => 'Kasanda', 'UG.406' => 'Kasese', 'UG.207' => 'Katakwi', 'UG.112' => 'Kayunga', 'UG.433' => 'Kazo', 'UG.407' => 'Kibaale', 'UG.103' => 'Kiboga', 'UG.227' => 'Kibuku', 'UG.432' => 'Kikuube', 'UG.419' => 'Kiruhura', 'UG.421' => 'Kiryandongo', 'UG.408' => 'Kisoro', 'UG.434' => 'Kitagwenda', 'UG.305' => 'Kitgum', 'UG.319' => 'Koboko', 'UG.325' => 'Kole', 'UG.306' => 'Kotido', 'UG.208' => 'Kumi', 'UG.333' => 'Kwania', 'UG.228' => 'Kween', 'UG.123' => 'Kyankwanzi', 'UG.422' => 'Kyegegwa', 'UG.415' => 'Kyenjojo', 'UG.125' => 'Kyotera', 'UG.326' => 'Lamwo', 'UG.307' => 'Lira', 'UG.229' => 'Luuka', 'UG.104' => 'Luwero', 'UG.124' => 'Lwengo', 'UG.114' => 'Lyantonde', 'UG.336' => 'Madi-Okollo', 'UG.223' => 'Manafwa', 'UG.320' => 'Maracha', 'UG.105' => 'Masaka', 'UG.409' => 'Masindi', 'UG.214' => 'Mayuge', 'UG.209' => 'Mbale', 'UG.410' => 'Mbarara', 'UG.423' => 'Mitooma', 'UG.115' => 'Mityana', 'UG.308' => 'Moroto', 'UG.309' => 'Moyo', 'UG.106' => 'Mpigi', 'UG.107' => 'Mubende', 'UG.108' => 'Mukono', 'UG.334' => 'Nabilatuk', 'UG.311' => 'Nakapiripirit', 'UG.116' => 'Nakaseke', 'UG.109' => 'Nakasongola', 'UG.230' => 'Namayingo', 'UG.234' => 'Namisindwa', 'UG.224' => 'Namutumba', 'UG.327' => 'Napak', 'UG.310' => 'Nebbi', 'UG.231' => 'Ngora', 'UG.424' => 'Ntoroko', 'UG.411' => 'Ntungamo', 'UG.328' => 'Nwoya', 'UG.337' => 'Obongi', 'UG.331' => 'Omoro', 'UG.329' => 'Otuke', 'UG.321' => 'Oyam', 'UG.312' => 'Pader', 'UG.332' => 'Pakwach', 'UG.210' => 'Pallisa', 'UG.110' => 'Rakai', 'UG.429' => 'Rubanda', 'UG.425' => 'Rubirizi', 'UG.431' => 'Rukiga', 'UG.412' => 'Rukungiri', 'UG.435' => 'Rwampara', 'UG.111' => 'Sembabule', 'UG.232' => 'Serere', 'UG.426' => 'Sheema', 'UG.215' => 'Sironko', 'UG.211' => 'Soroti', 'UG.212' => 'Tororo', 'UG.113' => 'Wakiso', 'UG.313' => 'Yumbe', 'UG.330' => 'Zombo'],
'UM' => ['UM.81' => 'Baker Island', 'UM.84' => 'Howland Island', 'UM.86' => 'Jarvis Island', 'UM.67' => 'Johnston Atoll', 'UM.89' => 'Kingman Reef', 'UM.71' => 'Midway Islands', 'UM.76' => 'Navassa Island', 'UM.95' => 'Palmyra Atoll', 'UM.79' => 'Wake Island'],
'US' => ['US.AL' => 'Alabama', 'US.AK' => 'Alaska', 'US.AZ' => 'Arizona', 'US.AR' => 'Arkansas', 'US.CA' => 'California', 'US.CO' => 'Colorado', 'US.CT' => 'Connecticut', 'US.DE' => 'Delaware', 'US.DC' => 'District of Columbia', 'US.FL' => 'Florida', 'US.GA' => 'Georgia', 'US.HI' => 'Hawaii', 'US.ID' => 'Idaho', 'US.IL' => 'Illinois', 'US.IN' => 'Indiana', 'US.IA' => 'Iowa', 'US.KS' => 'Kansas', 'US.KY' => 'Kentucky', 'US.LA' => 'Louisiana', 'US.ME' => 'Maine', 'US.MD' => 'Maryland', 'US.MA' => 'Massachusetts', 'US.MI' => 'Michigan', 'US.MN' => 'Minnesota', 'US.MS' => 'Mississippi', 'US.MO' => 'Missouri', 'US.MT' => 'Montana', 'US.NE' => 'Nebraska', 'US.NV' => 'Nevada', 'US.NH' => 'New Hampshire', 'US.NJ' => 'New Jersey', 'US.NM' => 'New Mexico', 'US.NY' => 'New York', 'US.NC' => 'North Carolina', 'US.ND' => 'North Dakota', 'US.OH' => 'Ohio', 'US.OK' => 'Oklahoma', 'US.OR' => 'Oregon', 'US.PA' => 'Pennsylvania', 'US.RI' => 'Rhode Island', 'US.SC' => 'South Carolina', 'US.SD' => 'South Dakota', 'US.TN' => 'Tennessee', 'US.TX' => 'Texas', 'US.UT' => 'Utah', 'US.VT' => 'Vermont', 'US.VA' => 'Virginia', 'US.WA' => 'Washington', 'US.WV' => 'West Virginia', 'US.WI' => 'Wisconsin', 'US.WY' => 'Wyoming'],
'UY' => ['UY.AR' => 'Artigas', 'UY.CA' => 'Canelones', 'UY.CL' => 'Cerro Largo', 'UY.CO' => 'Colonia', 'UY.DU' => 'Durazno', 'UY.FS' => 'Flores', 'UY.FD' => 'Florida', 'UY.LA' => 'Lavalleja', 'UY.MA' => 'Maldonado', 'UY.MO' => 'Montevideo', 'UY.PA' => 'Paysandu', 'UY.RN' => 'Rio Negro', 'UY.RV' => 'Rivera', 'UY.RO' => 'Rocha', 'UY.SA' => 'Salto', 'UY.SJ' => 'San Jose', 'UY.SO' => 'Soriano', 'UY.TA' => 'Tacuarembo', 'UY.TT' => 'Treinta y Tres'],
'UZ' => ['UZ.AN' => 'Andijon', 'UZ.BU' => 'Buxoro', 'UZ.FA' => 'Farg\'ona', 'UZ.JI' => 'Jizzax', 'UZ.NG' => 'Namangan', 'UZ.NW' => 'Navoiy', 'UZ.QA' => 'Qashqadaryo', 'UZ.QR' => 'Qoraqalpog\'iston Respublikasi', 'UZ.SA' => 'Samarqand', 'UZ.SI' => 'Sirdaryo', 'UZ.SU' => 'Surxondaryo', 'UZ.TK' => 'Toshkent', 'UZ.XO' => 'Xorazm'],
'VC' => ['VC.01' => 'Charlotte', 'VC.06' => 'Grenadines', 'VC.03' => 'Saint David', 'VC.04' => 'Saint George', 'VC.05' => 'Saint Patrick'],
'VE' => ['VE.Z' => 'Amazonas', 'VE.B' => 'Anzoategui', 'VE.C' => 'Apure', 'VE.D' => 'Aragua', 'VE.E' => 'Barinas', 'VE.F' => 'Bolivar', 'VE.G' => 'Carabobo', 'VE.H' => 'Cojedes', 'VE.Y' => 'Delta Amacuro', 'VE.W' => 'Dependencias Federales', 'VE.A' => 'Distrito Capital', 'VE.I' => 'Falcon', 'VE.J' => 'Guarico', 'VE.X' => 'La Guaira', 'VE.K' => 'Lara', 'VE.L' => 'Merida', 'VE.M' => 'Miranda', 'VE.N' => 'Monagas', 'VE.O' => 'Nueva Esparta', 'VE.P' => 'Portuguesa', 'VE.R' => 'Sucre', 'VE.S' => 'Tachira', 'VE.T' => 'Trujillo', 'VE.U' => 'Yaracuy', 'VE.V' => 'Zulia'],
'VN' => ['VN.44' => 'An Giang', 'VN.43' => 'Ba Ria - Vung Tau', 'VN.54' => 'Bac Giang', 'VN.53' => 'Bac Kan', 'VN.55' => 'Bac Lieu', 'VN.56' => 'Bac Ninh', 'VN.50' => 'Ben Tre', 'VN.31' => 'Binh Dinh', 'VN.57' => 'Binh Duong', 'VN.58' => 'Binh Phuoc', 'VN.40' => 'Binh Thuan', 'VN.59' => 'Ca Mau', 'VN.CT' => 'Can Tho', 'VN.04' => 'Cao Bang', 'VN.DN' => 'Da Nang', 'VN.33' => 'Dak Lak', 'VN.72' => 'Dak Nong', 'VN.71' => 'Dien Bien', 'VN.39' => 'Dong Nai', 'VN.45' => 'Dong Thap', 'VN.30' => 'Gia Lai', 'VN.03' => 'Ha Giang', 'VN.63' => 'Ha Nam', 'VN.HN' => 'Ha Noi', 'VN.23' => 'Ha Tinh', 'VN.61' => 'Hai Duong', 'VN.HP' => 'Hai Phong', 'VN.73' => 'Hau Giang', 'VN.SG' => 'Ho Chi Minh', 'VN.14' => 'Hoa Binh', 'VN.66' => 'Hung Yen', 'VN.34' => 'Khanh Hoa', 'VN.47' => 'Kien Giang', 'VN.28' => 'Kon Tum', 'VN.01' => 'Lai Chau', 'VN.35' => 'Lam Dong', 'VN.09' => 'Lang Son', 'VN.02' => 'Lao Cai', 'VN.41' => 'Long An', 'VN.67' => 'Nam Dinh', 'VN.22' => 'Nghe An', 'VN.18' => 'Ninh Binh', 'VN.36' => 'Ninh Thuan', 'VN.68' => 'Phu Tho', 'VN.32' => 'Phu Yen', 'VN.24' => 'Quang Binh', 'VN.27' => 'Quang Nam', 'VN.29' => 'Quang Ngai', 'VN.13' => 'Quang Ninh', 'VN.25' => 'Quang Tri', 'VN.52' => 'Soc Trang', 'VN.05' => 'Son La', 'VN.37' => 'Tay Ninh', 'VN.20' => 'Thai Binh', 'VN.69' => 'Thai Nguyen', 'VN.21' => 'Thanh Hoa', 'VN.26' => 'Thua Thien-Hue', 'VN.46' => 'Tien Giang', 'VN.51' => 'Tra Vinh', 'VN.07' => 'Tuyen Quang', 'VN.49' => 'Vinh Long', 'VN.70' => 'Vinh Phuc', 'VN.06' => 'Yen Bai'],
'VU' => ['VU.MAP' => 'Malampa', 'VU.PAM' => 'Penama', 'VU.SAM' => 'Sanma', 'VU.SEE' => 'Shefa', 'VU.TAE' => 'Tafea', 'VU.TOB' => 'Torba'],
'WF' => ['WF.AL' => 'Alo', 'WF.SG' => 'Sigave', 'WF.UV' => 'Uvea'],
'WS' => ['WS.AA' => 'A\'ana', 'WS.AL' => 'Aiga-i-le-Tai', 'WS.AT' => 'Atua', 'WS.FA' => 'Fa\'asaleleaga', 'WS.GE' => 'Gaga\'emauga', 'WS.GI' => 'Gagaifomauga', 'WS.PA' => 'Palauli', 'WS.SA' => 'Satupa\'itea', 'WS.TU' => 'Tuamasaga', 'WS.VF' => 'Va\'a-o-Fonoti', 'WS.VS' => 'Vaisigano'],
'YE' => ['YE.AD' => '\'Adan', 'YE.AM' => '\'Amran', 'YE.AB' => 'Abyan', 'YE.DA' => 'Ad Dali\'', 'YE.BA' => 'Al Bayda\'', 'YE.HU' => 'Al Hudaydah', 'YE.JA' => 'Al Jawf', 'YE.MR' => 'Al Mahrah', 'YE.MW' => 'Al Mahwit', 'YE.SA' => 'Amanat al \'Asimah', 'YE.DH' => 'Dhamar', 'YE.HD' => 'Hadramawt', 'YE.HJ' => 'Hajjah', 'YE.IB' => 'Ibb', 'YE.LA' => 'Lahij', 'YE.MA' => 'Ma\'rib', 'YE.RA' => 'Raymah', 'YE.SD' => 'Sa\'dah', 'YE.SN' => 'San\'a\'', 'YE.SH' => 'Shabwah', 'YE.TA' => 'Ta\'izz', 'YE.SU' => 'Arkhabil Suqutra'],
'ZA' => ['ZA.EC' => 'Eastern Cape', 'ZA.FS' => 'Free State', 'ZA.GT' => 'Gauteng', 'ZA.NL' => 'Kwazulu-Natal', 'ZA.LP' => 'Limpopo', 'ZA.MP' => 'Mpumalanga', 'ZA.NW' => 'North-West', 'ZA.NC' => 'Northern Cape', 'ZA.WC' => 'Western Cape'],
'ZM' => ['ZM.02' => 'Central', 'ZM.08' => 'Copperbelt', 'ZM.03' => 'Eastern', 'ZM.04' => 'Luapula', 'ZM.09' => 'Lusaka', 'ZM.10' => 'Muchinga', 'ZM.06' => 'North-Western', 'ZM.05' => 'Northern', 'ZM.07' => 'Southern', 'ZM.01' => 'Western'],
'ZW' => ['ZW.BU' => 'Bulawayo', 'ZW.HA' => 'Harare', 'ZW.MA' => 'Manicaland', 'ZW.MC' => 'Mashonaland Central', 'ZW.ME' => 'Mashonaland East', 'ZW.MW' => 'Mashonaland West', 'ZW.MV' => 'Masvingo', 'ZW.MN' => 'Matabeleland North', 'ZW.MS' => 'Matabeleland South', 'ZW.MI' => 'Midlands'],
];
if (isset($regions[$country_code])) {
foreach ($regions[$country_code] as $region_code => $name) {
if ($name == $region_name) {
return $region_code;
}
}
}
return false;
}
private function is_setup_completed()
{
if ($this->get_option('lookup_mode') == 'ws' && $this->get_option('api_key')) {
return true;
}
if ($this->get_option('lookup_mode') == 'bin' && is_file(IP2LOCATION_DIR . $this->get_option('database'))) {
return true;
}
return false;
}
private function get_database_date()
{
if (!is_file(IP2LOCATION_DIR . $this->get_option('database'))) {
return;
}
$obj = new \IP2Location\Database(IP2LOCATION_DIR . $this->get_option('database'), \IP2Location\Database::FILE_IO);
return date('Y-m-d', strtotime(str_replace('.', '-', $obj->getDatabaseVersion())));
}
private function is_region_supported()
{
if ($this->get_option('lookup_mode') == 'ws' && $this->get_option('api_key')) {
return true;
}
if (!is_file(IP2LOCATION_DIR . $this->get_option('database'))) {
return null;
}
$obj = new \IP2Location\Database(IP2LOCATION_DIR . $this->get_option('database'), \IP2Location\Database::FILE_IO);
$result = $obj->lookup('8.8.8.8', \IP2Location\Database::ALL);
if (preg_match('/unavailable/', $result['regionName'])) {
return false;
}
return true;
}
private function cidr_match($ip, $cidr)
{
list($subnet, $mask) = explode('/', $cidr);
if (filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4) && filter_var($subnet, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
return (ip2long($ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($subnet);
} elseif (filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6) && filter_var($subnet, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
$ip = inet_pton($ip);
$subnet = inet_pton($subnet);
$binMask = str_repeat('f', (int)($mask / 4));
switch ($mask % 4) {
case 0:
break;
case 1:
$binMask .= '8';
break;
case 2:
$binMask .= 'c';
break;
case 3:
$binMask .= 'e';
break;
}
$binMask = str_pad($binMask, 32, '0');
$binMask = pack('H*', $binMask);
return ($ip & $binMask) == $subnet;
}
return false;
}
private function cache_add($key, $value)
{
$value = is_array($value) ? $value : [$value];
file_put_contents(IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR . md5($key . '_ip2location_redirection') . '.json', json_encode($value));
}
private function cache_get($key)
{
if (file_exists(IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR . md5($key . '_ip2location_redirection') . '.json')) {
return json_decode(file_get_contents(IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR . md5($key . '_ip2location_redirection') . '.json'));
}
return null;
}
// Drop expired files, then trim to the ceiling (oldest first).
private function cache_clear($ttl_hours = self::CACHE_TTL_HOURS, $budget = 20000)
{
$dir = IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR;
if (!is_dir($dir)) {
return;
}
$files = @scandir($dir);
if (!$files) {
return;
}
$expire = time() - (60 * 60 * $ttl_hours);
$entries = [];
foreach ($files as $file) {
if (substr($file, -5) != '.json') {
continue;
}
$mtime = @filemtime($dir . $file);
if ($mtime !== false) {
$entries[$dir . $file] = $mtime;
}
}
// 1. Drop expired entries.
foreach ($entries as $path => $mtime) {
if ($budget <= 0) {
return;
}
if ($mtime < $expire) {
$this->cache_delete($path);
unset($entries[$path]);
$budget--;
}
}
// 2. Enforce the ceiling, evicting the oldest entries first.
$excess = count($entries) - self::CACHE_MAX_FILES;
if ($excess <= 0) {
return;
}
asort($entries);
foreach ($entries as $path => $mtime) {
if ($excess <= 0 || $budget <= 0) {
return;
}
$this->cache_delete($path);
$excess--;
$budget--;
}
}
// WP_Filesystem() can fail to init; fall back to unlink().
private function cache_delete($path)
{
require_once ABSPATH . 'wp-admin/includes/file.php';
if (empty($GLOBALS['wp_filesystem'])) {
WP_Filesystem();
}
if (!empty($GLOBALS['wp_filesystem']) && is_object($GLOBALS['wp_filesystem'])) {
return $GLOBALS['wp_filesystem']->delete($path);
}
return @unlink($path);
}
private function cache_size()
{
$size = 0;
$files = @scandir(IP2LOCATION_DIR . 'caches');
if (!$files) {
return 0;
}
foreach ($files as $file) {
if (substr($file, -5) == '.json') {
$size += (int) @filesize(IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR . $file);
}
}
return $size;
}
private function cache_flush()
{
$dir = IP2LOCATION_DIR . 'caches' . \DIRECTORY_SEPARATOR;
$files = @scandir($dir);
if (!$files) {
return;
}
foreach ($files as $file) {
if (substr($file, -5) == '.json') {
$this->cache_delete($dir . $file);
}
}
}
private function get_page_id()
{
$post_name = preg_replace('/\/?\?.+$/', '', trim($_SERVER['REQUEST_URI'], '/'));
if (strrpos($post_name, '/') !== false) {
$post_name = substr($post_name, strrpos($post_name, '/') + 1);
}
$results = $this->wpdb_get_results("SELECT * FROM {$GLOBALS['wpdb']->prefix}posts WHERE post_name = %s", [
$post_name
]);
return ($results) ? $results[0]->ID : null;
}
private function get_post_title($post_id)
{
return $this->wpdb_get_value("SELECT `post_title` FROM {$GLOBALS['wpdb']->prefix}posts WHERE `ID` = %d", [
$post_id
]);
}
private function get_permalink($page_id)
{
$results = $this->wpdb_get_results("SELECT * FROM {$GLOBALS['wpdb']->prefix}posts WHERE ID = %d", [
$page_id
]);
if ($results) {
if (preg_match('/page_id=[0-9]+$/', $results[0]->guid)) {
return '/' . $results[0]->post_name;
}
return $results[0]->guid;
}
return null;
}
private function sanitize_array($array)
{
if (is_string($array)) {
return sanitize_text_field($array);
}
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = $this->sanitize_array($value);
} else {
$array[$key] = sanitize_text_field($value);
}
}
return $array;
}
private function sanitize_list($list)
{
if (strpos($list, ';') === false && !filter_var(str_replace('*', '0', $list), \FILTER_VALIDATE_IP, \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE)) {
return;
}
$items = [];
$parts = explode(';', $list);
sort($parts);
foreach ($parts as $part) {
if (strpos($part, '/') !== false) {
list($ip, $range) = explode('/', $part);
// Skip invalid IP address
if (!filter_var($ip, \FILTER_VALIDATE_IP)) {
continue;
}
// Invalid IPv4 range
if (filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4) && ((int) $range < 1 || (int) $range > 32)) {
continue;
}
// Invalid IPv6 range
if (filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6) && ((int) $range < 1 || (int) $range > 128)) {
continue;
}
} elseif (!filter_var(str_replace('*', '0', $part), \FILTER_VALIDATE_IP)) {
continue;
}
$items[] = $part;
}
return implode(';', $items);
}
private function http_host()
{
return $_SERVER['HTTP_HOST'] ?? '';
}
private function display_bytes($bytes)
{
$ext = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$index = 0;
for (; $bytes > 1024; ++$index) {
$bytes /= 1024;
}
return number_format((float) $bytes, 0, '.', ',') . ' ' . $ext[$index];
}
}