text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
  	value: true
  });
  
  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // This is a port of Google Android `libphonenumber`'s
  // `phonenumberutil.js` of 17th November, 2016.
  //
  // https://github.com/googlei18n/libphonenumber/commits/master/javascript/i18n/phonenumbers/phonenumberutil.js
  
  exports.default = parse;
  exports.is_viable_phone_number = is_viable_phone_number;
  exports.extract_formatted_phone_number = extract_formatted_phone_number;
  exports.strip_national_prefix_and_carrier_code = strip_national_prefix_and_carrier_code;
  exports.find_country_code = find_country_code;
  
  var _common = require('./common');
  
  var _parseIncompletePhoneNumber = require('./parseIncompletePhoneNumber');
  
  var _parseIncompletePhoneNumber2 = _interopRequireDefault(_parseIncompletePhoneNumber);
  
  var _metadata = require('./metadata');
  
  var _metadata2 = _interopRequireDefault(_metadata);
  
  var _getCountryCallingCode = require('./getCountryCallingCode');
  
  var _getCountryCallingCode2 = _interopRequireDefault(_getCountryCallingCode);
  
  var _getNumberType = require('./getNumberType');
  
  var _getNumberType2 = _interopRequireDefault(_getNumberType);
  
  var _isPossibleNumber = require('./isPossibleNumber');
  
  var _RFC = require('./RFC3966');
  
  var _PhoneNumber = require('./PhoneNumber');
  
  var _PhoneNumber2 = _interopRequireDefault(_PhoneNumber);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // The minimum length of the national significant number.
  var MIN_LENGTH_FOR_NSN = 2;
  
  // We don't allow input strings for parsing to be longer than 250 chars.
  // This prevents malicious input from consuming CPU.
  var MAX_INPUT_STRING_LENGTH = 250;
  
  /**
   * 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 three regular expressions
   * here. The first covers RFC 3966 format, where the extension is added using
   * ';ext='. The second more generic one starts with optional white space and
   * ends with an optional full stop (.), followed by zero or more spaces/tabs
   * /commas 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! We allow two options for representing the accented o - the
   * character itself, and one in the unicode decomposed form with the combining
   * acute accent.
   */
  var EXTN_PATTERNS_FOR_PARSING = (0, _common.create_extension_pattern)('parsing');
  
  // Regexp of all known extension prefixes used by different regions followed by
  // 1 or more valid digits, for use when parsing.
  var EXTN_PATTERN = new RegExp('(?:' + EXTN_PATTERNS_FOR_PARSING + ')$', 'i');
  
  //  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. We also allow multiple '+' characters at the start.
  //
  //  Corresponds to the following:
  //  [digits]{minLengthNsn}|
  //  plus_sign*
  //  (([punctuation]|[star])*[digits]){3,}([punctuation]|[star]|[digits]|[alpha])*
  //
  //  The first reg-ex is to allow short numbers (two digits long) to be parsed if
  //  they are entered as "15" etc, but only if there is no punctuation in them.
  //  The second expression restricts the number of digits to three or more, but
  //  then allows them to be in international form, and to have alpha-characters
  //  and punctuation. We split up the two reg-exes here and combine them when
  //  creating the reg-ex VALID_PHONE_NUMBER_PATTERN itself so we can prefix it
  //  with ^ and append $ to each branch.
  //
  //  "Note VALID_PUNCTUATION starts with a -,
  //   so must be the first in the range" (c) Google devs.
  //  (wtf did they mean by saying that; probably nothing)
  //
  var MIN_LENGTH_PHONE_NUMBER_PATTERN = '[' + _common.VALID_DIGITS + ']{' + MIN_LENGTH_FOR_NSN + '}';
  //
  // And this is the second reg-exp:
  // (see MIN_LENGTH_PHONE_NUMBER_PATTERN for a full description of this reg-exp)
  //
  var VALID_PHONE_NUMBER = '[' + _common.PLUS_CHARS + ']{0,1}' + '(?:' + '[' + _common.VALID_PUNCTUATION + ']*' + '[' + _common.VALID_DIGITS + ']' + '){3,}' + '[' + _common.VALID_PUNCTUATION + _common.VALID_DIGITS + ']*';
  
  // The combined regular expression for valid phone numbers:
  //
  var VALID_PHONE_NUMBER_PATTERN = new RegExp(
  // Either a short two-digit-only phone number
  '^' + MIN_LENGTH_PHONE_NUMBER_PATTERN + '$' + '|' +
  // Or a longer fully parsed phone number (min 3 characters)
  '^' + VALID_PHONE_NUMBER +
  // Phone number extensions
  '(?:' + EXTN_PATTERNS_FOR_PARSING + ')?' + '$', 'i');
  
  // This consists of the plus symbol, digits, and arabic-indic digits.
  var PHONE_NUMBER_START_PATTERN = new RegExp('[' + _common.PLUS_CHARS + _common.VALID_DIGITS + ']');
  
  // Regular expression of trailing characters that we want to remove.
  var AFTER_PHONE_NUMBER_END_PATTERN = new RegExp('[^' + _common.VALID_DIGITS + ']+$');
  
  var default_options = {
  	country: {}
  
  	// `options`:
  	//  {
  	//    country:
  	//    {
  	//      restrict - (a two-letter country code)
  	//                 the phone number must be in this country
  	//
  	//      default - (a two-letter country code)
  	//                default country to use for phone number parsing and validation
  	//                (if no country code could be derived from the phone number)
  	//    }
  	//  }
  	//
  	// Returns `{ country, number }`
  	//
  	// Example use cases:
  	//
  	// ```js
  	// parse('8 (800) 555-35-35', 'RU')
  	// parse('8 (800) 555-35-35', 'RU', metadata)
  	// parse('8 (800) 555-35-35', { country: { default: 'RU' } })
  	// parse('8 (800) 555-35-35', { country: { default: 'RU' } }, metadata)
  	// parse('+7 800 555 35 35')
  	// parse('+7 800 555 35 35', metadata)
  	// ```
  	//
  };function parse(arg_1, arg_2, arg_3, arg_4) {
  	var _sort_out_arguments = sort_out_arguments(arg_1, arg_2, arg_3, arg_4),
  	    text = _sort_out_arguments.text,
  	    options = _sort_out_arguments.options,
  	    metadata = _sort_out_arguments.metadata;
  
  	// Validate `defaultCountry`.
  
  
  	if (options.defaultCountry && !metadata.hasCountry(options.defaultCountry)) {
  		if (options.v2) {
  			throw new Error('INVALID_COUNTRY');
  		}
  		throw new Error('Unknown country: ' + options.defaultCountry);
  	}
  
  	// Parse the phone number.
  
  	var _parse_input = parse_input(text, options.v2),
  	    formatted_phone_number = _parse_input.number,
  	    ext = _parse_input.ext;
  
  	// If the phone number is not viable then return nothing.
  
  
  	if (!formatted_phone_number) {
  		if (options.v2) {
  			throw new Error('NOT_A_NUMBER');
  		}
  		return {};
  	}
  
  	var _parse_phone_number = parse_phone_number(formatted_phone_number, options.defaultCountry, metadata),
  	    country = _parse_phone_number.country,
  	    nationalNumber = _parse_phone_number.national_number,
  	    countryCallingCode = _parse_phone_number.countryCallingCode,
  	    carrierCode = _parse_phone_number.carrierCode;
  
  	if (!metadata.selectedCountry()) {
  		if (options.v2) {
  			throw new Error('INVALID_COUNTRY');
  		}
  		return {};
  	}
  
  	// Validate national (significant) number length.
  	if (nationalNumber.length < MIN_LENGTH_FOR_NSN) {
  		// Won't throw here because the regexp already demands length > 1.
  		/* istanbul ignore if */
  		if (options.v2) {
  			throw new Error('TOO_SHORT');
  		}
  		// Google's demo just throws an error in this case.
  		return {};
  	}
  
  	// Validate national (significant) number length.
  	//
  	// A sidenote:
  	//
  	// They say that sometimes national (significant) numbers
  	// can be longer than `MAX_LENGTH_FOR_NSN` (e.g. in Germany).
  	// https://github.com/googlei18n/libphonenumber/blob/7e1748645552da39c4e1ba731e47969d97bdb539/resources/phonenumber.proto#L36
  	// Such numbers will just be discarded.
  	//
  	if (nationalNumber.length > _common.MAX_LENGTH_FOR_NSN) {
  		if (options.v2) {
  			throw new Error('TOO_LONG');
  		}
  		// Google's demo just throws an error in this case.
  		return {};
  	}
  
  	if (options.v2) {
  		var phoneNumber = new _PhoneNumber2.default(countryCallingCode, nationalNumber, metadata.metadata);
  
  		if (country) {
  			phoneNumber.country = country;
  		}
  		if (carrierCode) {
  			phoneNumber.carrierCode = carrierCode;
  		}
  		if (ext) {
  			phoneNumber.ext = ext;
  		}
  
  		return phoneNumber;
  	}
  
  	// Check if national phone number pattern matches the number.
  	// National number pattern is different for each country,
  	// even for those ones which are part of the "NANPA" group.
  	var valid = country && (0, _common.matches_entirely)(nationalNumber, metadata.nationalNumberPattern()) ? true : false;
  
  	if (!options.extended) {
  		return valid ? result(country, nationalNumber, ext) : {};
  	}
  
  	return {
  		country: country,
  		countryCallingCode: countryCallingCode,
  		carrierCode: carrierCode,
  		valid: valid,
  		possible: valid ? true : options.extended === true && metadata.possibleLengths() && (0, _isPossibleNumber.is_possible_number)(nationalNumber, countryCallingCode !== undefined, metadata),
  		phone: nationalNumber,
  		ext: ext
  	};
  }
  
  // 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 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
  // `extract_possible_number`.
  //
  function is_viable_phone_number(number) {
  	return number.length >= MIN_LENGTH_FOR_NSN && VALID_PHONE_NUMBER_PATTERN.test(number);
  }
  
  /**
   * Extracts a parseable phone number.
   * @param  {string} text - Input.
   * @return {string}.
   */
  function extract_formatted_phone_number(text, v2) {
  	if (!text) {
  		return;
  	}
  
  	if (text.length > MAX_INPUT_STRING_LENGTH) {
  		if (v2) {
  			throw new Error('TOO_LONG');
  		}
  		return;
  	}
  
  	// Attempt to extract a possible number from the string passed in
  
  	var starts_at = text.search(PHONE_NUMBER_START_PATTERN);
  
  	if (starts_at < 0) {
  		return;
  	}
  
  	return text
  	// Trim everything to the left of the phone number
  	.slice(starts_at)
  	// Remove trailing non-numerical characters
  	.replace(AFTER_PHONE_NUMBER_END_PATTERN, '');
  }
  
  // Strips any national prefix (such as 0, 1) present in the number provided.
  // "Carrier codes" are only used  in Colombia and Brazil,
  // and only when dialing within those countries from a mobile phone to a fixed line number.
  function strip_national_prefix_and_carrier_code(number, metadata) {
  	if (!number || !metadata.nationalPrefixForParsing()) {
  		return { number: number };
  	}
  
  	// Attempt to parse the first digits as a national prefix
  	var national_prefix_pattern = new RegExp('^(?:' + metadata.nationalPrefixForParsing() + ')');
  	var national_prefix_matcher = national_prefix_pattern.exec(number);
  
  	// If no national prefix is present in the phone number,
  	// but the national prefix is optional for this country,
  	// then consider this phone number valid.
  	//
  	// Google's reference `libphonenumber` implementation
  	// wouldn't recognize such phone numbers as valid,
  	// but I think it would perfectly make sense
  	// to consider such phone numbers as valid
  	// because if a national phone number was originally
  	// formatted without the national prefix
  	// then it must be parseable back into the original national number.
  	// In other words, `parse(format(number))`
  	// must always be equal to `number`.
  	//
  	if (!national_prefix_matcher) {
  		return { number: number };
  	}
  
  	var national_significant_number = void 0;
  
  	// `national_prefix_for_parsing` capturing groups
  	// (used only for really messy cases: Argentina, Brazil, Mexico, Somalia)
  	var captured_groups_count = national_prefix_matcher.length - 1;
  
  	// If the national number tranformation is needed then do it.
  	//
  	// `national_prefix_matcher[captured_groups_count]` means that
  	// the corresponding captured group is not empty.
  	// It can be empty if it's optional.
  	// Example: "0?(?:...)?" for Argentina.
  	//
  	if (metadata.nationalPrefixTransformRule() && national_prefix_matcher[captured_groups_count]) {
  		national_significant_number = number.replace(national_prefix_pattern, metadata.nationalPrefixTransformRule());
  	}
  	// Else, no transformation is necessary,
  	// and just strip the national prefix.
  	else {
  			national_significant_number = number.slice(national_prefix_matcher[0].length);
  		}
  
  	var carrierCode = void 0;
  	if (captured_groups_count > 0) {
  		carrierCode = national_prefix_matcher[1];
  	}
  
  	// The following is done in `get_country_and_national_number_for_local_number()` instead.
  	//
  	// // Verify the parsed national (significant) number for this country
  	// const national_number_rule = new RegExp(metadata.nationalNumberPattern())
  	// //
  	// // If the original number (before stripping national prefix) was viable,
  	// // and the resultant number is not, then prefer the original phone number.
  	// // This is because for some countries (e.g. Russia) the same digit could be both
  	// // a national prefix and a leading digit of a valid national phone number,
  	// // like `8` is the national prefix for Russia and both
  	// // `8 800 555 35 35` and `800 555 35 35` are valid numbers.
  	// if (matches_entirely(number, national_number_rule) &&
  	// 		!matches_entirely(national_significant_number, national_number_rule))
  	// {
  	// 	return number
  	// }
  
  	// Return the parsed national (significant) number
  	return {
  		number: national_significant_number,
  		carrierCode: carrierCode
  	};
  }
  
  function find_country_code(country_calling_code, national_phone_number, metadata) {
  	// Is always non-empty, because `country_calling_code` is always valid
  	var possible_countries = metadata.countryCallingCodes()[country_calling_code];
  
  	// If there's just one country corresponding to the country code,
  	// then just return it, without further phone number digits validation.
  	if (possible_countries.length === 1) {
  		return possible_countries[0];
  	}
  
  	return _find_country_code(possible_countries, national_phone_number, metadata.metadata);
  }
  
  // Changes `metadata` `country`.
  function _find_country_code(possible_countries, national_phone_number, metadata) {
  	metadata = new _metadata2.default(metadata);
  
  	for (var _iterator = possible_countries, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  		var _ref;
  
  		if (_isArray) {
  			if (_i >= _iterator.length) break;
  			_ref = _iterator[_i++];
  		} else {
  			_i = _iterator.next();
  			if (_i.done) break;
  			_ref = _i.value;
  		}
  
  		var country = _ref;
  
  		metadata.country(country);
  
  		// Leading digits check would be the simplest one
  		if (metadata.leadingDigits()) {
  			if (national_phone_number && national_phone_number.search(metadata.leadingDigits()) === 0) {
  				return country;
  			}
  		}
  		// Else perform full validation with all of those
  		// fixed-line/mobile/etc regular expressions.
  		else if ((0, _getNumberType2.default)({ phone: national_phone_number, country: country }, metadata.metadata)) {
  				return country;
  			}
  	}
  }
  
  // Sort out arguments
  function sort_out_arguments(arg_1, arg_2, arg_3, arg_4) {
  	var text = void 0;
  	var options = void 0;
  	var metadata = void 0;
  
  	// If the phone number is passed as a string.
  	// `parse('88005553535', ...)`.
  	if (typeof arg_1 === 'string') {
  		text = arg_1;
  	} else throw new TypeError('A phone number for parsing must be a string.');
  
  	// If "default country" argument is being passed
  	// then move it to `options`.
  	// `parse('88005553535', 'RU', [options], metadata)`.
  	if ((typeof arg_2 === 'undefined' ? 'undefined' : _typeof(arg_2)) !== 'object') {
  		if (arg_4) {
  			options = _extends({ defaultCountry: arg_2 }, arg_3);
  			metadata = arg_4;
  		} else {
  			options = { defaultCountry: arg_2 };
  			metadata = arg_3;
  		}
  	}
  	// No "default country" argument is being passed.
  	// International phone number is passed.
  	// `parse('+78005553535', [options], metadata)`.
  	else {
  			if (arg_3) {
  				options = arg_2;
  				metadata = arg_3;
  			} else {
  				metadata = arg_2;
  			}
  		}
  
  	// Apply default options.
  	if (options) {
  		options = _extends({}, default_options, options);
  	} else {
  		options = default_options;
  	}
  
  	return { text: text, options: options, metadata: new _metadata2.default(metadata) };
  }
  
  // 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.
  function strip_extension(number) {
  	var start = number.search(EXTN_PATTERN);
  	if (start < 0) {
  		return {};
  	}
  
  	// If we find a potential extension, and the number preceding this is a viable
  	// number, we assume it is an extension.
  	var number_without_extension = number.slice(0, start);
  	/* istanbul ignore if - seems a bit of a redundant check */
  	if (!is_viable_phone_number(number_without_extension)) {
  		return {};
  	}
  
  	var matches = number.match(EXTN_PATTERN);
  	var i = 1;
  	while (i < matches.length) {
  		if (matches[i] != null && matches[i].length > 0) {
  			return {
  				number: number_without_extension,
  				ext: matches[i]
  			};
  		}
  		i++;
  	}
  }
  
  /**
   * @param  {string} text - Input.
   * @return {object} `{ ?number, ?ext }`.
   */
  function parse_input(text, v2) {
  	// Parse RFC 3966 phone number URI.
  	if (text && text.indexOf('tel:') === 0) {
  		return (0, _RFC.parseRFC3966)(text);
  	}
  
  	var number = extract_formatted_phone_number(text, v2);
  
  	// If the phone number is not viable, then abort.
  	if (!number || !is_viable_phone_number(number)) {
  		return {};
  	}
  
  	// Attempt to parse extension first, since it doesn't require region-specific
  	// data and we want to have the non-normalised number here.
  	var with_extension_stripped = strip_extension(number);
  	if (with_extension_stripped.ext) {
  		return with_extension_stripped;
  	}
  
  	return { number: number };
  }
  
  /**
   * Creates `parse()` result object.
   */
  function result(country, national_number, ext) {
  	var result = {
  		country: country,
  		phone: national_number
  	};
  
  	if (ext) {
  		result.ext = ext;
  	}
  
  	return result;
  }
  
  /**
   * Parses a viable phone number.
   * Returns `{ country, countryCallingCode, national_number }`.
   */
  function parse_phone_number(formatted_phone_number, default_country, metadata) {
  	var _extractCountryCallin = (0, _common.extractCountryCallingCode)(formatted_phone_number, default_country, metadata.metadata),
  	    countryCallingCode = _extractCountryCallin.countryCallingCode,
  	    number = _extractCountryCallin.number;
  
  	if (!number) {
  		return { countryCallingCode: countryCallingCode };
  	}
  
  	var country = void 0;
  
  	if (countryCallingCode) {
  		metadata.chooseCountryByCountryCallingCode(countryCallingCode);
  	} else if (default_country) {
  		metadata.country(default_country);
  		country = default_country;
  		countryCallingCode = (0, _getCountryCallingCode2.default)(default_country, metadata.metadata);
  	} else return {};
  
  	var _parse_national_numbe = parse_national_number(number, metadata),
  	    national_number = _parse_national_numbe.national_number,
  	    carrier_code = _parse_national_numbe.carrier_code;
  
  	// Sometimes there are several countries
  	// corresponding to the same country phone code
  	// (e.g. NANPA countries all having `1` country phone code).
  	// Therefore, to reliably determine the exact country,
  	// national (significant) number should have been parsed first.
  	//
  	// When `metadata.json` is generated, all "ambiguous" country phone codes
  	// get their countries populated with the full set of
  	// "phone number type" regular expressions.
  	//
  
  
  	var exactCountry = find_country_code(countryCallingCode, national_number, metadata);
  	if (exactCountry) {
  		country = exactCountry;
  		metadata.country(country);
  	}
  
  	return {
  		country: country,
  		countryCallingCode: countryCallingCode,
  		national_number: national_number,
  		carrierCode: carrier_code
  	};
  }
  
  function parse_national_number(number, metadata) {
  	var national_number = (0, _parseIncompletePhoneNumber2.default)(number);
  	var carrier_code = void 0;
  
  	// Only strip national prefixes for non-international phone numbers
  	// because national prefixes can't be present in international phone numbers.
  	// Otherwise, while forgiving, it would parse a NANPA number `+1 1877 215 5230`
  	// first to `1877 215 5230` and then, stripping the leading `1`, to `877 215 5230`,
  	// and then it would assume that's a valid number which it isn't.
  	// So no forgiveness for grandmas here.
  	// The issue asking for this fix:
  	// https://github.com/catamphetamine/libphonenumber-js/issues/159
  
  	var _strip_national_prefi = strip_national_prefix_and_carrier_code(national_number, metadata),
  	    potential_national_number = _strip_national_prefi.number,
  	    carrierCode = _strip_national_prefi.carrierCode;
  
  	// If metadata has "possible lengths" then employ the new algorythm.
  
  
  	if (metadata.possibleLengths()) {
  		// We require that the NSN remaining after stripping the national prefix and
  		// carrier code be long enough to be a possible length for the region.
  		// Otherwise, we don't do the stripping, since the original number could be
  		// a valid short number.
  		switch ((0, _getNumberType.check_number_length_for_type)(potential_national_number, undefined, metadata)) {
  			case 'TOO_SHORT':
  			// case 'IS_POSSIBLE_LOCAL_ONLY':
  			case 'INVALID_LENGTH':
  				break;
  			default:
  				national_number = potential_national_number;
  				carrier_code = carrierCode;
  		}
  	} else {
  		// If the original number (before stripping national prefix) was viable,
  		// and the resultant number is not, then prefer the original phone number.
  		// This is because for some countries (e.g. Russia) the same digit could be both
  		// a national prefix and a leading digit of a valid national phone number,
  		// like `8` is the national prefix for Russia and both
  		// `8 800 555 35 35` and `800 555 35 35` are valid numbers.
  		if ((0, _common.matches_entirely)(national_number, metadata.nationalNumberPattern()) && !(0, _common.matches_entirely)(potential_national_number, metadata.nationalNumberPattern())) {
  			// Keep the number without stripping national prefix.
  		} else {
  			national_number = potential_national_number;
  			carrier_code = carrierCode;
  		}
  	}
  
  	return {
  		national_number: national_number,
  		carrier_code: carrier_code
  	};
  }
  
  // Determines the country for a given (possibly incomplete) phone number.
  // export function get_country_from_phone_number(number, metadata)
  // {
  // 	return parse_phone_number(number, null, metadata).country
  // }
  //# sourceMappingURL=parse.js.map