Socket
Socket
Sign inDemoInstall

globalize

Package Overview
Dependencies
Maintainers
4
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

globalize - npm Package Compare versions

Comparing version 1.0.0-alpha.10 to 1.0.0-alpha.11

doc/api/plural/plural-generator.md

6

bower.json
{
"name": "globalize",
"version": "1.0.0-alpha.10",
"version": "1.0.0-alpha.11",
"license": "MIT",

@@ -12,7 +12,7 @@ "ignore": [

"dependencies": {
"cldrjs": "0.3.9",
"cldrjs": "0.3.10",
"cldr-data": ">=25"
},
"devDependencies": {
"CLDRPluralRuleParser": "santhoshtr/CLDRPluralRuleParser#6b17882b834b1ab8bb3a593fd66529c9822dd6d7",
"make-plural": "eemeli/make-plural.js#2.1.2",
"es5-shim": "3.4.0",

@@ -19,0 +19,0 @@ "qunit": "1.12.0",

@@ -1,3 +0,3 @@

/*!
* Globalize v1.0.0-alpha.10
/**
* Globalize v1.0.0-alpha.11
*

@@ -10,4 +10,8 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/
/*!
* Globalize v1.0.0-alpha.11 2014-12-03T12:09Z Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -232,2 +236,10 @@

// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
var regexpEscape = function( string ) {
return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" );
};
function validateLikelySubtags( cldr ) {

@@ -301,3 +313,3 @@ cldr.once( "get", validateCldr );

Globalize._isPlainObject = isPlainObject;
Globalize._validate = validate;
Globalize._regexpEscape = regexpEscape;
Globalize._validateCldr = validateCldr;

@@ -309,2 +321,3 @@ Globalize._validateDefaultLocale = validateDefaultLocale;

Globalize._validateParameterType = validateParameterType;
Globalize._validate = validate;

@@ -311,0 +324,0 @@ return Globalize;

@@ -1,3 +0,3 @@

/*!
* Globalize v1.0.0-alpha.10
/**
* Globalize v1.0.0-alpha.11
*

@@ -10,4 +10,8 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/
/*!
* Globalize v1.0.0-alpha.11 2014-12-03T12:09Z Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -39,2 +43,3 @@

isPlainObject = Globalize._isPlainObject,
regexpEscape = Globalize._regexpEscape,
validateCldr = Globalize._validateCldr,

@@ -275,3 +280,3 @@ validateDefaultLocale = Globalize._validateDefaultLocale,

var datePatternRe = (/([a-z])\1*|'[^']+'|''|./ig);
var datePatternRe = (/([a-z])\1*|'([^']|'')+'|''|./ig);

@@ -555,3 +560,11 @@

// Anything else is considered a literal, including [ ,:/.'@#], chinese, japonese, and
// ' literals.
case "'":
current = current.replace( /''/, "'" );
if ( length > 2 ) {
current = current.slice( 1, -1 );
}
return current;
// Anything else is considered a literal, including [ ,:/.@#], chinese, japonese, and
// arabic characters.

@@ -1383,7 +1396,7 @@ default:

token.type = "literal";
if ( current.charAt( 1 ) === "'" ) {
tokenRe = /'/;
} else {
tokenRe = /'[^']+'/;
current = current.replace( /''/, "'" );
if ( length > 2 ) {
current = current.slice( 1, -1 );
}
tokenRe = new RegExp( regexpEscape( current ) );
break;

@@ -1390,0 +1403,0 @@

@@ -1,3 +0,3 @@

/*!
* Globalize v1.0.0-alpha.10
/**
* Globalize v1.0.0-alpha.11
*

@@ -10,4 +10,8 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/
/*!
* Globalize v1.0.0-alpha.11 2014-12-03T12:09Z Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -14,0 +18,0 @@

@@ -1,3 +0,3 @@

/*!
* Globalize v1.0.0-alpha.10
/**
* Globalize v1.0.0-alpha.11
*

@@ -10,4 +10,8 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/
/*!
* Globalize v1.0.0-alpha.11 2014-12-03T12:09Z Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -22,3 +26,4 @@

"../globalize",
"cldr/event"
"cldr/event",
"cldr/supplemental"
], factory );

@@ -37,2 +42,3 @@ } else if ( typeof exports === "object" ) {

var createError = Globalize._createError,
regexpEscape = Globalize._regexpEscape,
validateCldr = Globalize._validateCldr,

@@ -298,3 +304,3 @@ validateDefaultLocale = Globalize._validateDefaultLocale,

var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, padding, prefix,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix,
primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,

@@ -316,2 +322,3 @@ symbolMap;

symbolMap = properties[ 18 ];
nuDigitsMap = properties[ 19 ];

@@ -374,3 +381,3 @@ // NaN

// Padding
// Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g
// TODO implement here

@@ -380,8 +387,26 @@

// Symbols
return ret.replace( /'[^']+'|[.,\-+E%\u2030]/g, function( symbol ) {
if ( symbol.charAt( 0 ) === "'" ) {
return symbol;
return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) {
// Literals
if ( literal ) {
literal = literal.replace( /''/, "'" );
if ( literal.length > 2 ) {
literal = literal.slice( 1, -1 );
}
return literal;
}
return symbolMap[ symbol ];
// Symbols
character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) {
return symbolMap[ symbol ];
});
// Numbering system
if ( nuDigitsMap ) {
character = character.replace( /[0-9]/, function( digit ) {
return nuDigitsMap[ +digit ];
});
}
return character;
});

@@ -394,2 +419,61 @@ };

/**
* NumberingSystem( cldr )
*
* - http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems
* - http://cldr.unicode.org/index/bcp47-extension
* - http://www.unicode.org/reports/tr35/#u_Extension
*/
var numberNumberingSystem = function( cldr ) {
var nu = cldr.attributes[ "u-nu" ];
if ( nu ) {
if ( nu === "traditio" ) {
nu = "traditional";
}
if ( [ "native", "traditional", "finance" ].indexOf( nu ) !== -1 ) {
// Unicode locale extension `u-nu` is set using either (native, traditional or
// finance). So, lookup the respective locale's numberingSystem and return it.
return cldr.main([ "numbers/otherNumberingSystems", nu ]);
}
// Unicode locale extension `u-nu` is set with an explicit numberingSystem. Return it.
return nu;
}
// Return the default numberingSystem.
return cldr.main( "numbers/defaultNumberingSystem" );
};
/**
* nuMap( cldr )
*
* @cldr [Cldr instance].
*
* Return digits map if numbering system is different than `latn`.
*/
var numberNumberingSystemDigitsMap = function( cldr ) {
var aux,
nu = numberNumberingSystem( cldr );
if ( nu === "latn" ) {
return;
}
aux = cldr.supplemental([ "numberingSystems", nu ]);
if ( aux._type !== "numeric" ) {
throw createErrorUnsupportedFeature( "`" + aux._type + "` numbering system" );
}
return aux._digits;
};
/**
* EBNF representation:

@@ -574,14 +658,2 @@ *

/**
* NumberingSystem( cldr )
*
* TODO support ( native | traditional | finance ).
*/
var numberNumberingSystem = function( cldr ) {
return cldr.main( "numbers/defaultNumberingSystem" );
};
/**
* Symbol( name, cldr )

@@ -720,3 +792,4 @@ *

numberSymbol( "nan", cldr ),
numberSymbolMap( cldr )
numberSymbolMap( cldr ),
numberNumberingSystemDigitsMap( cldr )
]);

@@ -756,2 +829,3 @@

// 18: @symbolMap [Object] A bunch of other symbols.
// 19: @nuDigitsMap [Array] Digits map if numbering system is different than `latn`.
return properties;

@@ -803,10 +877,2 @@ };

// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
var regexpEscape = function( string ) {
return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" );
};
/**

@@ -824,4 +890,4 @@ * parse( value, properties )

var numberParse = function( value, properties ) {
var aux, infinitySymbol, invertedSymbolMap, localizedSymbolsRe, negativePrefix, negativeSuffix,
number, prefix, suffix;
var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe,
localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix;

@@ -832,2 +898,3 @@ infinitySymbol = properties[ 0 ];

negativeSuffix = properties[ 3 ];
invertedNuDigitsMap = properties[ 4 ];

@@ -844,2 +911,3 @@ // Infinite number.

// TODO: Create it during setup, i.e., make it a property.
localizedSymbolsRe = new RegExp(

@@ -857,2 +925,17 @@ Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {

// Reverse localized numbering system.
if ( invertedNuDigitsMap ) {
// TODO: Create it during setup, i.e., make it a property.
localizedDigitRe = new RegExp(
Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) {
return regexpEscape( localizedDigit );
}).join( "|" ),
"g"
);
value = value.replace( localizedDigitRe, function( localizedDigit ) {
return invertedNuDigitsMap[ localizedDigit ];
});
}
// Is it a valid number?

@@ -965,3 +1048,4 @@ value = value.match( numberNumberRe );

var numberParseProperties = function( pattern, cldr ) {
var negativePattern, negativeProperties;
var invertedNuDigitsMap, invertedNuDigitsMapSanityCheck, negativePattern, negativeProperties,
nuDigitsMap = numberNumberingSystemDigitsMap( cldr );

@@ -971,2 +1055,16 @@ pattern = pattern.split( ";" );

negativeProperties = numberPatternProperties( negativePattern );
if ( nuDigitsMap ) {
invertedNuDigitsMap = nuDigitsMap.split( "" ).reduce(function( object, localizedDigit, i ) {
object[ localizedDigit ] = String( i );
return object;
}, {} );
invertedNuDigitsMapSanityCheck = "0123456789".split( "" ).reduce(function( object, digit ) {
object[ digit ] = "invalid";
return object;
}, {} );
invertedNuDigitsMap = objectFlatExtend(
invertedNuDigitsMapSanityCheck,
invertedNuDigitsMap
);
}

@@ -981,2 +1079,4 @@ // 0: @infinitySymbol [String] Infinity symbol.

// 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out.
// 4: @invertedNuDigitsMap [Object] Inverted digits map if numbering system is different than
// `latn` augmented with sanity check (similar to invertedSymbolMap).
return [

@@ -986,3 +1086,4 @@ numberSymbol( "infinity", cldr ),

negativeProperties[ 0 ],
negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" )
negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" ),
invertedNuDigitsMap
];

@@ -989,0 +1090,0 @@ };

@@ -1,3 +0,3 @@

/*!
* Globalize v1.0.0-alpha.10
/**
* Globalize v1.0.0-alpha.11
*

@@ -10,4 +10,8 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/
/*!
* Globalize v1.0.0-alpha.11 2014-12-03T12:09Z Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -22,3 +26,4 @@

"../globalize",
"cldr/event"
"cldr/event",
"cldr/supplemental"
], factory );

@@ -36,662 +41,174 @@ } else if ( typeof exports === "object" ) {

var formatMessage = Globalize._formatMessage,
validate = Globalize._validate,
validateCldr = Globalize._validateCldr,
var validateCldr = Globalize._validateCldr,
validateDefaultLocale = Globalize._validateDefaultLocale,
validateParameterPresence = Globalize._validateParameterPresence,
validateParameterType = Globalize._validateParameterType,
validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject;
validateParameterType = Globalize._validateParameterType;
/**
* parameterKeyPresence( value, name, key )
* make-plural.js -- https://github.com/eemeli/make-plural.js/
* Copyright (c) 2014 by Eemeli Aro <eemeli@gmail.com>
*
* @value [Object] Variable value.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* @name [String] Name of variable.
*
* @key [String] The lowest valid value, inclusive.
* The software is provided "as is" and the author disclaims all warranties
* with regard to this software including all implied warranties of
* merchantability and fitness. In no event shall the author be liable for
* any special, direct, indirect, or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether in an
* action of contract, negligence or other tortious action, arising out of
* or in connection with the use or performance of this software.
*/
var validateParameterKeyPresence = function( value, name, key ) {
validate(
"E_PAR_MISSING_KEY",
"Parameter `{name}` misses key `{key}`",
value === undefined || key in value,
{
key: key,
name: "messageData"
}
);
};
var MakePlural;
/* jshint ignore:start */
MakePlural = (function() {
var validateParameterTypeNumber = function( value, name ) {
validateParameterType(
value,
name,
value === undefined || typeof value === "number",
"Number"
);
};
/**
* cldrpluralparser.js
* A parser engine for CLDR plural rules.
*
* Copyright 2012-2014 Santhosh Thottingal and other contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
* @source https://github.com/santhoshtr/CLDRPluralRuleParser
* @author Santhosh Thottingal <santhosh.thottingal@gmail.com>
* @author Timo Tijhof
* @author Amir Aharoni
*/
/**
* Evaluates a plural rule in CLDR syntax for a number
* @param {string} rule
* @param {integer} number
* @return {boolean} true if evaluation passed, false if evaluation failed.
*/
// UMD returnExports https://github.com/umdjs/umd/blob/master/returnExports.js
var CLDRPluralRuleParser = (function() {
function pluralRuleParser(rule, number) {
/*
Syntax: see http://unicode.org/reports/tr35/#Language_Plural_Rules
-----------------------------------------------------------------
condition = and_condition ('or' and_condition)*
('@integer' samples)?
('@decimal' samples)?
and_condition = relation ('and' relation)*
relation = is_relation | in_relation | within_relation
is_relation = expr 'is' ('not')? value
in_relation = expr (('not')? 'in' | '=' | '!=') range_list
within_relation = expr ('not')? 'within' range_list
expr = operand (('mod' | '%') value)?
operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
range_list = (range | value) (',' range_list)*
value = digit+
digit = 0|1|2|3|4|5|6|7|8|9
range = value'..'value
samples = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
sampleRange = decimalValue '~' decimalValue
decimalValue = value ('.' value)?
*/
// We don't evaluate the samples section of the rule. Ignore it.
rule = rule.split('@')[0].replace(/^\s*/, '').replace(/\s*$/, '');
if (!rule.length) {
// Empty rule or 'other' rule.
return true;
function parse(cond, symbols) {
if (cond == 'i = 0 or n = 1') return 'n >= 0 && n <= 1';
if (cond == 'i = 0,1') return 'n >= 0 && n < 2';
if (cond == 'i = 1 and v = 0') {
symbols['v0'] = 1;
return 'n == 1 && v0';
}
// Indicates the current position in the rule as we parse through it.
// Shared among all parsing functions below.
var pos = 0,
operand,
expression,
relation,
result,
whitespace = makeRegexParser(/^\s+/),
value = makeRegexParser(/^\d+/),
_n_ = makeStringParser('n'),
_i_ = makeStringParser('i'),
_f_ = makeStringParser('f'),
_t_ = makeStringParser('t'),
_v_ = makeStringParser('v'),
_w_ = makeStringParser('w'),
_is_ = makeStringParser('is'),
_isnot_ = makeStringParser('is not'),
_isnot_sign_ = makeStringParser('!='),
_equal_ = makeStringParser('='),
_mod_ = makeStringParser('mod'),
_percent_ = makeStringParser('%'),
_not_ = makeStringParser('not'),
_in_ = makeStringParser('in'),
_within_ = makeStringParser('within'),
_range_ = makeStringParser('..'),
_comma_ = makeStringParser(','),
_or_ = makeStringParser('or'),
_and_ = makeStringParser('and');
function debug() {
// console.log.apply(console, arguments);
}
debug('pluralRuleParser', rule, number);
// Try parsers until one works, if none work return null
function choice(parserSyntax) {
return function() {
var i, result;
for (i = 0; i < parserSyntax.length; i++) {
result = parserSyntax[i]();
if (result !== null) {
return result;
}
return cond
.replace(/([tv]) (!?)= 0/g, function(m, sym, noteq) {
var sn = sym + '0';
symbols[sn] = 1;
return noteq ? '!' + sn : sn;
})
.replace(/\b[fintv]\b/g, function(m) {
symbols[m] = 1;
return m;
})
.replace(/([fin]) % (10+)/g, function(m, sym, num) {
var sn = sym + num;
symbols[sn] = 1;
return sn;
})
.replace(/n10+ = 0/g, 't0 && $&')
.replace(/(\w+ (!?)= )([0-9.]+,[0-9.,]+)/g, function(m, se, noteq, x) {
if (m == 'n = 0,1') return '(n == 0 || n == 1)';
if (noteq) return se + x.split(',').join(' && ' + se);
return '(' + se + x.split(',').join(' || ' + se) + ')';
})
.replace(/(\w+) (!?)= ([0-9]+)\.\.([0-9]+)/g, function(m, sym, noteq, x0, x1) {
if (Number(x0) + 1 == Number(x1)) {
if (noteq) return sym + ' != ' + x0 + ' && ' + sym + ' != ' + x1;
return '(' + sym + ' == ' + x0 + ' || ' + sym + ' == ' + x1 + ')';
}
if (noteq) return '(' + sym + ' < ' + x0 + ' || ' + sym + ' > ' + x1 + ')';
if (sym == 'n') { symbols['t0'] = 1; return '(t0 && n >= ' + x0 + ' && n <= ' + x1 + ')'; }
return '(' + sym + ' >= ' + x0 + ' && ' + sym + ' <= ' + x1 + ')';
})
.replace(/ and /g, ' && ')
.replace(/ or /g, ' || ')
.replace(/ = /g, ' == ');
}
return null;
};
function vars(symbols) {
var vars = [];
if (symbols['i']) vars.push("i = s[0]");
if (symbols['f'] || symbols['v']) vars.push("f = s[1] || ''");
if (symbols['t']) vars.push("t = (s[1] || '').replace(/0+$/, '')");
if (symbols['v']) vars.push("v = f.length")
if (symbols['v0']) vars.push("v0 = !s[1]");
if (symbols['t0'] || symbols['n10'] || symbols['n100']) vars.push("t0 = Number(s[0]) == n");
for (var k in symbols) if (/^.10+$/.test(k)) {
var k0 = (k[0] == 'n') ? 't0 && s[0]' : k[0];
vars.push(k + ' = ' + k0 + '.substr(-' + k.substr(2).length + ')');
}
// Try several parserSyntax-es in a row.
// All must succeed; otherwise, return null.
// This is the only eager one.
function sequence(parserSyntax) {
var i, parserRes,
originalPos = pos,
result = [];
for (i = 0; i < parserSyntax.length; i++) {
parserRes = parserSyntax[i]();
if (parserRes === null) {
pos = originalPos;
return null;
}
result.push(parserRes);
}
return result;
if (vars.length) {
vars.unshift("s = String(n).split('.')");
return 'var ' + vars.join(', ') + ';';
}
return '';
}
// Run the same parser over and over until it fails.
// Must succeed a minimum of n times; otherwise, return null.
function nOrMore(n, p) {
return function() {
var originalPos = pos,
result = [],
parsed = p();
while (parsed !== null) {
result.push(parsed);
parsed = p();
}
if (result.length < n) {
pos = originalPos;
return null;
}
return result;
};
}
// Helpers - just make parserSyntax out of simpler JS builtin types
function makeStringParser(s) {
var len = s.length;
return function() {
var result = null;
if (rule.substr(pos, len) === s) {
result = s;
pos += len;
}
return result;
};
}
function makeRegexParser(regex) {
return function() {
var matches = rule.substr(pos).match(regex);
if (matches === null) {
return null;
}
pos += matches[0].length;
return matches[0];
};
}
/**
* Integer digits of n.
*/
function i() {
var result = _i_();
if (result === null) {
debug(' -- failed i', parseInt(number, 10));
return result;
}
result = parseInt(number, 10);
debug(' -- passed i ', result);
return result;
}
/**
* Absolute value of the source number (integer and decimals).
*/
function n() {
var result = _n_();
if (result === null) {
debug(' -- failed n ', number);
return result;
}
result = parseFloat(number, 10);
debug(' -- passed n ', result);
return result;
}
/**
* Visible fractional digits in n, with trailing zeros.
*/
function f() {
var result = _f_();
if (result === null) {
debug(' -- failed f ', number);
return result;
}
result = (number + '.').split('.')[1] || 0;
debug(' -- passed f ', result);
return result;
}
/**
* Visible fractional digits in n, without trailing zeros.
*/
function t() {
var result = _t_();
if (result === null) {
debug(' -- failed t ', number);
return result;
}
result = (number + '.').split('.')[1].replace(/0$/, '') || 0;
debug(' -- passed t ', result);
return result;
}
/**
* Number of visible fraction digits in n, with trailing zeros.
*/
function v() {
var result = _v_();
if (result === null) {
debug(' -- failed v ', number);
return result;
}
result = (number + '.').split('.')[1].length || 0;
debug(' -- passed v ', result);
return result;
}
/**
* Number of visible fraction digits in n, without trailing zeros.
*/
function w() {
var result = _w_();
if (result === null) {
debug(' -- failed w ', number);
return result;
}
result = (number + '.').split('.')[1].replace(/0$/, '').length || 0;
debug(' -- passed w ', result);
return result;
}
// operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
operand = choice([n, i, f, t, v, w]);
// expr = operand (('mod' | '%') value)?
expression = choice([mod, operand]);
function mod() {
var result = sequence(
[operand, whitespace, choice([_mod_, _percent_]), whitespace, value]
);
if (result === null) {
debug(' -- failed mod');
return null;
}
debug(' -- passed ' + parseInt(result[0], 10) + ' ' + result[2] + ' ' + parseInt(result[4], 10));
return parseFloat(result[0]) % parseInt(result[4], 10);
}
function not() {
var result = sequence([whitespace, _not_]);
if (result === null) {
debug(' -- failed not');
return null;
}
return result[1];
}
// is_relation = expr 'is' ('not')? value
function is() {
var result = sequence([expression, whitespace, choice([_is_]), whitespace, value]);
if (result !== null) {
debug(' -- passed is : ' + result[0] + ' == ' + parseInt(result[4], 10));
return result[0] === parseInt(result[4], 10);
}
debug(' -- failed is');
return null;
}
// is_relation = expr 'is' ('not')? value
function isnot() {
var result = sequence(
[expression, whitespace, choice([_isnot_, _isnot_sign_]), whitespace, value]
);
if (result !== null) {
debug(' -- passed isnot: ' + result[0] + ' != ' + parseInt(result[4], 10));
return result[0] !== parseInt(result[4], 10);
}
debug(' -- failed isnot');
return null;
}
function not_in() {
var i, range_list,
result = sequence([expression, whitespace, _isnot_sign_, whitespace, rangeList]);
if (result !== null) {
debug(' -- passed not_in: ' + result[0] + ' != ' + result[4]);
range_list = result[4];
for (i = 0; i < range_list.length; i++) {
if (parseInt(range_list[i], 10) === parseInt(result[0], 10)) {
return false;
function build(lc, opt, tests) {
var lines = [], symbols = {},
_fold = function(l) { return l.replace(/(.{1,72})( \|\| |$) ?/gm, '$1\n $2').replace(/\s+$/gm, ''); },
_compile = function(type, req) {
var cases = [];
if (MakePlural.rules[type][lc]) {
for (var r in MakePlural.rules[type][lc]) {
var key = r.replace('pluralRule-count-', ''),
parts = MakePlural.rules[type][lc][r].split(/@\w*/),
cond = parts.shift().trim();
if (cond) cases.push([parse(cond, symbols), key]);
tests[type][key] = parts.join(' ')
.replace(/^[ ,]+|[ ,…]+$/g, '')
.replace(/(0\.[0-9])~(1\.[1-9])/g, '$1 1.0 $2')
.split(/[ ,~…]+/);
}
}
return true;
}
debug(' -- failed not_in');
return null;
}
// range_list = (range | value) (',' range_list)*
function rangeList() {
var result = sequence([choice([range, value]), nOrMore(0, rangeTail)]),
resultList = [];
if (result !== null) {
resultList = resultList.concat(result[0]);
if (result[1][0]) {
resultList = resultList.concat(result[1][0]);
}
return resultList;
}
debug(' -- failed rangeList');
return null;
}
function rangeTail() {
// ',' range_list
var result = sequence([_comma_, rangeList]);
if (result !== null) {
return result[1];
}
debug(' -- failed rangeTail');
return null;
}
// range = value'..'value
function range() {
var i, array, left, right,
result = sequence([value, _range_, value]);
if (result !== null) {
debug(' -- passed range');
array = [];
left = parseInt(result[0], 10);
right = parseInt(result[2], 10);
for (i = left; i <= right; i++) {
array.push(i);
}
return array;
}
debug(' -- failed range');
return null;
}
function _in() {
var result, range_list, i;
// in_relation = expr ('not')? 'in' range_list
result = sequence(
[expression, nOrMore(0, not), whitespace, choice([_in_, _equal_]), whitespace, rangeList]
);
if (result !== null) {
debug(' -- passed _in:' + result);
range_list = result[5];
for (i = 0; i < range_list.length; i++) {
if (parseInt(range_list[i], 10) === parseFloat(result[0])) {
return (result[1][0] !== 'not');
}
}
return (result[1][0] === 'not');
}
debug(' -- failed _in ');
return null;
}
/**
* The difference between "in" and "within" is that
* "in" only includes integers in the specified range,
* while "within" includes all values.
*/
function within() {
var range_list, result;
// within_relation = expr ('not')? 'within' range_list
result = sequence(
[expression, nOrMore(0, not), whitespace, _within_, whitespace, rangeList]
);
if (result !== null) {
debug(' -- passed within');
range_list = result[5];
if ((result[0] >= parseInt(range_list[0], 10)) &&
(result[0] < parseInt(range_list[range_list.length - 1], 10))) {
return (result[1][0] !== 'not');
}
return (result[1][0] === 'not');
}
debug(' -- failed within ');
return null;
}
// relation = is_relation | in_relation | within_relation
relation = choice([is, not_in, isnot, _in, within]);
// and_condition = relation ('and' relation)*
function and() {
var i,
result = sequence([relation, nOrMore(0, andTail)]);
if (result) {
if (!result[0]) {
} else if (req) {
if (!opt['quiet']) console.error('Locale "' + lc + '" ' + type + ' rules not found');
return false;
}
if (!cases.length) return "'other'";
if (cases.length == 1) return "(" + cases[0][0] + ") ? '" + cases[0][1] + "' : 'other'";
return cases.map(function(c) { return "(" + c[0] + ") ? '" + c[1] + "'"; }).concat("'other'").join('\n : ');
};
for (i = 0; i < result[1].length; i++) {
if (!result[1][i]) {
return false;
}
}
return true;
if (opt['ordinals']) {
if (opt['no_cardinals']) {
var l = _compile('ordinal', true);
if (!l) return null;
lines.push(_fold(' return ' + l + ';'));
} else {
lines.push(_fold(' if (ord) return ' + _compile('ordinal', false) + ';'));
}
debug(' -- failed and');
return null;
}
// ('and' relation)*
function andTail() {
var result = sequence([whitespace, _and_, whitespace, relation]);
if (result !== null) {
debug(' -- passed andTail' + result);
return result[3];
}
debug(' -- failed andTail');
return null;
if (!opt['no_cardinals']) {
var l = _compile('cardinal', true);
if (!l) return null;
lines.push(_fold(' return ' + l + ';'));
}
// ('or' and_condition)*
function orTail() {
var result = sequence([whitespace, _or_, whitespace, and]);
var fn_vars = vars(symbols).replace(/(.{1,78})(,|$) ?/g, '\n $1$2').trim();
if (fn_vars) lines.unshift(' ' + fn_vars);
return lines.join('\n');
}
if (result !== null) {
debug(' -- passed orTail: ' + result[3]);
return result[3];
}
debug(' -- failed orTail');
return null;
}
// condition = and_condition ('or' and_condition)*
function condition() {
var i,
result = sequence([and, nOrMore(0, orTail)]);
if (result) {
for (i = 0; i < result[1].length; i++) {
if (result[1][i]) {
return true;
}
}
return result[0];
}
return false;
var MakePlural = function(lc, opt) {
if (typeof lc == 'object') { opt = lc; lc = opt.lc; }
else {
if (!opt) opt = MakePlural.opt;
if (!lc) lc = opt.lc;
}
var tests = { 'ordinal':{}, 'cardinal':{} },
fn_body = build(lc, opt, tests),
fn = opt['ordinals'] && !opt['no_cardinals']
? new Function('n', 'ord', fn_body)
: new Function('n', fn_body);
fn.toString = function(name) {
var s = Function.prototype.toString.call(fn);
return s.replace(/^function( \w+)?/, name ? 'function ' + name : 'function');
};
return fn_body && (opt['no_tests'] || test(lc, fn, tests, opt)) ? fn : null;
};
result = condition();
MakePlural.opt = {};
MakePlural.rules = {};
/**
* For success, the pos must have gotten to the end of the rule
* and returned a non-null.
* n.b. This is part of language infrastructure,
* so we do not throw an internationalizable message.
*/
if (result === null) {
throw new Error('Parse error at position ' + pos.toString() + ' for rule: ' + rule);
}
if (pos !== rule.length) {
debug('Warning: Rule not parsed completely. Parser stopped at ' + rule.substr(0, pos) + ' for rule: ' + rule);
}
return result;
}
return pluralRuleParser;
return MakePlural;
}());
/* jshint ignore:end */
/**
* pluralForm( value, cldr )
*
* @value [Number]
*
* @cldr [Cldr instance].
*
* Return the corresponding form (zero | one | two | few | many | other) of a
* value given locale @cldr.
*/
var pluralForm = function( value, cldr ) {
var form,
rules = cldr.supplemental( "plurals-type-cardinal/{language}" );
for ( form in rules ) {
if ( CLDRPluralRuleParser( rules[ form ], value ) ) {
return form.replace( /pluralRule-count-/, "" );
}
}
return null;
var validateParameterTypeNumber = function( value, name ) {
validateParameterType(
value,
name,
value === undefined || typeof value === "number",
"Number"
);
};

@@ -703,56 +220,32 @@

/**
* .formatPlural( value, data, formatValue )
* .plural( value )
*
* @value [Number]
*
* @messageData [JSON] eg. { one: "{0} second", other: "{0} seconds" }
*
* @formatValue [String|Number] It defaults to `value`. It's used to replace the
* {0} variable of plural messages.
*
* Return the appropriate message based on value's plural group: zero | one |
* two | few | many | other.
* Return the corresponding form (zero | one | two | few | many | other) of a
* value given locale.
*/
Globalize.formatPlural =
Globalize.prototype.formatPlural = function( value, messageData, formatValue ) {
var form;
// Note: validateParameterTypeNumber( value, "value" ) is deferred to this.plural().
Globalize.plural =
Globalize.prototype.plural = function( value ) {
validateParameterPresence( value, "value" );
validateParameterPresence( messageData, "messageData" );
validateParameterTypePlainObject( messageData, "messageData" );
validateParameterType(
formatValue,
"formatValue",
formatValue === undefined || typeof formatValue === "string" ||
typeof formatValue === "number",
"String or Number"
);
form = this.plural( value );
// formatValue defaults to value, but it accepts anything including empty strings.
formatValue = formatValue === undefined ? value : formatValue;
validateParameterKeyPresence( messageData, "messageData", form );
return formatMessage( messageData[ form ], [ formatValue ] );
validateParameterTypeNumber( value, "value" );
return this.pluralGenerator()( value );
};
/**
* .plural( value )
* .pluralGenerator()
*
* Return a plural function (of the form below).
*
* fn( value )
*
* @value [Number]
*
* Return the corresponding form (zero | one | two | few | many | other) of a
* value given locale.
* Return the corresponding form (zero | one | two | few | many | other) of a value given the
* default/instance locale.
*/
Globalize.plural =
Globalize.prototype.plural = function( value ) {
var cldr, form;
Globalize.pluralGenerator =
Globalize.prototype.pluralGenerator = function() {
var cldr, plural;
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
cldr = this.cldr;

@@ -763,10 +256,18 @@

cldr.on( "get", validateCldr );
form = pluralForm( value, cldr );
cldr.supplemental( "plurals-type-cardinal/{language}" );
cldr.off( "get", validateCldr );
validate( "E_INVALID_CLDR", "{description}", typeof form === "string", {
description: "Missing rules to deduce plural form of `" + value + "`"
});
// Set CLDR data
MakePlural.rules = {
cardinal: cldr.supplemental( "plurals-type-cardinal" )
};
return form;
plural = MakePlural( cldr.attributes.language, { "no_tests": true } );
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return plural( value );
};
};

@@ -773,0 +274,0 @@

/*!
* Globalize v1.0.0-alpha.10
* Globalize v1.0.0-alpha.11
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-10-22T17:24Z
* Date: 2014-12-03T12:09Z
*/

@@ -13,0 +13,0 @@

@@ -33,6 +33,8 @@ ## .formatNumber( value [, options] )

var ar = new Globalize( "ar" ),
es = new Globalize( "es" );
es = new Globalize( "es" ),
zh = new Globalize( "zh-u-nu-native" );
ar.formatNumber( 3.141592 ); // "3٫142"
ar.formatNumber( 3.141592 ); // "٣٫١٤٢"
es.formatNumber( 3.141592 ); // "3,142"
zh.formatNumber( 3.141592 ); // "三.一四二"
```

@@ -39,0 +41,0 @@

@@ -64,6 +64,8 @@ ## .numberFormatter( [options] )

var arFormatter = Globalize( "ar" ).numberFormatter(),
esFormatter = Globalize( "es" ).numberFormatter();
esFormatter = Globalize( "es" ).numberFormatter(),
zhFormatter = Globalize( "zh-u-nu-native" ).numberFormatter();
arFormatter( 3.141592 ); // "3٫142"
arFormatter( 3.141592 ); // "٣٫١٤٢"
esFormatter( 3.141592 ); // "3,142"
zhFormatter( 3.141592 ); // "三.一四二"
```

@@ -70,0 +72,0 @@

@@ -15,4 +15,4 @@ ## .plural( value )

See also its sibling method [`.formatPlural( value, messageData [, formatValue ])`
](./format-plural.md).
*Important*: Use [`.pluralGenerator()`](./plural-generator.md) instead when
using this function two or more times, for improved performance.

@@ -49,3 +49,3 @@ ### Parameters

zh.formatPlural( 1 ); // "other"
zh.plural( 1 ); // "other"
```

@@ -77,3 +77,3 @@ module.exports = function( grunt ) {

dist: {
src: [ "dist/globalize*.js", "dist/globalize/*.js", "!dist/**/*.min.*js" ],
src: [ "dist/globalize*.js", "dist/globalize/*.js" ],
options: {

@@ -88,3 +88,3 @@ jshintrc: "src/.dist-jshintrc"

test: [ "test/*.js", "test/functional/**/*.js", "test/unit/**/*.js" ],
dist: [ "dist/globalize*.js", "dist/globalize/*.js", "!dist/**/*.min.*js" ]
dist: [ "dist/globalize*.js", "dist/globalize/*.js" ]
},

@@ -111,4 +111,3 @@ qunit: {

cldr: "../external/cldrjs/dist/cldr",
CLDRPluralRuleParser: "../external/CLDRPluralRuleParser/src/" +
"CLDRPluralRuleParser"
"make-plural": "../external/make-plural/make-plural"
},

@@ -136,2 +135,30 @@ skipSemiColonInsertion: true,

.replace( /}\)\);\s+$/, "}());" );
// MakePlural
} else if ( (/make-plural/).test( id ) ) {
return contents
// Replace its wrapper into var assignment.
.replace( /\(function \(global\) {/, [
"var MakePlural;",
"/* jshint ignore:start */",
"MakePlural = (function() {"
].join( "\n" ) )
.replace( /if \(\(typeof module !== 'undefined'[\s\S]*/, [
"return MakePlural;",
"}());",
"/* jshint ignore:end */"
].join( "\n" ) )
// Remove if (!MakePlural.rules...) {...}
.replace( /if \(!MakePlural.rules \|\|[\s\S]*?}/, "" )
// Remove function xhr_require(src, url) {...}
.replace( /function xhr_require\(src, [\s\S]*?}/, "" )
// Remove function test(...) {...}
.replace( /function test\(lc, fn, [\s\S]*?return ok;\n}/, "" )
// Remove MakePlural.load = function(.*) {...return MakePlural;.*};
.replace( /MakePlural.load = function\([\s\S]*?return MakePlural;\n};/, "" );
}

@@ -201,3 +228,3 @@

include: [ "plural" ],
exclude: [ "cldr", "cldr/event", "./core" ],
exclude: [ "cldr", "cldr/event", "cldr/supplemental", "./core" ],
create: true,

@@ -268,7 +295,7 @@ override: {

files: {
"dist/globalize.min.js": [ "dist/globalize.js" ],
"dist/globalize/date.min.js": [ "dist/globalize/date.js" ],
"dist/globalize/number.min.js": [ "dist/globalize/number.js" ],
"dist/globalize/plural.min.js": [ "dist/globalize/plural.js" ],
"dist/globalize/message.min.js": [ "dist/globalize/message.js" ]
"tmp/globalize.min.js": [ "dist/globalize.js" ],
"tmp/globalize/date.min.js": [ "dist/globalize/date.js" ],
"tmp/globalize/number.min.js": [ "dist/globalize/number.js" ],
"tmp/globalize/plural.min.js": [ "dist/globalize/plural.js" ],
"tmp/globalize/message.min.js": [ "dist/globalize/message.js" ]
}

@@ -281,4 +308,4 @@ }

files: [
"dist/globalize.min.js",
"dist/globalize/*min.js"
"tmp/globalize.min.js",
"tmp/globalize/*min.js"
],

@@ -285,0 +312,0 @@ options: {

{
"name": "globalize",
"version": "1.0.0-alpha.10",
"version": "1.0.0-alpha.11",
"description": "A JavaScript library for internationalization and localization that leverage the official Unicode CLDR JSON data.",

@@ -67,3 +67,3 @@ "keywords": [

"dependencies": {
"cldrjs": "0.3.9"
"cldrjs": "0.3.10"
},

@@ -74,3 +74,3 @@ "peerDependencies": {

"devDependencies": {
"cldr-data-downloader": "0.0.x",
"cldr-data-downloader": "0.1.x",
"grunt": "0.4.5",

@@ -77,0 +77,0 @@ "grunt-check-dependencies": "0.6.0",

@@ -103,3 +103,3 @@ # Globalize

| globalize/number.js | +2.6KB | [Number module](#number_module) provides number formatting and parsing |
| globalize/plural.js | +2.0KB | [Plural module](#plural_module) provides pluralization support |
| globalize/plural.js | +1.7KB | [Plural module](#plural_module) provides pluralization support |
<!--- By updating this table, also update its clone in #usage -->

@@ -172,3 +172,3 @@

| Date module | cldr/main/`locale`/ca-gregorian.json<br>cldr/main/`locale`/timeZoneNames.json<br>cldr/supplemental/timeData.json<br>cldr/supplemental/weekData.json |
| Number module | cldr/main/`locale`/numbers.json |
| Number module | cldr/main/`locale`/numbers.json<br>cldr/supplemental/numberingSystems.json |
| Plural module | cldr/supplemental/plurals.json |

@@ -319,10 +319,10 @@

- **`Globalize.formatPlural( value, messageData [, formatValue ] )`**
- **`.pluralGenerator()`**
Return the appropriate message based on value's plural group: `zero`, `one`,
`two`, `few`, `many`, or `other`.
Return a function that returns the value's corresponding plural group: `zero`, `one`, `two`, `few`,
`many`, or `other`.
[Read more...](doc/api/plural/format-plural.md)
[Read more...](doc/api/plural/plural-generator.md)
- **`Globalize.plural( value )`**
- **`.plural( value )`**

@@ -372,8 +372,2 @@ Return the value's corresponding plural group: `zero`, `one`, `two`, `few`, `many`, or `other`.

- **`E_PAR_MISSING_KEY`**
Thrown when a parameter misses a required key.
[Read more...](doc/error/e-par-missing-key.md)
- **`E_PAR_OUT_OF_RANGE`**

@@ -380,0 +374,0 @@

@@ -1,2 +0,2 @@

/*!
/**
* Globalize v@VERSION

@@ -12,2 +12,6 @@ *

*/
/*!
* Globalize v@VERSION @DATE Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -14,0 +18,0 @@

@@ -1,2 +0,2 @@

/*!
/**
* Globalize v@VERSION

@@ -12,2 +12,6 @@ *

*/
/*!
* Globalize v@VERSION @DATE Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -39,2 +43,3 @@

isPlainObject = Globalize._isPlainObject,
regexpEscape = Globalize._regexpEscape,
validateCldr = Globalize._validateCldr,

@@ -41,0 +46,0 @@ validateDefaultLocale = Globalize._validateDefaultLocale,

@@ -1,2 +0,2 @@

/*!
/**
* Globalize v@VERSION

@@ -12,2 +12,6 @@ *

*/
/*!
* Globalize v@VERSION @DATE Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -14,0 +18,0 @@

@@ -1,2 +0,2 @@

/*!
/**
* Globalize v@VERSION

@@ -12,2 +12,6 @@ *

*/
/*!
* Globalize v@VERSION @DATE Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -22,3 +26,4 @@

"../globalize",
"cldr/event"
"cldr/event",
"cldr/supplemental"
], factory );

@@ -37,2 +42,3 @@ } else if ( typeof exports === "object" ) {

var createError = Globalize._createError,
regexpEscape = Globalize._regexpEscape,
validateCldr = Globalize._validateCldr,

@@ -39,0 +45,0 @@ validateDefaultLocale = Globalize._validateDefaultLocale,

@@ -1,2 +0,2 @@

/*!
/**
* Globalize v@VERSION

@@ -12,2 +12,6 @@ *

*/
/*!
* Globalize v@VERSION @DATE Released under the MIT license
* http://git.io/TrdQbw
*/
(function( root, factory ) {

@@ -22,3 +26,4 @@

"../globalize",
"cldr/event"
"cldr/event",
"cldr/supplemental"
], factory );

@@ -36,8 +41,5 @@ } else if ( typeof exports === "object" ) {

var formatMessage = Globalize._formatMessage,
validate = Globalize._validate,
validateCldr = Globalize._validateCldr,
var validateCldr = Globalize._validateCldr,
validateDefaultLocale = Globalize._validateDefaultLocale,
validateParameterPresence = Globalize._validateParameterPresence,
validateParameterType = Globalize._validateParameterType,
validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject;
validateParameterType = Globalize._validateParameterType;

@@ -16,2 +16,3 @@ define([

"./util/is-plain-object",
"./util/regexp/escape",
"cldr/event"

@@ -21,3 +22,3 @@ ], function( Cldr, createError, formatMessage, validate, validateCldr, validateDefaultLocale,

validateParameterTypeLocale, validateParameterTypePlainObject, alwaysArray, alwaysCldr,
isPlainObject ) {
isPlainObject, regexpEscape ) {

@@ -92,3 +93,3 @@ function validateLikelySubtags( cldr ) {

Globalize._isPlainObject = isPlainObject;
Globalize._validate = validate;
Globalize._regexpEscape = regexpEscape;
Globalize._validateCldr = validateCldr;

@@ -100,2 +101,3 @@ Globalize._validateDefaultLocale = validateDefaultLocale;

Globalize._validateParameterType = validateParameterType;
Globalize._validate = validate;

@@ -102,0 +104,0 @@ return Globalize;

@@ -247,3 +247,11 @@ define([

// Anything else is considered a literal, including [ ,:/.'@#], chinese, japonese, and
// ' literals.
case "'":
current = current.replace( /''/, "'" );
if ( length > 2 ) {
current = current.slice( 1, -1 );
}
return current;
// Anything else is considered a literal, including [ ,:/.@#], chinese, japonese, and
// arabic characters.

@@ -250,0 +258,0 @@ default:

define(function() {
return (/([a-z])\1*|'[^']+'|''|./ig);
return (/([a-z])\1*|'([^']|'')+'|''|./ig);
});
define([
"./pattern-re"
], function( datePatternRe ) {
"./pattern-re",
"../util/regexp/escape"
], function( datePatternRe, regexpEscape ) {

@@ -315,7 +316,7 @@ /**

token.type = "literal";
if ( current.charAt( 1 ) === "'" ) {
tokenRe = /'/;
} else {
tokenRe = /'[^']+'/;
current = current.replace( /''/, "'" );
if ( length > 2 ) {
current = current.slice( 1, -1 );
}
tokenRe = new RegExp( regexpEscape( current ) );
break;

@@ -322,0 +323,0 @@

define([
"./numbering-system-digits-map",
"./pattern-properties",

@@ -7,3 +8,3 @@ "./symbol",

"../util/number/round"
], function( numberPatternProperties, numberSymbol, numberSymbolMap,
], function( numberNumberingSystemDigitsMap, numberPatternProperties, numberSymbol, numberSymbolMap,
numberSymbolName, numberRound ) {

@@ -56,3 +57,4 @@

numberSymbol( "nan", cldr ),
numberSymbolMap( cldr )
numberSymbolMap( cldr ),
numberNumberingSystemDigitsMap( cldr )
]);

@@ -92,2 +94,3 @@

// 18: @symbolMap [Object] A bunch of other symbols.
// 19: @nuDigitsMap [Array] Digits map if numbering system is different than `latn`.
return properties;

@@ -94,0 +97,0 @@ };

@@ -20,3 +20,3 @@ define([

var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, padding, prefix,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix,
primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,

@@ -38,2 +38,3 @@ symbolMap;

symbolMap = properties[ 18 ];
nuDigitsMap = properties[ 19 ];

@@ -96,3 +97,3 @@ // NaN

// Padding
// Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g
// TODO implement here

@@ -102,8 +103,26 @@

// Symbols
return ret.replace( /'[^']+'|[.,\-+E%\u2030]/g, function( symbol ) {
if ( symbol.charAt( 0 ) === "'" ) {
return symbol;
return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) {
// Literals
if ( literal ) {
literal = literal.replace( /''/, "'" );
if ( literal.length > 2 ) {
literal = literal.slice( 1, -1 );
}
return literal;
}
return symbolMap[ symbol ];
// Symbols
character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) {
return symbolMap[ symbol ];
});
// Numbering system
if ( nuDigitsMap ) {
character = character.replace( /[0-9]/, function( digit ) {
return nuDigitsMap[ +digit ];
});
}
return character;
});

@@ -110,0 +129,0 @@ };

@@ -6,5 +6,25 @@ define(function() {

*
* TODO support ( native | traditional | finance ).
* - http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems
* - http://cldr.unicode.org/index/bcp47-extension
* - http://www.unicode.org/reports/tr35/#u_Extension
*/
return function( cldr ) {
var nu = cldr.attributes[ "u-nu" ];
if ( nu ) {
if ( nu === "traditio" ) {
nu = "traditional";
}
if ( [ "native", "traditional", "finance" ].indexOf( nu ) !== -1 ) {
// Unicode locale extension `u-nu` is set using either (native, traditional or
// finance). So, lookup the respective locale's numberingSystem and return it.
return cldr.main([ "numbers/otherNumberingSystems", nu ]);
}
// Unicode locale extension `u-nu` is set with an explicit numberingSystem. Return it.
return nu;
}
// Return the default numberingSystem.
return cldr.main( "numbers/defaultNumberingSystem" );

@@ -11,0 +31,0 @@ };

define([
"./numbering-system-digits-map",
"./pattern-properties",

@@ -7,4 +8,4 @@ "./symbol",

"../util/object/flat-extend"
], function( numberPatternProperties, numberSymbol, numberSymbolInvertedMap, numberSymbolName,
objectFlatExtend ) {
], function( numberNumberingSystemDigitsMap, numberPatternProperties, numberSymbol,
numberSymbolInvertedMap, numberSymbolName, objectFlatExtend ) {

@@ -21,3 +22,4 @@ /**

return function( pattern, cldr ) {
var negativePattern, negativeProperties;
var invertedNuDigitsMap, invertedNuDigitsMapSanityCheck, negativePattern, negativeProperties,
nuDigitsMap = numberNumberingSystemDigitsMap( cldr );

@@ -27,2 +29,16 @@ pattern = pattern.split( ";" );

negativeProperties = numberPatternProperties( negativePattern );
if ( nuDigitsMap ) {
invertedNuDigitsMap = nuDigitsMap.split( "" ).reduce(function( object, localizedDigit, i ) {
object[ localizedDigit ] = String( i );
return object;
}, {} );
invertedNuDigitsMapSanityCheck = "0123456789".split( "" ).reduce(function( object, digit ) {
object[ digit ] = "invalid";
return object;
}, {} );
invertedNuDigitsMap = objectFlatExtend(
invertedNuDigitsMapSanityCheck,
invertedNuDigitsMap
);
}

@@ -37,2 +53,4 @@ // 0: @infinitySymbol [String] Infinity symbol.

// 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out.
// 4: @invertedNuDigitsMap [Object] Inverted digits map if numbering system is different than
// `latn` augmented with sanity check (similar to invertedSymbolMap).
return [

@@ -42,3 +60,4 @@ numberSymbol( "infinity", cldr ),

negativeProperties[ 0 ],
negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" )
negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" ),
invertedNuDigitsMap
];

@@ -45,0 +64,0 @@ };

@@ -18,4 +18,4 @@ define([

return function( value, properties ) {
var aux, infinitySymbol, invertedSymbolMap, localizedSymbolsRe, negativePrefix, negativeSuffix,
number, prefix, suffix;
var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe,
localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix;

@@ -26,2 +26,3 @@ infinitySymbol = properties[ 0 ];

negativeSuffix = properties[ 3 ];
invertedNuDigitsMap = properties[ 4 ];

@@ -38,2 +39,3 @@ // Infinite number.

// TODO: Create it during setup, i.e., make it a property.
localizedSymbolsRe = new RegExp(

@@ -51,2 +53,17 @@ Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {

// Reverse localized numbering system.
if ( invertedNuDigitsMap ) {
// TODO: Create it during setup, i.e., make it a property.
localizedDigitRe = new RegExp(
Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) {
return regexpEscape( localizedDigit );
}).join( "|" ),
"g"
);
value = value.replace( localizedDigitRe, function( localizedDigit ) {
return invertedNuDigitsMap[ localizedDigit ];
});
}
// Is it a valid number?

@@ -53,0 +70,0 @@ value = value.match( numberNumberRe );

define([
"cldr",
"make-plural",
"./core",
"./common/validate",
"./common/validate/cldr",
"./common/validate/default-locale",
"./common/validate/parameter-key-presence",
"./common/validate/parameter-presence",
"./common/validate/parameter-type",
"./common/validate/parameter-type/number",
"./common/validate/parameter-type/plain-object",
"./plural/form",
"./common/format-message"
], function( Globalize, validate, validateCldr, validateDefaultLocale, validateParameterKeyPresence,
validateParameterPresence, validateParameterType, validateParameterTypeNumber,
validateParameterTypePlainObject, pluralForm, formatMessage ) {
"cldr/supplemental"
], function( Cldr, MakePlural, Globalize, validateCldr, validateDefaultLocale,
validateParameterPresence, validateParameterType, validateParameterTypeNumber ) {
/**
* .formatPlural( value, data, formatValue )
* .plural( value )
*
* @value [Number]
*
* @messageData [JSON] eg. { one: "{0} second", other: "{0} seconds" }
*
* @formatValue [String|Number] It defaults to `value`. It's used to replace the
* {0} variable of plural messages.
*
* Return the appropriate message based on value's plural group: zero | one |
* two | few | many | other.
* Return the corresponding form (zero | one | two | few | many | other) of a
* value given locale.
*/
Globalize.formatPlural =
Globalize.prototype.formatPlural = function( value, messageData, formatValue ) {
var form;
// Note: validateParameterTypeNumber( value, "value" ) is deferred to this.plural().
Globalize.plural =
Globalize.prototype.plural = function( value ) {
validateParameterPresence( value, "value" );
validateParameterPresence( messageData, "messageData" );
validateParameterTypePlainObject( messageData, "messageData" );
validateParameterType(
formatValue,
"formatValue",
formatValue === undefined || typeof formatValue === "string" ||
typeof formatValue === "number",
"String or Number"
);
form = this.plural( value );
// formatValue defaults to value, but it accepts anything including empty strings.
formatValue = formatValue === undefined ? value : formatValue;
validateParameterKeyPresence( messageData, "messageData", form );
return formatMessage( messageData[ form ], [ formatValue ] );
validateParameterTypeNumber( value, "value" );
return this.pluralGenerator()( value );
};
/**
* .plural( value )
* .pluralGenerator()
*
* Return a plural function (of the form below).
*
* fn( value )
*
* @value [Number]
*
* Return the corresponding form (zero | one | two | few | many | other) of a
* value given locale.
* Return the corresponding form (zero | one | two | few | many | other) of a value given the
* default/instance locale.
*/
Globalize.plural =
Globalize.prototype.plural = function( value ) {
var cldr, form;
Globalize.pluralGenerator =
Globalize.prototype.pluralGenerator = function() {
var cldr, plural;
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
cldr = this.cldr;

@@ -77,10 +50,18 @@

cldr.on( "get", validateCldr );
form = pluralForm( value, cldr );
cldr.supplemental( "plurals-type-cardinal/{language}" );
cldr.off( "get", validateCldr );
validate( "E_INVALID_CLDR", "{description}", typeof form === "string", {
description: "Missing rules to deduce plural form of `" + value + "`"
});
// Set CLDR data
MakePlural.rules = {
cardinal: cldr.supplemental( "plurals-type-cardinal" )
};
return form;
plural = MakePlural( cldr.attributes.language, { "no_tests": true } );
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return plural( value );
};
};

@@ -87,0 +68,0 @@

@@ -33,3 +33,2 @@ require.config({

// plural
"./functional/plural/format-plural",
"./functional/plural/plural"

@@ -36,0 +35,0 @@

@@ -74,3 +74,3 @@ define([

assert.equal( Globalize( "pt" ).formatDate( date, { skeleton: "Ehms" } ), "qua, 5:35:07 PM" );
assert.equal( Globalize( "pt" ).formatDate( date, { skeleton: "GyMMMEd" } ), "qua, 15 'de' set 'de' 2010 d.C." );
assert.equal( Globalize( "pt" ).formatDate( date, { skeleton: "GyMMMEd" } ), "qua, 15 de set de 2010 d.C." );
});

@@ -77,0 +77,0 @@

@@ -6,6 +6,9 @@ define([

"json!cldr-data/main/es/numbers.json",
"json!cldr-data/main/zh/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json",
"json!cldr-data/supplemental/numberingSystems.json",
"../../util",
"globalize/number"
], function( Globalize, arNumbers, enNumbers, esNumbers, likelySubtags, util ) {
], function( Globalize, arNumbers, enNumbers, esNumbers, zhNumbers, likelySubtags, numberingSystems,
util ) {

@@ -18,3 +21,5 @@ var pi = 3.14159265359;

enNumbers,
esNumbers
esNumbers,
zhNumbers,
numberingSystems
);

@@ -60,3 +65,4 @@ }

assert.equal( Globalize( "es" ).formatNumber( pi ), "3,142" );
assert.equal( Globalize( "ar" ).formatNumber( pi ), "3٫142" );
assert.equal( Globalize( "ar" ).formatNumber( pi ), "٣٫١٤٢" );
assert.equal( Globalize( "zh-u-nu-native" ).formatNumber( pi ), "三.一四二" );
assert.equal( Globalize.formatNumber( 99999999.99 ), "99,999,999.99" );

@@ -105,5 +111,5 @@

assert.equal( Globalize.formatNumber( pi, { style: "percent" } ), "314%" );
assert.equal( Globalize( "ar" ).formatNumber( pi, { style: "percent" } ), "314٪" );
assert.equal( Globalize( "ar" ).formatNumber( pi, { style: "percent" } ), "٣١٤٪" );
});
});

@@ -7,8 +7,11 @@ define([

"json!cldr-data/main/sv/numbers.json",
"json!cldr-data/main/zh/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json",
"json!cldr-data/supplemental/numberingSystems.json",
"../../util",
"globalize/number"
], function( Globalize, arNumbers, enNumbers, esNumbers, svNumbers, likelySubtags, util ) {
], function( Globalize, arNumbers, enNumbers, esNumbers, svNumbers, zhNumbers, likelySubtags,
numberingSystems, util ) {
var ar, es, sv;
var ar, es, sv, zh;

@@ -20,3 +23,5 @@ function extraSetup() {

esNumbers,
svNumbers
svNumbers,
zhNumbers,
numberingSystems
);

@@ -31,2 +36,3 @@ }

sv = new Globalize( "sv" );
zh = new Globalize( "zh-u-nu-native" );
Globalize.locale( "en" );

@@ -90,3 +96,4 @@ },

assert.equal( es.parseNumber( "3,14" ), 3.14 );
assert.equal( ar.parseNumber( "3٫14" ), 3.14 );
assert.equal( ar.parseNumber( "٣٫١٤" ), 3.14 );
assert.equal( zh.parseNumber( "三.一四" ), 3.14 );
assert.equal( Globalize.parseNumber( "3.00" ), 3 );

@@ -117,3 +124,3 @@ assert.equal( Globalize.parseNumber( "12735.0" ), 12735 );

assert.equal( Globalize.parseNumber( "0.5%" ), 0.005 );
assert.equal( ar.parseNumber( "50٪" ), 0.5 );
assert.equal( ar.parseNumber( "٥٠٪" ), 0.5 );
assert.equal( Globalize.parseNumber( "-10%" ), -0.1 );

@@ -120,0 +127,0 @@ });

@@ -11,2 +11,16 @@ define([

Globalize.load( plurals );
// Temporary fix due to CLDR v26 regression about pt_BR plural
// http://unicode.org/cldr/trac/ticket/7178
Globalize.load({
"supplemental": {
"plurals-type-cardinal": {
pt: {
"pluralRule-count-one": "i = 0,1",
"pluralRule-count-other": ""
}
}
}
});
}

@@ -38,17 +52,2 @@

});
// Assert E_INVALID_CLDR "Missing rules to deduce plural form of `1`".
Globalize.load({
supplemental: {
"plurals-type-cardinal": { en: {} }
}
});
assert.throws(function() {
Globalize.plural( 1 );
}, function E_INVALID_CLDR( error ) {
return error.code === "E_INVALID_CLDR" &&
"description" in error &&
error.description === "Missing rules to deduce plural form of `1`";
}, "Expected \"E_MISSING_CLDR\" to be thrown" );
});

@@ -59,6 +58,64 @@

assert.equal( Globalize.plural( 0 ), "other" );
assert.equal( Globalize.plural( 0.14 ), "other" );
assert.equal( Globalize( "en" ).plural( 0 ), "other" );
assert.equal( Globalize( "en" ).plural( 1 ), "one" );
assert.equal( Globalize( "en" ).plural( 2 ), "other" );
assert.equal( Globalize( "en" ).plural( 1412 ), "other" );
assert.equal( Globalize( "en" ).plural( 0.14 ), "other" );
assert.equal( Globalize( "en" ).plural( 3.14 ), "other" );
assert.equal( Globalize( "ar" ).plural( 0 ), "zero" );
});
assert.equal( Globalize( "ar" ).plural( 1 ), "one" );
assert.equal( Globalize( "ar" ).plural( 2 ), "two" );
assert.equal( Globalize( "ar" ).plural( 3 ), "few" );
assert.equal( Globalize( "ar" ).plural( 6 ), "few" );
assert.equal( Globalize( "ar" ).plural( 9 ), "few" );
assert.equal( Globalize( "ar" ).plural( 10 ), "few" );
assert.equal( Globalize( "ar" ).plural( 11 ), "many" );
assert.equal( Globalize( "ar" ).plural( 15 ), "many" );
assert.equal( Globalize( "ar" ).plural( 21 ), "many" );
assert.equal( Globalize( "ar" ).plural( 70 ), "many" );
assert.equal( Globalize( "ar" ).plural( 99 ), "many" );
assert.equal( Globalize( "ar" ).plural( 100 ), "other" );
assert.equal( Globalize( "ar" ).plural( 101 ), "other" );
assert.equal( Globalize( "ar" ).plural( 102 ), "other" );
assert.equal( Globalize( "ar" ).plural( 103 ), "few" );
assert.equal( Globalize( "ar" ).plural( 111 ), "many" );
assert.equal( Globalize( "ar" ).plural( 199 ), "many" );
assert.equal( Globalize( "ar" ).plural( 3.14 ), "other" );
assert.equal( Globalize( "ja" ).plural( 0 ), "other" );
assert.equal( Globalize( "ja" ).plural( 1 ), "other" );
assert.equal( Globalize( "ja" ).plural( 2 ), "other" );
assert.equal( Globalize( "ja" ).plural( 3.14 ), "other" );
assert.equal( Globalize( "pt" ).plural( 0 ), "one" );
assert.equal( Globalize( "pt" ).plural( 1 ), "one" );
assert.equal( Globalize( "pt" ).plural( 2 ), "other" );
assert.equal( Globalize( "pt" ).plural( 0.1 ), "one" );
assert.equal( Globalize( "pt" ).plural( 3.14 ), "other" );
assert.equal( Globalize( "ru" ).plural( 0 ), "many" );
assert.equal( Globalize( "ru" ).plural( 1 ), "one" );
assert.equal( Globalize( "ru" ).plural( 2 ), "few" );
assert.equal( Globalize( "ru" ).plural( 3 ), "few" );
assert.equal( Globalize( "ru" ).plural( 4 ), "few" );
assert.equal( Globalize( "ru" ).plural( 5 ), "many" );
assert.equal( Globalize( "ru" ).plural( 6 ), "many" );
assert.equal( Globalize( "ru" ).plural( 9 ), "many" );
assert.equal( Globalize( "ru" ).plural( 11 ), "many" );
assert.equal( Globalize( "ru" ).plural( 12 ), "many" );
assert.equal( Globalize( "ru" ).plural( 19 ), "many" );
assert.equal( Globalize( "ru" ).plural( 21 ), "one" );
assert.equal( Globalize( "ru" ).plural( 22 ), "few" );
assert.equal( Globalize( "ru" ).plural( 29 ), "many" );
assert.equal( Globalize( "ru" ).plural( 3.14 ), "other" );
assert.equal( Globalize( "zh" ).plural( 0 ), "other" );
assert.equal( Globalize( "zh" ).plural( 1 ), "other" );
assert.equal( Globalize( "zh" ).plural( 2 ), "other" );
assert.equal( Globalize( "zh" ).plural( 3.14 ), "other" );
});
});

@@ -5,3 +5,2 @@ require.config({

"cldr-data": "../external/cldr-data",
CLDRPluralRuleParser: "../external/CLDRPluralRuleParser/src/CLDRPluralRuleParser",
json: "../external/requirejs-plugins/src/json",

@@ -42,9 +41,6 @@ src: "../src",

"./unit/number/parse-properties",
"./unit/number/parse",
"./unit/number/parse"
/* plural */
"./unit/plural/form"
], function() {
QUnit.start();
});

@@ -551,2 +551,12 @@ define([

/**
* Literal
*/
QUnit.test( "should format literal (')", function( assert ) {
assert.equal( format( date1, properties( "yyyy.MM.dd G 'at' HH:mm:ss", cldr ) ),
"1982.01.02 AD at 09:05:59" );
assert.equal( format( date1, properties( "hh 'o''clock' a", cldr ) ), "09 o'clock AM" );
});
});

@@ -394,3 +394,3 @@ define([

QUnit.test( "should format timezone (z)", function( assert ) {
QUnit.test( "should parse timezone (z)", function( assert ) {
[ "z", "zz", "zzz", "zzzz" ].forEach(function( z ) {

@@ -411,3 +411,3 @@ assertParseTimezone( assert, "GMT", z, cldr, 0 );

QUnit.test( "should format timezone (Z)", function( assert ) {
QUnit.test( "should parse timezone (Z)", function( assert ) {
assertParseTimezone( assert, "+0000", "Z", cldr, 0 );

@@ -432,3 +432,3 @@ assertParseTimezone( assert, "+0000", "ZZ", cldr, 0 );

QUnit.test( "should format timezone (O)", function( assert ) {
QUnit.test( "should parse timezone (O)", function( assert ) {
assertParseTimezone( assert, "GMT", "O", cldr, 0 );

@@ -444,3 +444,3 @@ assertParseTimezone( assert, "GMT", "OOOO", cldr, 0 );

QUnit.test( "should format timezone (X)", function( assert ) {
QUnit.test( "should parse timezone (X)", function( assert ) {
assertParseTimezone( assert, "Z", "X", cldr, 0 );

@@ -470,3 +470,3 @@ assertParseTimezone( assert, "Z", "XX", cldr, 0 );

QUnit.test( "should format timezone (x)", function( assert ) {
QUnit.test( "should parse timezone (x)", function( assert ) {
assertParseTimezone( assert, "+00", "x", cldr, 0 );

@@ -496,2 +496,9 @@ assertParseTimezone( assert, "+0000", "xx", cldr, 0 );

QUnit.test( "should parse literal (')", function( assert ) {
var date = new Date();
date.setHours( 9 );
date = startOf( date, "hour" );
assertParse( assert, "09 o'clock AM", "hh 'o''clock' a", cldr, date );
});
});

@@ -8,9 +8,11 @@ define([

"json!cldr-data/main/es/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json"
], function( Cldr, format, properties, arNumbers, enNumbers, esNumbers,
likelySubtags ) {
"json!cldr-data/main/zh/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json",
"json!cldr-data/supplemental/numberingSystems.json"
], function( Cldr, format, properties, arNumbers, enNumbers, esNumbers, zhNumbers, likelySubtags,
numberingSystems ) {
// 1: Earth average diameter according to:
// http://www.wolframalpha.com/input/?i=earth+diameter
var ar, en, es,
var ar, en, es, zh,
deci = 0.1,

@@ -24,3 +26,5 @@ earthDiameter = 12735, /* 1 */

esNumbers,
likelySubtags
zhNumbers,
likelySubtags,
numberingSystems
);

@@ -31,2 +35,3 @@

es = new Cldr( "es" );
zh = new Cldr( "zh-u-nu-native" );

@@ -86,3 +91,4 @@ QUnit.module( "Number Format" );

assert.equal( format( pi, properties( "0.##", es ) ), "3,14" );
assert.equal( format( pi, properties( "0.##", ar ) ), "3٫14" );
assert.equal( format( pi, properties( "0.##", ar ) ), "٣٫١٤" );
assert.equal( format( pi, properties( "0.##", zh ) ), "三.一四" );
});

@@ -223,3 +229,3 @@

QUnit.test( "should localize percent symbol (%)", function( assert ) {
assert.equal( format( 0.5, properties( "#0%", ar ) ), "50٪" );
assert.equal( format( 0.5, properties( "#0%", ar ) ), "٥٠٪" );
});

@@ -251,3 +257,3 @@

QUnit.test( "should localize per mille symbol (\u2030)", function( assert ) {
assert.equal( format( 0.5, properties( "#0\u2030", ar ) ), "500؉" );
assert.equal( format( 0.5, properties( "#0\u2030", ar ) ), "٥٠٠؉" );
});

@@ -278,2 +284,10 @@

/**
* Literal
*/
QUnit.test( "should format literal (')", function( assert ) {
assert.equal( format( 69900, properties( "'$'#,##0", en ) ), "$69,900" );
});
});

@@ -10,7 +10,9 @@ define([

"json!cldr-data/main/sv/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json"
], function( Cldr, parse, properties, arNumbers, enNumbers, esNumbers, ruNumbers,
svNumbers, likelySubtags ) {
"json!cldr-data/main/zh/numbers.json",
"json!cldr-data/supplemental/likelySubtags.json",
"json!cldr-data/supplemental/numberingSystems.json"
], function( Cldr, parse, properties, arNumbers, enNumbers, esNumbers, ruNumbers, svNumbers,
zhNumbers, likelySubtags, numberingSystems ) {
var ar, en, es, ru, sv;
var ar, en, es, ru, sv, zh;

@@ -23,3 +25,5 @@ Cldr.load(

svNumbers,
likelySubtags
zhNumbers,
likelySubtags,
numberingSystems
);

@@ -32,2 +36,3 @@

sv = new Cldr( "sv" );
zh = new Cldr( "zh-u-nu-native" );

@@ -66,3 +71,4 @@ QUnit.module( "Number Parse" );

assert.equal( parse( "3,14", properties( "0.##", es ) ), 3.14 );
assert.equal( parse( "3٫14", properties( "0.##", ar ) ), 3.14 );
assert.equal( parse( "٣٫١٤", properties( "0.##", ar ) ), 3.14 );
assert.equal( parse( "三.一四", properties( "0.##", zh ) ), 3.14 );
assert.equal( parse( "3.00", properties( "0.##", en ) ), 3 );

@@ -100,3 +106,3 @@ });

QUnit.test( "should localize percent symbol (%)", function( assert ) {
assert.equal( parse( "50٪", properties( "#0%", ar ) ), 0.5 );
assert.equal( parse( "٥٠٪", properties( "#0%", ar ) ), 0.5 );
});

@@ -125,3 +131,3 @@

assert.equal( parse( "500‰", properties( "#0‰", en ) ), 0.5 );
assert.equal( parse( "500؉", properties( "#0\u2030", ar ) ), 0.5 );
assert.equal( parse( "٥٠٠؉", properties( "#0\u2030", ar ) ), 0.5 );
});

@@ -161,3 +167,2 @@

});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc