1515 *
1616 * Based on an implementation from an Intl polyfill, but with some updates to handle negative numbers
1717 * @see <a href="https://github.com/eemeli/make-plural.js">make-plural.js</a>
18+ * @see <a href="https://www.unicode.org/cldr/charts/46/supplemental/language_plural_rules.html">plural rules from CLDR</a>
1819 * @author stamm
1920 * @since 1.1
2021 */
@@ -23,6 +24,7 @@ public class PluralRulesJsImpl {
2324 private final static String ONE = "function (n) {return n == 1 || n == -1 ? 'one' : 'other';}" ;
2425 private final static String ONE_OR_ZERO = "function (n) {return n == 0 || n == 1 || n == -1 ? 'one' : 'other';}" ;
2526 private final static String EXACT_ONE = "function (n) {return n == 1 && !String(n).split('.')[1] ? 'one' : 'other';}" ;
27+ private final static String EXACT_ONE_OR_NEG_ONE = "function (n) {return (n == 1 || n == -1) && !String(n).split('.')[1] ? 'one' : 'other';}" ;
2628
2729 public static String getSelectFunction (Locale locale ) {
2830 String override = getSelectFunctionOverride (locale );
@@ -75,7 +77,7 @@ public static String getSelectFunctionOverride(Locale locale) {
7577 //case "dz":return noDiff;
7678 //case "ee":return ONE;
7779 case GREEK :return ONE ;
78- case ENGLISH :return EXACT_ONE ;
80+ case ENGLISH :return EXACT_ONE_OR_NEG_ONE ;
7981 case ESPERANTO :return ONE ;
8082 case SPANISH :return ONE ;
8183 case ESTONIAN :return EXACT_ONE ;
@@ -93,7 +95,8 @@ public static String getSelectFunctionOverride(Locale locale) {
9395 case HEBREW_ISO :
9496 case HEBREW :return "function he(n) {\n " +
9597 "var s = String(n).split('.'), i = s[0], v0 = !s[1], t0 = Number(s[0]) == n, n10 = t0 && s[0].slice(-1);\n " +
96- "return n == 1 && v0 ? 'one' : i == 2 && v0 ? 'two' : v0 && (n < 0 || n > 10) && t0 && n10 == 0 ? 'many' : 'other';}" ;
98+ // "return n == 1 && v0 ? 'one' : i == 2 && v0 ? 'two' : v0 && (n < 0 || n > 10) && t0 && n10 == 0 ? 'many' : 'other';}";
99+ "return (i == 1 && v0) || (i == 0 && !v0) ? 'one' : i == 2 && v0 ? 'two' : 'other';}" ; // ICU > 70
97100
98101 case HUNGARIAN :return ONE ;
99102 case ARMENIAN :return "function hy(n) {return n >= 0 && n < 2 ? 'one' : 'other';}" ;
@@ -102,8 +105,9 @@ public static String getSelectFunctionOverride(Locale locale) {
102105 //case "id":return noDiff;
103106 //case "ig":return noDiff;
104107 case ICELANDIC :return "function is(n) {" +
105- "var s = String(n).split('.'),i = s[0],t0 = Number(s[0]) == n, i10 = i.slice(-1), i100 = i.slice(-2);" +
106- "return t0 && i10 == 1 && i100 != 11 || !t0 ? 'one' : 'other';}" ;
108+ "var s = String(n).split('.'),i = s[0],t = Number(s[1]),t0 = Number(s[0]) == n, i10 = i.slice(-1), i100 = i.slice(-2), t10 = t % 10, t100 = t % 100;" +
109+ // "return t0 && i10 == 1 && i100 != 11 || !t0 ? 'one' : 'other';}"; // ICU < 70
110+ "return t0 && i10 == 1 && (i100 != 11 || (!t10 != 1 && t100 != 11)) ? 'one' : 'other';}" ;
107111 //case "ja":return noDiff;
108112 //case "ji":return EXACT_ONE;
109113 //case "jv":return noDiff;
@@ -133,8 +137,8 @@ public static String getSelectFunctionOverride(Locale locale) {
133137 //case "ms":return noDiff;
134138 case MALTESE :return "function mt(n) {\n " +
135139 "var s = String(n).split('.'),t0 = Number(s[0]) == n,n100 = t0 && s[0].slice(-2);\n " +
136- "return n == 1 ? 'one' : (n == 0 || (n100 >= 2 && n100 <= 10)) ? 'few' : n100 >= 11 && n100 <= 19 ? 'many' : 'other';}" ;
137-
140+ // "return n == 1 ? 'one' : (n == 0 || (n100 >= 2 && n100 <= 10)) ? 'few' : n100 >= 11 && n100 <= 19 ? 'many' : 'other';}"; // ICU < 70
141+ "return n == 1 ? 'one' : n == 2 ? 'two' : (n == 0 || (n100 > 2 && n100 <= 10)) ? 'few' : n100 >= 11 && n100 <= 19 ? 'many' : 'other';}" ;
138142 //case "nb":return ONE;
139143 //case "nd":return ONE;
140144 //case "ne":return ONE;
@@ -151,10 +155,11 @@ public static String getSelectFunctionOverride(Locale locale) {
151155 }
152156 return "function pt(n) {return n >= 0 && n <= 2 && n != 2 ? 'one' : 'other';}" ;
153157 case ROMANSH :return ONE ;
158+ case "mo" :
154159 case ROMANIAN :return "function ro(n) {" +
155160 "var s = String(n).split('.'),v0 = !s[1],t0 = Number(s[0]) == n, n100 = t0 && s[0].slice(-2);" +
156- // "return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && (n100 >= 1 && n100 <= 19) ? 'few' : 'other';}"; // <ICU 64
157- "return n == 1 && v0 ? 'one' : !v0 || n == 0 || (n100 >= 2 && n100 <= 19) ? 'few' : 'other';}" ;
161+ "return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && (n100 >= 1 && n100 <= 19) ? 'few' : 'other';}" ;
162+ // "return n == 1 && v0 ? 'one' : !v0 || n == 0 || (n100 >= 2 && n100 <= 19) ? 'few' : 'other';}"; // ICU 64-70
158163 case RUSSIAN :
159164 case UKRAINIAN :
160165 return "function ru(n) {" +
0 commit comments