Last active
July 30, 2019 07:54
-
-
Save hww/130fdc912f5ae44869366de131c9a728 to your computer and use it in GitHub Desktop.
Simple localization solution for Unity engine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.IO; | |
using System.Collections.Generic; | |
using System; | |
/// <summary> | |
/// Simple localization solution for Unity engine. | |
/// Loading and parsing language.po.txt file from streaming assets folder. | |
/// | |
/// Author: Valery https://github.com/hww | |
/// | |
/// N.B. Do not support pluralization syntax with squared brackets msgstr[0]. | |
/// Use instead two separated entries: | |
/// | |
/// msgid "singular id" | |
/// msgstr "singular text" | |
/// msgid "plural id 0" | |
/// msgstr "plurral text 0" | |
/// ... | |
/// msgid "plural id n" | |
/// msgstr "plurral text n" | |
/// | |
/// </summary> | |
/// <example> | |
/// var pofile = new POFile(); | |
/// pofile.LoadLanguage("en"); | |
/// | |
/// To get string: | |
/// | |
/// var msg1 = pofile.GetText("global.hello_world"); | |
/// var msg2 = pofile.GetText("global.insert_x_coins", coinsCount); | |
/// | |
/// The last line is equivalent of: | |
/// | |
/// var key = pofile.GetPluralKey("global.insert_x_coins", coinsCount); | |
/// var msg2 = pofile.GetText(key); | |
/// | |
/// Example of string with pluralization: | |
/// | |
/// msgid "player.insert_x_coins_0" | |
/// msgstr "Insert {0} Coin" | |
/// msgid "player.insert_x_coins_1" | |
/// msgstr "Insert {0} Coins" | |
/// | |
/// The suffx _0 or _1 generated by method suffixMethod. The table suffixMethodsDictionary contains list | |
/// of suffixMethods for each language. | |
/// </example> | |
/// <see cref="https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files"/> | |
public class POFile | |
{ | |
/// <summary> | |
/// Read and parse .po file for selected language. | |
/// The file path format is "Streming Assets/languages/{language}.po.txt" | |
/// </summary> | |
/// <param name="lang">language name aka: "en", "ru" or "en_US"</param> | |
public void LoadLanguage(string lang) | |
{ | |
SetLanguage(lang); | |
string fullpath = Application.streamingAssetsPath + "/languages/" + lang + ".po.txt"; | |
var textAsset = File.ReadAllText(fullpath); | |
if (textAsset == null) | |
{ | |
Debug.LogError($"[POFile] '{fullpath}' file not found."); | |
} | |
else | |
{ | |
Debug.Log($"[POFile] loading: '{fullpath}'"); | |
stringsDictionary.Clear(); | |
StringReader reader = new StringReader(textAsset); | |
string key = null; | |
string val = null; | |
string line; | |
while ((line = reader.ReadLine()) != null) | |
{ | |
if (line.StartsWith("msgid \"")) | |
{ | |
key = RemoveQuotes(line, 5); | |
} | |
else if (line.StartsWith("msgstr \"")) | |
{ | |
val = RemoveQuotes(line, 6); | |
if (key != null && val != null) | |
{ | |
// TODO: add error handling here in case of duplicate keys | |
stringsDictionary.Add(key, val); | |
key = val = null; | |
} | |
else | |
Debug.LogError($"[POFile] key or value is null key:'{key}' value:'{val}'."); | |
} | |
} | |
reader.Close(); | |
} | |
} | |
// Set current language | |
private void SetLanguage(string language) | |
{ | |
currentLanguage = language; | |
suffixMethod = suffixMethodsDictionary[language]; | |
Debug.Assert(suffixMethod != null); | |
} | |
// Remove spaces ' ' and quotes '"' from begin and endo of string | |
private string RemoveQuotes(string str, int start) | |
{ | |
Debug.Assert(str != null); | |
Debug.Assert(start < str.Length); | |
int startQuote = 0; | |
int endQuote = 0; | |
for (var i = start; i < str.Length; i++) | |
{ | |
if (str[i] == ' ') continue; | |
if (str[i] == '"') | |
{ | |
startQuote = i; | |
break; | |
} | |
Debug.LogError($"Text does not have start quote: '{str}'"); | |
return str; | |
} | |
for (var i = str.Length - 1; i >= startQuote; i--) | |
{ | |
if (str[i] == ' ') continue; | |
if (str[i] == '"') | |
{ | |
endQuote = i; | |
break; | |
} | |
Debug.LogError($"Text does not have end quote: '{str}'"); | |
return str; | |
} | |
Debug.Assert(endQuote > startQuote); | |
return str.Substring(startQuote + 1, (endQuote - startQuote) - 1); | |
} | |
/// <summary>Find text value with the key</summary> | |
public string GetText(string key) | |
{ | |
Debug.Assert(key != null); | |
string result = ""; | |
return stringsDictionary.TryGetValue(key, out result) ? result : null; | |
} | |
/// <summary>Find text value with the key and quantity</summary> | |
public string GetText(string key, int quantity) | |
{ | |
Debug.Assert(key != null); | |
string pluralKey = GetPluralKey(key, quantity); | |
string result = ""; | |
return stringsDictionary.TryGetValue(pluralKey, out result) ? result : null; | |
} | |
/// <summary> | |
/// Get key for pluralized text value | |
/// </summary> | |
/// <param name="key"></param> | |
/// <param name="quantity"></param> | |
/// <returns></returns> | |
public string GetPluralKey(string key, int quantity) | |
{ | |
return $"{key}_{suffixMethod.Invoke(quantity)}"; | |
} | |
/// <summary>Contains current language</summary> | |
public string currentLanguage = "en"; | |
/// <summary>Keep the method for computing pluralization suffix</summary> | |
private Func<int, int> suffixMethod; | |
/// <summary>Key value pair from .po file</summary> | |
private Dictionary<string, string> stringsDictionary = new Dictionary<string, string>(100); | |
/// <summary> | |
/// Contains list of methos for each available language. | |
/// </summary> | |
private static readonly Dictionary<string, Func<int, int>> suffixMethodsDictionary = new Dictionary<string, Func<int, int>>() | |
{ | |
{ "ar", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "bg", (n) => n != 1 ? 1 : 0 }, // Bulgarian | |
{ "ca", (n) => n != 1 ? 1 : 0 }, // Catalan | |
{ "zh-CHS", (n) => 0 }, // Chinese | |
{ "cs", (n) => (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2 }, // Czech | |
{ "da", (n) => n != 1 ? 1 : 0 }, // Danish | |
{ "de", (n) => n != 1 ? 1 : 0 }, // German | |
{ "el", (n) => n != 1 ? 1 : 0 }, // Greek | |
{ "en", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "fi", (n) => n != 1 ? 1 : 0 }, // Finnish | |
{ "fr", (n) => n > 1 ? 1 : 0 }, // French | |
{ "he", (n) => n != 1 ? 1 : 0 }, // Hebrew | |
{ "hu", (n) => n != 1 ? 1 : 0 }, // Hungarian | |
{ "is", (n) => (n % 10 != 1 || n % 100 == 11) ? 1 : 0 }, // Icelandic | |
{ "it", (n) => n != 1 ? 1 : 0 }, // Italian | |
{ "ja", (n) => 0 }, // Japanese | |
{ "ko", (n) => 0 }, // Korean | |
{ "nl", (n) => n != 1 ? 1 : 0 }, // Dutch | |
{ "no", (n) => n != 1 ? 1 : 0 }, // Norwegian | |
{ "pl", (n) => n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Polish | |
{ "pt", (n) => n != 1 ? 1 : 0 }, // Portuguese | |
{ "ro", (n) => n == 1 ? 0 : (n == 0 || (n % 100 > 0 && n % 100 < 20)) ? 1 : 2 }, // Romanian | |
{ "ru", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Russian | |
{ "hr", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Croatian | |
{ "sk", (n) => (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2 }, // Slovak | |
{ "sq", (n) => n != 1 ? 1 : 0 }, // Albanian | |
{ "sv", (n) => n != 1 ? 1 : 0 }, // Swedish | |
{ "th", (n) => 0 }, // Thai | |
{ "tr", (n) => n > 1 ? 1 : 0 }, // Turkish | |
{ "id", (n) => 0 }, // Indonesian | |
{ "uk", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Ukrainian | |
{ "be", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Belarusian | |
{ "sl", (n) => n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0 }, // Slovenian | |
{ "et", (n) => n != 1 ? 1 : 0 }, // Estonian | |
{ "lv", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2 }, // Latvian | |
{ "lt", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Lithuanian | |
{ "fa", (n) => 0 }, // Persian | |
{ "vi", (n) => 0 }, // Vietnamese | |
{ "hy", (n) => n != 1 ? 1 : 0 }, // Armenian | |
{ "eu", (n) => n != 1 ? 1 : 0 }, // Basque | |
{ "mk", (n) => (n == 1 || n % 10 == 1) ? 1 : (n == 2 || n % 10 == 2) ? 2 : 0 }, // Macedonian | |
{ "af", (n) => n != 1 ? 1 : 0 }, // Afrikaans | |
{ "ka", (n) => 0 }, // Georgian | |
{ "fo", (n) => n != 1 ? 1 : 0 }, // Faroese | |
{ "hi", (n) => n != 1 ? 1 : 0 }, // Hindi | |
{ "sw", (n) => n != 1 ? 1 : 0 }, // Swahili | |
{ "gu", (n) => n != 1 ? 1 : 0 }, // Gujarati | |
{ "ta", (n) => n != 1 ? 1 : 0 }, // Tamil | |
{ "te", (n) => n != 1 ? 1 : 0 }, // Telugu | |
{ "kn", (n) => n != 1 ? 1 : 0 }, // Kannada | |
{ "mr", (n) => n != 1 ? 1 : 0 }, // Marathi | |
{ "gl", (n) => n != 1 ? 1 : 0 }, // Gallegan ------------------------------- | |
{ "kok", (n) => n != 1 ? 1 : 0 }, // Konkani ------------------------------- | |
{ "ar-SA", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "bg-BG", (n) => n != 1 ? 1 : 0 }, // Bulgarian | |
{ "ca-ES", (n) => n != 1 ? 1 : 0 }, // Catalan | |
{ "zh-TW", (n) => 0 }, // Chinese | |
{ "cs-CZ", (n) => (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2 }, // Czech | |
{ "da-DK", (n) => n != 1 ? 1 : 0 }, // Danish | |
{ "de-DE", (n) => n != 1 ? 1 : 0 }, // German | |
{ "el-GR", (n) => n != 1 ? 1 : 0 }, // Greek | |
{ "en-US", (n) => n != 1 ? 1 : 0 }, // English | |
{ "fi-FI", (n) => n != 1 ? 1 : 0 }, // Finnish | |
{ "fr-FR", (n) => n > 1 ? 1 : 0 }, // French | |
{ "he-IL", (n) => n != 1 ? 1 : 0 }, // Hebrew | |
{ "hu-HU", (n) => n != 1 ? 1 : 0 }, // Hungarian | |
{ "is-IS", (n) => (n % 10 != 1 || n % 100 == 11) ? 1 : 0 }, // Icelandic | |
{ "it-IT", (n) => n != 1 ? 1 : 0 }, // Italian | |
{ "ja-JP", (n) => 0 }, // Japanese | |
{ "ko-KR", (n) => 0 }, // Korean | |
{ "nl-NL", (n) => n != 1 ? 1 : 0 }, // Dutch | |
{ "nb-NO", (n) => n != 1 ? 1 : 0 }, // Norwegian | |
{ "pl-PL", (n) => n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Polish | |
{ "pt-BR", (n) => n > 1 ? 1 : 0 }, // Portuguese | |
{ "ro-RO", (n) => n == 1 ? 0 : (n == 0 || (n % 100 > 0 && n % 100 < 20)) ? 1 : 2 }, // Romanian | |
{ "ru-RU", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Russian | |
{ "hr-HR", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Croatian | |
{ "sk-SK", (n) => (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2 }, // Slovak | |
{ "sq-AL", (n) => n != 1 ? 1 : 0 }, // Albanian | |
{ "sv-SE", (n) => n != 1 ? 1 : 0 }, // Swedish | |
{ "th-TH", (n) => 0 }, // Thai | |
{ "tr-TR", (n) => n > 1 ? 1 : 0 }, // Turkish | |
{ "id-ID", (n) => 0 }, // Indonesian | |
{ "uk-UA", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Ukrainian | |
{ "be-BY", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Belarusian | |
{ "sl-SI", (n) => n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0 }, // Slovenian | |
{ "et-EE", (n) => n != 1 ? 1 : 0 }, // Estonian | |
{ "lv-LV", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2 }, // Latvian | |
{ "lt-LT", (n) => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 }, // Lithuanian | |
{ "fa-IR", (n) => 0 }, // Persian | |
{ "vi-VN", (n) => 0 }, // Vietnamese | |
{ "hy-AM", (n) => n != 1 ? 1 : 0 }, // Armenian | |
{ "eu-ES", (n) => n != 1 ? 1 : 0 }, // Basque | |
{ "mk-MK", (n) => (n == 1 || n % 10 == 1) ? 1 : (n == 2 || n % 10 == 2) ? 2 : 0}, // Macedonian | |
{ "af-ZA", (n) => n != 1 ? 1 : 0 }, // Afrikaans | |
{ "ka-GE", (n) => 0 }, // Georgian | |
{ "fo-FO", (n) => n != 1 ? 1 : 0 }, // Faroese | |
{ "hi-IN", (n) => n != 1 ? 1 : 0 }, // Hindi | |
{ "sw-KE", (n) => n != 1 ? 1 : 0 }, // Swahili | |
{ "gu-IN", (n) => n != 1 ? 1 : 0 }, // Gujarati | |
{ "ta-IN", (n) => n != 1 ? 1 : 0 }, // Tamil | |
{ "te-IN", (n) => n != 1 ? 1 : 0 }, // Telugu | |
{ "kn-IN", (n) => n != 1 ? 1 : 0 }, // Kannada | |
{ "mr-IN", (n) => n != 1 ? 1 : 0 }, // Marathi | |
{ "gl-ES", (n) => n != 1 ? 1 : 0 }, // Gallegan ------------------------------- | |
{ "kok-IN", (n) => n != 1 ? 1 : 0 }, // Konkani ------------------------------- | |
{ "ar-IQ", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "zh-CN", (n) => 0 }, // Chinese | |
{ "de-CH", (n) => n != 1 ? 1 : 0 }, // German | |
{ "en-GB", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-MX", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "fr-BE", (n) => n > 1 ? 1 : 0 }, // French | |
{ "it-CH", (n) => n != 1 ? 1 : 0 }, // Italian | |
{ "nl-BE", (n) => n != 1 ? 1 : 0 }, // Dutch | |
{ "nn-NO", (n) => n != 1 ? 1 : 0 }, // Norwegian | |
{ "pt-PT", (n) => n != 1 ? 1 : 0 }, // Portuguese | |
{ "sv-FI", (n) => n != 1 ? 1 : 0 }, // Swedish | |
{ "ar-EG", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "zh-HK", (n) => 0 }, // Chinese | |
{ "de-AT", (n) => n != 1 ? 1 : 0 }, // German | |
{ "en-AU", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-ES", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "fr-CA", (n) => n > 1 ? 1 : 0 }, // French | |
{ "ar-LY", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "zh-SG", (n) => 0 }, // Chinese | |
{ "de-LU", (n) => n != 1 ? 1 : 0 }, // German | |
{ "en-CA", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-GT", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "fr-CH", (n) => n > 1 ? 1 : 0 }, // French | |
{ "ar-DZ", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "zh-MO", (n) => 0 }, // Chinese | |
{ "en-NZ", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-CR", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "fr-LU", (n) => n > 1 ? 1 : 0 }, // French | |
{ "ar-MA", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "en-IE", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-PA", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-TN", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "en-ZA", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-DO", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-OM", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-VE", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-YE", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-CO", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-SY", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-PE", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-JO", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "en-TT", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-AR", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-LB", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "en-ZW", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-EC", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-KW", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "en-PH", (n) => n != 1 ? 1 : 0 }, // English | |
{ "es-CL", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-AE", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-UY", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-BH", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-PY", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "ar-QA", (n) => n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5 }, // Arabic | |
{ "es-BO", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "es-SV", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "es-HN", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "es-NI", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "es-PR", (n) => n != 1 ? 1 : 0 }, // Spanish | |
{ "zh-CHT", (n) => 0 }, // Chinese | |
{ "ms", (n) => 0 } // Malaysia | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment