Commits

Anonymous committed 05e11d0

JS: port Java changes from v4.9 (rev 469) and update metadata

  • Participants
  • Parent commits 43c4cf8
  • Branches default

Comments (0)

Files changed (6)

javascript/README

 
 How to update:
 ==============
-The JavaScript library is ported from the Java implementation (revision 448).
+The JavaScript library is ported from the Java implementation (revision 469).
 When the Java project gets updated follow these steps to update the JavaScript
 project:
 

javascript/i18n/phonenumbers/metadata.js

 ,878:["001"]
 ,880:["BD"]
 ,881:["001"]
+,882:["001"]
 ,883:["001"]
 ,886:["TW"]
 ,888:["001"]
 ]
 ,"BF":[,[,,"[24-7]\\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"]
-,[,,"(?:6(?:0[0-5]|[68]0)|7(?:[02-68]\\d|1[0-4689]|7[0-69]|9[0-689]))\\d{5}","\\d{8}",,,"70123456"]
+,[,,"(?:6(?:0[0-7]|6[0-2]|8[01])|7(?:[02-68]\\d|1[0-4689]|7[0-69]|9[0-689]))\\d{5}","\\d{8}",,,"70123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,,[,,"000|112","\\d{3}",,,"112"]
 ,[,,"NA","NA"]
 ]
-,"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]|7(?:0[25]|[2379]\\d))\\d{6}","\\d{9}",,,"601123456"]
-,[,,"800\\d{6}","\\d{9}",,,"800123456"]
-,[,,"9(?:0[05689]|76)\\d{6}","\\d{9}",,,"900123456"]
-,[,,"8[134]\\d{7}","\\d{9}",,,"811234567"]
-,[,,"70[01]\\d{6}","\\d{9}",,,"700123456"]
-,[,,"9[17]0\\d{6}","\\d{9}",,,"910123456"]
-,"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",,"","",0]
-]
-,,[,,"NA","NA"]
-,,,[,,"NA","NA"]
-,[,,"9(?:5[056]|7[234])\\d{6}","\\d{9}",,,"972123456"]
+,"CZ":[,[,,"[2-8]\\d{8}|9\\d{8,11}","\\d{9,12}"]
+,[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}","\\d{9,12}",,,"212345678"]
+,[,,"(?:60[1-8]|7(?:0[2-5]|[2379]\\d))\\d{6}","\\d{9,12}",,,"601123456"]
+,[,,"800\\d{6}","\\d{9,12}",,,"800123456"]
+,[,,"9(?:0[05689]|76)\\d{6}","\\d{9,12}",,,"900123456"]
+,[,,"8[134]\\d{7}","\\d{9,12}",,,"811234567"]
+,[,,"70[01]\\d{6}","\\d{9,12}",,,"700123456"]
+,[,,"9[17]0\\d{6}","\\d{9,12}",,,"910123456"]
+,"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8]|9[015-7]"]
+,"","",0]
+,[,"(96\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["96"]
+,"","",0]
+,[,"(9\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["9[36]"]
+,"","",0]
+]
+,,[,,"NA","NA"]
+,,,[,,"NA","NA"]
+,[,,"9(?:5[056]|7[234])\\d{6}","\\d{9,12}",,,"972123456"]
 ,,[,,"1(?:12|5[058])","\\d{3}",,,"112"]
-,[,,"NA","NA"]
+,[,,"9(?:3\\d{9}|6\\d{7,10})","\\d{9,12}",,,"93123456789"]
 ]
 ,"DE":[,[,,"[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:4[1-8]|[0-35-7]\\d)\\d{2,7})","\\d{2,15}"]
 ,[,,"[246]\\d{5,13}|3(?:[03-9]\\d{4,13}|2\\d{9})|5(?:0[2-8]|[1256]\\d|[38][0-8]|4\\d{0,2}|[79][0-7])\\d{3,11}|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-9]\\d)\\d{3,10}|9(?:0[6-9]|[1-9]\\d)\\d{3,10}","\\d{2,15}",,,"30123456"]
 ,[,,"NA","NA"]
 ]
 ,"ES":[,[,,"[5-9]\\d{8}","\\d{9}"]
-,[,,"(?:8(?:[13]0|[28][0-8]|[47][1-9]|5[01346-9]|6[0457-9])|9(?:[1238][0-8]|[47][1-9]|[56]\\d))\\d{6}","\\d{9}",,,"810123456"]
-,[,,"(?:6\\d|7[1-4])\\d{7}","\\d{9}",,,"612345678"]
+,[,,"8(?:[13]0|[28][0-8]|[47][1-9]|5[01346-9]|6[0457-9])\\d{6}|9(?:[1238][0-8]\\d{6}|4[1-9]\\d{6}|5\\d{7}|6(?:[0-8]\\d{6}|9(?:0(?:[0-57-9]\\d{4}|6(?:0[0-8]|1[1-9]|[2-9]\\d)\\d{2})|[1-9]\\d{5}))|7(?:[124-9]\\d{2}|3(?:[0-8]\\d|9[1-9]))\\d{4})","\\d{9}",,,"810123456"]
+,[,,"(?:6\\d{6}|7[1-4]\\d{5}|9(?:6906(?:09|10)|7390\\d{2}))\\d{2}","\\d{9}",,,"612345678"]
 ,[,,"[89]00\\d{6}","\\d{9}",,,"800123456"]
 ,[,,"80[367]\\d{6}","\\d{9}",,,"803123456"]
 ,[,,"90[12]\\d{6}","\\d{9}",,,"901123456"]
 ,,[,,"11[29]","\\d{3}",,,"112"]
 ,[,,"NA","NA"]
 ]
-,"KW":[,[,,"[12569]\\d{6,7}|65816\\d{6}","\\d{7,8}|\\d{11}"]
-,[,,"(?:18\\d|2(?:[23]\\d{2}|4[1-35-9]\\d|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}","\\d{7,8}",,,"22345678"]
-,[,,"(?:5(?:0[0-2568]|5\\d)|6(?:0[034679]|5(?:[015-79]|8(?:[02-9]|1[0-57-9]))|6\\d|7[067]|9[069])|9(?:0[09]|4[049]|6[69]|[79]\\d))\\d{5}","\\d{8}",,,"50012345"]
+,"KW":[,[,,"[12569]\\d{6,7}","\\d{7,8}"]
+,[,,"(?:18\\d|2(?:[23]\\d{2}|4(?:[1-35-9]\\d|44)|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}","\\d{7,8}",,,"22345678"]
+,[,,"(?:5(?:0[0-2568]|11|5\\d)|6(?:0[034679]|5[015-9]|6\\d|7[067]|9[069])|9(?:0[09]|4[049]|6[69]|[79]\\d))\\d{5}","\\d{8}",,,"50012345"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"KW",965,"00",,,,,,,,[[,"(\\d{4})(\\d{3,4})","$1 $2",["[1269]"]
 ,"","",0]
-,[,"(5[05]\\d)(\\d{5})","$1 $2",["5"]
+,[,"(5[015]\\d)(\\d{5})","$1 $2",["5"]
 ,"","",0]
-,[,"(65816)(\\d{6})","$1 $2",["65816"]
-,"","",0]
 ]
 ,,[,,"NA","NA"]
 ,,,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,,[,,"112","\\d{3}",,,"112"]
-,[,,"65816\\d{6}","\\d{11}",,,"65816123456"]
+,[,,"NA","NA"]
 ]
 ,"KY":[,[,,"[3589]\\d{9}","\\d{7}(?:\\d{3})?"]
 ,[,,"345(?:2(?:22|44)|444|6(?:23|38|40)|7(?:4[35-79]|6[6-9]|77)|8(?:00|1[45]|25|[48]8)|9(?:14|4[035-9]))\\d{4}","\\d{7}(?:\\d{3})?",,,"3452221234"]
 ,,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ]
+,"882":[,[,,"[13]\\d{6,11}","\\d{7,12}",,,"32123456"]
+,[,,"NA","NA",,,"32123456"]
+,[,,"3(?:2\\d{3}|37\\d{2}|4(?:2|7\\d{3}))\\d{4}","\\d{7,10}",,,"32123456"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"1(?:3(?:0[0347]|[13][0139]|2[035]|4[013568]|6[0459]|7[06]|8[15678]|9[0689])\\d{4}|6\\d{5,10})|345\\d{7}","\\d{7,12}",,,"32123456"]
+,"001",882,"",,,,,,,,[[,"(\\d{2})(\\d{4})(\\d{3})","$1 $2 $3",["3[23]"]
+,"","",0]
+,[,"(\\d{2})(\\d{5})","$1 $2",["16|342"]
+,"","",0]
+,[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["34[57]"]
+,"","",0]
+,[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["348"]
+,"","",0]
+,[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["1"]
+,"","",0]
+,[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["16"]
+,"","",0]
+,[,"(\\d{2})(\\d{4,5})(\\d{5})","$1 $2 $3",["16"]
+,"","",0]
+]
+,,[,,"NA","NA"]
+,,,[,,"NA","NA"]
+,[,,"NA","NA"]
+,,[,,"NA","NA"]
+,[,,"348[57]\\d{7}","\\d{11}",,,"32123456"]
+]
 ,"883":[,[,,"51\\d{7}(?:\\d{3})?","\\d{9}(?:\\d{3})?",,,"510012345"]
 ,[,,"NA","NA",,,"510012345"]
 ,[,,"NA","NA",,,"510012345"]

javascript/i18n/phonenumbers/metadatafortesting.js

 ,262:["RE","YT"]
 ,376:["AD"]
 ,800:["001"]
+,979:["001"]
 };
 
 /**
 ,,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ]
+,"979":[,[,,"\\d{9}","\\d{9}",,,"123456789"]
+,[,,"NA","NA",,,"123456789"]
+,[,,"NA","NA",,,"123456789"]
+,[,,"NA","NA"]
+,[,,"\\d{9}","\\d{9}",,,"123456789"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,"001",979,"",,,,,,,1,[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",,"","",0]
+]
+,,[,,"NA","NA"]
+,,,[,,"NA","NA"]
+,[,,"NA","NA"]
+,,[,,"NA","NA"]
+,[,,"NA","NA"]
+]
 };

javascript/i18n/phonenumbers/metadatalite.js

 ,878:["001"]
 ,880:["BD"]
 ,881:["001"]
+,882:["001"]
 ,883:["001"]
 ,886:["TW"]
 ,888:["001"]
 ]
 ,"BF":[,[,,"[24-7]\\d{7}","\\d{8}"]
 ,[,,"(?:20(?:49|5[23]|9[016-9])|40(?:4[569]|55|7[0179])|50[34]\\d)\\d{4}","\\d{8}"]
-,[,,"(?:6(?:0[0-5]|[68]0)|7(?:[02-68]\\d|1[0-4689]|7[0-69]|9[0-689]))\\d{5}","\\d{8}"]
+,[,,"(?:6(?:0[0-7]|6[0-2]|8[01])|7(?:[02-68]\\d|1[0-4689]|7[0-69]|9[0-689]))\\d{5}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,,[,,"000|112","\\d{3}"]
 ,[,,"NA","NA"]
 ]
-,"CZ":[,[,,"[2-9]\\d{8}","\\d{9}"]
-,[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}","\\d{9}"]
-,[,,"(?:60[1-8]|7(?:0[25]|[2379]\\d))\\d{6}","\\d{9}"]
-,[,,"800\\d{6}","\\d{9}"]
-,[,,"9(?:0[05689]|76)\\d{6}","\\d{9}"]
-,[,,"8[134]\\d{7}","\\d{9}"]
-,[,,"70[01]\\d{6}","\\d{9}"]
-,[,,"9[17]0\\d{6}","\\d{9}"]
-,"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",,"","",0]
-]
-,,[,,"NA","NA"]
-,,,[,,"NA","NA"]
-,[,,"9(?:5[056]|7[234])\\d{6}","\\d{9}"]
+,"CZ":[,[,,"[2-8]\\d{8}|9\\d{8,11}","\\d{9,12}"]
+,[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}","\\d{9,12}"]
+,[,,"(?:60[1-8]|7(?:0[2-5]|[2379]\\d))\\d{6}","\\d{9,12}"]
+,[,,"800\\d{6}","\\d{9,12}"]
+,[,,"9(?:0[05689]|76)\\d{6}","\\d{9,12}"]
+,[,,"8[134]\\d{7}","\\d{9,12}"]
+,[,,"70[01]\\d{6}","\\d{9,12}"]
+,[,,"9[17]0\\d{6}","\\d{9,12}"]
+,"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8]|9[015-7]"]
+,"","",0]
+,[,"(96\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["96"]
+,"","",0]
+,[,"(9\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["9[36]"]
+,"","",0]
+]
+,,[,,"NA","NA"]
+,,,[,,"NA","NA"]
+,[,,"9(?:5[056]|7[234])\\d{6}","\\d{9,12}"]
 ,,[,,"1(?:12|5[058])","\\d{3}"]
-,[,,"NA","NA"]
+,[,,"9(?:3\\d{9}|6\\d{7,10})","\\d{9,12}"]
 ]
 ,"DE":[,[,,"[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:4[1-8]|[0-35-7]\\d)\\d{2,7})","\\d{2,15}"]
 ,[,,"[246]\\d{5,13}|3(?:[03-9]\\d{4,13}|2\\d{9})|5(?:0[2-8]|[1256]\\d|[38][0-8]|4\\d{0,2}|[79][0-7])\\d{3,11}|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-9]\\d)\\d{3,10}|9(?:0[6-9]|[1-9]\\d)\\d{3,10}","\\d{2,15}"]
 ,[,,"NA","NA"]
 ]
 ,"ES":[,[,,"[5-9]\\d{8}","\\d{9}"]
-,[,,"(?:8(?:[13]0|[28][0-8]|[47][1-9]|5[01346-9]|6[0457-9])|9(?:[1238][0-8]|[47][1-9]|[56]\\d))\\d{6}","\\d{9}"]
-,[,,"(?:6\\d|7[1-4])\\d{7}","\\d{9}"]
+,[,,"8(?:[13]0|[28][0-8]|[47][1-9]|5[01346-9]|6[0457-9])\\d{6}|9(?:[1238][0-8]\\d{6}|4[1-9]\\d{6}|5\\d{7}|6(?:[0-8]\\d{6}|9(?:0(?:[0-57-9]\\d{4}|6(?:0[0-8]|1[1-9]|[2-9]\\d)\\d{2})|[1-9]\\d{5}))|7(?:[124-9]\\d{2}|3(?:[0-8]\\d|9[1-9]))\\d{4})","\\d{9}"]
+,[,,"(?:6\\d{6}|7[1-4]\\d{5}|9(?:6906(?:09|10)|7390\\d{2}))\\d{2}","\\d{9}"]
 ,[,,"[89]00\\d{6}","\\d{9}"]
 ,[,,"80[367]\\d{6}","\\d{9}"]
 ,[,,"90[12]\\d{6}","\\d{9}"]
 ,,[,,"11[29]","\\d{3}"]
 ,[,,"NA","NA"]
 ]
-,"KW":[,[,,"[12569]\\d{6,7}|65816\\d{6}","\\d{7,8}|\\d{11}"]
-,[,,"(?:18\\d|2(?:[23]\\d{2}|4[1-35-9]\\d|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}","\\d{7,8}"]
-,[,,"(?:5(?:0[0-2568]|5\\d)|6(?:0[034679]|5(?:[015-79]|8(?:[02-9]|1[0-57-9]))|6\\d|7[067]|9[069])|9(?:0[09]|4[049]|6[69]|[79]\\d))\\d{5}","\\d{8}"]
+,"KW":[,[,,"[12569]\\d{6,7}","\\d{7,8}"]
+,[,,"(?:18\\d|2(?:[23]\\d{2}|4(?:[1-35-9]\\d|44)|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}","\\d{7,8}"]
+,[,,"(?:5(?:0[0-2568]|11|5\\d)|6(?:0[034679]|5[015-9]|6\\d|7[067]|9[069])|9(?:0[09]|4[049]|6[69]|[79]\\d))\\d{5}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"KW",965,"00",,,,,,,,[[,"(\\d{4})(\\d{3,4})","$1 $2",["[1269]"]
 ,"","",0]
-,[,"(5[05]\\d)(\\d{5})","$1 $2",["5"]
+,[,"(5[015]\\d)(\\d{5})","$1 $2",["5"]
 ,"","",0]
-,[,"(65816)(\\d{6})","$1 $2",["65816"]
-,"","",0]
 ]
 ,,[,,"NA","NA"]
 ,,,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,,[,,"112","\\d{3}"]
-,[,,"65816\\d{6}","\\d{11}"]
+,[,,"NA","NA"]
 ]
 ,"KY":[,[,,"[3589]\\d{9}","\\d{7}(?:\\d{3})?"]
 ,[,,"345(?:2(?:22|44)|444|6(?:23|38|40)|7(?:4[35-79]|6[6-9]|77)|8(?:00|1[45]|25|[48]8)|9(?:14|4[035-9]))\\d{4}","\\d{7}(?:\\d{3})?"]
 ,,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ]
+,"882":[,[,,"[13]\\d{6,11}","\\d{7,12}"]
+,[,,"NA","NA"]
+,[,,"3(?:2\\d{3}|37\\d{2}|4(?:2|7\\d{3}))\\d{4}","\\d{7,10}"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"NA","NA"]
+,[,,"1(?:3(?:0[0347]|[13][0139]|2[035]|4[013568]|6[0459]|7[06]|8[15678]|9[0689])\\d{4}|6\\d{5,10})|345\\d{7}","\\d{7,12}"]
+,"001",882,"",,,,,,,,[[,"(\\d{2})(\\d{4})(\\d{3})","$1 $2 $3",["3[23]"]
+,"","",0]
+,[,"(\\d{2})(\\d{5})","$1 $2",["16|342"]
+,"","",0]
+,[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["34[57]"]
+,"","",0]
+,[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["348"]
+,"","",0]
+,[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["1"]
+,"","",0]
+,[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["16"]
+,"","",0]
+,[,"(\\d{2})(\\d{4,5})(\\d{5})","$1 $2 $3",["16"]
+,"","",0]
+]
+,,[,,"NA","NA"]
+,,,[,,"NA","NA"]
+,[,,"NA","NA"]
+,,[,,"NA","NA"]
+,[,,"348[57]\\d{7}","\\d{11}"]
+]
 ,"883":[,[,,"51\\d{7}(?:\\d{3})?","\\d{9}(?:\\d{3})?"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]

javascript/i18n/phonenumbers/phonenumberutil.js

  * @type {number}
  * @private
  */
-i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ = 3;
+i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ = 2;
 
 
 /**
 
 
 /**
- * We include the "+" here since RFC3966 format specifies that the context must
- * be specified in international format.
- *
  * @const
  * @type {string}
  * @private
  */
-i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_ = ';phone-context=+';
+i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_ = ';phone-context=';
+
+
+/**
+ * @const
+ * @type {string}
+ * @private
+ */
+i18n.phonenumbers.PhoneNumberUtil.RFC3966_ISDN_SUBADDRESS_ = ';isub=';
 
 
 /**
   '7': '7',
   '8': '8',
   '9': '9',
-  '+': '+',
+  '+': i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN,
   '*': '*'
 };
 
  * @type {string}
  */
 i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION =
-    '-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F \u00A0\u200B\u2060\u3000()' +
-    '\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E';
+    '-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F \u00A0\u00AD\u200B\u2060\u3000' +
+    '()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E';
 
 
 /**
 
 /**
  * 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
+ * all. At the moment, checks to see that the string begins with at least 2
  * 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
   // return the formatted phone number; otherwise we return the raw input the
   // user entered.
   return (formattedNumber != null &&
-          i18n.phonenumbers.PhoneNumberUtil
-              .normalizeDigitsOnly(formattedNumber) ==
-          i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly(rawInput)) ?
+          i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(formattedNumber,
+              i18n.phonenumbers.PhoneNumberUtil.DIALLABLE_CHAR_MAPPINGS_,
+              true /* remove non matches */) ==
+          i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(rawInput,
+              i18n.phonenumbers.PhoneNumberUtil.DIALLABLE_CHAR_MAPPINGS_,
+              true /* remove non matches */)) ?
       formattedNumber :
       rawInput;
 };
   }
   if (countryCodeSource !=
       i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY) {
-    if (fullNumber.getLength() <
+    if (fullNumber.getLength() <=
         i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_) {
       throw i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD;
     }
  *
  * @param {?string} numberToParse number that we are attempting to parse. This
  *     can contain formatting such as +, ( and -, as well as a phone number
- *     extension.
+ *     extension. It can also be provided in RFC3966 format.
  * @param {?string} defaultRegion region 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
     throw 'The string supplied was too long to parse';
   }
 
-  /** @type {number} */
-  var indexOfPhoneContext = numberToParse.indexOf(
-      i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_);
   /** @type {!goog.string.StringBuffer} */
   var nationalNumber = new goog.string.StringBuffer();
-  if (indexOfPhoneContext > 0) {
-    // Prefix the number with the phone context. The offset here is because the
-    // context we are expecting to match should start with a "+" sign, and we
-    // want to include this at the start of the number.
-    nationalNumber.append(numberToParse.substring(
-        indexOfPhoneContext +
-        i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_.length - 1));
-    // Now append everything between the "tel:" prefix and the phone-context.
-    nationalNumber.append(numberToParse.substring(
-        numberToParse.indexOf(
-            i18n.phonenumbers.PhoneNumberUtil.RFC3966_PREFIX_) +
-        i18n.phonenumbers.PhoneNumberUtil.RFC3966_PREFIX_.length,
-        indexOfPhoneContext));
-    // Note that phone-contexts that are URLs will not be parsed -
-    // isViablePhoneNumber will throw an exception below.
-  } else {
-    // Extract a possible number from the string passed in (this strips leading
-    // characters that could not be the start of a phone number.)
-    nationalNumber.append(
-        i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber(numberToParse));
-  }
+  this.buildNationalNumberForParsing_(numberToParse, nationalNumber);
 
   if (!i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber(
       nationalNumber.toString())) {
 
 
 /**
+ * Converts numberToParse to a form that we can parse and write it to
+ * nationalNumber if it is written in RFC3966; otherwise extract a possible
+ * number out of it and write to nationalNumber.
+ *
+ * @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 {!goog.string.StringBuffer} nationalNumber a string buffer for storing
+ *     the national significant number.
+ * @private
+ */
+i18n.phonenumbers.PhoneNumberUtil.prototype.buildNationalNumberForParsing_ =
+    function(numberToParse, nationalNumber) {
+
+  /** @type {number} */
+  var indexOfPhoneContext = numberToParse.indexOf(
+      i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_);
+  if (indexOfPhoneContext > 0) {
+    var phoneContextStart = indexOfPhoneContext +
+        i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_.length;
+    // If the phone context contains a phone number prefix, we need to capture
+    // it, whereas domains will be ignored.
+    if (numberToParse.charAt(phoneContextStart) ==
+        i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) {
+      // Additional parameters might follow the phone context. If so, we will
+      // remove them here because the parameters after phone context are not
+      // important for parsing the phone number.
+      var phoneContextEnd = numberToParse.indexOf(';', phoneContextStart);
+      if (phoneContextEnd > 0) {
+        nationalNumber.append(numberToParse.substring(phoneContextStart,
+            phoneContextEnd));
+      } else {
+        nationalNumber.append(numberToParse.substring(phoneContextStart));
+      }
+    }
+
+    // Now append everything between the "tel:" prefix and the phone-context.
+    // This should include the national number, an optional extension or
+    // isdn-subaddress component.
+    nationalNumber.append(numberToParse.substring(
+        numberToParse.indexOf(
+            i18n.phonenumbers.PhoneNumberUtil.RFC3966_PREFIX_) +
+        i18n.phonenumbers.PhoneNumberUtil.RFC3966_PREFIX_.length,
+        indexOfPhoneContext));
+  } else {
+    // Extract a possible number from the string passed in (this strips leading
+    // characters that could not be the start of a phone number.)
+    nationalNumber.append(
+        i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber(numberToParse));
+  }
+
+  // Delete the isdn-subaddress and everything after it if it is present.
+  // Note extension won't appear at the same time with isdn-subaddress
+  // according to paragraph 5.3 of the RFC3966 spec,
+  /** @type {string} */
+  var nationalNumberStr = nationalNumber.toString();
+  var indexOfIsdn = nationalNumberStr.indexOf(
+      i18n.phonenumbers.PhoneNumberUtil.RFC3966_ISDN_SUBADDRESS_);
+  if (indexOfIsdn > 0) {
+    nationalNumber.clear();
+    nationalNumber.append(nationalNumberStr.substring(0, indexOfIsdn));
+  }
+  // If both phone context and isdn-subaddress are absent but other
+  // parameters are present, the parameters are left in nationalNumber. This
+  // is because we are concerned about deleting content from a potential
+  // number string when there is no strong evidence that the number is
+  // actually written in RFC3966.
+};
+
+
+/**
  * Takes two phone numbers and compares them for equality.
  *
  * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero

javascript/i18n/phonenumbers/phonenumberutil_test.js

 INTERNATIONAL_TOLL_FREE.setNationalNumber(12345678);
 
 
+// We set this to be the same length as numbers for the other non-geographical
+// country prefix that we have in our test metadata. However, this is not
+// considered valid because they differ in their country calling code.
 /** @type {i18n.phonenumbers.PhoneNumber} */
 var INTERNATIONAL_TOLL_FREE_TOO_LONG = new i18n.phonenumbers.PhoneNumber();
 INTERNATIONAL_TOLL_FREE_TOO_LONG.setCountryCode(800);
-INTERNATIONAL_TOLL_FREE_TOO_LONG.setNationalNumber(1234567890);
+INTERNATIONAL_TOLL_FREE_TOO_LONG.setNationalNumber(123456789);
+
+
+/** @type {i18n.phonenumbers.PhoneNumber} */
+var UNIVERSAL_PREMIUM_RATE = new i18n.phonenumbers.PhoneNumber();
+UNIVERSAL_PREMIUM_RATE.setCountryCode(979);
+UNIVERSAL_PREMIUM_RATE.setNationalNumber(123456789);
 
 var RegionCode = i18n.phonenumbers.RegionCode;
 
 function testGetExampleNumberForNonGeoEntity() {
   assertTrue(INTERNATIONAL_TOLL_FREE.equals(
       phoneUtil.getExampleNumberForNonGeoEntity(800)));
+  assertTrue(UNIVERSAL_PREMIUM_RATE.equals(
+      phoneUtil.getExampleNumberForNonGeoEntity(979)));
 }
 
 function testConvertAlphaCharactersInNumber() {
 
 function testNormaliseRemovePunctuation() {
   /** @type {string} */
-  var inputNumber = '034-56&+#234';
+  var inputNumber = '034-56&+#2\u00AD34';
   /** @type {string} */
   var expectedOutput = '03456234';
   assertEquals('Conversion did not correctly remove punctuation',
   assertEquals('0011 1 650 253 0000',
       phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU2,
                                        RegionCode.AU));
+
+  // Test the star sign is not removed from or added to the original input by
+  // this method.
+  /** @type {i18n.phonenumbers.PhoneNumber} */
+  var starNumber =
+      phoneUtil.parseAndKeepRawInput('*1234', RegionCode.JP);
+  assertEquals('*1234', phoneUtil.formatInOriginalFormat(starNumber,
+                                                         RegionCode.JP));
+  /** @type {i18n.phonenumbers.PhoneNumber} */
+  var numberWithoutStar = phoneUtil.parseAndKeepRawInput('1234', RegionCode.JP);
+  assertEquals('1234', phoneUtil.formatInOriginalFormat(numberWithoutStar,
+                                                        RegionCode.JP));
 }
 
 function testIsPremiumRate() {
   premiumRateNumber.setCountryCode(49);
   premiumRateNumber.setNationalNumber(90091234567);
   assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
+  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(
+      UNIVERSAL_PREMIUM_RATE));
 }
 
 function testIsTollFree() {
   assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
   assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
   assertTrue(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE));
+  assertTrue(phoneUtil.isValidNumber(UNIVERSAL_PREMIUM_RATE));
 
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var nzNumber = new i18n.phonenumbers.PhoneNumber();
   assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
   assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
   assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(800));
+  assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(979));
 }
 
 function testGetRegionCodeForNumber() {
   assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
   assertEquals(RegionCode.UN001,
       phoneUtil.getRegionCodeForNumber(INTERNATIONAL_TOLL_FREE));
+  assertEquals(RegionCode.UN001,
+      phoneUtil.getRegionCodeForNumber(UNIVERSAL_PREMIUM_RATE));
 }
 
 function testGetCountryCodeForRegion() {
   assertEquals(VR.IS_POSSIBLE,
       phoneUtil.isPossibleNumberWithReason(adNumber));
   adNumber.setCountryCode(376);
-  adNumber.setNationalNumber(13);
+  adNumber.setNationalNumber(1);
   assertEquals(VR.TOO_SHORT,
       phoneUtil.isPossibleNumberWithReason(adNumber));
   adNumber.setCountryCode(376);
       phoneUtil.parse('tel:331-6005;phone-context=+64-3', RegionCode.NZ)));
   assertTrue(NZ_NUMBER.equals(
       phoneUtil.parse('tel:331-6005;phone-context=+64-3', RegionCode.US)));
-
+  // Test parsing RFC3966 format with optional user-defined parameters. The
+  // parameters will appear after the context if present.
+  assertTrue(NZ_NUMBER.equals(
+      phoneUtil.parse('tel:03-331-6005;phone-context=+64;a=%A1',
+                      RegionCode.NZ)));
+  // Test parsing RFC3966 with an ISDN subaddress.
+  assertTrue(NZ_NUMBER.equals(
+      phoneUtil.parse('tel:03-331-6005;isub=12345;phone-context=+64',
+                      RegionCode.NZ)));
+  assertTrue(NZ_NUMBER.equals(
+      phoneUtil.parse('tel:+64-3-331-6005;isub=12345', RegionCode.NZ)));
   // Testing international prefixes.
   // Should strip country calling code.
   assertTrue(
   assertTrue(
       NZ_NUMBER.equals(phoneUtil.parse('+ 00 64 3 331 6005', RegionCode.NZ)));
 
+  assertTrue(US_LOCAL_NUMBER.equals(
+      phoneUtil.parse('tel:253-0000;phone-context=www.google.com',
+                      RegionCode.US)));
+  assertTrue(US_LOCAL_NUMBER.equals(
+      phoneUtil.parse('tel:253-0000;isub=12345;phone-context=www.google.com',
+                      RegionCode.US)));
+  // This is invalid because no "+" sign is present as part of phone-context.
+  // The phone context is simply ignored in this case just as if it contains a
+  // domain.
+  assertTrue(US_LOCAL_NUMBER.equals(
+      phoneUtil.parse('tel:2530000;isub=12345;phone-context=1-650',
+                      RegionCode.US)));
+  assertTrue(US_LOCAL_NUMBER.equals(
+      phoneUtil.parse('tel:2530000;isub=12345;phone-context=1234.com',
+                      RegionCode.US)));
+
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var nzNumber = new i18n.phonenumbers.PhoneNumber();
   nzNumber.setCountryCode(64);
   // Using a full-width plus sign.
   assertTrue(US_NUMBER.equals(
       phoneUtil.parse('\uFF0B1 (650) 253-0000', RegionCode.SG)));
+  // Using a soft hyphen U+00AD.
+  assertTrue(US_NUMBER.equals(
+      phoneUtil.parse('1 (650) 253\u00AD-0000', RegionCode.US)));
   // The whole number, including punctuation, is here represented in full-width
   // form.
   assertTrue(US_NUMBER.equals(
   }
   try {
     /** @type {string} */
-    var domainRfcPhoneContext = 'tel:555-1234;phone-context:www.google.com';
-    phoneUtil.parse(domainRfcPhoneContext, RegionCode.US);
-    fail('Domain provided for phone context - should fail.');
+    var domainRfcPhoneContext = 'tel:555-1234;phone-context=www.google.com';
+    phoneUtil.parse(domainRfcPhoneContext, RegionCode.ZZ);
+    fail('"Unknown" region code not allowed: should fail.');
   } catch (e) {
     // Expected this exception.
     assertEquals('Wrong error type stored in exception.',
-                 i18n.phonenumbers.Error.NOT_A_NUMBER,
+                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
                  e);
   }
   try {
     // This is invalid because no '+' sign is present as part of phone-context.
     // This should not succeed in being parsed.
     /** @type {string} */
-    var invalidRfcPhoneContext = 'tel:555-1234;phone-context:1-331';
-    phoneUtil.parse(invalidRfcPhoneContext, RegionCode.US);
-    fail('No leading plus provided in phone context - should fail.');
+    var invalidRfcPhoneContext = 'tel:555-1234;phone-context=1-331';
+    phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
+    fail('"Unknown" region code not allowed: should fail.');
   } catch (e) {
     // Expected this exception.
     assertEquals('Wrong error type stored in exception.',
-                 i18n.phonenumbers.Error.NOT_A_NUMBER,
+                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
                  e);
   }
 }
       NZ_NUMBER.equals(phoneUtil.parse('+64 3 331 6005', null)));
   assertTrue(
       INTERNATIONAL_TOLL_FREE.equals(phoneUtil.parse('+800 1234 5678', null)));
