UNPKG

11.1 kBJavaScriptView Raw
1var BabelFish = window.BabelFish = (function () {
2 (function (self) {
3 self.def = function (name, func) {
4 self[name] = {exports: {}, called: false, func: func};
5 };
6 self.req = function (name) {
7 if (self[name].called) {
8 return self[name].exports;
9 }
10
11 self[name].called = true;
12 self[name].exports = self[name].func.call(self[name], self.req);
13
14 return self[name].exports;
15 };
16 }(this));
17
18 this.def("0", function (require) {
19 var module = this, exports = this.exports;
20
21// This is a "minimal" version of BabelFish used on client side ////////////////
22////////////////////////////////////////////////////////////////////////////////
23
24
25'use strict';
26
27
28/*global window*/
29
30
31// TODO: Provide shim for Underscore
32var Underscore = (window || global)._;
33var Pluralizer = require("1");
34
35
36// helpers
37////////////////////////////////////////////////////////////////////////////////
38
39
40// flattenParams(obj) -> Object
41//
42// Flattens object into one-level distionary.
43//
44// ##### Example
45//
46// var obj = {
47// abc: { def: 'foo' },
48// hij: 'bar'
49// };
50//
51// flattenParams(obj);
52// // -> { 'abc.def': 'foo', 'hij': 'bar' };
53function flattenParams(obj) {
54 var params = {};
55
56 Underscore.each(obj || {}, function (val, key) {
57 if (val && 'object' === typeof val) {
58 Underscore.each(flattenParams(val), function (sub_val, sub_key) {
59 params[key + '.' + sub_key] = sub_val;
60 });
61 return;
62 }
63
64 params[key] = val;
65 });
66
67 return params;
68}
69
70
71// Returns locale storage. Creates one if needed
72function getLocaleStorage(self, locale) {
73 if (undefined === self._storage[locale]) {
74 self._storage[locale] = {};
75 }
76
77 return self._storage[locale];
78}
79
80
81// public api (module)
82////////////////////////////////////////////////////////////////////////////////
83
84
85function BabelFish(storage) {
86 // storage of compiled translations
87 this._storage = storage;
88}
89
90
91// public api (instance)
92////////////////////////////////////////////////////////////////////////////////
93
94
95BabelFish.prototype.translate = function translate(locale, phrase, params) {
96 var translator = this.getCompiledData(locale, phrase);
97
98 if ('string' === translator.type) {
99 return translator.translation;
100 }
101
102 if ('function' === translator.type) {
103 return translator.translation.call({
104 flattenParams: flattenParams,
105 pluralize: Pluralizer
106 }, params);
107 }
108
109 return locale + ': No translation for [' + phrase + ']';
110};
111
112
113BabelFish.prototype.hasPhrase = function hasPhrase(locale, phrase) {
114 var translator = this.getCompiledData(locale, phrase);
115 return 'string' === translator.type || 'function' === translator.type;
116};
117
118
119BabelFish.prototype.t = BabelFish.prototype.translate;
120
121
122BabelFish.prototype.getCompiledData = function getCompiledData(locale, phrase) {
123 var storage = getLocaleStorage(this, locale);
124
125 // requested FULL storage
126 if (!phrase) {
127 return storage;
128 }
129
130 return storage[phrase] || {};
131};
132
133
134// export module
135module.exports = BabelFish;
136
137
138 return this.exports;
139 });
140 this.def("1", function (require) {
141 var module = this, exports = this.exports;
142
143//
144// See rules here:
145// http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
146//
147
148'use strict';
149
150
151// pluralizers cache
152var PLURALIZERS = {};
153
154
155module.exports = function pluralize(lang, count, forms) {
156 var idx;
157
158 if (!PLURALIZERS[lang]) {
159 return '[pluralizer for (' + lang + ') not exists]';
160 }
161
162 idx = PLURALIZERS[lang](count);
163
164 if (undefined === forms[idx]) {
165 return '[plural form N' + idx + ' not found in translation]';
166 }
167
168 return forms[idx];
169};
170
171
172// HELPERS
173////////////////////////////////////////////////////////////////////////////////
174
175
176// adds given `rule` pluralizer for given `locales` into `storage`
177function add(locales, rule) {
178 var i;
179 for (i = 0; i < locales.length; i += 1) {
180 PLURALIZERS[locales[i]] = rule;
181 }
182}
183
184// check if number is int or float
185function is_int(input) {
186 return (0 === input % 1);
187}
188
189// PLURALIZATION RULES
190////////////////////////////////////////////////////////////////////////////////
191////////////////////////////////////////////////////////////////////////////////
192
193
194// Azerbaijani, Bambara, Burmese, Chinese, Dzongkha, Georgian, Hungarian, Igbo,
195// Indonesian, Japanese, Javanese, Kabuverdianu, Kannada, Khmer, Korean,
196// Koyraboro Senni, Lao, Makonde, Malay, Persian, Root, Sakha, Sango,
197// Sichuan Yi, Thai, Tibetan, Tonga, Turkish, Vietnamese, Wolof, Yoruba
198
199add(['az', 'bm', 'my', 'zh', 'dz', 'ka', 'hu', 'ig',
200 'id', 'ja', 'jv', 'kea', 'kn', 'km', 'ko',
201 'ses', 'lo', 'kde', 'ms', 'fa', 'root', 'sah', 'sg',
202 'ii', 'th', 'bo', 'to', 'tr', 'vi', 'wo', 'yo'], function (n) {
203 return 0;
204});
205
206
207// Manx
208
209add(['gv'], function (n) {
210 var m10 = n % 10, m20 = n % 20;
211
212 if ((m10 === 1 || m10 === 2 || m20 === 0) && is_int(n)) {
213 return 0;
214 }
215
216 return 1;
217});
218
219
220// Central Morocco Tamazight
221
222add(['tzm'], function (n) {
223 if (n === 0 || n === 1 || (11 <= n && n <= 99 && is_int(n))) {
224 return 0;
225 }
226
227 return 1;
228});
229
230
231// Macedonian
232
233add(['mk'], function (n) {
234 if ((n % 10 === 1) && (n !== 11) && is_int(n)) {
235 return 0;
236 }
237
238 return 1;
239});
240
241
242// Akan, Amharic, Bihari, Filipino, Gun, Hindi,
243// Lingala, Malagasy, Northern Sotho, Tagalog, Tigrinya, Walloon
244
245add(['ak', 'am', 'bh', 'fil', 'guw', 'hi',
246 'ln', 'mg', 'nso', 'tl', 'ti', 'wa'], function (n) {
247 return (n === 0 || n === 1) ? 0 : 1;
248});
249
250
251// Afrikaans, Albanian, Basque, Bemba, Bengali, Bodo, Bulgarian, Catalan,
252// Cherokee, Chiga, Danish, Divehi, Dutch, English, Esperanto, Estonian, Ewe,
253// Faroese, Finnish, Friulian, Galician, Ganda, German, Greek, Gujarati, Hausa,
254// Hawaiian, Hebrew, Icelandic, Italian, Kalaallisut, Kazakh, Kurdish,
255// Luxembourgish, Malayalam, Marathi, Masai, Mongolian, Nahuatl, Nepali,
256// Norwegian, Norwegian Bokmål, Norwegian Nynorsk, Nyankole, Oriya, Oromo,
257// Papiamento, Pashto, Portuguese, Punjabi, Romansh, Saho, Samburu, Soga,
258// Somali, Spanish, Swahili, Swedish, Swiss German, Syriac, Tamil, Telugu,
259// Turkmen, Urdu, Walser, Western Frisian, Zulu
260
261add(['af', 'sq', 'eu', 'bem', 'bn', 'brx', 'bg', 'ca',
262 'chr', 'cgg', 'da', 'dv', 'nl', 'en', 'eo', 'et', 'ee',
263 'fo', 'fi', 'fur', 'gl', 'lg', 'de', 'el', 'gu', 'ha',
264 'haw', 'he', 'is', 'it', 'kl', 'kk', 'ku',
265 'lb', 'ml', 'mr', 'mas', 'mn', 'nah', 'ne',
266 'no', 'nb', 'nn', 'nyn', 'or', 'om',
267 'pap', 'ps', 'pt', 'pa', 'rm', 'ssy', 'saq', 'xog',
268 'so', 'es', 'sw', 'sv', 'gsw', 'syr', 'ta', 'te',
269 'tk', 'ur', 'wae', 'fy', 'zu'], function (n) {
270 return (1 === n) ? 0 : 1;
271});
272
273
274// Latvian
275
276add(['lv'], function (n) {
277 if (n === 0) {
278 return 0;
279 }
280
281 if ((n % 10 === 1) && (n % 100 !== 11) && is_int(n)) {
282 return 1;
283 }
284
285 return 2;
286});
287
288
289// Colognian
290
291add(['ksh'], function (n) {
292 return (n === 0) ? 0 : ((n === 1) ? 1 : 2);
293});
294
295
296// Cornish, Inari Sami, Inuktitut, Irish, Lule Sami, Northern Sami,
297// Sami Language, Skolt Sami, Southern Sami
298
299add(['kw', 'smn', 'iu', 'ga', 'smj', 'se',
300 'smi', 'sms', 'sma'], function (n) {
301 return (n === 1) ? 0 : ((n === 2) ? 1 : 2);
302});
303
304
305// Belarusian, Bosnian, Croatian, Russian, Serbian, Serbo-Croatian, Ukrainian
306
307add(['be', 'bs', 'hr', 'ru', 'sr', 'sh', 'uk'], function (n) {
308 var m10 = n % 10, m100 = n % 100;
309
310 if (!is_int(n)) {
311 return 3;
312 }
313
314 // one → n mod 10 is 1 and n mod 100 is not 11;
315 if (1 === m10 && 11 !== m100) {
316 return 0;
317 }
318
319 // few → n mod 10 in 2..4 and n mod 100 not in 12..14;
320 if (2 <= m10 && m10 <= 4 && !(12 <= m100 && m100 <= 14)) {
321 return 1;
322 }
323
324 // many → n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
325/* if (0 === m10 || (5 <= m10 && m10 <= 9) || (11 <= m100 && m100 <= 14)) {
326 return 2;
327 }
328
329 // other
330 return 3;*/
331 return 2;
332});
333
334
335// Polish
336
337add(['pl'], function (n) {
338 var m10 = n % 10, m100 = n % 100;
339
340 if (!is_int(n)) {
341 return 3;
342 }
343
344 // one → n is 1;
345 if (n === 1) {
346 return 0;
347 }
348
349 // few → n mod 10 in 2..4 and n mod 100 not in 12..14;
350 if (2 <= m10 && m10 <= 4 && !(12 <= m100 && m100 <= 14)) {
351 return 1;
352 }
353
354 // many → n is not 1 and n mod 10 in 0..1 or
355 // n mod 10 in 5..9 or n mod 100 in 12..14
356 // (all other except partials)
357 return 2;
358});
359
360
361// Lithuanian
362
363add(['lt'], function (n) {
364 var m10 = n % 10, m100 = n % 100;
365
366 if (!is_int(n)) {
367 return 2;
368 }
369
370 // one → n mod 10 is 1 and n mod 100 not in 11..19
371 if (m10 === 1 && !(11 <= m100 && m100 <= 19)) {
372 return 0;
373 }
374
375 // few → n mod 10 in 2..9 and n mod 100 not in 11..19
376 if (2 <= m10 && m10 <= 9 && !(11 <= m100 && m100 <= 19)) {
377 return 1;
378 }
379
380 // other
381 return 2;
382});
383
384
385// Tachelhit
386
387add(['shi'], function (n) {
388 return (0 <= n && n <= 1) ? 0 : ((is_int(n) && 2 <= n && n <= 10) ? 1 : 2);
389});
390
391
392// Moldavian, Romanian
393
394add(['mo', 'ro'], function (n) {
395 var m100 = n % 100;
396
397 if (!is_int(n)) {
398 return 2;
399 }
400
401 // one → n is 1
402 if (n === 1) {
403 return 0;
404 }
405
406 // few → n is 0 OR n is not 1 AND n mod 100 in 1..19
407 if (n === 0 || (1 <= m100 && m100 <= 19)) {
408 return 1;
409 }
410
411 // other
412 return 2;
413});
414
415
416// Czech, Slovak
417
418add(['cs', 'sk'], function (n) {
419 // one → n is 1
420 if (n === 1) {
421 return 0;
422 }
423
424 // few → n in 2..4
425 if (n === 2 || n === 3 || n === 4) {
426 return 1;
427 }
428
429 // other
430 return 2;
431});
432
433
434
435// Slovenian
436
437add(['sl'], function (n) {
438 var m100 = n % 100;
439
440 if (!is_int(n)) {
441 return 3;
442 }
443
444 // one → n mod 100 is 1
445 if (m100 === 1) {
446 return 0;
447 }
448
449 // one → n mod 100 is 2
450 if (m100 === 2) {
451 return 1;
452 }
453
454 // one → n mod 100 in 3..4
455 if (m100 === 3 || m100 === 4) {
456 return 2;
457 }
458
459 // other
460 return 3;
461});
462
463
464// Maltese
465
466add(['mt'], function (n) {
467 var m100 = n % 100;
468
469 if (!is_int(n)) {
470 return 3;
471 }
472
473 // one → n is 1
474 if (n === 1) {
475 return 0;
476 }
477
478 // few → n is 0 or n mod 100 in 2..10
479 if (n === 0 || (2 <= m100 && m100 <= 10)) {
480 return 1;
481 }
482
483 // many → n mod 100 in 11..19
484 if (11 <= m100 && m100 <= 19) {
485 return 2;
486 }
487
488 // other
489 return 3;
490});
491
492
493// Arabic
494
495add(['ar'], function (n) {
496 var m100 = n % 100;
497
498 if (!is_int(n)) {
499 return 5;
500 }
501
502 if (n === 0) {
503 return 0;
504 }
505 if (n === 1) {
506 return 1;
507 }
508 if (n === 2) {
509 return 2;
510 }
511
512 // few → n mod 100 in 3..10
513 if (3 <= m100 && m100 <= 10) {
514 return 3;
515 }
516
517 // many → n mod 100 in 11..99
518 if (11 <= m100 && m100 <= 99) {
519 return 4;
520 }
521
522 // other
523 return 5;
524});
525
526
527// Breton, Welsh
528
529add(['br', 'cy'], function (n) {
530
531 if (n === 0) {
532 return 0;
533 }
534 if (n === 1) {
535 return 1;
536 }
537 if (n === 2) {
538 return 2;
539 }
540 if (n === 3) {
541 return 3;
542 }
543 if (n === 6) {
544 return 4;
545 }
546
547 return 5;
548});
549
550
551// FRACTIONAL PARTS - SPECIAL CASES
552////////////////////////////////////////////////////////////////////////////////
553
554
555// French, Fulah, Kabyle
556
557add(['fr', 'ff', 'kab'], function (n) {
558 return (0 <= n && n < 2) ? 0 : 1;
559});
560
561
562// Langi
563
564add(['lag'], function (n) {
565 return (n === 0) ? 0 : ((0 < n && n < 2) ? 1 : 2);
566});
567
568
569
570 return this.exports;
571 });
572
573 return this.req("0");
574}.call({}));