blob: a14aaa3b0783b2d7904bd48fcb6b79d0e59f750b [file] [log] [blame]
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001#!/usr/bin/python2
Hung-Te Lin34f3d382015-04-10 18:18:23 +08002# -*- coding: utf-8 -*-
Hung-Te Lin76c55b22015-03-31 14:47:14 +08003# Copyright 2015 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Authoritative source for Chromium OS region/locale configuration.
8
9Run this module to display all known regions (use --help to see options).
10"""
11
12from __future__ import print_function
13
14import argparse
15import collections
16import json
17import re
18import sys
19
20import yaml
21
22
23# The regular expression to check values in Region.keyboards and Region.locales.
24# Keyboards should come with xkb: protocol, or the input methods (ime:, m17n:).
25# Examples: xkb:us:intl:eng, ime:ime:zh-t:cangjie
26KEYBOARD_PATTERN = re.compile(r'^xkb:\w+:\w*:\w+$|'
27 r'^(ime|m17n|t13n):[\w:-]+$')
28# Locale should be a combination of language and location.
29# Examples: en-US, ja.
30LOCALE_PATTERN = re.compile(r'^(\w+)(-[A-Z0-9]+)?$')
31
32
33class Enum(frozenset):
34 """An enumeration type.
35
36 Usage:
37 To create a enum object:
38 dummy_enum = Enum(['A', 'B', 'C'])
39
40 To access a enum object, use:
41 dummy_enum.A
42 dummy_enum.B
43 """
44
45 def __getattr__(self, name):
46 if name in self:
47 return name
48 raise AttributeError
49
50
51class RegionException(Exception):
52 """Exception in Region handling."""
53 pass
54
55
56def MakeList(value):
57 """Converts the given value to a list.
58
59 Returns:
60 A list of elements from "value" if it is iterable (except string);
61 otherwise, a list contains only one element.
62 """
63 if (isinstance(value, collections.Iterable) and
64 not isinstance(value, basestring)):
65 return list(value)
66 return [value]
67
68
69class Region(object):
70 """Comprehensive, standard locale configuration per country/region.
71
72 See :ref:`regions-values` for detailed information on how to set these values.
73 """
74 # pylint gets confused by some of the docstrings.
75 # pylint: disable=C0322
76
77 # ANSI = US-like
78 # ISO = UK-like
79 # JIS = Japanese
Hung-Te Lin4eb4f922016-03-04 11:51:04 +080080 # KS = Korean (see http://crosbug.com/p/50753 for why this is not used yet)
Hung-Te Lin76c55b22015-03-31 14:47:14 +080081 # ABNT2 = Brazilian (like ISO but with an extra key to the left of the
82 # right shift key)
83 KeyboardMechanicalLayout = Enum(['ANSI', 'ISO', 'JIS', 'KS', 'ABNT2'])
84
85 region_code = None
86 """A unique identifier for the region. This may be a lower-case
87 `ISO 3166-1 alpha-2 code
88 <http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2>`_ (e.g., ``us``),
89 a variant within an alpha-2 entity (e.g., ``ca.fr``), or an
90 identifier for a collection of countries or entities (e.g.,
91 ``latam-es-419`` or ``nordic``). See :ref:`region-codes`.
92
93 Note that ``uk`` is not a valid identifier; ``gb`` is used as it is
94 the real alpha-2 code for the UK."""
95
96 keyboards = None
97 """A list of keyboard layout identifiers (e.g., ``xkb:us:intl:eng``
98 or ``m17n:ar``). This field was designed to be the physical keyboard layout
99 in the beginning, and then becomes a list of OOBE keyboard selection, which
100 then includes non-physical layout elements like input methods (``ime:``).
101 To avoid confusion, physical layout is now defined by
102 :py:attr:`keyboard_mechanical_layout`, and this is reserved for logical
103 layouts.
104
105 This is identical to the legacy VPD ``keyboard_layout`` value."""
106
107 time_zones = None
108 """A list of default `tz database time zone
109 <http://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_
110 identifiers (e.g., ``America/Los_Angeles``). See
111 `timezone_settings.cc <http://goo.gl/WSVUeE>`_ for supported time
112 zones.
113
114 This is identical to the legacy VPD ``initial_timezone`` value."""
115
116 locales = None
117 """A list of default locale codes (e.g., ``en-US``); see
118 `l10n_util.cc <http://goo.gl/kVkht>`_ for supported locales.
119
120 This is identital to the legacy VPD ``initial_locale`` field."""
121
122 keyboard_mechanical_layout = None
123 """The keyboard's mechanical layout (``ANSI`` [US-like], ``ISO``
124 [UK-like], ``JIS`` [Japanese], ``ABNT2`` [Brazilian] or ``KS`` [Korean])."""
125
126 description = None
127 """A human-readable description of the region.
128 This defaults to :py:attr:`region_code` if not set."""
129
130 notes = None
131 """Implementation notes about the region. This may be None."""
132
133 numeric_id = None
134 """An integer for mapping into Chrome OS HWID.
135 Please never change this once it is assigned."""
136
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800137 regulatory_domain = None
138 """An ISO 3166-1 alpha 2 upper-cased two-letter region code for setting
139 Wireless regulatory. See crosbug.com/p/38745 for more details.
140
141 When omitted, this will derive from region_code."""
142
Hung-Te Lin1a14cc42015-04-14 01:23:34 +0800143 confirmed = None
144 """An optional boolean flag to indicate if the region data is confirmed."""
145
146 FIELDS = ['numeric_id', 'region_code', 'description', 'keyboards',
147 'time_zones', 'locales', 'keyboard_mechanical_layout',
148 'regulatory_domain']
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800149 """Names of fields that define the region."""
150
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800151 def __init__(self, region_code, keyboards, time_zones, locales,
152 keyboard_mechanical_layout, description=None, notes=None,
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800153 numeric_id=None, regdomain=None):
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800154 """Constructor.
155
156 Args:
157 region_code: See :py:attr:`region_code`.
158 keyboards: See :py:attr:`keyboards`. A single string is accepted for
159 backward compatibility.
160 time_zones: See :py:attr:`time_zones`.
161 locales: See :py:attr:`locales`. A single string is accepted
162 for backward compatibility.
163 keyboard_mechanical_layout: See :py:attr:`keyboard_mechanical_layout`.
164 description: See :py:attr:`description`.
165 notes: See :py:attr:`notes`.
166 numeric_id: See :py:attr:`numeric_id`. This must be None or a
167 non-negative integer.
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800168 regdomain: See :py:attr:`regulatory_domain`.
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800169 """
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800170
171 def regdomain_from_region(region):
172 if region.find('.') >= 0:
173 region = region[:region.index('.')]
174 if len(region) == 2:
175 return region.upper()
176 return None
177
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800178 # Quick check: should be 'gb', not 'uk'
179 if region_code == 'uk':
180 raise RegionException("'uk' is not a valid region code (use 'gb')")
181
182 self.region_code = region_code
183 self.keyboards = MakeList(keyboards)
184 self.time_zones = MakeList(time_zones)
185 self.locales = MakeList(locales)
186 self.keyboard_mechanical_layout = keyboard_mechanical_layout
187 self.description = description or region_code
188 self.notes = notes
189 self.numeric_id = numeric_id
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800190 self.regulatory_domain = (regdomain or regdomain_from_region(region_code))
Hung-Te Lin1a14cc42015-04-14 01:23:34 +0800191 self.confirmed = None
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800192
193 if self.numeric_id is not None:
194 if not isinstance(self.numeric_id, int):
195 raise TypeError('Numeric ID is %r but should be an integer' %
196 (self.numeric_id,))
197 if self.numeric_id < 0:
198 raise ValueError('Numeric ID is %r but should be non-negative' %
199 self.numeric_id)
200
201 for f in (self.keyboards, self.locales):
202 assert all(isinstance(x, str) for x in f), (
203 'Expected a list of strings, not %r' % f)
204 for f in self.keyboards:
205 assert KEYBOARD_PATTERN.match(f), (
206 'Keyboard pattern %r does not match %r' % (
207 f, KEYBOARD_PATTERN.pattern))
208 for f in self.locales:
209 assert LOCALE_PATTERN.match(f), (
210 'Locale %r does not match %r' % (
211 f, LOCALE_PATTERN.pattern))
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800212 assert (self.regulatory_domain and
213 len(self.regulatory_domain) == 2 and
214 self.regulatory_domain.upper() == self.regulatory_domain), (
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800215 'Regulatory domain settings error for region %s' % region_code)
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800216
217 def __repr__(self):
218 return 'Region(%s)' % (', '.join([getattr(self, x) for x in self.FIELDS]))
219
220 def GetFieldsDict(self):
221 """Returns a dict of all substantive fields.
222
223 notes and description are excluded.
224 """
225 return dict((k, getattr(self, k)) for k in self.FIELDS)
226
227_KML = Region.KeyboardMechanicalLayout
228REGIONS_LIST = [
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800229 Region(
230 'au', 'xkb:us::eng', 'Australia/Sydney', 'en-AU', _KML.ANSI,
231 'Australia', None, 1),
232 Region(
233 'be', 'xkb:be::nld', 'Europe/Brussels', 'en-GB', _KML.ISO,
234 'Belgium',
235 'Flemish (Belgian Dutch) keyboard; British English language for '
236 'neutrality', 2),
237 Region(
238 'br', 'xkb:br::por', 'America/Sao_Paulo', 'pt-BR', _KML.ABNT2,
239 'Brazil (ABNT2)',
240 (
241 'ABNT2 = ABNT NBR 10346 variant 2. This is the preferred layout '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800242 'for Brazil. ABNT2 is mostly an ISO layout, but it 12 keys between '
243 'the shift keys; see http://goo.gl/twA5tq'), 3),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800244 Region(
245 'br.abnt', 'xkb:br::por', 'America/Sao_Paulo', 'pt-BR',
246 _KML.ISO, 'Brazil (ABNT)',
247 (
248 'Like ABNT2, but lacking the extra key to the left of the right '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800249 'shift key found in that layout. ABNT2 (the "br" region) is '
250 'preferred to this layout'), 4),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800251 Region(
252 'br.usintl', 'xkb:us:intl:eng', 'America/Sao_Paulo', 'pt-BR',
253 _KML.ANSI, 'Brazil (US Intl)',
254 'Brazil with US International keyboard layout. ABNT2 ("br") and '
255 'ABNT1 ("br.abnt1 ") are both preferred to this.', 5),
256 Region(
257 'ca.ansi', 'xkb:us::eng', 'America/Toronto', 'en-CA', _KML.ANSI,
258 'Canada (US keyboard)',
259 'Canada with US (ANSI) keyboard. Not for en/fr hybrid ANSI '
260 'keyboards; for that you would want ca.hybridansi. See '
261 'http://goto/cros-canada', 6),
262 Region(
263 'ca.fr', 'xkb:ca::fra', 'America/Toronto', 'fr-CA', _KML.ISO,
264 'Canada (French keyboard)',
265 (
266 'Canadian French (ISO) keyboard. The most common configuration for '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800267 'Canadian French SKUs. See http://goto/cros-canada'), 7),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800268 Region(
269 'ca.hybrid', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA',
270 _KML.ISO, 'Canada (hybrid ISO)',
271 (
272 'Canada with hybrid (ISO) xkb:ca:eng:eng + xkb:ca::fra keyboard, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800273 'defaulting to English language and keyboard. Used only if there '
274 'needs to be a single SKU for all of Canada. See '
275 'http://goto/cros-canada'), 8),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800276 Region(
277 'ca.hybridansi', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA',
278 _KML.ANSI, 'Canada (hybrid ANSI)',
279 (
280 'Canada with hybrid (ANSI) xkb:ca:eng:eng + xkb:ca::fra keyboard, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800281 'defaulting to English language and keyboard. Used only if there '
282 'needs to be a single SKU for all of Canada. See '
283 'http://goto/cros-canada'), 9),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800284 Region(
285 'ca.multix', 'xkb:ca:multix:fra', 'America/Toronto', 'fr-CA',
286 _KML.ISO, 'Canada (multilingual)',
287 (
288 "Canadian Multilingual keyboard; you probably don't want this. See "
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800289 'http://goto/cros-canada'), 10),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800290 Region(
cncmidac586332015-10-24 16:13:22 +0800291 'ch', 'xkb:ch::ger', 'Europe/Zurich', 'de-CH', _KML.ISO,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800292 'Switzerland',
cncmidac586332015-10-24 16:13:22 +0800293 'German keyboard', 11),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800294 Region(
295 'de', 'xkb:de::ger', 'Europe/Berlin', 'de', _KML.ISO, 'Germany',
296 None, 12),
297 Region(
298 'es', 'xkb:es::spa', 'Europe/Madrid', 'es', _KML.ISO, 'Spain',
299 None, 13),
300 Region(
301 'fi', 'xkb:fi::fin', 'Europe/Helsinki', 'fi', _KML.ISO, 'Finland',
302 None, 14),
303 Region(
304 'fr', 'xkb:fr::fra', 'Europe/Paris', 'fr', _KML.ISO, 'France',
305 None, 15),
306 Region(
307 'gb', 'xkb:gb:extd:eng', 'Europe/London', 'en-GB', _KML.ISO, 'UK',
308 None, 16),
309 Region(
310 'ie', 'xkb:gb:extd:eng', 'Europe/Dublin', 'en-GB', _KML.ISO,
311 'Ireland', None, 17),
312 Region(
313 'in', 'xkb:us::eng', 'Asia/Calcutta', 'en-US', _KML.ANSI, 'India',
314 None, 18),
315 Region(
316 'it', 'xkb:it::ita', 'Europe/Rome', 'it', _KML.ISO, 'Italy', None,
317 19),
318 Region(
319 'latam-es-419', 'xkb:es::spa', 'America/Mexico_City', 'es-419',
320 _KML.ISO, 'Hispanophone Latin America',
321 (
322 'Spanish-speaking countries in Latin America, using the Iberian '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800323 '(Spain) Spanish keyboard, which is increasingly dominant in '
324 'Latin America. Known to be correct for '
325 'Chile, Colombia, Mexico, Peru; '
326 'still unconfirmed for other es-419 countries. The old Latin '
327 'American layout (xkb:latam::spa) has not been approved; before '
328 'using that you must seek review through http://goto/vpdsettings. '
329 'See also http://goo.gl/Iffuqh. Note that 419 is the UN M.49 '
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800330 'region code for Latin America'), 20, 'MX'),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800331 Region(
332 'my', 'xkb:us::eng', 'Asia/Kuala_Lumpur', 'ms', _KML.ANSI,
333 'Malaysia', None, 21),
334 Region(
335 'nl', 'xkb:us:intl:eng', 'Europe/Amsterdam', 'nl', _KML.ANSI,
336 'Netherlands', None, 22),
337 Region(
338 'nordic', 'xkb:se::swe', 'Europe/Stockholm', 'en-US', _KML.ISO,
339 'Nordics',
340 (
341 'Unified SKU for Sweden, Norway, and Denmark. This defaults '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800342 'to Swedish keyboard layout, but starts with US English language '
343 'for neutrality. Use if there is a single combined SKU for Nordic '
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800344 'countries.'), 23, 'SE'),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800345 Region(
346 'nz', 'xkb:us::eng', 'Pacific/Auckland', 'en-NZ', _KML.ANSI,
347 'New Zealand', None, 24),
348 Region(
349 'ph', 'xkb:us::eng', 'Asia/Manila', 'en-US', _KML.ANSI,
350 'Philippines', None, 25),
351 Region(
352 'ru', 'xkb:ru::rus', 'Europe/Moscow', 'ru', _KML.ANSI, 'Russia',
353 'For R31+ only; R30 and earlier must use US keyboard for login',
354 26),
355 Region(
356 'se', 'xkb:se::swe', 'Europe/Stockholm', 'sv', _KML.ISO, 'Sweden',
357 (
358 'Use this if there separate SKUs for Nordic countries (Sweden, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800359 'Norway, and Denmark), or the device is only shipping to Sweden. '
360 "If there is a single unified SKU, use 'nordic' instead."), 27),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800361 Region(
362 'sg', 'xkb:us::eng', 'Asia/Singapore', 'en-GB', _KML.ANSI,
363 'Singapore', None, 28),
364 Region(
365 'us', 'xkb:us::eng', 'America/Los_Angeles', 'en-US', _KML.ANSI,
366 'United States', None, 29),
367 Region(
368 'jp', 'xkb:jp::jpn', 'Asia/Tokyo', 'ja', _KML.JIS, 'Japan', None,
369 30),
370 Region(
Bernie Thompson5d3b89e2016-01-28 15:55:38 -0800371 'za', 'xkb:gb:extd:eng', 'Africa/Johannesburg', 'en-ZA',
372 _KML.ISO, 'South Africa', None, 31),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800373 Region(
374 'ng', 'xkb:us:intl:eng', 'Africa/Lagos', 'en-GB', _KML.ANSI,
375 'Nigeria', None, 32),
376 Region(
377 'hk',
378 ['xkb:us::eng', 'ime:zh-t:cangjie', 'ime:zh-t:quick',
379 'ime:zh-t:array', 'ime:zh-t:dayi', 'ime:zh-t:zhuyin',
380 'ime:zh-t:pinyin'], 'Asia/Hong_Kong',
381 ['zh-TW', 'en-GB', 'zh-CN'], _KML.ANSI, 'Hong Kong', None, 33),
382 Region(
383 'gcc', ['xkb:us::eng', 'm17n:ar', 't13n:ar'], 'Asia/Riyadh',
384 ['ar', 'en-GB'], _KML.ANSI, 'Gulf Cooperation Council (GCC)',
385 (
386 'GCC is a regional intergovernmental political and economic '
387 'union consisting of all Arab states of the Persian Gulf except '
388 'for Iraq. Its member states are the Islamic monarchies of '
389 'Bahrain, Kuwait, Oman, Qatar, Saudi Arabia, and the United Arab '
390 'Emirates.'), 34, 'SA'),
391 Region(
392 'cz', ['xkb:cz::cze', 'xkb:cz:qwerty:cze'], 'Europe/Prague',
393 ['cs', 'en-GB'], _KML.ISO, 'Czech Republic', None, 35),
394 Region(
395 'th',
396 ['xkb:us::eng', 'm17n:th', 'm17n:th_pattajoti', 'm17n:th_tis'],
397 'Asia/Bangkok', ['th', 'en-GB'], _KML.ANSI, 'Thailand', None, 36),
398 Region(
399 'id', 'xkb:us::ind', 'Asia/Jakarta', ['id', 'en-GB'], _KML.ANSI,
400 'Indonesia', None, 37),
401 Region(
402 'tw',
403 ['xkb:us::eng', 'ime:zh-t:zhuyin', 'ime:zh-t:array',
404 'ime:zh-t:dayi', 'ime:zh-t:cangjie', 'ime:zh-t:quick',
405 'ime:zh-t:pinyin'], 'Asia/Taipei', ['zh-TW', 'en-US'],
406 _KML.ANSI, 'Taiwan', None, 38),
407 Region(
408 'pl', 'xkb:pl::pol', 'Europe/Warsaw', ['pl', 'en-GB'],
409 _KML.ANSI, 'Poland', None, 39),
410 Region(
411 'gr', ['xkb:us::eng', 'xkb:gr::gre', 't13n:el'], 'Europe/Athens',
412 ['el', 'en-GB'], _KML.ANSI, 'Greece', None, 40),
413 Region(
414 'il', ['xkb:us::eng', 'xkb:il::heb', 't13n:he'], 'Asia/Jerusalem',
415 ['he', 'en-US', 'ar'], _KML.ANSI, 'Israel', None, 41),
416 Region(
417 'pt', 'xkb:pt::por', 'Europe/Lisbon', ['pt-PT', 'en-GB'],
418 _KML.ISO, 'Portugal', None, 42),
419 Region(
420 'ro', ['xkb:us::eng', 'xkb:ro::rum'], 'Europe/Bucharest',
421 ['ro', 'hu', 'de', 'en-GB'], _KML.ISO, 'Romania', None, 43),
422 Region(
423 'kr', ['xkb:us::eng', 'ime:ko:hangul'], 'Asia/Seoul',
Hung-Te Lin4eb4f922016-03-04 11:51:04 +0800424 ['ko', 'en-US'], _KML.ANSI, 'South Korea', None, 44),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800425 Region(
426 'ae', 'xkb:us::eng', 'Asia/Dubai', 'ar', _KML.ANSI, 'UAE', None,
427 45),
428 Region(
429 'za.us', 'xkb:us::eng', 'Africa/Johannesburg', 'en-ZA',
430 _KML.ANSI, 'South Africa', None, 46),
431 Region(
432 'vn',
433 ['xkb:us::eng', 'm17n:vi_telex', 'm17n:vi_vni', 'm17n:vi_viqr',
434 'm17n:vi_tcvn'], 'Asia/Ho_Chi_Minh',
435 ['vi', 'en-GB', 'en-US', 'fr', 'zh-TW'], _KML.ANSI, 'Vietnam',
436 None, 47),
437 Region(
438 'at', ['xkb:de::ger', 'xkb:de:neo:ger'], 'Europe/Vienna',
439 ['de', 'en-GB'], _KML.ISO, 'Austria', None, 48),
440 Region(
441 'sk', ['xkb:us::eng', 'xkb:sk::slo'], 'Europe/Bratislava',
442 ['sk', 'hu', 'cs', 'en-GB'], _KML.ISO, 'Slovakia', None, 49),
443 Region(
444 'ch.usintl', 'xkb:us:intl:eng', 'Europe/Zurich', 'en-US',
445 _KML.ANSI, 'Switzerland (US Intl)',
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800446 'Switzerland with US International keyboard layout.', 50),
447 Region(
448 'pe', 'xkb:pe::spa', 'America/Lima', 'es-PE',
449 _KML.ANSI, 'Peru', None, 115),
450 Region(
451 'sa', 'xkb:us::eng', 'Asia/Riyadh', ['ar-SA', 'en'], _KML.ANSI,
452 'Saudi Arabia', None, 128),
453 Region(
454 'mx', 'xkb:mx::spa', 'America/Mexico_City', 'es-MX', _KML.ANSI,
455 'Mexico', None, 154),
456 Region(
457 'cl', 'xkb:cl::spa', 'America/Santiago', 'es-CL', _KML.ANSI, 'Chile',
458 None, 176),
459 Region(
460 'kw', 'xkb:kw::ara', 'Asia/Kuwait', ['ar-KW', 'en'], _KML.ANSI,
461 'Kuwait', None, 201),
462 Region(
463 'uy', 'xkb:uy::spa', 'America/Montevideo', 'es-UY', _KML.ANSI,
464 'Uruguay', None, 216)]
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800465"""A list of :py:class:`regions.Region` objects for
466all **confirmed** regions. A confirmed region is a region whose
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800467properties are known to be correct and valid: all contents (locale / timezone /
468keyboards) are supported by Chrome."""
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800469
470
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800471UNCONFIRMED_REGIONS_LIST = [
472 Region(
473 'bd', 'xkb:bd::ben', 'Asia/Dhaka', ['bn-BD', 'en'], _KML.ANSI,
474 'Bangladesh', None, 51),
475 Region(
476 'bf', 'xkb:bf::fra', 'Africa/Ouagadougou', 'fr-BF', _KML.ANSI,
477 'Burkina Faso', None, 52),
478 Region(
479 'bg', ['xkb:bg::bul', 'xkb:bg:phonetic:bul'], 'Europe/Sofia',
480 ['bg', 'tr', 'en-GB'], _KML.ANSI, 'Bulgaria', None, 53),
481 Region(
482 'ba', 'xkb:ba::bos', 'Europe/Sarajevo', ['bs', 'hr-BA', 'sr-BA'],
483 _KML.ANSI, 'Bosnia and Herzegovina', None, 54),
484 Region(
485 'bb', 'xkb:bb::eng', 'America/Barbados', 'en-BB', _KML.ANSI,
486 'Barbados', None, 55),
487 Region(
488 'wf', 'xkb:us::eng', 'Pacific/Wallis', ['wls', 'fud', 'fr-WF'],
489 _KML.ANSI, 'Wallis and Futuna', None, 56),
490 Region(
491 'bl', 'xkb:bl::fra', 'America/St_Barthelemy', 'fr', _KML.ANSI,
492 'Saint Barthelemy', None, 57),
493 Region(
494 'bm', 'xkb:bm::eng', 'Atlantic/Bermuda', ['en-BM', 'pt'],
495 _KML.ANSI, 'Bermuda', None, 58),
496 Region(
497 'bn', 'xkb:bn::msa', 'Asia/Brunei', ['ms-BN', 'en-BN'],
498 _KML.ANSI, 'Brunei', None, 59),
499 Region(
500 'bo', 'xkb:bo::spa', 'America/La_Paz', ['es-BO', 'qu', 'ay'],
501 _KML.ANSI, 'Bolivia', None, 60),
502 Region(
503 'bh', 'xkb:bh::ara', 'Asia/Bahrain', ['ar-BH', 'en', 'fa', 'ur'],
504 _KML.ANSI, 'Bahrain', None, 61),
505 Region(
506 'bi', 'xkb:bi::fra', 'Africa/Bujumbura', ['fr-BI', 'rn'],
507 _KML.ANSI, 'Burundi', None, 62),
508 Region(
509 'bj', 'xkb:bj::fra', 'Africa/Porto-Novo', 'fr-BJ', _KML.ANSI,
510 'Benin', None, 63),
511 Region(
512 'bt', 'xkb:bt::dzo', 'Asia/Thimphu', 'dz', _KML.ANSI, 'Bhutan',
513 None, 64),
514 Region(
515 'jm', 'xkb:jm::eng', 'America/Jamaica', 'en-JM', _KML.ANSI,
516 'Jamaica', None, 65),
517 Region(
518 'bw', 'xkb:bw::eng', 'Africa/Gaborone', ['en-BW', 'tn-BW'],
519 _KML.ANSI, 'Botswana', None, 66),
520 Region(
521 'ws', 'xkb:ws::smo', 'Pacific/Apia', ['sm', 'en-WS'], _KML.ANSI,
522 'Samoa', None, 67),
523 Region(
524 'bq', 'xkb:bq::nld', 'America/Kralendijk', ['nl', 'pap', 'en'],
525 _KML.ANSI, 'Bonaire, Saint Eustatius and Saba ', None, 68),
526 Region(
527 'bs', 'xkb:bs::eng', 'America/Nassau', 'en-BS', _KML.ANSI,
528 'Bahamas', None, 69),
529 Region(
530 'je', 'xkb:je::eng', 'Europe/Jersey', ['en', 'pt'], _KML.ANSI,
531 'Jersey', None, 70),
532 Region(
533 'by', 'xkb:by::bel', 'Europe/Minsk', ['be', 'ru'], _KML.ANSI,
534 'Belarus', None, 71),
535 Region(
536 'bz', 'xkb:bz::eng', 'America/Belize', ['en-BZ', 'es'],
537 _KML.ANSI, 'Belize', None, 72),
538 Region(
539 'rw', 'xkb:rw::kin', 'Africa/Kigali',
540 ['rw', 'en-RW', 'fr-RW', 'sw'], _KML.ANSI, 'Rwanda', None, 73),
541 Region(
542 'rs', 'xkb:rs::srp', 'Europe/Belgrade', ['sr', 'hu', 'bs', 'rom'],
543 _KML.ANSI, 'Serbia', None, 74),
544 Region(
545 'tl', 'xkb:us::eng', 'Asia/Dili', ['tet', 'pt-TL', 'id', 'en'],
546 _KML.ANSI, 'East Timor', None, 75),
547 Region(
548 're', 'xkb:re::fra', 'Indian/Reunion', 'fr-RE', _KML.ANSI,
549 'Reunion', None, 76),
550 Region(
551 'tm', 'xkb:tm::tuk', 'Asia/Ashgabat', ['tk', 'ru', 'uz'],
552 _KML.ANSI, 'Turkmenistan', None, 77),
553 Region(
554 'tj', 'xkb:tj::tgk', 'Asia/Dushanbe', ['tg', 'ru'], _KML.ANSI,
555 'Tajikistan', None, 78),
556 Region(
557 'tk', 'xkb:us::eng', 'Pacific/Fakaofo', ['tkl', 'en-TK'],
558 _KML.ANSI, 'Tokelau', None, 79),
559 Region(
560 'gw', 'xkb:gw::por', 'Africa/Bissau', ['pt-GW', 'pov'],
561 _KML.ANSI, 'Guinea-Bissau', None, 80),
562 Region(
563 'gu', 'xkb:gu::eng', 'Pacific/Guam', ['en-GU', 'ch-GU'],
564 _KML.ANSI, 'Guam', None, 81),
565 Region(
566 'gt', 'xkb:gt::spa', 'America/Guatemala', 'es-GT', _KML.ANSI,
567 'Guatemala', None, 82),
568 Region(
569 'gs', 'xkb:gs::eng', 'Atlantic/South_Georgia', 'en', _KML.ANSI,
570 'South Georgia and the South Sandwich Islands', None, 83),
571 Region(
572 'gq', 'xkb:gq::spa', 'Africa/Malabo', ['es-GQ', 'fr'],
573 _KML.ANSI, 'Equatorial Guinea', None, 84),
574 Region(
575 'gp', 'xkb:gp::fra', 'America/Guadeloupe', 'fr-GP', _KML.ANSI,
576 'Guadeloupe', None, 85),
577 Region(
578 'gy', 'xkb:gy::eng', 'America/Guyana', 'en-GY', _KML.ANSI,
579 'Guyana', None, 86),
580 Region(
581 'gg', 'xkb:gg::eng', 'Europe/Guernsey', ['en', 'fr'], _KML.ANSI,
582 'Guernsey', None, 87),
583 Region(
584 'gf', 'xkb:gf::fra', 'America/Cayenne', 'fr-GF', _KML.ANSI,
585 'French Guiana', None, 88),
586 Region(
587 'ge', 'xkb:ge::geo', 'Asia/Tbilisi', 'ka', _KML.ANSI, 'Georgia', None,
588 89),
589 Region(
590 'gd', 'xkb:gd::eng', 'America/Grenada', 'en-GD', _KML.ANSI,
591 'Grenada', None, 90),
592 Region(
593 'ga', 'xkb:ga::fra', 'Africa/Libreville', 'fr-GA', _KML.ANSI,
594 'Gabon', None, 91),
595 Region(
596 'sv', 'xkb:sv::spa', 'America/El_Salvador', 'es-SV', _KML.ANSI,
597 'El Salvador', None, 92),
598 Region(
599 'gn', 'xkb:gn::fra', 'Africa/Conakry', 'fr-GN', _KML.ANSI,
600 'Guinea', None, 93),
601 Region(
602 'gm', 'xkb:gm::eng', 'Africa/Banjul',
603 ['en-GM', 'mnk', 'wof', 'wo', 'ff'], _KML.ANSI, 'Gambia', None, 94),
604 Region(
605 'gl', 'xkb:gl::kal',
606 ['America/Godthab', 'America/Danmarkshavn',
607 'America/Scoresbysund', 'America/Thule'], ['kl', 'da-GL', 'en'],
608 _KML.ANSI, 'Greenland', None, 95),
609 Region(
610 'gi', 'xkb:gi::eng', 'Europe/Gibraltar',
611 ['en-GI', 'es', 'it', 'pt'], _KML.ANSI, 'Gibraltar', None, 96),
612 Region(
613 'gh', 'xkb:gh::eng', 'Africa/Accra', ['en-GH', 'ak', 'ee', 'tw'],
614 _KML.ANSI, 'Ghana', None, 97),
615 Region(
616 'om', 'xkb:om::ara', 'Asia/Muscat', ['ar-OM', 'en', 'bal', 'ur'],
617 _KML.ANSI, 'Oman', None, 98),
618 Region(
619 'tn', 'xkb:tn::ara', 'Africa/Tunis', ['ar-TN', 'fr'], _KML.ANSI,
620 'Tunisia', None, 99),
621 Region(
622 'jo', 'xkb:jo::ara', 'Asia/Amman', ['ar-JO', 'en'], _KML.ANSI,
623 'Jordan', None, 100),
624 Region(
625 'hr', 'xkb:hr::scr', 'Europe/Zagreb', ['hr', 'en-GB'],
626 _KML.ISO, 'Croatia', None, 101),
627 Region(
628 'ht', 'xkb:ht::hat', 'America/Port-au-Prince', ['ht', 'fr-HT'],
629 _KML.ANSI, 'Haiti', None, 102),
630 Region(
631 'hu', ['xkb:us::eng', 'xkb:hu::hun'], 'Europe/Budapest',
632 ['hu', 'en-GB'], _KML.ISO, 'Hungary', None, 103),
633 Region(
634 'hn', 'xkb:hn::spa', 'America/Tegucigalpa', 'es-HN', _KML.ANSI,
635 'Honduras', None, 104),
636 Region(
637 've', 'xkb:ve::spa', 'America/Caracas', 'es-VE', _KML.ANSI,
638 'Venezuela', None, 105),
639 Region(
640 'pr', 'xkb:pr::eng', 'America/Puerto_Rico', ['en-PR', 'es-PR'],
641 _KML.ANSI, 'Puerto Rico', None, 106),
642 Region(
643 'ps', 'xkb:ps::ara', ['Asia/Gaza', 'Asia/Hebron'], 'ar-PS',
644 _KML.ANSI, 'Palestinian Territory', None, 107),
645 Region(
646 'pw', 'xkb:us::eng', 'Pacific/Palau',
647 ['pau', 'sov', 'en-PW', 'tox', 'ja', 'fil', 'zh'], _KML.ANSI,
648 'Palau', None, 108),
649 Region(
650 'sj', 'xkb:sj::nor', 'Arctic/Longyearbyen', ['no', 'ru'],
651 _KML.ANSI, 'Svalbard and Jan Mayen', None, 109),
652 Region(
653 'py', 'xkb:py::spa', 'America/Asuncion', ['es-PY', 'gn'],
654 _KML.ANSI, 'Paraguay', None, 110),
655 Region(
656 'iq', 'xkb:iq::ara', 'Asia/Baghdad', ['ar-IQ', 'ku', 'hy'],
657 _KML.ANSI, 'Iraq', None, 111),
658 Region(
659 'pa', 'xkb:pa::spa', 'America/Panama', ['es-PA', 'en'],
660 _KML.ANSI, 'Panama', None, 112),
661 Region(
662 'pf', 'xkb:pf::fra',
663 ['Pacific/Tahiti', 'Pacific/Marquesas', 'Pacific/Gambier'],
664 ['fr-PF', 'ty'], _KML.ANSI, 'French Polynesia', None, 113),
665 Region(
666 'pg', 'xkb:pg::eng',
667 ['Pacific/Port_Moresby', 'Pacific/Bougainville'],
668 ['en-PG', 'ho', 'meu', 'tpi'], _KML.ANSI, 'Papua New Guinea', None,
669 114),
670 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800671 'pk', 'xkb:pk::urd', 'Asia/Karachi',
672 ['ur-PK', 'en-PK', 'pa', 'sd', 'ps', 'brh'], _KML.ANSI,
673 'Pakistan', None, 116),
674 Region(
675 'pn', 'xkb:pn::eng', 'Pacific/Pitcairn', 'en-PN', _KML.ANSI,
676 'Pitcairn', None, 117),
677 Region(
678 'pm', 'xkb:pm::fra', 'America/Miquelon', 'fr-PM', _KML.ANSI,
679 'Saint Pierre and Miquelon', None, 118),
680 Region(
681 'zm', 'xkb:zm::eng', 'Africa/Lusaka',
682 ['en-ZM', 'bem', 'loz', 'lun', 'lue', 'ny', 'toi'], _KML.ANSI,
683 'Zambia', None, 119),
684 Region(
685 'eh', 'xkb:eh::ara', 'Africa/El_Aaiun', ['ar', 'mey'],
686 _KML.ANSI, 'Western Sahara', None, 120),
687 Region(
688 'ee', 'xkb:ee::est', 'Europe/Tallinn', ['et', 'ru', 'en-GB'], _KML.ISO,
689 'Estonia', None, 121),
690 Region(
691 'eg', 'xkb:eg::ara', 'Africa/Cairo', ['ar-EG', 'en', 'fr'],
692 _KML.ANSI, 'Egypt', None, 122),
693 Region(
694 'ec', 'xkb:ec::spa', ['America/Guayaquil', 'Pacific/Galapagos'],
695 'es-EC', _KML.ANSI, 'Ecuador', None, 123),
696 Region(
697 'sb', 'xkb:sb::eng', 'Pacific/Guadalcanal', ['en-SB', 'tpi'],
698 _KML.ANSI, 'Solomon Islands', None, 124),
699 Region(
700 'et', 'xkb:et::amh', 'Africa/Addis_Ababa',
701 ['am', 'en-ET', 'om-ET', 'ti-ET', 'so-ET', 'sid'], _KML.ANSI,
702 'Ethiopia', None, 125),
703 Region(
704 'so', 'xkb:so::som', 'Africa/Mogadishu',
705 ['so-SO', 'ar-SO', 'it', 'en-SO'], _KML.ANSI, 'Somalia', None, 126),
706 Region(
707 'zw', 'xkb:zw::eng', 'Africa/Harare', ['en-ZW', 'sn', 'nr', 'nd'],
708 _KML.ANSI, 'Zimbabwe', None, 127),
709 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800710 'er', 'xkb:er::aar', 'Africa/Asmara',
711 ['aa-ER', 'ar', 'tig', 'kun', 'ti-ER'], _KML.ANSI, 'Eritrea', None,
712 129),
713 Region(
714 'me', 'xkb:me::srp', 'Europe/Podgorica',
715 ['sr', 'hu', 'bs', 'sq', 'hr', 'rom'], _KML.ANSI, 'Montenegro',
716 None, 130),
717 Region(
718 'md', 'xkb:md::ron', 'Europe/Chisinau', ['ro', 'ru', 'gag', 'tr'],
719 _KML.ANSI, 'Moldova', None, 131),
720 Region(
721 'mg', 'xkb:mg::fra', 'Indian/Antananarivo', ['fr-MG', 'mg'],
722 _KML.ANSI, 'Madagascar', None, 132),
723 Region(
724 'mf', 'xkb:mf::fra', 'America/Marigot', 'fr', _KML.ANSI,
725 'Saint Martin', None, 133),
726 Region(
727 'ma', 'xkb:ma::ara', 'Africa/Casablanca', ['ar-MA', 'fr'],
728 _KML.ANSI, 'Morocco', None, 134),
729 Region(
730 'mc', 'xkb:mc::fra', 'Europe/Monaco', ['fr-MC', 'en', 'it'],
731 _KML.ANSI, 'Monaco', None, 135),
732 Region(
733 'uz', 'xkb:uz::uzb', ['Asia/Samarkand', 'Asia/Tashkent'],
734 ['uz', 'ru', 'tg'], _KML.ANSI, 'Uzbekistan', None, 136),
735 Region(
736 'mm', 'xkb:mm::mya', 'Asia/Rangoon', 'my', _KML.ANSI, 'Myanmar',
737 None, 137),
738 Region(
739 'ml', 'xkb:ml::fra', 'Africa/Bamako', ['fr-ML', 'bm'],
740 _KML.ANSI, 'Mali', None, 138),
741 Region(
742 'mo', 'xkb:mo::zho', 'Asia/Macau', ['zh', 'zh-MO', 'pt'],
743 _KML.ANSI, 'Macao', None, 139),
744 Region(
745 'mn', 'xkb:mn::mon',
746 ['Asia/Ulaanbaatar', 'Asia/Hovd', 'Asia/Choibalsan'],
747 ['mn', 'ru'], _KML.ANSI, 'Mongolia', None, 140),
748 Region(
749 'mh', 'xkb:mh::mah', ['Pacific/Majuro', 'Pacific/Kwajalein'],
750 ['mh', 'en-MH'], _KML.ANSI, 'Marshall Islands', None, 141),
751 Region(
752 'mk', 'xkb:mk::mkd', 'Europe/Skopje',
753 ['mk', 'sq', 'tr', 'rmm', 'sr'], _KML.ANSI, 'Macedonia', None, 142),
754 Region(
755 'mu', 'xkb:mu::eng', 'Indian/Mauritius', ['en-MU', 'bho', 'fr'],
756 _KML.ANSI, 'Mauritius', None, 143),
757 Region(
758 'mt', ['xkb:us::eng', 'xkb:mt::mlt'], 'Europe/Malta', ['mt', 'en-GB'],
759 _KML.ISO, 'Malta', None, 144),
760 Region(
761 'mw', 'xkb:mw::nya', 'Africa/Blantyre',
762 ['ny', 'yao', 'tum', 'swk'], _KML.ANSI, 'Malawi', None, 145),
763 Region(
764 'mv', 'xkb:mv::div', 'Indian/Maldives', ['dv', 'en'], _KML.ANSI,
765 'Maldives', None, 146),
766 Region(
767 'mq', 'xkb:mq::fra', 'America/Martinique', 'fr-MQ', _KML.ANSI,
768 'Martinique', None, 147),
769 Region(
770 'mp', 'xkb:us::eng', 'Pacific/Saipan',
771 ['fil', 'tl', 'zh', 'ch-MP', 'en-MP'], _KML.ANSI,
772 'Northern Mariana Islands', None, 148),
773 Region(
774 'ms', 'xkb:ms::eng', 'America/Montserrat', 'en-MS', _KML.ANSI,
775 'Montserrat', None, 149),
776 Region(
777 'mr', 'xkb:mr::ara', 'Africa/Nouakchott',
778 ['ar-MR', 'fuc', 'snk', 'fr', 'mey', 'wo'], _KML.ANSI,
779 'Mauritania', None, 150),
780 Region(
781 'im', 'xkb:im::eng', 'Europe/Isle_of_Man', ['en', 'gv'],
782 _KML.ANSI, 'Isle of Man', None, 151),
783 Region(
784 'ug', 'xkb:ug::eng', 'Africa/Kampala',
785 ['en-UG', 'lg', 'sw', 'ar'], _KML.ANSI, 'Uganda', None, 152),
786 Region(
787 'tz', 'xkb:tz::swa', 'Africa/Dar_es_Salaam',
788 ['sw-TZ', 'en', 'ar'], _KML.ANSI, 'Tanzania', None, 153),
789 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800790 'io', 'xkb:io::eng', 'Indian/Chagos', 'en-IO', _KML.ANSI,
791 'British Indian Ocean Territory', None, 155),
792 Region(
793 'sh', 'xkb:sh::eng', 'Atlantic/St_Helena', 'en-SH', _KML.ANSI,
794 'Saint Helena', None, 156),
795 Region(
796 'fj', 'xkb:fj::eng', 'Pacific/Fiji', ['en-FJ', 'fj'], _KML.ANSI,
797 'Fiji', None, 157),
798 Region(
799 'fk', 'xkb:fk::eng', 'Atlantic/Stanley', 'en-FK', _KML.ANSI,
800 'Falkland Islands', None, 158),
801 Region(
802 'fm', 'xkb:fm::eng',
803 ['Pacific/Chuuk', 'Pacific/Pohnpei', 'Pacific/Kosrae'],
804 ['en-FM', 'chk', 'pon', 'yap', 'kos', 'uli', 'woe', 'nkr', 'kpg'],
805 _KML.ANSI, 'Micronesia', None, 159),
806 Region(
807 'fo', 'xkb:fo::fao', 'Atlantic/Faroe', ['fo', 'da-FO'],
808 _KML.ANSI, 'Faroe Islands', None, 160),
809 Region(
810 'ni', 'xkb:ni::spa', 'America/Managua', ['es-NI', 'en'],
811 _KML.ANSI, 'Nicaragua', None, 161),
812 Region(
813 'no', 'xkb:no::nor', 'Europe/Oslo',
814 ['no', 'nb', 'nn', 'se', 'fi'], _KML.ISO, 'Norway', None, 162),
815 Region(
816 'na', 'xkb:na::eng', 'Africa/Windhoek',
817 ['en-NA', 'af', 'de', 'hz', 'naq'], _KML.ANSI, 'Namibia', None, 163),
818 Region(
819 'vu', 'xkb:vu::bis', 'Pacific/Efate', ['bi', 'en-VU', 'fr-VU'],
820 _KML.ANSI, 'Vanuatu', None, 164),
821 Region(
822 'nc', 'xkb:nc::fra', 'Pacific/Noumea', 'fr-NC', _KML.ANSI,
823 'New Caledonia', None, 165),
824 Region(
825 'ne', 'xkb:ne::fra', 'Africa/Niamey',
826 ['fr-NE', 'ha', 'kr', 'dje'], _KML.ANSI, 'Niger', None, 166),
827 Region(
828 'nf', 'xkb:nf::eng', 'Pacific/Norfolk', 'en-NF', _KML.ANSI,
829 'Norfolk Island', None, 167),
830 Region(
831 'np', 'xkb:np::nep', 'Asia/Kathmandu', ['ne', 'en'], _KML.ANSI,
832 'Nepal', None, 168),
833 Region(
834 'nr', 'xkb:nr::nau', 'Pacific/Nauru', ['na', 'en-NR'],
835 _KML.ANSI, 'Nauru', None, 169),
836 Region(
837 'nu', 'xkb:us::eng', 'Pacific/Niue', ['niu', 'en-NU'],
838 _KML.ANSI, 'Niue', None, 170),
839 Region(
840 'ck', 'xkb:ck::eng', 'Pacific/Rarotonga', ['en-CK', 'mi'],
841 _KML.ANSI, 'Cook Islands', None, 171),
842 Region(
843 'ci', 'xkb:ci::fra', 'Africa/Abidjan', 'fr-CI', _KML.ANSI,
844 'Ivory Coast', None, 172),
845 Region(
846 'co', 'xkb:co::spa', 'America/Bogota', 'es-CO', _KML.ANSI,
847 'Colombia', None, 173),
848 Region(
849 'cn', 'xkb:us::eng', 'Asia/Shanghai', 'zh-CN', _KML.ANSI, 'China',
850 None, 174),
851 Region(
852 'cm', 'xkb:cm::eng', 'Africa/Douala', ['en-CM', 'fr-CM'],
853 _KML.ANSI, 'Cameroon', None, 175),
854 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800855 'cc', 'xkb:cc::msa', 'Indian/Cocos', ['ms-CC', 'en'], _KML.ANSI,
856 'Cocos Islands', None, 177),
857 Region(
858 'cg', 'xkb:cg::fra', 'Africa/Brazzaville',
859 ['fr-CG', 'kg', 'ln-CG'], _KML.ANSI, 'Republic of the Congo', None,
860 178),
861 Region(
862 'cf', 'xkb:cf::fra', 'Africa/Bangui', ['fr-CF', 'sg', 'ln', 'kg'],
863 _KML.ANSI, 'Central African Republic', None, 179),
864 Region(
865 'cd', 'xkb:cd::fra', ['Africa/Kinshasa', 'Africa/Lubumbashi'],
866 ['fr-CD', 'ln', 'kg'], _KML.ANSI,
867 'Democratic Republic of the Congo', None, 180),
868 Region(
869 'cy', 'xkb:cy::ell', 'Asia/Nicosia', ['el-CY', 'tr-CY', 'en'],
870 _KML.ANSI, 'Cyprus', None, 181),
871 Region(
872 'cx', 'xkb:cx::eng', 'Indian/Christmas', ['en', 'zh', 'ms-CC'],
873 _KML.ANSI, 'Christmas Island', None, 182),
874 Region(
875 'cr', 'xkb:cr::spa', 'America/Costa_Rica', ['es-CR', 'en'],
876 _KML.ANSI, 'Costa Rica', None, 183),
877 Region(
878 'cw', 'xkb:cw::nld', 'America/Curacao', ['nl', 'pap'],
879 _KML.ANSI, 'Curacao', None, 184),
880 Region(
881 'cv', 'xkb:cv::por', 'Atlantic/Cape_Verde', 'pt-CV', _KML.ANSI,
882 'Cape Verde', None, 185),
883 Region(
884 'cu', 'xkb:cu::spa', 'America/Havana', 'es-CU', _KML.ANSI, 'Cuba',
885 None, 186),
886 Region(
887 'sz', 'xkb:sz::eng', 'Africa/Mbabane', ['en-SZ', 'ss-SZ'],
888 _KML.ANSI, 'Swaziland', None, 187),
889 Region(
890 'sy', 'xkb:sy::ara', 'Asia/Damascus',
891 ['ar-SY', 'ku', 'hy', 'arc', 'fr', 'en'], _KML.ANSI, 'Syria', None,
892 188),
893 Region(
894 'sx', 'xkb:sx::nld', 'America/Lower_Princes', ['nl', 'en'],
895 _KML.ANSI, 'Sint Maarten', None, 189),
896 Region(
897 'kg', 'xkb:kg::kir', 'Asia/Bishkek', ['ky', 'uz', 'ru'],
898 _KML.ANSI, 'Kyrgyzstan', None, 190),
899 Region(
900 'ke', 'xkb:ke::eng', 'Africa/Nairobi', ['en-KE', 'sw-KE'],
901 _KML.ANSI, 'Kenya', None, 191),
902 Region(
903 'ss', 'xkb:ss::eng', 'Africa/Juba', 'en', _KML.ANSI,
904 'South Sudan', None, 192),
905 Region(
906 'sr', 'xkb:sr::nld', 'America/Paramaribo',
907 ['nl-SR', 'en', 'srn', 'hns', 'jv'], _KML.ANSI, 'Suriname', None, 193),
908 Region(
909 'ki', 'xkb:ki::eng',
910 ['Pacific/Tarawa', 'Pacific/Enderbury', 'Pacific/Kiritimati'],
911 ['en-KI', 'gil'], _KML.ANSI, 'Kiribati', None, 194),
912 Region(
913 'kh', 'xkb:kh::khm', 'Asia/Phnom_Penh', ['km', 'fr', 'en'],
914 _KML.ANSI, 'Cambodia', None, 195),
915 Region(
916 'kn', 'xkb:kn::eng', 'America/St_Kitts', 'en-KN', _KML.ANSI,
917 'Saint Kitts and Nevis', None, 196),
918 Region(
919 'km', 'xkb:km::ara', 'Indian/Comoro', ['ar', 'fr-KM'],
920 _KML.ANSI, 'Comoros', None, 197),
921 Region(
922 'st', 'xkb:st::por', 'Africa/Sao_Tome', 'pt-ST', _KML.ANSI,
923 'Sao Tome and Principe', None, 198),
924 Region(
925 'si', 'xkb:si::slv', 'Europe/Ljubljana',
926 ['sl', 'hu', 'it', 'sr', 'de', 'hr', 'en-GB'], _KML.ISO,
927 'Slovenia', None, 199),
928 Region(
929 'kp', 'xkb:kp::kor', 'Asia/Pyongyang', 'ko-KP', _KML.ANSI,
930 'North Korea', None, 200),
931 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800932 'sn', 'xkb:sn::fra', 'Africa/Dakar',
933 ['fr-SN', 'wo', 'fuc', 'mnk'], _KML.ANSI, 'Senegal', None, 202),
934 Region(
935 'sm', 'xkb:sm::ita', 'Europe/San_Marino', 'it-SM', _KML.ANSI,
936 'San Marino', None, 203),
937 Region(
938 'sl', 'xkb:sl::eng', 'Africa/Freetown', ['en-SL', 'men', 'tem'],
939 _KML.ANSI, 'Sierra Leone', None, 204),
940 Region(
941 'sc', 'xkb:sc::eng', 'Indian/Mahe', ['en-SC', 'fr-SC'],
942 _KML.ANSI, 'Seychelles', None, 205),
943 Region(
944 'kz', 'xkb:kz::kaz',
945 ['Asia/Almaty', 'Asia/Qyzylorda', 'Asia/Aqtobe', 'Asia/Aqtau',
946 'Asia/Oral'], ['kk', 'ru'], _KML.ANSI, 'Kazakhstan', None, 206),
947 Region(
948 'ky', 'xkb:ky::eng', 'America/Cayman', 'en-KY', _KML.ANSI,
949 'Cayman Islands', None, 207),
950 Region(
951 'sd', 'xkb:sd::ara', 'Africa/Khartoum', ['ar-SD', 'en', 'fia'],
952 _KML.ANSI, 'Sudan', None, 208),
953 Region(
954 'do', 'xkb:do::spa', 'America/Santo_Domingo', 'es-DO',
955 _KML.ANSI, 'Dominican Republic', None, 209),
956 Region(
957 'dm', 'xkb:dm::eng', 'America/Dominica', 'en-DM', _KML.ANSI,
958 'Dominica', None, 210),
959 Region(
960 'dj', 'xkb:dj::fra', 'Africa/Djibouti',
961 ['fr-DJ', 'ar', 'so-DJ', 'aa'], _KML.ANSI, 'Djibouti', None, 211),
962 Region(
963 'dk', 'xkb:dk::dan', 'Europe/Copenhagen',
964 ['da-DK', 'en', 'fo', 'de-DK'], _KML.ISO, 'Denmark', None, 212),
965 Region(
966 'vg', 'xkb:vg::eng', 'America/Tortola', 'en-VG', _KML.ANSI,
967 'British Virgin Islands', None, 213),
968 Region(
969 'ye', 'xkb:ye::ara', 'Asia/Aden', 'ar-YE', _KML.ANSI, 'Yemen',
970 None, 214),
971 Region(
972 'dz', 'xkb:dz::ara', 'Africa/Algiers', 'ar-DZ', _KML.ANSI,
973 'Algeria', None, 215),
974 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800975 'yt', 'xkb:yt::fra', 'Indian/Mayotte', 'fr-YT', _KML.ANSI,
976 'Mayotte', None, 217),
977 Region(
978 'um', 'xkb:um::eng',
979 ['Pacific/Johnston', 'Pacific/Midway', 'Pacific/Wake'], 'en-UM',
980 _KML.ANSI, 'United States Minor Outlying Islands', None, 218),
981 Region(
982 'lb', 'xkb:lb::ara', 'Asia/Beirut',
983 ['ar-LB', 'fr-LB', 'en', 'hy'], _KML.ANSI, 'Lebanon', None, 219),
984 Region(
985 'lc', 'xkb:lc::eng', 'America/St_Lucia', 'en-LC', _KML.ANSI,
986 'Saint Lucia', None, 220),
987 Region(
988 'la', 'xkb:la::lao', 'Asia/Vientiane', ['lo', 'fr', 'en'],
989 _KML.ANSI, 'Laos', None, 221),
990 Region(
991 'tv', 'xkb:us::eng', 'Pacific/Funafuti',
992 ['tvl', 'en', 'sm', 'gil'], _KML.ANSI, 'Tuvalu', None, 222),
993 Region(
994 'tt', 'xkb:tt::eng', 'America/Port_of_Spain',
995 ['en-TT', 'hns', 'fr', 'es', 'zh'], _KML.ANSI,
996 'Trinidad and Tobago', None, 223),
997 Region(
998 'tr', 'xkb:tr::tur', 'Europe/Istanbul',
999 ['tr', 'ku', 'diq', 'az', 'av'], _KML.ISO, 'Turkey', None, 224),
1000 Region(
1001 'lk', 'xkb:lk::sin', 'Asia/Colombo', ['si', 'ta', 'en'],
1002 _KML.ANSI, 'Sri Lanka', None, 225),
1003 Region(
1004 'li', 'xkb:ch::ger', 'Europe/Vaduz', ['de', 'en-GB'], _KML.ISO,
1005 'Liechtenstein', None, 226),
1006 Region(
1007 'lv', 'xkb:lv:apostrophe:lav', 'Europe/Riga',
1008 ['lv', 'lt', 'ru', 'en-GB'], _KML.ISO, 'Latvia', None, 227),
1009 Region(
1010 'to', 'xkb:to::ton', 'Pacific/Tongatapu', ['to', 'en-TO'],
1011 _KML.ANSI, 'Tonga', None, 228),
1012 Region(
1013 'lt', 'xkb:lt::lit', 'Europe/Vilnius', ['lt', 'ru', 'pl', 'en-GB'],
1014 _KML.ISO, 'Lithuania', None, 229),
1015 Region(
1016 'lu', 'xkb:lu::ltz', 'Europe/Luxembourg',
1017 ['lb', 'de-LU', 'fr-LU'], _KML.ANSI, 'Luxembourg', None, 230),
1018 Region(
1019 'lr', 'xkb:lr::eng', 'Africa/Monrovia', 'en-LR', _KML.ANSI,
1020 'Liberia', None, 231),
1021 Region(
1022 'ls', 'xkb:ls::eng', 'Africa/Maseru', ['en-LS', 'st', 'zu', 'xh'],
1023 _KML.ANSI, 'Lesotho', None, 232),
1024 Region(
1025 'tf', 'xkb:tf::fra', 'Indian/Kerguelen', 'fr', _KML.ANSI,
1026 'French Southern Territories', None, 233),
1027 Region(
1028 'tg', 'xkb:tg::fra', 'Africa/Lome',
1029 ['fr-TG', 'ee', 'hna', 'kbp', 'dag', 'ha'], _KML.ANSI, 'Togo',
1030 None, 234),
1031 Region(
1032 'td', 'xkb:td::fra', 'Africa/Ndjamena', ['fr-TD', 'ar-TD', 'sre'],
1033 _KML.ANSI, 'Chad', None, 235),
1034 Region(
1035 'tc', 'xkb:tc::eng', 'America/Grand_Turk', 'en-TC', _KML.ANSI,
1036 'Turks and Caicos Islands', None, 236),
1037 Region(
1038 'ly', 'xkb:ly::ara', 'Africa/Tripoli', ['ar-LY', 'it', 'en'],
1039 _KML.ANSI, 'Libya', None, 237),
1040 Region(
1041 'va', 'xkb:va::lat', 'Europe/Vatican', ['la', 'it', 'fr'],
1042 _KML.ANSI, 'Vatican', None, 238),
1043 Region(
1044 'vc', 'xkb:vc::eng', 'America/St_Vincent', ['en-VC', 'fr'],
1045 _KML.ANSI, 'Saint Vincent and the Grenadines', None, 239),
1046 Region(
1047 'ad', 'xkb:ad::cat', 'Europe/Andorra', 'ca', _KML.ANSI, 'Andorra',
1048 None, 240),
1049 Region(
1050 'ag', 'xkb:ag::eng', 'America/Antigua', 'en-AG', _KML.ANSI,
1051 'Antigua and Barbuda', None, 241),
1052 Region(
1053 'af', 'xkb:af::fas', 'Asia/Kabul', ['fa-AF', 'ps', 'uz-AF', 'tk'],
1054 _KML.ANSI, 'Afghanistan', None, 242),
1055 Region(
1056 'ai', 'xkb:ai::eng', 'America/Anguilla', 'en-AI', _KML.ANSI,
1057 'Anguilla', None, 243),
1058 Region(
1059 'vi', 'xkb:vi::eng', 'America/St_Thomas', 'en-VI', _KML.ANSI,
1060 'U.S. Virgin Islands', None, 244),
1061 Region(
1062 'is', 'xkb:is::ice', 'Atlantic/Reykjavik',
1063 ['is', 'en-GB', 'da', 'de'], _KML.ISO, 'Iceland', None, 245),
1064 Region(
1065 'ir', 'xkb:ir::fas', 'Asia/Tehran', ['fa-IR', 'ku'], _KML.ANSI,
1066 'Iran', None, 246),
1067 Region(
1068 'am', 'xkb:am::hye', 'Asia/Yerevan', 'hy', _KML.ANSI, 'Armenia',
1069 None, 247),
1070 Region(
1071 'al', 'xkb:al::sqi', 'Europe/Tirane', ['sq', 'el'], _KML.ANSI,
1072 'Albania', None, 248),
1073 Region(
1074 'ao', 'xkb:ao::por', 'Africa/Luanda', 'pt-AO', _KML.ANSI,
1075 'Angola', None, 249),
1076 Region(
1077 'as', 'xkb:as::eng', 'Pacific/Pago_Pago', ['en-AS', 'sm', 'to'],
1078 _KML.ANSI, 'American Samoa', None, 250),
1079 Region(
1080 'ar', 'xkb:ar::spa',
1081 ['America/Argentina/Buenos_Aires', 'America/Argentina/Cordoba',
1082 'America/Argentina/Salta', 'America/Argentina/Jujuy',
1083 'America/Argentina/Tucuman', 'America/Argentina/Catamarca',
1084 'America/Argentina/La_Rioja', 'America/Argentina/San_Juan',
1085 'America/Argentina/Mendoza', 'America/Argentina/San_Luis',
1086 'America/Argentina/Rio_Gallegos', 'America/Argentina/Ushuaia'],
1087 ['es-AR', 'en', 'it', 'de', 'fr', 'gn'], _KML.ANSI, 'Argentina',
1088 None, 251),
1089 Region(
1090 'aw', 'xkb:aw::nld', 'America/Aruba', ['nl-AW', 'es', 'en'],
1091 _KML.ANSI, 'Aruba', None, 252),
1092 Region(
1093 'ax', 'xkb:ax::swe', 'Europe/Mariehamn', 'sv-AX', _KML.ANSI,
1094 'Aland Islands', None, 253),
1095 Region(
1096 'az', 'xkb:az::aze', 'Asia/Baku', ['az', 'ru', 'hy'], _KML.ANSI,
1097 'Azerbaijan', None, 254),
1098 Region(
1099 'ua', 'xkb:ua::ukr',
1100 ['Europe/Kiev', 'Europe/Uzhgorod', 'Europe/Zaporozhye'],
1101 ['uk', 'ru-UA', 'rom', 'pl', 'hu'], _KML.ANSI, 'Ukraine', None, 255),
1102 Region(
Hung-Te Lindf179fd2016-05-12 19:22:13 +08001103 'qa', 'xkb:qa::ara', 'Asia/Bahrain', ['ar-QA', 'en'], _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001104 'Qatar', None, 256),
1105 Region(
1106 'mz', 'xkb:mz::por', 'Africa/Maputo', ['pt-MZ', 'vmw'],
1107 _KML.ANSI, 'Mozambique', None, 257)]
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001108"""A list of :py:class:`regions.Region` objects for
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001109**unconfirmed** regions. These may contain incorrect information (or not
1110supported by Chrome browser yet), and all fields must be reviewed before launch.
1111See http://goto/vpdsettings.
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001112
1113Currently, non-Latin keyboards must use an underlying Latin keyboard
1114for VPD. (This assumption should be revisited when moving items to
1115:py:data:`regions.Region.REGIONS_LIST`.) This is
1116currently being discussed on <http://crbug.com/325389>.
1117
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001118Some timezones or locales may be missing from ``timezone_settings.cc`` (see
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001119http://crosbug.com/p/23902). This must be rectified before moving
1120items to :py:data:`regions.Region.REGIONS_LIST`.
1121"""
1122
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001123
1124def ConsolidateRegions(regions):
1125 """Consolidates a list of regions into a dict.
1126
1127 Args:
1128 regions: A list of Region objects. All objects for any given
1129 region code must be identical or we will throw an exception.
1130 (We allow duplicates in case identical region objects are
1131 defined in both regions.py and the overlay, e.g., when moving
1132 items to the public overlay.)
1133
1134 Returns:
1135 A dict from region code to Region.
1136
1137 Raises:
1138 RegionException: If there are multiple regions defined for a given
1139 region, and the values for those regions differ.
1140 """
1141 # Build a dict from region_code to the first Region with that code.
1142 region_dict = {}
1143 for r in regions:
1144 existing_region = region_dict.get(r.region_code)
1145 if existing_region:
1146 if existing_region.GetFieldsDict() != r.GetFieldsDict():
1147 raise RegionException(
1148 'Conflicting definitions for region %r: %r, %r' %
1149 (r.region_code, existing_region.GetFieldsDict(),
1150 r.GetFieldsDict()))
1151 else:
1152 region_dict[r.region_code] = r
1153
1154 return region_dict
1155
1156
1157def BuildRegionsDict(include_all=False):
1158 """Builds a dictionary mapping from code to :py:class:`regions.Region` object.
1159
1160 The regions include:
1161
1162 * :py:data:`regions.REGIONS_LIST`
1163 * :py:data:`regions_overlay.REGIONS_LIST`
1164 * Only if ``include_all`` is true:
1165
1166 * :py:data:`regions.UNCONFIRMED_REGIONS_LIST`
1167 * :py:data:`regions.INCOMPLETE_REGIONS_LIST`
1168
1169 A region may only appear in one of the above lists, or this function
1170 will (deliberately) fail.
1171 """
1172 regions = list(REGIONS_LIST)
1173 if include_all:
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001174 known_codes = [r.region_code for r in regions]
1175 regions += [r for r in UNCONFIRMED_REGIONS_LIST if r.region_code not in
1176 known_codes]
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001177
1178 # Build dictionary of region code to list of regions with that
1179 # region code. Check manually for duplicates, since the region may
1180 # be present both in the overlay and the public repo.
1181 return ConsolidateRegions(regions)
1182
1183
1184REGIONS = BuildRegionsDict()
1185
1186
1187def main(args=sys.argv[1:], out=None):
1188 parser = argparse.ArgumentParser(description=(
1189 'Display all known regions and their parameters. '))
1190 parser.add_argument('--format',
1191 choices=('human-readable', 'csv', 'json', 'yaml'),
1192 default='human-readable',
1193 help='Output format (default=%(default)s)')
1194 parser.add_argument('--all', action='store_true',
1195 help='Include unconfirmed and incomplete regions')
1196 parser.add_argument('--output', default=None,
1197 help='Specify output file')
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001198 parser.add_argument('--overlay', default=None,
1199 help='Specify a Python file to overlay extra data')
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001200 args = parser.parse_args(args)
1201
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001202 if args.overlay is not None:
1203 execfile(args.overlay)
1204
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001205 if args.all:
1206 # Add an additional 'confirmed' property to help identifying region status,
1207 # for autotests, unit tests and factory module.
1208 Region.FIELDS.insert(1, 'confirmed')
1209 for r in REGIONS_LIST:
1210 r.confirmed = True
1211 for r in UNCONFIRMED_REGIONS_LIST:
1212 r.confirmed = False
1213
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001214 regions_dict = BuildRegionsDict(args.all)
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001215
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001216 if out is None:
1217 if args.output is None:
1218 out = sys.stdout
1219 else:
1220 out = open(args.output, 'w')
1221
1222 # Handle YAML and JSON output.
1223 if args.format == 'yaml' or args.format == 'json':
1224 data = {}
1225 for region in regions_dict.values():
1226 item = {}
1227 for field in Region.FIELDS:
1228 item[field] = getattr(region, field)
1229 data[region.region_code] = item
1230 if args.format == 'yaml':
1231 yaml.dump(data, out)
1232 else:
1233 json.dump(data, out)
1234 return
1235
1236 # Handle CSV or plain-text output: build a list of lines to print.
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001237 # The CSV format is for publishing discussion spreadsheet so 'notes' should be
1238 # added.
1239 if args.format == 'csv':
1240 Region.FIELDS += ['notes']
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001241 lines = [Region.FIELDS]
1242
1243 def CoerceToString(value):
1244 """Returns the arguments in simple string type.
1245
1246 If value is a list, concatenate its values with commas. Otherwise, just
1247 return value.
1248 """
1249 if isinstance(value, list):
1250 return ','.join(value)
1251 else:
1252 return str(value)
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001253
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001254 for region in sorted(regions_dict.values(), key=lambda v: v.region_code):
1255 lines.append([CoerceToString(getattr(region, field))
1256 for field in Region.FIELDS])
1257
1258 if args.format == 'csv':
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001259 # Just print the lines in CSV format. Note the values may include ',' so the
1260 # separator must be tab.
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001261 for l in lines:
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001262 print('\t'.join(l))
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001263 elif args.format == 'human-readable':
1264 num_columns = len(lines[0])
1265
1266 # Calculate maximum length of each column.
1267 max_lengths = []
1268 for column_no in xrange(num_columns):
1269 max_lengths.append(max(len(line[column_no]) for line in lines))
1270
1271 # Print each line, padding as necessary to the max column length.
1272 for line in lines:
1273 for column_no in xrange(num_columns):
1274 out.write(line[column_no].ljust(max_lengths[column_no] + 2))
1275 out.write('\n')
1276 else:
1277 exit('Sorry, unknown format specified: %s' % args.format)
1278
1279
1280if __name__ == '__main__':
1281 main()