2333 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			2333 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* compromise-numbers 1.1.0 MIT */
 | ||
| (function (global, factory) {
 | ||
|   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
 | ||
|   typeof define === 'function' && define.amd ? define(factory) :
 | ||
|   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.compromiseNumbers = factory());
 | ||
| }(this, (function () { 'use strict';
 | ||
| 
 | ||
|   function _classCallCheck(instance, Constructor) {
 | ||
|     if (!(instance instanceof Constructor)) {
 | ||
|       throw new TypeError("Cannot call a class as a function");
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   function _inherits(subClass, superClass) {
 | ||
|     if (typeof superClass !== "function" && superClass !== null) {
 | ||
|       throw new TypeError("Super expression must either be null or a function");
 | ||
|     }
 | ||
| 
 | ||
|     subClass.prototype = Object.create(superClass && superClass.prototype, {
 | ||
|       constructor: {
 | ||
|         value: subClass,
 | ||
|         writable: true,
 | ||
|         configurable: true
 | ||
|       }
 | ||
|     });
 | ||
|     if (superClass) _setPrototypeOf(subClass, superClass);
 | ||
|   }
 | ||
| 
 | ||
|   function _getPrototypeOf(o) {
 | ||
|     _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
 | ||
|       return o.__proto__ || Object.getPrototypeOf(o);
 | ||
|     };
 | ||
|     return _getPrototypeOf(o);
 | ||
|   }
 | ||
| 
 | ||
|   function _setPrototypeOf(o, p) {
 | ||
|     _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
 | ||
|       o.__proto__ = p;
 | ||
|       return o;
 | ||
|     };
 | ||
| 
 | ||
|     return _setPrototypeOf(o, p);
 | ||
|   }
 | ||
| 
 | ||
|   function _isNativeReflectConstruct() {
 | ||
|     if (typeof Reflect === "undefined" || !Reflect.construct) return false;
 | ||
|     if (Reflect.construct.sham) return false;
 | ||
|     if (typeof Proxy === "function") return true;
 | ||
| 
 | ||
|     try {
 | ||
|       Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
 | ||
|       return true;
 | ||
|     } catch (e) {
 | ||
|       return false;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   function _assertThisInitialized(self) {
 | ||
|     if (self === void 0) {
 | ||
|       throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
 | ||
|     }
 | ||
| 
 | ||
|     return self;
 | ||
|   }
 | ||
| 
 | ||
|   function _possibleConstructorReturn(self, call) {
 | ||
|     if (call && (typeof call === "object" || typeof call === "function")) {
 | ||
|       return call;
 | ||
|     }
 | ||
| 
 | ||
|     return _assertThisInitialized(self);
 | ||
|   }
 | ||
| 
 | ||
|   function _createSuper(Derived) {
 | ||
|     var hasNativeReflectConstruct = _isNativeReflectConstruct();
 | ||
| 
 | ||
|     return function _createSuperInternal() {
 | ||
|       var Super = _getPrototypeOf(Derived),
 | ||
|           result;
 | ||
| 
 | ||
|       if (hasNativeReflectConstruct) {
 | ||
|         var NewTarget = _getPrototypeOf(this).constructor;
 | ||
| 
 | ||
|         result = Reflect.construct(Super, arguments, NewTarget);
 | ||
|       } else {
 | ||
|         result = Super.apply(this, arguments);
 | ||
|       }
 | ||
| 
 | ||
|       return _possibleConstructorReturn(this, result);
 | ||
|     };
 | ||
|   }
 | ||
| 
 | ||
|   var tens = 'twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|fourty';
 | ||
|   var teens = 'eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen'; // this is a bit of a mess
 | ||
| 
 | ||
|   var findNumbers = function findNumbers(doc, n) {
 | ||
|     var match = doc.match('#Value+'); //"50 83"
 | ||
| 
 | ||
|     if (match.has('#NumericValue #NumericValue')) {
 | ||
|       //a comma may mean two numbers
 | ||
|       if (match.has('#Value @hasComma #Value')) {
 | ||
|         match.splitAfter('@hasComma');
 | ||
|       } else if (match.has('#NumericValue #Fraction')) {
 | ||
|         match.splitAfter('#NumericValue #Fraction');
 | ||
|       } else {
 | ||
|         match = match.splitAfter('#NumericValue');
 | ||
|       }
 | ||
|     } //three-length
 | ||
| 
 | ||
| 
 | ||
|     if (match.has('#Value #Value #Value') && !match.has('#Multiple')) {
 | ||
|       //twenty-five-twenty
 | ||
|       if (match.has('(' + tens + ') #Cardinal #Cardinal')) {
 | ||
|         match = match.splitAfter('(' + tens + ') #Cardinal');
 | ||
|       }
 | ||
|     } //two-length ones
 | ||
| 
 | ||
| 
 | ||
|     if (match.has('#Value #Value')) {
 | ||
|       //june 21st 1992 is two seperate values
 | ||
|       if (match.has('#NumericValue #NumericValue')) {
 | ||
|         match = match.splitOn('#Year');
 | ||
|       } //sixty fifteen
 | ||
| 
 | ||
| 
 | ||
|       if (match.has('(' + tens + ') (' + teens + ')')) {
 | ||
|         match = match.splitAfter('(' + tens + ')');
 | ||
|       } //"72 82"
 | ||
| 
 | ||
| 
 | ||
|       var _double = match.match('#Cardinal #Cardinal');
 | ||
| 
 | ||
|       if (_double.found && !match.has('(point|decimal)')) {
 | ||
|         //not 'two hundred'
 | ||
|         if (!_double.has('#Cardinal (#Multiple|point|decimal)')) {
 | ||
|           //one proper way, 'twenty one', or 'hundred one'
 | ||
|           if (!_double.has('(' + tens + ') #Cardinal') && !_double.has('#Multiple #Value')) {
 | ||
|             // double = double.firstTerm()
 | ||
|             _double.terms().forEach(function (d) {
 | ||
|               match = match.splitOn(d);
 | ||
|             });
 | ||
|           }
 | ||
|         }
 | ||
|       } //seventh fifth
 | ||
| 
 | ||
| 
 | ||
|       if (match.match('#Ordinal #Ordinal').match('#TextValue').found && !match.has('#Multiple')) {
 | ||
|         //the one proper way, 'twenty first'
 | ||
|         if (!match.has('(' + tens + ') #Ordinal')) {
 | ||
|           match = match.splitAfter('#Ordinal');
 | ||
|         }
 | ||
|       } //fifth five
 | ||
| 
 | ||
| 
 | ||
|       if (match.has('#Ordinal #Cardinal')) {
 | ||
|         match = match.splitBefore('#Cardinal+');
 | ||
|       } //five 2017 (support '5 hundred', and 'twenty 5'
 | ||
| 
 | ||
| 
 | ||
|       if (match.has('#TextValue #NumericValue') && !match.has('(' + tens + '|#Multiple)')) {
 | ||
|         match = match.splitBefore('#NumericValue+');
 | ||
|       }
 | ||
|     } //5-8
 | ||
| 
 | ||
| 
 | ||
|     if (match.has('#NumberRange')) {
 | ||
|       match = match.splitAfter('#NumberRange');
 | ||
|     } //grab (n)th result
 | ||
| 
 | ||
| 
 | ||
|     if (typeof n === 'number') {
 | ||
|       match = match.get(n);
 | ||
|     }
 | ||
| 
 | ||
|     return match;
 | ||
|   };
 | ||
| 
 | ||
|   var find = findNumbers;
 | ||
| 
 | ||
|   //support global multipliers, like 'half-million' by doing 'million' then multiplying by 0.5
 | ||
|   var findModifiers = function findModifiers(str) {
 | ||
|     var mults = [{
 | ||
|       reg: /^(minus|negative)[\s\-]/i,
 | ||
|       mult: -1
 | ||
|     }, {
 | ||
|       reg: /^(a\s)?half[\s\-](of\s)?/i,
 | ||
|       mult: 0.5
 | ||
|     } //  {
 | ||
|     //   reg: /^(a\s)?quarter[\s\-]/i,
 | ||
|     //   mult: 0.25
 | ||
|     // }
 | ||
|     ];
 | ||
| 
 | ||
|     for (var i = 0; i < mults.length; i++) {
 | ||
|       if (mults[i].reg.test(str) === true) {
 | ||
|         return {
 | ||
|           amount: mults[i].mult,
 | ||
|           str: str.replace(mults[i].reg, '')
 | ||
|         };
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     return {
 | ||
|       amount: 1,
 | ||
|       str: str
 | ||
|     };
 | ||
|   };
 | ||
| 
 | ||
|   var findModifiers_1 = findModifiers;
 | ||
| 
 | ||
|   var data = {
 | ||
|     ones: {
 | ||
|       zeroth: 0,
 | ||
|       first: 1,
 | ||
|       second: 2,
 | ||
|       third: 3,
 | ||
|       fourth: 4,
 | ||
|       fifth: 5,
 | ||
|       sixth: 6,
 | ||
|       seventh: 7,
 | ||
|       eighth: 8,
 | ||
|       ninth: 9,
 | ||
|       zero: 0,
 | ||
|       one: 1,
 | ||
|       two: 2,
 | ||
|       three: 3,
 | ||
|       four: 4,
 | ||
|       five: 5,
 | ||
|       six: 6,
 | ||
|       seven: 7,
 | ||
|       eight: 8,
 | ||
|       nine: 9
 | ||
|     },
 | ||
|     teens: {
 | ||
|       tenth: 10,
 | ||
|       eleventh: 11,
 | ||
|       twelfth: 12,
 | ||
|       thirteenth: 13,
 | ||
|       fourteenth: 14,
 | ||
|       fifteenth: 15,
 | ||
|       sixteenth: 16,
 | ||
|       seventeenth: 17,
 | ||
|       eighteenth: 18,
 | ||
|       nineteenth: 19,
 | ||
|       ten: 10,
 | ||
|       eleven: 11,
 | ||
|       twelve: 12,
 | ||
|       thirteen: 13,
 | ||
|       fourteen: 14,
 | ||
|       fifteen: 15,
 | ||
|       sixteen: 16,
 | ||
|       seventeen: 17,
 | ||
|       eighteen: 18,
 | ||
|       nineteen: 19
 | ||
|     },
 | ||
|     tens: {
 | ||
|       twentieth: 20,
 | ||
|       thirtieth: 30,
 | ||
|       fortieth: 40,
 | ||
|       fourtieth: 40,
 | ||
|       fiftieth: 50,
 | ||
|       sixtieth: 60,
 | ||
|       seventieth: 70,
 | ||
|       eightieth: 80,
 | ||
|       ninetieth: 90,
 | ||
|       twenty: 20,
 | ||
|       thirty: 30,
 | ||
|       forty: 40,
 | ||
|       fourty: 40,
 | ||
|       fifty: 50,
 | ||
|       sixty: 60,
 | ||
|       seventy: 70,
 | ||
|       eighty: 80,
 | ||
|       ninety: 90
 | ||
|     },
 | ||
|     multiples: {
 | ||
|       hundredth: 100,
 | ||
|       thousandth: 1000,
 | ||
|       millionth: 1e6,
 | ||
|       billionth: 1e9,
 | ||
|       trillionth: 1e12,
 | ||
|       quadrillionth: 1e15,
 | ||
|       quintillionth: 1e18,
 | ||
|       sextillionth: 1e21,
 | ||
|       septillionth: 1e24,
 | ||
|       hundred: 100,
 | ||
|       thousand: 1000,
 | ||
|       million: 1e6,
 | ||
|       billion: 1e9,
 | ||
|       trillion: 1e12,
 | ||
|       quadrillion: 1e15,
 | ||
|       quintillion: 1e18,
 | ||
|       sextillion: 1e21,
 | ||
|       septillion: 1e24,
 | ||
|       grand: 1000
 | ||
|     }
 | ||
|   };
 | ||
| 
 | ||
|   var isValid = function isValid(w, has) {
 | ||
|     if (data.ones.hasOwnProperty(w)) {
 | ||
|       if (has.ones || has.teens) {
 | ||
|         return false;
 | ||
|       }
 | ||
|     } else if (data.teens.hasOwnProperty(w)) {
 | ||
|       if (has.ones || has.teens || has.tens) {
 | ||
|         return false;
 | ||
|       }
 | ||
|     } else if (data.tens.hasOwnProperty(w)) {
 | ||
|       if (has.ones || has.teens || has.tens) {
 | ||
|         return false;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     return true;
 | ||
|   };
 | ||
| 
 | ||
|   var validate = isValid;
 | ||
| 
 | ||
|   var parseDecimals = function parseDecimals(arr) {
 | ||
|     var str = '0.';
 | ||
| 
 | ||
|     for (var i = 0; i < arr.length; i++) {
 | ||
|       var w = arr[i];
 | ||
| 
 | ||
|       if (data.ones.hasOwnProperty(w) === true) {
 | ||
|         str += data.ones[w];
 | ||
|       } else if (data.teens.hasOwnProperty(w) === true) {
 | ||
|         str += data.teens[w];
 | ||
|       } else if (data.tens.hasOwnProperty(w) === true) {
 | ||
|         str += data.tens[w];
 | ||
|       } else if (/^[0-9]$/.test(w) === true) {
 | ||
|         str += w;
 | ||
|       } else {
 | ||
|         return 0;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     return parseFloat(str);
 | ||
|   };
 | ||
| 
 | ||
|   var parseDecimals_1 = parseDecimals;
 | ||
| 
 | ||
|   //parse a string like "4,200.1" into Number 4200.1
 | ||
|   var parseNumeric = function parseNumeric(str) {
 | ||
|     //remove ordinal - 'th/rd'
 | ||
|     str = str.replace(/1st$/, '1');
 | ||
|     str = str.replace(/2nd$/, '2');
 | ||
|     str = str.replace(/3rd$/, '3');
 | ||
|     str = str.replace(/([4567890])r?th$/, '$1'); //remove prefixes
 | ||
| 
 | ||
|     str = str.replace(/^[$€¥£¢]/, ''); //remove suffixes
 | ||
| 
 | ||
|     str = str.replace(/[%$€¥£¢]$/, ''); //remove commas
 | ||
| 
 | ||
|     str = str.replace(/,/g, ''); //split '5kg' from '5'
 | ||
| 
 | ||
|     str = str.replace(/([0-9])([a-z\u00C0-\u00FF]{1,2})$/, '$1');
 | ||
|     return str;
 | ||
|   };
 | ||
| 
 | ||
|   var parseNumeric_1 = parseNumeric;
 | ||
| 
 | ||
|   var improperFraction = /^([0-9,\. ]+)\/([0-9,\. ]+)$/; //some numbers we know
 | ||
| 
 | ||
|   var casualForms = {
 | ||
|     // 'a few': 3,
 | ||
|     'a couple': 2,
 | ||
|     'a dozen': 12,
 | ||
|     'two dozen': 24,
 | ||
|     zero: 0
 | ||
|   }; // a 'section' is something like 'fifty-nine thousand'
 | ||
|   // turn a section into something we can add to - like 59000
 | ||
| 
 | ||
|   var section_sum = function section_sum(obj) {
 | ||
|     return Object.keys(obj).reduce(function (sum, k) {
 | ||
|       sum += obj[k];
 | ||
|       return sum;
 | ||
|     }, 0);
 | ||
|   }; //turn a string into a number
 | ||
| 
 | ||
| 
 | ||
|   var parse = function parse(str) {
 | ||
|     //convert some known-numbers
 | ||
|     if (casualForms.hasOwnProperty(str) === true) {
 | ||
|       return casualForms[str];
 | ||
|     } //'a/an' is 1
 | ||
| 
 | ||
| 
 | ||
|     if (str === 'a' || str === 'an') {
 | ||
|       return 1;
 | ||
|     }
 | ||
| 
 | ||
|     var modifier = findModifiers_1(str);
 | ||
|     str = modifier.str;
 | ||
|     var last_mult = null;
 | ||
|     var has = {};
 | ||
|     var sum = 0;
 | ||
|     var isNegative = false;
 | ||
|     var terms = str.split(/[ -]/);
 | ||
| 
 | ||
|     for (var i = 0; i < terms.length; i++) {
 | ||
|       var w = terms[i];
 | ||
|       w = parseNumeric_1(w);
 | ||
| 
 | ||
|       if (!w || w === 'and') {
 | ||
|         continue;
 | ||
|       }
 | ||
| 
 | ||
|       if (w === '-' || w === 'negative') {
 | ||
|         isNegative = true;
 | ||
|         continue;
 | ||
|       }
 | ||
| 
 | ||
|       if (w.charAt(0) === '-') {
 | ||
|         isNegative = true;
 | ||
|         w = w.substr(1);
 | ||
|       } //decimal mode
 | ||
| 
 | ||
| 
 | ||
|       if (w === 'point') {
 | ||
|         sum += section_sum(has);
 | ||
|         sum += parseDecimals_1(terms.slice(i + 1, terms.length));
 | ||
|         sum *= modifier.amount;
 | ||
|         return sum;
 | ||
|       } //improper fraction
 | ||
| 
 | ||
| 
 | ||
|       var fm = w.match(improperFraction);
 | ||
| 
 | ||
|       if (fm) {
 | ||
|         var num = parseFloat(fm[1].replace(/[, ]/g, ''));
 | ||
|         var denom = parseFloat(fm[2].replace(/[, ]/g, ''));
 | ||
| 
 | ||
|         if (denom) {
 | ||
|           sum += num / denom || 0;
 | ||
|         }
 | ||
| 
 | ||
|         continue;
 | ||
|       } //prevent mismatched units, like 'seven eleven'
 | ||
| 
 | ||
| 
 | ||
|       if (validate(w, has) === false) {
 | ||
|         return null;
 | ||
|       } //buildOut section, collect 'has' values
 | ||
| 
 | ||
| 
 | ||
|       if (/^[0-9\.]+$/.test(w)) {
 | ||
|         has['ones'] = parseFloat(w); //not technically right
 | ||
|       } else if (data.ones.hasOwnProperty(w) === true) {
 | ||
|         has['ones'] = data.ones[w];
 | ||
|       } else if (data.teens.hasOwnProperty(w) === true) {
 | ||
|         has['teens'] = data.teens[w];
 | ||
|       } else if (data.tens.hasOwnProperty(w) === true) {
 | ||
|         has['tens'] = data.tens[w];
 | ||
|       } else if (data.multiples.hasOwnProperty(w) === true) {
 | ||
|         var mult = data.multiples[w]; //something has gone wrong : 'two hundred five hundred'
 | ||
| 
 | ||
|         if (mult === last_mult) {
 | ||
|           return null;
 | ||
|         } //support 'hundred thousand'
 | ||
|         //this one is tricky..
 | ||
| 
 | ||
| 
 | ||
|         if (mult === 100 && terms[i + 1] !== undefined) {
 | ||
|           // has['hundreds']=
 | ||
|           var w2 = terms[i + 1];
 | ||
| 
 | ||
|           if (data.multiples[w2]) {
 | ||
|             mult *= data.multiples[w2]; //hundredThousand/hundredMillion
 | ||
| 
 | ||
|             i += 1;
 | ||
|           }
 | ||
|         } //natural order of things
 | ||
|         //five thousand, one hundred..
 | ||
| 
 | ||
| 
 | ||
|         if (last_mult === null || mult < last_mult) {
 | ||
|           sum += (section_sum(has) || 1) * mult;
 | ||
|           last_mult = mult;
 | ||
|           has = {};
 | ||
|         } else {
 | ||
|           //maybe hundred .. thousand
 | ||
|           sum += section_sum(has);
 | ||
|           last_mult = mult;
 | ||
|           sum = (sum || 1) * mult;
 | ||
|           has = {};
 | ||
|         }
 | ||
|       }
 | ||
|     } //dump the remaining has values
 | ||
| 
 | ||
| 
 | ||
|     sum += section_sum(has); //post-process add modifier
 | ||
| 
 | ||
|     sum *= modifier.amount;
 | ||
|     sum *= isNegative ? -1 : 1; //dont return 0, if it went straight-through
 | ||
| 
 | ||
|     if (sum === 0 && Object.keys(has).length === 0) {
 | ||
|       return null;
 | ||
|     }
 | ||
| 
 | ||
|     return sum;
 | ||
|   };
 | ||
| 
 | ||
|   var toNumber = parse;
 | ||
| 
 | ||
|   var parseNumeric$1 = function parseNumeric(str, p) {
 | ||
|     str = str.replace(/,/g, ''); //parse a numeric-number (easy)
 | ||
| 
 | ||
|     var arr = str.split(/^([^0-9]*)([0-9.,]*)([^0-9]*)$/);
 | ||
| 
 | ||
|     if (arr && arr[2] && p.terms().length < 2) {
 | ||
|       var num = parseFloat(arr[2] || str); //ensure that num is an actual number
 | ||
| 
 | ||
|       if (typeof num !== 'number') {
 | ||
|         num = null;
 | ||
|       } // strip an ordinal off the suffix
 | ||
| 
 | ||
| 
 | ||
|       var suffix = arr[3] || '';
 | ||
| 
 | ||
|       if (suffix === 'st' || suffix === 'nd' || suffix === 'rd' || suffix === 'th') {
 | ||
|         suffix = '';
 | ||
|       } // support M for million, k for thousand
 | ||
| 
 | ||
| 
 | ||
|       if (suffix === 'm' || suffix === 'M') {
 | ||
|         num *= 1000000;
 | ||
|         suffix = '';
 | ||
|       }
 | ||
| 
 | ||
|       if (suffix === 'k' || suffix === 'k') {
 | ||
|         num *= 1000;
 | ||
|         suffix = '';
 | ||
|       }
 | ||
| 
 | ||
|       return {
 | ||
|         prefix: arr[1] || '',
 | ||
|         num: num,
 | ||
|         suffix: suffix
 | ||
|       };
 | ||
|     }
 | ||
| 
 | ||
|     return null;
 | ||
|   }; // get a numeric value from this phrase
 | ||
| 
 | ||
| 
 | ||
|   var parseNumber = function parseNumber(p) {
 | ||
|     var str = p.text('reduced'); // is it in '3,123' format?
 | ||
| 
 | ||
|     var hasComma = /[0-9],[0-9]/.test(p.text('text')); // parse a numeric-number like '$4.00'
 | ||
| 
 | ||
|     var res = parseNumeric$1(str, p);
 | ||
| 
 | ||
|     if (res !== null) {
 | ||
|       res.hasComma = hasComma;
 | ||
|       return res;
 | ||
|     } //parse a text-numer (harder)
 | ||
| 
 | ||
| 
 | ||
|     var num = toNumber(str);
 | ||
|     return {
 | ||
|       hasComma: hasComma,
 | ||
|       prefix: '',
 | ||
|       num: num,
 | ||
|       suffix: ''
 | ||
|     };
 | ||
|   };
 | ||
| 
 | ||
|   var parse$1 = parseNumber;
 | ||
| 
 | ||
|   // handle 'one bottle', 'two bottles'
 | ||
|   var agreeUnits = function agreeUnits(agree, val, obj) {
 | ||
|     if (agree === false) {
 | ||
|       return;
 | ||
|     }
 | ||
| 
 | ||
|     var unit = val.lookAhead('^(#Unit|#Noun)'); // don't do these
 | ||
| 
 | ||
|     if (unit.has('(#Address|#Money|#Percent)') || val.has('#Ordinal')) {
 | ||
|       return;
 | ||
|     }
 | ||
| 
 | ||
|     if (obj.num === 1) {
 | ||
|       unit.nouns().toSingular();
 | ||
|     } else if (unit.has('#Singular')) {
 | ||
|       unit.nouns().toPlural();
 | ||
|     }
 | ||
|   };
 | ||
| 
 | ||
|   var _agreeUnits = agreeUnits;
 | ||
| 
 | ||
|   /**
 | ||
|    * turn big numbers, like 2.3e+22, into a string with a ton of trailing 0's
 | ||
|    * */
 | ||
|   var numToString = function numToString(n) {
 | ||
|     if (n < 1000000) {
 | ||
|       return String(n);
 | ||
|     }
 | ||
| 
 | ||
|     var str;
 | ||
| 
 | ||
|     if (typeof n === 'number') {
 | ||
|       str = n.toFixed(0);
 | ||
|     } else {
 | ||
|       str = n;
 | ||
|     }
 | ||
| 
 | ||
|     if (str.indexOf('e+') === -1) {
 | ||
|       return str;
 | ||
|     }
 | ||
| 
 | ||
|     return str.replace('.', '').split('e+').reduce(function (p, b) {
 | ||
|       return p + Array(b - p.length + 2).join(0);
 | ||
|     });
 | ||
|   };
 | ||
| 
 | ||
|   var _toString = numToString; // console.log(numToString(2.5e+22));
 | ||
| 
 | ||
|   /**
 | ||
|    * turns an integer/float into.ber, like 'fifty-five'
 | ||
|    */
 | ||
| 
 | ||
|   var tens_mapping = [['ninety', 90], ['eighty', 80], ['seventy', 70], ['sixty', 60], ['fifty', 50], ['forty', 40], ['thirty', 30], ['twenty', 20]];
 | ||
|   var ones_mapping = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
 | ||
|   var sequence = [[1e24, 'septillion'], [1e20, 'hundred sextillion'], [1e21, 'sextillion'], [1e20, 'hundred quintillion'], [1e18, 'quintillion'], [1e17, 'hundred quadrillion'], [1e15, 'quadrillion'], [1e14, 'hundred trillion'], [1e12, 'trillion'], [1e11, 'hundred billion'], [1e9, 'billion'], [1e8, 'hundred million'], [1e6, 'million'], [100000, 'hundred thousand'], [1000, 'thousand'], [100, 'hundred'], [1, 'one']]; //turn number into an array of magnitudes, like [[5, million], [2, hundred]]
 | ||
| 
 | ||
|   var breakdown_magnitudes = function breakdown_magnitudes(num) {
 | ||
|     var working = num;
 | ||
|     var have = [];
 | ||
|     sequence.forEach(function (a) {
 | ||
|       if (num >= a[0]) {
 | ||
|         var howmany = Math.floor(working / a[0]);
 | ||
|         working -= howmany * a[0];
 | ||
| 
 | ||
|         if (howmany) {
 | ||
|           have.push({
 | ||
|             unit: a[1],
 | ||
|             count: howmany
 | ||
|           });
 | ||
|         }
 | ||
|       }
 | ||
|     });
 | ||
|     return have;
 | ||
|   }; //turn numbers from 100-0 into their text
 | ||
| 
 | ||
| 
 | ||
|   var breakdown_hundred = function breakdown_hundred(num) {
 | ||
|     var arr = [];
 | ||
| 
 | ||
|     if (num > 100) {
 | ||
|       return arr; //something bad happened..
 | ||
|     }
 | ||
| 
 | ||
|     for (var i = 0; i < tens_mapping.length; i++) {
 | ||
|       if (num >= tens_mapping[i][1]) {
 | ||
|         num -= tens_mapping[i][1];
 | ||
|         arr.push(tens_mapping[i][0]);
 | ||
|       }
 | ||
|     } //(hopefully) we should only have 20-0 now
 | ||
| 
 | ||
| 
 | ||
|     if (ones_mapping[num]) {
 | ||
|       arr.push(ones_mapping[num]);
 | ||
|     }
 | ||
| 
 | ||
|     return arr;
 | ||
|   };
 | ||
|   /** print-out 'point eight nine'*/
 | ||
| 
 | ||
| 
 | ||
|   var handle_decimal = function handle_decimal(num) {
 | ||
|     var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
 | ||
|     var arr = []; //parse it out like a string, because js math is such shit
 | ||
| 
 | ||
|     var str = _toString(num);
 | ||
|     var decimal = str.match(/\.([0-9]+)/);
 | ||
| 
 | ||
|     if (!decimal || !decimal[0]) {
 | ||
|       return arr;
 | ||
|     }
 | ||
| 
 | ||
|     arr.push('point');
 | ||
|     var decimals = decimal[0].split('');
 | ||
| 
 | ||
|     for (var i = 0; i < decimals.length; i++) {
 | ||
|       arr.push(names[decimals[i]]);
 | ||
|     }
 | ||
| 
 | ||
|     return arr;
 | ||
|   };
 | ||
|   /** turns an integer into a textual number */
 | ||
| 
 | ||
| 
 | ||
|   var to_text = function to_text(num) {
 | ||
|     // handle zero, quickly
 | ||
|     if (num === 0 || num === '0') {
 | ||
|       return 'zero'; // no?
 | ||
|     } //big numbers, north of sextillion, aren't gonna work well..
 | ||
|     //keep them small..
 | ||
| 
 | ||
| 
 | ||
|     if (num > 1e21) {
 | ||
|       num = _toString(num);
 | ||
|     }
 | ||
| 
 | ||
|     var arr = []; //handle negative numbers
 | ||
| 
 | ||
|     if (num < 0) {
 | ||
|       arr.push('minus');
 | ||
|       num = Math.abs(num);
 | ||
|     } //break-down into units, counts
 | ||
| 
 | ||
| 
 | ||
|     var units = breakdown_magnitudes(num); //build-up the string from its components
 | ||
| 
 | ||
|     for (var i = 0; i < units.length; i++) {
 | ||
|       var unit_name = units[i].unit;
 | ||
| 
 | ||
|       if (unit_name === 'one') {
 | ||
|         unit_name = ''; //put an 'and' in here
 | ||
| 
 | ||
|         if (arr.length > 1) {
 | ||
|           arr.push('and');
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       arr = arr.concat(breakdown_hundred(units[i].count));
 | ||
|       arr.push(unit_name);
 | ||
|     } //also support decimals - 'point eight'
 | ||
| 
 | ||
| 
 | ||
|     arr = arr.concat(handle_decimal(num)); //remove empties
 | ||
| 
 | ||
|     arr = arr.filter(function (s) {
 | ||
|       return s;
 | ||
|     });
 | ||
| 
 | ||
|     if (arr.length === 0) {
 | ||
|       arr[0] = '';
 | ||
|     }
 | ||
| 
 | ||
|     return arr.join(' ');
 | ||
|   };
 | ||
| 
 | ||
|   var toText = to_text; // console.log(to_text(-1000.8));
 | ||
| 
 | ||
|   /**
 | ||
|    * turn a number like 5 into an ordinal like 5th
 | ||
|    */
 | ||
| 
 | ||
|   var numOrdinal = function numOrdinal(num) {
 | ||
|     if (!num && num !== 0) {
 | ||
|       return null;
 | ||
|     } //the teens are all 'th'
 | ||
| 
 | ||
| 
 | ||
|     var tens = num % 100;
 | ||
| 
 | ||
|     if (tens > 10 && tens < 20) {
 | ||
|       return String(num) + 'th';
 | ||
|     } //the rest of 'em
 | ||
| 
 | ||
| 
 | ||
|     var mapping = {
 | ||
|       0: 'th',
 | ||
|       1: 'st',
 | ||
|       2: 'nd',
 | ||
|       3: 'rd'
 | ||
|     };
 | ||
|     var str = _toString(num);
 | ||
|     var last = str.slice(str.length - 1, str.length);
 | ||
| 
 | ||
|     if (mapping[last]) {
 | ||
|       str += mapping[last];
 | ||
|     } else {
 | ||
|       str += 'th';
 | ||
|     }
 | ||
| 
 | ||
|     return str;
 | ||
|   };
 | ||
| 
 | ||
|   var numOrdinal_1 = numOrdinal;
 | ||
| 
 | ||
|   var irregulars = {
 | ||
|     one: 'first',
 | ||
|     two: 'second',
 | ||
|     three: 'third',
 | ||
|     five: 'fifth',
 | ||
|     eight: 'eighth',
 | ||
|     nine: 'ninth',
 | ||
|     twelve: 'twelfth',
 | ||
|     twenty: 'twentieth',
 | ||
|     thirty: 'thirtieth',
 | ||
|     forty: 'fortieth',
 | ||
|     fourty: 'fourtieth',
 | ||
|     fifty: 'fiftieth',
 | ||
|     sixty: 'sixtieth',
 | ||
|     seventy: 'seventieth',
 | ||
|     eighty: 'eightieth',
 | ||
|     ninety: 'ninetieth'
 | ||
|   };
 | ||
|   /**
 | ||
|    * convert a javascript number to 'twentieth' format
 | ||
|    * */
 | ||
| 
 | ||
|   var textOrdinal = function textOrdinal(num) {
 | ||
|     var words = toText(num).split(' '); //convert the last number to an ordinal
 | ||
| 
 | ||
|     var last = words[words.length - 1];
 | ||
| 
 | ||
|     if (irregulars.hasOwnProperty(last)) {
 | ||
|       words[words.length - 1] = irregulars[last];
 | ||
|     } else {
 | ||
|       words[words.length - 1] = last.replace(/y$/, 'i') + 'th';
 | ||
|     }
 | ||
| 
 | ||
|     return words.join(' ');
 | ||
|   };
 | ||
| 
 | ||
|   var textOrdinal_1 = textOrdinal;
 | ||
| 
 | ||
|   var prefixes = {
 | ||
|     '¢': 'cents',
 | ||
|     $: 'dollars',
 | ||
|     '£': 'pounds',
 | ||
|     '¥': 'yen',
 | ||
|     '€': 'euros',
 | ||
|     '₡': 'colón',
 | ||
|     '฿': 'baht',
 | ||
|     '₭': 'kip',
 | ||
|     '₩': 'won',
 | ||
|     '₹': 'rupees',
 | ||
|     '₽': 'ruble',
 | ||
|     '₺': 'liras'
 | ||
|   };
 | ||
|   var suffixes = {
 | ||
|     '%': 'percent',
 | ||
|     s: 'seconds',
 | ||
|     cm: 'centimetres',
 | ||
|     km: 'kilometres'
 | ||
|   };
 | ||
|   var _symbols = {
 | ||
|     prefixes: prefixes,
 | ||
|     suffixes: suffixes
 | ||
|   };
 | ||
| 
 | ||
|   var prefixes$1 = _symbols.prefixes;
 | ||
|   var suffixes$1 = _symbols.suffixes;
 | ||
|   var isCurrency = {
 | ||
|     usd: true,
 | ||
|     eur: true,
 | ||
|     jpy: true,
 | ||
|     gbp: true,
 | ||
|     cad: true,
 | ||
|     aud: true,
 | ||
|     chf: true,
 | ||
|     cny: true,
 | ||
|     hkd: true,
 | ||
|     nzd: true,
 | ||
|     kr: true,
 | ||
|     rub: true
 | ||
|   }; // convert $ to 'dollars', etc
 | ||
| 
 | ||
|   var prefixToText = function prefixToText(obj) {
 | ||
|     // turn 5% to 'five percent'
 | ||
|     if (prefixes$1.hasOwnProperty(obj.prefix)) {
 | ||
|       obj.suffix += prefixes$1[obj.prefix];
 | ||
|       obj.prefix = '';
 | ||
|     } //turn 5km to 'five kilometres'
 | ||
| 
 | ||
| 
 | ||
|     if (suffixes$1.hasOwnProperty(obj.suffix)) {
 | ||
|       obj.suffix = suffixes$1[obj.suffix];
 | ||
|     } //uppercase lost case for 'USD', etc
 | ||
| 
 | ||
| 
 | ||
|     if (isCurrency.hasOwnProperty(obj.suffix)) {
 | ||
|       obj.suffix = obj.suffix.toUpperCase();
 | ||
|     } // add a space, if it exists
 | ||
| 
 | ||
| 
 | ||
|     if (obj.suffix) {
 | ||
|       obj.suffix = ' ' + obj.suffix;
 | ||
|     }
 | ||
| 
 | ||
|     return obj;
 | ||
|   }; //business-logic for converting a cardinal-number to other forms
 | ||
| 
 | ||
| 
 | ||
|   var makeNumber = function makeNumber(obj, isText, isOrdinal) {
 | ||
|     var num = String(obj.num);
 | ||
| 
 | ||
|     if (isText) {
 | ||
|       obj = prefixToText(obj);
 | ||
| 
 | ||
|       if (isOrdinal) {
 | ||
|         //ordinal-text
 | ||
|         num = textOrdinal_1(num);
 | ||
|         return "".concat(obj.prefix || '').concat(num).concat(obj.suffix || '');
 | ||
|       } //cardinal-text
 | ||
| 
 | ||
| 
 | ||
|       num = toText(num);
 | ||
|       return "".concat(obj.prefix || '').concat(num).concat(obj.suffix || '');
 | ||
|     } //ordinal-number
 | ||
| 
 | ||
| 
 | ||
|     if (isOrdinal) {
 | ||
|       num = numOrdinal_1(num); // support '5th percent'
 | ||
| 
 | ||
|       obj = prefixToText(obj);
 | ||
|       return "".concat(obj.prefix || '').concat(num).concat(obj.suffix || '');
 | ||
|     } // support comma format
 | ||
| 
 | ||
| 
 | ||
|     if (obj.hasComma === true) {
 | ||
|       num = obj.num.toLocaleString();
 | ||
|     } // cardinal-number
 | ||
| 
 | ||
| 
 | ||
|     num = _toString(num); // support very large numbers
 | ||
| 
 | ||
|     return "".concat(obj.prefix || '').concat(num).concat(obj.suffix || '');
 | ||
|   };
 | ||
| 
 | ||
|   var makeNumber_1 = makeNumber;
 | ||
| 
 | ||
|   var methods = {
 | ||
|     /** overloaded json method with additional number information */
 | ||
|     json: function json(options) {
 | ||
|       var n = null;
 | ||
| 
 | ||
|       if (typeof options === 'number') {
 | ||
|         n = options;
 | ||
|         options = null;
 | ||
|       }
 | ||
| 
 | ||
|       options = options || {
 | ||
|         text: true,
 | ||
|         normal: true,
 | ||
|         trim: true,
 | ||
|         terms: true
 | ||
|       };
 | ||
|       var res = [];
 | ||
|       this.forEach(function (doc) {
 | ||
|         var json = doc.json(options)[0];
 | ||
|         var obj = parse$1(doc);
 | ||
|         json.prefix = obj.prefix;
 | ||
|         json.number = obj.num;
 | ||
|         json.suffix = obj.suffix;
 | ||
|         json.cardinal = makeNumber_1(obj, false, false);
 | ||
|         json.ordinal = makeNumber_1(obj, false, true);
 | ||
|         json.textCardinal = makeNumber_1(obj, true, false);
 | ||
|         json.textOrdinal = makeNumber_1(obj, true, true);
 | ||
|         res.push(json);
 | ||
|       });
 | ||
| 
 | ||
|       if (n !== null) {
 | ||
|         return res[n];
 | ||
|       }
 | ||
| 
 | ||
|       return res;
 | ||
|     },
 | ||
| 
 | ||
|     /** two of what? */
 | ||
|     units: function units() {
 | ||
|       var m = this.lookAhead('(#Unit|#Noun)+');
 | ||
|       m = m.splitAfter('@hasComma').first();
 | ||
|       m = m.not('#Pronoun');
 | ||
|       return m.first();
 | ||
|     },
 | ||
| 
 | ||
|     /** return only ordinal numbers */
 | ||
|     isOrdinal: function isOrdinal() {
 | ||
|       return this["if"]('#Ordinal');
 | ||
|     },
 | ||
| 
 | ||
|     /** return only cardinal numbers*/
 | ||
|     isCardinal: function isCardinal() {
 | ||
|       return this["if"]('#Cardinal');
 | ||
|     },
 | ||
| 
 | ||
|     /** convert to numeric form like '8' or '8th' */
 | ||
|     toNumber: function toNumber() {
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         var str = makeNumber_1(obj, false, val.has('#Ordinal'));
 | ||
|         val.replaceWith(str, true);
 | ||
|         val.tag('NumericValue');
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** add commas, or nicer formatting for numbers */
 | ||
|     toLocaleString: function toLocaleString() {
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         obj.num = obj.num.toLocaleString();
 | ||
|         var str = makeNumber_1(obj, false, val.has('#Ordinal'));
 | ||
|         val.replaceWith(str, true);
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** convert to text form - like 'eight' or 'eigth'*/
 | ||
|     toText: function toText() {
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         var str = makeNumber_1(obj, true, val.has('#Ordinal'));
 | ||
|         val.replaceWith(str, true);
 | ||
|         val.tag('TextValue');
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** convert to cardinal form, like 'eight', or '8' */
 | ||
|     toCardinal: function toCardinal(agree) {
 | ||
|       var m = this["if"]('#Ordinal');
 | ||
|       m.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         var str = makeNumber_1(obj, val.has('#TextValue'), false); // a hack for number-ranges
 | ||
| 
 | ||
|         if (val.has('#NumberRange')) {
 | ||
|           var t = val.termList()[0];
 | ||
| 
 | ||
|           if (t.text && t.post === '') {
 | ||
|             t.post = ' ';
 | ||
|           }
 | ||
|         } // change the number text
 | ||
| 
 | ||
| 
 | ||
|         val.replaceWith(str, true);
 | ||
|         val.tag('Cardinal'); // turn unit into plural -> 'seven beers'
 | ||
| 
 | ||
|         _agreeUnits(agree, val, obj);
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** convert to ordinal form, like 'eighth', or '8th' */
 | ||
|     toOrdinal: function toOrdinal() {
 | ||
|       var _this = this;
 | ||
| 
 | ||
|       var m = this["if"]('#Cardinal');
 | ||
|       m.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         var str = makeNumber_1(obj, val.has('#TextValue'), true); // a hack for number-ranges
 | ||
| 
 | ||
|         if (val.has('#NumberRange')) {
 | ||
|           var t = val.termList()[0];
 | ||
| 
 | ||
|           if (t.text && t.post === '') {
 | ||
|             t.post = ' ';
 | ||
|           }
 | ||
|         } // change the number text
 | ||
| 
 | ||
| 
 | ||
|         val.replaceWith(str, true);
 | ||
|         val.tag('Ordinal'); // turn unit into singular -> 'seventh beer'
 | ||
| 
 | ||
|         var unit = _this.lookAhead('^#Plural');
 | ||
| 
 | ||
|         if (unit.found) {
 | ||
|           unit.nouns().toSingular();
 | ||
|         }
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** return only numbers that are == n */
 | ||
|     isEqual: function isEqual(n) {
 | ||
|       return this.filter(function (val) {
 | ||
|         var num = parse$1(val).num;
 | ||
|         return num === n;
 | ||
|       });
 | ||
|     },
 | ||
| 
 | ||
|     /** return only numbers that are > n*/
 | ||
|     greaterThan: function greaterThan(n) {
 | ||
|       return this.filter(function (val) {
 | ||
|         var num = parse$1(val).num;
 | ||
|         return num > n;
 | ||
|       });
 | ||
|     },
 | ||
| 
 | ||
|     /** return only numbers that are < n*/
 | ||
|     lessThan: function lessThan(n) {
 | ||
|       return this.filter(function (val) {
 | ||
|         var num = parse$1(val).num;
 | ||
|         return num < n;
 | ||
|       });
 | ||
|     },
 | ||
| 
 | ||
|     /** return only numbers > min and < max */
 | ||
|     between: function between(min, max) {
 | ||
|       return this.filter(function (val) {
 | ||
|         var num = parse$1(val).num;
 | ||
|         return num > min && num < max;
 | ||
|       });
 | ||
|     },
 | ||
| 
 | ||
|     /** set these number to n */
 | ||
|     set: function set(n, agree) {
 | ||
|       if (n === undefined) {
 | ||
|         return this; // don't bother
 | ||
|       }
 | ||
| 
 | ||
|       if (typeof n === 'string') {
 | ||
|         n = toNumber(n);
 | ||
|       }
 | ||
| 
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
|         obj.num = n;
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         var str = makeNumber_1(obj, val.has('#TextValue'), val.has('#Ordinal'));
 | ||
|         val = val.not('#Currency');
 | ||
|         val.replaceWith(str, true); // handle plural/singular unit
 | ||
| 
 | ||
|         _agreeUnits(agree, val, obj);
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
|     add: function add(n, agree) {
 | ||
|       if (!n) {
 | ||
|         return this; // don't bother
 | ||
|       }
 | ||
| 
 | ||
|       if (typeof n === 'string') {
 | ||
|         n = toNumber(n);
 | ||
|       }
 | ||
| 
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num === null) {
 | ||
|           return;
 | ||
|         }
 | ||
| 
 | ||
|         obj.num += n;
 | ||
|         var str = makeNumber_1(obj, val.has('#TextValue'), val.has('#Ordinal'));
 | ||
|         val = val.not('#Currency');
 | ||
|         val.replaceWith(str, true); // handle plural/singular unit
 | ||
| 
 | ||
|         _agreeUnits(agree, val, obj);
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** decrease each number by n*/
 | ||
|     subtract: function subtract(n, agree) {
 | ||
|       return this.add(n * -1, agree);
 | ||
|     },
 | ||
| 
 | ||
|     /** increase each number by 1 */
 | ||
|     increment: function increment(agree) {
 | ||
|       this.add(1, agree);
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** decrease each number by 1 */
 | ||
|     decrement: function decrement(agree) {
 | ||
|       this.add(-1, agree);
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** return things like CCXX*/
 | ||
|     romanNumerals: function romanNumerals(n) {
 | ||
|       var m = this.match('#RomanNumeral').numbers();
 | ||
| 
 | ||
|       if (typeof n === 'number') {
 | ||
|         m = m.get(n);
 | ||
|       }
 | ||
| 
 | ||
|       return m;
 | ||
|     },
 | ||
| 
 | ||
|     /** split-apart suffix and number */
 | ||
|     normalize: function normalize() {
 | ||
|       var keep = {
 | ||
|         '%': true
 | ||
|       };
 | ||
|       this.forEach(function (val) {
 | ||
|         var obj = parse$1(val);
 | ||
| 
 | ||
|         if (obj.num !== null && obj.suffix && keep[obj.suffix] !== true) {
 | ||
|           var prefix = obj.prefix || '';
 | ||
|           val = val.replaceWith(prefix + obj.num + ' ' + obj.suffix);
 | ||
|           return;
 | ||
|         }
 | ||
|       });
 | ||
|       return this;
 | ||
|     },
 | ||
| 
 | ||
|     /** retrieve the parsed number */
 | ||
|     get: function get(n) {
 | ||
|       var arr = [];
 | ||
|       this.forEach(function (doc) {
 | ||
|         arr.push(parse$1(doc).num);
 | ||
|       });
 | ||
| 
 | ||
|       if (n !== undefined) {
 | ||
|         return arr[n];
 | ||
|       }
 | ||
| 
 | ||
|       return arr;
 | ||
|     }
 | ||
|   }; // aliases
 | ||
| 
 | ||
|   methods.toNice = methods.toLocaleString;
 | ||
|   methods.isBetween = methods.between;
 | ||
|   methods.minus = methods.subtract;
 | ||
|   methods.plus = methods.add;
 | ||
|   methods.equals = methods.isEqual;
 | ||
|   var methods_1 = methods;
 | ||
| 
 | ||
|   //from wikipedia's {{infobox currency}}, Dec 2020
 | ||
|   var currencies = [{
 | ||
|     dem: 'american',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'usd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$', 'US$', 'U$']
 | ||
|   }, {
 | ||
|     name: 'euro',
 | ||
|     iso: 'eur',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['€']
 | ||
|   }, {
 | ||
|     dem: 'british',
 | ||
|     name: 'pound',
 | ||
|     iso: 'gbp',
 | ||
|     sub: 'penny',
 | ||
|     alias: {
 | ||
|       sterling: true
 | ||
|     },
 | ||
|     sym: ['£']
 | ||
|   }, {
 | ||
|     name: 'renminbi',
 | ||
|     iso: 'cny',
 | ||
|     sub: 'yuán',
 | ||
|     plural: 'yuán',
 | ||
|     alias: {
 | ||
|       yuan: true
 | ||
|     },
 | ||
|     sym: ['元'] //'¥'
 | ||
| 
 | ||
|   }, {
 | ||
|     dem: 'japanese',
 | ||
|     name: 'yen',
 | ||
|     iso: 'jpy',
 | ||
|     sub: 'sen',
 | ||
|     sym: ['¥', '円', '圓']
 | ||
|   }, // kr
 | ||
|   {
 | ||
|     dem: 'swedish',
 | ||
|     name: 'krona',
 | ||
|     iso: 'sek',
 | ||
|     sub: 'öre',
 | ||
|     alias: {
 | ||
|       ore: true,
 | ||
|       kronor: true
 | ||
|     },
 | ||
|     sym: ['kr']
 | ||
|   }, {
 | ||
|     dem: 'estonian',
 | ||
|     name: 'kroon',
 | ||
|     iso: 'eek',
 | ||
|     sub: 'sent',
 | ||
|     sym: ['kr']
 | ||
|   }, {
 | ||
|     dem: 'norwegian',
 | ||
|     name: 'krone',
 | ||
|     iso: 'nok',
 | ||
|     sub: 'øre',
 | ||
|     sym: ['kr']
 | ||
|   }, {
 | ||
|     dem: 'icelandic',
 | ||
|     name: 'króna',
 | ||
|     iso: 'isk',
 | ||
|     sym: ['kr']
 | ||
|   }, {
 | ||
|     dem: 'danish',
 | ||
|     name: 'krone',
 | ||
|     iso: 'dkk',
 | ||
|     sub: 'øre',
 | ||
|     sym: ['kr.']
 | ||
|   }, // {
 | ||
|   //   dem: 'scandinavian',
 | ||
|   //   name: 'Monetary Union',
 | ||
|   //   sub: 'øre',
 | ||
|   //   sym: ['kr.'],
 | ||
|   // },
 | ||
|   // 'k'
 | ||
|   {
 | ||
|     dem: 'zambian',
 | ||
|     name: 'kwacha',
 | ||
|     iso: 'zmw',
 | ||
|     sub: 'ngwee',
 | ||
|     sym: ['K']
 | ||
|   }, {
 | ||
|     dem: 'malawian',
 | ||
|     name: 'kwacha',
 | ||
|     iso: 'mwk',
 | ||
|     sub: 'tambala',
 | ||
|     sym: ['K']
 | ||
|   }, // misc
 | ||
|   {
 | ||
|     dem: 'greek',
 | ||
|     name: 'drachma',
 | ||
|     iso: 'grd',
 | ||
|     sub: 'leptοn',
 | ||
|     sym: ['Δρχ.', 'Δρ.', '₯']
 | ||
|   }, {
 | ||
|     dem: 'eastern caribbean',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'xcd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'finnish',
 | ||
|     name: 'markka',
 | ||
|     iso: 'fim',
 | ||
|     sub: 'penni',
 | ||
|     sym: ['mk']
 | ||
|   }, {
 | ||
|     dem: 'polish',
 | ||
|     name: 'złoty',
 | ||
|     iso: 'pln',
 | ||
|     sub: 'grosz',
 | ||
|     sym: ['zł']
 | ||
|   }, {
 | ||
|     dem: 'slovenian',
 | ||
|     name: 'tolar',
 | ||
|     iso: 'sit',
 | ||
|     sub: 'stotin',
 | ||
|     sym: []
 | ||
|   }, {
 | ||
|     dem: 'australian',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'aud',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$', 'A$', 'AU$']
 | ||
|   }, {
 | ||
|     dem: 'deutsche',
 | ||
|     name: 'mark',
 | ||
|     iso: 'dem',
 | ||
|     sub: 'pfennig',
 | ||
|     sym: ['DM']
 | ||
|   }, {
 | ||
|     dem: 'thai',
 | ||
|     name: 'baht',
 | ||
|     iso: 'thb',
 | ||
|     sub: 'satang',
 | ||
|     sym: ['฿']
 | ||
|   }, {
 | ||
|     dem: 'canadian',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'cad',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$', 'Can$', 'C$', 'CA$', 'CAD']
 | ||
|   }, {
 | ||
|     dem: 'mexican',
 | ||
|     name: 'peso',
 | ||
|     iso: 'mxn',
 | ||
|     sub: 'centavo',
 | ||
|     sym: ['$', 'Mex$']
 | ||
|   }, {
 | ||
|     dem: 'spanish',
 | ||
|     name: 'peseta',
 | ||
|     iso: 'esp',
 | ||
|     sub: 'céntimo',
 | ||
|     sym: ['Pta']
 | ||
|   }, {
 | ||
|     dem: 'new zealand',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'nzd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$', 'NZ$']
 | ||
|   }, {
 | ||
|     dem: 'chilean',
 | ||
|     name: 'peso',
 | ||
|     iso: 'clp',
 | ||
|     sub: 'Centavo',
 | ||
|     sym: ['Cifrão', '$']
 | ||
|   }, {
 | ||
|     dem: 'nigerian',
 | ||
|     name: 'naira',
 | ||
|     iso: 'ngn',
 | ||
|     sub: 'kobo',
 | ||
|     sym: ['₦']
 | ||
|   }, {
 | ||
|     dem: 'austrian',
 | ||
|     name: 'schilling',
 | ||
|     iso: 'ats',
 | ||
|     sub: 'groschen',
 | ||
|     sym: ['S', 'öS']
 | ||
|   }, {
 | ||
|     dem: 'guatemalan',
 | ||
|     name: 'quetzal',
 | ||
|     iso: 'gtq',
 | ||
|     sub: 'centavo',
 | ||
|     sym: ['Q']
 | ||
|   }, {
 | ||
|     dem: 'philippine',
 | ||
|     name: 'peso',
 | ||
|     iso: 'php',
 | ||
|     sub: 'sentimo',
 | ||
|     sym: ['₱']
 | ||
|   }, {
 | ||
|     dem: 'hungarian',
 | ||
|     name: 'forint',
 | ||
|     iso: 'huf',
 | ||
|     sub: 'fillér',
 | ||
|     sym: ['Ft']
 | ||
|   }, {
 | ||
|     dem: 'russian',
 | ||
|     name: 'ruble',
 | ||
|     iso: 'rub',
 | ||
|     sub: 'kopeyka',
 | ||
|     sym: ['₽', 'руб', 'р.']
 | ||
|   }, {
 | ||
|     dem: 'kuwaiti',
 | ||
|     name: 'dinar',
 | ||
|     iso: 'kwd',
 | ||
|     sub: 'fils',
 | ||
|     sym: ['د.ك', 'KD']
 | ||
|   }, {
 | ||
|     dem: 'israeli',
 | ||
|     name: 'new shekel',
 | ||
|     iso: 'ils',
 | ||
|     sub: 'agora',
 | ||
|     sym: ['₪']
 | ||
|   }, {
 | ||
|     dem: 'latvian',
 | ||
|     name: 'lats',
 | ||
|     iso: 'lvl',
 | ||
|     sub: 'santīms',
 | ||
|     sym: ['Ls']
 | ||
|   }, {
 | ||
|     dem: 'kazakhstani',
 | ||
|     name: 'tenge',
 | ||
|     iso: 'kzt',
 | ||
|     sub: 'tıyn',
 | ||
|     sym: ['₸']
 | ||
|   }, {
 | ||
|     dem: 'iraqi',
 | ||
|     name: 'dinar',
 | ||
|     iso: 'iqd',
 | ||
|     sub: 'fils',
 | ||
|     sym: ['د.ع']
 | ||
|   }, {
 | ||
|     dem: 'bahamian',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'bsd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$', 'B$']
 | ||
|   }, {
 | ||
|     dem: 'seychellois',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'scr',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['SCR', 'SR']
 | ||
|   }, {
 | ||
|     dem: 'albanian',
 | ||
|     name: 'lek',
 | ||
|     iso: 'all',
 | ||
|     sub: 'qindarkë',
 | ||
|     sym: ['L']
 | ||
|   }, {
 | ||
|     dem: 'bulgarian',
 | ||
|     name: 'lev',
 | ||
|     iso: 'bgn',
 | ||
|     sub: 'stotinka',
 | ||
|     sym: ['лв.']
 | ||
|   }, {
 | ||
|     dem: 'irish',
 | ||
|     name: 'pound',
 | ||
|     iso: 'iep',
 | ||
|     sym: ['£', 'IR£']
 | ||
|   }, {
 | ||
|     name: 'cfp franc',
 | ||
|     iso: 'xpf',
 | ||
|     sym: ['f']
 | ||
|   }, {
 | ||
|     dem: 'south african',
 | ||
|     name: 'rand',
 | ||
|     iso: 'zar',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['R']
 | ||
|   }, {
 | ||
|     dem: 'south korean',
 | ||
|     name: 'won',
 | ||
|     iso: 'krw',
 | ||
|     sub: 'jeon',
 | ||
|     plural: 'won',
 | ||
|     sym: ['₩']
 | ||
|   }, {
 | ||
|     dem: 'north korean',
 | ||
|     name: 'won',
 | ||
|     iso: 'kpw',
 | ||
|     sub: 'chon',
 | ||
|     plural: 'won',
 | ||
|     sym: ['₩']
 | ||
|   }, {
 | ||
|     dem: 'portuguese',
 | ||
|     name: 'escudo',
 | ||
|     iso: 'pte',
 | ||
|     sub: 'centavo',
 | ||
|     sym: []
 | ||
|   }, {
 | ||
|     dem: 'ghanaian',
 | ||
|     name: 'cedi',
 | ||
|     iso: 'ghs',
 | ||
|     sub: 'pesewa',
 | ||
|     sym: ['GH₵']
 | ||
|   }, {
 | ||
|     dem: 'hong kong',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'hkd',
 | ||
|     sub: '毫',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'new taiwan',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'twd',
 | ||
|     sub: 'dime',
 | ||
|     sym: ['NT$']
 | ||
|   }, {
 | ||
|     dem: 'east german',
 | ||
|     name: 'mark',
 | ||
|     iso: 'ddm',
 | ||
|     sub: 'pfennig',
 | ||
|     sym: ['M']
 | ||
|   }, {
 | ||
|     dem: 'namibian',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'nad',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'malaysian',
 | ||
|     name: 'ringgit',
 | ||
|     iso: 'myr',
 | ||
|     sub: 'sen',
 | ||
|     sym: ['RM']
 | ||
|   }, {
 | ||
|     dem: 'swiss',
 | ||
|     name: 'franc',
 | ||
|     iso: 'chf',
 | ||
|     sym: ['Rp.']
 | ||
|   }, {
 | ||
|     dem: 'panamanian',
 | ||
|     name: 'balboa',
 | ||
|     iso: 'pab',
 | ||
|     sub: 'centésimo',
 | ||
|     sym: ['B/.']
 | ||
|   }, {
 | ||
|     dem: 'indonesian',
 | ||
|     name: 'rupiah',
 | ||
|     iso: 'idr',
 | ||
|     sub: 'sen',
 | ||
|     sym: ['Rp']
 | ||
|   }, {
 | ||
|     dem: 'brunei',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'bnd',
 | ||
|     sub: 'sen',
 | ||
|     sym: ['$', 'B$']
 | ||
|   }, {
 | ||
|     dem: 'venezuelan',
 | ||
|     name: 'bolívar',
 | ||
|     iso: 'vef',
 | ||
|     sub: 'céntimo',
 | ||
|     sym: ['Bs.F', 'Bs.']
 | ||
|   }, {
 | ||
|     dem: 'macedonian',
 | ||
|     name: 'denar',
 | ||
|     iso: 'mkd',
 | ||
|     sub: 'deni',
 | ||
|     sym: ['den']
 | ||
|   }, {
 | ||
|     dem: 'mauritanian',
 | ||
|     name: 'ouguiya',
 | ||
|     iso: 'mru',
 | ||
|     sub: 'khoums',
 | ||
|     sym: ['UM']
 | ||
|   }, {
 | ||
|     dem: 'argentine',
 | ||
|     name: 'peso',
 | ||
|     iso: 'ars',
 | ||
|     sub: 'centavo',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'libyan',
 | ||
|     name: 'dinar',
 | ||
|     iso: 'lyd',
 | ||
|     sub: 'dirham',
 | ||
|     sym: ['LD', 'ل.د']
 | ||
|   }, {
 | ||
|     dem: 'jordanian',
 | ||
|     name: 'dinar',
 | ||
|     iso: 'jod',
 | ||
|     sub: 'dirham',
 | ||
|     sym: ['د.أ']
 | ||
|   }, {
 | ||
|     dem: 'french',
 | ||
|     name: 'franc',
 | ||
|     iso: 'frf',
 | ||
|     sub: 'centime',
 | ||
|     sym: ['F', 'Fr', 'FF', '₣']
 | ||
|   }, {
 | ||
|     dem: 'syrian',
 | ||
|     name: 'pound',
 | ||
|     iso: 'syp',
 | ||
|     sub: 'piastre',
 | ||
|     sym: ['LS', '£S']
 | ||
|   }, {
 | ||
|     dem: 'belize',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'bzd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'saudi',
 | ||
|     name: 'riyal',
 | ||
|     iso: 'sar',
 | ||
|     sub: 'halalah',
 | ||
|     sym: ['SAR', 'ر.س', ' ﷼']
 | ||
|   }, {
 | ||
|     dem: 'surinamese',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'srd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['$']
 | ||
|   }, {
 | ||
|     dem: 'singapore',
 | ||
|     name: 'dollar',
 | ||
|     iso: 'sgd',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['S$', '$']
 | ||
|   }, {
 | ||
|     dem: 'nepalese',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'npr',
 | ||
|     sub: 'Paisa',
 | ||
|     sym: ['रु ₨', 'Re']
 | ||
|   }, {
 | ||
|     dem: 'macanese',
 | ||
|     name: 'pataca',
 | ||
|     iso: 'mop',
 | ||
|     sub: 'ho',
 | ||
|     sym: ['MOP$']
 | ||
|   }, {
 | ||
|     dem: 'nicaraguan',
 | ||
|     name: 'córdoba',
 | ||
|     iso: 'nio',
 | ||
|     sub: 'centavo',
 | ||
|     sym: ['C$']
 | ||
|   }, {
 | ||
|     dem: 'bangladeshi',
 | ||
|     name: 'taka',
 | ||
|     iso: 'bdt',
 | ||
|     sub: 'poysha',
 | ||
|     sym: ['৳']
 | ||
|   }, {
 | ||
|     dem: 'indian',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'inr',
 | ||
|     sub: 'paisa',
 | ||
|     sym: ['₹']
 | ||
|   }, {
 | ||
|     dem: 'maldivian',
 | ||
|     name: 'rufiyaa',
 | ||
|     iso: 'mvr',
 | ||
|     sub: 'laari',
 | ||
|     sym: ['Rf', 'MRf', 'MVR', '.ރ ']
 | ||
|   }, {
 | ||
|     dem: 'sri lankan',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'lkr',
 | ||
|     sub: 'Cents',
 | ||
|     sym: ['Rs', 'රු', 'ரூ']
 | ||
|   }, {
 | ||
|     dem: 'bhutanese',
 | ||
|     name: 'ngultrum',
 | ||
|     iso: 'btn',
 | ||
|     sub: 'chhertum',
 | ||
|     sym: ['Nu.']
 | ||
|   }, {
 | ||
|     dem: 'turkish',
 | ||
|     name: 'lira',
 | ||
|     iso: 'try',
 | ||
|     sub: 'new kuruş',
 | ||
|     sym: ['YTL']
 | ||
|   }, {
 | ||
|     dem: 'serbian',
 | ||
|     name: 'dinar',
 | ||
|     iso: 'rsd',
 | ||
|     sub: 'para',
 | ||
|     sym: ['din', 'дин']
 | ||
|   }, {
 | ||
|     dem: 'bosnia and herzegovina',
 | ||
|     name: 'convertible mark',
 | ||
|     iso: 'bam',
 | ||
|     sub: 'Fening/Pfenig',
 | ||
|     sym: ['KM']
 | ||
|   }, {
 | ||
|     dem: 'botswana',
 | ||
|     name: 'pula',
 | ||
|     iso: 'bwp',
 | ||
|     sub: 'thebe',
 | ||
|     sym: ['p']
 | ||
|   }, {
 | ||
|     dem: 'swazi',
 | ||
|     name: 'lilangeni',
 | ||
|     iso: 'szl',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['L', 'E']
 | ||
|   }, {
 | ||
|     dem: 'lithuanian',
 | ||
|     name: 'litas',
 | ||
|     iso: 'ltl',
 | ||
|     sub: 'centas',
 | ||
|     sym: ['Lt', 'ct']
 | ||
|   }, {
 | ||
|     dem: 'mauritian',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'mur',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['₨']
 | ||
|   }, {
 | ||
|     dem: 'pakistani',
 | ||
|     name: 'rupee',
 | ||
|     iso: 'pkr',
 | ||
|     sub: 'Paisa',
 | ||
|     sym: ['₨']
 | ||
|   }, {
 | ||
|     dem: 'maltese',
 | ||
|     name: 'lira',
 | ||
|     iso: 'mtl',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['₤', 'Lm']
 | ||
|   }, {
 | ||
|     dem: 'cypriot',
 | ||
|     name: 'pound',
 | ||
|     iso: 'cyp',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['£']
 | ||
|   }, {
 | ||
|     dem: 'moldovan',
 | ||
|     name: 'leu',
 | ||
|     iso: 'mdl',
 | ||
|     sub: 'ban',
 | ||
|     sym: ['l']
 | ||
|   }, {
 | ||
|     dem: 'croatian',
 | ||
|     name: 'kuna',
 | ||
|     iso: 'hrk',
 | ||
|     sub: 'lipa',
 | ||
|     sym: ['kn']
 | ||
|   }, {
 | ||
|     dem: 'afghan',
 | ||
|     name: 'afghani',
 | ||
|     iso: 'afn',
 | ||
|     sub: 'pul',
 | ||
|     sym: ['؋', 'Af', 'Afs']
 | ||
|   }, {
 | ||
|     dem: 'ecuadorian',
 | ||
|     name: 'sucre',
 | ||
|     iso: 'ecs',
 | ||
|     sub: 'centavo',
 | ||
|     sym: ['S/.']
 | ||
|   }, {
 | ||
|     dem: 'sierra leonean',
 | ||
|     name: 'leone',
 | ||
|     iso: 'sll',
 | ||
|     sub: 'cent',
 | ||
|     sym: ['Le']
 | ||
|   } // {
 | ||
|   //
 | ||
|   //   name: 'European Currency Unit',
 | ||
|   //   iso: 'xeu',
 | ||
|   //   sym: ['₠'],
 | ||
|   // },
 | ||
|   // {
 | ||
|   //
 | ||
|   //   name: 'Special drawing rights',
 | ||
|   //   iso: 'xdr',
 | ||
|   //   sym: ['SDR'],
 | ||
|   // },
 | ||
|   // {
 | ||
|   //
 | ||
|   //   name: 'Unidad de Valor Constante',
 | ||
|   //   iso: 'ecv',
 | ||
|   // },
 | ||
|   ];
 | ||
| 
 | ||
|   var symbols = {};
 | ||
|   currencies.forEach(function (o) {
 | ||
|     o.sym.forEach(function (str) {
 | ||
|       symbols[str] = symbols[str] || o.iso;
 | ||
|     });
 | ||
|     symbols[o.iso] = symbols[o.iso] || o.iso;
 | ||
|   }); // parse 'australian dollars'
 | ||
| 
 | ||
|   var getNamedCurrency = function getNamedCurrency(doc) {
 | ||
|     var m = doc.match('#Currency+');
 | ||
|     m.nouns().toSingular(); // 'dollars'➔'dollar'
 | ||
| 
 | ||
|     var str = m.text('reduced');
 | ||
|     return currencies.find(function (o) {
 | ||
|       // 'mexcan peso'
 | ||
|       if (str === "".concat(o.dem, " ").concat(o.name)) {
 | ||
|         return o;
 | ||
|       } // 'CAD'
 | ||
| 
 | ||
| 
 | ||
|       if (str === o.iso) {
 | ||
|         return o;
 | ||
|       } // 'cent'
 | ||
| 
 | ||
| 
 | ||
|       if (str === o.sub) {
 | ||
|         return o;
 | ||
|       } // 'peso'
 | ||
| 
 | ||
| 
 | ||
|       if (str === o.name) {
 | ||
|         return o;
 | ||
|       } // any other alt names
 | ||
| 
 | ||
| 
 | ||
|       if (o.alias && o.alias[str] === true) {
 | ||
|         return o;
 | ||
|       }
 | ||
| 
 | ||
|       return false;
 | ||
|     });
 | ||
|   }; // turn '£' into GBP
 | ||
| 
 | ||
| 
 | ||
|   var getBySymbol = function getBySymbol(obj) {
 | ||
|     // do suffix first, for '$50CAD'
 | ||
|     if (obj.suffix && symbols.hasOwnProperty(obj.suffix)) {
 | ||
|       return currencies.find(function (o) {
 | ||
|         return o.iso === symbols[obj.suffix];
 | ||
|       });
 | ||
|     } // parse prefix for '£50'
 | ||
| 
 | ||
| 
 | ||
|     if (obj.prefix && symbols.hasOwnProperty(obj.prefix)) {
 | ||
|       return currencies.find(function (o) {
 | ||
|         return o.iso === symbols[obj.prefix];
 | ||
|       });
 | ||
|     }
 | ||
| 
 | ||
|     return null;
 | ||
|   };
 | ||
| 
 | ||
|   var parseMoney = function parseMoney(doc) {
 | ||
|     var res = parse$1(doc);
 | ||
|     var found = getBySymbol(res) || getNamedCurrency(doc) || {};
 | ||
|     var sym = '';
 | ||
| 
 | ||
|     if (found && found.sym) {
 | ||
|       sym = found.sym[0];
 | ||
|     }
 | ||
| 
 | ||
|     return {
 | ||
|       num: res.num,
 | ||
|       iso: found.iso,
 | ||
|       demonym: found.dem,
 | ||
|       currency: found.name,
 | ||
|       plural: found.plural,
 | ||
|       symbol: sym
 | ||
|     };
 | ||
|   };
 | ||
| 
 | ||
|   var parse$2 = parseMoney;
 | ||
| 
 | ||
|   var titleCase = function titleCase() {
 | ||
|     var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
 | ||
|     return str.replace(/\w\S*/g, function (txt) {
 | ||
|       return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
 | ||
|     });
 | ||
|   };
 | ||
| 
 | ||
|   var moneyMethods = {
 | ||
|     /** which currency is this money in? */
 | ||
|     currency: function currency(n) {
 | ||
|       var arr = [];
 | ||
|       this.forEach(function (doc) {
 | ||
|         var found = parse$2(doc);
 | ||
| 
 | ||
|         if (found) {
 | ||
|           arr.push(found);
 | ||
|         }
 | ||
|       });
 | ||
| 
 | ||
|       if (typeof n === 'number') {
 | ||
|         return arr[n];
 | ||
|       }
 | ||
| 
 | ||
|       return arr;
 | ||
|     },
 | ||
| 
 | ||
|     /** overloaded json method with additional number information */
 | ||
|     json: function json(options) {
 | ||
|       var n = null;
 | ||
| 
 | ||
|       if (typeof options === 'number') {
 | ||
|         n = options;
 | ||
|         options = null;
 | ||
|       }
 | ||
| 
 | ||
|       options = options || {
 | ||
|         text: true,
 | ||
|         normal: true,
 | ||
|         trim: true,
 | ||
|         terms: true
 | ||
|       };
 | ||
|       var res = [];
 | ||
|       this.forEach(function (doc) {
 | ||
|         var json = doc.json(options)[0];
 | ||
|         var obj = parse$2(doc);
 | ||
|         json.number = obj.num;
 | ||
| 
 | ||
|         if (obj.iso) {
 | ||
|           json.iso = obj.iso.toUpperCase();
 | ||
|           json.symbol = obj.symbol;
 | ||
|           json.currency = titleCase(obj.demonym) + ' ' + titleCase(obj.currency);
 | ||
|         } // 'thirty pounds'
 | ||
| 
 | ||
| 
 | ||
|         json.textFmt = makeNumber_1(obj, true, false);
 | ||
| 
 | ||
|         if (obj.currency) {
 | ||
|           var str = obj.currency;
 | ||
| 
 | ||
|           if (obj.num !== 1) {
 | ||
|             str = obj.plural || str + 's';
 | ||
|           }
 | ||
| 
 | ||
|           json.textFmt += ' ' + str;
 | ||
|         }
 | ||
| 
 | ||
|         res.push(json);
 | ||
|       });
 | ||
| 
 | ||
|       if (n !== null) {
 | ||
|         return res[n] || {};
 | ||
|       }
 | ||
| 
 | ||
|       return res;
 | ||
|     }
 | ||
|   };
 | ||
|   var methods$1 = moneyMethods;
 | ||
| 
 | ||
|   var endS = /s$/;
 | ||
| 
 | ||
|   var slashForm = function slashForm(m) {
 | ||
|     var str = m.text('reduced');
 | ||
|     var found = str.match(/^([-+]?[0-9]+)\/([-+]?[0-9]+)(st|nd|rd|th)?s?$/);
 | ||
| 
 | ||
|     if (found && found[1] && found[0]) {
 | ||
|       return {
 | ||
|         numerator: Number(found[1]),
 | ||
|         denominator: Number(found[2])
 | ||
|       };
 | ||
|     }
 | ||
| 
 | ||
|     return null;
 | ||
|   }; // parse '4 out of 4'
 | ||
| 
 | ||
| 
 | ||
|   var textForm1 = function textForm1(m) {
 | ||
|     var found = m.match('[<num>#Value+] out of every? [<den>#Value+]');
 | ||
| 
 | ||
|     if (found.found !== true) {
 | ||
|       return null;
 | ||
|     }
 | ||
| 
 | ||
|     var _found$groups = found.groups(),
 | ||
|         num = _found$groups.num,
 | ||
|         den = _found$groups.den;
 | ||
| 
 | ||
|     num = num.numbers().get(0);
 | ||
|     den = den.numbers().get(0);
 | ||
| 
 | ||
|     if (typeof num === 'number' && typeof den === 'number') {
 | ||
|       return {
 | ||
|         numerator: num,
 | ||
|         denominator: den
 | ||
|       };
 | ||
|     }
 | ||
| 
 | ||
|     return null;
 | ||
|   }; // parse 'a third'
 | ||
| 
 | ||
| 
 | ||
|   var textForm2 = function textForm2(m) {
 | ||
|     var found = m.match('[<num>(#Cardinal|a)+] [<den>#Ordinal+]');
 | ||
| 
 | ||
|     if (found.found !== true) {
 | ||
|       return null;
 | ||
|     }
 | ||
| 
 | ||
|     var _found$groups2 = found.groups(),
 | ||
|         num = _found$groups2.num,
 | ||
|         den = _found$groups2.den; // quick-support for 'a third'
 | ||
| 
 | ||
| 
 | ||
|     if (num.has('a')) {
 | ||
|       num = 1;
 | ||
|     } else {
 | ||
|       num = num.numbers().get(0);
 | ||
|     } // turn 'thirds' into third
 | ||
| 
 | ||
| 
 | ||
|     var str = den.text('reduced');
 | ||
| 
 | ||
|     if (endS.test(str)) {
 | ||
|       str = str.replace(endS, '');
 | ||
|       den.replaceWith(str);
 | ||
|     } // support 'one half' as '1/2'
 | ||
| 
 | ||
| 
 | ||
|     if (den.has('half')) {
 | ||
|       den = 2;
 | ||
|     } else {
 | ||
|       den = den.numbers().get(0);
 | ||
|     }
 | ||
| 
 | ||
|     if (typeof num === 'number' && typeof den === 'number') {
 | ||
|       return {
 | ||
|         numerator: num,
 | ||
|         denominator: den
 | ||
|       };
 | ||
|     }
 | ||
| 
 | ||
|     return null;
 | ||
|   };
 | ||
| 
 | ||
|   var parseFraction = function parseFraction(m) {
 | ||
|     return slashForm(m) || textForm1(m) || textForm2(m) || null;
 | ||
|   };
 | ||
| 
 | ||
|   var parse$3 = parseFraction;
 | ||
| 
 | ||
|   var methods$2 = {
 | ||
|     /** overloaded json method with additional number information */
 | ||
|     json: function json(options) {
 | ||
|       var n = null;
 | ||
| 
 | ||
|       if (typeof options === 'number') {
 | ||
|         n = options;
 | ||
|         options = null;
 | ||
|       }
 | ||
| 
 | ||
|       options = options || {
 | ||
|         text: true,
 | ||
|         normal: true,
 | ||
|         trim: true,
 | ||
|         terms: true
 | ||
|       };
 | ||
|       var res = [];
 | ||
|       this.forEach(function (m) {
 | ||
|         var json = m.json(options)[0];
 | ||
|         var found = parse$3(m) || {};
 | ||
|         json.numerator = found.numerator;
 | ||
|         json.denominator = found.denominator;
 | ||
|         res.push(json);
 | ||
|       });
 | ||
| 
 | ||
|       if (n !== null) {
 | ||
|         return res[n] || {};
 | ||
|       }
 | ||
| 
 | ||
|       return res;
 | ||
|     },
 | ||
| 
 | ||
|     /** change 'four out of 10' to 4/10 */
 | ||
|     normalize: function normalize() {
 | ||
|       var _this = this;
 | ||
| 
 | ||
|       this.forEach(function (m) {
 | ||
|         var found = parse$3(m);
 | ||
| 
 | ||
|         if (found && typeof found.numerator === 'number' && typeof found.denominator === 'number') {
 | ||
|           var str = "".concat(found.numerator, "/").concat(found.denominator);
 | ||
| 
 | ||
|           _this.replace(m, str);
 | ||
|         }
 | ||
|       });
 | ||
|       return this;
 | ||
|     }
 | ||
|   };
 | ||
|   var methods_1$1 = methods$2;
 | ||
| 
 | ||
|   var here = 'number-tag';
 | ||
|   var multiples = '(hundred|thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion)'; //support 'two thirds'
 | ||
|   // (do this conservatively)
 | ||
| 
 | ||
|   var ordinals = ['half', 'third', 'fourth', 'quarter', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'hundredth', 'thousandth', 'millionth']; // add plural forms
 | ||
| 
 | ||
|   var len = ordinals.length;
 | ||
| 
 | ||
|   for (var i = 0; i < len; i += 1) {
 | ||
|     ordinals.push(ordinals[i] + 's');
 | ||
|   }
 | ||
| 
 | ||
|   ordinals = "(".concat(ordinals.join('|'), ")"); // improved tagging for numbers
 | ||
| 
 | ||
|   var tagger = function tagger(doc) {
 | ||
|     doc.match(multiples).tag('#Multiple', here); //  in the 400s
 | ||
| 
 | ||
|     doc.match('the [/[0-9]+s$/]').tag('#Plural', here); //half a million
 | ||
| 
 | ||
|     doc.match('half a? #Value').tag('Value', 'half-a-value'); //(quarter not ready)
 | ||
|     //five and a half
 | ||
| 
 | ||
|     doc.match('#Value and a (half|quarter)').tag('Value', 'value-and-a-half'); //one hundred and seven dollars
 | ||
| 
 | ||
|     doc.match('#Money and #Money #Currency?').tag('Money', 'money-and-money'); // $5.032 is invalid money
 | ||
| 
 | ||
|     doc.match('#Money').not('#TextValue').match('/\\.[0-9]{3}$/').unTag('#Money', 'three-decimal money'); // cleanup currency false-positives
 | ||
| 
 | ||
|     doc.ifNo('#Value').match('#Currency #Verb').unTag('Currency', 'no-currency'); // 6 dollars and 5 cents
 | ||
| 
 | ||
|     doc.match('#Value #Currency [and] #Value (cents|ore|centavos|sens)', 0).tag('Money', here); // maybe currencies
 | ||
| 
 | ||
|     var m = doc.match('[<num>#Value] [<currency>(mark|rand|won|rub|ore)]');
 | ||
|     m.group('num').tag('Money', here);
 | ||
|     m.group('currency').tag('Currency', here); // fraction - '3 out of 5'
 | ||
| 
 | ||
|     doc.match('#Cardinal+ out of every? #Cardinal').tag('Fraction', here); // fraction - 'a third of a slice'
 | ||
| 
 | ||
|     m = doc.match("[(#Cardinal|a) ".concat(ordinals, "] of (a|an|the)"), 0).tag('Fraction', here); // tag 'thirds' as a ordinal
 | ||
| 
 | ||
|     m.match('.$').tag('Ordinal', 'plural-ordinal');
 | ||
|   };
 | ||
| 
 | ||
|   var tagger_1 = tagger;
 | ||
| 
 | ||
|   var tags = {
 | ||
|     Fraction: {
 | ||
|       isA: ['Value', 'NumericValue']
 | ||
|     },
 | ||
|     Multiple: {
 | ||
|       isA: 'Value'
 | ||
|     }
 | ||
|   };
 | ||
| 
 | ||
|   var ambig = {
 | ||
|     mark: true,
 | ||
|     sucre: true,
 | ||
|     leone: true,
 | ||
|     afghani: true,
 | ||
|     rand: true,
 | ||
|     "try": true,
 | ||
|     mop: true,
 | ||
|     won: true,
 | ||
|     all: true,
 | ||
|     rub: true,
 | ||
|     eek: true,
 | ||
|     sit: true,
 | ||
|     bam: true,
 | ||
|     npr: true,
 | ||
|     leu: true
 | ||
|   };
 | ||
|   var lex = {
 | ||
|     kronor: 'Currency'
 | ||
|   };
 | ||
|   currencies.forEach(function (o) {
 | ||
|     if (o.iso && !ambig[o.iso]) {
 | ||
|       lex[o.iso] = ['Acronym', 'Currency'];
 | ||
|     }
 | ||
| 
 | ||
|     var name = o.name;
 | ||
| 
 | ||
|     if (name && !ambig[name]) {
 | ||
|       lex[name] = 'Currency';
 | ||
|       lex[name + 's'] = 'Currency';
 | ||
|     }
 | ||
| 
 | ||
|     if (o.dem) {
 | ||
|       var dem = o.dem;
 | ||
|       lex["".concat(dem, " ").concat(name)] = 'Currency';
 | ||
|       lex["".concat(dem, " ").concat(name, "s")] = 'Currency';
 | ||
|     }
 | ||
|   });
 | ||
|   var lexicon = lex;
 | ||
| 
 | ||
|   /** adds .numbers() method */
 | ||
| 
 | ||
|   var plugin = function plugin(Doc, world) {
 | ||
|     // add money words to our lexicon
 | ||
|     world.addWords(lexicon); // add tags to our tagset
 | ||
| 
 | ||
|     world.addTags(tags); // additional tagging before running the number-parser
 | ||
| 
 | ||
|     world.postProcess(tagger_1);
 | ||
|     /** a list of number values, and their units */
 | ||
| 
 | ||
|     var Numbers = /*#__PURE__*/function (_Doc) {
 | ||
|       _inherits(Numbers, _Doc);
 | ||
| 
 | ||
|       var _super = _createSuper(Numbers);
 | ||
| 
 | ||
|       function Numbers() {
 | ||
|         _classCallCheck(this, Numbers);
 | ||
| 
 | ||
|         return _super.apply(this, arguments);
 | ||
|       }
 | ||
| 
 | ||
|       return Numbers;
 | ||
|     }(Doc);
 | ||
| 
 | ||
|     Object.assign(Numbers.prototype, methods_1);
 | ||
|     /** a number and a currency */
 | ||
| 
 | ||
|     var Money = /*#__PURE__*/function (_Numbers) {
 | ||
|       _inherits(Money, _Numbers);
 | ||
| 
 | ||
|       var _super2 = _createSuper(Money);
 | ||
| 
 | ||
|       function Money() {
 | ||
|         _classCallCheck(this, Money);
 | ||
| 
 | ||
|         return _super2.apply(this, arguments);
 | ||
|       }
 | ||
| 
 | ||
|       return Money;
 | ||
|     }(Numbers);
 | ||
| 
 | ||
|     Object.assign(Money.prototype, methods$1);
 | ||
| 
 | ||
|     var Fraction = /*#__PURE__*/function (_Numbers2) {
 | ||
|       _inherits(Fraction, _Numbers2);
 | ||
| 
 | ||
|       var _super3 = _createSuper(Fraction);
 | ||
| 
 | ||
|       function Fraction() {
 | ||
|         _classCallCheck(this, Fraction);
 | ||
| 
 | ||
|         return _super3.apply(this, arguments);
 | ||
|       }
 | ||
| 
 | ||
|       return Fraction;
 | ||
|     }(Numbers);
 | ||
| 
 | ||
|     Object.assign(Fraction.prototype, methods_1$1);
 | ||
|     var docMethods = {
 | ||
|       /** find all numbers and values */
 | ||
|       numbers: function numbers(n) {
 | ||
|         var m = find(this, n);
 | ||
|         return new Numbers(m.list, this, this.world);
 | ||
|       },
 | ||
| 
 | ||
|       /** return '4%' or 'four percent' etc*/
 | ||
|       percentages: function percentages(n) {
 | ||
|         var m = this.match('#Percent+');
 | ||
|         m = m.concat(this.match('[#Cardinal] percent', 0));
 | ||
| 
 | ||
|         if (typeof n === 'number') {
 | ||
|           m = m.eq(n);
 | ||
|         }
 | ||
| 
 | ||
|         return new Numbers(m.list, this, this.world);
 | ||
|       },
 | ||
| 
 | ||
|       /** return '3 out of 5' or '3/5' etc**/
 | ||
|       fractions: function fractions(n) {
 | ||
|         var m = this.match('#Fraction+');
 | ||
| 
 | ||
|         if (typeof n === 'number') {
 | ||
|           m = m.eq(n);
 | ||
|         }
 | ||
| 
 | ||
|         return new Fraction(m.list, this, this.world);
 | ||
|       },
 | ||
| 
 | ||
|       /** number + currency pair */
 | ||
|       money: function money() {
 | ||
|         var m = this.splitOn('(#Money|#Currency)+');
 | ||
|         m = m["if"]('#Money')["if"]('#Value');
 | ||
|         return new Money(m.list, this, this.world);
 | ||
|       }
 | ||
|     }; // aliases
 | ||
| 
 | ||
|     docMethods.values = docMethods.numbers;
 | ||
|     docMethods.percents = docMethods.percentages;
 | ||
|     Object.assign(Doc.prototype, docMethods);
 | ||
|     return Doc;
 | ||
|   };
 | ||
| 
 | ||
|   var src = plugin;
 | ||
| 
 | ||
|   return src;
 | ||
| 
 | ||
| })));
 | ||
| //# sourceMappingURL=compromise-numbers.js.map
 |