From 66c535dfa0ec98c02d8be7f79c8f0e5ec653d042 Mon Sep 17 00:00:00 2001 From: Shaopeng Jia Date: Thu, 29 Jul 2010 08:19:02 +0000 Subject: [PATCH] Fixing issue 1. Patch submitted by tronikos. --- javascript/README | 61 + .../i18n/phonenumbers/asyoutypeformatter.js | 657 ++++ .../phonenumbers/asyoutypeformatter_test.html | 36 + .../phonenumbers/asyoutypeformatter_test.js | 482 +++ javascript/i18n/phonenumbers/demo.html | 125 + javascript/i18n/phonenumbers/metadata.js | 2942 +++++++++++++++++ .../i18n/phonenumbers/metadatafortesting.js | 248 ++ .../i18n/phonenumbers/phonemetadata.pb.js | 1890 +++++++++++ .../i18n/phonenumbers/phonenumber.pb.js | 405 +++ .../i18n/phonenumbers/phonenumberutil.js | 2512 ++++++++++++++ .../phonenumbers/phonenumberutil_test.html | 35 + .../i18n/phonenumbers/phonenumberutil_test.js | 2019 +++++++++++ 12 files changed, 11412 insertions(+) create mode 100644 javascript/README create mode 100644 javascript/i18n/phonenumbers/asyoutypeformatter.js create mode 100644 javascript/i18n/phonenumbers/asyoutypeformatter_test.html create mode 100644 javascript/i18n/phonenumbers/asyoutypeformatter_test.js create mode 100644 javascript/i18n/phonenumbers/demo.html create mode 100644 javascript/i18n/phonenumbers/metadata.js create mode 100644 javascript/i18n/phonenumbers/metadatafortesting.js create mode 100644 javascript/i18n/phonenumbers/phonemetadata.pb.js create mode 100644 javascript/i18n/phonenumbers/phonenumber.pb.js create mode 100644 javascript/i18n/phonenumbers/phonenumberutil.js create mode 100644 javascript/i18n/phonenumbers/phonenumberutil_test.html create mode 100644 javascript/i18n/phonenumbers/phonenumberutil_test.js diff --git a/javascript/README b/javascript/README new file mode 100644 index 000000000..0e6fccbb3 --- /dev/null +++ b/javascript/README @@ -0,0 +1,61 @@ +Info: +===== +Google's JavaScript library for parsing, formatting, and validating +international phone numbers. + + +How to setup: +============= +1. Checkout closure-library next to libphonenumber: + +e.g. +svn checkout http://libphonenumber.googlecode.com/svn/trunk/ ~/src/libphonenumber +svn checkout http://closure-library.googlecode.com/svn/trunk/ ~/src/closure-library + +(Or change the path of the + + + + + + + + + + + diff --git a/javascript/i18n/phonenumbers/asyoutypeformatter_test.js b/javascript/i18n/phonenumbers/asyoutypeformatter_test.js new file mode 100644 index 000000000..110965202 --- /dev/null +++ b/javascript/i18n/phonenumbers/asyoutypeformatter_test.js @@ -0,0 +1,482 @@ +// Copyright (C) 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Unit tests for the AsYouTypeFormatter. + * + * @author Nikolaos Trogkanis + */ + +goog.require('goog.testing.jsunit'); +goog.require('i18n.phonenumbers.AsYouTypeFormatter'); + +function testAsYouTypeFormatterUS() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('US'); + assertEquals('6', f.inputDigit('6')); + assertEquals('65', f.inputDigit('5')); + assertEquals('650', f.inputDigit('0')); + assertEquals('6502', f.inputDigit('2')); + assertEquals('65025', f.inputDigit('5')); + assertEquals('650 253', f.inputDigit('3')); + assertEquals('650 253 2', f.inputDigit('2')); + assertEquals('650 253 22', f.inputDigit('2')); + assertEquals('650 253 222', f.inputDigit('2')); + assertEquals('650 253 2222', f.inputDigit('2')); + + f.clear(); + assertEquals('1', f.inputDigit('1')); + assertEquals('16', f.inputDigit('6')); + assertEquals('165', f.inputDigit('5')); + assertEquals('1650', f.inputDigit('0')); + assertEquals('16502', f.inputDigit('2')); + assertEquals('1 650 25', f.inputDigit('5')); + assertEquals('1 650 253', f.inputDigit('3')); + assertEquals('1 650 253 2', f.inputDigit('2')); + assertEquals('1 650 253 22', f.inputDigit('2')); + assertEquals('1 650 253 222', f.inputDigit('2')); + assertEquals('1 650 253 2222', f.inputDigit('2')); + + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0114', f.inputDigit('4')); + assertEquals('01144', f.inputDigit('4')); + assertEquals('011 44 6', f.inputDigit('6')); + assertEquals('011 44 61', f.inputDigit('1')); + assertEquals('011 44 612', f.inputDigit('2')); + assertEquals('011 44 6 123', f.inputDigit('3')); + assertEquals('011 44 6 123 1', f.inputDigit('1')); + assertEquals('011 44 6 123 12', f.inputDigit('2')); + assertEquals('011 44 6 123 123', f.inputDigit('3')); + assertEquals('011 44 6 123 123 1', f.inputDigit('1')); + assertEquals('011 44 6 123 123 12', f.inputDigit('2')); + assertEquals('011 44 6 123 123 123', f.inputDigit('3')); + + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0115', f.inputDigit('5')); + assertEquals('01154', f.inputDigit('4')); + assertEquals('011 54 9', f.inputDigit('9')); + assertEquals('011 54 91', f.inputDigit('1')); + assertEquals('011 54 911', f.inputDigit('1')); + assertEquals('011 54 9 11 2', f.inputDigit('2')); + assertEquals('011 54 9 11 23', f.inputDigit('3')); + assertEquals('011 54 9 11 231', f.inputDigit('1')); + assertEquals('011 54 9 11 2312', f.inputDigit('2')); + assertEquals('011 54 9 11 2312 1', f.inputDigit('1')); + assertEquals('011 54 9 11 2312 12', f.inputDigit('2')); + assertEquals('011 54 9 11 2312 123', f.inputDigit('3')); + assertEquals('011 54 9 11 2312 1234', f.inputDigit('4')); + + f.clear(); + assertEquals('+', f.inputDigit('+')); + assertEquals('+4', f.inputDigit('4')); + assertEquals('+48', f.inputDigit('8')); + assertEquals('+488', f.inputDigit('8')); + assertEquals('+4888', f.inputDigit('8')); + assertEquals('+48 881', f.inputDigit('1')); + assertEquals('+48 88 12', f.inputDigit('2')); + assertEquals('+48 88 123', f.inputDigit('3')); + assertEquals('+48 88 123 1', f.inputDigit('1')); + assertEquals('+48 88 123 12', f.inputDigit('2')); + assertEquals('+48 88 123 12 1', f.inputDigit('1')); + assertEquals('+48 88 123 12 12', f.inputDigit('2')); +} + +function testAsYouTypeFormatterUSFullWidthCharacters() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('US'); + assertEquals('\uFF16', f.inputDigit('\uFF16')); + assertEquals('\uFF16\uFF15', f.inputDigit('\uFF15')); + assertEquals('\uFF16\uFF15\uFF10', f.inputDigit('\uFF10')); + assertEquals('\uFF16\uFF15\uFF10\uFF12', f.inputDigit('\uFF12')); + assertEquals('\uFF16\uFF15\uFF10\uFF12\uFF15', f.inputDigit('\uFF15')); + assertEquals('650 253', f.inputDigit('\uFF13')); + assertEquals('650 253 2', f.inputDigit('\uFF12')); + assertEquals('650 253 22', f.inputDigit('\uFF12')); + assertEquals('650 253 222', f.inputDigit('\uFF12')); + assertEquals('650 253 2222', f.inputDigit('\uFF12')); +} + +function testAsYouTypeFormatterUSMobileShortCode() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('US'); + assertEquals('*', f.inputDigit('*')); + assertEquals('*1', f.inputDigit('1')); + assertEquals('*12', f.inputDigit('2')); + assertEquals('*121', f.inputDigit('1')); + assertEquals('*121#', f.inputDigit('#')); +} + +function testAsYouTypeFormatterUSVanityNumber() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('US'); + assertEquals('8', f.inputDigit('8')); + assertEquals('80', f.inputDigit('0')); + assertEquals('800', f.inputDigit('0')); + assertEquals('800 ', f.inputDigit(' ')); + assertEquals('800 M', f.inputDigit('M')); + assertEquals('800 MY', f.inputDigit('Y')); + assertEquals('800 MY ', f.inputDigit(' ')); + assertEquals('800 MY A', f.inputDigit('A')); + assertEquals('800 MY AP', f.inputDigit('P')); + assertEquals('800 MY APP', f.inputDigit('P')); + assertEquals('800 MY APPL', f.inputDigit('L')); + assertEquals('800 MY APPLE', f.inputDigit('E')); +} + +function testAsYouTypeFormatterAndRememberPositionUS() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('US'); + assertEquals('1', f.inputDigitAndRememberPosition('1')); + assertEquals(1, f.getRememberedPosition()); + assertEquals('16', f.inputDigit('6')); + assertEquals('165', f.inputDigit('5')); + assertEquals(1, f.getRememberedPosition()); + assertEquals('1650', f.inputDigitAndRememberPosition('0')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('16502', f.inputDigit('2')); + assertEquals('1 650 25', f.inputDigit('5')); + // Note the remembered position for digit '0' changes from 4 to 5, because a + // space is now inserted in the front. + assertEquals(5, f.getRememberedPosition()); + assertEquals('1 650 253', f.inputDigit('3')); + assertEquals('1 650 253 2', f.inputDigit('2')); + assertEquals('1 650 253 22', f.inputDigit('2')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('1 650 253 222', f.inputDigitAndRememberPosition('2')); + assertEquals(13, f.getRememberedPosition()); + assertEquals('1 650 253 2222', f.inputDigit('2')); + assertEquals(13, f.getRememberedPosition()); + assertEquals('165025322222', f.inputDigit('2')); + assertEquals(10, f.getRememberedPosition()); + assertEquals('1650253222222', f.inputDigit('2')); + assertEquals(10, f.getRememberedPosition()); + + f.clear(); + assertEquals('1', f.inputDigit('1')); + assertEquals('16', f.inputDigit('6')); + assertEquals('165', f.inputDigitAndRememberPosition('5')); + assertEquals('1650', f.inputDigit('0')); + assertEquals(3, f.getRememberedPosition()); + assertEquals('16502', f.inputDigit('2')); + assertEquals('1 650 25', f.inputDigit('5')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('1 650 253', f.inputDigit('3')); + assertEquals('1 650 253 2', f.inputDigit('2')); + assertEquals('1 650 253 22', f.inputDigit('2')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('1 650 253 222', f.inputDigit('2')); + assertEquals('1 650 253 2222', f.inputDigit('2')); + assertEquals('165025322222', f.inputDigit('2')); + assertEquals(3, f.getRememberedPosition()); + assertEquals('1650253222222', f.inputDigit('2')); + assertEquals(3, f.getRememberedPosition()); + + f.clear(); + assertEquals('6', f.inputDigit('6')); + assertEquals('65', f.inputDigit('5')); + assertEquals('650', f.inputDigit('0')); + assertEquals('6502', f.inputDigit('2')); + assertEquals('65025', f.inputDigitAndRememberPosition('5')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('650 253', f.inputDigit('3')); + assertEquals(6, f.getRememberedPosition()); + assertEquals('650 253 2', f.inputDigit('2')); + assertEquals('650 253 22', f.inputDigit('2')); + assertEquals('650 253 222', f.inputDigit('2')); + // No more formatting when semicolon is entered. + assertEquals('650253222;', f.inputDigit(';')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('650253222;2', f.inputDigit('2')); + + f.clear(); + assertEquals('6', f.inputDigit('6')); + assertEquals('65', f.inputDigit('5')); + assertEquals('650', f.inputDigit('0')); + // No more formatting when users choose to do their own formatting. + assertEquals('650-', f.inputDigit('-')); + assertEquals('650-2', f.inputDigitAndRememberPosition('2')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('650-25', f.inputDigit('5')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('650-253', f.inputDigit('3')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('650-253-', f.inputDigit('-')); + assertEquals('650-253-2', f.inputDigit('2')); + assertEquals('650-253-22', f.inputDigit('2')); + assertEquals('650-253-222', f.inputDigit('2')); + assertEquals('650-253-2222', f.inputDigit('2')); + + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0114', f.inputDigitAndRememberPosition('4')); + assertEquals('01148', f.inputDigit('8')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('011 48 8', f.inputDigit('8')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('011 48 88', f.inputDigit('8')); + assertEquals('011 48 881', f.inputDigit('1')); + assertEquals('011 48 88 12', f.inputDigit('2')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('011 48 88 123', f.inputDigit('3')); + assertEquals('011 48 88 123 1', f.inputDigit('1')); + assertEquals('011 48 88 123 12', f.inputDigit('2')); + assertEquals('011 48 88 123 12 1', f.inputDigit('1')); + assertEquals('011 48 88 123 12 12', f.inputDigit('2')); + + f.clear(); + assertEquals('+', f.inputDigit('+')); + assertEquals('+1', f.inputDigit('1')); + assertEquals('+16', f.inputDigitAndRememberPosition('6')); + assertEquals('+165', f.inputDigit('5')); + assertEquals('+1650', f.inputDigit('0')); + assertEquals(3, f.getRememberedPosition()); + assertEquals('+1 650 2', f.inputDigit('2')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('+1 650 25', f.inputDigit('5')); + assertEquals('+1 650 253', f.inputDigitAndRememberPosition('3')); + assertEquals('+1 650 253 2', f.inputDigit('2')); + assertEquals('+1 650 253 22', f.inputDigit('2')); + assertEquals('+1 650 253 222', f.inputDigit('2')); + assertEquals(10, f.getRememberedPosition()); + + f.clear(); + assertEquals('+', f.inputDigit('+')); + assertEquals('+1', f.inputDigit('1')); + assertEquals('+16', f.inputDigitAndRememberPosition('6')); + assertEquals('+165', f.inputDigit('5')); + assertEquals('+1650', f.inputDigit('0')); + assertEquals(3, f.getRememberedPosition()); + assertEquals('+1 650 2', f.inputDigit('2')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('+1 650 25', f.inputDigit('5')); + assertEquals('+1 650 253', f.inputDigit('3')); + assertEquals('+1 650 253 2', f.inputDigit('2')); + assertEquals('+1 650 253 22', f.inputDigit('2')); + assertEquals('+1 650 253 222', f.inputDigit('2')); + assertEquals('+1650253222;', f.inputDigit(';')); + assertEquals(3, f.getRememberedPosition()); +} + +function testAsYouTypeFormatterGBFixedLine() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('GB'); + assertEquals('0', f.inputDigit('0')); + assertEquals('02', f.inputDigit('2')); + assertEquals('020', f.inputDigit('0')); + assertEquals('0207', f.inputDigitAndRememberPosition('7')); + assertEquals(4, f.getRememberedPosition()); + assertEquals('02070', f.inputDigit('0')); + assertEquals('020 703', f.inputDigit('3')); + assertEquals(5, f.getRememberedPosition()); + assertEquals('020 7031', f.inputDigit('1')); + assertEquals('020 7031 3', f.inputDigit('3')); + assertEquals('020 7031 30', f.inputDigit('0')); + assertEquals('020 7031 300', f.inputDigit('0')); + assertEquals('020 7031 3000', f.inputDigit('0')); +} + +function testAsYouTypeFormatterGBTollFree() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('gb'); + assertEquals('0', f.inputDigit('0')); + assertEquals('08', f.inputDigit('8')); + assertEquals('080', f.inputDigit('0')); + assertEquals('0807', f.inputDigit('7')); + assertEquals('08070', f.inputDigit('0')); + assertEquals('080 703', f.inputDigit('3')); + assertEquals('080 7031', f.inputDigit('1')); + assertEquals('080 7031 3', f.inputDigit('3')); + assertEquals('080 7031 30', f.inputDigit('0')); + assertEquals('080 7031 300', f.inputDigit('0')); + assertEquals('080 7031 3000', f.inputDigit('0')); +} + +function testAsYouTypeFormatterGBPremiumRate() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('GB'); + assertEquals('0', f.inputDigit('0')); + assertEquals('09', f.inputDigit('9')); + assertEquals('090', f.inputDigit('0')); + assertEquals('0907', f.inputDigit('7')); + assertEquals('09070', f.inputDigit('0')); + assertEquals('090 703', f.inputDigit('3')); + assertEquals('090 7031', f.inputDigit('1')); + assertEquals('090 7031 3', f.inputDigit('3')); + assertEquals('090 7031 30', f.inputDigit('0')); + assertEquals('090 7031 300', f.inputDigit('0')); + assertEquals('090 7031 3000', f.inputDigit('0')); +} + +function testAsYouTypeFormatterNZMobile() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('NZ'); + assertEquals('0', f.inputDigit('0')); + assertEquals('02', f.inputDigit('2')); + assertEquals('021', f.inputDigit('1')); + assertEquals('0211', f.inputDigit('1')); + assertEquals('02112', f.inputDigit('2')); + // Note the unittest is using fake metadata which might produce non-ideal + // results. + assertEquals('02-112 3', f.inputDigit('3')); + assertEquals('02-112 34', f.inputDigit('4')); + assertEquals('02-112 345', f.inputDigit('5')); + assertEquals('02-112 3456', f.inputDigit('6')); +} + +function testAsYouTypeFormatterDE() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('DE'); + assertEquals('0', f.inputDigit('0')); + assertEquals('03', f.inputDigit('3')); + assertEquals('030', f.inputDigit('0')); + assertEquals('0301', f.inputDigit('1')); + assertEquals('03012', f.inputDigit('2')); + assertEquals('030 123', f.inputDigit('3')); + assertEquals('030 1234', f.inputDigit('4')); +} + +function testAsYouTypeFormatterAR() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('AR'); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0117', f.inputDigit('7')); + assertEquals('01170', f.inputDigit('0')); + assertEquals('011 703', f.inputDigit('3')); + assertEquals('011 7031', f.inputDigit('1')); + assertEquals('011 7031-3', f.inputDigit('3')); + assertEquals('011 7031-30', f.inputDigit('0')); + assertEquals('011 7031-300', f.inputDigit('0')); + assertEquals('011 7031-3000', f.inputDigit('0')); +} + +function testAsYouTypeFormatterARMobile() { + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('AR'); + assertEquals('+', f.inputDigit('+')); + assertEquals('+5', f.inputDigit('5')); + assertEquals('+54', f.inputDigit('4')); + assertEquals('+549', f.inputDigit('9')); + assertEquals('+5491', f.inputDigit('1')); + assertEquals('+54 911', f.inputDigit('1')); + assertEquals('+54 9 11 2', f.inputDigit('2')); + assertEquals('+54 9 11 23', f.inputDigit('3')); + assertEquals('+54 9 11 231', f.inputDigit('1')); + assertEquals('+54 9 11 2312', f.inputDigit('2')); + assertEquals('+54 9 11 2312 1', f.inputDigit('1')); + assertEquals('+54 9 11 2312 12', f.inputDigit('2')); + assertEquals('+54 9 11 2312 123', f.inputDigit('3')); + assertEquals('+54 9 11 2312 1234', f.inputDigit('4')); +} + +function testAsYouTypeFormatterKR() { + // +82 51 234 5678 + /** @type {i18n.phonenumbers.AsYouTypeFormatter} */ + var f = new i18n.phonenumbers.AsYouTypeFormatter('KR'); + assertEquals('+', f.inputDigit('+')); + assertEquals('+8', f.inputDigit('8')); + assertEquals('+82', f.inputDigit('2')); + assertEquals('+825', f.inputDigit('5')); + assertEquals('+8251', f.inputDigit('1')); + assertEquals('+82 512', f.inputDigit('2')); + assertEquals('+82 51-23', f.inputDigit('3')); + assertEquals('+82 51-234', f.inputDigit('4')); + assertEquals('+82 51-234-5', f.inputDigit('5')); + assertEquals('+82 51-234-56', f.inputDigit('6')); + assertEquals('+82 51-234-567', f.inputDigit('7')); + assertEquals('+82 51-234-5678', f.inputDigit('8')); + + // +82 2 531 5678 + f.clear(); + assertEquals('+', f.inputDigit('+')); + assertEquals('+8', f.inputDigit('8')); + assertEquals('+82', f.inputDigit('2')); + assertEquals('+822', f.inputDigit('2')); + assertEquals('+8225', f.inputDigit('5')); + assertEquals('+82 253', f.inputDigit('3')); + assertEquals('+82 2-531', f.inputDigit('1')); + assertEquals('+82 2-531-5', f.inputDigit('5')); + assertEquals('+82 2-531-56', f.inputDigit('6')); + assertEquals('+82 2-531-567', f.inputDigit('7')); + assertEquals('+82 2-531-5678', f.inputDigit('8')); + + // +82 2 3665 5678 + f.clear(); + assertEquals('+', f.inputDigit('+')); + assertEquals('+8', f.inputDigit('8')); + assertEquals('+82', f.inputDigit('2')); + assertEquals('+822', f.inputDigit('2')); + assertEquals('+8223', f.inputDigit('3')); + assertEquals('+82 236', f.inputDigit('6')); + assertEquals('+82 2-366', f.inputDigit('6')); + assertEquals('+82 2-3665', f.inputDigit('5')); + assertEquals('+82 2-3665-5', f.inputDigit('5')); + assertEquals('+82 2-3665-56', f.inputDigit('6')); + assertEquals('+82 2-3665-567', f.inputDigit('7')); + assertEquals('+82 2-3665-5678', f.inputDigit('8')); + + // 02-114 : This is too short to format. Checking that there are no + // side-effects. + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('02', f.inputDigit('2')); + assertEquals('021', f.inputDigit('1')); + assertEquals('0211', f.inputDigit('1')); + assertEquals('02114', f.inputDigit('4')); + + // 02-1300 + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('02', f.inputDigit('2')); + assertEquals('021', f.inputDigit('1')); + assertEquals('0213', f.inputDigit('3')); + assertEquals('02130', f.inputDigit('0')); + assertEquals('02-1300', f.inputDigit('0')); + + // 011-456-7890 + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0114', f.inputDigit('4')); + assertEquals('01145', f.inputDigit('5')); + assertEquals('011-456', f.inputDigit('6')); + assertEquals('011-456-7', f.inputDigit('7')); + assertEquals('011-456-78', f.inputDigit('8')); + assertEquals('011-456-789', f.inputDigit('9')); + assertEquals('011-456-7890', f.inputDigit('0')); + + // 011-9876-7890 + f.clear(); + assertEquals('0', f.inputDigit('0')); + assertEquals('01', f.inputDigit('1')); + assertEquals('011', f.inputDigit('1')); + assertEquals('0119', f.inputDigit('9')); + assertEquals('01198', f.inputDigit('8')); + assertEquals('011-987', f.inputDigit('7')); + assertEquals('011-9876', f.inputDigit('6')); + assertEquals('011-9876-7', f.inputDigit('7')); + assertEquals('011-9876-78', f.inputDigit('8')); + assertEquals('011-9876-789', f.inputDigit('9')); + assertEquals('011-9876-7890', f.inputDigit('0')); +} diff --git a/javascript/i18n/phonenumbers/demo.html b/javascript/i18n/phonenumbers/demo.html new file mode 100644 index 000000000..306dafdee --- /dev/null +++ b/javascript/i18n/phonenumbers/demo.html @@ -0,0 +1,125 @@ + + + + + +Phone Number Parser Demo + + + + + + + + + + + +

Phone Number Parser Demo

+ +
+

+ Specify a Phone Number: + +

+

+ Specify a Default Country: + + (ISO 3166-1 two-letter country code) +

+ + +

+ +

+
+ + + diff --git a/javascript/i18n/phonenumbers/metadata.js b/javascript/i18n/phonenumbers/metadata.js new file mode 100644 index 000000000..055a3f74a --- /dev/null +++ b/javascript/i18n/phonenumbers/metadata.js @@ -0,0 +1,2942 @@ +// Copyright (C) 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Generated metadata for file + * PhoneNumberMetaData.xml + * @author Nikolaos Trogkanis + */ + +goog.provide('i18n.phonenumbers.metadata'); + +/** + * A mapping from a country code to the region codes which denote the + * country/region represented by that country code. In the case of multiple + * countries sharing a calling code, such as the NANPA countries, the one + * indicated with 'isMainCountryForCode' in the metadata should be first. + * @type {Object.>} + */ +i18n.phonenumbers.metadata.countryCodeToRegionCodeMap = { + 1: ['US','AG','AI','AS','BB','BM','BS','CA','DM','DO','GD','GU','JM','KN','KY','LC','MP','MS','PR','TC','TT','VC','VG','VI'], + 7: ['RU','KZ'], + 20: ['EG'], + 27: ['ZA'], + 30: ['GR'], + 31: ['NL'], + 32: ['BE'], + 33: ['FR'], + 34: ['ES'], + 36: ['HU'], + 39: ['IT'], + 40: ['RO'], + 41: ['CH'], + 43: ['AT'], + 44: ['GB','GG','IM','JE'], + 45: ['DK'], + 46: ['SE'], + 47: ['NO'], + 48: ['PL'], + 49: ['DE'], + 51: ['PE'], + 52: ['MX'], + 53: ['CU'], + 54: ['AR'], + 55: ['BR'], + 56: ['CL'], + 57: ['CO'], + 58: ['VE'], + 60: ['MY'], + 61: ['AU'], + 62: ['ID'], + 63: ['PH'], + 64: ['NZ'], + 65: ['SG'], + 66: ['TH'], + 81: ['JP'], + 82: ['KR'], + 84: ['VN'], + 86: ['CN'], + 90: ['TR'], + 91: ['IN'], + 92: ['PK'], + 93: ['AF'], + 94: ['LK'], + 95: ['MM'], + 98: ['IR'], + 212: ['MA'], + 213: ['DZ'], + 216: ['TN'], + 218: ['LY'], + 220: ['GM'], + 221: ['SN'], + 222: ['MR'], + 223: ['ML'], + 224: ['GN'], + 225: ['CI'], + 226: ['BF'], + 227: ['NE'], + 228: ['TG'], + 229: ['BJ'], + 230: ['MU'], + 231: ['LR'], + 232: ['SL'], + 233: ['GH'], + 234: ['NG'], + 235: ['TD'], + 236: ['CF'], + 237: ['CM'], + 238: ['CV'], + 239: ['ST'], + 240: ['GQ'], + 241: ['GA'], + 242: ['CG'], + 243: ['CD'], + 244: ['AO'], + 245: ['GW'], + 246: ['IO'], + 248: ['SC'], + 249: ['SD'], + 250: ['RW'], + 251: ['ET'], + 252: ['SO'], + 253: ['DJ'], + 254: ['KE'], + 255: ['TZ'], + 256: ['UG'], + 257: ['BI'], + 258: ['MZ'], + 260: ['ZM'], + 261: ['MG'], + 262: ['RE','TF','YT'], + 263: ['ZW'], + 264: ['NA'], + 265: ['MW'], + 266: ['LS'], + 267: ['BW'], + 268: ['SZ'], + 269: ['KM'], + 290: ['SH'], + 291: ['ER'], + 297: ['AW'], + 298: ['FO'], + 299: ['GL'], + 350: ['GI'], + 351: ['PT'], + 352: ['LU'], + 353: ['IE'], + 354: ['IS'], + 355: ['AL'], + 356: ['MT'], + 357: ['CY'], + 358: ['FI'], + 359: ['BG'], + 370: ['LT'], + 371: ['LV'], + 372: ['EE'], + 373: ['MD'], + 374: ['AM'], + 375: ['BY'], + 376: ['AD'], + 377: ['MC'], + 378: ['SM'], + 379: ['VA'], + 380: ['UA'], + 381: ['RS'], + 382: ['ME'], + 385: ['HR'], + 386: ['SI'], + 387: ['BA'], + 389: ['MK'], + 420: ['CZ'], + 421: ['SK'], + 423: ['LI'], + 500: ['FK'], + 501: ['BZ'], + 502: ['GT'], + 503: ['SV'], + 504: ['HN'], + 505: ['NI'], + 506: ['CR'], + 507: ['PA'], + 508: ['PM'], + 509: ['HT'], + 590: ['GP','BL','MF'], + 591: ['BO'], + 592: ['GY'], + 593: ['EC'], + 594: ['GF'], + 595: ['PY'], + 596: ['MQ'], + 597: ['SR'], + 598: ['UY'], + 599: ['AN'], + 670: ['TL'], + 672: ['NF'], + 673: ['BN'], + 674: ['NR'], + 675: ['PG'], + 676: ['TO'], + 677: ['SB'], + 678: ['VU'], + 679: ['FJ'], + 680: ['PW'], + 681: ['WF'], + 682: ['CK'], + 683: ['NU'], + 685: ['WS'], + 686: ['KI'], + 687: ['NC'], + 688: ['TV'], + 689: ['PF'], + 690: ['TK'], + 691: ['FM'], + 692: ['MH'], + 850: ['KP'], + 852: ['HK'], + 853: ['MO'], + 855: ['KH'], + 856: ['LA'], + 880: ['BD'], + 886: ['TW'], + 960: ['MV'], + 961: ['LB'], + 962: ['JO'], + 963: ['SY'], + 964: ['IQ'], + 965: ['KW'], + 966: ['SA'], + 967: ['YE'], + 968: ['OM'], + 970: ['PS'], + 971: ['AE'], + 972: ['IL'], + 973: ['BH'], + 974: ['QA'], + 975: ['BT'], + 976: ['MN'], + 977: ['NP'], + 992: ['TJ'], + 993: ['TM'], + 994: ['AZ'], + 995: ['GE'], + 996: ['KG'], + 998: ['UZ'] +}; + +/** + * A mapping from a region code to the PhoneMetadata for that region. + * @type {Object.} + */ +i18n.phonenumbers.metadata.countryToMetadata = { + "AD": [,[,,"(?:[346-9]|180)\\d{5}","\\d{6,8}"] +,[,,"[78]\\d{5}","\\d{6}",,,"712345"] +,[,,"[346]\\d{5}","\\d{6}",,,"312345"] +,[,,"180[02]\\d{4}","\\d{8}",,,"18001234"] +,[,,"9\\d{5}","\\d{6}",,,"912345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AD",376,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1 $2","[346-9]","",""], +[,"(180[02])(\\d{4})","$1 $2","1","",""]]] +, + "AE": [,[,,"[2-79]\\d{7,8}|800\\d{2,9}","\\d{5,12}"] +,[,,"(?:[2-4679][2-8]\\d|600[25])\\d{5}","\\d{7,9}",,,"22345678"] +,[,,"5[056]\\d{7}","\\d{9}",,,"501234567"] +,[,,"400\\d{6}|800\\d{2,9}","\\d{5,12}",,,"800123456"] +,[,,"900[02]\\d{5}","\\d{9}",,,"900234567"] +,[,,"700[05]\\d{5}","\\d{9}",,,"700012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AE",971,"00","0",,,"0",,,,[[,"([2-4679])(\\d{3})(\\d{4})","$1 $2 $3","[2-4679][2-8]","0$1",""], +[,"(5[056])(\\d{3})(\\d{4})","$1 $2 $3","5","0$1",""], +[,"([4679]00)(\\d)(\\d{5})","$1 $2 $3","[4679]0","0$1",""], +[,"(800)(\\d{2})(\\d{0,7})","$1 $2 $3","8","0$1",""]]] +, + "AF": [,[,,"[2-7]\\d{8}","\\d{9}"] +,[,,"(?:[25][0-8]|[34][0-4]|6[0-5])[2-9]\\d{6}","\\d{9}",,,"234567890"] +,[,,"7[057-9]\\d{7}","\\d{9}",,,"701234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AF",93,"00","0",,,"0",,,,[[,"([2-7]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]]] +, + "AG": [,[,,"[289]\\d{9}","\\d{7,10}"] +,[,,"268(?:4(?:6[0-3]|84)|56[0-2])\\d{4}","\\d{7,10}",,,"2684601234"] +,[,,"268(?:464|7(?:2[0-9]|64|7[0-5]|8[358]))\\d{4}","\\d{10}",,,"2684641234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"26848[01]\\d{4}","\\d{10}",,,"2684801234"] +,"AG",1,"011",,,,,,,,,,,,"268"] +, + "AI": [,[,,"[289]\\d{9}","\\d{7,10}"] +,[,,"2644(?:6[12]|9[78])\\d{4}","\\d{7,10}",,,"2644612345"] +,[,,"264(?:235|476|5(?:3[6-9]|8[1-4])|7(?:29|72))\\d{4}","\\d{10}",,,"2642351234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AI",1,"011",,,,,,,,,,,,"264"] +, + "AL": [,[,,"[2-57]\\d{7}|6\\d{8}|8\\d{5,7}|9\\d{5}","\\d{5,9}"] +,[,,"(?:2(?:[168][1-9]|[247]\\d|9[1-7])|3(?:1[1-3]|[2-6]\\d|[79][1-8]|8[1-9])|4\\d{2}|5(?:1[1-4]|[2-578]\\d|6[1-5]|9[1-7])|8(?:[19][1-5]|[2-6]\\d|[78][1-7]))\\d{5}","\\d{5,8}",,,"22345678"] +,[,,"6[6-9]\\d{7}","\\d{9}",,,"661234567"] +,[,,"800\\d{4}","\\d{7}",,,"8001234"] +,[,,"900\\d{3}","\\d{6}",,,"900123"] +,[,,"808\\d{3}","\\d{6}",,,"808123"] +,[,,"700\\d{5}","\\d{8}",,,"70012345"] +,[,,"NA","NA"] +,"AL",355,"00","0",,,"0",,,,[[,"(4)(\\d{3})(\\d{4})","$1 $2 $3","4[0-6]","0$1",""], +[,"(6[6-9])(\\d{3})(\\d{4})","$1 $2 $3","6","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2358][2-5]|4[7-9]","0$1",""], +[,"(\\d{3})(\\d{5})","$1 $2","[2358][16-9]","0$1",""], +[,"(800)(\\d{4})","$1 $2","800","0$1",""], +[,"(\\d{3})(\\d{3})","$1 $2","9|808","0$1",""], +[,"(700)(\\d{5})","$1 $2","7","0$1",""]]] +, + "AM": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AM",374,"00","8",,,"8",,,1] +, + "AN": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AN",599,"00",,,,,,,1] +, + "AO": [,[,,"[29]\\d{8}","\\d{9}"] +,[,,"2\\d(?:[26-9]\\d|\\d[26-9])\\d{5}","\\d{9}",,,"222123456"] +,[,,"9[1-3]\\d{7}","\\d{9}",,,"923123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AO",244,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "AR": [,[,,"[1-9]\\d{9,11}","\\d{6,12}"] +,[,,"[1-9]\\d{9}","\\d{6,10}",,,"1123456789"] +,[,,"9(?:11[2-9]\\d{7}|(?:2(?:2[013]|37|6[14]|9[179])|3(?:4[1235]|5[138]|8[1578]))[2-9]\\d{6}|\\d{4}[2-9]\\d{5})","\\d{6,12}",,,"91123456789"] +,[,,"80\\d{8}","\\d{10}",,,"8012345678"] +,[,,"6(?:0\\d|10)\\d{7}","\\d{10}",,,"6001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AR",54,"00","0",,,"0(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1-367])|3(?:[06]2|1[467]|2[02-6]|3[13-8]|[49][2-6]|5[2-8]|7)|47[3-578]|6(?:1|2[2-7]|4[6-8]?|5[125-8])|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[0-24-68]|5[2-4]|6[2-6]|72?|8[23]?))|3(?:3(?:2[79]|8[2578])|4(?:0[124-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6\\d|7[126]|8[237-9]|9[1-36-8])|5(?:1|2[1245]|3[2-4]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|7(?:1[15-8]|2[125]|3[1245]|4[13]|5[124-8]|7[2-57]|8[1-36])|8(?:1|2[125-7]|3[23578]|4[13-6]|5[4-8]?|6[1-357-9]|7[5-8]?|8[4-7]?|9[124])))15)?","9$1",,,[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]","0$1",""], +[,"9(11)(\\d{4})(\\d{4})","$1 15-$2-$3","91","0$1",""], +[,"9(\\d{3})(\\d{3})(\\d{4})","$1 15-$2-$3","9(?:2(?:2[013]|37|6[14]|9[179])|3(?:4[1235]|5[138]|8[1578]))","0$1",""], +[,"9(\\d{4})(\\d{2})(\\d{4})","$1 15-$2-$3","9(?:2(?:2[24-9]|3[0-69]|47|6[25]|9[02-68])|3(?:3[28]|4[046-9]|5[2467]|7[1-578]|8[23469]))","0$1",""], +[,"(11)(\\d{4})(\\d{4})","$1 $2-$3","1","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|37|6[14]|9[179])|3(?:4[1235]|5[138]|8[1578])","0$1",""], +[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]","0$1",""]] +,[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,""], +[,"9(11)(\\d{4})(\\d{4})","9 $1 $2-$3","91",,""], +[,"9(\\d{3})(\\d{3})(\\d{4})","9 $1 $2-$3","9(?:2(?:2[013]|37|6[14]|9[179])|3(?:4[1235]|5[138]|8[1578]))",,""], +[,"9(\\d{4})(\\d{2})(\\d{4})","9 $1 $2-$3","9(?:2(?:2[24-9]|3[0-69]|47|6[25]|9[02-68])|3(?:3[28]|4[046-9]|5[2467]|7[1-578]|8[23469]))",,""], +[,"(11)(\\d{4})(\\d{4})","$1 $2-$3","1",,""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|37|6[14]|9[179])|3(?:4[1235]|5[138]|8[1578])",,""], +[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]",,""]]] +, + "AS": [,[,,"[689]\\d{9}","\\d{7,10}"] +,[,,"6846(?:22|33|44|55|77|88|9[19])\\d{4}","\\d{7,10}",,,"6846221234"] +,[,,"684(?:733|258)\\d{4}","\\d{10}",,,"6847331234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AS",1,"011",,,,,,,,,,,,"684"] +, + "AT": [,[,,"\\d{4,13}","\\d{3,13}"] +,[,,"1\\d{3,12}|(?:2(?:1[467]|2[134-8]|5[2357]|6[1-46-8]|7[1-8]|8[124-7]|8[1458])|3(?:1[1-8]|3[23568]|4[5-7]|5[1378]|6[1-38]|8[3-68])|4(?:2[1-8]|35|63|7[1368]|8[2457])|5(?:1[27]|2[1-8]|3[357]|4[147]|5[12578]|6[37])|6(?:13|2[1-47]|4[1-35-8]|5[468]|62)|7(?:2[1-8]|3[25]|4[13478]|5[68]|6[16-8]|7[1-6]|9[45]))\\d{3,10}|5(?:0[1-9]|[79]\\d)\\d{2,10}|720\\d{6,10}","\\d{3,13}",,,"1234567890"] +,[,,"6(?:44|5[0-3579]|6[013-9]|[7-9]\\d)\\d{4,10}","\\d{7,13}",,,"644123456"] +,[,,"80[02]\\d{6,10}","\\d{9,13}",,,"800123456"] +,[,,"(?:711|9(?:0[01]|3[019]))\\d{6,10}","\\d{9,13}",,,"900123456"] +,[,,"8(?:10|2[018])\\d{6,10}","\\d{9,13}",,,"810123456"] +,[,,"NA","NA"] +,[,,"780\\d{6,10}","\\d{9,13}",,,"780123456"] +,"AT",43,"00","0",,,"0",,,,[[,"([15])(\\d{3,12})","$1 $2","1|5[079]","0$1",""], +[,"(\\d{3})(\\d{3,10})","$1 $2","316|46|51|732|6(?:44|5[0-3579]|[6-9])|7(?:1|[28]0)|[89]","0$1",""], +[,"(\\d{4})(\\d{3,9})","$1 $2","2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-35-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[57-9])","0$1",""]]] +, + "AU": [,[,,"[1-578]\\d{5,9}","\\d{6,10}"] +,[,,"[2378]\\d{8}","\\d{8,9}",,,"212345678"] +,[,,"4[0-68]\\d{7}","\\d{9}",,,"412345678"] +,[,,"1(?:80(?:0\\d{2})?|3(?:00\\d{2})?)\\d{4}","\\d{6,10}",,,"1800123456"] +,[,,"190[0126]\\d{6}","\\d{10}",,,"1900123456"] +,[,,"NA","NA"] +,[,,"500\\d{6}","\\d{9}",,,"500123456"] +,[,,"550\\d{6}","\\d{9}",,,"550123456"] +,"AU",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]","0",,,"0",,"0011",,[[,"([2378])(\\d{4})(\\d{4})","$1 $2 $3","[2378]","(0$1)",""], +[,"(4\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","4","0$1",""], +[,"(5[05]0)(\\d{3})(\\d{3})","$1 $2 $3","5","0$1",""], +[,"(1[389]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[38]00|9)","$1",""], +[,"(180)(\\d{4})","$1 $2","180[1-9]","$1",""], +[,"(13)(\\d{2})(\\d{2})","$1 $2 $3","13[1-9]","$1",""]]] +, + "AW": [,[,,"[5-9]\\d{6}","\\d{7}"] +,[,,"5(?:2\\d{2}|8(?:[2-7]\\d|8[0-79]|9[48]))\\d{3}","\\d{7}",,,"5212345"] +,[,,"(?:5[69]\\d|660|9(?:6\\d|9[02-9])|7[34]\\d)\\d{4}","\\d{7}",,,"5601234"] +,[,,"800\\d{4}","\\d{7}",,,"8001234"] +,[,,"900\\d{4}","\\d{7}",,,"9001234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AW",297,"00",,,,,,,,[[,"([5-9]\\d{2})(\\d{4})","$1 $2",,"",""]]] +, + "AZ": [,[,,"[124-8]\\d{7,8}","\\d{8,9}"] +,[,,"(?:1(?:(?:[28]\\d|36|9)\\d|02|1[0-589]|3[358]|4[013-79]|5[0-479]|6[0236-9]|7[0-24-8])|2(?:16|2\\d|3[0-24]|4[1468]|55|6[56]|79))\\d{5}","\\d{8,9}",,,"123123456"] +,[,,"(?:4[04]|5[015]|60|7[07])\\d{7}","\\d{9}",,,"401234567"] +,[,,"88\\d{7}","\\d{9}",,,"881234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AZ",994,"00",,,,,,,,[[,"([4-8]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[4-8]","",""], +[,"([12]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","1[28]|22","",""], +[,"([12]\\d{2})(\\d{5})","$1 $2","1[013-79]|2[013-9]","",""]]] +, + "BA": [,[,,"[3-689]\\d{7}","\\d{6,8}"] +,[,,"(?:[35]\\d|49|81)\\d{6}","\\d{6,8}",,,"30123456"] +,[,,"6[1-356]\\d{6}","\\d{8}",,,"61123456"] +,[,,"8[08]\\d{6}","\\d{8}",,,"80123456"] +,[,,"9[0246]\\d{6}","\\d{8}",,,"90123456"] +,[,,"82\\d{6}","\\d{8}",,,"82123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BA",387,"00","0",,,"0",,,,[[,"([3-689]\\d)(\\d{3})(\\d{3})","$1 $2-$3",,"0$1",""]]] +, + "BB": [,[,,"[289]\\d{9}","\\d{7,10}"] +,[,,"246[2-9]\\d{6}","\\d{7,10}",,,"2462345678"] +,[,,"246(?:(?:2[346]|45|82)\\d|25[0-4])\\d{4}","\\d{10}",,,"2462501234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BB",1,"011",,,,,,,,,,,,"246"] +, + "BD": [,[,,"[2-79]\\d{5,9}|1\\d{9}|8[0-7]\\d{4,8}","\\d{6,10}"] +,[,,"2(?:7\\d1|8(?:[026]1|[1379][1-5]|8[1-8])|9(?:0[0-2]|1[1-4]|3[3-5]|5[56]|6[67]|71|8[078]))\\d{4}|3(?:[6-8]1|(?:0[23]|[25][12]|82|416)\\d|(?:31|12?[5-7])\\d{2})\\d{3}|4(?:(?:02|[49]6|[68]1)|(?:0[13]|21\\d?|[23]2|[457][12]|6[28])\\d|(?:23|[39]1)\\d{2}|1\\d{3})\\d{3}|5(?:(?:[457-9]1|62)|(?:1\\d?|2[12]|3[1-3]|52)\\d|61{2})|6(?:[45]1|(?:11|2[15]|[39]1)\\d|(?:[06-8]1|62)\\d{2})|7(?:(?:32|91)|(?:02|31|[67][12])\\d|[458]1\\d{2}|21\\d{3})\\d{3}|8(?:(?:4[12]|[5-7]2|1\\d?)|(?:0|3[12]|[5-7]1|217)\\d)\\d{4}|9(?:[35]1|(?:[024]2|81)\\d|(?:1|[24]1)\\d{2})\\d{3}","\\d{6,9}",,,"27111234"] +,[,,"(?:1[13-9]\\d|(?:3[78]|44)[02-9]|6(?:44|6[02-9]))\\d{7}","\\d{10}",,,"1812345678"] +,[,,"80[03]\\d{7}","\\d{10}",,,"8001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BD",880,"00[12]?","0",,,"0",,"00",,[[,"(2)(\\d{7})","$1 $2","2","0$1",""], +[,"(\\d{2})(\\d{4,6})","$1 $2","[3-79]1","0$1",""], +[,"(\\d{3})(\\d{3,7})","$1 $2","[3-79][2-9]|8","0$1",""], +[,"(\\d{4})(\\d{6})","$1 $2","1","0$1",""]]] +, + "BE": [,[,,"[1-9]\\d{7,8}","\\d{8,9}"] +,[,,"(?:1[0-69]|[23][2-8]|[49][23]|5\\d|6[013-57-9]|7[18])\\d{6}|8(?:0[1-9]|[1-79]\\d)\\d{5}","\\d{8}",,,"12345678"] +,[,,"4(?:7\\d|8[4-9]|9[1-9])\\d{6}","\\d{9}",,,"470123456"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"(?:90|7[07])\\d{6}","\\d{8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BE",32,"00","0",,,"0",,,,[[,"(4[7-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","4[7-9]","0$1",""], +[,"([2-49])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[23]|[49][23]","0$1",""], +[,"([15-8]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[156]|7[18]|8(?:0[1-9]|[1-79])","0$1",""], +[,"([89]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","(?:80|9)0","0$1",""], +[,"(7[07])(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","7[07]","0$1",""]]] +, + "BF": [,[,,"[2457]\\d{7}","\\d{8}"] +,[,,"(?:20(?:49|5[23]|9[016-9])|40(?:4[569]|55|7[0179])|50[34]\\d)\\d{4}","\\d{8}",,,"20491234"] +,[,,"7(?:[04-6]\\d|1[0-489]|2[0-8]|8[013-9]|90)\\d{5}","\\d{8}",,,"70123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BF",226,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "BG": [,[,,"[1-9]\\d{6,8}","\\d{7,9}"] +,[,,"2\\d{6,7}|(?:[367]\\d|4[124-7]|5[1-9]|8[1-6]|9[1-7])\\d{5,6}|43[1-6]\\d{4,5}","\\d{7,8}",,,"2123456"] +,[,,"(?:8[7-9]|98)\\d{7}|43[0789]\\d{5}|48\\d{6}","\\d{8,9}",,,"48123456"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"90\\d{6}","\\d{8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BG",359,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{3,4})","$1 $2 $3","2","0$1",""], +[,"(43[1-6])(\\d{4,5})","$1 $2","43[1-6]","0$1",""], +[,"(\\d{2})(\\d{2,3})(\\d{3})","$1 $2 $3","[35-7]|4[124-7]|8[1-6]|9[1-7]","0$1",""], +[,"([89]\\d)(\\d{3})(\\d{4})","$1 $2 $3","8[7-9]|98","0$1",""], +[,"([49]\\d)(\\d{3})(\\d{3})","$1 $2 $3","48|90","0$1",""], +[,"(\\d{3})(\\d{5})","$1 $2","43[0789]|800","0$1",""]]] +, + "BH": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BH",973,"00",,,,,,,1] +, + "BI": [,[,,"[27]\\d{7}","\\d{8}"] +,[,,"22(?:2[0-7]|[3-5]0)\\d{4}","\\d{8}",,,"22201234"] +,[,,"(?:29\\d|7(?:1[1-3]|[4-9]\\d))\\d{5}","\\d{8}",,,"79561234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BI",257,"00",,,,,,,,[[,"([27]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "BJ": [,[,,"[2689]\\d{7}|7\\d{3}","\\d{4,8}"] +,[,,"2(?:02|1[037]|2[45]|3[68])\\d{5}","\\d{8}",,,"20211234"] +,[,,"66\\d{6}|9(?:0[069]|[35][0-2457-9]|[6-8]\\d)\\d{5}","\\d{8}",,,"90011234"] +,[,,"7[3-5]\\d{2}","\\d{4}",,,"7312"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"857[58]\\d{4}","\\d{8}",,,"85751234"] +,"BJ",229,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "BL": [,[,,"[56]\\d{8}","\\d{9}"] +,[,,"590(?:2[7-9]|5[12]|87)\\d{4}","\\d{9}",,,"590271234"] +,[,,"690(?:10|2[27]|66|77|8[78])\\d{4}","\\d{9}",,,"690221234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BL",590,"00","0",,,"0"] +, + "BM": [,[,,"[489]\\d{9}","\\d{7,10}"] +,[,,"441(?:2(?:02|23|61|[3479]\\d)|[46]\\d{2}|5(?:4\\d|60|89)|824)\\d{4}","\\d{7,10}",,,"4412345678"] +,[,,"441(?:[37]\\d|5[0-39])\\d{5}","\\d{10}",,,"4413701234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BM",1,"011",,,,,,,,,,,,"441"] +, + "BN": [,[,,"[2-578]\\d{6}","\\d{7}"] +,[,,"[2-5]\\d{6}","\\d{7}",,,"2345678"] +,[,,"[78]\\d{6}","\\d{7}",,,"7123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BN",673,"00","0",,,"0",,,,[[,"([2-578]\\d{2})(\\d{4})","$1 $2",,"0$1",""]]] +, + "BO": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BO",591,"001[0-3]","0",,,"0",,,1] +, + "BR": [,[,,"[1-9]\\d{7,9}","\\d{8,10}"] +,[,,"(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[2-5]\\d{7}","\\d{8,10}",,,"1123456789"] +,[,,"(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[6-9]\\d{7}","\\d{10}",,,"1161234567"] +,[,,"800\\d{6,7}","\\d{8,10}",,,"800123456"] +,[,,"[359]00\\d{6,7}","\\d{8,10}",,,"300123456"] +,[,,"(?:400\\d|3003)\\d{4}","\\d{8,10}",,,"40041234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BR",55,"00(?:1[45]|2[135]|[34]1|43)","0",,,"0(?:(?:1[245]|2[135]|[34]1)(\\d{10}))?","$1",,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","[1-9][1-9]","($1)","0 $CC $1"], +[,"([34]00\\d)(\\d{4})","$1-$2","400|3003","",""], +[,"([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3","[3589]00","0$1",""]]] +, + "BS": [,[,,"[289]\\d{9}","\\d{7,10}"] +,[,,"242(?:3(?:02|[236][1-9]|4[0-24-9]|5[0-68]|7[3467]|8[0-4]|9[2-467])|461|502|6(?:12|7[67]|8[78]|9[89])|702)\\d{4}","\\d{7,10}",,,"2423456789"] +,[,,"242(?:3(?:5[79]|[79]5)|4(?:[2-4][1-9]|5[1-8]|6[2-8]|7\\d|81)|5(?:2[34]|3[35]|44|5[1-9]|65|77)|6[34]6|727)\\d{4}","\\d{10}",,,"2423591234"] +,[,,"242300\\d{4}|8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BS",1,"011",,,,,,,,,,,,"242"] +, + "BT": [,[,,"(?:17|[2-8])\\d{6}","\\d{6,8}"] +,[,,"(?:2[3-6]|[34][5-7]|5[236]|6[2-46]|7[246]|8[2-4])\\d{5}","\\d{6,7}",,,"2345678"] +,[,,"17\\d{6}","\\d{8}",,,"17123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BT",975,"00",,,,,,,,[[,"(17)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","1","",""], +[,"([2-8])(\\d{3})(\\d{3})","$1 $2 $3","[2-8]","",""]]] +, + "BW": [,[,,"[2-9]\\d{6,7}","\\d{7,8}"] +,[,,"(?:2(?:4[0-48]|6[0-24]|9[0578])|3(?:1[0235-9]|55|6\\d|7[01]|9[0-57])|4(?:6[03]|7[1267]|9[0-5])|5(?:3[0389]|4[0489]|7[1-47]|88|9[0-49])|6(?:2[1-35]|5[149]|8[067]))\\d{4}","\\d{7}",,,"2401234"] +,[,,"7[1-3]\\d{6}|74[0-7]\\d{5}","\\d{8}",,,"71123456"] +,[,,"8\\d{6}","\\d{7}",,,"8123456"] +,[,,"90\\d{5}","\\d{7}",,,"9012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BW",267,"00",,,,,,,,[[,"(7[1-4])(\\d{3})(\\d{3})","$1 $2 $3","7","",""], +[,"(90)(\\d{5})","$1 $2","9","",""]]] +, + "BY": [,[,,"[12-4]\\d{8}|[89]\\d{9}","\\d{7,10}"] +,[,,"(?:1(?:5(?:1[1-5]|2\\d|6[1-4]|9[1-7])|6(?:[235]\\d|4[1-7])|7\\d{2})|2(?:1(?:[246]\\d|3[0-35-9]|5[1-9])|2(?:[235]\\d|4[0-8])|3(?:2\\d|3[02-79]|4[024-7]|5[0-7])))\\d{5}","\\d{7,9}",,,"152450911"] +,[,,"(?:2(?:5[679]|9[1-9])|33\\d|44\\d)\\d{6}","\\d{9}",,,"294911911"] +,[,,"80[13]\\d{7}","\\d{10}",,,"8011234567"] +,[,,"902\\d{7}","\\d{10}",,,"9021234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BY",375,"8~10","8",,,"80?",,,,[[,"([1-4]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[1-4]","8 0$1",""], +[,"([89]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[89]","8 $1",""]]] +, + "BZ": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BZ",501,"00","0",,,"0",,,1] +, + "CA": [,[,,"[2-9]\\d{9}|3\\d{6}","\\d{7,10}"] +,[,,"(?:2(?:04|26|50|89)|306|4(03|16|18|38|50|56)|5(?:00|06|14|19|81|87)|6(?:00|04|13|47)|7(?:00|05|09|10|78|80)|8(?:07|19|67))[2-9]\\d{6}|310\\d{4}","\\d{7,10}",,,"2042345678"] +,[,,"(?:2(?:04|26|50|89)|306|4(03|16|18|38|50|56)|5(?:00|06|14|19|81|87)|6(?:00|04|13|47)|7(?:00|05|09|10|78|80)|8(?:07|19|67)|9(?:02|05))[2-9]\\d{6}","\\d{7,10}",,,"2042345678"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}|310\\d{4}","\\d{7,10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CA",1,"011"] +, + "CD": [,[,,"[89]\\d{8}|[1-6]\\d{6}","\\d{7,9}"] +,[,,"[1-6]\\d{6}","\\d{7}",,,"1234567"] +,[,,"(?:8[0149]|9[7-9])\\d{7}","\\d{9}",,,"991234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CD",243,"00","0",,,"0",,,,[[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[89]","0$1",""], +[,"([1-6]\\d)(\\d{5})","$1 $2","[1-6]","0$1",""]]] +, + "CF": [,[,,"[278]\\d{7}","\\d{8}"] +,[,,"2[12]\\d{6}","\\d{8}",,,"21612345"] +,[,,"7[0257]\\d{6}","\\d{8}",,,"70012345"] +,[,,"NA","NA"] +,[,,"8776\\d{4}","\\d{8}",,,"87761234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CF",236,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "CG": [,[,,"[24-68]\\d{6}","\\d{7}"] +,[,,"(?:2[1-589]|8\\d)\\d{5}","\\d{7}",,,"2123456"] +,[,,"[4-6]\\d{6}","\\d{7}",,,"5012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CG",242,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "CH": [,[,,"[2-9]\\d{8}","\\d{9}"] +,[,,"(?:2[12467]|3[1-4]|4[134]|5[12568]|6[12]|[7-9]1)\\d{7}","\\d{9}",,,"212345678"] +,[,,"7[46-9]\\d{7}","\\d{9}",,,"741234567"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"90[016]\\d{6}","\\d{9}",,,"900123456"] +,[,,"84[0248]\\d{6}","\\d{9}",,,"840123456"] +,[,,"878\\d{6}","\\d{9}",,,"878123456"] +,[,,"NA","NA"] +,"CH",41,"00","0",,,"0",,,,[[,"([2-9]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[2-6]|[7-9]1","0$1",""], +[,"(7[46-9])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","7[46-9]","0$1",""], +[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","8[047]|90","0$1",""]]] +, + "CI": [,[,,"[02-5]\\d{7}","\\d{8}"] +,[,,"(?:2(?:0[023]|1[02357]|[23][045]|4[03-5])|3(?:0[06]|1[069]|[2-4][07]|5[09]|6[08]))\\d{5}","\\d{8}",,,"21234567"] +,[,,"(?:0[1-9]|4[04-9]|50|6[067])\\d{6}","\\d{8}",,,"01234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CI",225,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "CK": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CK",682,"00","00",,,"00",,,1] +, + "CL": [,[,,"(?:[2-9]|600|123)\\d{7,8}","\\d{6,11}"] +,[,,"(?:2|32|41)\\d{7}|(?:3[3-5]|4[235]|5[1-3578]|6[13-57]|7[1-35])\\d{6,7}","\\d{6,9}",,,"21234567"] +,[,,"9[6-9]\\d{7}","\\d{8,9}",,,"961234567"] +,[,,"800\\d{6}|1230\\d{7}","\\d{9,11}",,,"800123456"] +,[,,"600\\d{7,8}","\\d{10,11}",,,"6001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"44\\d{7}","\\d{9}",,,"441234567"] +,"CL",56,"(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0",,,"(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3","2","0$1",""], +[,"(\\d{2})(\\d{2,3})(\\d{4})","$1 $2 $3","[357]|4[1-35]|6[13-57]","0$1",""], +[,"(9)([6-9]\\d{3})(\\d{4})","$1 $2 $3","9","0$1",""], +[,"(44)(\\d{3})(\\d{4})","$1 $2 $3","44","0$1",""], +[,"(600)(\\d{3})(\\d{4})","$1 $2 $3","60","$1",""], +[,"(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4","60","$1",""], +[,"(800)(\\d{3})(\\d{3})","$1 $2 $3","8","$1",""], +[,"(1230)(\\d{3})(\\d{4})","$1 $2 $3","1","$1",""]]] +, + "CM": [,[,,"[237-9]\\d{7}","\\d{8}"] +,[,,"(?:22|33)\\d{6}","\\d{8}",,,"22123456"] +,[,,"[79]\\d{7}","\\d{8}",,,"71234567"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"88\\d{6}","\\d{8}",,,"88012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CM",237,"00",,,,,,,,[[,"([237-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[2379]|88","",""], +[,"(800)(\\d{2})(\\d{3})","$1 $2 $3","80","",""]]] +, + "CN": [,[,,"[1-79]\\d{7,11}|8[0-357-9]\\d{6,9}","\\d{4,12}"] +,[,,"21\\d{8,10}|(?:10|2[02-57-9]|3(?:11|7[159])|4[135]1|5(?:1\\d|2[37]|3[12]|7[13-79]|9[15])|7(?:31|5[457]|6[09])|898)\\d{8}|(?:3(?:1[02-9]|35|49|5\\d|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7[0-46-9]|8[23])|5(?:3[03-9]|4[36]|5\\d|6[1-6]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]\\d|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|[37]\\d|5[1-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]\\d|4[13]|5[1-5]))\\d{7}|80(?:29|6[03578]|7[018]|81)\\d{4}","\\d{4,12}",,,"1012345678"] +,[,,"1(?:3[0-9]|47|5[0135689]|8[05-9])\\d{8}","\\d{11}",,,"13123456789"] +,[,,"10800\\d{7}","\\d{12}",,,"108001234567"] +,[,,"16[08]\\d{5}","\\d{8}",,,"16812345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"400\\d{7}","\\d{10}",,,"4001234567"] +,"CN",86,"00","0",,,"0",,,,[[,"(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","0$1",""], +[,"([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","0$1",""], +[,"(80\\d{2})(\\d{4})","$1 $2","80","0$1",""], +[,"(\\d{3})(\\d{3,4})(\\d{4})","$1 $2 $3","[35-79]|[48][1-9]","0$1",""], +[,"(1[3-58]\\d)(\\d{4})(\\d{4})","$1 $2 $3","1[3-58]","",""], +[,"(400)(\\d{3})(\\d{4})","$1 $2 $3","40","",""], +[,"(10800)(\\d{3})(\\d{4})","$1 $2 $3","1080","",""]]] +, + "CO": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CO",57,"(?:00[579]|#555|#999)","0",,,"0",,,1] +, + "CR": [,[,,"[28]\\d{7}","\\d{8}"] +,[,,"2[24-7]\\d{6}","\\d{8}",,,"22123456"] +,[,,"8[38]\\d{6}","\\d{8}",,,"83123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CR",506,"00",,,,,,,,[[,"([28]\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "CU": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CU",53,"119","0",,,"0",,,1] +, + "CV": [,[,,"[259]\\d{6}","\\d{7}"] +,[,,"2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\\d|7[1-3]|8[1-5])\\d{4}","\\d{7}",,,"2211234"] +,[,,"(?:9\\d|59)\\d{5}","\\d{7}",,,"9911234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"CV",238,"0",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]]] +, + "CY": [,[,,"[27-9]\\d{7}","\\d{8}"] +,[,,"2[2-6]\\d{6}","\\d{8}",,,"22345678"] +,[,,"7777\\d{4}|9(?:[69]\\d|7[67])\\d{5}","\\d{8}",,,"96123456"] +,[,,"8000\\d{4}","\\d{8}",,,"80001234"] +,[,,"9009\\d{4}","\\d{8}",,,"90091234"] +,[,,"NA","NA"] +,[,,"700\\d{5}","\\d{8}",,,"70012345"] +,[,,"NA","NA"] +,"CY",357,"00",,,,,,,,[[,"([27-9]\\d)(\\d{6})","$1 $2",,"",""]]] +, + "CZ": [,[,,"[2-9]\\d{8}","\\d{9}"] +,[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}","\\d{9}",,,"212345678"] +,[,,"60[1-8]\\d{6}|7[2379]\\d{7}","\\d{9}",,,"601123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"90[0689]\\d{6}","\\d{9}",,,"900123456"] +,[,,"8[134]\\d{7}","\\d{9}",,,"811234567"] +,[,,"70[01]\\d{6}","\\d{9}",,,"700123456"] +,[,,"NA","NA"] +,"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "DE": [,[,,"(?:4[0-8]|[1-35-9]\\d)\\d{4,12}|49(?:4[1-8]|[0-35-7]\\d)\\d{2,7}","\\d{2,14}"] +,[,,"(?:[246]\\d{2}|3[02-9]\\d|5(?:0[2-8]|[38][0-8]|[124-6]\\d|[79][0-7])|[789](?:[1-9]\\d|0[2-9]))\\d{3,10}","\\d{2,14}",,,"30123456"] +,[,,"1(?:5\\d{9}|7(?:[0-57-9]|6\\d)\\d{7}|6[02]\\d{7,8}|63\\d{7})","\\d{10,11}",,,"15123456789"] +,[,,"800\\d{7,9}","\\d{10,12}",,,"8001234567"] +,[,,"900(?:[135]\\d{6}|9\\d{7})","\\d{10,11}",,,"9001234567"] +,[,,"180\\d{5,11}","\\d{8,14}",,,"18012345"] +,[,,"700\\d{8}","\\d{11}",,,"70012345678"] +,[,,"NA","NA"] +,"DE",49,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{4,11})","$1/$2","3[02]|40|[68]9","0$1",""], +[,"(\\d{3})(\\d{3,10})","$1/$2","2(?:\\d1|0[2389]|1[24]|28|34)|3[3-9][15]|340|906|[4-9][1-9]1","0$1",""], +[,"([24-9]\\d{3})(\\d{2,8})","$1/$2","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)","0$1",""], +[,"(\\d{4})(\\d{2,7})","$1/$2","3(?:3(?:0[1-467]|2[127-9]|3[124578]|[46][1246]|7[1257-9]|8[1256]|9[145])|4(?:2[135]|3[1357]|4[13578]|6[1246]|7[1356]|9[1346])|5(?:0[14]|2[1-3589]|3[1357]|4[1246]|6[1-4]|7[1346]|8[13568]|9[1246])|6(?:0[356]|2[1-489]|3[124-6]|4[1347]|6[13]|7[12579]|8[1-356]|9[135])|7(?:2[1-7]|3[1357]|4[145]|6[1-5]|7[1-4])|8(?:21|3[1468]|4[1347]|6[0135-9]|7[1467]|8[136])|9(?:0[12479]|2[1358]|3[1357]|4[134679]|6[1-9]|7[136]|8[147]|9[1468]))","0$1",""], +[,"(\\d{5})(\\d{1,6})","$1/$2","3","0$1",""], +[,"(1[5-7]\\d)(\\d{7,8})","$1 $2","1[5-7]","0$1",""], +[,"(180)(\\d)(\\d{4,10})","$1 $2 $3","180","0$1",""], +[,"(700)(\\d{4})(\\d{4})","$1 $2 $3","700","0$1",""], +[,"(800)(\\d{7,9})","$1 $2","800","0$1",""], +[,"(900)(\\d)(\\d{6})","$1 $2 $3","900[135]","0$1",""], +[,"(900)(9)(\\d{7})","$1 $2 $3","9009","0$1",""]]] +, + "DJ": [,[,,"[2-8]\\d{5}","\\d{6}"] +,[,,"(?:25|3[0-6]|42)\\d{4}","\\d{6}",,,"251234"] +,[,,"(?:[5-7]\\d|8[0-7])\\d{4}","\\d{6}",,,"601234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"DJ",253,"00",,,,,,,,[[,"([2-8]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,"",""]]] +, + "DK": [,[,,"[1-9]\\d{7}","\\d{8}"] +,[,,"(?:3[2-9]|4[3-9]|5[4-9]|6[2-9]|7[02-9]|8[26-9]|9[6-9])\\d{6}","\\d{8}",,,"32123456"] +,[,,"(?:2[0-9]|3[0-2]|4[0-2]|5[0-3]|6[01]|72|99)\\d{6}","\\d{8}",,,"20123456"] +,[,,"80\\d{6}","\\d{8}",,,"80123456"] +,[,,"90\\d{6}","\\d{8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"DK",45,"00",,,,,,,,[[,"([1-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "DM": [,[,,"[7-9]\\d{9}","\\d{7,10}"] +,[,,"767(?:2(?:55|66)|4(?:2[01]|4[0-25-9])|50[0-4])\\d{4}","\\d{7,10}",,,"7674201234"] +,[,,"767(?:2(?:[2346]5|7[5-7])|31[5-7]|61[4-6])\\d{4}","\\d{10}",,,"7672251234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"DM",1,"011",,,,,,,,,,,,"767"] +, + "DO": [,[,,"[89]\\d{9}","\\d{7,10}"] +,[,,"8[024]9[2-9]\\d{6}","\\d{7,10}",,,"8092345678"] +,[,,"8[024]9[2-9]\\d{6}","\\d{7,10}",,,"8092345678"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"DO",1,"011",,,,,,,1,,,,,"8[024]9"] +, + "DZ": [,[,,"(?:[1-4]|[5-9]\\d)\\d{7}","\\d{8,9}"] +,[,,"(?:1\\d|2[014-79]|3[0-8]|4[0135689])\\d{6}|9619\\d{5}","\\d{8,9}",,,"12345678"] +,[,,"(?:5[56]|6[69]|7[79])\\d{7}","\\d{9}",,,"551234567"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"80[3-689]1\\d{5}","\\d{9}",,,"808123456"] +,[,,"80[12]1\\d{5}","\\d{9}",,,"801123456"] +,[,,"NA","NA"] +,[,,"98[23]\\d{6}","\\d{9}",,,"983123456"] +,"DZ",213,"00","0",,,"0",,,,[[,"([1-4]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[1-4]","0$1",""], +[,"([5-8]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[5-8]","0$1",""], +[,"(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","0$1",""]]] +, + "EC": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"EC",593,"00","0",,,"0",,,1] +, + "EE": [,[,,"[3-9]\\d{6,7}|800\\d{6,7}","\\d{6,10}"] +,[,,"(?:3[23589]|4[3-8]|6\\d|7[1-9]|88)\\d{5}","\\d{7}",,,"3212345"] +,[,,"(?:5\\d|8[1-5])\\d{6}|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])\\d{3}","\\d{7,8}",,,"51234567"] +,[,,"800(?:0\\d{3}|1\\d|[2-9])\\d{3}","\\d{7,10}",,,"80012345"] +,[,,"900\\d{4}","\\d{7}",,,"9001234"] +,[,,"NA","NA"] +,[,,"70\\d{5}","\\d{7}",,,"7012345"] +,[,,"NA","NA"] +,"EE",372,"00",,,,,,,,[[,"([34-79]\\d{2})(\\d{4})","$1 $2","[34679]|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])","",""], +[,"(8000)(\\d{3})(\\d{3})","$1 $2 $3","8000","",""], +[,"([58]\\d{3})(\\d{4})","$1 $2","5|8(?:001|[1-5])","",""], +[,"(800[2-9])(\\d{3})","$1 $2","800[2-9]","",""]]] +, + "EG": [,[,,"1\\d{4,9}|[2-689]\\d{7,9}","\\d{5,10}"] +,[,,"(?:1[35][23]|2[23]\\d|3\\d|4(?:0[2-4]|[578][23]|64)|5(?:0[234]|[57][23])|6[24-689]3|8(?:[28][2-4]|42|6[23])|9(?:[25]2|3[24]|6[23]|7[2-4]))\\d{6}|1[69]\\d{3}","\\d{5,9}",,,"234567890"] +,[,,"1[0-246-9]\\d{7}","\\d{9}",,,"101234567"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"900\\d{7}","\\d{10}",,,"9001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"EG",20,"00","0",,,"0",,,,[[,"(2)(\\d{8})","$1 $2","2","0$1",""], +[,"(3)(\\d{7})","$1 $2","3","0$1",""], +[,"(\\d{2})(\\d{7})","$1 $2","[14-6]|[89][2-9]","0$1",""], +[,"([89]00)(\\d{3})(\\d{4})","$1 $2 $3","[89]00","0$1",""]]] +, + "ER": [,[,,"[178]\\d{6}","\\d{6,7}"] +,[,,"1(?:1[12568]|20|40|55|6[146])\\d{4}|8\\d{6}","\\d{6,7}",,,"8370362"] +,[,,"17[1-3]\\d{4}|7\\d{6}","\\d{7}",,,"7123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ER",291,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"0$1",""]]] +, + "ES": [,[,,"[5-9]\\d{8}","\\d{9}"] +,[,,"[89][1-8]\\d{7}","\\d{9}",,,"812345678"] +,[,,"6\\d{8}","\\d{9}",,,"612345678"] +,[,,"[89]00\\d{6}","\\d{9}",,,"800123456"] +,[,,"80[367]\\d{6}","\\d{9}",,,"803123456"] +,[,,"90[12]\\d{6}","\\d{9}",,,"901123456"] +,[,,"70\\d{7}","\\d{9}",,,"701234567"] +,[,,"NA","NA"] +,"ES",34,"00",,,,,,,,[[,"([5-9]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "ET": [,[,,"[1-59]\\d{8}","\\d{7,9}"] +,[,,"(?:11(?:1(?:1[124]|2[2-57]|3[1-5]|5[5-8]|8[6-8])|2(?:13|3[6-8]|5[89]|7[05-9]|8[2-6])|3(?:2[01]|3[0-289]|4[1289]|7[1-4]|87)|4(?:1[69]|3[2-49]|4[0-23]|6[5-8])|5(?:1[57]|44|5[0-4])|6(?:18|2[69]|4[5-7]|5[1-5]|6[0-59]|8[015-8]))|2(?:2(?:11[1-9]|22[0-7]|33\\d|44[1467]|66[1-68])|5(?:11[124-6]|33[2-8]|44[1467]|55[14]|66[1-3679]|77[124-79]|880))|3(?:3(?:11[0-46-8]|22[0-6]|33[0134689]|44[04]|55[0-6]|66[01467])|4(?:44[0-8]|55[0-69]|66[0-3]|77[1-5]))|4(?:6(?:22[0-24-7]|33[1-5]|44[13-69]|55[14-689]|660|88[1-4])|7(?:11[1-9]|22[1-9]|33[13-7]|44[13-6]|55[1-689]))|5(?:7(?:227|55[05]|(?:66|77)[14-8])|8(?:11[149]|22[013-79]|33[0-68]|44[013-8]|550|66[1-5]|77\\d)))\\d{4}","\\d{7,9}",,,"111112345"] +,[,,"91(?:1(?:[146]\\d|2[0-5]|3[4-6]|50|7[2-6]|8[46-9])|31\\d|4(?:3[0-2489]|7[0-3])|5(?:3[23]|7[3-5])|6(?:58|8[23])|7(?:5[57]|8[01])|8(?:3[45]|7[67]))\\d{4}","\\d{9}",,,"911123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ET",251,"00","0",,,"0",,,,[[,"([1-59]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]]] +, + "FI": [,[,,"[1-9]\\d{4,11}","\\d{5,12}"] +,[,,"1(?:0[1-9]\\d{3,7}|[35689][1-8]\\d{3,9}|[47]\\d{5,10})|2(?:0(?:[16-8]\\d{3,7}|2[14-9]\\d{1,6}|[3-5]\\d{2,7}|9[0-7]\\d{1,6})|[1-8]\\d{3,9}|9\\d{4,8})|3(?:0[1-9]\\d{3,7}|[1-8]\\d{3,9}|9\\d{4,8})|[5689][1-8]\\d{3,9}|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{2,7})","\\d{5,12}",,,"1312345678"] +,[,,"4\\d{5,10}|50\\d{4,8}","\\d{6,11}",,,"412345678"] +,[,,"800\\d{4,7}","\\d{7,10}",,,"8001234567"] +,[,,"[67]00\\d{5,6}","\\d{8,9}",,,"600123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"FI",358,"00|99[049]","0",,,"0",,,,[[,"(\\d{2})(\\d{4,10})","$1 $2","2[09]|[14]|50|7[135]","0$1",""], +[,"(\\d)(\\d{4,11})","$1 $2","[25689][1-8]|3","0$1",""], +[,"([6-8]00)(\\d{4,7})","$1 $2","[6-8]0","0$1",""]]] +, + "FJ": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"FJ",679,"00",,,,,,,1] +, + "FK": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"FK",500,"00","0",,,"0",,,1] +, + "FM": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"FM",691,"00",,,,,,,1] +, + "FO": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"FO",298,"00",,,,,,,1] +, + "FR": [,[,,"[1-9]\\d{8}","\\d{9}"] +,[,,"[1-5]\\d{8}","\\d{9}",,,"123456789"] +,[,,"6\\d{8}|7[5-9]\\d{7}","\\d{9}",,,"612345678"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"8(?:1[01]|2[0156]|84|9[0-37-9])\\d{6}","\\d{9}",,,"810123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"9\\d{8}","\\d{9}",,,"912345678"] +,"FR",33,"[04579]0","0",,,"0",,,,[[,"([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","[1-79]","0$1",""], +[,"(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","8","0 $1",""]]] +, + "GA": [,[,,"[4-9]\\d{5}|0\\d{7}","\\d{6,8}"] +,[,,"(?:4(?:[04-8]\\d|2[04])|(?:5[04-689]|6[024-9]|7\\d|8[236]|9[02368])\\d)\\d{3}","\\d{6}",,,"441234"] +,[,,"0(?:5(?:0[89]|3[0-4]|8[0-26]|9[238])|6(?:0[3-7]|1[01]|2[0-7]|6[0-589]|71|83|9[57])|7(?:1[2-5]|2[89]|3[35-9]|4[01]|5[0-347-9]|[67]\\d|8[457-9]|9[0146]))\\d{4}","\\d{8}",,,"06031234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GA",241,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3","[4-9]","",""], +[,"(0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","0","",""]]] +, + "GB": [,[,,"\\d{7,10}","\\d{6,10}"] +,[,,"1(?:1[3-8]|[2-69]1)\\d{7}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-47-9]|7[013-9]|8[02-9]|9[0-9])|3(?:0\\d|[25][02-9]|3[02-579]|4[0-56-9]|[68][0-46-9]|7[1-35-79]|9[24578])|4(?:0[03-9]|2[02-57-9]|[37]\\d|4[02-69]|5[0-8]|[69][0-79]|8[02-9])|5(?:0[1-35-9]|2[024-9]|3[015689]|4[02-9]|[57][03-9]|6\\d|8[0-68]|9[0-57-9])|6(?:0[034689]|2[035689]|3[13-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|8[013-9]|9[0-24578])|7(?:0[0246-9]|2\\d|3[0236-8]|4[03-9]|5[0-46-9]|6[13-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-9]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[2-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-57-9]|4[2-9]|5[0-579]|6[2-47-9]|7[0-24578]|8\\d|9[2-57]))\\d{5,6}|(?:2[03489]|3[0347]|55)\\d{8}","\\d{6,10}",,,"1212345678"] +,[,,"7(?:4[0-26]\\d|5(?:[013-9]\\d|2[0-35-9])|7(?:0[1-9]|8[02-9]|9[0-689]|[1-7]\\d)|8(?:[014-9]\\d|[23][0-8])|9(?:1[02-9]|2[0135-9]|3[0-689]|[04-9]\\d))\\d{6}","\\d{10}",,,"7400123456"] +,[,,"80(?:01111|\\d{7,8})|500\\d{6}","\\d{7,10}",,,"8012345678"] +,[,,"(?:9[018]\\d|87[1-3])\\d{7}","\\d{10}",,,"9012345678"] +,[,,"8(?:4[3-5]|70)\\d{7}","\\d{10}",,,"8431234567"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,[,,"56\\d{8}","\\d{10}",,,"5612345678"] +,"GB",44,"00","0"," x",,"0",,,,[[,"([235]\\d)(\\d{4})(\\d{4})","$1 $2 $3","[23]|55","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:1\\d|\\d1)","0$1",""], +[,"(\\d{5})(\\d{4,5})","$1 $2","1(?:3873|5(?:242|39[4-6])|697[347]|768[347]|9467)","0$1",""], +[,"(\\d{4})(\\d{4,6})","$1 $2","1","0$1",""], +[,"(7\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","7[1-9]","0$1",""], +[,"(500)(\\d{3})(\\d{3})","$1 $2 $3","500","0$1",""], +[,"([59]\\d)(\\d{4})(\\d{4})","$1 $2 $3","56|9[018]","0$1",""], +[,"(70\\d{2})(\\d{6})","$1 $2","70","0$1",""], +[,"(800)(1111)","$1 $2","8001","0$1",""], +[,"(80\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","80","0$1",""], +[,"(8\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","8(?:4[3-5]|7[01])","0$1",""]] +,,,1] +, + "GD": [,[,,"[489]\\d{9}","\\d{7,10}"] +,[,,"473(?:2(?:3[0-2]|69)|3(?:2[89]|86)|4(?:08|3[5-9]|4[0-49]|5[5-79]|68|73|90)|63[68]|7(?:58|84)|938)\\d{4}","\\d{7,10}",,,"4732691234"] +,[,,"473(?:4(?:0[3-79]|1[04-9]|20|58)|53[3-8])\\d{4}","\\d{10}",,,"4734031234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GD",1,"011",,,,,,,,,,,,"473"] +, + "GE": [,[,,"[1-3579]\\d{7}|8\\d{8}","\\d{3,9}"] +,[,,"(?:122|2(?:22|36|5[03])|3(?:1[0-35-8]|[24-6]\\d|3[1-35679]|7[0-39]|9[1-35-7])|44[2-6])\\d{5}","\\d{3,8}",,,"32123456"] +,[,,"(?:5[1578]|6[28]|7[0147-9]|9[0135-9])\\d{6}","\\d{8}",,,"55123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GE",995,"8~10","8",,,"8",,,,[[,"(32)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","32","8 $1",""], +[,"(\\d{3})(\\d{5})","$1 $2","2|3[13-79]|446","8 $1",""], +[,"(\\d{4})(\\d{4})","$1 $2","44(?:2[2369]|[345])","8 $1",""], +[,"(442[57])(\\d{3})","$1 $2","442[57]","8 $1",""], +[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[5679]","8 $1",""], +[,"(800)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","8","8 $1",""]]] +, + "GF": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GF",594,"00",,,,,,,1] +, + "GG": [,[,,"[157-9]\\d{6,9}","\\d{6,10}"] +,[,,"1481\\d{6}","\\d{6,10}",,,"1481123456"] +,[,,"7(?:781|839|911)\\d{6}","\\d{10}",,,"7781123456"] +,[,,"80(?:01111|\\d{7,8})|500\\d{6}","\\d{7,10}",,,"8012345678"] +,[,,"(?:9[018]\\d|87[1-3])\\d{7}","\\d{10}",,,"9012345678"] +,[,,"8(?:4[3-5]|70)\\d{7}","\\d{10}",,,"8431234567"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,[,,"56\\d{8}","\\d{10}",,,"5612345678"] +,"GG",44,"00","0"," x",,"0"] +, + "GH": [,[,,"[2-9]\\d{4,8}","\\d{5,9}"] +,[,,"(?:251|3[467]2|41|5(?:[36]1|[78]2)|61|882|9(?:1|6[268]))\\d{3}|(?:31[24]|567|6(?:1|5[23])|7(?:2|43)|9(?:1|35))\\d{4}|(?:2[12]|3(?:45|9[24])|4(?:2|32])|5(?:1|6[58])|64[28]|7(?:1[567]?|46|5[26]|62)|8(?:1|4[268]|7[26])|9(?:31|53))\\d{5}|(?:2[12]|42|51)\\d{6}|3\\d{8}","\\d{5,9}",,,"251234"] +,[,,"2(?:755\\d{4}|(?:4\\d?|08)\\d{6}|[368]\\d{7})|54\\d{7}","\\d{8,9}",,,"27551234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GH",233,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3,6})","$1 $2","[27][12]|4[12]|[35689]1","0$1",""], +[,"([2-9]\\d{2})(\\d{3,5})","$1 $2","25|31|[4-9]","0$1",""], +[,"(3\\d)(\\d{3})(\\d{4})","$1 $2 $3","3[02-9]","0$1",""], +[,"(2[47])(\\d{3})(\\d{3,4})","$1 $2 $3","2[47]","0$1",""], +[,"([25]\\d)(\\d{3})(\\d{4})","$1 $2 $3","2[0368]|54","0$1",""]]] +, + "GI": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GI",350,"00",,,,,,,1] +, + "GL": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GL",299,"00",,,,,,,1] +, + "GM": [,[,,"[3-9]\\d{6}","\\d{7}"] +,[,,"(4(?:[23]\\d{2}|4(?:1[024679]|[6-9]\\d))|5(?:54[0-7]|6(?:[67]\\d)|7(?:1[04]|2[035]|3[58]|48))|8\\d{3})\\d{3}","\\d{7}",,,"5661234"] +,[,,"[3679]\\d{6}","\\d{7}",,,"3012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GM",220,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "GN": [,[,,"[367]\\d{7}","\\d{8}"] +,[,,"30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\\d{4}","\\d{8}",,,"30241234"] +,[,,"6(?:0(?:2\\d|3[3467]|5[2457-9])|[2457]\\d{2}|3(?:[14]0|35))\\d{4}","\\d{8}",,,"60201234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GN",224,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "GP": [,[,,"[56]\\d{8}","\\d{9}"] +,[,,"590(?:1[12]|2[0-68]|3[28]|4[126-8]|5[067]|6[018]|[89]\\d)\\d{4}","\\d{9}",,,"590201234"] +,[,,"690(?:00|[3-5]\\d|6[0-57-9]|7[1-6]|8[0-6]|9[09])\\d{4}","\\d{9}",,,"690301234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GP",590,"00","0",,,"0",,,,[[,"([56]90)(\\d{2})(\\d{4})","$1 $2-$3",,"0$1",""]] +,,,1] +, + "GQ": [,[,,"[23589]\\d{8}","\\d{6,9}"] +,[,,"3(?:3(?:3\\d[7-9]|[0-24-9]\\d[46])|5\\d{2}[7-9])\\d{4}","\\d{6,9}",,,"333091234"] +,[,,"(?:222|551)\\d{6}","\\d{6,9}",,,"222123456"] +,[,,"80\\d[1-9]\\d{5}","\\d{6,9}",,,"800123456"] +,[,,"90\\d[1-9]\\d{5}","\\d{6,9}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GQ",240,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[235]","",""], +[,"(\\d{3})(\\d{6})","$1 $2","[899]","",""]]] +, + "GR": [,[,,"[26-9]\\d{9}","\\d{10}"] +,[,,"2(?:1\\d{2}|2(?:3[1-8]|4[1-7]|5[1-4]|6[1-8]|7[1-5]|[289][1-9])|3(?:1\\d|2[1-5]|3[1-4]|[45][1-3]|7[1-7]|8[1-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|2[1-3]|4[124]|5[1-6]|[39][1-4])|6(?:1\\d|3[24]|4[1-7]|5[13-9]|[269][1-6]|7[14]|8[1-35])|7(?:1\\d|[23][1-5]|4[1-7]|5[1-57]|6[134]|9[15-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-7]))\\d{6}","\\d{10}",,,"2123456789"] +,[,,"69\\d{8}","\\d{10}",,,"6912345678"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"90[19]\\d{7}","\\d{10}",,,"9091234567"] +,[,,"8(?:0[16]|12|25)\\d{7}","\\d{10}",,,"8011234567"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,[,,"NA","NA"] +,"GR",30,"00",,,,,,,,[[,"([27]\\d)(\\d{4})(\\d{4})","$1 $2 $3","21|7","",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","2[2-9]1|[689]","",""], +[,"(2\\d{3})(\\d{6})","$1 $2","2[2-9][02-9]","",""]]] +, + "GT": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GT",502,"00",,,,,,,1] +, + "GU": [,[,,"[689]\\d{9}","\\d{7,10}"] +,[,,"671(?:3\\d{2}|47\\d|56\\d|6[3-5]\\d|7(?:3\\d|89)|828)\\d{4}","\\d{7,10}",,,"6713123456"] +,[,,"671(?:3\\d{2}|47\\d|56\\d|6[3-5]\\d|7(?:3\\d|89)|828)\\d{4}","\\d{7,10}",,,"6713123456"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GU",1,"011",,,,,,,1,,,,,"671"] +, + "GW": [,[,,"[3567]\\d{6}","\\d{7}"] +,[,,"3(?:2[0125]|3[1245]|4[12]|5[1-4]|70|9[1-467])\\d{4}","\\d{7}",,,"3201234"] +,[,,"[5-7]\\d{6}","\\d{7}",,,"5012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GW",245,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "GY": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"GY",592,"001","0",,,"0",,,1] +, + "HK": [,[,,"[235-9]\\d{7,11}","\\d{8,11}"] +,[,,"[23]\\d{7}","\\d{8}",,,"21234567"] +,[,,"[5-79]\\d{7}","\\d{8}",,,"51234567"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"900\\d{8}","\\d{11}",,,"90012345678"] +,[,,"NA","NA"] +,[,,"8[1-3]\\d{6}","\\d{8}"] +,[,,"NA","NA"] +,"HK",852,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2","[235-7]|[89](?:0[1-9]|[1-9])","",""], +[,"(800)(\\d{3})(\\d{3})","$1 $2 $3","800","",""], +[,"(900)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","900","",""]]] +, + "HN": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"HN",504,"00","0",,,"0",,,1] +, + "HR": [,[,,"[1-7]\\d{5,8}|[89]\\d{6,11}","\\d{6,12}"] +,[,,"(?:1|6[029])\\d{7}|(?:2[0-3]|3[1-5]|4[02-47-9]|5[1-3])\\d{6}","\\d{6,9}",,,"12345678"] +,[,,"9[12589]\\d{6,10}","\\d{8,12}",,,"912345678"] +,[,,"80[01]\\d{4,7}","\\d{7,10}",,,"8001234567"] +,[,,"6[145]\\d{4,7}","\\d{6,9}",,,"611234"] +,[,,"NA","NA"] +,[,,"7[45]\\d{4,7}","\\d{6,9}",,,"741234567"] +,[,,"NA","NA"] +,"HR",385,"00","0",,,"0",,,,[[,"(1)(\\d{4})(\\d{3})","$1 $2 $3","1","0$1",""], +[,"(6[029])(\\d{4})(\\d{3})","$1 $2 $3","6[029]","0$1",""], +[,"([2-5]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[2-5]","0$1",""], +[,"(9[12589])(\\d{3,4})(\\d{3,4})","$1 $2 $3","9","0$1",""], +[,"(9[12589])(\\d{3,4})(\\d{3})(\\d{3})","$1 $2 $3 $4","9","0$1",""], +[,"(\\d{2})(\\d{2})(\\d{2,3})","$1 $2 $3","6[145]|7","0$1",""], +[,"(\\d{2})(\\d{3,4})(\\d{3})","$1 $2 $3","6[145]|7","0$1",""], +[,"(80[01])(\\d{2})(\\d{2,3})","$1 $2 $3","8","0$1",""], +[,"(80[01])(\\d{3,4})(\\d{3})","$1 $2 $3","8","0$1",""]]] +, + "HT": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"HT",509,"00","0",,,"0",,,1] +, + "HU": [,[,,"\\d{8,9}","\\d{6,9}"] +,[,,"(?:1\\d|2(?:1\\d|[2-9])|3[2-7]|4[24-9]|5[2-79]|6[23689]|7(?:1\\d|[2-9])|8[2-57-9]|9[2-69])\\d{6}","\\d{6,9}",,,"12345678"] +,[,,"(?:[237]0|31)\\d{7}","\\d{9}",,,"201234567"] +,[,,"80\\d{6}","\\d{8}",,,"80123456"] +,[,,"9[01]\\d{6}","\\d{8}",,,"90123456"] +,[,,"40\\d{6}","\\d{8}",,,"40123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"HU",36,"00","06",,,"06",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3","1","($1)",""], +[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[4-689]|[237][2-9]","($1)",""], +[,"([237][01])(\\d{3})(\\d{4})","$1 $2 $3","[237][01]","($1)",""]]] +, + "ID": [,[,,"[1-9]\\d{6,10}","\\d{5,11}"] +,[,,"2[124]\\d{7,8}|(?:2(?:[35][1-4]|6[0-8]|7[1-6]|8\\d|9[1-8])|3(?:1|2[1-578]|3[1-68]|4[1-3]|5[1-8]|6[1-3568]|7[0-46]|8\\d)|4(?:0[1-589]|1[01347-9]|2[0-36-8]|3[0-24-68]|5[1-378]|6[1-5]|7[134]|8[1245])|5(?:1[1-35-9]|2[25-8]|3[1246-9]|4[1-3589]|5[1-46]|6[1-8])|6(?:19?|[25]\\d|3[1-469]|4[1-6])|7(?:1[1-46-9]|2[14-9]|[36]\\d|4[1-8]|5[1-9]|7[0-36-9])|9(?:0[12]|1[0134-8]|2[0-479]|5[125-8]|6[23679]|7[159]|8[01346]))\\d{5,8}","\\d{5,10}",,,"612345678"] +,[,,"8[1-35-9]\\d{7,9}","\\d{9,11}",,,"812345678"] +,[,,"177\\d{6,8}|800\\d{5,7}","\\d{8,11}",,,"8001234567"] +,[,,"809\\d{7}","\\d{10}",,,"8091234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ID",62,"0(?:0[1789]|10(?:00|1[67]))","0",,,"0",,,,[[,"(\\d{2})(\\d{7,8})","$1 $2","2[124]|[36]1","(0$1)",""], +[,"(\\d{3})(\\d{5,7})","$1 $2","[4579]|2[035-9]|[36][02-9]","(0$1)",""], +[,"(8\\d{2})(\\d{3,4})(\\d{3,4})","$1-$2-$3","8[1-35-9]","0$1",""], +[,"(177)(\\d{6,8})","$1 $2","1","0$1",""], +[,"(800)(\\d{5,7})","$1 $2","800","0$1",""], +[,"(809)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4","809","0$1",""]]] +, + "IE": [,[,,"[124-9]\\d{6,9}","\\d{5,10}"] +,[,,"1\\d{7,8}|(?:2[24-9]|4(?:0[24]|7)|5(?:0[45]|8)|6[237-9]|9[3-9])\\d{5}|(?:45|[569]1|818)\\d{6}|(?:4[12469]|5[3679]|6[56]|7[14]|9[04])\\d{7}|21\\d{6,7}|(?:23|4[34]|52|64)\\d{5,7}|48\\d{8}","\\d{5,10}",,,"2212345"] +,[,,"8[35-9]\\d{7}","\\d{9}",,,"850123456"] +,[,,"1800\\d{6}","\\d{10}",,,"1800123456"] +,[,,"15(?:1[2-9]|[2-8]0|59|9[089])\\d{6}","\\d{10}",,,"1520123456"] +,[,,"18[59]0\\d{6}","\\d{10}",,,"1850123456"] +,[,,"700\\d{6}","\\d{9}",,,"700123456"] +,[,,"76\\d{7}","\\d{9}",,,"761234567"] +,"IE",353,"00","0",,,"0",,,,[[,"(1)(\\d{3,4})(\\d{4})","$1 $2 $3","1","(0$1)",""], +[,"(\\d{2})(\\d{5})","$1 $2","2[2-9]|4[347]|5[2-58]|6[2-47-9]|9[3-9]","(0$1)",""], +[,"(\\d{3})(\\d{5})","$1 $2","40[24]|50[45]","(0$1)",""], +[,"(48)(\\d{4})(\\d{4})","$1 $2 $3","48","(0$1)",""], +[,"(818)(\\d{3})(\\d{3})","$1 $2 $3","81","(0$1)",""], +[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[24-69]|7[14]","(0$1)",""], +[,"(8[35-9])(\\d{3})(\\d{4})","$1 $2 $3","8[35-9]","0$1",""], +[,"(76)(\\d{3})(\\d{4})","$1 $2 $3","76","0$1",""], +[,"(700)(\\d{3})(\\d{3})","$1 $2 $3","70","0$1",""], +[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:8[059]0|5)","$1",""]]] +, + "IL": [,[,,"[1-57-9]\\d{6,9}","\\d{7,10}"] +,[,,"(?:[2-489]|7[2-46-8])\\d{7}","\\d{7,9}",,,"21234567"] +,[,,"5[024679]\\d{7}","\\d{9}",,,"501234567"] +,[,,"1(?:80[01]\\d{3}|255)\\d{3}","\\d{7,10}",,,"1800123456"] +,[,,"1(?:212|(?:919|200)\\d{2})\\d{4}","\\d{8,10}",,,"1919123456"] +,[,,"1(?:700|809)\\d{6}","\\d{10}",,,"1700123456"] +,[,,"NA","NA"] +,[,,"77\\d{7}","\\d{9}",,,"771234567"] +,"IL",972,"0(?:0|1[2-48])","0",,,"0",,,,[[,"([2-489])(\\d{3})(\\d{4})","$1-$2-$3","[2-489]","0$1",""], +[,"([57]\\d)(\\d{3})(\\d{4})","$1-$2-$3","[57]","0$1",""], +[,"(1)([7-9]\\d{2})(\\d{3})(\\d{3})","$1-$2-$3-$4","1[7-9]","$1",""], +[,"(1255)(\\d{3})","$1-$2","125","$1",""], +[,"(1200)(\\d{3})(\\d{3})","$1-$2-$3","120","$1",""], +[,"(1212)(\\d{2})(\\d{2})","$1-$2-$3","121","$1",""]]] +, + "IM": [,[,,"[157-9]\\d{6,9}","\\d{6,10}"] +,[,,"1624\\d{6}","\\d{6,10}",,,"1624123456"] +,[,,"7[69]24\\d{6}","\\d{6,10}",,,"7624123456"] +,[,,"80(?:01111|\\d{7,8})|500\\d{6}","\\d{7,10}",,,"8012345678"] +,[,,"(?:9[018]\\d|87[1-3])\\d{7}","\\d{10}",,,"9012345678"] +,[,,"8(?:4[3-5]|70)\\d{7}","\\d{10}",,,"8431234567"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,[,,"56\\d{8}","\\d{10}",,,"5612345678"] +,"IM",44,"00","0"," x",,"0"] +, + "IN": [,[,,"[1-9]\\d{9,10}","\\d{6,11}"] +,[,,"(?:11|2[02]|33|4[04]|79|80)[2-6]\\d{7}|(?:1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[014]|7[1257]|8[01346]|9[14])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91))[2-6]\\d{6}|(?:(?:1(?:2[35-8]|3[346-9]|4[236-9]|5[0235-9]|6[235-9]|7[34689]|8[257-9]|9[0235-9])|2(?:1[134689]|3[24-8]|4[2-8]|5[25689]|6[2-4679]|7[13-79]|8[2-479]|9[235-9])|3(?:01|1[79]|2[1-5]|4[25-8]|5[125689]|6[235-7]|7[157-9]|8[2-467])|4(?:1[14578]|2[5689]|3[2-467]|5[4-7]|6[35]|73|8[2689]|9[2389])|5(?:1[146-9]|2[14-8]|3[1346]|4[14-69]|5[46]|6[146-9]|7[2-4]|8[2-8]|9[246])|6(?:1[1358]|2[2457]|3[2-4]|4[235-7]|5[2-689]|6[24-58]|7[23-689]|8[1-6])|8(?:1[1357-9]|2[235-8]|3[03-57-9]|4[0-24-9]|5\\d|6[2457-9]|7[1-6]|8[1256]|9[2-4]))\\d|7(?:(?:1[013-9]|2[0235-9]|3[2679]|4[1-35689]|5[2-46-9]|[67][02-9]|9\\d)\\d|8(?:2[0-6]|[013-8]\\d)))[2-6]\\d{5}","\\d{6,10}",,,"1123456789"] +,[,,"(?:7(?:39[89]|5(?:50|6[6-8]|79|[89][7-9])|6(?:0[027]|20|3[19]|54|65|7[67]|9[6-9])|7(?:0[89]|3[589]|42|60|9[5-9])|8(?:[03][07-9]|14|2[7-9]|4[25]|6[09]))\\d|9\\d{4}|8(?:0[01589]\\d|1[024]\\d|8(?:[079]\\d|44)|9[057-9]\\d)\\d)\\d{5}","\\d{10}",,,"9123456789"] +,[,,"1(?:800\\d?|600)\\d{6}","\\d{10,11}",,,"1800123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IN",91,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{2})(\\d{6})","$1 $2 $3","7(?:39|5(?:50|[6-9])|[67][02-9]|8[0-6])|8(?:0[01589]|1[024]|8(?:[079]|44)|9[057-9])|9","0$1",""], +[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-6]","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|5[14]|6[14]|7[1257]|8[1346]|9[14]|[68][1-9])","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","5(?:1[25]|22|3[25]|4[28]|5[12]|6[25]|[78]1|9[15])","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","6(?:12|[2345]1|57|6[13]|7[14]|80)","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5(?:1|5[1-9])|[67]1|88)","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)","0$1",""], +[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[2-579]|[68][1-9])|[2-8]","0$1",""], +[,"(1600)(\\d{2})(\\d{4})","$1 $2 $3","1600","$1",""], +[,"(1800)(\\d{2,3})(\\d{4})","$1 $2 $3","1800","$1",""]]] +, + "IO": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IO",246,"00",,,,,,,1] +, + "IQ": [,[,,"[1-7]\\d{7,9}","\\d{6,10}"] +,[,,"1\\d{7}|(?:2[13-5]|3[02367]|4[023]|5[03]|6[026])\\d{6,7}","\\d{6,9}",,,"12345678"] +,[,,"7[5-9]\\d{8}","\\d{10}",,,"7912345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IQ",964,"00","0",,,"0",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3","1","0$1",""], +[,"([2-6]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[2-6]","0$1",""], +[,"(7[5-9]\\d)(\\d{3})(\\d{4})","$1 $2 $3","7","0$1",""]]] +, + "IR": [,[,,"[1-9]\\d{9}","\\d{7,10}"] +,[,,"[1-8]\\d{9}","\\d{7,10}",,,"2123456789"] +,[,,"9(?:1\\d|3[1-8])\\d{7}","\\d{10}",,,"9123456789"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IR",98,"00","0",,,"0",,,,[[,"(21)(\\d{4})(\\d{4})","$1 $2 $3","21","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[13-89]|2[02-9]","0$1",""]]] +, + "IS": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IS",354,"00","0",,,"0",,,1] +, + "IT": [,[,,"[01389]\\d{5,10}","\\d{6,11}"] +,[,,"0\\d{7,10}","\\d{8,11}",,,"0212345678"] +,[,,"3\\d{8,9}","\\d{9,10}",,,"312345678"] +,[,,"80(?:0\\d{6}|3\\d{3})","\\d{6,9}",,,"800123456"] +,[,,"89(?:2\\d{3}|9\\d{6})","\\d{6,9}",,,"899123456"] +,[,,"84[78]\\d{6,7}","\\d{9,10}",,,"8481234567"] +,[,,"178\\d{6,7}","\\d{9,10}",,,"1781234567"] +,[,,"NA","NA"] +,"IT",39,"00",,,,,,,,[[,"(0[26])(\\d{3,4})(\\d{4})","$1 $2 $3","0[26]","",""], +[,"(0[26])(\\d{4})(\\d{5})","$1 $2 $3","0[26]","",""], +[,"(0[26])(\\d{6})","$1 $2","0[26]","",""], +[,"(0\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3","0(?:[13-57-9][0159]|36)","",""], +[,"(0\\d{2})(\\d{5,6})","$1 $2","0(?:[13-57-9][0159]|36)","",""], +[,"(0\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","0[13-57-9]","",""], +[,"(0\\d{3})(\\d{4,6})","$1 $2","0[13-57-9]","",""], +[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[13]|84[78]","",""], +[,"(800)(\\d{3})(\\d{3})","$1 $2 $3","800","",""], +[,"(803)(\\d{3})","$1 $2","803","",""], +[,"(89\\d)(\\d{3,6})","$1 $2","89","",""]]] +, + "JE": [,[,,"[157-9]\\d{6,9}","\\d{6,10}"] +,[,,"1534\\d{6}","\\d{6,10}",,,"1534123456"] +,[,,"7(?:7(?:00|97)|829|937)\\d{6}","\\d{10}",,,"7797123456"] +,[,,"80(?:01111|\\d{7,8})|500\\d{6}","\\d{7,10}",,,"8012345678"] +,[,,"(?:9[018]\\d|87[1-3])\\d{7}","\\d{10}",,,"9012345678"] +,[,,"8(?:4[3-5]|70)\\d{7}","\\d{10}",,,"8431234567"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,[,,"56\\d{8}","\\d{10}",,,"5612345678"] +,"JE",44,"00","0"," x",,"0"] +, + "JM": [,[,,"[89]\\d{9}","\\d{7,10}"] +,[,,"876(?:(?:5[0-26]|6\\d|7[1-6]|9[2-8])\\d{5}|(?:7(?:0[2-689]|8[056]|9[45])|9(?:0[1-8]|1[02378]|9[2-468]))\\d{4})","\\d{7,10}",,,"8765123456"] +,[,,"876(?:(?:21|[348]\\d|5[78]|77)\\d|7(?:0[07]|8[1-47-9]|9[0-36-9])|9(?:[01]9|9[0579]))\\d{4}","\\d{10}",,,"8762101234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"JM",1,"011",,,,,,,,,,,,"876"] +, + "JO": [,[,,"[235-9]\\d{7,8}","\\d{7,9}"] +,[,,"(?:[2356][2-8])\\d{6}","\\d{7,8}",,,"62345678"] +,[,,"7(?:4[5-7]|7[5-79]|8[5-8]|9[05-9])\\d{6}","\\d{9}",,,"790123456"] +,[,,"80\\d{6}","\\d{8}",,,"80012345"] +,[,,"90\\d{6}","\\d{8}",,,"90012345"] +,[,,"(?:8[57]\\d|810)\\d{5}","\\d{8}",,,"85012345"] +,[,,"70\\d{7}","\\d{9}",,,"700123456"] +,[,,"NA","NA"] +,"JO",962,"00","0",,,"0",,,,[[,"([2356])(\\d{3})(\\d{4})","$1 $2 $3","[2356]","(0$1)",""], +[,"(7)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","7[47-9]","0$1",""], +[,"(70\\d)(\\d{6})","$1 $2","70","0$1",""], +[,"([89]\\d{2})(\\d{5})","$1 $2","[89]","0$1",""]]] +, + "JP": [,[,,"\\d{9,10}","\\d{9,10}"] +,[,,"(?:1[1-9][1-9]|9(?:[3-9][1-9]|2\\d)|(?:[36][1-9]|[24578][2-9])\\d)\\d{6}","\\d{9}",,,"312345678"] +,[,,"[7-9]0\\d{8}","\\d{10}",,,"7012345678"] +,[,,"120\\d{6}","\\d{9}",,,"120123456"] +,[,,"990\\d{6}","\\d{9}",,,"990123456"] +,[,,"NA","NA"] +,[,,"60\\d{7}","\\d{9}",,,"601234567"] +,[,,"50\\d{8}","\\d{10}",,,"5012345678"] +,"JP",81,"010","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","(?:12|99)0","0$1",""], +[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","[57-9]0","0$1",""], +[,"(\\d{4})(\\d)(\\d{4})","$1 $2 $3","1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:769|979[2-69])|499[2468]|7468|8(?:3(?:8[78]|96[2457-9])|636[2-57-9]|477|51[24])|9(?:496|802|91[23]|969)","0$1",""], +[,"(\\d{3})(\\d{2})(\\d{4})","$1 $2 $3","1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|6[2-7]|7[2-689]|8[2-7]|9[1-578])|2(?:2[04-9]|3[3-58]|4[0-468]|6[0135-8]|7[0679]|8[024578]|23[23]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:17|4[2-5])|78[2-7]|8(?:3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|7[059][2-8]|3[689]|6[035-7]|7[68]|80|9[3-5])|5(?:3[1-36-9]|9(?:7[49]|[89][2-8])|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-7])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[017-9]|618|797|9(?:4[6-8]|5[2-478]|6[2-589]))|8(?:29(?:20|4[04-9]|65[25]|[36]60)|376[0-59]|6(?:366|55[014-9]|69[02-69]|99[23])|24[4-8]|29[3578]|3(?:[3-6][2-9]|[78][2-5])|6(?:5[467]|9[236-8]|[68][2-8])|4[5-8]|5[2-9]|6[37]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[0246-9]|5[025-79]|6[4-9]|7[27-9]|8[02-7]|[47]3|[57]4|9(?:4[2-69]|3(?:3[02-9]|4[0-24689])|[5-7]))","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","1|2(?:23|5(?:[57]|[68]0|917|999)|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|8(?:[46-9]|3[279]|2(?:[124589]|9[24])|3[79]6|6(?:69|99))|9(?:[235-8]|9331|934)|15[45]","0$1",""], +[,"(\\d{3})(\\d{2})(\\d{4})","$1 $2 $3","2(?:9[14-79]|74|[34]7|[56]9)|82|993","0$1",""], +[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3","[36]|4(?:2[09]|7[01])","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[2479]","0$1",""]]] +, + "KE": [,[,,"\\d{6,10}","\\d{4,10}"] +,[,,"(?:20|4[0-6]|5\\d|6[0-24-9])\\d{4,7}","\\d{4,9}",,,"202012345"] +,[,,"7(?:1[0-6]|2\\d|3[2-8]|5[0-2]|7[023])\\d{6}","\\d{9}",,,"712123456"] +,[,,"8(?:00|88)\\d{6,7}","\\d{9,10}",,,"800123456"] +,[,,"9(?:00|1)\\d{6,7}","\\d{8,10}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KE",254,"000","0",,,"0",,,,[[,"([2-6]\\d)(\\d{4,7})","$1 $2","[2-6]","0$1",""], +[,"(7\\d{2})(\\d{6})","$1 $2","7","0$1",""], +[,"(\\d{3})(\\d{6,7})","$1 $2","8|90","0$1",""], +[,"(91)(\\d{6,7})","$1 $2","91","0$1",""]]] +, + "KG": [,[,,"[356-8]\\d{8}","\\d{5,9}"] +,[,,"(?:3(?:1(?:2\\d|3[1-9]|52|6[1-8])|2(?:22|3[0-479]|6[0-7])|4(?:22|5[6-9]|6[0-4])|5(?:22|3[4-7]|59|6[0-5])|6(?:22|5[35-7]|6[0-3])|7(?:22|3[468]|4[1-8]|59|6\\d|7[5-7])|9(?:22|4[1-7]|6[0-8]))|6(?:09|12|2[2-4])\\d)\\d{5}","\\d{5,9}",,,"312123456"] +,[,,"5[124-7]\\d{7}|7(?:0[05]|7\\d)\\d{6}","\\d{9}",,,"700123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KG",996,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","31[25]|[5-8]","0$1",""], +[,"(\\d{4})(\\d{5})","$1 $2","3(?:1[36]|[2-9])","0$1",""]]] +, + "KH": [,[,,"[1-9]\\d{7,9}","\\d{6,10}"] +,[,,"(?:2[3-6]|3[2-6]|4[2-4]|[5-7][2-5])[2-47-9]\\d{5}","\\d{6,8}",,,"23456789"] +,[,,"(?:(?:1[0-35-9]|9[1-49])[1-9]|85[2-689])\\d{5}","\\d{8}",,,"91234567"] +,[,,"1800(?:1\\d|2[09])\\d{4}","\\d{10}",,,"1800123456"] +,[,,"1900(?:1\\d|2[09])\\d{4}","\\d{10}",,,"1900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KH",855,"00[178]","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1\\d[1-9]|[2-9]","0$1",""], +[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1[89]0","",""]]] +, + "KI": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KI",686,"00","0",,,"0",,,1] +, + "KM": [,[,,"[37]\\d{6}","\\d{7}"] +,[,,"7(?:6[0-37-9]|7[0-57-9])\\d{4}","\\d{7}",,,"7712345"] +,[,,"3[23]\\d{5}","\\d{7}",,,"3212345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KM",269,"00",,,,,,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "KN": [,[,,"[89]\\d{9}","\\d{7,10}"] +,[,,"869(?:2(?:29|36)|4(?:6[5-9]|70))\\d{4}","\\d{7,10}",,,"8692361234"] +,[,,"869(?:5(?:5[6-8]|6[5-7])|66[2-9]|76[2-5])\\d{4}","\\d{10}",,,"8695561234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KN",1,"011",,,,,,,,,,,,"869"] +, + "KP": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KP",850,"00","0",,,"0",,,1] +, + "KR": [,[,,"[1-79]\\d{3,9}|8\\d{8}","\\d{4,10}"] +,[,,"(?:2|[34][1-3]|5[1-5]|6[1-4])(?:1\\d{2,3}|[2-9]\\d{6,7})","\\d{4,10}",,,"22123456"] +,[,,"1[0-25-9]\\d{7,8}","\\d{9,10}",,,"1023456789"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"60[2-9]\\d{6}","\\d{9}",,,"602345678"] +,[,,"NA","NA"] +,[,,"50\\d{8}","\\d{10}",,,"5012345678"] +,[,,"70\\d{8}","\\d{10}",,,"7012345678"] +,"KR",82,"00(?:[124-68]|[37]\\d{2})","0",,,"0(?:8[1-46-8]|85\\d{2})?",,,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5(?:[1-3]|4[56]))|[68]0|[3-9][1-9][2-9]","0$1",""], +[,"(\\d{3})(\\d)(\\d{4})","$1-$2-$3","1312","0$1",""], +[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131[13-9]","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]","0$1",""], +[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30","0$1",""], +[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3","2(?:[26]|3(?:01|1[45]|2[17-9]|39|4|6[67]|7[078]))","0$1",""], +[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3","2(?:3(?:0[02-9]|1[0-36-9]|2[02-6]|3[0-8]|6[0-589]|7[1-69]|[589])|[457-9])","0$1",""], +[,"(\\d)(\\d{3})","$1-$2","21(?:[0-247-9]|3[124]|6[1269])","0$1",""], +[,"(\\d)(\\d{4})","$1-$2","21(?:3[035-9]|6[03-578])","0$1",""], +[,"(\\d{2})(\\d{3})","$1-$2","[3-9][1-9]1(?:[0-247-9]|3[124]|6[1269])","0$1",""], +[,"(\\d{2})(\\d{4})","$1-$2","[3-9][1-9]1(?:3[035-9]|6[03-578])","0$1",""]]] +, + "KW": [,[,,"[12569]\\d{6,7}","\\d{7,8}"] +,[,,"(?:18|2[2-5]\\d)\\d{5}","\\d{7,8}",,,"22345678"] +,[,,"(?:5[05]|6[05-7]|9[0479])\\d{6}","\\d{8}",,,"50012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KW",965,"00","0",,,"0",,,,[[,"(18\\d{2})(\\d{3})","$1 $2","1","0$1",""], +[,"(2[2-5]\\d{2})(\\d{4})","$1 $2","2","0$1",""], +[,"([69]\\d{3})(\\d{4})","$1 $2","[69]","0$1",""], +[,"(5[05]\\d)(\\d{5})","$1 $2","5","0$1",""]]] +, + "KY": [,[,,"[389]\\d{9}","\\d{7,10}"] +,[,,"345(?:2(?:22|44)|444|6(?:23|38|40)|7(?:6[6-9]|77)|8(?:00|1[45]|25|4[89]|88)|9(?:14|4[035-9]))\\d{4}","\\d{7,10}",,,"3452221234"] +,[,,"345(?:32[3-79]|5(?:1[467]|2[5-7]|4[5-9])|9(?:1[679]|2[4-9]|3[89]))\\d{4}","\\d{10}",,,"3453231234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}|345976\\d{4}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KY",1,"011",,,,,,,,,,,,"345"] +, + "KZ": [,[,,"(?:[67]\\d{2}|80[09])\\d{7}","\\d{10}"] +,[,,"7(?:1\\d[2-7]|2(?:[0-689][2-7]|75[279]))\\d{6}","\\d{10}",,,"7123456789"] +,[,,"7(?:(?:(?:1[2-578]|2[13-7])9[01]|2758)\\d{5}|(?:0[0-257]|6[02-4]|7[57])\\d{7})|6\\{9}","\\d{10}",,,"7129012345"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"809\\d{7}","\\d{10}",,,"8091234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KZ",7,"8~10","8",,,"8"] +, + "LA": [,[,,"[2-57]\\d{7,8}","\\d{6,9}"] +,[,,"(?:[2-57]1|54)\\d{6}","\\d{6,8}",,,"21212862"] +,[,,"20[2357-9]\\d{6}","\\d{9}",,,"202345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LA",856,"00","0",,,"0",,,,[[,"(20)([2357-9])(\\d{3})(\\d{3})","$1 $2 $3 $4","20","0$1",""], +[,"([2-57]\\d)(\\d{3})(\\d{3})","$1 $2 $3","21|[3-57]","0$1",""]]] +, + "LB": [,[,,"[13-9]\\d{6,7}","\\d{7,8}"] +,[,,"(?:[14-6]\\d|[7-9][2-9])\\d{5}","\\d{7}",,,"1123456"] +,[,,"(3\\d|7(?:0\\d|1[167]))\\d{5}","\\d{7,8}",,,"71123456"] +,[,,"NA","NA"] +,[,,"8[01]\\d{6}","\\d{8}",,,"80123456"] +,[,,"9[01]\\d{6}","\\d{8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LB",961,"00","0",,,"0",,,,[[,"([13-6])(\\d{3})(\\d{3})","$1 $2 $3","[13-6]","0$1",""], +[,"([7-9][01])(\\d{3})(\\d{3})","$1 $2 $3","[7-9][01]","0$1",""], +[,"([7-9][2-9])(\\d{2})(\\d{3})","$1 $2 $3","[7-9][2-9]","0$1",""]]] +, + "LC": [,[,,"[789]\\d{9}","\\d{7,10}"] +,[,,"758(?:234|4(?:5[0-9]|6[2-9]|8[0-2])|638|758)\\d{4}","\\d{7,10}",,,"7582345678"] +,[,,"758(?:28[4-7]|384|4(?:6[01]|8[4-9])|5(?:1[89]|20|84)|7(?:1[2-9]|2[0-4]))\\d{4}","\\d{10}",,,"7582845678"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LC",1,"011",,,,,,,,,,,,"758"] +, + "LI": [,[,,"(?:66|80|90)\\d{7}|[237-9]\\d{6}","\\d{7,9}"] +,[,,"(?:2(?:17|3\\d|6[02-58]|96)|3(?:02|7[01357]|8[048]|9[0269])|870)\\d{4}","\\d{7}",,,"2345678"] +,[,,"66(?:[0178][0-4]|2[025-9]|[36]\\d|4[129]|5[45]|9[019])\\d{5}|7(?:4[2-59]|56|[6-9]\\d)\\d{4}","\\d{7,9}",,,"661234567"] +,[,,"80(?:0(?:07|2[238]|79|\\d{4})|9\\d{2})\\d{2}","\\d{7,9}",,,"8002222"] +,[,,"NA","NA"] +,[,,"90(?:0(?:2[278]|79|\\d{4})|1(?:23|\\d{4})|6(?:66|\\d{4}))\\d{2}","\\d{7,9}",,,"9002222"] +,[,,"701\\d{4}","\\d{7}",,,"7011234"] +,[,,"NA","NA"] +,"LI",423,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3","[23]|7[4-9]|87","",""], +[,"(6\\d)(\\d{3})(\\d{3})","$1 $2 $3","6","",""], +[,"([7-9]0\\d)(\\d{2})(\\d{2})","$1 $2 $3","[7-9]0","",""], +[,"([89]0\\d)(\\d{2})(\\d{2})(\\d{2})","0$1 $2 $3 $4","[89]0","",""]]] +, + "LK": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LK",94,"00","0",,,"0",,,1] +, + "LR": [,[,,"(?:[27]\\d|[4-6])\\d{6}","\\d{7,8}"] +,[,,"2\\d{7}","\\d{8}",,,"21234567"] +,[,,"(?:4[67]|5\\d|7\\d{2}|6[4-8])\\d{5}","\\d{7,8}",,,"4612345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LR",231,"00","0",,,"0",,,,[[,"([27]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[27]","0$1",""], +[,"([4-6])(\\d{3})(\\d{3})","$1 $2 $3","[4-6]","0$1",""]]] +, + "LS": [,[,,"[2568]\\d{7}","\\d{8}"] +,[,,"2\\d{7}","\\d{8}",,,"22123456"] +,[,,"[56]\\d{7}","\\d{8}",,,"50123456"] +,[,,"800[256]\\d{4}","\\d{8}",,,"80021234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LS",266,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",,"",""]]] +, + "LT": [,[,,"[3-9]\\d{7}","\\d{8}"] +,[,,"(?:3[1478]|4[124-6]|52)\\d{6}","\\d{8}",,,"31234567"] +,[,,"6\\d{7}","\\d{8}",,,"61234567"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"90[0239]\\d{5}","\\d{8}",,,"90012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LT",370,"00","8",,,"8",,,,[[,"([34]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","37|4(?:1|5[45]|6[2-4])","8 $1",""], +[,"([3-689]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","3[148]|4(?:[24]|6[09])|5(?:[0189]|28)|[689]","8 $1",""], +[,"(5)(2[0-79]\\d)(\\d{4})","$1 $2 $3","52[0-79]","8 $1",""]]] +, + "LU": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LU",352,"00",,,,,,,1] +, + "LV": [,[,,"[2689]\\d{7}","\\d{8}"] +,[,,"6\\d{7}","\\d{8}",,,"61234567"] +,[,,"2\\d{7}","\\d{8}",,,"21234567"] +,[,,"80\\d{6}","\\d{8}",,,"80123456"] +,[,,"90\\d{6}","\\d{8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LV",371,"00",,,,,,,,[[,"([2689]\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "LY": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"LY",218,"00","0",,,"0",,,1] +, + "MA": [,[,,"[5689]\\d{8}","\\d{9}"] +,[,,"5(?:2(?:[015-7]\\d{2}|(?:[28][2-9]|3[2-7]|4[2-8])\\d|9(?:0\\d|[89]0))|3(?:[0-4]\\d{2}|(?:[57][2-9]|6[2-8]|9[3-9])\\d|8(?:0\\d|[89]0)))\\d{4}","\\d{9}",,,"520123456"] +,[,,"6(?:00|33|[15-7]\\d|4[0-8]|99)\\d{6}","\\d{9}",,,"650123456"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"89\\d{7}","\\d{9}",,,"891234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MA",212,"00","0",,,"0",,,,[[,"([56]\\d{2})(\\d{6})","$1-$2","5(?:2[015-7]|3[0-4])|6","0$1",""], +[,"([58]\\d{3})(\\d{5})","$1-$2","5(?:2(?:[2-48]|90)|3(?:[5-79]|80))|892","0$1",""], +[,"(5\\d{4})(\\d{4})","$1-$2","5(?:29[89]|38[89])","0$1",""], +[,"(8[09])(\\d{7})","$1-$2","8(?:0|9[013-9])","0$1",""]]] +, + "MC": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MC",377,"00","0",,,"0",,,1] +, + "MD": [,[,,"[256-9]\\d{7}","\\d{8}"] +,[,,"(?:2(?:1[0569]|2\\d|3[015-7]|4[1-46-9]|5[0-24689]|6[2-589]|7[1-37]|9[1347-9])|5(?:33|5[257]))\\d{5}","\\d{5,8}",,,"22212345"] +,[,,"(?:6(?:50|7[12]|[89]\\d)|7(?:80|9\\d))\\d{5}","\\d{8}",,,"65012345"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"900\\d{5}","\\d{8}",,,"90012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MD",373,"00","0",,,"0",,,,[[,"(22)(\\d{3})(\\d{3})","$1 $2 $3","22","0$1",""], +[,"([25-7]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","2[13-79]|[5-7]","0$1",""], +[,"([89]00)(\\d{5})","$1 $2","[89]","0$1",""]]] +, + "ME": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ME",382,"99","0",,,"0",,,1] +, + "MG": [,[,,"[23]\\d{8}","\\d{7,9}"] +,[,,"2(?:0(?:(?:2\\d|4[47]|5[3467]|6[279]|8[268]|9[245])\\d|7(?:2[29]|[35]\\d))|210\\d)\\d{4}","\\d{7,9}",,,"202123456"] +,[,,"3[02-4]\\d{7}","\\d{9}",,,"301234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MG",261,"00","0",,,"0",,,,[[,"([23]\\d)(\\d{2})(\\d{3})(\\d{2})","$1 $2 $3 $4",,"0$1",""]]] +, + "MF": [,[,,"[56]\\d{8}","\\d{9}"] +,[,,"590(?:10|2[79]|5[128]|[78]7)\\d{4}","\\d{9}",,,"590271234"] +,[,,"690(?:10|2[27]|66|77|8[78])\\d{4}","\\d{9}",,,"690221234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MF",590,"00","0",,,"0"] +, + "MH": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MH",692,"011","1",,,"1",,,1] +, + "MK": [,[,,"[2-578]\\d{7}","\\d{8}"] +,[,,"(?:2\\d|3[1-4]|4[2-8])\\d{6}","\\d{6,8}",,,"22212345"] +,[,,"7\\d{7}","\\d{8}",,,"72345678"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"5[02-9]\\d{6}","\\d{8}",,,"50012345"] +,[,,"8(?:0[1-9]|[1-9]\\d)\\d{5}","\\d{8}",,,"80123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MK",389,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3","2","0$1",""], +[,"([347]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[347]","0$1",""], +[,"([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4","[58]","0$1",""]]] +, + "ML": [,[,,"[246-8]\\d{7}","\\d{8}"] +,[,,"(?:2(?:0(?:2[0-589]|7[027-9])|1(?:2[5-7]|[3-689]\\d))|442\\d)\\d{4}","\\d{8}",,,"20212345"] +,[,,"(?:6(?:[569]\\d)|7(?:[08][1-9]|[3579][0-4]|4[014-7]|6\\d))\\d{5}","\\d{8}",,,"65012345"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ML",223,"00","0",,,"0",,,,[[,"([246-8]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "MM": [,[,,"[124-8]\\d{5,7}|9\\d{7,8}","\\d{5,9}"] +,[,,"(?:1\\d|2|4[2-6]|5[2-9]|6\\d|7[0-5]|8[1-6])\\d{5}|1333\\d{4}","\\d{5,8}",,,"1234567"] +,[,,"9(?:[25689]\\d|444)\\d{5}","\\d{8,9}",,,"92123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MM",95,"00",,,,,,,,[[,"(1)(\\d{3})(\\d{3})","$1 $2 $3","1","",""], +[,"(1)(3)(33\\d)(\\d{3})","$1 $2 $3 $4","13","",""], +[,"(2)(\\d{2})(\\d{3})","$1 $2 $3","2","",""], +[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","[4-8]","",""], +[,"(9444)(\\d{5})","$1 $2","94","",""], +[,"(9)([25689]\\d{2})(\\d{4})","$1 $2 $3","9[25689]","",""]]] +, + "MN": [,[,,"[127-9]\\d{7}","\\d{8}"] +,[,,"(?:[12](?:1\\d|2[1-37]|3[2-8]|4[2-68]|5[1-4689])|70)\\d{6}","\\d{8}",,,"70123456"] +,[,,"(?:88|9[1569])\\d{6}","\\d{8}",,,"88123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MN",976,"001","0",,,"0",,,,[[,"([127-9]\\d)(\\d{2})(\\d{4})","$1 $2 $3","[12]1|[7-9]","0$1",""], +[,"([12]2\\d)(\\d{5})","$1 $2","[12]2[1-3]","0$1",""], +[,"([12]\\d{3})(\\d{4})","$1 $2","[12](?:27|[3-5]\\d)2","0$1",""], +[,"([12]\\d{4})(\\d{3})","$1 $2","[12](?:27|[3-5]\\d)[4-9]","0$1",""]]] +, + "MO": [,[,,"[268]\\d{7}","\\d{8}"] +,[,,"(?:28[2-57-9]|8[2-57-9]\\d)\\d{5}","\\d{8}",,,"28212345"] +,[,,"6[26]\\d{6}","\\d{8}",,,"66123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MO",853,"00",,,,,,,,[[,"([268]\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "MP": [,[,,"[689]\\d{9}","\\d{7,10}"] +,[,,"670(?:2(?:3[3-5]|88|56)|32[23]|4[38]3|532|6(?:64|70|8\\d))\\d{4}","\\d{7,10}",,,"6702345678"] +,[,,"670(?:2(?:3[3-5]|88|56)|32[23]|4[38]3|532|6(?:64|70|8\\d))\\d{4}","\\d{7,10}",,,"6702345678"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MP",1,"011",,,,,,,1,,,,,"670"] +, + "MQ": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MQ",596,"00","0",,,"0",,,1] +, + "MR": [,[,,"[2-7]\\d{6}","\\d{7}"] +,[,,"5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\\d{4}","\\d{7}",,,"5131234"] +,[,,"(?:[23][0-4]|4[3-5]|6\\d|7[0-7])\\d{5}","\\d{7}",,,"3123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MR",222,"00",,,,,,,,[[,"([2-7]\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]]] +, + "MS": [,[,,"[689]\\d{9}","\\d{7,10}"] +,[,,"664491\\d{4}","\\d{7,10}",,,"6644912345"] +,[,,"664492\\d{4}","\\d{10}",,,"6644923456"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002123456"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MS",1,"011",,,,,,,,,,,,"664"] +, + "MT": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MT",356,"00","21",,,"21",,,1] +, + "MU": [,[,,"[2-9]\\d{6}","\\d{7}"] +,[,,"(?:2(?:[034789]\\d|1[0-8]|2[0-79])|4(?:[013-8]\\d|2[4-7])|[56]\\d{2}|8(?:14|3[129]))\\d{4}","\\d{7}",,,"2012345"] +,[,,"(?:25\\d|4(?:2[12389]|9\\d)|7\\d{2}|87[15-7]|9[1-8]\\d)\\d{4}","\\d{7}",,,"2512345"] +,[,,"80[012]\\d{4}","\\d{7}",,,"8001234"] +,[,,"30\\d{5}","\\d{7}",,,"3012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MU",230,"020",,,,,,,,[[,"([2-9]\\d{2})(\\d{4})","$1 $2",,"",""]]] +, + "MV": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MV",960,"020","0",,,"0",,,1] +, + "MW": [,[,,"(?:[13-5]|[27]\\d{2}|[89](?:\\d{2})?)\\d{6}","\\d{7,9}"] +,[,,"(?:1[2-9]|21\\d{2})\\d{5}","\\d{7,9}",,,"1234567"] +,[,,"(?:[3-5]|77|8(?:8\\d)?|9(?:9\\d)?)\\d{6}","\\d{7,9}",,,"991234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MW",265,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3","[13-5]","0$1",""], +[,"(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","2","0$1",""], +[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3","7","0$1",""], +[,"(\\d)(\\d{3,4})(\\d{3,4})","$1 $2 $3","[89]","0$1",""]]] +, + "MX": [,[,,"[1-9]\\d{9,10}","\\d{7,11}"] +,[,,"(?:33|55|81)\\d{8}|(?:2(?:2[2-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-58]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[234][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7}","\\d{7,10}",,,"2221234567"] +,[,,"1(?:(?:33|55|81)\\d{8}|(?:2(?:2[2-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-58]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[2-4][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7})","\\d{11}",,,"12221234567"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"900\\d{7}","\\d{10}",,,"9001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MX",52,"0[09]","01",,,"0[12]|04[45](\\d{10})","1$1",,,[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3","33|55|81","01 $1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[2467]|3[12457-9]|5[89]|8[2-9]|9[1-35-9]","01 $1",""], +[,"1([358]\\d)(\\d{4})(\\d{4})","045 $1 $2 $3","1(?:33|55|81)","$1",""], +[,"1(\\d{3})(\\d{3})(\\d{4})","045 $1 $2 $3","1(?:[2467]|3[12457-9]|5[89]|8[2-9]|9[1-35-9])","$1",""], +[,"([89]00)(\\d{3})(\\d{4})","$1 $2 $3","[89]0","01 $1",""]] +,[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3","33|55|81",,""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[2467]|3[12457-9]|5[89]|8[2-9]|9[1-35-9]",,""], +[,"(1)([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3 $4","1(?:33|55|81)",,""], +[,"(1)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3 $4","1(?:[2467]|3[12457-9]|5[89]|8[2-9]|9[1-35-9])",,""], +[,"([89]00)(\\d{3})(\\d{4})","$1 $2 $3","[89]0",,""]]] +, + "MY": [,[,,"[13-9]\\d{7,9}","\\d{6,10}"] +,[,,"(?:3\\d{2}|[4-79]\\d|8[2-9])\\d{6}","\\d{6,9}",,,"312345678"] +,[,,"1[0-46-9]\\d{7}","\\d{9}",,,"123456789"] +,[,,"1[38]00\\d{6}","\\d{10}",,,"1300123456"] +,[,,"1600\\d{6}","\\d{10}",,,"1600123456"] +,[,,"NA","NA"] +,[,,"1700\\d{6}","\\d{10}",,,"1700123456"] +,[,,"154\\d{7}","\\d{10}",,,"1541234567"] +,"MY",60,"00","0",,,"0",,,,[[,"([4-79])(\\d{3})(\\d{4})","$1-$2 $3","[4-79]","0$1",""], +[,"(3)(\\d{4})(\\d{4})","$1-$2 $3","3","0$1",""], +[,"(8[2-9])(\\d{3})(\\d{3})","$1-$2 $3","8","0$1",""], +[,"(1\\d)(\\d{3})(\\d{4})","$1-$2 $3","1[0-46-9][1-9]","0$1",""], +[,"(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4","1[36-8]0","",""], +[,"(154)(\\d{3})(\\d{4})","$1-$2 $3","15","0$1",""]]] +, + "MZ": [,[,,"[28]\\d{7,8}","\\d{8,9}"] +,[,,"2(?:[1346]\\d|5[0-2]|[78][12]|93)\\d{5}","\\d{8}",,,"21123456"] +,[,,"8[24]\\d{7}","\\d{9}",,,"821234567"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MZ",258,"00",,,,,,,,[[,"(2\\d)(\\d{3})(\\d{3})","$1 $2 $3","2","",""], +[,"(8[24])(\\d{3})(\\d{4})","$1 $2 $3","8[24]","",""], +[,"(80\\d)(\\d{3})(\\d{3})","$1 $2 $3","80","",""]]] +, + "NA": [,[,,"[68]\\d{5,9}","\\d{4,10}"] +,[,,"6(?:1(?:[136]|2\\d?)\\d|2(?:[25]\\d?|[134678])\\d|3(?:2\\d{0,3}|4\\d{1,2}|[135-8]\\d?)|4(?:[13-8]\\d|2\\d{1,2})|(?:5(?:[16-7]\\d|[3-58]\\d?|2\\d{1,2}))|6\\d{0,4}|7\\d{0,3})\\d{4}","\\d{4,10}",,,"612012345"] +,[,,"8(?:1(?:1[0-24]|[2-4]\\d|50|6[0-2])|5\\d{2})\\d{5}","\\d{9}",,,"811012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"88\\d{6}","\\d{8}",,,"88123456"] +,"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3","8[15]","0$1",""], +[,"(632532)(\\d{2,4})","$1 $2","6325","0$1",""], +[,"(6\\d)(\\d{2,3})(\\d{4})","$1 $2 $3","6(?:1|[245][1-7]|3[125-7]|6[1256]|7[1236])","0$1",""], +[,"(6\\d)(\\d{4,5})","$1 $2","6(?:3[12567]|5[3-5]|6[1256]|7[1236])","0$1",""], +[,"(6\\d{2})(\\d{4,6})","$1 $2","6[2356]8","0$1",""], +[,"(6\\d{3})(\\d{4,5})","$1 $2","6(?:342|6[34]|751)","0$1",""], +[,"(88)(\\d{3})(\\d{3})","$1 $2 $3","88","0$1",""]]] +, + "NC": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NC",687,"00","0",,,"0",,,1] +, + "NE": [,[,,"[029]\\d{7}","\\d{8}"] +,[,,"2(?:0(?:20|3[1-7]|4[134]|5[14]|6[14578]|7[1-578])|1(?:4[145]|5[14]|6[14-68]|7[169]|88))\\d{4}","\\d{8}",,,"20201234"] +,[,,"9[03467]\\d{6}","\\d{8}",,,"93123456"] +,[,,"08\\d{6}","\\d{8}",,,"08123456"] +,[,,"09\\d{6}","\\d{8}",,,"09123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NE",227,"00",,,,,,,,[[,"([029]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[29]|09","",""], +[,"(08)(\\d{3})(\\d{3})","$1 $2 $3","08","",""]]] +, + "NF": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NF",672,"00",,,,,,,1] +, + "NG": [,[,,"[1-69]\\d{5,8}|[78]\\d{5,13}","\\d{5,14}"] +,[,,"[12]\\d{6,7}|9\\d{7}|(?:4[023568]|5[02368]|6[02-469]|7[569]|8[2-9])\\d{6}|(?:4[47]|5[14579]|6[1578]|7[0-357])\\d{5,6}|(?:78|41)\\d{5}","\\d{5,9}",,,"12345678"] +,[,,"(?:70[3-9]|8(?:0[2-9]|1[23]))\\d{7}|(?:702[1-9]|819[01])\\d{6}","\\d{10}",,,"8021234567"] +,[,,"800\\d{7,11}","\\d{10,14}",,,"80017591759"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"700\\d{7,11}","\\d{10,14}",,,"7001234567"] +,[,,"NA","NA"] +,"NG",234,"009","0",,,"0",,,,[[,"([12])(\\d{3})(\\d{3,4})","$1 $2 $3","[12]","0$1",""], +[,"(9)(\\d{3})(\\d{4})","$1 $2 $3","9","0$1",""], +[,"([3-8]\\d)(\\d{3})(\\d{2,3})","$1 $2 $3","[3-6]|7(?:[1-79]|0[1-9])|8[2-9]","0$1",""], +[,"([78]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","70[3-9]|8(?:0[1-9]|1[23])","0$1",""], +[,"([78]\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","702|819","0$1",""], +[,"([78]00)(\\d{3})(\\d{3,4})","$1 $2 $3","[78]00","0$1",""], +[,"([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3","[78]00","0$1",""], +[,"([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3","[78]00","0$1",""], +[,"(78)(\\d{2})(\\d{3})","$1 $2 $3","78","0$1",""]]] +, + "NI": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NI",505,"00","0",,,"0",,,1] +, + "NL": [,[,,"[1-9]\\d{6,9}","\\d{7,10}"] +,[,,"(?:1[0135-8]|2[02-69]|3[0-68]|4[0135-9]|[57]\\d|8[478])\\d{7}","\\d{9}",,,"101234567"] +,[,,"6[1-58]\\d{7}","\\d{9}",,,"612345678"] +,[,,"800\\d{4,7}","\\d{7,10}",,,"8001234"] +,[,,"90[069]\\d{4,7}","\\d{7,10}",,,"9001234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"85\\d{7}","\\d{9}"] +,"NL",31,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7|8[458]","0$1",""], +[,"([1-5]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1[16-8]|2[259]|3[124]|4[17-9]|5[124679]","0$1",""], +[,"(6)(\\d{8})","$1 $2","6","0$1",""], +[,"([89]0\\d)(\\d{4,7})","$1 $2","80|9","0$1",""]]] +, + "NO": [,[,,"0\\d{4}|[2-9]\\d{7}","\\d{5}(?:\\d{3})?"] +,[,,"0\\d{4}|(?:2[1-4]|3[1-3578]|5[1-35-7]|6[1-4679]|7\\d)\\d{6}|81(?:0(?:0[7-9]|1\\d)|5\\d{2})\\d{3}","\\d{5}(?:\\d{3})?",,,"21234567"] +,[,,"(?:4[015-8]|9\\d)\\d{6}","\\d{8}",,,"41234567"] +,[,,"80[01]\\d{5}","\\d{8}",,,"80012345"] +,[,,"82[09]\\d{5}","\\d{8}",,,"82012345"] +,[,,"810(?:0[0-6]|[2-8]\\d)\\d{3}","\\d{8}",,,"81021234"] +,[,,"880\\d{5}","\\d{8}",,,"88012345"] +,[,,"NA","NA"] +,"NO",47,"00",,,,,,,,[[,"([489]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","[489]","",""], +[,"([235-7]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[235-7]","",""]]] +, + "NP": [,[,,"[1-8]\\d{5,7}|98[45]\\d{7}","\\d{6,10}"] +,[,,"(?:1[014-6]|2[13-79]|3[135-8]|4[146-9]|5[135-7]|6[13-9]|7[15-9]|8[1-4679]|9[1-79])\\d{6}","\\d{6,8}",,,"14567890"] +,[,,"98[45]\\d{7}","\\d{10}",,,"9841234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NP",977,"00","0",,,"0",,,,[[,"(1)([4-6]\\d{3})(\\d{3})","$1 $2 $3","1[4-6]","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1[01]|[2-8]|9[1-79]","0$1",""], +[,"(98[45])(\\d{3})(\\d{4})","$1 $2 $3","98","0$1",""]]] +, + "NR": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NR",674,"00","0",,,"0",,,1] +, + "NU": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NU",683,"00","0",,,"0",,,1] +, + "NZ": [,[,,"[2-9]\\d{7,9}","\\d{7,10}"] +,[,,"(?:3[2-79]|[479][2-689]|6[235-9])\\d{6}|24099\\d{3}","\\d{7,8}",,,"32345678"] +,[,,"2(?:[027]\\d{7}|9\\d{6,7}|1(?:0\\d{5,7}|[12]\\d{5,6}|[3-9]\\d{5})|4[1-9]\\d{6}|8\\d{7,8})","\\d{8,10}",,,"211234567"] +,[,,"(?:800|508)\\d{6,7}","\\d{9,10}",,,"800123456"] +,[,,"900\\d{6,7}","\\d{9,10}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NZ",64,"00","0",,,"0",,,,[[,"([34679])(\\d{3})(\\d{4})","$1-$2 $3","[3467]|9[1-9]","0$1",""], +[,"(21)(\\d{4})(\\d{3,4})","$1 $2 $3","21","0$1",""], +[,"([2589]\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","2[0247-9]|5|[89]00","0$1",""], +[,"(2[019])(\\d{3})(\\d{3})","$1 $2 $3","2[019]","0$1",""], +[,"(24099)(\\d{3})","$1 $2","24099","0$1",""]]] +, + "OM": [,[,,"(?:2[3-6]|5|9[2-9])\\d{6}|800\\d{5,6}","\\d{7,9}"] +,[,,"2[3-6]\\d{6}","\\d{8}",,,"23123456"] +,[,,"9[2-9]\\d{6}","\\d{8}",,,"92123456"] +,[,,"8007\\d{4,5}|500\\d{4}","\\d{7,9}",,,"80071234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"OM",968,"00",,,,,,,,[[,"(2\\d)(\\d{6})","$1 $2","2","",""], +[,"(9\\d{3})(\\d{4})","$1 $2","9","",""], +[,"(800)(7\\d{4,5})","$1 $2","8","",""], +[,"(500)(\\d{4})","$1 $2","5","",""]]] +, + "PA": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PA",507,"00","0",,,"0",,,1] +, + "PE": [,[,,"[146-8]\\d{7,10}|5\\d{7}(?:\\d{3})?","\\d{7,11}"] +,[,,"(?:1\\d{2}|4[1-4]|5[1-46]|6[1-7]|7[2-46]|8[2-4])\\d{6}","\\d{7,9}",,,"112345678"] +,[,,"(?:1|4[1-4]|5[1-46]|6[1-7]|7[2-46]|8[2-4])9\\d{8}","\\d{10,11}",,,"54951234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PE",51,"00","0"," Anexo ",,"0",,,,[[,"(1)(9\\d{2})(\\d{6})","$1 $2 $3","19","($1)",""], +[,"(1)(\\d{8})","$1 $2","1[0-8]","($1)",""], +[,"([4-8]\\d)(\\d{6})","$1 $2","[4-8]\\d[0-8]","($1)",""], +[,"([4-8]\\d)(9\\d{2})(\\d{6})","$1 $2 $3","[4-8]\\d9","($1)",""]]] +, + "PF": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PF",689,"00",,,,,,,1] +, + "PG": [,[,,"[1-9]\\d{6,7}","\\d{7,8}"] +,[,,"(?:3\\d{2}|4[257]\\d|5[34]\\d|6[24]9|85[02-46-9]|9[78]\\d)\\d{4}","\\d{7}",,,"3123456"] +,[,,"(?:68|7(?:[126]\\d|3[34689]))\\d{5}","\\d{7,8}",,,"6812345"] +,[,,"180\\d{4}","\\d{7}",,,"1801234"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"275\\d{4}","\\d{7}",,,"2751234"] +,"PG",675,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2","[1-689]","",""], +[,"(7[1-36]\\d)(\\d{2})(\\d{3})","$1 $2 $3","7[1-36]","",""]]] +, + "PH": [,[,,"[2-9]\\d{7,9}|1800\\d{7,9}","\\d{7,13}"] +,[,,"(?:2|3[2-68]|4[2-9]|5[2-6]|6[2-58]|7[24578]|8[2-8])\\d{7}","\\d{7,9}",,,"21234567"] +,[,,"9(?:0[5-9]|1[025-9]|2[0-36-9]|3[0235-9]|7[349]|[89]9)\\d{7}","\\d{10}",,,"9051234567"] +,[,,"1800\\d{7,9}","\\d{11,13}",,,"180012345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PH",63,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3","2","(0$1)",""], +[,"(\\d{4})(\\d{5})","$1 $2","3(?:230|397|461)|4(?:2(?:35|[46]4|51)|396|4(?:22|63)|59[347]|76[15])|5(?:221|446)|642[23]|8(?:622|8(?:[24]2|5[13]))","(0$1)",""], +[,"(\\d{5})(\\d{4})","$1 $2","3469|4(?:279|9(?:30|56))|8834","(0$1)",""], +[,"([3-8]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[3-8]","(0$1)",""], +[,"(9\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","9","0$1",""], +[,"(1800)(\\d{3})(\\d{4})","$1 $2 $3","1","",""], +[,"(1800)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4","1","",""]]] +, + "PK": [,[,,"[2-9]\\d{7,9}","\\d{7,10}"] +,[,,"(?:21|42)\\d{8}|(?:2(?:[25]|3[2358]|4[2-4]|9[78])|4(?:[0146-9]|5[3479])|5(?:[1-35-8]|4[2-467])|6(?:[1-8]|0[468])|7(?:[14]|2[236])|8(?:[16]|2[2-689]|3[23578]|4[3478]|5[2356])|9(?:1|2[2-8]|3[27-9]|4[2-6]|6[3569]|9[25-8]))\\d{7}","\\d{7,10}",,,"2112345678"] +,[,,"3[0-6]\\d{8}","\\d{10}",,,"3012345678"] +,[,,"800\\d{5}","\\d{8}",,,"80012345"] +,[,,"900\\d{5}","\\d{8}",,,"90012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PK",92,"00","0",,,"0",,,,[[,"([24]\\d)(\\d{4})(\\d{4})","$1 $2 $3","21|42","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","2[25]|4[0146-9]|5[1-35-8]|6[1-8]|7[14]|8[16]|91","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","2[349]|3|45|54|60|72|8[2-5]|9[2-9]","0$1",""], +[,"([89]00)(\\d{3})(\\d{2})","$1 $2 $3","89","0$1",""]]] +, + "PL": [,[,,"[1-9]\\d{8}","\\d{9}"] +,[,,"(?:1[2-8]|2[2-59]|3[2-4]|4[1-468]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145])\\d{7}","\\d{9}",,,"123456789"] +,[,,"(?:5[013]|6[069]|7[289]|88)\\d{7}","\\d{9}",,,"512345678"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"70\\d{7}","\\d{9}",,,"701234567"] +,[,,"801\\d{6}","\\d{9}",,,"801234567"] +,[,,"NA","NA"] +,[,,"39\\d{7}","\\d{9}",,,"391234567"] +,"PL",48,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[124]|3[2-4]|5[24-689]|6[1-3578]|7[014-7]|8[1-79]|9[145]","",""], +[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","39|5[013]|6[069]|7[289]|8[08]","",""]]] +, + "PM": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PM",508,"00","0",,,"0",,,1] +, + "PR": [,[,,"[789]\\d{9}","\\d{7,10}"] +,[,,"(?:787|939)[2-9]\\d{6}","\\d{7,10}",,,"7872345678"] +,[,,"(?:787|939)[2-9]\\d{6}","\\d{7,10}",,,"7872345678"] +,[,,"8(00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PR",1,"011",,,,,,,1,,,,,"787|939"] +, + "PS": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PS",970,"00","0",,,"0",,,1] +, + "PT": [,[,,"[2-46-9]\\d{8}","\\d{9}"] +,[,,"2(?:[12]\\d|[35][1-689]|4[1-59]|6[1-35689]|7[1-9]|8[1-69]|9[1256])\\d{6}","\\d{9}",,,"212345678"] +,[,,"9(?:[136]\\d{2}|2[25-79]\\d|4(?:80|9\\d))\\d{5}","\\d{9}",,,"912345678"] +,[,,"4\\d{8}|80[02]\\d{6}","\\d{9}",,,"800123456"] +,[,,"71\\d{7}","\\d{9}",,,"712345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"30\\d{7}","\\d{9}",,,"301234567"] +,"PT",351,"00",,,,,,,,[[,"([2-46-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "PW": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PW",680,"011",,,,,,,1] +, + "PY": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PY",595,"002","0",,,"0",,,1] +, + "QA": [,[,,"[3-8]\\d{6}","\\d{7}"] +,[,,"4\\d{6}","\\d{7}",,,"4123456"] +,[,,"[35-7]\\d{6}","\\d{7}",,,"3123456"] +,[,,"80\\d{5}","\\d{7}",,,"8012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"QA",974,"00",,,,,,,,[[,"([3-8]\\d{2})(\\d{4})","$1 $2",,"",""]]] +, + "RE": [,[,,"[268]\\d{8}","\\d{9}"] +,[,,"262\\d{6}","\\d{9}",,,"262161234"] +,[,,"6(?:9[23]|47)\\d{6}","\\d{9}",,,"692123456"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"8(?:1[01]|2[0156]|84|9[0-37-9])\\d{6}","\\d{9}",,,"810123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"RE",262,"00","0",,,"0",,,,[[,"([268]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1",""]] +,,,1,"262|6[49]|8"] +, + "RO": [,[,,"[237-9]\\d{8}","\\d{9}"] +,[,,"[23][13-6]\\d{7}","\\d{9}",,,"211234567"] +,[,,"7[1-8]\\d{7}","\\d{9}",,,"712345678"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"90[036]\\d{6}","\\d{9}",,,"900123456"] +,[,,"801\\d{6}","\\d{9}",,,"801123456"] +,[,,"802\\d{6}","\\d{9}",,,"802123456"] +,[,,"NA","NA"] +,"RO",40,"00","0"," int ",,"0",,,,[[,"([237]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[23]1|7","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","[23][02-9]|[89]","0$1",""]]] +, + "RS": [,[,,"[1-46-9]\\d{4,11}","\\d{5,12}"] +,[,,"[1-3]\\d{6,9}","\\d{5,10}",,,"1012345"] +,[,,"6[0-689]\\d{3,10}","\\d{5,12}",,,"6012345"] +,[,,"800\\d{3,6}","\\d{6,9}",,,"80012345"] +,[,,"(?:9[0-2]|42)\\d{4,7}","\\d{6,9}",,,"90012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"RS",381,"00","0",,,"0",,,,[[,"([23]\\d{2})(\\d{4,7})","$1 $2","(?:2[389]|39)0","0$1",""], +[,"([1-3]\\d)(\\d{5,8})","$1 $2","1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])","0$1",""], +[,"(6[0-689])(\\d{3,10})","$1 $2","6","0$1",""], +[,"(42)(\\d{4,7})","$1 $2","42","0$1",""], +[,"([89]0\\d)(\\d{3,6})","$1 $2","[89]","0$1",""]]] +, + "RU": [,[,,"[3489]\\d{9}","\\d{10}"] +,[,,"(?:3(?:0[12]|4[1-35-79]|5[1-3]|8[1-58]|9[0145])|4(?:01|1[1356]|2[13467]|7[1-5]|8[1-7]|9[1-689])|8(?:1[1-8]|2[01]|3[13-6]|4[0-8]|5[15]|6[1-35-7]|7[1-37-9]))\\d{7}","\\d{10}",,,"3011234567"] +,[,,"9\\d{9}","\\d{10}",,,"9123456789"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"809\\d{7}","\\d{10}",,,"8091234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"RU",7,"8~10","8",,,"8",,,,[[,"([34689]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4","[34689]","8 ($1)",""], +[,"([7]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7","8 ($1)",""]] +,,,1] +, + "RW": [,[,,"[27-9]\\d{8}","\\d{9}"] +,[,,"25\\d{7}","\\d{9}",,,"250123456"] +,[,,"7[258]\\d{7}","\\d{9}",,,"720123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"900\\d{6}","\\d{9}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"RW",250,"000","0",,,"0",,,,[[,"(25\\d)(\\d{3})(\\d{3})","$1 $2 $3","2","$1",""], +[,"([7-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[7-9]","0$1",""]]] +, + "SA": [,[,,"[1-9]\\d{7,10}","\\d{7,11}"] +,[,,"(?:1[24-7]|2[24-8]|3[35-8]|4[34-68]|6[2-5]|7[235-7])\\d{6}","\\d{7,8}",,,"12345678"] +,[,,"(?:5[013-69]\\d|8111)\\d{6}","\\d{9,10}",,,"512345678"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"9200\\d{7}","\\d{11}",,,"92001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SA",966,"00","0",,,"0",,,,[[,"([1-467])(\\d{3})(\\d{4})","$1 $2 $3","[1-467]","0$1",""], +[,"(9200)(\\d{3})(\\d{4})","$1 $2 $3","9","0$1",""], +[,"(5\\d)(\\d{3})(\\d{4})","$1 $2 $3","5","0$1",""], +[,"(800)(\\d{3})(\\d{4})","$1 $2 $3","80","0$1",""], +[,"(8111)(\\d{3})(\\d{3})","$1 $2 $3","81","0$1",""]]] +, + "SB": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SB",677,"00",,,,,,,1] +, + "SC": [,[,,"[2-8]\\d{5}","\\d{6}"] +,[,,"(?:2(?:1[78]|2[14-69]|3[2-4]|4[1-36-8]|6[167]|[89]\\d)|3(?:2[1-6]|4[4-6]|55|6[016]|7\\d|8[0-589]|9[0-5])|5(?:5\\d|6[0-2])|6(?:0[0-27-9]|1[0-478]|2[145]|3[02-4]|4[124]|6[015]|7\\d|8[1-3])|78[0138])\\d{3}","\\d{6}",,,"217123"] +,[,,"(?:5(?:[1247-9]\\d|6[3-9])|7(?:[14679]\\d|2[1-9]|8[24-79]))\\d{3}","\\d{6}",,,"510123"] +,[,,"8000\\d{2}","\\d{6}",,,"800000"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"4[1-37]\\d{4}","\\d{6}",,,"410123"] +,"SC",248,"0[0-2]",,,,,,"00",,[[,"(\\d{3})(\\d{3})","$1 $2",,"",""]]] +, + "SD": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SD",249,"00","0",,,"0",,,1] +, + "SE": [,[,,"\\d{7,10}","\\d{5,10}"] +,[,,"1(?:0[1-8]\\d{6}|[136]\\d{5,7}|(?:2[0-35]|4[0-4]|5[0-25-9]|7[13-6]|[89]\\d)\\d{5,6})|2(?:[136]\\d{5,7}|(?:2[0-7]|4[0136-8]|5[0-38]|7[018]|8[01]|9[0-57])\\d{5,6})|3(?:[356]\\d{5,7}|(?:0[0-4]|1\\d|2[0-25]|4[056]|7[0-2]|8[0-3]|9[023])\\d{5,6})|4(?:[0246]\\d{5,7}|(?:1[01-8]|3[0135]|5[14-79]|7[0-246-9]|8[0156]|9[0-689])\\d{5,6})|5(?:0[0-6]|1[1-5]|2[0-68]|3[0-4]|4\\d|5[0-5]|6[03-5]|7[013]|8[0-79]|9[01])\\d{5,6}|6(?:[03]\\d{5,7}|(?:1[1-3]|2[0-4]|4[02-57]|5[0-37]|6[0-3]|7[0-2]|8[0247]|9[0-356])\\d{5,6})|8\\d{6,8}|9(?:0\\d{5,7}|(?:1[0-68]|2\\d|3[02-59]|4[0-4]|5[0-4]|6[01]|7[0135-8]|8[01])\\d{5,6})","\\d{5,9}",,,"8123456"] +,[,,"7[02-46]\\d{7}","\\d{9}",,,"701234567"] +,[,,"20\\d{4,7}","\\d{6,9}",,,"201234567"] +,[,,"9(?:00|39|44)\\d{7}","\\d{10}",,,"9001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SE",46,"00","0",,,"0",,,,[[,"(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1 $2 $3 $4","8","0$1",""], +[,"([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1 $2 $3 $4","1[013689]|2[136]|3[1356]|4[0246]|54|6[03]|90","0$1",""], +[,"([1-69]\\d)(\\d{3})(\\d{2})","$1 $2 $3","1[13689]|2[136]|3[1356]|4[0246]|54|6[03]|90","0$1",""], +[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])","0$1",""], +[,"(\\d{3})(\\d{2,3})(\\d{2})","$1 $2 $3","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])","0$1",""], +[,"(7[02-46])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","7[02-46]","0$1",""], +[,"(20)(\\d{2,3})(\\d{2})(\\d{2})","$1 $2 $3 $4","20","0$1",""], +[,"(20)(\\d{2,3})(\\d{2})","$1 $2 $3","20","0$1",""], +[,"(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4","9[034]","0$1",""]]] +, + "SG": [,[,,"[13689]\\d{7,10}","\\d{8,11}"] +,[,,"[36]\\d{7}","\\d{8}",,,"31234567"] +,[,,"[89]\\d{7}","\\d{8}",,,"81234567"] +,[,,"1?800\\d{7}","\\d{10,11}",,,"18001234567"] +,[,,"1900\\d{7}","\\d{11}",,,"19001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SG",65,"0[0-3][0-9]",,,,,,,,[[,"([3689]\\d{3})(\\d{4})","$1 $2","[369]|8[1-9]","",""], +[,"(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3","1[89]","",""], +[,"(800)(\\d{3})(\\d{4})","$1 $2 $3","80","",""]]] +, + "SH": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SH",290,"00",,,,,,,1] +, + "SI": [,[,,"[1-9]\\d{5,7}","\\d{6,8}"] +,[,,"[1-57]\\d{6}","\\d{7,8}",,,"1123456"] +,[,,"(?:[37][01]|4[019]|51|64)\\d{6}","\\d{8}",,,"31234567"] +,[,,"80\\d{4,6}","\\d{6,8}",,,"80123456"] +,[,,"90\\d{4,6}","\\d{6,8}",,,"90123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SI",386,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[12]|3[4-8]|4[24-8]|5[4-8]|7[3-8]","0$1",""], +[,"([3-7]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[37][01]|4[019]|51|64","0$1",""], +[,"([89]0)(\\d{4,6})","$1 $2","[89]","0$1",""]]] +, + "SK": [,[,,"[2-689]\\d{8}","\\d{9}"] +,[,,"[2-5]\\d{8}","\\d{9}",,,"212345678"] +,[,,"9(?:0[1-8]|1[0-24-9]|4[0489])\\d{6}","\\d{9}",,,"912123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"9(?:[78]\\d{7}|00\\d{6})","\\d{9}",,,"900123456"] +,[,,"8[5-9]\\d{7}","\\d{9}",,,"850123456"] +,[,,"NA","NA"] +,[,,"6(?:5[0-4]|9[0-6])\\d{6}","\\d{9}",,,"690123456"] +,"SK",421,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{3})(\\d{2})","$1/$2 $3 $4","2","0$1",""], +[,"([3-5]\\d)(\\d{3})(\\d{2})(\\d{2})","$1/$2 $3 $4","[3-5]","0$1",""], +[,"([689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[689]","0$1",""]]] +, + "SL": [,[,,"[2-578]\\d{7}","\\d{6,8}"] +,[,,"[235]2[2-4][2-9]\\d{4}","\\d{6,8}",,,"22221234"] +,[,,"(?:25|3[03]|44|5[056]|7[6-8]|88)[1-9]\\d{5}","\\d{6,8}",,,"25123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SL",232,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",,"(0$1)",""]]] +, + "SM": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SM",378,"00","0",,,"0",,,1] +, + "SN": [,[,,"[37]\\d{8}","\\d{9}"] +,[,,"3(?:010|3(?:8[1-9]|9[2-9]))\\d{5}","\\d{9}",,,"301012345"] +,[,,"7(?:0[1256]0|6(?:1[23]|2[89]|3[3489]|4[6-9]|5[1-389]|6[6-9]|7[45]|8[3-8])|7(?:1[014-8]|2[0-7]|3[0-35-8]|4[0-6]|[56]\\d|7[0-589]|8[01]|9[0-6]))\\d{5}","\\d{9}",,,"701012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"33301\\d{4}","\\d{9}",,,"333011234"] +,"SN",221,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "SO": [,[,,"[13-59]\\d{6,7}","\\d{7,8}"] +,[,,"(?:5[57-9]|[134]\\d)\\d{5}","\\d{7}",,,"5522010"] +,[,,"(?:9[01]|15)\\d{6}","\\d{8}",,,"90792024"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SO",252,"00",,,,,,,,[[,"([13-5])(\\d{6})","$1 $2","[13-5]","",""], +[,"([19]\\d)(\\d{6})","$1 $2","[19]","",""]]] +, + "SR": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SR",597,"00",,,,,,,1] +, + "ST": [,[,,"[29]\\d{6}","\\d{7}"] +,[,,"22\\d{5}","\\d{7}",,,"2221234"] +,[,,"9[89]\\d{5}","\\d{7}",,,"9812345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ST",239,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]]] +, + "SV": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SV",503,"00",,,,,,,1] +, + "SY": [,[,,"[1-59]\\d{7,8}","\\d{6,9}"] +,[,,"(?:1(?:|1\\d?|4\\d|[2356])|2[1-35]|3(?:1\\d|[34])|4[13]|5[1-3])\\d{6}","\\d{6,9}",,,"112345678"] +,[,,"9(?:3[23]|4[457]|55|6[67]|88|9[19])\\d{6}","\\d{9}",,,"944567890"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SY",963,"00","0",,,"0",,,,[[,"([13]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[13]","0$1",""], +[,"([245]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[245]","0$1",""], +[,"(9[3-689])(\\d{4})(\\d{3})","$1 $2 $3","9","0$1",""]]] +, + "SZ": [,[,,"[2-7]\\d{6,7}","\\d{7,8}"] +,[,,"2?(?:2(?:0[07]|[13]7|2[57])|3(?:0[34]|[1278]3|3[23]|[46][34])|(?:40[4-69]|16|2[12]|3[57]|[4578]2|67)|5(?:0[5-7]|1[6-9]|[23][78]|48|5[01]))\\d{4}","\\d{7,8}",,,"2171234"] +,[,,"(?:6|7[67])\\d{6}","\\d{7,8}",,,"6012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SZ",268,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2","[2-6]","",""], +[,"(\\d{4})(\\d{4})","$1 $2","7","",""]]] +, + "TC": [,[,,"[689]\\d{9}","\\d{7,10}"] +,[,,"649(?:712|9(?:4\\d|50))\\d{4}","\\d{7,10}",,,"6497121234"] +,[,,"649(?:2(?:3[12]|4[1-5])|3(?:3[1-39]|4[1-57])|4[34][12])\\d{4}","\\d{10}",,,"6492311234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"64971[01]\\d{4}","\\d{10}",,,"6497101234"] +,"TC",1,"011",,,,,,,,,,,,"649"] +, + "TD": [,[,,"[2679]\\d{7}","\\d{8}"] +,[,,"22(?:[3789]0|5[0-5]|6[89])\\d{4}","\\d{8}",,,"22501234"] +,[,,"(?:6(?:3[0-7]|6\\d)|77\\d|9(?:5[0-4]|9\\d))\\d{5}","\\d{8}",,,"63012345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TD",235,"00|16",,,,,,"00",,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"",""]]] +, + "TF": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TF",262,"00","0",,,"0",,,1] +, + "TG": [,[,,"[02-9]\\d{6}","\\d{7}"] +,[,,"(?:2[2-7]|3[23]|44|55|66|77)\\d{5}","\\d{7}",,,"2212345"] +,[,,"(?:0[1-9]|7[56]|8[1-7]|9\\d)\\d{5}","\\d{7}",,,"0112345"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TG",228,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]]] +, + "TH": [,[,,"[1-8]\\d{7,9}","\\d{8,10}"] +,[,,"(?:2[1-9]|3[24-9]|4[2-5]|5[3-6]|7[3-7])\\d{6}","\\d{8}",,,"21234567"] +,[,,"8\\d{8}","\\d{9}",,,"812345678"] +,[,,"1800\\d{6}","\\d{10}",,,"1800123456"] +,[,,"1900\\d{6}","\\d{10}",,,"1900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"60\\d{7}","\\d{9}",,,"601234567"] +,"TH",66,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3","2","0$1",""], +[,"(60)(\\d{3})(\\d{4})","$1 $2 $3","6","0$1",""], +[,"([3-57]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[3-57]","0$1",""], +[,"(8)(\\d{4})(\\d{4})","$1 $2 $3","8","0$1",""], +[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1","$1",""]]] +, + "TJ": [,[,,"[349]\\d{8}","\\d{3,9}"] +,[,,"(?:3(?:1[3-5]|2[245]|31|4[24-7]|5[25]|72)|4(?:46|74|87))\\d{6}","\\d{3,9}",,,"372123456"] +,[,,"9[0-35-9]\\d{7}","\\d{9}",,,"917123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TJ",992,"8~10","8",,,"8",,,,[[,"([349]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","[34]7|91[78]","8$1",""], +[,"(4[48])(\\d{3})(\\d{4})","$1 $2 $3","4[48]","8$1",""], +[,"(331700)(\\d)(\\d{2})","$1 $2 $3","3317","8$1",""], +[,"(\\d{4})(\\d)(\\d{4})","$1 $2 $3","3(?:[1245]|3(?:[02-9]|1[0-589]))","8$1",""], +[,"(9\\d)(\\d{3})(\\d{4})","$1 $2 $3","9(?:19|[0235-9])","8$1",""]]] +, + "TK": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TK",690,"00",,,,,,,1] +, + "TL": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TL",670,"00",,,,,,,1] +, + "TM": [,[,,"[1-6]\\d{7}","\\d{8}"] +,[,,"(?:12\\d|243|[3-5]22)\\d{5}","\\d{8}",,,"12345678"] +,[,,"6[6-8]\\d{6}","\\d{8}",,,"66123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TM",993,"8~10","8",,,"8",,,,[[,"([1-6]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"8 $1",""]]] +, + "TN": [,[,,"[247-9]\\d{7}","\\d{8}"] +,[,,"7\\d{7}","\\d{8}",,,"71234567"] +,[,,"(?:2[0-7]|40|9\\d)\\d{6}","\\d{8}",,,"20123456"] +,[,,"NA","NA"] +,[,,"8[028]\\d{6}","\\d{8}",,,"80123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TN",216,"00",,,,,,,,[[,"([247-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"",""]]] +, + "TO": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TO",676,"00",,,,,,,1] +, + "TR": [,[,,"[2-589]\\d{9}","\\d{10}"] +,[,,"[2-4]\\d{9}|850\\d{7}","\\d{10}",,,"2123456789"] +,[,,"5\\d{9}","\\d{10}",,,"5123456789"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"900\\d{7}","\\d{10}",,,"9001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TR",90,"00","0",,,"0",,,,[[,"([2-589]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]]] +, + "TT": [,[,,"[89]\\d{9}","\\d{7,10}"] +,[,,"868(?:22[1-4]|6(?:1[4-6]|[2-6]\\d|7[0-79]|9[0-8])|82[12])\\d{4}","\\d{7,10}",,,"8682211234"] +,[,,"868(?:29\\d|3(?:0[1-9]|1[02-9]|[2-9]\\d)|4([679]\\d|8[0-4])|6(?:20|78|8\\d)|7(?:1[02-9]|[2-9]\\d))\\d{4}","\\d{10}",,,"8682911234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TT",1,"011",,,,,,,,,,,,"868"] +, + "TV": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TV",688,"00",,,,,,,1] +, + "TW": [,[,,"[2-9]\\d{7,8}","\\d{8,9}"] +,[,,"[2-8]\\d{7,8}","\\d{8,9}",,,"21234567"] +,[,,"9\\d{8}","\\d{9}",,,"912345678"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"900\\d{6}","\\d{9}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"TW",886,"0(?:0[25679]|19)","0","#",,"0",,,,[[,"([2-8])(\\d{3,4})(\\d{4})","$1 $2 $3","[2-7]|8[1-9]","0$1",""], +[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","80|9","0$1",""]]] +, + "TZ": [,[,,"\\d{9}","\\d{7,9}"] +,[,,"2[2-8]\\d{7}","\\d{7,9}",,,"222345678"] +,[,,"(?:6[158]|7[1-9])(\\d{7})","\\d{9}",,,"612345678"] +,[,,"80[08]\\d{6}","\\d{9}",,,"800123456"] +,[,,"90\\d{7}","\\d{9}",,,"900123456"] +,[,,"8(?:40|6[01])\\d{6}","\\d{9}",,,"840123456"] +,[,,"NA","NA"] +,[,,"41\\d{7}","\\d{9}",,,"412345678"] +,"TZ",255,"00[056]","0",,,"0",,,,[[,"([24]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[24]","0$1",""], +[,"([67]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[67]","0$1",""], +[,"([89]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","[89]","0$1",""]]] +, + "UA": [,[,,"[3-689]\\d{8}","\\d{5,9}"] +,[,,"(?:3[1-8]|4[13-8]|5[1-7]|6[12459])\\d{7}","\\d{5,9}",,,"311234567"] +,[,,"(?:39|50|6[36-8]|9[1-9])\\d{7}","\\d{9}",,,"391234567"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"900\\d{6}","\\d{9}",,,"900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"UA",380,"0~0","0",,,"0",,,,[[,"([3-69]\\d)(\\d{3})(\\d{4})","$1 $2 $3","39|4(?:[45][0-5]|87)|5(?:0|67|7[37])|6[36-8]|9[1-9]","0$1",""], +[,"([3-689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","3(?:[1-46-8]2[013-9]|52)|4[1378]2|5(?:[124-7]2|64)|6(?:[49]2|[12][29]|5[24])|8|90","0$1",""], +[,"([3-6]\\d{3})(\\d{5})","$1 $2","3(?:5[013-9]|[1-46-8](?:22|[013-9]))|4(?:[137][013-9]|6|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6[0135-9]|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])","0$1",""]]] +, + "UG": [,[,,"\\d{9}","\\d{5,9}"] +,[,,"3\\d{8}|4(?:[1-6]\\d|7[136]|8[1356]|96)\\d{6}|20(?:0\\d|24)\\d{5}","\\d{5,9}",,,"312345678"] +,[,,"7(?:[1578]\\d|0[0-4])\\d{6}","\\d{9}",,,"712345678"] +,[,,"800[123]\\d{5}","\\d{9}",,,"800123456"] +,[,,"90[123]\\d{6}","\\d{9}",,,"901123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"UG",256,"00[057]","0",,,"0",,,,[[,"([247-9]\\d{2})(\\d{6})","$1 $2","[7-9]|200|4(?:6[45]|[7-9])","0$1",""], +[,"([34]\\d)(\\d{7})","$1 $2","3|4(?:[1-5]|6[0-36-9])","0$1",""], +[,"(2024)(\\d{5})","$1 $2","202","0$1",""]]] +, + "US": [,[,,"[2-9]\\d{9}","\\d{7,10}"] +,[,,"(?:2(?:0[1-35-9]|1[02-9]|2[4589]|3[149]|4[08]|5[1-46]|6[0279]|7[06]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[014679]|47|5[12]|6[01]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|69|7[089]|8[04])|5(?:0[1-57-9]|1[0235-8]|[23]0|4[01]|5[19]|6[1-37]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[036]|3[016]|4[16]|5[017]|6[0-29]|78|8[12])|7(?:0[1-46-8]|1[2-9]|2[047]|3[124]|4[07]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[06-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[058]|3[167]|4[0179]|5[1246]|7[0-3589]|8[059]))[2-9]\\d{6}","\\d{7,10}",,,"2012345678"] +,[,,"(?:2(?:0[1-35-9]|1[02-9]|2[4589]|3[149]|4[08]|5[1-46]|6[0279]|7[06]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[014679]|47|5[12]|6[01]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|69|7[089]|8[04])|5(?:0[1-57-9]|1[0235-8]|[23]0|4[01]|5[19]|6[1-37]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[036]|3[016]|4[16]|5[017]|6[0-29]|78|8[12])|7(?:0[1-46-8]|1[2-9]|2[047]|3[124]|4[07]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[06-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[058]|3[167]|4[0179]|5[1246]|7[0-3589]|8[059]))[2-9]\\d{6}","\\d{7,10}",,,"2012345678"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"US",1,"011",,,,,,,1,[[,"(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,"",""], +[,"(\\d{3})(\\d{4})","$1-$2",,"",""]] +,[[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",,,""], +[,"(\\d{3})(\\d{4})","$1-$2",,,""]] +,,1] +, + "UY": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"UY",598,"00","0",,,"0",,,1] +, + "UZ": [,[,,"[679]\\d{8}","\\d{7,9}"] +,[,,"(?:6[125679]|7[0-69])\\d{7}","\\d{7,9}",,,"612345678"] +,[,,"9[0-57-9]\\d{7}","\\d{7,9}",,,"912345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"UZ",998,"8~10","8",,,"8",,,,[[,"([679]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"8$1",""]]] +, + "VA": [,[,,"06\\d{8}","\\d{10}"] +,[,,"06698\\d{5}","\\d{10}",,,"0669812345"] +,[,,"N/A","N/A"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VA",379,"00",,,,,,,,[[,"(06)(\\d{4})(\\d{4})","$1 $2 $3",,"",""]]] +, + "VC": [,[,,"(?:784|8(?:00|66|77|88)|900)[2-9]\\d{6}","\\d{7,10}"] +,[,,"784(?:266|3(?:6[6-9]|7\\d|8[0-24-6])|4(?:38|5[0-36-8]|8\\d|9[01])|555|638|784)\\d{4}","\\d{7,10}",,,"7842661234"] +,[,,"784(?:4(?:3[0-24]|5[45]|9[2-5])|5(?:2[6-9]|3[0-3]|93))\\d{4}","\\d{10}",,,"7844301234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VC",1,"011",,,,,,,,,,,,"784"] +, + "VE": [,[,,"[24589]\\d{9}","\\d{7,10}"] +,[,,"(?:2(?:12|3[457-9]|[58][1-9]|[467]\\d|9[1-6])|50[01])\\d{7}","\\d{7,10}",,,"2121234567"] +,[,,"4(?:1[24-8]|2[46])\\d{7}","\\d{10}",,,"4121234567"] +,[,,"800\\d{7}","\\d{10}",,,"8001234567"] +,[,,"900\\d{7}","\\d{10}",,,"9001234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VE",58,"00","0",,,"1\\d{2}|0",,,,[[,"(\\d{3})(\\d{7})","$1-$2",,"0$1",""]]] +, + "VG": [,[,,"(?:284|8(?:00|66|77|88)|900)[2-9]\\d{6}","\\d{7,10}"] +,[,,"284(?:(?:229|4(?:46|9[45])|8(?:52|6[459]))\\d{4}|496[0-5]\\d{3})","\\d{7,10}",,,"2842291234"] +,[,,"284(?:(?:30[0-3]|4(?:4[0-5]|68|99)|54[0-4])\\d{4}|496[6-9]\\d{3})","\\d{10}",,,"2843001234"] +,[,,"8(?:00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VG",1,"011",,,,,,,,,,,,"284"] +, + "VI": [,[,,"340(?:6[49]2|7[17]\\d)\\d{4}|(?:8(?:00|66|77|88)|900)[2-9]\\d{6}","\\d{7,10}"] +,[,,"340(?:6[49]2|7[17]\\d)\\d{4}|(?:8(?:00|66|77|88)|900)[2-9]\\d{6}","\\d{7,10}",,,"3406421234"] +,[,,"340(?:6[49]2|7[17]\\d)\\d{4}|(?:8(?:00|66|77|88)|900)[2-9]\\d{6}","\\d{7,10}",,,"3406421234"] +,[,,"8(00|66|77|88)[2-9]\\d{6}","\\d{10}",,,"8002345678"] +,[,,"900[2-9]\\d{6}","\\d{10}",,,"9002345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VI",1,"011",,,,,,,1,,,,,"340"] +, + "VN": [,[,,"8\\d{5,8}|[1-79]\\d{7,9}","\\d{7,10}"] +,[,,"(?:2(?:[025-79]|1[0189]|[348][01])|3(?:[0136-9]|[25][01])|[48]\\d|5(?:[01][01]|[2-9])|6(?:[0-46-8]|5[01])|7(?:[02-79]|[18][01]))\\d{7}|(?:80|69[3-5])\\d{5}","\\d{7,10}",,,"2101234567"] +,[,,"(?:9[0-8]|1(?:2\\d|6[3-9]|99))\\d{7}","\\d{9,10}",,,"912345678"] +,[,,"1800\\d{4,6}","\\d{8,10}",,,"1800123456"] +,[,,"1900\\d{4,6}","\\d{8,10}",,,"1900123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VN",84,"00","0",,,"0",,,,[[,"([48])(\\d{4})(\\d{4})","$1 $2 $3","[48]","0$1",""], +[,"([235-7]\\d)(\\d{4})(\\d{3})","$1 $2 $3","2[025-79]|3[0136-9]|5[2-9]|6[0-46-9]|7[02-79]","0$1",""], +[,"(80)(\\d{5})","$1 $2","80","0$1",""], +[,"(69[3-5])(\\d{5})","$1 $2","693","0$1",""], +[,"([235-7]\\d{2})(\\d{4})(\\d{3})","$1 $2 $3","2[1348]|3[25]|5[01]|65|7[18]","0$1",""], +[,"(9[0-8])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","0$1",""], +[,"(1[269]\\d)(\\d{3})(\\d{4})","$1 $2 $3","1(?:[26]|99)","0$1",""], +[,"(1[89]00)(\\d{4,6})","$1 $2","1(?:8|90)","$1",""]]] +, + "VU": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"VU",678,"00",,,,,,,1] +, + "WF": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"WF",681,"19",,,,,,,1] +, + "WS": [,[,,"[2-8]\\d{4,6}","\\d{5,7}"] +,[,,"(?:[2-5]\\d|6[1-9]|840\\d)\\d{3}","\\d{5,7}",,,"22123"] +,[,,"(?:60|7[25-7]\\d)\\d{4}","\\d{6,7}",,,"601234"] +,[,,"800\\d{3}","\\d{6}",,,"800123"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"WS",685,"0","0",,,"0",,,,[[,"(840)(\\d{4})","$1 $2","840","0$1",""], +[,"(7[25-7])(\\d{5})","$1 $2","7[25-7]","0$1",""], +[,"(800)(\\d{3})","$1 $2","800","0$1",""]]] +, + "YE": [,[,,"[1-7]\\d{6,8}","\\d{6,9}"] +,[,,"(?:1(?:7\\d|[2-68])|2[2-68]|3[2358]|4[2-58]|5[2-6]|6[3-58]|7[24-68])\\d{5}","\\d{6,8}",,,"1234567"] +,[,,"7[137]\\d{7}","\\d{9}",,,"712345678"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"YE",967,"00","0",,,"0",,,,[[,"([1-7])(\\d{3})(\\d{3})","$1 $2 $3","1[2-68]|[2-6]|7[24-68]","0$1",""], +[,"(1)(\\d{3})(\\d{4})","$1 $2 $3","17","0$1",""], +[,"(7[137]\\d)(\\d{3})(\\d{3})","$1 $2 $3","7[137]","0$1",""]]] +, + "YT": [,[,,"[268]\\d{8}","\\d{9}"] +,[,,"2696[0-4]\\d{4}","\\d{9}",,,"269601234"] +,[,,"639\\d{6}","\\d{9}",,,"639123456"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"YT",262,"00","0",,,"0",,,,,,,,"269|63"] +, + "ZA": [,[,,"\\d{9}","\\d{8,9}"] +,[,,"(?:1[0-8]|2[1-478]|3[1-69]|4\\d|5[1346-8])\\d{7}","\\d{8,9}",,,"101234567"] +,[,,"(?:7[1-4689]|8[1-5789])\\d{7}","\\d{9}",,,"711234567"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"86\\d{7}","\\d{9}",,,"861234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"87\\d{7}","\\d{9}",,,"871234567"] +,"ZA",27,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]]] +, + "ZM": [,[,,"[289]\\d{8}","\\d{9}"] +,[,,"21[1-8]\\d{6}","\\d{9}",,,"211234567"] +,[,,"9(?:55|6[4-9]|7[4-9])\\d{6}","\\d{9}",,,"955123456"] +,[,,"800\\d{6}","\\d{9}",,,"800123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ZM",260,"00","0",,,"0",,,,[[,"([29]\\d)(\\d{7})","$1 $2","[29]","0$1",""], +[,"(800)(\\d{3})(\\d{3})","$1 $2 $3","8","0$1",""]]] +, + "ZW": [,[,,"(?:[19]1|23)\\d{3,8}|[1-69]\\d{4,8}","\\d{3,10}"] +,[,,"(?:1[346-8]|2(?:0[45]|2[28]|48|58[23]|[69]|7[2-46-8]|8[13-9])|3(?:08?|17?|3[78]|[45]|7[1569]|8[379])|5(?:18|483|[57-9])|6(?:37?|[459]|88)|848)\\d{3,6}|(?:2(?:27|5|7[159]|82)|39|5[346]|6[16-8])\\d{4,6}|2(?:0|70)\\d{5,6}|(?:9[2-8]|4\\d)\\d{4,7}","\\d{3,10}",,,"1312345"] +,[,,"(?:[19]1|73)\\d{3,8}","\\d{3,10}",,,"11123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"ZW",263,"00","0",,,"0",,,,[[,"([49])(\\d{3})(\\d{2,5})","$1 $2 $3","4|9[2-9]","0$1",""], +[,"([179]\\d)(\\d{3})(\\d{3,5})","$1 $2 $3","[19]1|7","0$1",""], +[,"([1-356]\\d)(\\d{3,5})","$1 $2","1[3-9]|2(?:[1-469]|0[0-35-9]|[45][0-79])|3(?:0[0-79]|1[0-689]|[24-69]|3[0-69])|5(?:[02-46-9]|[15][0-69])|6(?:[0145]|[29][0-79]|3[0-689]|[68][0-69])","0$1",""], +[,"([1-356]\\d)(\\d{3})(\\d{3})","$1 $2 $3","1[3-9]|2(?:[1-469]|0[0-35-9]|[45][0-79])|3(?:0[0-79]|1[0-689]|[24-69]|3[0-69])|5(?:[02-46-9]|[15][0-69])|6(?:[0145]|[29][0-79]|3[0-689]|[68][0-69])","0$1",""], +[,"([2356]\\d{2})(\\d{3,5})","$1 $2","2(?:[278]|0[45]|48)|3(?:08|17|3[78]|[78])|5[15][78]|6(?:[29]8|37|[68][78])","0$1",""], +[,"([2356]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","2(?:[278]|0[45]|48)|3(?:08|17|3[78]|[78])|5[15][78]|6(?:[29]8|37|[68][78])","0$1",""], +[,"([25]\\d{3})(\\d{3,5})","$1 $2","258[23]|5483","0$1",""], +[,"([25]\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","258[23]|5483","0$1",""]]] +}; diff --git a/javascript/i18n/phonenumbers/metadatafortesting.js b/javascript/i18n/phonenumbers/metadatafortesting.js new file mode 100644 index 000000000..08cc9f533 --- /dev/null +++ b/javascript/i18n/phonenumbers/metadatafortesting.js @@ -0,0 +1,248 @@ +// Copyright (C) 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Generated metadata for file + * PhoneNumberMetaDataForTesting.xml + * @author Nikolaos Trogkanis + */ + +goog.provide('i18n.phonenumbers.metadata'); + +/** + * A mapping from a country code to the region codes which denote the + * country/region represented by that country code. In the case of multiple + * countries sharing a calling code, such as the NANPA countries, the one + * indicated with 'isMainCountryForCode' in the metadata should be first. + * @type {Object.>} + */ +i18n.phonenumbers.metadata.countryCodeToRegionCodeMap = { + 1: ['US','BS'], + 39: ['IT'], + 44: ['GB'], + 48: ['PL'], + 49: ['DE'], + 52: ['MX'], + 54: ['AR'], + 61: ['AU'], + 64: ['NZ'], + 65: ['SG'], + 82: ['KR'], + 262: ['RE','YT'], + 376: ['AD'] +}; + +/** + * A mapping from a region code to the PhoneMetadata for that region. + * @type {Object.} + */ +i18n.phonenumbers.metadata.countryToMetadata = { + "AD": [,[] +,[] +,[] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AD",376,"00",,,,,,,1] +, + "AR": [,[,,"[1-3689]\\d{9,10}","\\d{6,11}"] +,[,,"[1-3]\\d{9}","\\d{6,10}"] +,[,,"9\\d{10}|[1-3]\\d{9}","\\d{10,11}"] +,[,,"80\\d{8}","\\d{10}"] +,[,,"6(0\\d|10)\\d{7}","\\d{10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AR",54,"00","0",,,"0(?:(11|343|3715)15)?","9$1",,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","11","0$1",""], +[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","1[02-9]|[23]","0$1",""], +[,"9(11)(\\d{4})(\\d{4})","$1 15 $2-$3","911","0$1",""], +[,"9(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","9(?:1[02-9]|[23])","0$1","$1 $CC"], +[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[68]","0$1",""]] +,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","11",,""], +[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","1[02-9]|[23]",,""], +[,"(9)(11)(\\d{4})(\\d{4})","$1 $2 $3 $4","911",,""], +[,"(9)(\\d{4})(\\d{2})(\\d{4})","$1 $2 $3 $4","9(?:1[02-9]|[23])",,""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,""]]] +, + "AU": [,[,,"[1-578]\\d{4,14}","\\d{5,15}"] +,[,,"[2378]\\d{8}","\\d{9}"] +,[,,"4\\d{8}","\\d{9}"] +,[,,"1800\\d{6}","\\d{10}"] +,[,,"190[0126]\\d{6}","\\d{10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"AU",61,"001[12]","0",,,"0",,"0011",,[[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1","$1",""], +[,"(\\d{1})(\\d{4})(\\d{4})","$1 $2 $3","[2-478]","0$1",""]]] +, + "BS": [,[,,"(242|8(00|66|77|88)|900)\\d{7}","\\d{7,10}"] +,[,,"242(?:3(?:02|[236][1-9]|4[0-24-9]|5[0-68]|7[3-57]|9[2-5])|4(?:2[237]|51|64|77)|502|636|702)\\d{4}","\\d{7,10}"] +,[,,"242(357|359|457|557)\\d{4}","\\d{10}"] +,[,,"8(00|66|77|88)\\d{7}","\\d{10}"] +,[,,"900\\d{7}","\\d{10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"BS",1,"011",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",,"",""]]] +, + "DE": [,[,,"\\d{4,14}","\\d{2,14}"] +,[,,"(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:[1-9]\\d|0[2-9]))\\d{3,8}","\\d{2,14}",,,"30123456"] +,[,,"1(5\\d{9}|7\\d{8}|6[02]\\d{8}|63\\d{7})","\\d{10,11}"] +,[,,"800\\d{7}","\\d{10}"] +,[,,"900([135]\\d{6}|9\\d{7})","\\d{10,11}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"DE",49,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3,8})","$1 $2","2|3[3-9]|906|[4-9][1-9]1","0$1",""], +[,"(\\d{2})(\\d{4,9})","$1 $2","[34]0|[68]9","0$1",""], +[,"([4-9]\\d{3})(\\d{2,7})","$1 $2","[4-9]","0$1",""], +[,"(\\d{3})(\\d{1})(\\d{6})","$1 $2 $3","800","0$1",""], +[,"(\\d{3})(\\d{3})(d{4})","$1 $2 $3","900[135]","0$1",""], +[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","9009","0$1",""]]] +, + "GB": [,[,,"\\d{10}","\\d{6,10}"] +,[,,"[1-6]\\d{9}","\\d{6,10}"] +,[,,"7[1-57-9]\\d{8}","\\d{10}"] +,[,,"80\\d{8}","\\d{10}"] +,[,,"9[018]\\d{8}","\\d{10}"] +,[,,"8(?:4[3-5]|7[0-2])\\d{7}","\\d{10}"] +,[,,"70\\d{8}","\\d{10}"] +,[,,"56\\d{8}","\\d{10}"] +,"GB",44,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","[1-59]|[78]0","(0$1)",""], +[,"(\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4","6","(0$1)",""], +[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","7[1-57-9]","(0$1)",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8[47]","(0$1)",""]]] +, + "IT": [,[,,"[0389]\\d{5,10}","\\d{6,11}"] +,[,,"0\\d{9,10}","\\d{10,11}"] +,[,,"3\\d{8,9}","\\d{9,10}"] +,[,,"80(?:0\\d{6}|3\\d{3})","\\d{6,9}"] +,[,,"89(?:2\\d{3}|9\\d{6})","\\d{6,9}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"IT",39,"00",,,,,,,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","0[26]","",""], +[,"(\\d{3})(\\d{4})(\\d{3,4})","$1 $2 $3","0[13-57-9]","",""], +[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","3","",""], +[,"(\\d{3})(\\d{3,6})","$1 $2","8","",""]]] +, + "KR": [,[,,"[1-79]\\d{3,9}|8\\d{8}","\\d{4,10}"] +,[,,"[1-79]\\d{3,9}|8\\d{8}","\\d{4,10}"] +,[,,"[1-79]\\d{3,9}|8\\d{8}","\\d{4,10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"KR",82,"00(?:[124-68]|[37]\\d{2})","0",,,"0(?:8[1-46-8]|85\\d{2})?",,,1,[[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0","0$1",""], +[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5(?:[1-3]|4[56]))|[68]0|[3-9][1-9][2-9]","0$1",""], +[,"(\\d{3})(\\d)(\\d{4})","$1-$2-$3","1312","0$1",""], +[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131[13-9]","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]","0$1",""], +[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30","0$1",""], +[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3","2(?:[26]|3(?:01|1[45]|2[17-9]|39|4|6[67]|7[078]))","0$1",""], +[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3","2(?:3(?:0[02-9]|1[0-36-9]|2[02-6]|3[0-8]|6[0-589]|7[1-69]|[589])|[457-9])","0$1",""], +[,"(\\d)(\\d{3})","$1-$2","21(?:[0-247-9]|3[124]|6[1269])","0$1",""], +[,"(\\d)(\\d{4})","$1-$2","21(?:3[035-9]|6[03-578])","0$1",""], +[,"(\\d{2})(\\d{3})","$1-$2","[3-9][1-9]1(?:[0-247-9]|3[124]|6[1269])","0$1",""], +[,"(\\d{2})(\\d{4})","$1-$2","[3-9][1-9]1(?:3[035-9]|6[03-578])","0$1",""]]] +, + "MX": [,[,,"[1-9]\\d{9,10}","\\d{7,11}"] +,[,,"[2-9]\\d{9}","\\d{7,10}"] +,[,,"1\\d{10}","\\d{11}"] +,[,,"800\\d{7}","\\d{10}"] +,[,,"900\\d{7}","\\d{10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"MX",52,"00","01",,,"01|04[45](\\d{10})","1$1",,,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[89]00","",""], +[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","33|55|81","",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[2467]|3[0-24-9]|5[0-46-9]|8[2-9]|9[1-9]","",""], +[,"1(\\d{2})(\\d{4})(\\d{4})","045 $1 $2 $3","1(?:33|55|81)","",""], +[,"1(\\d{3})(\\d{3})(\\d{4})","045 $1 $2 $3","1(?:[124579]|3[0-24-9]|5[0-46-9]|8[02-9])","",""]] +,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[89]00",,""], +[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","33|55|81",,""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[2467]|3[0-24-9]|5[0-46-9]|8[2-9]|9[1-9]",,""], +[,"(1)(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3 $4","1(?:33|55|81)",,""], +[,"(1)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3 $4","1(?:[124579]|3[0-24-9]|5[0-46-9]|8[02-9])",,""]]] +, + "NZ": [,[,,"[2-9]\\d{7,9}","\\d{7,10}"] +,[,,"24099\\d{3}|(?:3[2-79]|[479][2-689]|6[235-9])\\d{6}","\\d{7,8}"] +,[,,"2(?:[027]\\d{7}|9\\d{6,7}|1(?:0\\d{5,7}|[12]\\d{5,6}|[3-9]\\d{5})|4[1-9]\\d{6}|8\\d{7,8})","\\d{8,10}"] +,[,,"800\\d{6,7}","\\d{9,10}"] +,[,,"900\\d{6,7}","\\d{9,10}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"NZ",64,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1-$2 $3","24|[34679]","0$1",""], +[,"(\\d)(\\d{3})(\\d{3,5})","$1-$2 $3","2[179]","0$1",""], +[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[89]","0$1",""]]] +, + "PL": [,[,,"[1-9]\\d{8}","\\d{9}"] +,[,,"[1-9]\\d{8}","\\d{9}"] +,[,,"(?:5[01]|6[069]|7[289]|88)\\d{7}","\\d{9}"] +,[,,"800\\d{6}","\\d{9}"] +,[,,"70\\d{7}","\\d{9}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"PL",48,"0~0","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1",""]]] +, + "RE": [,[,,"[268]\\d{8}","\\d{9}"] +,[,,"262\\d{6}","\\d{9}",,,"262161234"] +,[,,"6(?:9[23]|47)\\d{6}","\\d{9}",,,"692123456"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"8(?:1[01]|2[0156]|84|9[0-37-9])\\d{6}","\\d{9}",,,"810123456"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"RE",262,"00","0",,,"0",,,,[[,"([268]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1",""]] +,,,,"262|6(?:9[23]|47)|8"] +, + "SG": [,[,,"[13689]\\d{7,10}","\\d{8,11}"] +,[,,"[36]\\d{7}","\\d{8}"] +,[,,"[89]\\d{7}","\\d{8}"] +,[,,"1?800\\d{7}","\\d{10,11}"] +,[,,"1900\\d{7}","\\d{11}"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"SG",65,"0[0-3][0-9]",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2","[369]|8[1-9]","",""], +[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3","1[89]","",""], +[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","800","",""]]] +, + "US": [,[,,"[13-9]\\d{9}|2[0-35-9]\\d{8}","\\d{7,10}",,,"1234567890"] +,[,,"[13-9]\\d{9}|2[0-35-9]\\d{8}","\\d{7,10}",,,"1234567890"] +,[,,"[13-9]\\d{9}|2[0-35-9]\\d{8}","\\d{7,10}",,,"1234567890"] +,[,,"8(00|66|77|88)\\d{7}","\\d{10}",,,"1234567890"] +,[,,"900\\d{7}","\\d{10}",,,"1234567890"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"US",1,"011",," extn. ",,,,,1,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",,"",""], +[,"(\\d{3})(\\d{4})","$1 $2",,"",""]] +,,,1] +, + "YT": [,[,,"[268]\\d{8}","\\d{9}"] +,[,,"2696[0-4]\\d{4}","\\d{9}",,,"269601234"] +,[,,"639\\d{6}","\\d{9}",,,"639123456"] +,[,,"80\\d{7}","\\d{9}",,,"801234567"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,[,,"NA","NA"] +,"YT",262,"00","0",,,"0",,,,,,,,"269|639"] +}; diff --git a/javascript/i18n/phonenumbers/phonemetadata.pb.js b/javascript/i18n/phonenumbers/phonemetadata.pb.js new file mode 100644 index 000000000..e06d5d17e --- /dev/null +++ b/javascript/i18n/phonenumbers/phonemetadata.pb.js @@ -0,0 +1,1890 @@ +// Protocol Buffer 2 Copyright 2008 Google Inc +// All other code copyright its respective owners(s). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Generated Protocol Buffer code for file + * phonemetadata.proto. + */ + +goog.provide('i18n.phonenumbers.NumberFormat'); +goog.provide('i18n.phonenumbers.PhoneNumberDesc'); +goog.provide('i18n.phonenumbers.PhoneMetadata'); +goog.provide('i18n.phonenumbers.PhoneMetadataCollection'); + +goog.require('goog.proto2.Message'); + +/** + * Message NumberFormat. + * @constructor + * @extends {goog.proto2.Message} + */ +i18n.phonenumbers.NumberFormat = function() { + goog.proto2.Message.apply(this); +}; +goog.inherits(i18n.phonenumbers.NumberFormat, goog.proto2.Message); + +/** + * Gets the value of the pattern field. + * @return {?string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getPattern = function() { + return /** @type {?string} */ (this.get$Value(1)); +}; + + +/** + * Gets the value of the pattern field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getPatternOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(1)); +}; + + +/** + * Sets the value of the pattern field. + * @param {string} value The value. + */ +i18n.phonenumbers.NumberFormat.prototype.setPattern = function(value) { + this.set$Value(1, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the pattern field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.NumberFormat.prototype.hasPattern = function() { + return this.has$Value(1); +}; + + +/** + * Gets the number of values in the pattern field. + * @return {number} + */ +i18n.phonenumbers.NumberFormat.prototype.patternCount = function() { + return this.count$Values(1); +}; + + +/** + * Clears the values in the pattern field. + */ +i18n.phonenumbers.NumberFormat.prototype.clearPattern = function() { + this.clear$Field(1); +}; + + +/** + * Gets the value of the format field. + * @return {?string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getFormat = function() { + return /** @type {?string} */ (this.get$Value(2)); +}; + + +/** + * Gets the value of the format field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getFormatOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(2)); +}; + + +/** + * Sets the value of the format field. + * @param {string} value The value. + */ +i18n.phonenumbers.NumberFormat.prototype.setFormat = function(value) { + this.set$Value(2, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the format field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.NumberFormat.prototype.hasFormat = function() { + return this.has$Value(2); +}; + + +/** + * Gets the number of values in the format field. + * @return {number} + */ +i18n.phonenumbers.NumberFormat.prototype.formatCount = function() { + return this.count$Values(2); +}; + + +/** + * Clears the values in the format field. + */ +i18n.phonenumbers.NumberFormat.prototype.clearFormat = function() { + this.clear$Field(2); +}; + + +/** + * Gets the value of the leading_digits field. + * @return {?string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getLeadingDigits = function() { + return /** @type {?string} */ (this.get$Value(3)); +}; + + +/** + * Gets the value of the leading_digits field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getLeadingDigitsOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(3)); +}; + + +/** + * Sets the value of the leading_digits field. + * @param {string} value The value. + */ +i18n.phonenumbers.NumberFormat.prototype.setLeadingDigits = function(value) { + this.set$Value(3, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the leading_digits field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.NumberFormat.prototype.hasLeadingDigits = function() { + return this.has$Value(3); +}; + + +/** + * Gets the number of values in the leading_digits field. + * @return {number} + */ +i18n.phonenumbers.NumberFormat.prototype.leadingDigitsCount = function() { + return this.count$Values(3); +}; + + +/** + * Clears the values in the leading_digits field. + */ +i18n.phonenumbers.NumberFormat.prototype.clearLeadingDigits = function() { + this.clear$Field(3); +}; + + +/** + * Gets the value of the national_prefix_formatting_rule field. + * @return {?string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getNationalPrefixFormattingRule = function() { + return /** @type {?string} */ (this.get$Value(4)); +}; + + +/** + * Gets the value of the national_prefix_formatting_rule field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getNationalPrefixFormattingRuleOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(4)); +}; + + +/** + * Sets the value of the national_prefix_formatting_rule field. + * @param {string} value The value. + */ +i18n.phonenumbers.NumberFormat.prototype.setNationalPrefixFormattingRule = function(value) { + this.set$Value(4, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_prefix_formatting_rule field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.NumberFormat.prototype.hasNationalPrefixFormattingRule = function() { + return this.has$Value(4); +}; + + +/** + * Gets the number of values in the national_prefix_formatting_rule field. + * @return {number} + */ +i18n.phonenumbers.NumberFormat.prototype.nationalPrefixFormattingRuleCount = function() { + return this.count$Values(4); +}; + + +/** + * Clears the values in the national_prefix_formatting_rule field. + */ +i18n.phonenumbers.NumberFormat.prototype.clearNationalPrefixFormattingRule = function() { + this.clear$Field(4); +}; + + +/** + * Gets the value of the domestic_carrier_code_formatting_rule field. + * @return {?string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getDomesticCarrierCodeFormattingRule = function() { + return /** @type {?string} */ (this.get$Value(5)); +}; + + +/** + * Gets the value of the domestic_carrier_code_formatting_rule field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.NumberFormat.prototype.getDomesticCarrierCodeFormattingRuleOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(5)); +}; + + +/** + * Sets the value of the domestic_carrier_code_formatting_rule field. + * @param {string} value The value. + */ +i18n.phonenumbers.NumberFormat.prototype.setDomesticCarrierCodeFormattingRule = function(value) { + this.set$Value(5, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the domestic_carrier_code_formatting_rule field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.NumberFormat.prototype.hasDomesticCarrierCodeFormattingRule = function() { + return this.has$Value(5); +}; + + +/** + * Gets the number of values in the domestic_carrier_code_formatting_rule field. + * @return {number} + */ +i18n.phonenumbers.NumberFormat.prototype.domesticCarrierCodeFormattingRuleCount = function() { + return this.count$Values(5); +}; + + +/** + * Clears the values in the domestic_carrier_code_formatting_rule field. + */ +i18n.phonenumbers.NumberFormat.prototype.clearDomesticCarrierCodeFormattingRule = function() { + this.clear$Field(5); +}; + + + + +/** + * Message PhoneNumberDesc. + * @constructor + * @extends {goog.proto2.Message} + */ +i18n.phonenumbers.PhoneNumberDesc = function() { + goog.proto2.Message.apply(this); +}; +goog.inherits(i18n.phonenumbers.PhoneNumberDesc, goog.proto2.Message); + +/** + * Gets the value of the national_number_pattern field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getNationalNumberPattern = function() { + return /** @type {?string} */ (this.get$Value(2)); +}; + + +/** + * Gets the value of the national_number_pattern field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getNationalNumberPatternOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(2)); +}; + + +/** + * Sets the value of the national_number_pattern field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.setNationalNumberPattern = function(value) { + this.set$Value(2, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_number_pattern field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.hasNationalNumberPattern = function() { + return this.has$Value(2); +}; + + +/** + * Gets the number of values in the national_number_pattern field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.nationalNumberPatternCount = function() { + return this.count$Values(2); +}; + + +/** + * Clears the values in the national_number_pattern field. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.clearNationalNumberPattern = function() { + this.clear$Field(2); +}; + + +/** + * Gets the value of the possible_number_pattern field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getPossibleNumberPattern = function() { + return /** @type {?string} */ (this.get$Value(3)); +}; + + +/** + * Gets the value of the possible_number_pattern field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getPossibleNumberPatternOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(3)); +}; + + +/** + * Sets the value of the possible_number_pattern field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.setPossibleNumberPattern = function(value) { + this.set$Value(3, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the possible_number_pattern field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.hasPossibleNumberPattern = function() { + return this.has$Value(3); +}; + + +/** + * Gets the number of values in the possible_number_pattern field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.possibleNumberPatternCount = function() { + return this.count$Values(3); +}; + + +/** + * Clears the values in the possible_number_pattern field. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.clearPossibleNumberPattern = function() { + this.clear$Field(3); +}; + + +/** + * Gets the value of the example_number field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getExampleNumber = function() { + return /** @type {?string} */ (this.get$Value(6)); +}; + + +/** + * Gets the value of the example_number field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.getExampleNumberOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(6)); +}; + + +/** + * Sets the value of the example_number field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.setExampleNumber = function(value) { + this.set$Value(6, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the example_number field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.hasExampleNumber = function() { + return this.has$Value(6); +}; + + +/** + * Gets the number of values in the example_number field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.exampleNumberCount = function() { + return this.count$Values(6); +}; + + +/** + * Clears the values in the example_number field. + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.clearExampleNumber = function() { + this.clear$Field(6); +}; + + + + +/** + * Message PhoneMetadata. + * @constructor + * @extends {goog.proto2.Message} + */ +i18n.phonenumbers.PhoneMetadata = function() { + goog.proto2.Message.apply(this); +}; +goog.inherits(i18n.phonenumbers.PhoneMetadata, goog.proto2.Message); + +/** + * Gets the value of the general_desc field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getGeneralDesc = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(1)); +}; + + +/** + * Gets the value of the general_desc field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getGeneralDescOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(1)); +}; + + +/** + * Sets the value of the general_desc field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setGeneralDesc = function(value) { + this.set$Value(1, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the general_desc field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasGeneralDesc = function() { + return this.has$Value(1); +}; + + +/** + * Gets the number of values in the general_desc field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.generalDescCount = function() { + return this.count$Values(1); +}; + + +/** + * Clears the values in the general_desc field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearGeneralDesc = function() { + this.clear$Field(1); +}; + + +/** + * Gets the value of the fixed_line field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getFixedLine = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(2)); +}; + + +/** + * Gets the value of the fixed_line field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getFixedLineOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(2)); +}; + + +/** + * Sets the value of the fixed_line field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setFixedLine = function(value) { + this.set$Value(2, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the fixed_line field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasFixedLine = function() { + return this.has$Value(2); +}; + + +/** + * Gets the number of values in the fixed_line field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.fixedLineCount = function() { + return this.count$Values(2); +}; + + +/** + * Clears the values in the fixed_line field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearFixedLine = function() { + this.clear$Field(2); +}; + + +/** + * Gets the value of the mobile field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getMobile = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(3)); +}; + + +/** + * Gets the value of the mobile field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getMobileOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(3)); +}; + + +/** + * Sets the value of the mobile field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setMobile = function(value) { + this.set$Value(3, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the mobile field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasMobile = function() { + return this.has$Value(3); +}; + + +/** + * Gets the number of values in the mobile field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.mobileCount = function() { + return this.count$Values(3); +}; + + +/** + * Clears the values in the mobile field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearMobile = function() { + this.clear$Field(3); +}; + + +/** + * Gets the value of the toll_free field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getTollFree = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(4)); +}; + + +/** + * Gets the value of the toll_free field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getTollFreeOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(4)); +}; + + +/** + * Sets the value of the toll_free field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setTollFree = function(value) { + this.set$Value(4, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the toll_free field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasTollFree = function() { + return this.has$Value(4); +}; + + +/** + * Gets the number of values in the toll_free field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.tollFreeCount = function() { + return this.count$Values(4); +}; + + +/** + * Clears the values in the toll_free field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearTollFree = function() { + this.clear$Field(4); +}; + + +/** + * Gets the value of the premium_rate field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPremiumRate = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(5)); +}; + + +/** + * Gets the value of the premium_rate field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPremiumRateOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(5)); +}; + + +/** + * Sets the value of the premium_rate field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setPremiumRate = function(value) { + this.set$Value(5, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the premium_rate field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasPremiumRate = function() { + return this.has$Value(5); +}; + + +/** + * Gets the number of values in the premium_rate field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.premiumRateCount = function() { + return this.count$Values(5); +}; + + +/** + * Clears the values in the premium_rate field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearPremiumRate = function() { + this.clear$Field(5); +}; + + +/** + * Gets the value of the shared_cost field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getSharedCost = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(6)); +}; + + +/** + * Gets the value of the shared_cost field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getSharedCostOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(6)); +}; + + +/** + * Sets the value of the shared_cost field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setSharedCost = function(value) { + this.set$Value(6, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the shared_cost field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasSharedCost = function() { + return this.has$Value(6); +}; + + +/** + * Gets the number of values in the shared_cost field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.sharedCostCount = function() { + return this.count$Values(6); +}; + + +/** + * Clears the values in the shared_cost field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearSharedCost = function() { + this.clear$Field(6); +}; + + +/** + * Gets the value of the personal_number field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPersonalNumber = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(7)); +}; + + +/** + * Gets the value of the personal_number field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPersonalNumberOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(7)); +}; + + +/** + * Sets the value of the personal_number field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setPersonalNumber = function(value) { + this.set$Value(7, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the personal_number field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasPersonalNumber = function() { + return this.has$Value(7); +}; + + +/** + * Gets the number of values in the personal_number field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.personalNumberCount = function() { + return this.count$Values(7); +}; + + +/** + * Clears the values in the personal_number field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearPersonalNumber = function() { + this.clear$Field(7); +}; + + +/** + * Gets the value of the voip field. + * @return {?i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getVoip = function() { + return /** @type {?i18n.phonenumbers.PhoneNumberDesc} */ (this.get$Value(8)); +}; + + +/** + * Gets the value of the voip field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumberDesc} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getVoipOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumberDesc} */ (this.get$ValueOrDefault(8)); +}; + + +/** + * Sets the value of the voip field. + * @param {i18n.phonenumbers.PhoneNumberDesc} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setVoip = function(value) { + this.set$Value(8, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the voip field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasVoip = function() { + return this.has$Value(8); +}; + + +/** + * Gets the number of values in the voip field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.voipCount = function() { + return this.count$Values(8); +}; + + +/** + * Clears the values in the voip field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearVoip = function() { + this.clear$Field(8); +}; + + +/** + * Gets the value of the id field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getId = function() { + return /** @type {?string} */ (this.get$Value(9)); +}; + + +/** + * Gets the value of the id field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getIdOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(9)); +}; + + +/** + * Sets the value of the id field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setId = function(value) { + this.set$Value(9, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the id field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasId = function() { + return this.has$Value(9); +}; + + +/** + * Gets the number of values in the id field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.idCount = function() { + return this.count$Values(9); +}; + + +/** + * Clears the values in the id field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearId = function() { + this.clear$Field(9); +}; + + +/** + * Gets the value of the country_code field. + * @return {?number} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getCountryCode = function() { + return /** @type {?number} */ (this.get$Value(10)); +}; + + +/** + * Gets the value of the country_code field or the default value if not set. + * @return {number} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getCountryCodeOrDefault = function() { + return /** @type {number} */ (this.get$ValueOrDefault(10)); +}; + + +/** + * Sets the value of the country_code field. + * @param {number} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setCountryCode = function(value) { + this.set$Value(10, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the country_code field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasCountryCode = function() { + return this.has$Value(10); +}; + + +/** + * Gets the number of values in the country_code field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.countryCodeCount = function() { + return this.count$Values(10); +}; + + +/** + * Clears the values in the country_code field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearCountryCode = function() { + this.clear$Field(10); +}; + + +/** + * Gets the value of the international_prefix field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getInternationalPrefix = function() { + return /** @type {?string} */ (this.get$Value(11)); +}; + + +/** + * Gets the value of the international_prefix field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getInternationalPrefixOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(11)); +}; + + +/** + * Sets the value of the international_prefix field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setInternationalPrefix = function(value) { + this.set$Value(11, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the international_prefix field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasInternationalPrefix = function() { + return this.has$Value(11); +}; + + +/** + * Gets the number of values in the international_prefix field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.internationalPrefixCount = function() { + return this.count$Values(11); +}; + + +/** + * Clears the values in the international_prefix field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearInternationalPrefix = function() { + this.clear$Field(11); +}; + + +/** + * Gets the value of the preferred_international_prefix field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPreferredInternationalPrefix = function() { + return /** @type {?string} */ (this.get$Value(17)); +}; + + +/** + * Gets the value of the preferred_international_prefix field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPreferredInternationalPrefixOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(17)); +}; + + +/** + * Sets the value of the preferred_international_prefix field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setPreferredInternationalPrefix = function(value) { + this.set$Value(17, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the preferred_international_prefix field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasPreferredInternationalPrefix = function() { + return this.has$Value(17); +}; + + +/** + * Gets the number of values in the preferred_international_prefix field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.preferredInternationalPrefixCount = function() { + return this.count$Values(17); +}; + + +/** + * Clears the values in the preferred_international_prefix field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearPreferredInternationalPrefix = function() { + this.clear$Field(17); +}; + + +/** + * Gets the value of the national_prefix field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefix = function() { + return /** @type {?string} */ (this.get$Value(12)); +}; + + +/** + * Gets the value of the national_prefix field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefixOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(12)); +}; + + +/** + * Sets the value of the national_prefix field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setNationalPrefix = function(value) { + this.set$Value(12, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_prefix field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasNationalPrefix = function() { + return this.has$Value(12); +}; + + +/** + * Gets the number of values in the national_prefix field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.nationalPrefixCount = function() { + return this.count$Values(12); +}; + + +/** + * Clears the values in the national_prefix field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearNationalPrefix = function() { + this.clear$Field(12); +}; + + +/** + * Gets the value of the preferred_extn_prefix field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPreferredExtnPrefix = function() { + return /** @type {?string} */ (this.get$Value(13)); +}; + + +/** + * Gets the value of the preferred_extn_prefix field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getPreferredExtnPrefixOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(13)); +}; + + +/** + * Sets the value of the preferred_extn_prefix field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setPreferredExtnPrefix = function(value) { + this.set$Value(13, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the preferred_extn_prefix field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasPreferredExtnPrefix = function() { + return this.has$Value(13); +}; + + +/** + * Gets the number of values in the preferred_extn_prefix field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.preferredExtnPrefixCount = function() { + return this.count$Values(13); +}; + + +/** + * Clears the values in the preferred_extn_prefix field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearPreferredExtnPrefix = function() { + this.clear$Field(13); +}; + + +/** + * Gets the value of the national_prefix_for_parsing field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefixForParsing = function() { + return /** @type {?string} */ (this.get$Value(15)); +}; + + +/** + * Gets the value of the national_prefix_for_parsing field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefixForParsingOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(15)); +}; + + +/** + * Sets the value of the national_prefix_for_parsing field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setNationalPrefixForParsing = function(value) { + this.set$Value(15, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_prefix_for_parsing field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasNationalPrefixForParsing = function() { + return this.has$Value(15); +}; + + +/** + * Gets the number of values in the national_prefix_for_parsing field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.nationalPrefixForParsingCount = function() { + return this.count$Values(15); +}; + + +/** + * Clears the values in the national_prefix_for_parsing field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearNationalPrefixForParsing = function() { + this.clear$Field(15); +}; + + +/** + * Gets the value of the national_prefix_transform_rule field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefixTransformRule = function() { + return /** @type {?string} */ (this.get$Value(16)); +}; + + +/** + * Gets the value of the national_prefix_transform_rule field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNationalPrefixTransformRuleOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(16)); +}; + + +/** + * Sets the value of the national_prefix_transform_rule field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setNationalPrefixTransformRule = function(value) { + this.set$Value(16, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_prefix_transform_rule field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasNationalPrefixTransformRule = function() { + return this.has$Value(16); +}; + + +/** + * Gets the number of values in the national_prefix_transform_rule field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.nationalPrefixTransformRuleCount = function() { + return this.count$Values(16); +}; + + +/** + * Clears the values in the national_prefix_transform_rule field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearNationalPrefixTransformRule = function() { + this.clear$Field(16); +}; + + +/** + * Gets the value of the same_mobile_and_fixed_line_pattern field. + * @return {?boolean} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getSameMobileAndFixedLinePattern = function() { + return /** @type {?boolean} */ (this.get$Value(18)); +}; + + +/** + * Gets the value of the same_mobile_and_fixed_line_pattern field or the default value if not set. + * @return {boolean} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getSameMobileAndFixedLinePatternOrDefault = function() { + return /** @type {boolean} */ (this.get$ValueOrDefault(18)); +}; + + +/** + * Sets the value of the same_mobile_and_fixed_line_pattern field. + * @param {boolean} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setSameMobileAndFixedLinePattern = function(value) { + this.set$Value(18, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the same_mobile_and_fixed_line_pattern field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasSameMobileAndFixedLinePattern = function() { + return this.has$Value(18); +}; + + +/** + * Gets the number of values in the same_mobile_and_fixed_line_pattern field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.sameMobileAndFixedLinePatternCount = function() { + return this.count$Values(18); +}; + + +/** + * Clears the values in the same_mobile_and_fixed_line_pattern field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearSameMobileAndFixedLinePattern = function() { + this.clear$Field(18); +}; + + +/** + * Gets the value of the number_format field at the index given. + * @param {number} index The index to lookup. + * @return {?i18n.phonenumbers.NumberFormat} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNumberFormat = function(index) { + return /** @type {?i18n.phonenumbers.NumberFormat} */ (this.get$Value(19, index)); +}; + + +/** + * Gets the value of the number_format field at the index given or the default value if not set. + * @param {number} index The index to lookup. + * @return {i18n.phonenumbers.NumberFormat} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getNumberFormatOrDefault = function(index) { + return /** @type {i18n.phonenumbers.NumberFormat} */ (this.get$ValueOrDefault(19, index)); +}; + + +/** + * Adds a value to the number_format field. + * @param {i18n.phonenumbers.NumberFormat} value The value to add. + */ +i18n.phonenumbers.PhoneMetadata.prototype.addNumberFormat = function(value) { + this.add$Value(19, /** @type {Object} */ (value)); +}; + + +/** + * Returns the array of values in the number_format field. + * @return {Array.} The values in the field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.numberFormatArray = function() { + return /** @type {Array.} */ (this.array$Values(19)); +}; + + +/** + * Returns whether the number_format field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasNumberFormat = function() { + return this.has$Value(19); +}; + + +/** + * Gets the number of values in the number_format field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.numberFormatCount = function() { + return this.count$Values(19); +}; + + +/** + * Clears the values in the number_format field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearNumberFormat = function() { + this.clear$Field(19); +}; + + +/** + * Gets the value of the intl_number_format field at the index given. + * @param {number} index The index to lookup. + * @return {?i18n.phonenumbers.NumberFormat} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getIntlNumberFormat = function(index) { + return /** @type {?i18n.phonenumbers.NumberFormat} */ (this.get$Value(20, index)); +}; + + +/** + * Gets the value of the intl_number_format field at the index given or the default value if not set. + * @param {number} index The index to lookup. + * @return {i18n.phonenumbers.NumberFormat} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getIntlNumberFormatOrDefault = function(index) { + return /** @type {i18n.phonenumbers.NumberFormat} */ (this.get$ValueOrDefault(20, index)); +}; + + +/** + * Adds a value to the intl_number_format field. + * @param {i18n.phonenumbers.NumberFormat} value The value to add. + */ +i18n.phonenumbers.PhoneMetadata.prototype.addIntlNumberFormat = function(value) { + this.add$Value(20, /** @type {Object} */ (value)); +}; + + +/** + * Returns the array of values in the intl_number_format field. + * @return {Array.} The values in the field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.intlNumberFormatArray = function() { + return /** @type {Array.} */ (this.array$Values(20)); +}; + + +/** + * Returns whether the intl_number_format field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasIntlNumberFormat = function() { + return this.has$Value(20); +}; + + +/** + * Gets the number of values in the intl_number_format field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.intlNumberFormatCount = function() { + return this.count$Values(20); +}; + + +/** + * Clears the values in the intl_number_format field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearIntlNumberFormat = function() { + this.clear$Field(20); +}; + + +/** + * Gets the value of the main_country_for_code field. + * @return {?boolean} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getMainCountryForCode = function() { + return /** @type {?boolean} */ (this.get$Value(22)); +}; + + +/** + * Gets the value of the main_country_for_code field or the default value if not set. + * @return {boolean} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getMainCountryForCodeOrDefault = function() { + return /** @type {boolean} */ (this.get$ValueOrDefault(22)); +}; + + +/** + * Sets the value of the main_country_for_code field. + * @param {boolean} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setMainCountryForCode = function(value) { + this.set$Value(22, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the main_country_for_code field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasMainCountryForCode = function() { + return this.has$Value(22); +}; + + +/** + * Gets the number of values in the main_country_for_code field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.mainCountryForCodeCount = function() { + return this.count$Values(22); +}; + + +/** + * Clears the values in the main_country_for_code field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearMainCountryForCode = function() { + this.clear$Field(22); +}; + + +/** + * Gets the value of the leading_digits field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getLeadingDigits = function() { + return /** @type {?string} */ (this.get$Value(23)); +}; + + +/** + * Gets the value of the leading_digits field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.getLeadingDigitsOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(23)); +}; + + +/** + * Sets the value of the leading_digits field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.setLeadingDigits = function(value) { + this.set$Value(23, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the leading_digits field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadata.prototype.hasLeadingDigits = function() { + return this.has$Value(23); +}; + + +/** + * Gets the number of values in the leading_digits field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadata.prototype.leadingDigitsCount = function() { + return this.count$Values(23); +}; + + +/** + * Clears the values in the leading_digits field. + */ +i18n.phonenumbers.PhoneMetadata.prototype.clearLeadingDigits = function() { + this.clear$Field(23); +}; + + + + +/** + * Message PhoneMetadataCollection. + * @constructor + * @extends {goog.proto2.Message} + */ +i18n.phonenumbers.PhoneMetadataCollection = function() { + goog.proto2.Message.apply(this); +}; +goog.inherits(i18n.phonenumbers.PhoneMetadataCollection, goog.proto2.Message); + +/** + * Gets the value of the metadata field at the index given. + * @param {number} index The index to lookup. + * @return {?i18n.phonenumbers.PhoneMetadata} The value. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.getMetadata = function(index) { + return /** @type {?i18n.phonenumbers.PhoneMetadata} */ (this.get$Value(1, index)); +}; + + +/** + * Gets the value of the metadata field at the index given or the default value if not set. + * @param {number} index The index to lookup. + * @return {i18n.phonenumbers.PhoneMetadata} The value. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.getMetadataOrDefault = function(index) { + return /** @type {i18n.phonenumbers.PhoneMetadata} */ (this.get$ValueOrDefault(1, index)); +}; + + +/** + * Adds a value to the metadata field. + * @param {i18n.phonenumbers.PhoneMetadata} value The value to add. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.addMetadata = function(value) { + this.add$Value(1, /** @type {Object} */ (value)); +}; + + +/** + * Returns the array of values in the metadata field. + * @return {Array.} The values in the field. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.metadataArray = function() { + return /** @type {Array.} */ (this.array$Values(1)); +}; + + +/** + * Returns whether the metadata field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.hasMetadata = function() { + return this.has$Value(1); +}; + + +/** + * Gets the number of values in the metadata field. + * @return {number} + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.metadataCount = function() { + return this.count$Values(1); +}; + + +/** + * Clears the values in the metadata field. + */ +i18n.phonenumbers.PhoneMetadataCollection.prototype.clearMetadata = function() { + this.clear$Field(1); +}; + + + + +goog.proto2.Message.set$Metadata(i18n.phonenumbers.NumberFormat, { + 0 : { + name: 'NumberFormat', + fullName: 'i18n.phonenumbers.NumberFormat' + }, + '1' : { + name: 'pattern', + required: true, + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '2' : { + name: 'format', + required: true, + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '3' : { + name: 'leading_digits', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '4' : { + name: 'national_prefix_formatting_rule', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '5' : { + name: 'domestic_carrier_code_formatting_rule', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }}); + +goog.proto2.Message.set$Metadata(i18n.phonenumbers.PhoneNumberDesc, { + 0 : { + name: 'PhoneNumberDesc', + fullName: 'i18n.phonenumbers.PhoneNumberDesc' + }, + '2' : { + name: 'national_number_pattern', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '3' : { + name: 'possible_number_pattern', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '6' : { + name: 'example_number', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }}); + +goog.proto2.Message.set$Metadata(i18n.phonenumbers.PhoneMetadata, { + 0 : { + name: 'PhoneMetadata', + fullName: 'i18n.phonenumbers.PhoneMetadata' + }, + '1' : { + name: 'general_desc', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '2' : { + name: 'fixed_line', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '3' : { + name: 'mobile', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '4' : { + name: 'toll_free', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '5' : { + name: 'premium_rate', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '6' : { + name: 'shared_cost', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '7' : { + name: 'personal_number', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '8' : { + name: 'voip', + required: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneNumberDesc + }, + '9' : { + name: 'id', + required: true, + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '10' : { + name: 'country_code', + required: true, + fieldType: goog.proto2.Message.FieldType.INT32, + type: Number + }, + '11' : { + name: 'international_prefix', + required: true, + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '17' : { + name: 'preferred_international_prefix', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '12' : { + name: 'national_prefix', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '13' : { + name: 'preferred_extn_prefix', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '15' : { + name: 'national_prefix_for_parsing', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '16' : { + name: 'national_prefix_transform_rule', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '18' : { + name: 'same_mobile_and_fixed_line_pattern', + fieldType: goog.proto2.Message.FieldType.BOOL, + defaultValue: false, + type: Boolean + }, + '19' : { + name: 'number_format', + repeated: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.NumberFormat + }, + '20' : { + name: 'intl_number_format', + repeated: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.NumberFormat + }, + '22' : { + name: 'main_country_for_code', + fieldType: goog.proto2.Message.FieldType.BOOL, + defaultValue: false, + type: Boolean + }, + '23' : { + name: 'leading_digits', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }}); + +goog.proto2.Message.set$Metadata(i18n.phonenumbers.PhoneMetadataCollection, { + 0 : { + name: 'PhoneMetadataCollection', + fullName: 'i18n.phonenumbers.PhoneMetadataCollection' + }, + '1' : { + name: 'metadata', + repeated: true, + fieldType: goog.proto2.Message.FieldType.MESSAGE, + type: i18n.phonenumbers.PhoneMetadata + }}); + diff --git a/javascript/i18n/phonenumbers/phonenumber.pb.js b/javascript/i18n/phonenumbers/phonenumber.pb.js new file mode 100644 index 000000000..cc36a1804 --- /dev/null +++ b/javascript/i18n/phonenumbers/phonenumber.pb.js @@ -0,0 +1,405 @@ +// Protocol Buffer 2 Copyright 2008 Google Inc +// All other code copyright its respective owners(s). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Generated Protocol Buffer code for file + * phonenumber.proto. + */ + +goog.provide('i18n.phonenumbers.PhoneNumber'); +goog.provide('i18n.phonenumbers.PhoneNumber.CountryCodeSource'); + +goog.require('goog.proto2.Message'); + +/** + * Message PhoneNumber. + * @constructor + * @extends {goog.proto2.Message} + */ +i18n.phonenumbers.PhoneNumber = function() { + goog.proto2.Message.apply(this); +}; +goog.inherits(i18n.phonenumbers.PhoneNumber, goog.proto2.Message); + +/** + * Gets the value of the country_code field. + * @return {?number} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getCountryCode = function() { + return /** @type {?number} */ (this.get$Value(1)); +}; + + +/** + * Gets the value of the country_code field or the default value if not set. + * @return {number} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getCountryCodeOrDefault = function() { + return /** @type {number} */ (this.get$ValueOrDefault(1)); +}; + + +/** + * Sets the value of the country_code field. + * @param {number} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setCountryCode = function(value) { + this.set$Value(1, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the country_code field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasCountryCode = function() { + return this.has$Value(1); +}; + + +/** + * Gets the number of values in the country_code field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.countryCodeCount = function() { + return this.count$Values(1); +}; + + +/** + * Clears the values in the country_code field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearCountryCode = function() { + this.clear$Field(1); +}; + + +/** + * Gets the value of the national_number field. + * @return {?number} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getNationalNumber = function() { + return /** @type {?number} */ (this.get$Value(2)); +}; + + +/** + * Gets the value of the national_number field or the default value if not set. + * @return {number} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getNationalNumberOrDefault = function() { + return /** @type {number} */ (this.get$ValueOrDefault(2)); +}; + + +/** + * Sets the value of the national_number field. + * @param {number} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setNationalNumber = function(value) { + this.set$Value(2, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the national_number field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasNationalNumber = function() { + return this.has$Value(2); +}; + + +/** + * Gets the number of values in the national_number field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.nationalNumberCount = function() { + return this.count$Values(2); +}; + + +/** + * Clears the values in the national_number field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearNationalNumber = function() { + this.clear$Field(2); +}; + + +/** + * Gets the value of the extension field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getExtension = function() { + return /** @type {?string} */ (this.get$Value(3)); +}; + + +/** + * Gets the value of the extension field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getExtensionOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(3)); +}; + + +/** + * Sets the value of the extension field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setExtension = function(value) { + this.set$Value(3, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the extension field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasExtension = function() { + return this.has$Value(3); +}; + + +/** + * Gets the number of values in the extension field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.extensionCount = function() { + return this.count$Values(3); +}; + + +/** + * Clears the values in the extension field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearExtension = function() { + this.clear$Field(3); +}; + + +/** + * Gets the value of the italian_leading_zero field. + * @return {?boolean} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getItalianLeadingZero = function() { + return /** @type {?boolean} */ (this.get$Value(4)); +}; + + +/** + * Gets the value of the italian_leading_zero field or the default value if not set. + * @return {boolean} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getItalianLeadingZeroOrDefault = function() { + return /** @type {boolean} */ (this.get$ValueOrDefault(4)); +}; + + +/** + * Sets the value of the italian_leading_zero field. + * @param {boolean} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setItalianLeadingZero = function(value) { + this.set$Value(4, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the italian_leading_zero field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasItalianLeadingZero = function() { + return this.has$Value(4); +}; + + +/** + * Gets the number of values in the italian_leading_zero field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.italianLeadingZeroCount = function() { + return this.count$Values(4); +}; + + +/** + * Clears the values in the italian_leading_zero field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearItalianLeadingZero = function() { + this.clear$Field(4); +}; + + +/** + * Gets the value of the raw_input field. + * @return {?string} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getRawInput = function() { + return /** @type {?string} */ (this.get$Value(5)); +}; + + +/** + * Gets the value of the raw_input field or the default value if not set. + * @return {string} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getRawInputOrDefault = function() { + return /** @type {string} */ (this.get$ValueOrDefault(5)); +}; + + +/** + * Sets the value of the raw_input field. + * @param {string} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setRawInput = function(value) { + this.set$Value(5, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the raw_input field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasRawInput = function() { + return this.has$Value(5); +}; + + +/** + * Gets the number of values in the raw_input field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.rawInputCount = function() { + return this.count$Values(5); +}; + + +/** + * Clears the values in the raw_input field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearRawInput = function() { + this.clear$Field(5); +}; + + +/** + * Gets the value of the country_code_source field. + * @return {?i18n.phonenumbers.PhoneNumber.CountryCodeSource} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getCountryCodeSource = function() { + return /** @type {?i18n.phonenumbers.PhoneNumber.CountryCodeSource} */ (this.get$Value(6)); +}; + + +/** + * Gets the value of the country_code_source field or the default value if not set. + * @return {i18n.phonenumbers.PhoneNumber.CountryCodeSource} The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.getCountryCodeSourceOrDefault = function() { + return /** @type {i18n.phonenumbers.PhoneNumber.CountryCodeSource} */ (this.get$ValueOrDefault(6)); +}; + + +/** + * Sets the value of the country_code_source field. + * @param {i18n.phonenumbers.PhoneNumber.CountryCodeSource} value The value. + */ +i18n.phonenumbers.PhoneNumber.prototype.setCountryCodeSource = function(value) { + this.set$Value(6, /** @type {Object} */ (value)); +}; + + +/** + * Returns whether the country_code_source field has a value. + * @return {boolean} true if the field has a value. + */ +i18n.phonenumbers.PhoneNumber.prototype.hasCountryCodeSource = function() { + return this.has$Value(6); +}; + + +/** + * Gets the number of values in the country_code_source field. + * @return {number} + */ +i18n.phonenumbers.PhoneNumber.prototype.countryCodeSourceCount = function() { + return this.count$Values(6); +}; + + +/** + * Clears the values in the country_code_source field. + */ +i18n.phonenumbers.PhoneNumber.prototype.clearCountryCodeSource = function() { + this.clear$Field(6); +}; + + +/** + * Enumeration CountryCodeSource. + * @enum {number} + */ +i18n.phonenumbers.PhoneNumber.CountryCodeSource = { + FROM_NUMBER_WITH_PLUS_SIGN : 1, + FROM_NUMBER_WITH_IDD : 5, + FROM_NUMBER_WITHOUT_PLUS_SIGN : 10, + FROM_DEFAULT_COUNTRY : 20 +}; + + + +goog.proto2.Message.set$Metadata(i18n.phonenumbers.PhoneNumber, { + 0 : { + name: 'PhoneNumber', + fullName: 'i18n.phonenumbers.PhoneNumber' + }, + '1' : { + name: 'country_code', + required: true, + fieldType: goog.proto2.Message.FieldType.INT32, + type: Number + }, + '2' : { + name: 'national_number', + required: true, + fieldType: goog.proto2.Message.FieldType.UINT64, + type: Number + }, + '3' : { + name: 'extension', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '4' : { + name: 'italian_leading_zero', + fieldType: goog.proto2.Message.FieldType.BOOL, + type: Boolean + }, + '5' : { + name: 'raw_input', + fieldType: goog.proto2.Message.FieldType.STRING, + type: String + }, + '6' : { + name: 'country_code_source', + fieldType: goog.proto2.Message.FieldType.ENUM, + defaultValue: i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, + type: i18n.phonenumbers.PhoneNumber.CountryCodeSource + }}); + diff --git a/javascript/i18n/phonenumbers/phonenumberutil.js b/javascript/i18n/phonenumbers/phonenumberutil.js new file mode 100644 index 000000000..2a9ffbe01 --- /dev/null +++ b/javascript/i18n/phonenumbers/phonenumberutil.js @@ -0,0 +1,2512 @@ +// Copyright (C) 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utility for international phone numbers. + * Functionality includes formatting, parsing and validation. + * (based on the java implementation). + * + * @author Nikolaos Trogkanis + */ + +goog.provide('i18n.phonenumbers.PhoneNumberUtil'); + +goog.require('goog.array'); +goog.require('goog.proto2.PbLiteSerializer'); +goog.require('goog.string'); +goog.require('goog.string.StringBuffer'); +goog.require('i18n.phonenumbers.NumberFormat'); +goog.require('i18n.phonenumbers.PhoneMetadata'); +goog.require('i18n.phonenumbers.PhoneMetadataCollection'); +goog.require('i18n.phonenumbers.PhoneNumber'); +goog.require('i18n.phonenumbers.PhoneNumber.CountryCodeSource'); +goog.require('i18n.phonenumbers.PhoneNumberDesc'); +goog.require('i18n.phonenumbers.metadata'); + +/** + * @constructor + * @private + */ +i18n.phonenumbers.PhoneNumberUtil = function() { + /** + * A mapping from a region code to the PhoneMetadata for that region. + * @type {Object.} + */ + this.countryToMetadata = {}; +}; +goog.addSingletonGetter(i18n.phonenumbers.PhoneNumberUtil); + +/** + * Errors encountered when parsing phone numbers. + * + * @enum {string} + */ +i18n.phonenumbers.Error = { + INVALID_COUNTRY_CODE: 'Invalid country code', + // This generally indicates the string passed in had less than 3 digits in it. + // More specifically, the number failed to match the regular expression + // VALID_PHONE_NUMBER. + NOT_A_NUMBER: 'The string supplied did not seem to be a phone number', + // This indicates the string started with an international dialing prefix, but + // after this was stripped from the number, had less digits than any valid + // phone number (including country code) could have. + TOO_SHORT_AFTER_IDD: 'Phone number too short after IDD', + // This indicates the string, after any country code has been stripped, had + // less digits than any + // valid phone number could have. + TOO_SHORT_NSN: 'The string supplied is too short to be a phone number', + // This indicates the string had more digits than any valid phone number could + // have. + TOO_LONG: 'The string supplied is too long to be a phone number' +} + +/** + * @const + * @type {number} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.NANPA_COUNTRY_CODE_ = 1; + +/** + * The minimum length of the national significant number. + * + * @const + * @type {number} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ = 3; + +/** + * The maximum length of the national significant number. + * + * @const + * @type {number} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_ = 15; + +/** + * The PLUS_SIGN signifies the international prefix. + * + * @const + * @type {string} + */ +i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN = '+'; + +/** + * These mappings map a character (key) to a specific digit that should replace + * it for normalization purposes. Non-European digits that may be used in phone + * numbers are mapped to a European equivalent. + * + * @const + */ +i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS = { + '0': '0', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '\uFF10': '0', // Fullwidth digit 0 + '\uFF11': '1', // Fullwidth digit 1 + '\uFF12': '2', // Fullwidth digit 2 + '\uFF13': '3', // Fullwidth digit 3 + '\uFF14': '4', // Fullwidth digit 4 + '\uFF15': '5', // Fullwidth digit 5 + '\uFF16': '6', // Fullwidth digit 6 + '\uFF17': '7', // Fullwidth digit 7 + '\uFF18': '8', // Fullwidth digit 8 + '\uFF19': '9', // Fullwidth digit 9 + '\u0660': '0', // Arabic-indic digit 0 + '\u0661': '1', // Arabic-indic digit 1 + '\u0662': '2', // Arabic-indic digit 2 + '\u0663': '3', // Arabic-indic digit 3 + '\u0664': '4', // Arabic-indic digit 4 + '\u0665': '5', // Arabic-indic digit 5 + '\u0666': '6', // Arabic-indic digit 6 + '\u0667': '7', // Arabic-indic digit 7 + '\u0668': '8', // Arabic-indic digit 8 + '\u0669': '9' // Arabic-indic digit 9 +}; + +/** + * Only upper-case variants of alpha characters are stored. + * + * @const + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.ALPHA_MAPPINGS_ = { + 'A': '2', + 'B': '2', + 'C': '2', + 'D': '3', + 'E': '3', + 'F': '3', + 'G': '4', + 'H': '4', + 'I': '4', + 'J': '5', + 'K': '5', + 'L': '5', + 'M': '6', + 'N': '6', + 'O': '6', + 'P': '7', + 'Q': '7', + 'R': '7', + 'S': '7', + 'T': '8', + 'U': '8', + 'V': '8', + 'W': '9', + 'X': '9', + 'Y': '9', + 'Z': '9' +}; + +/** + * For performance reasons, amalgamate both into one map. + * + * @const + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.ALL_NORMALIZATION_MAPPINGS_ = { + '0': '0', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '\uFF10': '0', // Fullwidth digit 0 + '\uFF11': '1', // Fullwidth digit 1 + '\uFF12': '2', // Fullwidth digit 2 + '\uFF13': '3', // Fullwidth digit 3 + '\uFF14': '4', // Fullwidth digit 4 + '\uFF15': '5', // Fullwidth digit 5 + '\uFF16': '6', // Fullwidth digit 6 + '\uFF17': '7', // Fullwidth digit 7 + '\uFF18': '8', // Fullwidth digit 8 + '\uFF19': '9', // Fullwidth digit 9 + '\u0660': '0', // Arabic-indic digit 0 + '\u0661': '1', // Arabic-indic digit 1 + '\u0662': '2', // Arabic-indic digit 2 + '\u0663': '3', // Arabic-indic digit 3 + '\u0664': '4', // Arabic-indic digit 4 + '\u0665': '5', // Arabic-indic digit 5 + '\u0666': '6', // Arabic-indic digit 6 + '\u0667': '7', // Arabic-indic digit 7 + '\u0668': '8', // Arabic-indic digit 8 + '\u0669': '9', // Arabic-indic digit 9 + 'A': '2', + 'B': '2', + 'C': '2', + 'D': '3', + 'E': '3', + 'F': '3', + 'G': '4', + 'H': '4', + 'I': '4', + 'J': '5', + 'K': '5', + 'L': '5', + 'M': '6', + 'N': '6', + 'O': '6', + 'P': '7', + 'Q': '7', + 'R': '7', + 'S': '7', + 'T': '8', + 'U': '8', + 'V': '8', + 'W': '9', + 'X': '9', + 'Y': '9', + 'Z': '9' +}; + +/** + * A list of all country codes where national significant numbers (excluding any + * national prefix) exist that start with a leading zero. + * + * @const + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.LEADING_ZERO_COUNTRIES_ = { + 39: 1, // Italy + 47: 1, // Norway + 225: 1, // Cote d'Ivoire + 227: 1, // Niger + 228: 1, // Togo + 241: 1, // Gabon + 379: 1 // Vatican City +}; + +/** + * Pattern that makes it easy to distinguish whether a country has a unique + * international dialing prefix or not. If a country has a unique international + * prefix (e.g. 011 in USA), it will be represented as a string that contains a + * sequence of ASCII digits. If there are multiple available international + * prefixes in a country, they will be represented as a regex string that always + * contains character(s) other than ASCII digits. Note this regex also includes + * tilde, which signals waiting for the tone. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.UNIQUE_INTERNATIONAL_PREFIX_ = + /[\d]+(?:[~\u2053\u223C\uFF5E][\d]+)?/; + +/** + * Regular expression of acceptable punctuation found in phone numbers. This + * excludes punctuation found as a leading character only. This consists of dash + * characters, white space characters, full stops, slashes, square brackets, + * parentheses and tildes. It also includes the letter 'x' as that is found as a + * placeholder for carrier information in some phone numbers. + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ = + '-x\u2010-\u2015\u2212\uFF0D-\uFF0F \u00A0\u200B\u2060\u3000()' + + '\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E'; + +/** + * Digits accepted in phone numbers (ascii, fullwidth, and arabic-indic digits). + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ = + '0-9\uFF10-\uFF19\u0660-\u0669'; + +/** + * We accept alpha characters in phone numbers, ASCII only, upper and lower + * case. + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ = 'A-Za-z'; + +/** + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ = '+\uFF0B'; + +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.CAPTURING_DIGIT_PATTERN_ = + new RegExp('([' + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + '])'); + +/** + * Regular expression of acceptable characters that may start a phone number for + * the purposes of parsing. This allows us to strip away meaningless prefixes to + * phone numbers that may be mistakenly given to us. This consists of digits, + * the plus symbol and arabic-indic digits. This does not contain alpha + * characters, although they may be used later in the number. It also does not + * include other punctuation, as this will be stripped later during parsing and + * is of no information value when parsing a number. + * + * @const + * @type {RegExp} + * @protected + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_START_CHAR_PATTERN = + new RegExp('[' + i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ + + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']'); + +/** + * Regular expression of characters typically used to start a second phone + * number for the purposes of parsing. This allows us to strip off parts of the + * number that are actually the start of another number, such as for: + * (530) 583-6985 x302/x2303 -> the second extension here makes this actually + * two phone numbers, (530) 583-6985 x302 and (530) 583-6985 x2303. We remove + * the second extension so that the first number is parsed correctly. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.SECOND_NUMBER_START_PATTERN_ = /[\\\/] *x/; + +/** + * Regular expression of trailing characters that we want to remove. We remove + * all characters that are not alpha or numerical characters. The hash character + * is retained here, as it may signify the previous block was an extension. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN_ = + new RegExp('[^' + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + + i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ + '#]+$'); + +/** + * We use this pattern to check if the phone number has at least three letters + * in it - if so, then we treat it as a number where some phone-number digits + * are represented by letters. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_PHONE_PATTERN_ = + /(?:.*?[A-Za-z]){3}.*/; + +/** + * Regular expression of viable phone numbers. This is location independent. + * Checks we have at least three leading digits, and only valid punctuation, + * alpha characters and digits in the phone number. Does not include extension + * data. The symbol 'x' is allowed here as valid punctuation since it is often + * used as a placeholder for carrier codes, for example in Brazilian phone + * numbers. Corresponds to the following: + * plus_sign?([punctuation]*[digits]){3,}([punctuation]|[digits]|[alpha])* + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_ = + '[' + i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ + ']?(?:[' + + i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ + ']*[' + + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']){3,}[' + + i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ + + i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ + + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']*'; + +/** + * Default extension prefix to use when formatting. This will be put in front of + * any extension component of the number, after the main national number is + * formatted. For example, if you wish the default extension formatting to be + * ' extn: 3456', then you should specify ' extn: ' here as the default + * extension prefix. This can be overridden by country-specific preferences. + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.DEFAULT_EXTN_PREFIX_ = ' ext. '; + +/** + * Regexp of all possible ways to write extensions, for use when parsing. This + * will be run as a case-insensitive regexp match. Wide character versions are + * also provided after each ascii version. There are two regular expressions + * here: the more generic one starts with optional white space and ends with an + * optional full stop (.), followed by zero or more spaces/tabs and then the + * numbers themselves. The other one covers the special case of American numbers + * where the extension is written with a hash at the end, such as "- 503#". Note + * that the only capturing groups should be around the digits that you want to + * capture as part of the extension, or else parsing will fail! + * + * @const + * @type {string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ = + '[ \u00A0\\t,]*' + '(?:ext(?:ensio)?n?|\uFF45\uFF58\uFF54\uFF4E?|' + + '[,x\uFF58#\uFF03~\uFF5E]|int|anexo|\uFF49\uFF4E\uFF54)' + + '[:\\.\uFF0E]?[ \u00A0\\t,-]*([' + + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']{1,7})|[- ]+([' + + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']{1,5})#'; + +/** + * Regexp of all known extension prefixes used by different countries followed + * by 1 or more valid digits, for use when parsing. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.EXTN_PATTERN_ = + new RegExp('(?:' + i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ + + ')$', 'i'); + +/** + * We append optionally the extension pattern to the end here, as a valid phone + * number may have an extension prefix appended, followed by 1 or more digits. + * + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_PATTERN_ = + new RegExp('^' + i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_ + + '(?:' + i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ + + ')?' + '$', 'i'); + +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.NON_DIGITS_PATTERN_ = /\D+/; +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.FIRST_GROUP_PATTERN_ = /(\$1)/; +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.NP_PATTERN_ = /\$NP/; +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.FG_PATTERN_ = /\$FG/; +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.CC_PATTERN_ = /\$CC/; +/** + * @const + * @type {RegExp} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.NON_DIGIT_PATTERN_ = /\D/; + +/** + * INTERNATIONAL and NATIONAL formats are consistent with the definition in + * ITU-T Recommendation E. 123. For example, the number of the Google Zurich + * office will be written as "+41 44 668 1800" in INTERNATIONAL format, and as + * "044 668 1800" in NATIONAL format. E164 format is as per INTERNATIONAL format + * but with no formatting applied, e.g. +41446681800. + * + * @enum {number} + */ +i18n.phonenumbers.PhoneNumberFormat = { + E164: 0, + INTERNATIONAL: 1, + NATIONAL: 2 +}; + +/** + * Type of phone numbers. + * + * @enum {number} + */ +i18n.phonenumbers.PhoneNumberType = { + FIXED_LINE: 0, + MOBILE: 1, + // In some countries (e.g. the USA), it is impossible to distinguish between + // fixed-line and mobile numbers by looking at the phone number itself. + FIXED_LINE_OR_MOBILE: 2, + // Freephone lines + TOLL_FREE: 3, + PREMIUM_RATE: 4, + // The cost of this call is shared between the caller and the recipient, and + // is hence typically less than PREMIUM_RATE calls. See + // http://en.wikipedia.org/wiki/Shared_Cost_Service for more information. + SHARED_COST: 5, + // Voice over IP numbers. This includes TSoIP (Telephony Service over IP). + VOIP: 6, + // A personal number is associated with a particular person, and may be routed + // to either a MOBILE or FIXED_LINE number. Some more information can be found + // here: http://en.wikipedia.org/wiki/Personal_Numbers + PERSONAL_NUMBER: 7, + // A phone number is of type UNKNOWN when it does not fit any of the known + // patterns for a specific country. + UNKNOWN: 8 +}; + +/** + * Types of phone number matches. See detailed description beside the + * isNumberMatch() method. + * + * @enum {number} + */ +i18n.phonenumbers.PhoneNumberUtil.MatchType = { + NO_MATCH: 0, + SHORT_NSN_MATCH: 1, + NSN_MATCH: 2, + EXACT_MATCH: 3 +}; + +/** + * Possible outcomes when testing if a PhoneNumber is possible. + * + * @enum {number} + */ +i18n.phonenumbers.PhoneNumberUtil.ValidationResult = { + IS_POSSIBLE: 0, + INVALID_COUNTRY_CODE: 1, + TOO_SHORT: 2, + TOO_LONG: 3 +}; + +/** + * Attempts to extract a possible number from the string passed in. This + * currently strips all leading characters that could not be used to start a + * phone number. Characters that can be used to start a phone number are defined + * in the VALID_START_CHAR_PATTERN. If none of these characters are found in the + * number passed in, an empty string is returned. This function also attempts to + * strip off any alternative extensions or endings if two or more are present, + * such as in the case of: (530) 583-6985 x302/x2303. The second extension here + * makes this actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985 + * x2303. We remove the second extension so that the first number is parsed + * correctly. + * + * @param {string} number the string that might contain a phone number. + * @return {string} the number, stripped of any non-phone-number prefix (such as + * 'Tel:') or an empty string if no character used to start phone numbers + * (such as + or any digit) is found in the number. + */ +i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber = function(number) { + /** @type {string} */ + var possibleNumber; + + /** @type {number} */ + var start = number + .search(i18n.phonenumbers.PhoneNumberUtil.VALID_START_CHAR_PATTERN); + if (start >= 0) { + possibleNumber = number.substring(start); + // Remove trailing non-alpha non-numerical characters. + possibleNumber = possibleNumber.replace( + i18n.phonenumbers.PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN_, ''); + + // Check for extra numbers at the end. + /** @type {number} */ + var secondNumberStart = possibleNumber + .search(i18n.phonenumbers.PhoneNumberUtil.SECOND_NUMBER_START_PATTERN_); + if (secondNumberStart >= 0) { + possibleNumber = possibleNumber.substring(0, secondNumberStart); + } + } else { + possibleNumber = ''; + } + return possibleNumber; +}; + +/** + * Checks to see if the string of characters could possibly be a phone number at + * all. At the moment, checks to see that the string begins with at least 3 + * digits, ignoring any punctuation commonly found in phone numbers. This method + * does not require the number to be normalized in advance - but does assume + * that leading non-number symbols have been removed, such as by the method + * extractPossibleNumber. + * + * @param {string} number string to be checked for viability as a phone number. + * @return {boolean} true if the number could be a phone number of some sort, + * otherwise false. + */ +i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber = function(number) { + if (number.length < i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) { + return false; + } + return i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_PATTERN_, number); +}; + +/** + * Normalizes a string of characters representing a phone number. This performs + * the following conversions: + * - Wide-ascii digits are converted to normal ASCII (European) digits. + * - Letters are converted to their numeric representation on a telephone + * keypad. The keypad used here is the one defined in ITU Recommendation E.161. + * This is only done if there are 3 or more letters in the number, to lessen the + * risk that such letters are typos - otherwise alpha characters are stripped. + * - Punctuation is stripped. + * - Arabic-Indic numerals are converted to European numerals. + * + * @param {string} number a string of characters representing a phone number. + * @return {string} the normalized string version of the phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.normalize = function(number) { + if (i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_PHONE_PATTERN_, number)) { + return i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(number, + i18n.phonenumbers.PhoneNumberUtil.ALL_NORMALIZATION_MAPPINGS_, true); + } else { + return i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(number, + i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS, true); + } +}; + +/** + * Normalizes a string of characters representing a phone number. This is a + * wrapper for normalize(String number) but does in-place normalization of the + * StringBuffer provided. + * + * @param {!goog.string.StringBuffer} number a StringBuffer of characters + * representing a phone number that will be normalized in place. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.normalizeSB_ = function(number) { + /** @type {string} */ + var normalizedNumber = i18n.phonenumbers.PhoneNumberUtil.normalize(number + .toString()); + number.clear(); + number.append(normalizedNumber); +}; + +/** + * Normalizes a string of characters representing a phone number. This converts + * wide-ascii and arabic-indic numerals to European numerals, and strips + * punctuation and alpha characters. + * + * @param {string} number a string of characters representing a phone number. + * @return {string} the normalized string version of the phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly = function(number) { + return i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(number, + i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS, true); +}; + +/** + * Converts all alpha characters in a number to their respective digits on a + * keypad, but retains existing formatting. Also converts wide-ascii digits to + * normal ascii digits, and converts Arabic-Indic numerals to European numerals. + * + * @param {string} number a string of characters representing a phone number. + * @return {string} the normalized string version of the phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.convertAlphaCharactersInNumber = + function(number) { + + return i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(number, + i18n.phonenumbers.PhoneNumberUtil.ALL_NORMALIZATION_MAPPINGS_, false); +}; + +/** + * Gets the length of the geographical area code from the national_number field + * of the PhoneNumber object passed in, so that clients could use it to split a + * national significant number into geographical area code and subscriber + * number. It works in such a way that the resultant subscriber number should be + * diallable, at least on some devices. An example of how this could be used: + * + * var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); + * var number = phoneUtil.parse('16502530000', 'US'); + * var nationalSignificantNumber = + * i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + * var areaCode; + * var subscriberNumber; + * + * var areaCodeLength = phoneUtil.getLengthOfGeographicalAreaCode(number); + * if (areaCodeLength > 0) { + * areaCode = nationalSignificantNumber.substring(0, areaCodeLength); + * subscriberNumber = nationalSignificantNumber.substring(areaCodeLength); + * } else { + * areaCode = ''; + * subscriberNumber = nationalSignificantNumber; + * } + * + * N.B.: area code is a very ambiguous concept, so the I18N team generally + * recommends against using it for most purposes, but recommends using the more + * general national_number instead. Read the following carefully before deciding + * to use this method: + * - geographical area codes change over time, and this method honors those + * changes; therefore, it doesn't guarantee the stability of the result it + * produces. + * - subscriber numbers may not be diallable from all devices (notably mobile + * devices, which typically requires the full national_number to be dialled in + * most countries). + * - most non-geographical numbers have no area codes. + * - some geographical numbers have no area codes. + * + * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber object for + * which clients want to know the length of the area code in the + * national_number field. + * @return {number} the length of area code of the PhoneNumber object passed in. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode = + function(number) { + + if (number == null) { + return 0; + } + /** @type {string} */ + var regionCode = /** @type {string} */ (this.getRegionCodeForNumber(number)); + if (!this.isValidRegionCode_(regionCode)) { + return 0; + } + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + // For NANPA countries, national prefix is the same as country code, but it + // is not stored in + // the metadata. + if (!metadata.hasNationalPrefix() && !this.isNANPACountry(regionCode)) { + return 0; + } + + /** @type {i18n.phonenumbers.PhoneNumberType} */ + var type = this.getNumberTypeHelper_('' + number.getNationalNumber(), + metadata); + // Most numbers other than the two types below have to be dialled in full. + if (type != i18n.phonenumbers.PhoneNumberType.FIXED_LINE && + type != i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE) { + return 0; + } + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var copiedProto; + if (number.hasExtension()) { + // We don't want to alter the proto given to us, but we don't want to + // include the extension when we format it, so we copy it and clear the + // extension here. + copiedProto = new i18n.phonenumbers.PhoneNumber(); + copiedProto.values_ = goog.cloneObject(number.values_); + copiedProto.clearExtension(); + } else { + copiedProto = number; + } + + /** @type {string} */ + var nationalSignificantNumber = this.format(copiedProto, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL); + /** @type {!Array.} */ + var numberGroups = nationalSignificantNumber.split( + i18n.phonenumbers.PhoneNumberUtil.NON_DIGIT_PATTERN_); + // The pattern will start with '+COUNTRY_CODE ' so the first group will always + // be the empty string (before the + symbol) and the second group will be the + // country code. The third group will be area code if it's not the last group. + // NOTE: On IE the first group that is supposed to be the empty string does + // not appear in the array of number groups... so make the result on non-IE + // browsers to be that of IE. + if (numberGroups[0].length == 0) { + numberGroups.shift(); + } + if (numberGroups.length <= 2) { + return 0; + } + // Note all countries that use leading zero in national number currently don't + // use national prefix, so they won't have an area code, which means clients + // don't need to worry about appending the leading zero to the geographical + // area code they derive from the length we return here. + return numberGroups[1].length; +}; + +/** + * Normalizes a string of characters representing a phone number by replacing + * all characters found in the accompanying map with the values therein, and + * stripping all other characters if removeNonMatches is true. + * + * @param {string} number a string of characters representing a phone number. + * @param {!Object} normalizationReplacements a mapping of characters to what + * they should be replaced by in the normalized version of the phone number. + * @param {boolean} removeNonMatches indicates whether characters that are not + * able to be replaced should be stripped from the number. If this is false, + * they will be left unchanged in the number. + * @return {string} the normalized string version of the phone number. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_ = + function(number, normalizationReplacements, removeNonMatches) { + + /** @type {!goog.string.StringBuffer} */ + var normalizedNumber = new goog.string.StringBuffer(); + /** @type {string} */ + var character; + /** @type {string} */ + var newDigit; + /** @type {number} */ + var numberLength = number.length; + for (var i = 0; i < numberLength; ++i) { + character = number.charAt(i); + newDigit = normalizationReplacements[character.toUpperCase()]; + if (newDigit != null) { + normalizedNumber.append(newDigit); + } else if (!removeNonMatches) { + normalizedNumber.append(character); + } + // If neither of the above are true, we remove this character. + } + return normalizedNumber.toString(); +}; + +/** + * Helper function to check region code is not unknown or null. + * + * @param {?string} regionCode the ISO 3166-1 two-letter country code that + * denotes the country/region that we want to get the country code for. + * @return {boolean} true if region code is valid. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isValidRegionCode_ = + function(regionCode) { + + return regionCode != null && + regionCode.toUpperCase() in i18n.phonenumbers.metadata.countryToMetadata; +}; + +/** + * Formats a phone number in the specified format using default rules. Note that + * this does not promise to produce a phone number that the user can dial from + * where they are - although we do format in either 'national' or + * 'international' format depending on what the client asks for, we do not + * currently support a more abbreviated format, such as for users in the same + * "area" who could potentially dial the number without area code. Note that if + * the phone number has a country code of 0 or an otherwise invalid country + * code, we cannot work out which formatting rules to apply so we return the + * national significant number with no formatting applied. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be + * formatted. + * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the + * phone number should be formatted into. + * @return {string} the formatted phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.format = + function(number, numberFormat) { + + /** @type {!goog.string.StringBuffer} */ + var formattedNumber = new goog.string.StringBuffer(); + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + /** @type {string} */ + var nationalSignificantNumber = i18n.phonenumbers.PhoneNumberUtil + .getNationalSignificantNumber(number); + if (numberFormat == i18n.phonenumbers.PhoneNumberFormat.E164) { + // Early exit for E164 case since no formatting of the national number needs + // to be applied. Extensions are not formatted. + formattedNumber.append(nationalSignificantNumber); + this.formatNumberByFormat_(countryCode, + i18n.phonenumbers.PhoneNumberFormat.E164, + formattedNumber); + return formattedNumber.toString(); + } + // Note getRegionCodeForCountryCode() is used because formatting information + // for countries which share a country code is contained by only one country + // for performance reasons. For example, for NANPA countries it will be + // contained in the metadata for US. + /** @type {string} */ + var regionCode = this.getRegionCodeForCountryCode(countryCode); + if (!this.isValidRegionCode_(regionCode)) { + formattedNumber.append(nationalSignificantNumber); + return formattedNumber.toString(); + } + + formattedNumber.append(this.formatNationalNumber_(nationalSignificantNumber, + regionCode, numberFormat)); + this.maybeGetFormattedExtension_(number, regionCode, formattedNumber); + this.formatNumberByFormat_(countryCode, numberFormat, formattedNumber); + return formattedNumber.toString(); +}; + +/** + * Formats a phone number in the specified format using client-defined + * formatting rules. Note that if the phone number has a country code of zero or + * an otherwise invalid country code, we cannot work out things like whether + * there should be a national prefix applied, or how to format extensions, so we + * return the national significant number with no formatting applied. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be + * formatted. + * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the + * phone number should be formatted into. + * @param {Array.} userDefinedFormats formatting + * rules specified by clients. + * @return {string} the formatted phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatByPattern = + function(number, numberFormat, userDefinedFormats) { + + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + /** @type {string} */ + var nationalSignificantNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + // Note getRegionCodeForCountryCode() is used because formatting information + // for countries which share a country code is contained by only one country + // for performance reasons. For example, for NANPA countries it will be + // contained in the metadata for US. + /** @type {string} */ + var regionCode = this.getRegionCodeForCountryCode(countryCode); + if (!this.isValidRegionCode_(regionCode)) { + return nationalSignificantNumber; + } + /** @type {number} */ + var size = userDefinedFormats.length; + for (var i = 0; i < size; ++i) { + /** @type {i18n.phonenumbers.NumberFormat} */ + var numFormat = userDefinedFormats[i]; + /** @type {string} */ + var nationalPrefixFormattingRule = + numFormat.getNationalPrefixFormattingRuleOrDefault(); + if (nationalPrefixFormattingRule.length > 0) { + /** @type {string} */ + var nationalPrefix = + this.getMetadataForRegion(regionCode).getNationalPrefixOrDefault(); + // Replace $NP with national prefix and $FG with the first group ($1). + nationalPrefixFormattingRule = nationalPrefixFormattingRule + .replace(i18n.phonenumbers.PhoneNumberUtil.NP_PATTERN_, + nationalPrefix) + .replace(i18n.phonenumbers.PhoneNumberUtil.FG_PATTERN_, '$1'); + numFormat.setNationalPrefixFormattingRule(nationalPrefixFormattingRule); + } + } + + /** @type {!goog.string.StringBuffer} */ + var formattedNumber = new goog.string.StringBuffer( + this.formatAccordingToFormats_(nationalSignificantNumber, + userDefinedFormats, numberFormat)); + this.maybeGetFormattedExtension_(number, regionCode, formattedNumber); + this.formatNumberByFormat_(countryCode, numberFormat, formattedNumber); + return formattedNumber.toString(); +}; + +/** + * @param {i18n.phonenumbers.PhoneNumber} number + * @param {string} carrierCode + * @return {string} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype. + formatNationalNumberWithCarrierCode = function(number, carrierCode) { + + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + /** @type {string} */ + var nationalSignificantNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + // Note getRegionCodeForCountryCode() is used because formatting information + // for countries which share a country code is contained by only one country + // for performance reasons. For example, for NANPA countries it will be + // contained in the metadata for US. + /** @type {string} */ + var regionCode = this.getRegionCodeForCountryCode(countryCode); + if (!this.isValidRegionCode_(regionCode)) { + return nationalSignificantNumber; + } + + /** @type {!goog.string.StringBuffer} */ + var formattedNumber = new goog.string.StringBuffer( + this.formatNationalNumber_(nationalSignificantNumber, + regionCode, + i18n.phonenumbers.PhoneNumberFormat.NATIONAL, + carrierCode)); + this.maybeGetFormattedExtension_(number, regionCode, formattedNumber); + this.formatNumberByFormat_(countryCode, + i18n.phonenumbers.PhoneNumberFormat.NATIONAL, + formattedNumber); + return formattedNumber.toString(); +} + +/** + * Formats a phone number for out-of-country dialing purpose. If no + * countryCallingFrom is supplied, we format the number in its INTERNATIONAL + * format. If the countryCallingFrom is the same as the country where the number + * is from, then NATIONAL formatting will be applied. + * + * If the number itself has a country code of zero or an otherwise invalid + * country code, then we return the number with no formatting applied. + * + * Note this function takes care of the case for calling inside of NANPA and + * between Russia and Kazakhstan (who share the same country code). In those + * cases, no international prefix is used. For countries which have multiple + * international prefixes, the number in its INTERNATIONAL format will be + * returned instead. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number to be + * formatted. + * @param {string} countryCallingFrom the ISO 3166-1 two-letter country code + * that denotes the foreign country where the call is being placed. + * @return {string} the formatted phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatOutOfCountryCallingNumber = + function(number, countryCallingFrom) { + + if (!this.isValidRegionCode_(countryCallingFrom)) { + return this.format(number, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL); + } + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + /** @type {string} */ + var regionCode = this.getRegionCodeForCountryCode(countryCode); + /** @type {string} */ + var nationalSignificantNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + if (!this.isValidRegionCode_(regionCode)) { + return nationalSignificantNumber; + } + if (countryCode == i18n.phonenumbers.PhoneNumberUtil.NANPA_COUNTRY_CODE_) { + if (this.isNANPACountry(countryCallingFrom)) { + // For NANPA countries, return the national format for these countries but + // prefix it with the country code. + return countryCode + ' ' + + this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL); + } + } else if (countryCode == this.getCountryCodeForRegion(countryCallingFrom)) { + // For countries that share a country calling code, the country code need not + // be dialled. This also applies when dialling within a country, so this if + // clause covers both these cases. Technically this is the case for dialling + // from la Reunion to other overseas departments of France (French Guiana, + // Martinique, Guadeloupe), but not vice versa - so we don't cover this edge + // case for now and for those cases return the version including country code. + // Details here: http://www.petitfute.com/voyage/225-info-pratiques-reunion + return this.format(number, + i18n.phonenumbers.PhoneNumberFormat.NATIONAL); + } + /** @type {string} */ + var formattedNationalNumber = + this.formatNationalNumber_(nationalSignificantNumber, regionCode, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL); + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(countryCallingFrom); + /** @type {string} */ + var internationalPrefix = metadata.getInternationalPrefixOrDefault(); + + // For countries that have multiple international prefixes, the international + // format of the number is returned, unless there is a preferred international + // prefix. + /** @type {string} */ + var internationalPrefixForFormatting = ''; + if (i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + i18n.phonenumbers.PhoneNumberUtil.UNIQUE_INTERNATIONAL_PREFIX_, + internationalPrefix)) { + internationalPrefixForFormatting = internationalPrefix; + } else if (metadata.hasPreferredInternationalPrefix()) { + internationalPrefixForFormatting = + metadata.getPreferredInternationalPrefixOrDefault(); + } + + /** @type {!goog.string.StringBuffer} */ + var formattedNumber = new goog.string.StringBuffer(formattedNationalNumber); + this.maybeGetFormattedExtension_(number, regionCode, formattedNumber); + if (internationalPrefixForFormatting.length > 0) { + return internationalPrefixForFormatting + ' ' + countryCode + ' ' + + formattedNumber.toString(); + } else { + this.formatNumberByFormat_(countryCode, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL, formattedNumber); + } + return formattedNumber.toString(); +}; + +/** + * Formats a phone number using the original phone number format that the number + * is parsed from. The original format is embedded in the country_code_source + * field of the PhoneNumber object passed in. If such information is missing, + * the number will be formatted into the NATIONAL format by default. + * + * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber that needs to + * be formatted in its original number format. + * @param {string} countryCallingFrom the country whose IDD needs to be prefixed + * if the original number has one. + * @return {string} the formatted phone number in its original number format. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatInOriginalFormat = + function(number, countryCallingFrom) { + + if (!number.hasCountryCodeSource()) { + return this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL); + } + switch (number.getCountryCodeSource()) { + case i18n.phonenumbers.PhoneNumber.CountryCodeSource + .FROM_NUMBER_WITH_PLUS_SIGN: + return this.format(number, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL); + case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD: + return this.formatOutOfCountryCallingNumber(number, countryCallingFrom); + case i18n.phonenumbers.PhoneNumber.CountryCodeSource + .FROM_NUMBER_WITHOUT_PLUS_SIGN: + return this.format(number, + i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL).substring(1); + case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY: + default: + return this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL); + } +}; + +/** + * Gets the national significant number of the a phone number. Note a national + * significant number doesn't contain a national prefix or any formatting. + * + * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber object for + * which the national significant number is needed. + * @return {string} the national significant number of the PhoneNumber object + * passed in. + */ +i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber = + function(number) { + + // The leading zero in the national (significant) number of an Italian phone + // number has a special meaning. Unlike the rest of the world, it indicates + // the number is a landline number. There have been plans to migrate landline + // numbers to start with the digit two since December 2000, but it has not yet + // happened. See http://en.wikipedia.org/wiki/%2B39 for more details. + // Other countries such as Cote d'Ivoire and Gabon use this for their mobile + // numbers. + /** @type {string} */ + var nationalNumber = '' + number.getNationalNumber(); + if (number.hasItalianLeadingZero() && number.getItalianLeadingZero() && + i18n.phonenumbers.PhoneNumberUtil.isLeadingZeroCountry( + number.getCountryCodeOrDefault())) { + return '0' + nationalNumber; + } + return nationalNumber; +}; + +/** + * A helper function that is used by format and formatByPattern. + * + * @param {number} countryCode the country calling code. + * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the + * phone number should be formatted into. + * @param {!goog.string.StringBuffer} formattedNumber the formatted phone + * number. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatNumberByFormat_ = + function(countryCode, numberFormat, formattedNumber) { + + switch (numberFormat) { + case i18n.phonenumbers.PhoneNumberFormat.E164: + /** @type {string} */ + var a = formattedNumber.toString(); + formattedNumber.clear(); + formattedNumber.append(i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + + countryCode + a); + return; + case i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL: + a = formattedNumber.toString(); + formattedNumber.clear(); + formattedNumber.append(i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + + countryCode + ' ' + a); + return; + case i18n.phonenumbers.PhoneNumberFormat.NATIONAL: + default: + return; + } +}; + +/** + * Note in some countries, the national number can be written in two completely + * different ways depending on whether it forms part of the NATIONAL format or + * INTERNATIONAL format. The numberFormat parameter here is used to specify + * which format to use for those cases. If a carrierCode is specified, this will + * be inserted into the formatted string to replace $CC. + * + * @param {string} number a string of characters representing a phone number. + * @param {string} regionCode the ISO 3166-1 two-letter country code. + * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the + * phone number should be formatted into. + * @param {string=} opt_carrierCode + * @return {string} the formatted phone number. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatNationalNumber_ = + function(number, regionCode, numberFormat, opt_carrierCode) { + + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + /** @type {Array.} */ + var intlNumberFormats = metadata.intlNumberFormatArray(); + // When the intlNumberFormats exists, we use that to format national number + // for the INTERNATIONAL format instead of using the numberDesc.numberFormats. + /** @type {Array.} */ + var availableFormats = + (intlNumberFormats.length == 0 || + numberFormat == i18n.phonenumbers.PhoneNumberFormat.NATIONAL) ? + metadata.numberFormatArray() : metadata.intlNumberFormatArray(); + return this.formatAccordingToFormats_(number, availableFormats, numberFormat, + opt_carrierCode); +}; + +/** + * Note that carrierCode is optional - if NULL or an empty string, no carrier + * code replacement will take place. Carrier code replacement occurs before + * national prefix replacement. + * + * @param {string} nationalNumber a string of characters representing a phone + * number. + * @param {Array.} availableFormats the + * available formats the phone number could be formatted into. + * @param {i18n.phonenumbers.PhoneNumberFormat} numberFormat the format the + * phone number should be formatted into. + * @param {string=} opt_carrierCode + * @return {string} the formatted phone number. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.formatAccordingToFormats_ = + function(nationalNumber, availableFormats, numberFormat, opt_carrierCode) { + + /** @type {i18n.phonenumbers.NumberFormat} */ + var numFormat; + /** @type {number} */ + var l = availableFormats.length; + for (var i = 0; i < l; ++i) { + numFormat = availableFormats[i]; + if (!numFormat.hasLeadingDigits() || + nationalNumber.search(numFormat.getLeadingDigits()) == 0) { + /** @type {RegExp} */ + var patternToMatch = new RegExp(numFormat.getPattern()); + /** @type {string} */ + var numberFormatRule = numFormat.getFormatOrDefault(); + if (i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_(patternToMatch, + nationalNumber)) { + if (opt_carrierCode != null && opt_carrierCode.length > 0) { + /** @type {string} */ + var domesticCarrierCodeFormattingRule = + numFormat.getDomesticCarrierCodeFormattingRuleOrDefault(); + if (domesticCarrierCodeFormattingRule.length > 0) { + // Replace the $CC in the formatting rule with the desired carrier + // code. + /** @type {string} */ + var carrierCodeFormattingRule = domesticCarrierCodeFormattingRule + .replace(i18n.phonenumbers.PhoneNumberUtil.CC_PATTERN_, + opt_carrierCode); + // Now replace the $FG in the formatting rule with the first group + // and the carrier code combined in the appropriate way. + numberFormatRule = numberFormatRule.replace( + i18n.phonenumbers.PhoneNumberUtil.FIRST_GROUP_PATTERN_, + carrierCodeFormattingRule); + } + } + /** @type {string} */ + var nationalPrefixFormattingRule = + numFormat.getNationalPrefixFormattingRuleOrDefault(); + if (numberFormat == i18n.phonenumbers.PhoneNumberFormat.NATIONAL && + nationalPrefixFormattingRule != null && + nationalPrefixFormattingRule.length > 0) { + return nationalNumber.replace(patternToMatch, numberFormatRule + .replace(i18n.phonenumbers.PhoneNumberUtil.FIRST_GROUP_PATTERN_, + nationalPrefixFormattingRule)); + } else { + return nationalNumber.replace(patternToMatch, numberFormatRule); + } + } + } + } + + // If no pattern above is matched, we format the number as a whole. + return nationalNumber; +}; + +/** + * Gets a valid number for the specified country. + * + * @param {string} regionCode the ISO 3166-1 two-letter country code that + * denotes the country for which an example number is needed. + * @return {i18n.phonenumbers.PhoneNumber} a valid fixed-line number for the + * specified country. Returns null when the metadata does not contain such + * information. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumber = + function(regionCode) { + + return this.getExampleNumberForType(regionCode, + i18n.phonenumbers.PhoneNumberType.FIXED_LINE); +}; + +/** + * Gets a valid number, if any, for the specified country and number type. + * + * @param {string} regionCode the ISO 3166-1 two-letter country code that + * denotes the country for which an example number is needed. + * @param {i18n.phonenumbers.PhoneNumberType} type the type of number that is + * needed. + * @return {i18n.phonenumbers.PhoneNumber} a valid number for the specified + * country and type. Returns null when the metadata does not contain such + * information. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumberForType = + function(regionCode, type) { + + /** @type {i18n.phonenumbers.PhoneNumberDesc} */ + var desc = this.getNumberDescByType_( + this.getMetadataForRegion(regionCode), type); + try { + if (desc.hasExampleNumber()) { + return this.parse(desc.getExampleNumberOrDefault(), regionCode); + } + } catch (e) { + } + return null; +}; + +/** + * Appends the formatted extension of a phone number to formattedNumber, if the + * phone number had an extension specified. + * + * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber that might have + * an extension. + * @param {string} regionCode the ISO 3166-1 two-letter country code. + * @param {!goog.string.StringBuffer} formattedNumber the formatted phone + * number. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.maybeGetFormattedExtension_ = + function(number, regionCode, formattedNumber) { + + if (number.hasExtension()) { + // Formats the extension part of the phone number by prefixing it with the + // appropriate extension prefix. This will be the default extension prefix, + // unless overridden by a preferred extension prefix for this country. + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + if (metadata.hasPreferredExtnPrefix()) { + formattedNumber.append(metadata.getPreferredExtnPrefix()); + } else { + formattedNumber.append( + i18n.phonenumbers.PhoneNumberUtil.DEFAULT_EXTN_PREFIX_); + } + formattedNumber.append(number.getExtension()); + } +}; + +/** + * @param {i18n.phonenumbers.PhoneMetadata} metadata + * @param {i18n.phonenumbers.PhoneNumberType} type + * @return {i18n.phonenumbers.PhoneNumberDesc} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberDescByType_ = + function(metadata, type) { + + switch (type) { + case i18n.phonenumbers.PhoneNumberType.PREMIUM_RATE: + return metadata.getPremiumRate(); + case i18n.phonenumbers.PhoneNumberType.TOLL_FREE: + return metadata.getTollFree(); + case i18n.phonenumbers.PhoneNumberType.MOBILE: + return metadata.getMobile(); + case i18n.phonenumbers.PhoneNumberType.FIXED_LINE: + case i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE: + return metadata.getFixedLine(); + case i18n.phonenumbers.PhoneNumberType.SHARED_COST: + return metadata.getSharedCost(); + case i18n.phonenumbers.PhoneNumberType.VOIP: + return metadata.getVoip(); + case i18n.phonenumbers.PhoneNumberType.PERSONAL_NUMBER: + return metadata.getPersonalNumber(); + default: + return metadata.getGeneralDesc(); + } +}; + +/** + * Gets the type of a phone number. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want + * to know the type. + * @return {i18n.phonenumbers.PhoneNumberType} the type of the phone number. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberType = + function(number) { + + /** @type {string} */ + var regionCode = /** @type {string} */ (this.getRegionCodeForNumber(number)); + if (!this.isValidRegionCode_(regionCode)) { + return i18n.phonenumbers.PhoneNumberType.UNKNOWN; + } + /** @type {string} */ + var nationalSignificantNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + return this.getNumberTypeHelper_(nationalSignificantNumber, + this.getMetadataForRegion(regionCode)); +}; + +/** + * @param {string} nationalNumber + * @param {i18n.phonenumbers.PhoneMetadata} metadata + * @return {i18n.phonenumbers.PhoneNumberType} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberTypeHelper_ = + function(nationalNumber, metadata) { + + /** @type {i18n.phonenumbers.PhoneNumberDesc} */ + var generalNumberDesc = metadata.getGeneralDesc(); + if (!generalNumberDesc.hasNationalNumberPattern() || + !this.isNumberMatchingDesc_(nationalNumber, generalNumberDesc)) { + return i18n.phonenumbers.PhoneNumberType.UNKNOWN; + } + + if (this.isNumberMatchingDesc_(nationalNumber, metadata.getPremiumRate())) { + return i18n.phonenumbers.PhoneNumberType.PREMIUM_RATE; + } + if (this.isNumberMatchingDesc_(nationalNumber, metadata.getTollFree())) { + return i18n.phonenumbers.PhoneNumberType.TOLL_FREE; + } + if (this.isNumberMatchingDesc_(nationalNumber, metadata.getSharedCost())) { + return i18n.phonenumbers.PhoneNumberType.SHARED_COST; + } + if (this.isNumberMatchingDesc_(nationalNumber, metadata.getVoip())) { + return i18n.phonenumbers.PhoneNumberType.VOIP; + } + if (this.isNumberMatchingDesc_(nationalNumber, + metadata.getPersonalNumber())) { + return i18n.phonenumbers.PhoneNumberType.PERSONAL_NUMBER; + } + + /** @type {boolean} */ + var isFixedLine = this.isNumberMatchingDesc_(nationalNumber, metadata + .getFixedLine()); + if (isFixedLine) { + if (metadata.getSameMobileAndFixedLinePattern()) { + return i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE; + } else if (this.isNumberMatchingDesc_(nationalNumber, + metadata.getMobile())) { + return i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE; + } + return i18n.phonenumbers.PhoneNumberType.FIXED_LINE; + } + // Otherwise, test to see if the number is mobile. Only do this if certain + // that the patterns for mobile and fixed line aren't the same. + if (!metadata.getSameMobileAndFixedLinePattern() && + this.isNumberMatchingDesc_(nationalNumber, metadata.getMobile())) { + return i18n.phonenumbers.PhoneNumberType.MOBILE; + } + return i18n.phonenumbers.PhoneNumberType.UNKNOWN; +}; + +/** + * @param {?string} regionCode + * @return {i18n.phonenumbers.PhoneMetadata} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getMetadataForRegion = + function(regionCode) { + + if (regionCode == null) { + return null; + } + regionCode = regionCode.toUpperCase(); + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.countryToMetadata[regionCode]; + if (metadata == null) { + /** @type {goog.proto2.PbLiteSerializer} */ + var serializer = new goog.proto2.PbLiteSerializer(); + /** @type {Array} */ + var metadataSerialized = + i18n.phonenumbers.metadata.countryToMetadata[regionCode]; + if (metadataSerialized == null) { + return null; + } + metadata = /** @type {i18n.phonenumbers.PhoneMetadata} */ ( + serializer.deserialize(i18n.phonenumbers.PhoneMetadata.getDescriptor(), + metadataSerialized)); + this.countryToMetadata[regionCode] = metadata; + } + return metadata; +}; + +/** + * @param {string} nationalNumber + * @param {i18n.phonenumbers.PhoneNumberDesc} numberDesc + * @return {boolean} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatchingDesc_ = + function(nationalNumber, numberDesc) { + + return i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + numberDesc.getPossibleNumberPattern(), nationalNumber) && + i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + numberDesc.getNationalNumberPattern(), nationalNumber); +}; + +/** + * Tests whether a phone number matches a valid pattern. Note this doesn't + * verify the number is actually in use, which is impossible to tell by just + * looking at a number itself. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want + * to validate. + * @return {boolean} a boolean that indicates whether the number is of a valid + * pattern. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumber = function(number) { + /** @type {string} */ + var regionCode = /** @type {string} */ (this.getRegionCodeForNumber(number)); + return this.isValidRegionCode_(regionCode) && + this.isValidNumberForRegion(number, regionCode); +}; + +/** + * Tests whether a phone number is valid for a certain region. Note this doesn't + * verify the number is actually in use, which is impossible to tell by just + * looking at a number itself. If the country code is not the same as the + * country code for the region, this immediately exits with false. After this, + * the specific number pattern rules for the region are examined. This is useful + * for determining for example whether a particular number is valid for Canada, + * rather than just a valid NANPA number. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number that we want + * to validate. + * @param {string} regionCode the ISO 3166-1 two-letter country code that + * denotes the region/country that we want to validate the phone number for. + * @return {boolean} a boolean that indicates whether the number is of a valid + * pattern. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumberForRegion = + function(number, regionCode) { + + if (number.getCountryCodeOrDefault() != + this.getCountryCodeForRegion(regionCode)) { + return false; + } + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + /** @type {i18n.phonenumbers.PhoneNumberDesc} */ + var generalNumDesc = metadata.getGeneralDesc(); + /** @type {string} */ + var nationalSignificantNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + + // For countries where we don't have metadata for PhoneNumberDesc, we treat + // any number passed in as a valid number if its national significant number + // is between the minimum and maximum lengths defined by ITU for a national + // significant number. + if (!generalNumDesc.hasNationalNumberPattern()) { + /** @type {number} */ + var numberLength = nationalSignificantNumber.length; + return numberLength > + i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ && + numberLength <= i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_; + } + return this.getNumberTypeHelper_(nationalSignificantNumber, metadata) != + i18n.phonenumbers.PhoneNumberType.UNKNOWN; +}; + +/** + * Returns the country/region where a phone number is from. This could be used + * for geo-coding in the country/region level. + * + * @param {i18n.phonenumbers.PhoneNumber} number the phone number whose origin + * we want to know. + * @return {?string} the country/region where the phone number is from, or null + * if no country matches this calling code. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForNumber = + function(number) { + + if (number == null) { + return null; + } + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + /** @type {Array.} */ + var regions = + i18n.phonenumbers.metadata.countryCodeToRegionCodeMap[countryCode]; + if (regions == null) { + return null; + } + if (regions.length == 1) { + return regions[0]; + } else { + return this.getRegionCodeForNumberFromRegionList_(number, regions); + } +}; + +/** + * @param {i18n.phonenumbers.PhoneNumber} number + * @param {Array.} regionCodes + * @return {?string} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype. + getRegionCodeForNumberFromRegionList_ = function(number, regionCodes) { + + /** @type {string} */ + var nationalNumber = '' + number.getNationalNumber(); + /** @type {string} */ + var regionCode; + /** @type {number} */ + var regionCodesLength = regionCodes.length; + for (var i = 0; i < regionCodesLength; i++) { + regionCode = regionCodes[i]; + // If leadingDigits is present, use this. Otherwise, do full validation. + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + if (metadata.hasLeadingDigits()) { + if (nationalNumber.search(metadata.getLeadingDigits()) == 0) { + return regionCode; + } + } else if (this.getNumberTypeHelper_(nationalNumber, metadata) != + i18n.phonenumbers.PhoneNumberType.UNKNOWN) { + return regionCode; + } + } + return null; +}; + +/** + * Returns the region code that matches the specific country code. In the case + * of no region code being found, ZZ will be returned. In the case of multiple + * regions, the one designated in the metadata as the "main" country for this + * calling code will be returned. + * + * @param {number} countryCode the country calling code. + * @return {string} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForCountryCode = + function(countryCode) { + + /** @type {Array.} */ + var regionCodes = + i18n.phonenumbers.metadata.countryCodeToRegionCodeMap[countryCode]; + return regionCodes == null ? 'ZZ' : regionCodes[0]; +}; + +/** + * Returns the country calling code for a specific region. For example, this + * would be 1 for the United States, and 64 for New Zealand. + * + * @param {?string} regionCode the ISO 3166-1 two-letter country code that + * denotes the country/region that we want to get the country code for. + * @return {number} the country calling code for the country/region denoted by + * regionCode. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.getCountryCodeForRegion = + function(regionCode) { + + if (!this.isValidRegionCode_(regionCode)) { + return 0; + } + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = this.getMetadataForRegion(regionCode); + if (metadata == null) { + return 0; + } + return metadata.getCountryCodeOrDefault(); +}; + +/** + * Check if a country is one of the countries under the North American Numbering + * Plan Administration (NANPA). + * + * @param {string} regionCode the ISO 3166-1 two-letter country code. + * @return {boolean} true if regionCode is one of the countries under NANPA. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isNANPACountry = + function(regionCode) { + + return goog.array.contains( + i18n.phonenumbers.metadata.countryCodeToRegionCodeMap[ + i18n.phonenumbers.PhoneNumberUtil.NANPA_COUNTRY_CODE_], + regionCode.toUpperCase()); +}; + +/** + * Convenience wrapper around isPossibleNumberWithReason. Instead of returning + * the reason for failure, this method returns a boolean value. + * + * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be + * checked. + * @return {boolean} true if the number is possible. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumber = + function(number) { + + return this.isPossibleNumberWithReason(number) == + i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE; +}; + +/** + * Check whether countryCode represents the country calling code from a country + * whose national significant number could contain a leading zero. An example of + * such a country is Italy. + * + * @param {number} countryCode the country calling code. + * @return {boolean} + */ +i18n.phonenumbers.PhoneNumberUtil.isLeadingZeroCountry = function(countryCode) { + return countryCode in + i18n.phonenumbers.PhoneNumberUtil.LEADING_ZERO_COUNTRIES_; +}; + +/** + * Check whether a phone number is a possible number. It provides a more lenient + * check than isValidNumber in the following sense: + * + * 1. It only checks the length of phone numbers. In particular, it doesn't + * check starting digits of the number. + * + * 2. It doesn't attempt to figure out the type of the number, but uses general + * rules which applies to all types of phone numbers in a country. Therefore, it + * is much faster than isValidNumber. + * + * 3. For fixed line numbers, many countries have the concept of area code, + * which together with subscriber number constitute the national significant + * number. It is sometimes okay to dial the subscriber number only when dialing + * in the same area. This function will return true if the + * subscriber-number-only version is passed in. On the other hand, because + * isValidNumber validates using information on both starting digits (for fixed + * line numbers, that would most likely be area codes) and length (obviously + * includes the length of area codes for fixed line numbers), it will return + * false for the subscriber-number-only version. + * + * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be + * checked. + * @return {i18n.phonenumbers.PhoneNumberUtil.ValidationResult} a + * ValidationResult object which indicates whether the number is possible. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberWithReason = + function(number) { + + /** @type {number} */ + var countryCode = number.getCountryCodeOrDefault(); + // Note: For Russian Fed and NANPA numbers, we just use the rules from the + // default region (US or Russia) since the getRegionCodeForNumber will not + // work if the number is possible but not valid. This would need to be + // revisited if the possible number pattern ever differed between various + // countries within those plans. + /** @type {string} */ + var regionCode = this.getRegionCodeForCountryCode(countryCode); + if (!this.isValidRegionCode_(regionCode)) { + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult + .INVALID_COUNTRY_CODE; + } + /** @type {string} */ + var nationalNumber = + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number); + /** @type {i18n.phonenumbers.PhoneNumberDesc} */ + var generalNumDesc = this.getMetadataForRegion(regionCode).getGeneralDesc(); + // Handling case of numbers with no metadata. + if (!generalNumDesc.hasNationalNumberPattern()) { + /** @type {number} */ + var numberLength = nationalNumber.length; + if (numberLength < i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) { + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_SHORT; + } else if (numberLength > i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_) { + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG; + } else { + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE; + } + } + /** @type {string} */ + var possibleNumberPattern = + generalNumDesc.getPossibleNumberPatternOrDefault(); + /** @type {Array. } */ + var a = nationalNumber.match('^' + possibleNumberPattern); + /** @type {string} */ + var m = a ? a[0] : ''; + if (m.length > 0) { + return (m.length == nationalNumber.length) ? + i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE : + i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG; + } else { + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_SHORT; + } +}; + +/** + * Check whether a phone number is a possible number given a number in the form + * of a string, and the country where the number could be dialed from. It + * provides a more lenient check than isValidNumber. See + * isPossibleNumber(number) for details. + * + * This method first parses the number, then invokes + * isPossibleNumber(PhoneNumber number) with the resultant PhoneNumber object. + * + * @param {string} number the number that needs to be checked, in the form of a + * string. + * @param {string} countryDialingFrom the ISO 3166-1 two-letter country code + * that denotes the country that we are expecting the number to be dialed + * from. Note this is different from the country where the number brlongs. + * For example, the number +1 650 253 0000 is a number that belongs to US. + * When written in this form, it could be dialed from any country. When it + * is written as 00 1 650 253 0000, it could be dialed from any country + * which has international prefix 00. When it is written as + * 650 253 0000, it could only be dialed from US, and when written as + * 253 0000, it could only be dialed from US (Mountain View, CA, to be more + * specific). + * @return {boolean} true if the number is possible. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberString = + function(number, countryDialingFrom) { + + try { + return this.isPossibleNumber(this.parse(number, countryDialingFrom)); + } catch (e) { + return false; + } +}; + +/** + * Extracts country code from fullNumber, returns it and places the remaining + * number in nationalNumber. It assumes that the leading plus sign or IDD has + * already been removed. Returns 0 if fullNumber doesn't start with a valid + * country code, and leaves nationalNumber unmodified. + * + * @param {!goog.string.StringBuffer} fullNumber + * @param {!goog.string.StringBuffer} nationalNumber + * @return {number} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.extractCountryCode = + function(fullNumber, nationalNumber) { + + /** @type {string} */ + var fullNumberStr = fullNumber.toString(); + /** @type {number} */ + var potentialCountryCode; + for (var i = 1; i <= 3; ++i) { + potentialCountryCode = parseInt(fullNumberStr.substring(0, i), 10); + if (potentialCountryCode in + i18n.phonenumbers.metadata.countryCodeToRegionCodeMap) { + nationalNumber.append(fullNumberStr.substring(i)); + return potentialCountryCode; + } + } + return 0; +}; + +/** + * Tries to extract a country code from a number. This method will return zero + * if no country code is considered to be present. Country codes are extracted + * in the following ways: + * - by stripping the international dialing prefix of the country the person is + * dialing from, if this is present in the number, and looking at the next + * digits + * - by stripping the '+' sign if present and then looking at the next digits + * - by comparing the start of the number and the country code of the default + * region. If the number is not considered possible for the numbering plan of + * the default region initially, but starts with the country code of this + * region, validation will be reattempted after stripping this country code. If + * this number is considered a possible number, then the first digits will be + * considered the country code and removed as such. + * + * It will throw a i18n.phonenumbers.Error if the number starts with a '+' but + * the country code supplied after this does not match that of any known + * country. + * + * @param {string} number non-normalized telephone number that we wish to + * extract a country code from - may begin with '+'. + * @param {i18n.phonenumbers.PhoneMetadata} defaultRegionMetadata metadata + * about the region this number may be from. + * @param {!goog.string.StringBuffer} nationalNumber a string buffer to store + * the national significant number in, in the case that a country code was + * extracted. The number is appended to any existing contents. If no country + * code was extracted, this will be left unchanged. + * @param {boolean} storeCountryCodeSource true if the country_code_source field + * of phoneNumber should be populated. + * @param {i18n.phonenumbers.PhoneNumber} phoneNumber the PhoneNumber object + * that needs to be populated with country code and country code source. + * Note the country code is always populated, whereas country code source is + * only populated when keepCountryCodeSource is true. + * @return {number} the country code extracted or 0 if none could be extracted. + * @throws {i18n.phonenumbers.Error} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.maybeExtractCountryCode = + function(number, defaultRegionMetadata, nationalNumber, + storeCountryCodeSource, phoneNumber) { + + if (number.length == 0) { + return 0; + } + /** @type {!goog.string.StringBuffer} */ + var fullNumber = new goog.string.StringBuffer(number); + // Set the default prefix to be something that will never match. + /** @type {?string} */ + var possibleCountryIddPrefix; + if (defaultRegionMetadata != null) { + possibleCountryIddPrefix = defaultRegionMetadata.getInternationalPrefix(); + } + if (possibleCountryIddPrefix == null) { + possibleCountryIddPrefix = 'NonMatch'; + } + + /** @type {i18n.phonenumbers.PhoneNumber.CountryCodeSource} */ + var countryCodeSource = this.maybeStripInternationalPrefixAndNormalize( + fullNumber, possibleCountryIddPrefix); + if (storeCountryCodeSource) { + phoneNumber.setCountryCodeSource(countryCodeSource); + } + if (countryCodeSource != + i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY) { + if (fullNumber.getLength() < + i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) { + throw i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD; + } + /** @type {number} */ + var potentialCountryCode = this.extractCountryCode(fullNumber, + nationalNumber); + if (potentialCountryCode != 0) { + phoneNumber.setCountryCode(potentialCountryCode); + return potentialCountryCode; + } + + // If this fails, they must be using a strange country code that we don't + // recognize, or that doesn't exist. + throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE; + } else if (defaultRegionMetadata != null) { + // Check to see if the number is valid for the default region already. If + // not, we check to see if the country code for the default region is + // present at the start of the number. + /** @type {RegExp} */ + var validNumberPattern = new RegExp(defaultRegionMetadata.getGeneralDesc() + .getNationalNumberPattern()); + if (!i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + validNumberPattern, fullNumber.toString())) { + /** @type {number} */ + var defaultCountryCode = defaultRegionMetadata.getCountryCodeOrDefault(); + /** @type {string} */ + var defaultCountryCodeString = '' + defaultCountryCode; + /** @type {string} */ + var normalizedNumber = fullNumber.toString(); + if (goog.string.startsWith(normalizedNumber, defaultCountryCodeString)) { + // If so, strip this, and see if the resultant number is valid. + /** @type {!goog.string.StringBuffer} */ + var potentialNationalNumber = new goog.string.StringBuffer( + normalizedNumber.substring(defaultCountryCodeString.length)); + this.maybeStripNationalPrefix(potentialNationalNumber, + defaultRegionMetadata.getNationalPrefixForParsing(), + defaultRegionMetadata.getNationalPrefixTransformRule(), + validNumberPattern); + /** @type {string} */ + var potentialNationalNumberStr = potentialNationalNumber.toString(); + if (i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_( + validNumberPattern, potentialNationalNumberStr)) { + nationalNumber.append(potentialNationalNumberStr); + if (storeCountryCodeSource) { + phoneNumber.setCountryCodeSource( + i18n.phonenumbers.PhoneNumber.CountryCodeSource + .FROM_NUMBER_WITHOUT_PLUS_SIGN); + } + phoneNumber.setCountryCode(defaultCountryCode); + return defaultCountryCode; + } + } + } + } + // No country code present. + phoneNumber.setCountryCode(0); + return 0; +}; + +/** + * Strips the IDD from the start of the number if present. Helper function used + * by maybeStripInternationalPrefixAndNormalize. + * + * @param {RegExp} iddPattern the regular expression for the international + * prefix. + * @param {!goog.string.StringBuffer} number the phone number that we wish to + * strip any international dialing prefix from. + * @return {boolean} true if an international prefix was present. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.parsePrefixAsIdd_ = + function(iddPattern, number) { + + /** @type {string} */ + var numberStr = number.toString(); + if (numberStr.search(iddPattern) == 0) { + /** @type {number} */ + var matchEnd = numberStr.match(iddPattern)[0].length; + /** @type {Array. } */ + var a = numberStr.substring(matchEnd).match( + i18n.phonenumbers.PhoneNumberUtil.CAPTURING_DIGIT_PATTERN_); + if (a && a[1] != null && a[1].length > 0) { + /** @type {string} */ + var normalizedGroup = i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_( + a[1], i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS, true); + if (normalizedGroup == '0') { + return false; + } + } + number.clear(); + number.append(numberStr.substring(matchEnd)); + return true; + } + return false; +}; + +/** + * Strips any international prefix (such as +, 00, 011) present in the number + * provided, normalizes the resulting number, and indicates if an international + * prefix was present. + * + * @param {!goog.string.StringBuffer} number the non-normalized telephone number + * that we wish to strip any international dialing prefix from. + * @param {string} possibleIddPrefix the international direct dialing prefix + * from the country we think this number may be dialed in. + * @return {i18n.phonenumbers.PhoneNumber.CountryCodeSource} the corresponding + * CountryCodeSource if an international dialing prefix could be removed + * from the number, otherwise CountryCodeSource.FROM_DEFAULT_COUNTRY if + * the number did not seem to be in international format. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype. + maybeStripInternationalPrefixAndNormalize = function(number, + possibleIddPrefix) { + /** @type {string} */ + var numberStr = number.toString(); + if (numberStr.length == 0) { + return i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY; + } + if (numberStr.charAt(0) == i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) { + // Can now normalize the rest of the number since we've consumed the "+" + // sign at the start. + number.clear(); + number.append( + i18n.phonenumbers.PhoneNumberUtil.normalize(numberStr.substring(1))); + return i18n.phonenumbers.PhoneNumber.CountryCodeSource + .FROM_NUMBER_WITH_PLUS_SIGN; + } + // Attempt to parse the first digits as an international prefix. + /** @type {RegExp} */ + var iddPattern = new RegExp(possibleIddPrefix); + if (this.parsePrefixAsIdd_(iddPattern, number)) { + i18n.phonenumbers.PhoneNumberUtil.normalizeSB_(number); + return i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD; + } + // If still not found, then try and normalize the number and then try again. + // This shouldn't be done before, since non-numeric characters (+ and ~) may + // legally be in the international prefix. + i18n.phonenumbers.PhoneNumberUtil.normalizeSB_(number); + return this.parsePrefixAsIdd_(iddPattern, number) ? + i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD : + i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY; +}; + +/** + * Strips any national prefix (such as 0, 1) present in the number provided. + * + * @param {!goog.string.StringBuffer} number the normalized telephone number + * that we wish to strip any national dialing prefix from. + * @param {?string} possibleNationalPrefix a regex that represents the national + * direct dialing prefix from the country we think this number may be dialed + * in. + * @param {?string} transformRule the string that specifies how number should be + * transformed according to the regex specified in possibleNationalPrefix. + * @param {RegExp} nationalNumberRule a regular expression that specifies what a + * valid phonenumber from this region should look like after any national + * prefix was stripped or transformed. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripNationalPrefix = + function(number, possibleNationalPrefix, transformRule, nationalNumberRule) { + + /** @type {string} */ + var numberStr = number.toString(); + /** @type {number} */ + var numberLength = numberStr.length; + if (numberLength == 0 || possibleNationalPrefix == null || + possibleNationalPrefix.length == 0) { + // Early return for numbers of zero length. + return; + } + // Attempt to parse the first digits as a national prefix. + /** @type {RegExp} */ + var re = new RegExp('^' + possibleNationalPrefix); + /** @type {Array.} */ + var m = re.exec(numberStr); + if (m) { + /** @type {string} */ + var transformedNumber; + // m[1] == null implies nothing was captured by the capturing groups in + // possibleNationalPrefix; therefore, no transformation is necessary, and + // we just remove the national prefix. + if (transformRule == null || transformRule.length == 0 || m[1] == null || + m[1].length == 0) { + transformedNumber = numberStr.substring(m[0].length); + } else { + transformedNumber = numberStr.replace(re, transformRule); + } + // Check that the resultant number is viable. If not, return. + if (!i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_(nationalNumberRule, + transformedNumber)) { + return; + } + number.clear(); + number.append(transformedNumber); + } +}; + +/** + * Strips any extension (as in, the part of the number dialled after the call is + * connected, usually indicated with extn, ext, x or similar) from the end of + * the number, and returns it. + * + * @param {!goog.string.StringBuffer} number the non-normalized telephone number + * that we wish to strip the extension from. + * @return {string} the phone extension. + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripExtension = + function(number) { + + /** @type {string} */ + var numberStr = number.toString(); + /** @type {number} */ + var mStart = + numberStr.search(i18n.phonenumbers.PhoneNumberUtil.EXTN_PATTERN_); + // If we find a potential extension, and the number preceding this is a viable + // number, we assume it is an extension. + if (mStart >= 0 && i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber( + numberStr.substring(0, mStart))) { + // The numbers are captured into groups in the regular expression. + /** @type {Array.} */ + var a = numberStr.match(i18n.phonenumbers.PhoneNumberUtil.EXTN_PATTERN_); + /** @type {number} */ + var aLength = a.length; + for (var i = 1; i < aLength; ++i) { + if (a[i] != null && a[i].length > 0) { + number.clear(); + number.append(numberStr.substring(0, mStart)); + return a[i]; + } + } + } + return ''; +}; + +/** + * Parses a string and returns it in proto buffer format. This method will throw + * a i18n.phonenumbers.Error if the number is not considered to be a possible + * number. Note that validation of whether the number is actually a valid number + * for a particular country/region is not performed. This can be done separately + * with isValidNumber. + * + * @param {string} numberToParse number that we are attempting to parse. This + * can contain formatting such as +, ( and -, as well as a phone number + * extension. + * @param {?string} defaultCountry the ISO 3166-1 two-letter country code that + * denotes the country that we are expecting the number to be from. This is + * only used if the number being parsed is not written in international + * format. The country code for the number in this case would be stored as + * that of the default country supplied. + * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled + * with the parsed number. + * @throws {i18n.phonenumbers.Error} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.parse = function(numberToParse, + defaultCountry) { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var phoneNumber = new i18n.phonenumbers.PhoneNumber(); + if (!this.isValidRegionCode_(defaultCountry)) { + if (numberToParse.charAt(0) != + i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) { + throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE; + } + } + this.parseHelper_(numberToParse, defaultCountry, false, phoneNumber); + return phoneNumber; +}; + +/** + * Parses a string and returns it in proto buffer format. This method differs + * from parse() in that it always populates the raw_input field of the protocol + * buffer with numberToParse as well as the country_code_source field. + * + * @param {string} numberToParse number that we are attempting to parse. This + * can contain formatting such as +, ( and -, as well as a phone number + * extension. + * @param {?string} defaultCountry the ISO 3166-1 two-letter country code that + * denotes the country that we are expecting the number to be from. This is + * only used if the number being parsed is not written in international + * format. The country code for the number in this case would be stored as + * that of the default country supplied. + * @param {i18n.phonenumbers.PhoneNumber=} opt_phoneNumber mutable PhoneNumber + * to decrease object creation when invoked many times. + * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled + * with the parsed number. + * @throws {i18n.phonenumbers.Error} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.parseAndKeepRawInput = + function(numberToParse, defaultCountry, opt_phoneNumber) { + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var phoneNumber = opt_phoneNumber != null ? + opt_phoneNumber : new i18n.phonenumbers.PhoneNumber(); + if (!this.isValidRegionCode_(defaultCountry)) { + if (numberToParse.charAt(0) != + i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) { + throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE; + } + } + this.parseHelper_(numberToParse, defaultCountry, true, phoneNumber); + return phoneNumber; +}; + +/** + * Parses a string and fills up the phoneNumber. This method is the same as the + * public parse() method, with the exception that it allows the default country + * to be null, for use by isNumberMatch(). + * + * @param {string} numberToParse number that we are attempting to parse. This + * can contain formatting such as +, ( and -, as well as a phone number + * extension. + * @param {?string} defaultCountry the ISO 3166-1 two-letter country code that + * denotes the country that we are expecting the number to be from. This is + * only used if the number being parsed is not written in international + * format. The country code for the number in this case would be stored as + * that of the default country supplied. + * @param {boolean} keepRawInput whether to populate the raw_input field of the + * phoneNumber with numberToParse. + * @param {i18n.phonenumbers.PhoneNumber} phoneNumber the PhoneNumber object to + * populate. + * @throws {i18n.phonenumbers.Error} + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.parseHelper_ = + function(numberToParse, defaultCountry, keepRawInput, phoneNumber) { + + // Extract a possible number from the string passed in (this strips leading + // characters that could not be the start of a phone number.) + /** @type {string} */ + var number = + i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber(numberToParse); + if (!i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber(number)) { + throw i18n.phonenumbers.Error.NOT_A_NUMBER; + } + + if (keepRawInput) { + phoneNumber.setRawInput(numberToParse); + } + /** @type {!goog.string.StringBuffer} */ + var nationalNumber = new goog.string.StringBuffer(number); + // Attempt to parse extension first, since it doesn't require + // country-specific data and we want to have the non-normalised number here. + /** @type {string} */ + var extension = this.maybeStripExtension(nationalNumber); + if (extension.length > 0) { + phoneNumber.setExtension(extension); + } + + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var countryMetadata = this.getMetadataForRegion(defaultCountry); + // Check to see if the number is given in international format so we know + // whether this number is from the default country or not. + /** @type {!goog.string.StringBuffer} */ + var normalizedNationalNumber = new goog.string.StringBuffer(); + /** @type {number} */ + var countryCode = this.maybeExtractCountryCode(nationalNumber.toString(), + countryMetadata, normalizedNationalNumber, keepRawInput, phoneNumber); + if (countryCode != 0) { + /** @type {string} */ + var phoneNumberRegion = this.getRegionCodeForCountryCode(countryCode); + if (phoneNumberRegion != defaultCountry) { + countryMetadata = this.getMetadataForRegion(phoneNumberRegion); + } + } else { + // If no extracted country code, use the region supplied instead. The + // national number is just the normalized version of the number we were + // given to parse. + i18n.phonenumbers.PhoneNumberUtil.normalizeSB_(nationalNumber); + normalizedNationalNumber.append(nationalNumber.toString()); + if (defaultCountry != null) { + countryCode = countryMetadata.getCountryCodeOrDefault(); + phoneNumber.setCountryCode(countryCode); + } else if (keepRawInput) { + phoneNumber.clearCountryCodeSource(); + } + } + if (normalizedNationalNumber.getLength() < + i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) { + throw i18n.phonenumbers.Error.TOO_SHORT_NSN; + } + + if (countryMetadata != null) { + /** @type {RegExp} */ + var validNumberPattern = + new RegExp(countryMetadata.getGeneralDesc().getNationalNumberPattern()); + this.maybeStripNationalPrefix(normalizedNationalNumber, countryMetadata + .getNationalPrefixForParsing(), countryMetadata + .getNationalPrefixTransformRule(), validNumberPattern); + } + /** @type {string} */ + var normalizedNationalNumberStr = normalizedNationalNumber.toString(); + /** @type {number} */ + var lengthOfNationalNumber = normalizedNationalNumberStr.length; + if (lengthOfNationalNumber < + i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) { + throw i18n.phonenumbers.Error.TOO_SHORT_NSN; + } + if (lengthOfNationalNumber > + i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_) { + throw i18n.phonenumbers.Error.TOO_LONG; + } + if (normalizedNationalNumberStr.charAt(0) == '0' && + i18n.phonenumbers.PhoneNumberUtil.isLeadingZeroCountry(countryCode)) { + phoneNumber.setItalianLeadingZero(true); + } + phoneNumber.setNationalNumber(parseInt(normalizedNationalNumberStr, 10)); +}; + +/** + * Takes two phone numbers and compares them for equality. + * + * Returns EXACT_MATCH if the country code, NSN, presence of a leading zero for + * Italian numbers and any extension present are the same. Returns NSN_MATCH if + * either or both has no country specified, and the NSNs and extensions are the + * same. Returns SHORT_NSN_MATCH if either or both has no country specified, or + * the country specified is the same, and one NSN could be a shorter version of + * the other number. This includes the case where one has an extension + * specified, and the other does not. Returns NO_MATCH otherwise. For example, + * the numbers +1 345 657 1234 and 657 1234 are a SHORT_NSN_MATCH. The numbers + * +1 345 657 1234 and 345 657 are a NO_MATCH. + * + * @param {i18n.phonenumbers.PhoneNumber|string} firstNumberIn first number to + * compare. If it is a string it can contain formatting, and can have + * country code specified with + at the start. + * @param {i18n.phonenumbers.PhoneNumber|string} secondNumberIn second number to + * compare. If it is a string it can contain formatting, and can have + * country code specified with + at the start. + * @return {i18n.phonenumbers.PhoneNumberUtil.MatchType} NO_MATCH, + * SHORT_NSN_MATCH, NSN_MATCH or EXACT_MATCH depending on the level of + * equality of the two numbers, described in the method definition. + * @throws {i18n.phonenumbers.Error} + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatch = + function(firstNumberIn, secondNumberIn) { + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var firstNumber = new i18n.phonenumbers.PhoneNumber(); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var secondNumber = new i18n.phonenumbers.PhoneNumber(); + // If the input arguements are strings parse them to a proto buffer format. + // Else make copies of the phone numbers so that the numbers passed in are not + // edited. + if (typeof firstNumberIn == 'string') { + this.parseHelper_(firstNumberIn, null, false, firstNumber); + } else { + firstNumber.values_ = goog.cloneObject(firstNumberIn.values_); + } + if (typeof secondNumberIn == 'string') { + this.parseHelper_(secondNumberIn, null, false, secondNumber); + } else { + secondNumber.values_ = goog.cloneObject(secondNumberIn.values_); + } + // First clear raw_input and country_code_source field and any empty-string + // extensions so that + // we can use the PhoneNumber.exactlySameAs() method. + firstNumber.clearRawInput(); + firstNumber.clearCountryCodeSource(); + secondNumber.clearRawInput(); + secondNumber.clearCountryCodeSource(); + if (firstNumber.hasExtension() && firstNumber.getExtension().length == 0) { + firstNumber.clearExtension(); + } + if (secondNumber.hasExtension() && secondNumber.getExtension().length == 0) { + secondNumber.clearExtension(); + } + + // Early exit if both had extensions and these are different. + if (firstNumber.hasExtension() && secondNumber.hasExtension() && + firstNumber.getExtension() != secondNumber.getExtension()) { + return i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH; + } + /** @type {number} */ + var firstNumberCountryCode = firstNumber.getCountryCodeOrDefault(); + /** @type {number} */ + var secondNumberCountryCode = secondNumber.getCountryCodeOrDefault(); + // Both had country code specified. + if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) { + if (firstNumber.exactlySameAs(secondNumber)) { + return i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH; + } else if (firstNumberCountryCode == secondNumberCountryCode && + this.isNationalNumberSuffixOfTheOther_(firstNumber, secondNumber)) { + // A SHORT_NSN_MATCH occurs if there is a difference because of the + // presence or absence of an 'Italian leading zero', the presence or + // absence of an extension, or one NSN being a shorter variant of the + // other. + return i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH; + } + // This is not a match. + return i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH; + } + // Checks cases where one or both country codes were not specified. To make + // equality checks easier, we first set the country codes to be equal. + firstNumber.setCountryCode(0); + secondNumber.setCountryCode(0); + // If all else was the same, then this is an NSN_MATCH. + if (firstNumber.exactlySameAs(secondNumber)) { + return i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH; + } + if (this.isNationalNumberSuffixOfTheOther_(firstNumber, secondNumber)) { + return i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH; + } + return i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH; +}; + +/** + * Returns true when one national number is the suffix of the other or both are + * the same. + * + * @param {i18n.phonenumbers.PhoneNumber} firstNumber the first PhoneNumber + * object. + * @param {i18n.phonenumbers.PhoneNumber} secondNumber the second PhoneNumber + * object. + * @return {boolean} true if one PhoneNumber is the suffix of the other one. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.prototype.isNationalNumberSuffixOfTheOther_ = + function(firstNumber, secondNumber) { + + /** @type {string} */ + var firstNumberNationalNumber = '' + firstNumber.getNationalNumber(); + /** @type {string} */ + var secondNumberNationalNumber = '' + secondNumber.getNationalNumber(); + // Note that endsWith returns true if the numbers are equal. + return goog.string.endsWith(firstNumberNationalNumber, + secondNumberNationalNumber) || + goog.string.endsWith(secondNumberNationalNumber, + firstNumberNationalNumber); +}; + +/** + * Check whether the entire input sequence can be matched against the regular + * expression. + * + * @param {RegExp|string} regex the regular expression to match against. + * @param {string} str the string to test. + * @return {boolean} true if str can be matched entirely against regex. + * @private + */ +i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_ = function(regex, str) { + /** @type {Array.} */ + var a = str.match(regex); + if (a && a[0].length == str.length) { + return true; + } + return false; +}; + +/** + * @param {i18n.phonenumbers.PhoneNumber} other + * @return {boolean} + */ +i18n.phonenumbers.PhoneNumber.prototype.exactlySameAs = function(other) { + return other != null && + this.getCountryCode() == other.getCountryCode() && + this.getNationalNumber() == other.getNationalNumber() && + this.getExtension() == other.getExtension() && + this.getItalianLeadingZero() == other.getItalianLeadingZero() && + this.getRawInput() == other.getRawInput() && + this.getCountryCodeSource() == other.getCountryCodeSource(); +}; + +/** + * @param {i18n.phonenumbers.PhoneNumberDesc} other + * @return {boolean} + */ +i18n.phonenumbers.PhoneNumberDesc.prototype.exactlySameAs = function(other) { + return other != null && + this.getNationalNumberPattern() == other.getNationalNumberPattern() && + this.getPossibleNumberPattern() == other.getPossibleNumberPattern() && + this.getExampleNumber() == other.getExampleNumber(); +}; diff --git a/javascript/i18n/phonenumbers/phonenumberutil_test.html b/javascript/i18n/phonenumbers/phonenumberutil_test.html new file mode 100644 index 000000000..a576ee735 --- /dev/null +++ b/javascript/i18n/phonenumbers/phonenumberutil_test.html @@ -0,0 +1,35 @@ + + + + + +libphonenumber Unit Tests - i18n.phonenumbers - phonenumberutil.js + + + + + + + + + + + diff --git a/javascript/i18n/phonenumbers/phonenumberutil_test.js b/javascript/i18n/phonenumbers/phonenumberutil_test.js new file mode 100644 index 000000000..5dfecd02e --- /dev/null +++ b/javascript/i18n/phonenumbers/phonenumberutil_test.js @@ -0,0 +1,2019 @@ +// Copyright (C) 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Unit tests for the PhoneNumberUtil. + * + * @author Nikolaos Trogkanis + */ + +goog.require('goog.testing.jsunit'); +goog.require('i18n.phonenumbers.PhoneNumberUtil'); + +/** @type {i18n.phonenumbers.PhoneNumberUtil} */ +var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); + +function testGetInstanceLoadUSMetadata() { + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = phoneUtil.getMetadataForRegion('US'); + assertEquals('US', metadata.getId()); + assertEquals(1, metadata.getCountryCode()); + assertEquals('011', metadata.getInternationalPrefix()); + assertFalse(metadata.hasNationalPrefix()); + assertEquals(2, metadata.numberFormatCount()); + assertEquals('(\\d{3})(\\d{3})(\\d{4})', + metadata.getNumberFormat(0).getPattern()); + assertEquals('$1 $2 $3', metadata.getNumberFormat(0).getFormat()); + assertEquals('[13-9]\\d{9}|2[0-35-9]\\d{8}', + metadata.getGeneralDesc().getNationalNumberPattern()); + assertEquals('\\d{7,10}', + metadata.getGeneralDesc().getPossibleNumberPattern()); + assertTrue(metadata.getGeneralDesc().exactlySameAs(metadata.getFixedLine())); + assertEquals('\\d{10}', + metadata.getTollFree().getPossibleNumberPattern()); + assertEquals('900\\d{7}', + metadata.getPremiumRate().getNationalNumberPattern()); + // No shared-cost data is available, so it should be initialised to 'NA'. + assertEquals('NA', metadata.getSharedCost().getNationalNumberPattern()); + assertEquals('NA', metadata.getSharedCost().getPossibleNumberPattern()); +} + +function testGetInstanceLoadDEMetadata() { + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = phoneUtil.getMetadataForRegion('DE'); + assertEquals('DE', metadata.getId()); + assertEquals(49, metadata.getCountryCode()); + assertEquals('00', metadata.getInternationalPrefix()); + assertEquals('0', metadata.getNationalPrefix()); + assertEquals(6, metadata.numberFormatCount()); + assertEquals('9009', metadata.getNumberFormat(5).getLeadingDigits()); + assertEquals('(\\d{3})(\\d{4})(\\d{4})', + metadata.getNumberFormat(5).getPattern()); + assertEquals('$1 $2 $3', metadata.getNumberFormat(5).getFormat()); + assertEquals('(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:[1-9]\\d|0[2-9]))\\d{3,8}', + metadata.getFixedLine().getNationalNumberPattern()); + assertEquals('\\d{2,14}', metadata.getFixedLine().getPossibleNumberPattern()); + assertEquals('30123456', metadata.getFixedLine().getExampleNumber()); + assertEquals('\\d{10}', metadata.getTollFree().getPossibleNumberPattern()); + assertEquals('900([135]\\d{6}|9\\d{7})', + metadata.getPremiumRate().getNationalNumberPattern()); +} + +function testGetInstanceLoadARMetadata() { + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = phoneUtil.getMetadataForRegion('AR'); + assertEquals('AR', metadata.getId()); + assertEquals(54, metadata.getCountryCode()); + assertEquals('00', metadata.getInternationalPrefix()); + assertEquals('0', metadata.getNationalPrefix()); + assertEquals('0(?:(11|343|3715)15)?', metadata.getNationalPrefixForParsing()); + assertEquals('9$1', metadata.getNationalPrefixTransformRule()); + assertEquals('$1 15 $2-$3', metadata.getNumberFormat(2).getFormat()); + assertEquals('9(\\d{4})(\\d{2})(\\d{4})', + metadata.getNumberFormat(3).getPattern()); + assertEquals('(9)(\\d{4})(\\d{2})(\\d{4})', + metadata.getIntlNumberFormat(3).getPattern()); + assertEquals('$1 $2 $3 $4', metadata.getIntlNumberFormat(3).getFormat()); +} + +function testGetLengthOfGeographicalAreaCode() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + // Google MTV, which has area code '650'. + number.setCountryCode(1); + number.setNationalNumber(6502530000); + assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // A North America toll-free number, which has no area code. + number.setCountryCode(1); + number.setNationalNumber(8002530000); + assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // An invalid US number (1 digit shorter), which has no area code. + number.setCountryCode(1); + number.setNationalNumber(650253000); + assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // Google London, which has area code '20'. + number.setCountryCode(44); + number.setNationalNumber(2070313000); + assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // A UK mobile phone, which has no area code. + number.setCountryCode(44); + number.setNationalNumber(7123456789); + assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // Google Buenos Aires, which has area code '11'. + number.setCountryCode(54); + number.setNationalNumber(1155303000); + assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // Google Sydney, which has area code '2'. + number.setCountryCode(61); + number.setNationalNumber(293744000); + assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(number)); + + // Google Singapore. Singapore has no area code and no national prefix. + number.setCountryCode(65); + number.setNationalNumber(65218000); + assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number)); +} + +function testGetNationalSignificantNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(6502530000); + assertEquals('6502530000', + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number)); + + // An Italian mobile number. + number.setCountryCode(39); + number.setNationalNumber(312345678); + assertEquals('312345678', + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number)); + + // An Italian fixed line number. + number.setCountryCode(39); + number.setNationalNumber(236618300); + number.setItalianLeadingZero(true); + assertEquals('0236618300', + i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number)); +} + +function testGetExampleNumber() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(30123456); + assertTrue(deNumber.exactlySameAs(phoneUtil.getExampleNumber('DE'))); + assertTrue(deNumber.exactlySameAs(phoneUtil.getExampleNumber('de'))); + + assertTrue(deNumber.exactlySameAs( + phoneUtil.getExampleNumberForType('DE', PNT.FIXED_LINE))); + assertNull(phoneUtil.getExampleNumberForType('DE', PNT.MOBILE)); + // For the US, the example number is placed under general description, and + // hence should be used for both fixed line and mobile, so neither of these + // should return null. + assertNotNull(phoneUtil.getExampleNumberForType('US', PNT.FIXED_LINE)); + assertNotNull(phoneUtil.getExampleNumberForType('US', PNT.MOBILE)); +} + +function testNormaliseRemovePunctuation() { + /** @type {string} */ + var inputNumber = '034-56&+#234'; + /** @type {string} */ + var expectedOutput = '03456234'; + assertEquals('Conversion did not correctly remove punctuation', + expectedOutput, + i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber)); +} + +function testNormaliseReplaceAlphaCharacters() { + /** @type {string} */ + var inputNumber = '034-I-am-HUNGRY'; + /** @type {string} */ + var expectedOutput = '034426486479'; + assertEquals('Conversion did not correctly replace alpha characters', + expectedOutput, + i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber)); +} + +function testNormaliseOtherDigits() { + /** @type {string} */ + var inputNumber = '\uFF125\u0665'; + /** @type {string} */ + var expectedOutput = '255'; + assertEquals('Conversion did not correctly replace non-latin digits', + expectedOutput, + i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber)); +} + +function testNormaliseStripAlphaCharacters() { + /** @type {string} */ + var inputNumber = '034-56&+a#234'; + /** @type {string} */ + var expectedOutput = '03456234'; + assertEquals('Conversion did not correctly remove alpha character', + expectedOutput, + i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly(inputNumber)); +} + +function testFormatUSNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertEquals('650 253 0000', + phoneUtil.format(usNumber, PNF.NATIONAL)); + assertEquals('+1 650 253 0000', + phoneUtil.format(usNumber, PNF.INTERNATIONAL)); + + usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(8002530000); + assertEquals('800 253 0000', + phoneUtil.format(usNumber, PNF.NATIONAL)); + assertEquals('+1 800 253 0000', + phoneUtil.format(usNumber, PNF.INTERNATIONAL)); + + usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(9002530000); + assertEquals('900 253 0000', + phoneUtil.format(usNumber, PNF.NATIONAL)); + assertEquals('+1 900 253 0000', + phoneUtil.format(usNumber, PNF.INTERNATIONAL)); +} + +function testFormatBSNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var bsNumber = new i18n.phonenumbers.PhoneNumber(); + bsNumber.setCountryCode(1); + bsNumber.setNationalNumber(2421234567); + assertEquals('242 123 4567', + phoneUtil.format(bsNumber, PNF.NATIONAL)); + assertEquals('+1 242 123 4567', + phoneUtil.format(bsNumber, PNF.INTERNATIONAL)); + + bsNumber = new i18n.phonenumbers.PhoneNumber(); + bsNumber.setCountryCode(1); + bsNumber.setNationalNumber(8002530000); + assertEquals('800 253 0000', + phoneUtil.format(bsNumber, PNF.NATIONAL)); + assertEquals('+1 800 253 0000', + phoneUtil.format(bsNumber, PNF.INTERNATIONAL)); + + bsNumber = new i18n.phonenumbers.PhoneNumber(); + bsNumber.setCountryCode(1); + bsNumber.setNationalNumber(9002530000); + assertEquals('900 253 0000', + phoneUtil.format(bsNumber, PNF.NATIONAL)); + assertEquals('+1 900 253 0000', + phoneUtil.format(bsNumber, PNF.INTERNATIONAL)); +} + +function testFormatGBNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(2087389353); + assertEquals('(020) 8738 9353', + phoneUtil.format(gbNumber, PNF.NATIONAL)); + assertEquals('+44 20 8738 9353', + phoneUtil.format(gbNumber, PNF.INTERNATIONAL)); + + gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(7912345678); + assertEquals('(07912) 345 678', + phoneUtil.format(gbNumber, PNF.NATIONAL)); + assertEquals('+44 7912 345 678', + phoneUtil.format(gbNumber, PNF.INTERNATIONAL)); +} + +function testFormatDENumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(301234); + assertEquals('030 1234', + phoneUtil.format(deNumber, PNF.NATIONAL)); + assertEquals('+49 30 1234', + phoneUtil.format(deNumber, PNF.INTERNATIONAL)); + + deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(291123); + assertEquals('0291 123', + phoneUtil.format(deNumber, PNF.NATIONAL)); + assertEquals('+49 291 123', + phoneUtil.format(deNumber, PNF.INTERNATIONAL)); + + deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(29112345678); + assertEquals('0291 12345678', + phoneUtil.format(deNumber, PNF.NATIONAL)); + assertEquals('+49 291 12345678', + phoneUtil.format(deNumber, PNF.INTERNATIONAL)); + + deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(9123123); + assertEquals('09123 123', + phoneUtil.format(deNumber, PNF.NATIONAL)); + assertEquals('+49 9123 123', + phoneUtil.format(deNumber, PNF.INTERNATIONAL)); + + deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(1234); + // Note this number is correctly formatted without national prefix. + // Most of the numbers that are treated as invalid numbers by the library are + // short numbers, and they are usually not dialed with national prefix. + assertEquals('1234', + phoneUtil.format(deNumber, PNF.NATIONAL)); + assertEquals('+49 1234', + phoneUtil.format(deNumber, PNF.INTERNATIONAL)); +} + +function testFormatITNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + assertEquals('02 3661 8300', + phoneUtil.format(itNumber, PNF.NATIONAL)); + assertEquals('+39 02 3661 8300', + phoneUtil.format(itNumber, PNF.INTERNATIONAL)); + assertEquals('+390236618300', + phoneUtil.format(itNumber, PNF.E164)); + + itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(345678901); + assertEquals('345 678 901', + phoneUtil.format(itNumber, PNF.NATIONAL)); + assertEquals('+39 345 678 901', + phoneUtil.format(itNumber, PNF.INTERNATIONAL)); + assertEquals('+39345678901', + phoneUtil.format(itNumber, PNF.E164)); +} + +function testFormatAUNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var auNumber = new i18n.phonenumbers.PhoneNumber(); + auNumber.setCountryCode(61); + auNumber.setNationalNumber(236618300); + assertEquals('02 3661 8300', + phoneUtil.format(auNumber, PNF.NATIONAL)); + assertEquals('+61 2 3661 8300', + phoneUtil.format(auNumber, PNF.INTERNATIONAL)); + assertEquals('+61236618300', + phoneUtil.format(auNumber, PNF.E164)); + + auNumber = new i18n.phonenumbers.PhoneNumber(); + auNumber.setCountryCode(61); + auNumber.setNationalNumber(1800123456); + assertEquals('1800 123 456', + phoneUtil.format(auNumber, PNF.NATIONAL)); + assertEquals('+61 1800 123 456', + phoneUtil.format(auNumber, PNF.INTERNATIONAL)); + assertEquals('+611800123456', + phoneUtil.format(auNumber, PNF.E164)); +} + +function testFormatARNumber() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(1187654321); + assertEquals('011 8765-4321', + phoneUtil.format(arNumber, PNF.NATIONAL)); + assertEquals('+54 11 8765-4321', + phoneUtil.format(arNumber, PNF.INTERNATIONAL)); + assertEquals('+541187654321', + phoneUtil.format(arNumber, PNF.E164)); + + arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(91187654321); + assertEquals('011 15 8765-4321', + phoneUtil.format(arNumber, PNF.NATIONAL)); + assertEquals('+54 9 11 8765 4321', + phoneUtil.format(arNumber, PNF.INTERNATIONAL)); + assertEquals('+5491187654321', + phoneUtil.format(arNumber, PNF.E164)); +} + +function testFormatOutOfCountryCallingNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(9002530000); + assertEquals('00 1 900 253 0000', + phoneUtil.formatOutOfCountryCallingNumber(usNumber, 'DE')); + + usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertEquals('1 650 253 0000', + phoneUtil.formatOutOfCountryCallingNumber(usNumber, 'BS')); + + assertEquals('0~0 1 650 253 0000', + phoneUtil.formatOutOfCountryCallingNumber(usNumber, 'PL')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(7912345678); + assertEquals('011 44 7912 345 678', + phoneUtil.formatOutOfCountryCallingNumber(gbNumber, 'US')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(1234); + assertEquals('00 49 1234', + phoneUtil.formatOutOfCountryCallingNumber(deNumber, 'GB')); + // Note this number is correctly formatted without national prefix. + // Most of the numbers that are treated as invalid numbers by the library are + // short numbers, and they are usually not dialed with national prefix. + assertEquals('1234', + phoneUtil.formatOutOfCountryCallingNumber(deNumber, 'DE')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + assertEquals('011 39 02 3661 8300', + phoneUtil.formatOutOfCountryCallingNumber(itNumber, 'US')); + assertEquals('02 3661 8300', + phoneUtil.formatOutOfCountryCallingNumber(itNumber, 'IT')); + assertEquals('+39 02 3661 8300', + phoneUtil.formatOutOfCountryCallingNumber(itNumber, 'SG')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var sgNumber = new i18n.phonenumbers.PhoneNumber(); + sgNumber.setCountryCode(65); + sgNumber.setNationalNumber(94777892); + assertEquals('9477 7892', + phoneUtil.formatOutOfCountryCallingNumber(sgNumber, 'SG')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(91187654321); + assertEquals('011 54 9 11 8765 4321', + phoneUtil.formatOutOfCountryCallingNumber(arNumber, 'US')); + + arNumber.setExtension('1234'); + assertEquals('011 54 9 11 8765 4321 ext. 1234', + phoneUtil.formatOutOfCountryCallingNumber(arNumber, 'US')); + assertEquals('0011 54 9 11 8765 4321 ext. 1234', + phoneUtil.formatOutOfCountryCallingNumber(arNumber, 'AU')); + assertEquals('011 15 8765-4321 ext. 1234', + phoneUtil.formatOutOfCountryCallingNumber(arNumber, 'AR')); + assertEquals('011 15 8765-4321 ext. 1234', + phoneUtil.formatOutOfCountryCallingNumber(arNumber, 'ar')); +} + +function testFormatOutOfCountryWithPreferredIntlPrefix() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + // This should use 0011, since that is the preferred international prefix + // (both 0011 and 0012 are accepted as possible international prefixes in our + // test metadta.) + assertEquals('0011 39 02 3661 8300', + phoneUtil.formatOutOfCountryCallingNumber(itNumber, 'AU')); +} + +function testFormatWithCarrierCode() { + // We only support this for AR in our test metadata. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(91234125678); + assertEquals('01234 12-5678', + phoneUtil.format(arNumber, + i18n.phonenumbers.PhoneNumberFormat.NATIONAL)); + // Test formatting with a carrier code. + assertEquals('01234 15 12-5678', + phoneUtil.formatNationalNumberWithCarrierCode(arNumber, '15')); + // Here the international rule is used, so no carrier code should be present. + assertEquals('+5491234125678', + phoneUtil.format(arNumber, + i18n.phonenumbers.PhoneNumberFormat.E164)); + // We don't support this for the US so there should be no change. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(4241231234); + assertEquals('424 123 1234', + phoneUtil.format(usNumber, + i18n.phonenumbers.PhoneNumberFormat.NATIONAL)); + assertEquals('424 123 1234', + phoneUtil.formatNationalNumberWithCarrierCode(usNumber, '15')); +} + +function testFormatByPattern() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + /** @type {i18n.phonenumbers.NumberFormat} */ + var newNumFormat = new i18n.phonenumbers.NumberFormat(); + newNumFormat.setPattern('(\\d{3})(\\d{3})(\\d{4})'); + newNumFormat.setFormat('($1) $2-$3'); + /** @type {Array.} */ + var newNumberFormats = []; + newNumberFormats[0] = newNumFormat; + + assertEquals('(650) 253-0000', + phoneUtil.formatByPattern(usNumber, + PNF.NATIONAL, + newNumberFormats)); + assertEquals('+1 (650) 253-0000', + phoneUtil.formatByPattern(usNumber, + PNF.INTERNATIONAL, + newNumberFormats)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + + newNumFormat.setPattern('(\\d{2})(\\d{5})(\\d{3})'); + newNumFormat.setFormat('$1-$2 $3'); + newNumberFormats[0] = newNumFormat; + + assertEquals('02-36618 300', + phoneUtil.formatByPattern(itNumber, + PNF.NATIONAL, + newNumberFormats)); + assertEquals('+39 02-36618 300', + phoneUtil.formatByPattern(itNumber, + PNF.INTERNATIONAL, + newNumberFormats)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(2012345678); + + newNumFormat.setNationalPrefixFormattingRule('$NP$FG'); + newNumFormat.setPattern('(\\d{2})(\\d{4})(\\d{4})'); + newNumFormat.setFormat('$1 $2 $3'); + newNumberFormats[0] = newNumFormat; + assertEquals('020 1234 5678', + phoneUtil.formatByPattern(gbNumber, + PNF.NATIONAL, + newNumberFormats)); + + newNumFormat.setNationalPrefixFormattingRule('($NP$FG)'); + newNumberFormats[0] = newNumFormat; + assertEquals('(020) 1234 5678', + phoneUtil.formatByPattern(gbNumber, + PNF.NATIONAL, + newNumberFormats)); + + newNumFormat.setNationalPrefixFormattingRule(''); + newNumberFormats[0] = newNumFormat; + assertEquals('20 1234 5678', + phoneUtil.formatByPattern(gbNumber, + PNF.NATIONAL, + newNumberFormats)); + + newNumFormat.setNationalPrefixFormattingRule(''); + newNumberFormats[0] = newNumFormat; + assertEquals('+44 20 1234 5678', + phoneUtil.formatByPattern(gbNumber, + PNF.INTERNATIONAL, + newNumberFormats)); +} + +function testFormatE164Number() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertEquals('+16502530000', phoneUtil.format(usNumber, PNF.E164)); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(301234); + assertEquals('+49301234', phoneUtil.format(deNumber, PNF.E164)); +} + +function testFormatNumberWithExtension() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + nzNumber.setExtension('1234'); + // Uses default extension prefix: + assertEquals('03-331 6005 ext. 1234', + phoneUtil.format(nzNumber, PNF.NATIONAL)); + // Extension prefix overridden in the territory information for the US: + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + usNumber.setExtension('4567'); + assertEquals('650 253 0000 extn. 4567', + phoneUtil.format(usNumber, PNF.NATIONAL)); +} + +function testFormatInOriginalFormat() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number1 = phoneUtil.parseAndKeepRawInput('+442087654321', 'GB'); + assertEquals('+44 20 8765 4321', + phoneUtil.formatInOriginalFormat(number1, 'GB')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number2 = phoneUtil.parseAndKeepRawInput('02087654321', 'GB'); + assertEquals('(020) 8765 4321', + phoneUtil.formatInOriginalFormat(number2, 'GB')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number3 = phoneUtil.parseAndKeepRawInput('011442087654321', 'US'); + assertEquals('011 44 20 8765 4321', + phoneUtil.formatInOriginalFormat(number3, 'US')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number4 = phoneUtil.parseAndKeepRawInput('442087654321', 'GB'); + assertEquals('44 20 8765 4321', + phoneUtil.formatInOriginalFormat(number4, 'GB')); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number5 = phoneUtil.parse('+442087654321', 'GB'); + assertEquals('(020) 8765 4321', + phoneUtil.formatInOriginalFormat(number5, 'GB')); +} + +function testIsPremiumRate() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var premiumRateNumber = new i18n.phonenumbers.PhoneNumber(); + + premiumRateNumber.setCountryCode(1); + premiumRateNumber.setNationalNumber(9004433030); + assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber)); + + premiumRateNumber = new i18n.phonenumbers.PhoneNumber(); + premiumRateNumber.setCountryCode(39); + premiumRateNumber.setNationalNumber(892123); + assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber)); + + premiumRateNumber = new i18n.phonenumbers.PhoneNumber(); + premiumRateNumber.setCountryCode(44); + premiumRateNumber.setNationalNumber(9187654321); + assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber)); + + premiumRateNumber = new i18n.phonenumbers.PhoneNumber(); + premiumRateNumber.setCountryCode(49); + premiumRateNumber.setNationalNumber(9001654321); + assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber)); + + premiumRateNumber = new i18n.phonenumbers.PhoneNumber(); + premiumRateNumber.setCountryCode(49); + premiumRateNumber.setNationalNumber(90091234567); + assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber)); +} + +function testIsTollFree() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var tollFreeNumber = new i18n.phonenumbers.PhoneNumber(); + + tollFreeNumber.setCountryCode(1); + tollFreeNumber.setNationalNumber(8881234567); + assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber)); + + tollFreeNumber = new i18n.phonenumbers.PhoneNumber(); + tollFreeNumber.setCountryCode(39); + tollFreeNumber.setNationalNumber(803123); + assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber)); + + tollFreeNumber = new i18n.phonenumbers.PhoneNumber(); + tollFreeNumber.setCountryCode(44); + tollFreeNumber.setNationalNumber(8012345678); + assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber)); + + tollFreeNumber = new i18n.phonenumbers.PhoneNumber(); + tollFreeNumber.setCountryCode(49); + tollFreeNumber.setNationalNumber(8001234567); + assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber)); +} + +function testIsMobile() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var mobileNumber = new i18n.phonenumbers.PhoneNumber(); + + // A Bahama mobile number + mobileNumber.setCountryCode(1); + mobileNumber.setNationalNumber(2423570000); + assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber)); + + mobileNumber = new i18n.phonenumbers.PhoneNumber(); + mobileNumber.setCountryCode(39); + mobileNumber.setNationalNumber(312345678); + assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber)); + + mobileNumber = new i18n.phonenumbers.PhoneNumber(); + mobileNumber.setCountryCode(44); + mobileNumber.setNationalNumber(7912345678); + assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber)); + + mobileNumber = new i18n.phonenumbers.PhoneNumber(); + mobileNumber.setCountryCode(49); + mobileNumber.setNationalNumber(15123456789); + assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber)); + + mobileNumber = new i18n.phonenumbers.PhoneNumber(); + mobileNumber.setCountryCode(54); + mobileNumber.setNationalNumber(91187654321); + assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber)); +} + +function testIsFixedLine() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var fixedLineNumber = new i18n.phonenumbers.PhoneNumber(); + + // A Bahama fixed-line number + fixedLineNumber.setCountryCode(1); + fixedLineNumber.setNationalNumber(2423651234); + assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(fixedLineNumber)); + + // An Italian fixed-line number + fixedLineNumber = new i18n.phonenumbers.PhoneNumber(); + fixedLineNumber.setCountryCode(39); + fixedLineNumber.setNationalNumber(236618300); + fixedLineNumber.setItalianLeadingZero(true); + assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(fixedLineNumber)); + + fixedLineNumber = new i18n.phonenumbers.PhoneNumber(); + fixedLineNumber.setCountryCode(44); + fixedLineNumber.setNationalNumber(2012345678); + assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(fixedLineNumber)); + + fixedLineNumber = new i18n.phonenumbers.PhoneNumber(); + fixedLineNumber.setCountryCode(49); + fixedLineNumber.setNationalNumber(301234); + assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(fixedLineNumber)); +} + +function testIsFixedLineAndMobile() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var fixedLineAndMobileNumber = new i18n.phonenumbers.PhoneNumber(); + fixedLineAndMobileNumber.setCountryCode(1); + fixedLineAndMobileNumber.setNationalNumber(6502531111); + assertEquals(PNT.FIXED_LINE_OR_MOBILE, + phoneUtil.getNumberType(fixedLineAndMobileNumber)); + + fixedLineAndMobileNumber = new i18n.phonenumbers.PhoneNumber(); + fixedLineAndMobileNumber.setCountryCode(54); + fixedLineAndMobileNumber.setNationalNumber(1987654321); + assertEquals(PNT.FIXED_LINE_OR_MOBILE, + phoneUtil.getNumberType(fixedLineAndMobileNumber)); +} + +function testIsSharedCost() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(8431231234); + assertEquals(PNT.SHARED_COST, phoneUtil.getNumberType(gbNumber)); +} + +function testIsVoip() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(5631231234); + assertEquals(PNT.VOIP, phoneUtil.getNumberType(gbNumber)); +} + +function testIsPersonalNumber() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(7031231234); + assertEquals(PNT.PERSONAL_NUMBER, phoneUtil.getNumberType(gbNumber)); +} + +function testIsUnknown() { + var PNT = i18n.phonenumbers.PhoneNumberType; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var unknownNumber = new i18n.phonenumbers.PhoneNumber(); + unknownNumber.setCountryCode(1); + unknownNumber.setNationalNumber(65025311111); + assertEquals(PNT.UNKNOWN, phoneUtil.getNumberType(unknownNumber)); +} + +function testIsValidNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertTrue(phoneUtil.isValidNumber(usNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + assertTrue(phoneUtil.isValidNumber(itNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(7912345678); + assertTrue(phoneUtil.isValidNumber(gbNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(21387835); + assertTrue(phoneUtil.isValidNumber(nzNumber)); +} + + +function testIsValidForRegion() { + // This number is valid for the Bahamas, but is not a valid US number. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var bsNumber = new i18n.phonenumbers.PhoneNumber(); + bsNumber.setCountryCode(1); + bsNumber.setNationalNumber(2423232345); + assertTrue(phoneUtil.isValidNumber(bsNumber)); + assertTrue(phoneUtil.isValidNumberForRegion(bsNumber, 'BS')); + assertTrue(phoneUtil.isValidNumberForRegion(bsNumber, 'bs')); + assertFalse(phoneUtil.isValidNumberForRegion(bsNumber, 'US')); + bsNumber.setNationalNumber(2421232345); + // This number is no longer valid. + assertFalse(phoneUtil.isValidNumber(bsNumber)); + + // La Mayotte and Reunion use 'leadingDigits' to differentiate them. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var reNumber = new i18n.phonenumbers.PhoneNumber(); + reNumber.setCountryCode(262); + reNumber.setNationalNumber(262123456); + assertTrue(phoneUtil.isValidNumber(reNumber)); + assertTrue(phoneUtil.isValidNumberForRegion(reNumber, 'RE')); + assertFalse(phoneUtil.isValidNumberForRegion(reNumber, 'YT')); + // Now change the number to be a number for La Mayotte. + reNumber.setNationalNumber(269601234); + assertTrue(phoneUtil.isValidNumberForRegion(reNumber, 'YT')); + assertFalse(phoneUtil.isValidNumberForRegion(reNumber, 'RE')); + // This number is no longer valid for La Reunion. + reNumber.setNationalNumber(269123456); + assertFalse(phoneUtil.isValidNumberForRegion(reNumber, 'YT')); + assertFalse(phoneUtil.isValidNumberForRegion(reNumber, 'RE')); + assertFalse(phoneUtil.isValidNumber(reNumber)); + // However, it should be recognised as from La Mayotte, since it is valid for + // this region. + assertEquals('YT', phoneUtil.getRegionCodeForNumber(reNumber)); + // This number is valid in both places. + reNumber.setNationalNumber(800123456); + assertTrue(phoneUtil.isValidNumberForRegion(reNumber, 'YT')); + assertTrue(phoneUtil.isValidNumberForRegion(reNumber, 'RE')); +} + +function testIsNotValidNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(2530000); + assertFalse(phoneUtil.isValidNumber(usNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(23661830000); + itNumber.setItalianLeadingZero(true); + assertFalse(phoneUtil.isValidNumber(itNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(791234567); + assertFalse(phoneUtil.isValidNumber(gbNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(1234); + assertFalse(phoneUtil.isValidNumber(deNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(3316005); + assertFalse(phoneUtil.isValidNumber(nzNumber)); +} + +function testGetRegionCodeForCountryCode() { + assertEquals('US', phoneUtil.getRegionCodeForCountryCode(1)); + assertEquals('GB', phoneUtil.getRegionCodeForCountryCode(44)); + assertEquals('DE', phoneUtil.getRegionCodeForCountryCode(49)); +} + +function testGetRegionCodeForNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var bsNumber = new i18n.phonenumbers.PhoneNumber(); + bsNumber.setCountryCode(1); + bsNumber.setNationalNumber(2423027000); + assertEquals('BS', phoneUtil.getRegionCodeForNumber(bsNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertEquals('US', phoneUtil.getRegionCodeForNumber(usNumber)); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var gbNumber = new i18n.phonenumbers.PhoneNumber(); + gbNumber.setCountryCode(44); + gbNumber.setNationalNumber(7912345678); + assertEquals('GB', phoneUtil.getRegionCodeForNumber(gbNumber)); +} + +function testGetCountryCodeForRegion() { + assertEquals(1, phoneUtil.getCountryCodeForRegion('US')); + assertEquals(64, phoneUtil.getCountryCodeForRegion('NZ')); + assertEquals(64, phoneUtil.getCountryCodeForRegion('nz')); + assertEquals(0, phoneUtil.getCountryCodeForRegion(null)); + assertEquals(0, phoneUtil.getCountryCodeForRegion('ZZ')); + // CS is already deprecated so the library doesn't support it. + assertEquals(0, phoneUtil.getCountryCodeForRegion('CS')); +} + +function testIsNANPACountry() { + assertTrue(phoneUtil.isNANPACountry('US')); + assertTrue(phoneUtil.isNANPACountry('BS')); + assertTrue(phoneUtil.isNANPACountry('bs')); +} + +function testIsPossibleNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(6502530000); + assertTrue(phoneUtil.isPossibleNumber(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(2530000); + assertTrue(phoneUtil.isPossibleNumber(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(44); + number.setNationalNumber(2070313000); + assertTrue(phoneUtil.isPossibleNumber(number)); + + assertTrue(phoneUtil.isPossibleNumberString('+1 650 253 0000', 'US')); + assertTrue(phoneUtil.isPossibleNumberString('+1 650 GOO OGLE', 'US')); + assertTrue(phoneUtil.isPossibleNumberString('(650) 253-0000', 'US')); + assertTrue(phoneUtil.isPossibleNumberString('253-0000', 'US')); + assertTrue(phoneUtil.isPossibleNumberString('+1 650 253 0000', 'GB')); + assertTrue(phoneUtil.isPossibleNumberString('+44 20 7031 3000', 'GB')); + assertTrue(phoneUtil.isPossibleNumberString('(020) 7031 3000', 'GB')); + assertTrue(phoneUtil.isPossibleNumberString('7031 3000', 'GB')); + assertTrue(phoneUtil.isPossibleNumberString('3331 6005', 'NZ')); + assertTrue(phoneUtil.isPossibleNumberString('3331 6005', 'nz')); +} + +function testIsPossibleNumberWithReason() { + var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult; + // FYI, national numbers for country code +1 that are within 7 to 10 digits + // are possible. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(6502530000); + assertEquals(VR.IS_POSSIBLE, + phoneUtil.isPossibleNumberWithReason(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(2530000); + assertEquals(VR.IS_POSSIBLE, + phoneUtil.isPossibleNumberWithReason(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(0); + number.setNationalNumber(2530000); + assertEquals(VR.INVALID_COUNTRY_CODE, + phoneUtil.isPossibleNumberWithReason(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(253000); + assertEquals(VR.TOO_SHORT, + phoneUtil.isPossibleNumberWithReason(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(65025300000); + assertEquals(VR.TOO_LONG, + phoneUtil.isPossibleNumberWithReason(number)); + + // Try with number that we don't have metadata for. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var adNumber = new i18n.phonenumbers.PhoneNumber(); + adNumber.setCountryCode(376); + adNumber.setNationalNumber(12345); + assertEquals(VR.IS_POSSIBLE, + phoneUtil.isPossibleNumberWithReason(adNumber)); + adNumber.setCountryCode(376); + adNumber.setNationalNumber(13); + assertEquals(VR.TOO_SHORT, + phoneUtil.isPossibleNumberWithReason(adNumber)); + adNumber.setCountryCode(376); + adNumber.setNationalNumber(1234567890123456); + assertEquals(VR.TOO_LONG, + phoneUtil.isPossibleNumberWithReason(adNumber)); +} + +function testIsNotPossibleNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(65025300000); + assertFalse(phoneUtil.isPossibleNumber(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(1); + number.setNationalNumber(253000); + assertFalse(phoneUtil.isPossibleNumber(number)); + + number = new i18n.phonenumbers.PhoneNumber(); + number.setCountryCode(44); + number.setNationalNumber(300); + assertFalse(phoneUtil.isPossibleNumber(number)); + + assertFalse(phoneUtil.isPossibleNumberString('+1 650 253 00000', 'US')); + assertFalse(phoneUtil.isPossibleNumberString('(650) 253-00000', 'US')); + assertFalse(phoneUtil.isPossibleNumberString('I want a Pizza', 'US')); + assertFalse(phoneUtil.isPossibleNumberString('253-000', 'US')); + assertFalse(phoneUtil.isPossibleNumberString('1 3000', 'GB')); + assertFalse(phoneUtil.isPossibleNumberString('+44 300', 'GB')); +} + +function testIsViablePhoneNumber() { + var isViable = i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber; + // Only one or two digits before strange non-possible punctuation. + assertFalse(isViable('12. March')); + assertFalse(isViable('1+1+1')); + assertFalse(isViable('80+0')); + assertFalse(isViable('00')); + // Three digits is viable. + assertTrue(isViable('111')); + // Alpha numbers. + assertTrue(isViable('0800-4-pizza')); + assertTrue(isViable('0800-4-PIZZA')); + // Only one or two digits before possible punctuation followed by more digits. + assertTrue(isViable('1\u300034')); + assertFalse(isViable('1\u30003+4')); + // Unicode variants of possible starting character and other allowed + // punctuation/digits. + assertTrue(isViable('\uFF081\uFF09\u30003456789')); + // Testing a leading + is okay. + assertTrue(isViable('+1\uFF09\u30003456789')); +} + +function testExtractPossibleNumber() { + var extract = i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber; + // Removes preceding funky punctuation and letters but leaves the rest + // untouched. + assertEquals('0800-345-600', extract('Tel:0800-345-600')); + assertEquals('0800 FOR PIZZA', extract('Tel:0800 FOR PIZZA')); + // Should not remove plus sign + assertEquals('+800-345-600', extract('Tel:+800-345-600')); + // Should recognise wide digits as possible start values. + assertEquals('\uFF10\uFF12\uFF13', extract('\uFF10\uFF12\uFF13')); + // Dashes are not possible start values and should be removed. + assertEquals('\uFF11\uFF12\uFF13', extract('Num-\uFF11\uFF12\uFF13')); + // If not possible number present, return empty string. + assertEquals('', extract('Num-....')); + // Leading brackets are stripped - these are not used when parsing. + assertEquals('650) 253-0000', extract('(650) 253-0000')); + + // Trailing non-alpha-numeric characters should be removed. + assertEquals('650) 253-0000', extract('(650) 253-0000..- ..')); + assertEquals('650) 253-0000', extract('(650) 253-0000.')); + // This case has a trailing RTL char. + assertEquals('650) 253-0000', extract('(650) 253-0000\u200F')); +} + +function testMaybeStripNationalPrefix() { + /** @type {string} */ + var nationalPrefix = '34'; + /** @type {!goog.string.StringBuffer} */ + var numberToStrip = new goog.string.StringBuffer('34356778'); + /** @type {string} */ + var strippedNumber = '356778'; + /** @type {RegExp} */ + var nationalRule = /\d{4,7}/; + phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, '', + nationalRule); + assertEquals('Should have had national prefix stripped.', + strippedNumber, numberToStrip.toString()); + // Retry stripping - now the number should not start with the national prefix, + // so no more stripping should occur. + phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, '', + nationalRule); + assertEquals('Should have had no change - no national prefix present.', + strippedNumber, numberToStrip.toString()); + // Some countries have no national prefix. Repeat test with none specified. + nationalPrefix = ''; + phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, '', + nationalRule); + assertEquals('Should not strip anything with empty national prefix.', + strippedNumber, numberToStrip.toString()); + // If the resultant number doesn't match the national rule, it shouldn't be + // stripped. + nationalPrefix = '3'; + numberToStrip = new goog.string.StringBuffer('3123'); + strippedNumber = '3123'; + phoneUtil.maybeStripNationalPrefix(numberToStrip, nationalPrefix, '', + nationalRule); + assertEquals('Should have had no change - after stripping, it would not ' + + 'have matched the national rule.', + strippedNumber, numberToStrip.toString()); +} + +function testMaybeStripInternationalPrefix() { + var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource; + /** @type {string} */ + var internationalPrefix = '00[39]'; + /** @type {!goog.string.StringBuffer} */ + var numberToStrip = new goog.string.StringBuffer('0034567700-3898003'); + // Note the dash is removed as part of the normalization. + /** @type {!goog.string.StringBuffer} */ + var strippedNumber = new goog.string.StringBuffer('45677003898003'); + assertEquals(CCS.FROM_NUMBER_WITH_IDD, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + assertEquals('The number supplied was not stripped of its international ' + + 'prefix.', + strippedNumber.toString(), numberToStrip.toString()); + // Now the number no longer starts with an IDD prefix, so it should now report + // FROM_DEFAULT_COUNTRY. + assertEquals(CCS.FROM_DEFAULT_COUNTRY, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + + numberToStrip = new goog.string.StringBuffer('00945677003898003'); + assertEquals(CCS.FROM_NUMBER_WITH_IDD, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + assertEquals('The number supplied was not stripped of its international ' + + 'prefix.', + strippedNumber.toString(), numberToStrip.toString()); + // Test it works when the international prefix is broken up by spaces. + numberToStrip = new goog.string.StringBuffer('00 9 45677003898003'); + assertEquals(CCS.FROM_NUMBER_WITH_IDD, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + assertEquals('The number supplied was not stripped of its international ' + + 'prefix.', + strippedNumber.toString(), numberToStrip.toString()); + // Now the number no longer starts with an IDD prefix, so it should now report + // FROM_DEFAULT_COUNTRY. + assertEquals(CCS.FROM_DEFAULT_COUNTRY, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + + // Test the + symbol is also recognised and stripped. + numberToStrip = new goog.string.StringBuffer('+45677003898003'); + strippedNumber = new goog.string.StringBuffer('45677003898003'); + assertEquals(CCS.FROM_NUMBER_WITH_PLUS_SIGN, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + assertEquals('The number supplied was not stripped of the plus symbol.', + strippedNumber.toString(), numberToStrip.toString()); + + // If the number afterwards is a zero, we should not strip this - no country + // code begins with 0. + numberToStrip = new goog.string.StringBuffer('0090112-3123'); + strippedNumber = new goog.string.StringBuffer('00901123123'); + assertEquals(CCS.FROM_DEFAULT_COUNTRY, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); + assertEquals('The number supplied had a 0 after the match so should not be ' + + 'stripped.', + strippedNumber.toString(), numberToStrip.toString()); + // Here the 0 is separated by a space from the IDD. + numberToStrip = new goog.string.StringBuffer('009 0-112-3123'); + assertEquals(CCS.FROM_DEFAULT_COUNTRY, + phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip, + internationalPrefix)); +} + +function testMaybeExtractCountryCode() { + var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var number = new i18n.phonenumbers.PhoneNumber(); + /** @type {i18n.phonenumbers.PhoneMetadata} */ + var metadata = phoneUtil.getMetadataForRegion('US'); + // Note that for the US, the IDD is 011. + try { + /** @type {string} */ + var phoneNumber = '011112-3456789'; + /** @type {string} */ + var strippedNumber = '123456789'; + /** @type {number} */ + var countryCode = 1; + /** @type {!goog.string.StringBuffer} */ + var numberToFill = new goog.string.StringBuffer(); + assertEquals('Did not extract country code ' + countryCode + ' correctly.', + countryCode, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number)); + assertEquals('Did not figure out CountryCodeSource correctly', + CCS.FROM_NUMBER_WITH_IDD, + number.getCountryCodeSource()); + // Should strip and normalize national significant number. + assertEquals('Did not strip off the country code correctly.', + strippedNumber, + numberToFill.toString()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '+6423456789'; + countryCode = 64; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Did not extract country code ' + countryCode + ' correctly.', + countryCode, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number)); + assertEquals('Did not figure out CountryCodeSource correctly', + CCS.FROM_NUMBER_WITH_PLUS_SIGN, + number.getCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '2345-6789'; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Should not have extracted a country code - ' + + 'no international prefix present.', + 0, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number)); + assertEquals('Did not figure out CountryCodeSource correctly', + CCS.FROM_DEFAULT_COUNTRY, + number.getCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '0119991123456789'; + numberToFill = new goog.string.StringBuffer(); + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number); + fail('Should have thrown an exception, no valid country code present.'); + } catch (e) { + // Expected. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '(1 610) 619 4466'; + countryCode = 1; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Should have extracted the country code of the region ' + + 'passed in', + countryCode, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number)); + assertEquals('Did not figure out CountryCodeSource correctly', + CCS.FROM_NUMBER_WITHOUT_PLUS_SIGN, + number.getCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '(1 610) 619 4466'; + countryCode = 1; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Should have extracted the country code of the region ' + + 'passed in', + countryCode, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, false, + number)); + assertFalse('Should not contain CountryCodeSource.', + number.hasCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '(1 610) 619 446'; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Should not have extracted a country code - ' + + 'invalid number after extraction of uncertain country code.', + 0, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, false, + number)); + assertFalse('Should not contain CountryCodeSource.', + number.hasCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } + number = new i18n.phonenumbers.PhoneNumber(); + try { + phoneNumber = '(1 610) 619 43 446'; + numberToFill = new goog.string.StringBuffer(); + assertEquals('Should not have extracted a country code - invalid number ' + + 'both before and after extraction of uncertain country code.', + 0, + phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, + numberToFill, true, number)); + assertEquals('Did not figure out CountryCodeSource correctly', + CCS.FROM_DEFAULT_COUNTRY, + number.getCountryCodeSource()); + } catch (e) { + fail('Should not have thrown an exception: ' + e.toString()); + } +} + +function testParseNationalNumber() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + + // National prefix attached. + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('033316005', 'NZ'))); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('033316005', 'nz'))); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('33316005', 'NZ'))); + // National prefix attached and some formatting present. + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('03-331 6005', 'NZ'))); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('03 331 6005', 'NZ'))); + + // Testing international prefixes. + // Should strip country code. + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('0064 3 331 6005', 'NZ'))); + // Try again, but this time we have an international number with Region Code + // US. It should recognise the country code and parse accordingly. + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('01164 3 331 6005', 'US'))); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('+64 3 331 6005', 'US'))); + + nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(64123456); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('64(0)64123456', 'NZ'))); + // Check that using a '/' is fine in a phone number. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var deNumber = new i18n.phonenumbers.PhoneNumber(); + deNumber.setCountryCode(49); + deNumber.setNationalNumber(12345678); + assertTrue(deNumber.exactlySameAs(phoneUtil.parse('123/45678', 'DE'))); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + // Check it doesn't use the '1' as a country code when parsing if the phone + // number was already possible. + usNumber.setCountryCode(1); + usNumber.setNationalNumber(1234567890); + assertTrue(usNumber.exactlySameAs(phoneUtil.parse('123-456-7890', 'US'))); +} + + function testParseNumberWithAlphaCharacters() { + // Test case with alpha characters. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var tollfreeNumber = new i18n.phonenumbers.PhoneNumber(); + tollfreeNumber.setCountryCode(64); + tollfreeNumber.setNationalNumber(800332005); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var premiumNumber = new i18n.phonenumbers.PhoneNumber(); + premiumNumber.setCountryCode(64); + premiumNumber.setNationalNumber(9003326005); + assertTrue(premiumNumber.exactlySameAs( + phoneUtil.parse('0900 DDA 6005', 'NZ'))); + // Not enough alpha characters for them to be considered intentional, so they + // are stripped. + assertTrue(premiumNumber.exactlySameAs( + phoneUtil.parse('0900 332 6005a', 'NZ'))); + assertTrue(premiumNumber.exactlySameAs( + phoneUtil.parse('0900 332 600a5', 'NZ'))); + assertTrue(premiumNumber.exactlySameAs( + phoneUtil.parse('0900 332 600A5', 'NZ'))); + assertTrue(premiumNumber.exactlySameAs( + phoneUtil.parse('0900 a332 600A5', 'NZ'))); +} + +function testParseWithInternationalPrefixes() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6503336000); + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('+1 (650) 333-6000', 'NZ'))); + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('1-650-333-6000', 'US'))); + // Calling the US number from Singapore by using different service providers + // 1st test: calling using SingTel IDD service (IDD is 001) + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('0011-650-333-6000', 'SG'))); + // 2nd test: calling using StarHub IDD service (IDD is 008) + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('0081-650-333-6000', 'SG'))); + // 3rd test: calling using SingTel V019 service (IDD is 019) + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('0191-650-333-6000', 'SG'))); + // Calling the US number from Poland + assertTrue(usNumber.exactlySameAs( + phoneUtil.parse('0~01-650-333-6000', 'PL'))); +} + +function testParseWithLeadingZero() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(236618300); + itNumber.setItalianLeadingZero(true); + assertTrue(itNumber.exactlySameAs(phoneUtil.parse('+39 02-36618 300', 'NZ'))); + assertTrue(itNumber.exactlySameAs(phoneUtil.parse('02-36618 300', 'IT'))); + + itNumber = new i18n.phonenumbers.PhoneNumber(); + itNumber.setCountryCode(39); + itNumber.setNationalNumber(312345678); + assertTrue(itNumber.exactlySameAs(phoneUtil.parse('312 345 678', 'IT'))); +} + +function testParseNationalNumberArgentina() { + // Test parsing mobile numbers of Argentina. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arNumber = new i18n.phonenumbers.PhoneNumber(); + + arNumber.setCountryCode(54); + arNumber.setNationalNumber(93435551212); + assertTrue(arNumber.exactlySameAs( + phoneUtil.parse('+54 9 343 555 1212', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('0343 15 555 1212', 'AR'))); + + arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(93715654320); + assertTrue(arNumber.exactlySameAs( + phoneUtil.parse('+54 9 3715 65 4320', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('03715 15 65 4320', 'AR'))); + + // Test parsing fixed-line numbers of Argentina. + arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(1137970000); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('+54 11 3797 0000', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('011 3797 0000', 'AR'))); + + arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(3715654321); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('+54 3715 65 4321', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('03715 65 4321', 'AR'))); + + arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(2312340000); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('+54 23 1234 0000', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('023 1234 0000', 'AR'))); +} + +function testParseWithXInNumber() { + // Test that having an 'x' in the phone number at the start is ok and that it + // just gets removed. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arNumber = new i18n.phonenumbers.PhoneNumber(); + arNumber.setCountryCode(54); + arNumber.setNationalNumber(123456789); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('0123456789', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('(0) 123456789', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('0 123456789', 'AR'))); + assertTrue(arNumber.exactlySameAs(phoneUtil.parse('(0xx) 123456789', 'AR'))); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var arFromUs = new i18n.phonenumbers.PhoneNumber(); + arFromUs.setCountryCode(54); + arFromUs.setNationalNumber(81429712); + // This test is intentionally constructed such that the number of digit after + // xx is larger than 7, so that the number won't be mistakenly treated as an + // extension, as we allow extensions up to 7 digits. This assumption is okay + // for now as all the countries where a carrier selection code is written in + // the form of xx have a national significant number of length larger than 7. + assertTrue(arFromUs.exactlySameAs(phoneUtil.parse('011xx5481429712', 'US'))); +} + +function testParseNumbersMexico() { + // Test parsing fixed-line numbers of Mexico. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var mxNumber = new i18n.phonenumbers.PhoneNumber(); + mxNumber.setCountryCode(52); + mxNumber.setNationalNumber(4499780001); + assertTrue(mxNumber.exactlySameAs( + phoneUtil.parse('+52 (449)978-0001', 'MX'))); + assertTrue(mxNumber.exactlySameAs(phoneUtil.parse('01 (449)978-0001', 'MX'))); + assertTrue(mxNumber.exactlySameAs(phoneUtil.parse('(449)978-0001', 'MX'))); + + // Test parsing mobile numbers of Mexico. + mxNumber = new i18n.phonenumbers.PhoneNumber(); + mxNumber.setCountryCode(52); + mxNumber.setNationalNumber(13312345678); + assertTrue(mxNumber.exactlySameAs( + phoneUtil.parse('+52 1 33 1234-5678', 'MX'))); + assertTrue(mxNumber.exactlySameAs( + phoneUtil.parse('044 (33) 1234-5678', 'MX'))); + assertTrue(mxNumber.exactlySameAs( + phoneUtil.parse('045 33 1234-5678', 'MX'))); +} + +function testFailedParseOnInvalidNumbers() { + try { + /** @type {string} */ + var sentencePhoneNumber = 'This is not a phone number'; + phoneUtil.parse(sentencePhoneNumber, 'NZ'); + fail('This should not parse without throwing an exception ' + + sentencePhoneNumber); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.NOT_A_NUMBER, + e); + } + try { + /** @type {string} */ + var tooLongPhoneNumber = '01495 72553301873 810104'; + phoneUtil.parse(tooLongPhoneNumber, 'GB'); + fail('This should not parse without throwing an exception ' + + tooLongPhoneNumber); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_LONG, + e); + } + try { + /** @type {string} */ + var plusMinusPhoneNumber = '+---'; + phoneUtil.parse(plusMinusPhoneNumber, 'DE'); + fail('This should not parse without throwing an exception ' + + plusMinusPhoneNumber); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.NOT_A_NUMBER, + e); + } + try { + /** @type {string} */ + var tooShortPhoneNumber = '+49 0'; + phoneUtil.parse(tooShortPhoneNumber, 'DE'); + fail('This should not parse without throwing an exception ' + + tooShortPhoneNumber); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_SHORT_NSN, + e); + } + try { + /** @type {string} */ + var invalidCountryCode = '+210 3456 56789'; + phoneUtil.parse(invalidCountryCode, 'NZ'); + fail('This is not a recognised country code: should fail: ' + + invalidCountryCode); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } + try { + /** @type {string} */ + var someNumber = '123 456 7890'; + phoneUtil.parse(someNumber, 'YY'); + fail('Unknown country code not allowed: should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } + try { + /** @type {string} */ + someNumber = '123 456 7890'; + phoneUtil.parse(someNumber, 'CS'); + fail('Deprecated country code not allowed: should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } + try { + someNumber = '123 456 7890'; + phoneUtil.parse(someNumber, null); + fail('Null country code not allowed: should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } + try { + someNumber = '0044------'; + phoneUtil.parse(someNumber, 'GB'); + fail('No number provided, only country code: should fail'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD, + e); + } + try { + someNumber = '0044'; + phoneUtil.parse(someNumber, 'GB'); + fail('No number provided, only country code: should fail'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD, + e); + } + try { + someNumber = '011'; + phoneUtil.parse(someNumber, 'US'); + fail('Only IDD provided - should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD, + e); + } + try { + someNumber = '0119'; + phoneUtil.parse(someNumber, 'US'); + fail('Only IDD provided and then 9 - should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD, + e); + } +} + +function testParseNumbersWithPlusWithNoRegion() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + // 'ZZ' is allowed only if the number starts with a '+' - then the country + // code can be calculated. + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('+64 3 331 6005', 'ZZ'))); + assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('+64 3 331 6005', null))); + nzNumber.setRawInput('+64 3 331 6005'); + nzNumber.setCountryCodeSource(i18n.phonenumbers.PhoneNumber + .CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN); + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('+64 3 331 6005', 'ZZ'))); + // Null is also allowed for the region code in these cases. + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('+64 3 331 6005', null))); +} + +function testParseExtensions() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + nzNumber.setExtension('3456'); + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parse('03 331 6005 ext 3456', 'NZ'))); + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parse('03-3316005x3456', 'NZ'))); + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parse('03-3316005 int.3456', 'NZ'))); + assertTrue(nzNumber.exactlySameAs( + phoneUtil.parse('03 3316005 #3456', 'NZ'))); + + // Test the following do not extract extensions: + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nonExtnNumber = new i18n.phonenumbers.PhoneNumber(); + nonExtnNumber.setCountryCode(1); + nonExtnNumber.setNationalNumber(180074935247); + assertTrue(nonExtnNumber.exactlySameAs( + phoneUtil.parse('1800 six-flags', 'US'))); + assertTrue(nonExtnNumber.exactlySameAs( + phoneUtil.parse('1800 SIX FLAGS', 'US'))); + assertTrue(nonExtnNumber.exactlySameAs( + phoneUtil.parse('0~01 1800 7493 5247', 'PL'))); + assertTrue(nonExtnNumber.exactlySameAs( + phoneUtil.parse('(1800) 7493.5247', 'US'))); + + // Check that the last instance of an extension token is matched. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var extnNumber = new i18n.phonenumbers.PhoneNumber(); + extnNumber.setCountryCode(1); + extnNumber.setNationalNumber(180074935247); + extnNumber.setExtension('1234'); + assertTrue(extnNumber.exactlySameAs( + phoneUtil.parse('0~01 1800 7493 5247 ~1234', 'PL'))); + + // Verifying bug-fix where the last digit of a number was previously omitted + // if it was a 0 when extracting the extension. Also verifying a few different + // cases of extensions. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var ukNumber = new i18n.phonenumbers.PhoneNumber(); + ukNumber.setCountryCode(44); + ukNumber.setNationalNumber(2034567890); + ukNumber.setExtension('456'); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890x456', 'NZ'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890x456', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 x456', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 X456', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 X 456', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 X 456', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 x 456 ', 'GB'))); + assertTrue(ukNumber.exactlySameAs( + phoneUtil.parse('+44 2034567890 X 456', 'GB'))); + + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usWithExtension = new i18n.phonenumbers.PhoneNumber(); + usWithExtension.setCountryCode(1); + usWithExtension.setNationalNumber(8009013355); + usWithExtension.setExtension('7246433'); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('(800) 901-3355 x 7246433', 'US'))); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('(800) 901-3355 , ext 7246433', 'US'))); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('(800) 901-3355 ,extension 7246433', 'US'))); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('(800) 901-3355 , 7246433', 'US'))); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('(800) 901-3355 ext: 7246433', 'US'))); + + // Test that if a number has two extensions specified, we ignore the second. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usWithTwoExtensionsNumber = new i18n.phonenumbers.PhoneNumber(); + usWithTwoExtensionsNumber.setCountryCode(1); + usWithTwoExtensionsNumber.setNationalNumber(2121231234); + usWithTwoExtensionsNumber.setExtension('508'); + assertTrue(usWithTwoExtensionsNumber.exactlySameAs( + phoneUtil.parse('(212)123-1234 x508/x1234', 'US'))); + assertTrue(usWithTwoExtensionsNumber.exactlySameAs( + phoneUtil.parse('(212)123-1234 x508/ x1234', 'US'))); + assertTrue(usWithTwoExtensionsNumber.exactlySameAs( + phoneUtil.parse('(212)123-1234 x508\\x1234', 'US'))); + + // Test parsing numbers in the form (645) 123-1234-910# works, where the last + // 3 digits before the # are an extension. + usWithExtension = new i18n.phonenumbers.PhoneNumber(); + usWithExtension.setCountryCode(1); + usWithExtension.setNationalNumber(6451231234); + usWithExtension.setExtension('910'); + assertTrue(usWithExtension.exactlySameAs( + phoneUtil.parse('+1 (645) 123 1234-910#', 'US'))); +} + +function testParseAndKeepRaw() { + var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource; + /** @type {i18n.phonenumbers.PhoneNumber} */ + var alphaNumericNumber = new i18n.phonenumbers.PhoneNumber(); + alphaNumericNumber.setCountryCode(1); + alphaNumericNumber.setNationalNumber(180074935247); + alphaNumericNumber.setRawInput('1800 six-flags'); + alphaNumericNumber.setCountryCodeSource(CCS.FROM_DEFAULT_COUNTRY); + assertTrue(alphaNumericNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('1800 six-flags', 'US'))); + + alphaNumericNumber.setCountryCode(1); + alphaNumericNumber.setNationalNumber(8007493524); + alphaNumericNumber.setRawInput('1800 six-flag'); + alphaNumericNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITHOUT_PLUS_SIGN); + assertTrue(alphaNumericNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('1800 six-flag', 'US'))); + + alphaNumericNumber.setCountryCode(1); + alphaNumericNumber.setNationalNumber(8007493524); + alphaNumericNumber.setRawInput('+1800 six-flag'); + alphaNumericNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITH_PLUS_SIGN); + assertTrue(alphaNumericNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('+1800 six-flag', 'NZ'))); + + alphaNumericNumber.setCountryCode(1); + alphaNumericNumber.setNationalNumber(8007493524); + alphaNumericNumber.setRawInput('001800 six-flag'); + alphaNumericNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITH_IDD); + assertTrue(alphaNumericNumber.exactlySameAs( + phoneUtil.parseAndKeepRawInput('001800 six-flag', 'NZ'))); + + // Invalid region code supplied. + try { + phoneUtil.parseAndKeepRawInput('123 456 7890', 'CS'); + fail('Deprecated country code not allowed: should fail.'); + } catch (e) { + // Expected this exception. + assertEquals('Wrong error type stored in exception.', + i18n.phonenumbers.Error.INVALID_COUNTRY_CODE, + e); + } +} + +function testCountryWithNoNumberDesc() { + var PNF = i18n.phonenumbers.PhoneNumberFormat; + var PNT = i18n.phonenumbers.PhoneNumberType; + // Andorra is a country where we don't have PhoneNumberDesc info in the + // metadata. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var adNumber = new i18n.phonenumbers.PhoneNumber(); + adNumber.setCountryCode(376); + adNumber.setNationalNumber(12345); + assertEquals('+376 12345', phoneUtil.format(adNumber, PNF.INTERNATIONAL)); + assertEquals('+37612345', phoneUtil.format(adNumber, PNF.E164)); + assertEquals('12345', phoneUtil.format(adNumber, PNF.NATIONAL)); + assertEquals(PNT.UNKNOWN, phoneUtil.getNumberType(adNumber)); + assertTrue(phoneUtil.isValidNumber(adNumber)); + + // Test dialing a US number from within Andorra. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var usNumber = new i18n.phonenumbers.PhoneNumber(); + usNumber.setCountryCode(1); + usNumber.setNationalNumber(6502530000); + assertEquals('00 1 650 253 0000', + phoneUtil.formatOutOfCountryCallingNumber(usNumber, 'AD')); +} + +function testUnknownCountryCallingCodeForValidation() { + /** @type {i18n.phonenumbers.PhoneNumber} */ + var invalidNumber = new i18n.phonenumbers.PhoneNumber(); + invalidNumber.setCountryCode(0); + invalidNumber.setNationalNumber(1234); + assertFalse(phoneUtil.isValidNumber(invalidNumber)); +} + +function testIsNumberMatchMatches() { + // Test simple matches where formatting is different, or leading zeroes, + // or country code has been specified. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var num1 = phoneUtil.parse('+64 3 331 6005', 'NZ'); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var num2 = phoneUtil.parse('+64 03 331 6005', 'NZ'); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch(num1, num2)); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+64 3 331 6005', '+64 03 331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+64 03 331-6005', '+64 03331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+643 331-6005', '+64033316005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+643 331-6005', '+6433316005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '+6433316005')); + // Test alpha numbers. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+1800 siX-Flags', '+1 800 7493 5247')); + // Test numbers with extensions. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234', + '+6433316005#1234')); + // Test proto buffers. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + nzNumber.setExtension('3456'); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch(nzNumber, '+643 331 6005 ext 3456')); + nzNumber.clearExtension(); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch(nzNumber, '+6403 331 6005')); + // Check empty extensions are ignored. + nzNumber.setExtension(''); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch(nzNumber, '+6403 331 6005')); + // Check variant with two proto buffers. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumberTwo = new i18n.phonenumbers.PhoneNumber(); + nzNumberTwo.setCountryCode(64); + nzNumberTwo.setNationalNumber(33316005); + assertEquals('Number nzNumber did not match nzNumberTwo', + i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH, + phoneUtil.isNumberMatch(nzNumber, nzNumberTwo)); +} + +function testIsNumberMatchNonMatches() { + // Non-matches. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH, + phoneUtil.isNumberMatch('03 331 6005', '03 331 6006')); + // Different country code, partial number match. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '+16433316005')); + // Different country code, same number. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '+6133316005')); + // Extension different, all else the same. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234', + '0116433316005#1235')); + // NSN matches, but extension is different - not the same number. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005 ext.1235', + '3 331 6005#1234')); +} + +function testIsNumberMatchNsnMatches() { + // NSN matches. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '03 331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH, + phoneUtil.isNumberMatch('3 331-6005', '03 331 6005')); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var nzNumber = new i18n.phonenumbers.PhoneNumber(); + nzNumber.setCountryCode(64); + nzNumber.setNationalNumber(33316005); + nzNumber.setExtension(''); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH, + phoneUtil.isNumberMatch(nzNumber, '03 331 6005')); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var unchangedNzNumber = new i18n.phonenumbers.PhoneNumber(); + unchangedNzNumber.setCountryCode(64); + unchangedNzNumber.setNationalNumber(33316005); + unchangedNzNumber.setExtension(''); + // Check the phone number proto was not edited during the method call. + assertTrue(unchangedNzNumber.exactlySameAs(nzNumber)); +} + +function testIsNumberMatchShortNsnMatches() { + // Short NSN matches with the country not specified for either one or both + // numbers. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('3 331-6005', '331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('3 331-6005', '+64 331 6005')); + // Short NSN match with the country specified. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('03 331-6005', '331 6005')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('1 234 345 6789', '345 6789')); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('+1 (234) 345 6789', '345 6789')); + // NSN matches, country code omitted for one number, extension missing for + // one. + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch('+64 3 331-6005', '3 331 6005#1234')); + // One has Italian leading zero, one does not. + /** @type {i18n.phonenumbers.PhoneNumber} */ + var italianNumberOne = new i18n.phonenumbers.PhoneNumber(); + italianNumberOne.setCountryCode(39); + italianNumberOne.setNationalNumber(1234); + italianNumberOne.setItalianLeadingZero(true); + /** @type {i18n.phonenumbers.PhoneNumber} */ + var italianNumberTwo = new i18n.phonenumbers.PhoneNumber(); + italianNumberTwo.setCountryCode(39); + italianNumberTwo.setNationalNumber(1234); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo)); + // One has an extension, the other has an extension of ''. + italianNumberOne.setExtension('1234'); + italianNumberOne.clearItalianLeadingZero(); + italianNumberTwo.setExtension(''); + assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH, + phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo)); +}