mediawiki.api: Adopt async-await and assert.rejects() in various tests
[mediawiki.git] / resources / lib / jquery.i18n / src / jquery.i18n.language.js
blobf905aa8f0d4371d271cdf0fbc328eff4a95a9c07
1 /* global pluralRuleParser */
2 ( function ( $ ) {
3         'use strict';
5         // jscs:disable
6         var language = {
7                 // CLDR plural rules generated using
8                 // libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html
9                 pluralRules: {
10                         ak: {
11                                 one: 'n = 0..1'
12                         },
13                         am: {
14                                 one: 'i = 0 or n = 1'
15                         },
16                         ar: {
17                                 zero: 'n = 0',
18                                 one: 'n = 1',
19                                 two: 'n = 2',
20                                 few: 'n % 100 = 3..10',
21                                 many: 'n % 100 = 11..99'
22                         },
23                         ars: {
24                                 zero: 'n = 0',
25                                 one: 'n = 1',
26                                 two: 'n = 2',
27                                 few: 'n % 100 = 3..10',
28                                 many: 'n % 100 = 11..99'
29                         },
30                         as: {
31                                 one: 'i = 0 or n = 1'
32                         },
33                         be: {
34                                 one: 'n % 10 = 1 and n % 100 != 11',
35                                 few: 'n % 10 = 2..4 and n % 100 != 12..14',
36                                 many: 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14'
37                         },
38                         bh: {
39                                 one: 'n = 0..1'
40                         },
41                         bn: {
42                                 one: 'i = 0 or n = 1'
43                         },
44                         br: {
45                                 one: 'n % 10 = 1 and n % 100 != 11,71,91',
46                                 two: 'n % 10 = 2 and n % 100 != 12,72,92',
47                                 few: 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99',
48                                 many: 'n != 0 and n % 1000000 = 0'
49                         },
50                         bs: {
51                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
52                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
53                         },
54                         cs: {
55                                 one: 'i = 1 and v = 0',
56                                 few: 'i = 2..4 and v = 0',
57                                 many: 'v != 0'
58                         },
59                         cy: {
60                                 zero: 'n = 0',
61                                 one: 'n = 1',
62                                 two: 'n = 2',
63                                 few: 'n = 3',
64                                 many: 'n = 6'
65                         },
66                         da: {
67                                 one: 'n = 1 or t != 0 and i = 0,1'
68                         },
69                         dsb: {
70                                 one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
71                                 two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
72                                 few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
73                         },
74                         fa: {
75                                 one: 'i = 0 or n = 1'
76                         },
77                         ff: {
78                                 one: 'i = 0,1'
79                         },
80                         fil: {
81                                 one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
82                         },
83                         fr: {
84                                 one: 'i = 0,1'
85                         },
86                         ga: {
87                                 one: 'n = 1',
88                                 two: 'n = 2',
89                                 few: 'n = 3..6',
90                                 many: 'n = 7..10'
91                         },
92                         gd: {
93                                 one: 'n = 1,11',
94                                 two: 'n = 2,12',
95                                 few: 'n = 3..10,13..19'
96                         },
97                         gu: {
98                                 one: 'i = 0 or n = 1'
99                         },
100                         guw: {
101                                 one: 'n = 0..1'
102                         },
103                         gv: {
104                                 one: 'v = 0 and i % 10 = 1',
105                                 two: 'v = 0 and i % 10 = 2',
106                                 few: 'v = 0 and i % 100 = 0,20,40,60,80',
107                                 many: 'v != 0'
108                         },
109                         he: {
110                                 one: 'i = 1 and v = 0',
111                                 two: 'i = 2 and v = 0',
112                                 many: 'v = 0 and n != 0..10 and n % 10 = 0'
113                         },
114                         hi: {
115                                 one: 'i = 0 or n = 1'
116                         },
117                         hr: {
118                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
119                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
120                         },
121                         hsb: {
122                                 one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
123                                 two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
124                                 few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
125                         },
126                         hy: {
127                                 one: 'i = 0,1'
128                         },
129                         is: {
130                                 one: 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0'
131                         },
132                         iu: {
133                                 one: 'n = 1',
134                                 two: 'n = 2'
135                         },
136                         iw: {
137                                 one: 'i = 1 and v = 0',
138                                 two: 'i = 2 and v = 0',
139                                 many: 'v = 0 and n != 0..10 and n % 10 = 0'
140                         },
141                         kab: {
142                                 one: 'i = 0,1'
143                         },
144                         kn: {
145                                 one: 'i = 0 or n = 1'
146                         },
147                         kw: {
148                                 one: 'n = 1',
149                                 two: 'n = 2'
150                         },
151                         lag: {
152                                 zero: 'n = 0',
153                                 one: 'i = 0,1 and n != 0'
154                         },
155                         ln: {
156                                 one: 'n = 0..1'
157                         },
158                         lt: {
159                                 one: 'n % 10 = 1 and n % 100 != 11..19',
160                                 few: 'n % 10 = 2..9 and n % 100 != 11..19',
161                                 many: 'f != 0'
162                         },
163                         lv: {
164                                 zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
165                                 one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
166                         },
167                         mg: {
168                                 one: 'n = 0..1'
169                         },
170                         mk: {
171                                 one: 'v = 0 and i % 10 = 1 or f % 10 = 1'
172                         },
173                         mo: {
174                                 one: 'i = 1 and v = 0',
175                                 few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
176                         },
177                         mr: {
178                                 one: 'i = 0 or n = 1'
179                         },
180                         mt: {
181                                 one: 'n = 1',
182                                 few: 'n = 0 or n % 100 = 2..10',
183                                 many: 'n % 100 = 11..19'
184                         },
185                         naq: {
186                                 one: 'n = 1',
187                                 two: 'n = 2'
188                         },
189                         nso: {
190                                 one: 'n = 0..1'
191                         },
192                         pa: {
193                                 one: 'n = 0..1'
194                         },
195                         pl: {
196                                 one: 'i = 1 and v = 0',
197                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
198                                 many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14'
199                         },
200                         prg: {
201                                 zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
202                                 one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
203                         },
204                         pt: {
205                                 one: 'i = 0..1'
206                         },
207                         ro: {
208                                 one: 'i = 1 and v = 0',
209                                 few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
210                         },
211                         ru: {
212                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
213                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
214                                 many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
215                         },
216                         se: {
217                                 one: 'n = 1',
218                                 two: 'n = 2'
219                         },
220                         sh: {
221                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
222                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
223                         },
224                         shi: {
225                                 one: 'i = 0 or n = 1',
226                                 few: 'n = 2..10'
227                         },
228                         si: {
229                                 one: 'n = 0,1 or i = 0 and f = 1'
230                         },
231                         sk: {
232                                 one: 'i = 1 and v = 0',
233                                 few: 'i = 2..4 and v = 0',
234                                 many: 'v != 0'
235                         },
236                         sl: {
237                                 one: 'v = 0 and i % 100 = 1',
238                                 two: 'v = 0 and i % 100 = 2',
239                                 few: 'v = 0 and i % 100 = 3..4 or v != 0'
240                         },
241                         sma: {
242                                 one: 'n = 1',
243                                 two: 'n = 2'
244                         },
245                         smi: {
246                                 one: 'n = 1',
247                                 two: 'n = 2'
248                         },
249                         smj: {
250                                 one: 'n = 1',
251                                 two: 'n = 2'
252                         },
253                         smn: {
254                                 one: 'n = 1',
255                                 two: 'n = 2'
256                         },
257                         sms: {
258                                 one: 'n = 1',
259                                 two: 'n = 2'
260                         },
261                         sr: {
262                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
263                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
264                         },
265                         ti: {
266                                 one: 'n = 0..1'
267                         },
268                         tl: {
269                                 one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
270                         },
271                         tzm: {
272                                 one: 'n = 0..1 or n = 11..99'
273                         },
274                         uk: {
275                                 one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
276                                 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
277                                 many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
278                         },
279                         wa: {
280                                 one: 'n = 0..1'
281                         },
282                         zu: {
283                                 one: 'i = 0 or n = 1'
284                         }
285                 },
286                 // jscs:enable
288                 /**
289                  * Plural form transformations, needed for some languages.
290                  *
291                  * @param {integer} count
292                  *            Non-localized quantifier
293                  * @param {Array} forms
294                  *            List of plural forms
295                  * @return {string} Correct form for quantifier in this language
296                  */
297                 convertPlural: function ( count, forms ) {
298                         var pluralRules,
299                                 pluralFormIndex,
300                                 index,
301                                 explicitPluralPattern = /\d+=/i,
302                                 formCount,
303                                 form;
305                         if ( !forms || forms.length === 0 ) {
306                                 return '';
307                         }
309                         // Handle for Explicit 0= & 1= values
310                         for ( index = 0; index < forms.length; index++ ) {
311                                 form = forms[ index ];
312                                 if ( explicitPluralPattern.test( form ) ) {
313                                         formCount = parseInt( form.slice( 0, form.indexOf( '=' ) ), 10 );
314                                         if ( formCount === count ) {
315                                                 return ( form.slice( form.indexOf( '=' ) + 1 ) );
316                                         }
317                                         forms[ index ] = undefined;
318                                 }
319                         }
321                         forms = $.map( forms, function ( form ) {
322                                 if ( form !== undefined ) {
323                                         return form;
324                                 }
325                         } );
327                         pluralRules = this.pluralRules[ $.i18n().locale ];
329                         if ( !pluralRules ) {
330                                 // default fallback.
331                                 return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
332                         }
334                         pluralFormIndex = this.getPluralForm( count, pluralRules );
335                         pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
337                         return forms[ pluralFormIndex ];
338                 },
340                 /**
341                  * For the number, get the plural for index
342                  *
343                  * @param {integer} number
344                  * @param {Object} pluralRules
345                  * @return {integer} plural form index
346                  */
347                 getPluralForm: function ( number, pluralRules ) {
348                         var i,
349                                 pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ],
350                                 pluralFormIndex = 0;
352                         for ( i = 0; i < pluralForms.length; i++ ) {
353                                 if ( pluralRules[ pluralForms[ i ] ] ) {
354                                         if ( pluralRuleParser( pluralRules[ pluralForms[ i ] ], number ) ) {
355                                                 return pluralFormIndex;
356                                         }
358                                         pluralFormIndex++;
359                                 }
360                         }
362                         return pluralFormIndex;
363                 },
365                 /**
366                  * Converts a number using digitTransformTable.
367                  *
368                  * @param {number} num Value to be converted
369                  * @param {boolean} integer Convert the return value to an integer
370                  * @return {string} The number converted into a String.
371                  */
372                 convertNumber: function ( num, integer ) {
373                         var tmp, item, i,
374                                 transformTable, numberString, convertedNumber;
376                         // Set the target Transform table:
377                         transformTable = this.digitTransformTable( $.i18n().locale );
378                         numberString = String( num );
379                         convertedNumber = '';
381                         if ( !transformTable ) {
382                                 return num;
383                         }
385                         // Check if the restore to Latin number flag is set:
386                         if ( integer ) {
387                                 if ( parseFloat( num, 10 ) === num ) {
388                                         return num;
389                                 }
391                                 tmp = [];
393                                 for ( item in transformTable ) {
394                                         tmp[ transformTable[ item ] ] = item;
395                                 }
397                                 transformTable = tmp;
398                         }
400                         for ( i = 0; i < numberString.length; i++ ) {
401                                 if ( transformTable[ numberString[ i ] ] ) {
402                                         convertedNumber += transformTable[ numberString[ i ] ];
403                                 } else {
404                                         convertedNumber += numberString[ i ];
405                                 }
406                         }
408                         return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber;
409                 },
411                 /**
412                  * Grammatical transformations, needed for inflected languages.
413                  * Invoked by putting {{grammar:form|word}} in a message.
414                  * Override this method for languages that need special grammar rules
415                  * applied dynamically.
416                  *
417                  * @param {string} word
418                  * @param {string} form
419                  * @return {string}
420                  */
421                 // eslint-disable-next-line no-unused-vars
422                 convertGrammar: function ( word, form ) {
423                         return word;
424                 },
426                 /**
427                  * Provides an alternative text depending on specified gender. Usage
428                  * {{gender:[gender|user object]|masculine|feminine|neutral}}. If second
429                  * or third parameter are not specified, masculine is used.
430                  *
431                  * These details may be overriden per language.
432                  *
433                  * @param {string} gender
434                  *      male, female, or anything else for neutral.
435                  * @param {Array} forms
436                  *      List of gender forms
437                  *
438                  * @return {string}
439                  */
440                 gender: function ( gender, forms ) {
441                         if ( !forms || forms.length === 0 ) {
442                                 return '';
443                         }
445                         while ( forms.length < 2 ) {
446                                 forms.push( forms[ forms.length - 1 ] );
447                         }
449                         if ( gender === 'male' ) {
450                                 return forms[ 0 ];
451                         }
453                         if ( gender === 'female' ) {
454                                 return forms[ 1 ];
455                         }
457                         return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
458                 },
460                 /**
461                  * Get the digit transform table for the given language
462                  * See http://cldr.unicode.org/translation/numbering-systems
463                  *
464                  * @param {string} language
465                  * @return {Array|boolean} List of digits in the passed language or false
466                  * representation, or boolean false if there is no information.
467                  */
468                 digitTransformTable: function ( language ) {
469                         var tables = {
470                                 ar: '٠١٢٣٤٥٦٧٨٩',
471                                 fa: '۰۱۲۳۴۵۶۷۸۹',
472                                 ml: '൦൧൨൩൪൫൬൭൮൯',
473                                 kn: '೦೧೨೩೪೫೬೭೮೯',
474                                 lo: '໐໑໒໓໔໕໖໗໘໙',
475                                 or: '୦୧୨୩୪୫୬୭୮୯',
476                                 kh: '០១២៣៤៥៦៧៨៩',
477                                 nqo: '߀߁߂߃߄߅߆߇߈߉', // Note that the digits go right to left
478                                 pa: '੦੧੨੩੪੫੬੭੮੯',
479                                 gu: '૦૧૨૩૪૫૬૭૮૯',
480                                 hi: '०१२३४५६७८९',
481                                 my: '၀၁၂၃၄၅၆၇၈၉',
482                                 ta: '௦௧௨௩௪௫௬௭௮௯',
483                                 te: '౦౧౨౩౪౫౬౭౮౯',
484                                 th: '๐๑๒๓๔๕๖๗๘๙', // FIXME use iso 639 codes
485                                 bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes
486                         };
488                         if ( !tables[ language ] ) {
489                                 return false;
490                         }
492                         return tables[ language ].split( '' );
493                 }
494         };
496         $.extend( $.i18n.languages, {
497                 default: language
498         } );
499 }( jQuery ) );