+  assertTrue(
+      UNIVERSAL_PREMIUM_RATE.equals(phoneUtil.parse('+979 123 456 789', null)));
 
   // Test parsing RFC3966 format with a phone context.
   assertTrue(NZ_NUMBER.equals(
       phoneUtil.parse('tel:03-331-6005;phone-context=+64', RegionCode.ZZ)));
   assertTrue(NZ_NUMBER.equals(
       phoneUtil.parse('  tel:03-331-6005;phone-context=+64', RegionCode.ZZ)));
+  assertTrue(NZ_NUMBER.equals(
+      phoneUtil.parse('tel:03-331-6005;isub=12345;phone-context=+64',
+                      RegionCode.ZZ)));
 
   // It is important that we set the carrier code to an empty string, since we
   // used ParseAndKeepRawInput and no carrier code was found.
                phoneUtil.isNumberMatch('+643 331-6005', '+6433316005'));
   assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
                phoneUtil.isNumberMatch('+64 3 331-6005', '+6433316005'));
+  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
+               phoneUtil.isNumberMatch('+64 3 331-6005',
+                                       'tel:+64-3-331-6005;isub=123'));
   // Test alpha numbers.
   assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
                phoneUtil.isNumberMatch('+1800 siX-Flags', '+1 800 7493 5247'));
   assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
                phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234',
                                        '0116433316005#1235'));
+  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
+               phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234',
+                                       'tel:+64-3-331-6005;ext=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',
   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('+64 3 331-6005',
+               'tel:03-331-6005;isub=1234;phone-context=abc.nz'));
+  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
                phoneUtil.isNumberMatch(NZ_NUMBER, '03 331 6005'));
   // Here the second number possibly starts with the country calling code for
   // New Zealand, although we are unsure.
   // 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('+64 3 331-6005',
+                                       'tel:331-6005;phone-context=abc.nz'));
+  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+               phoneUtil.isNumberMatch(
+                   '+64 3 331-6005',
+                   'tel:331-6005;isub=1234;phone-context=abc.nz'));
+  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+               phoneUtil.isNumberMatch(
+                   '+64 3 331-6005',
+                   'tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1'));
   // We did not know that the '0' was a national prefix since neither number has
   // a country code, so this is considered a SHORT_NSN_MATCH.
   assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
   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',
+                                       'tel:331-6005;phone-context=abc.nz'));
+  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,