|
|
(function (root) { |
|
|
'use strict'; |
|
|
|
|
|
/** |
|
|
* charMap |
|
|
* @type {Object} |
|
|
*/ |
|
|
var charMap = { |
|
|
|
|
|
// latin |
|
|
'À': 'A', |
|
|
'Á': 'A', |
|
|
'Â': 'A', |
|
|
'Ã': 'A', |
|
|
'Ä': 'Ae', |
|
|
'Å': 'A', |
|
|
'Æ': 'AE', |
|
|
'Ç': 'C', |
|
|
'È': 'E', |
|
|
'É': 'E', |
|
|
'Ê': 'E', |
|
|
'Ë': 'E', |
|
|
'Ì': 'I', |
|
|
'Í': 'I', |
|
|
'Î': 'I', |
|
|
'Ï': 'I', |
|
|
'Ð': 'D', |
|
|
'Ñ': 'N', |
|
|
'Ò': 'O', |
|
|
'Ó': 'O', |
|
|
'Ô': 'O', |
|
|
'Õ': 'O', |
|
|
'Ö': 'Oe', |
|
|
'Ő': 'O', |
|
|
'Ø': 'O', |
|
|
'Ù': 'U', |
|
|
'Ú': 'U', |
|
|
'Û': 'U', |
|
|
'Ü': 'Ue', |
|
|
'Ű': 'U', |
|
|
'Ý': 'Y', |
|
|
'Þ': 'TH', |
|
|
'ß': 'ss', |
|
|
'à': 'a', |
|
|
'á': 'a', |
|
|
'â': 'a', |
|
|
'ã': 'a', |
|
|
'ä': 'ae', |
|
|
'å': 'a', |
|
|
'æ': 'ae', |
|
|
'ç': 'c', |
|
|
'è': 'e', |
|
|
'é': 'e', |
|
|
'ê': 'e', |
|
|
'ë': 'e', |
|
|
'ì': 'i', |
|
|
'í': 'i', |
|
|
'î': 'i', |
|
|
'ï': 'i', |
|
|
'ð': 'd', |
|
|
'ñ': 'n', |
|
|
'ò': 'o', |
|
|
'ó': 'o', |
|
|
'ô': 'o', |
|
|
'õ': 'o', |
|
|
'ö': 'oe', |
|
|
'ő': 'o', |
|
|
'ø': 'o', |
|
|
'ù': 'u', |
|
|
'ú': 'u', |
|
|
'û': 'u', |
|
|
'ü': 'ue', |
|
|
'ű': 'u', |
|
|
'ý': 'y', |
|
|
'þ': 'th', |
|
|
'ÿ': 'y', |
|
|
'ẞ': 'SS', |
|
|
|
|
|
// language specific |
|
|
|
|
|
// Arabic |
|
|
'ا': 'a', |
|
|
'أ': 'a', |
|
|
'إ': 'i', |
|
|
'آ': 'aa', |
|
|
'ؤ': 'u', |
|
|
'ئ': 'e', |
|
|
'ء': 'a', |
|
|
'ب': 'b', |
|
|
'ت': 't', |
|
|
'ث': 'th', |
|
|
'ج': 'j', |
|
|
'ح': 'h', |
|
|
'خ': 'kh', |
|
|
'د': 'd', |
|
|
'ذ': 'th', |
|
|
'ر': 'r', |
|
|
'ز': 'z', |
|
|
'س': 's', |
|
|
'ش': 'sh', |
|
|
'ص': 's', |
|
|
'ض': 'dh', |
|
|
'ط': 't', |
|
|
'ظ': 'z', |
|
|
'ع': 'a', |
|
|
'غ': 'gh', |
|
|
'ف': 'f', |
|
|
'ق': 'q', |
|
|
'ك': 'k', |
|
|
'ل': 'l', |
|
|
'م': 'm', |
|
|
'ن': 'n', |
|
|
'ه': 'h', |
|
|
'و': 'w', |
|
|
'ي': 'y', |
|
|
'ى': 'a', |
|
|
'ة': 'h', |
|
|
'ﻻ': 'la', |
|
|
'ﻷ': 'laa', |
|
|
'ﻹ': 'lai', |
|
|
'ﻵ': 'laa', |
|
|
|
|
|
// Persian additional characters than Arabic |
|
|
'گ': 'g', |
|
|
'چ': 'ch', |
|
|
'پ': 'p', |
|
|
'ژ': 'zh', |
|
|
'ک': 'k', |
|
|
'ی': 'y', |
|
|
|
|
|
// Arabic diactrics |
|
|
'َ': 'a', |
|
|
'ً': 'an', |
|
|
'ِ': 'e', |
|
|
'ٍ': 'en', |
|
|
'ُ': 'u', |
|
|
'ٌ': 'on', |
|
|
'ْ': '', |
|
|
|
|
|
// Arabic numbers |
|
|
'٠': '0', |
|
|
'١': '1', |
|
|
'٢': '2', |
|
|
'٣': '3', |
|
|
'٤': '4', |
|
|
'٥': '5', |
|
|
'٦': '6', |
|
|
'٧': '7', |
|
|
'٨': '8', |
|
|
'٩': '9', |
|
|
|
|
|
// Persian numbers |
|
|
'۰': '0', |
|
|
'۱': '1', |
|
|
'۲': '2', |
|
|
'۳': '3', |
|
|
'۴': '4', |
|
|
'۵': '5', |
|
|
'۶': '6', |
|
|
'۷': '7', |
|
|
'۸': '8', |
|
|
'۹': '9', |
|
|
|
|
|
// Burmese consonants |
|
|
'က': 'k', |
|
|
'ခ': 'kh', |
|
|
'ဂ': 'g', |
|
|
'ဃ': 'ga', |
|
|
'င': 'ng', |
|
|
'စ': 's', |
|
|
'ဆ': 'sa', |
|
|
'ဇ': 'z', |
|
|
'စျ': 'za', |
|
|
'ည': 'ny', |
|
|
'ဋ': 't', |
|
|
'ဌ': 'ta', |
|
|
'ဍ': 'd', |
|
|
'ဎ': 'da', |
|
|
'ဏ': 'na', |
|
|
'တ': 't', |
|
|
'ထ': 'ta', |
|
|
'ဒ': 'd', |
|
|
'ဓ': 'da', |
|
|
'န': 'n', |
|
|
'ပ': 'p', |
|
|
'ဖ': 'pa', |
|
|
'ဗ': 'b', |
|
|
'ဘ': 'ba', |
|
|
'မ': 'm', |
|
|
'ယ': 'y', |
|
|
'ရ': 'ya', |
|
|
'လ': 'l', |
|
|
'ဝ': 'w', |
|
|
'သ': 'th', |
|
|
'ဟ': 'h', |
|
|
'ဠ': 'la', |
|
|
'အ': 'a', |
|
|
// consonant character combos |
|
|
'ြ': 'y', |
|
|
'ျ': 'ya', |
|
|
'ွ': 'w', |
|
|
'ြွ': 'yw', |
|
|
'ျွ': 'ywa', |
|
|
'ှ': 'h', |
|
|
// independent vowels |
|
|
'ဧ': 'e', |
|
|
'၏': '-e', |
|
|
'ဣ': 'i', |
|
|
'ဤ': '-i', |
|
|
'ဉ': 'u', |
|
|
'ဦ': '-u', |
|
|
'ဩ': 'aw', |
|
|
'သြော': 'aw', |
|
|
'ဪ': 'aw', |
|
|
// numbers |
|
|
'၀': '0', |
|
|
'၁': '1', |
|
|
'၂': '2', |
|
|
'၃': '3', |
|
|
'၄': '4', |
|
|
'၅': '5', |
|
|
'၆': '6', |
|
|
'၇': '7', |
|
|
'၈': '8', |
|
|
'၉': '9', |
|
|
// virama and tone marks which are silent in transliteration |
|
|
'္': '', |
|
|
'့': '', |
|
|
'း': '', |
|
|
|
|
|
// Czech |
|
|
'č': 'c', |
|
|
'ď': 'd', |
|
|
'ě': 'e', |
|
|
'ň': 'n', |
|
|
'ř': 'r', |
|
|
'š': 's', |
|
|
'ť': 't', |
|
|
'ů': 'u', |
|
|
'ž': 'z', |
|
|
'Č': 'C', |
|
|
'Ď': 'D', |
|
|
'Ě': 'E', |
|
|
'Ň': 'N', |
|
|
'Ř': 'R', |
|
|
'Š': 'S', |
|
|
'Ť': 'T', |
|
|
'Ů': 'U', |
|
|
'Ž': 'Z', |
|
|
|
|
|
// Dhivehi |
|
|
'ހ': 'h', |
|
|
'ށ': 'sh', |
|
|
'ނ': 'n', |
|
|
'ރ': 'r', |
|
|
'ބ': 'b', |
|
|
'ޅ': 'lh', |
|
|
'ކ': 'k', |
|
|
'އ': 'a', |
|
|
'ވ': 'v', |
|
|
'މ': 'm', |
|
|
'ފ': 'f', |
|
|
'ދ': 'dh', |
|
|
'ތ': 'th', |
|
|
'ލ': 'l', |
|
|
'ގ': 'g', |
|
|
'ޏ': 'gn', |
|
|
'ސ': 's', |
|
|
'ޑ': 'd', |
|
|
'ޒ': 'z', |
|
|
'ޓ': 't', |
|
|
'ޔ': 'y', |
|
|
'ޕ': 'p', |
|
|
'ޖ': 'j', |
|
|
'ޗ': 'ch', |
|
|
'ޘ': 'tt', |
|
|
'ޙ': 'hh', |
|
|
'ޚ': 'kh', |
|
|
'ޛ': 'th', |
|
|
'ޜ': 'z', |
|
|
'ޝ': 'sh', |
|
|
'ޞ': 's', |
|
|
'ޟ': 'd', |
|
|
'ޠ': 't', |
|
|
'ޡ': 'z', |
|
|
'ޢ': 'a', |
|
|
'ޣ': 'gh', |
|
|
'ޤ': 'q', |
|
|
'ޥ': 'w', |
|
|
'ަ': 'a', |
|
|
'ާ': 'aa', |
|
|
'ި': 'i', |
|
|
'ީ': 'ee', |
|
|
'ު': 'u', |
|
|
'ޫ': 'oo', |
|
|
'ެ': 'e', |
|
|
'ޭ': 'ey', |
|
|
'ޮ': 'o', |
|
|
'ޯ': 'oa', |
|
|
'ް': '', |
|
|
|
|
|
// Georgian https://en.wikipedia.org/wiki/Romanization_of_Georgian |
|
|
// National system (2002) |
|
|
'ა': 'a', |
|
|
'ბ': 'b', |
|
|
'გ': 'g', |
|
|
'დ': 'd', |
|
|
'ე': 'e', |
|
|
'ვ': 'v', |
|
|
'ზ': 'z', |
|
|
'თ': 't', |
|
|
'ი': 'i', |
|
|
'კ': 'k', |
|
|
'ლ': 'l', |
|
|
'მ': 'm', |
|
|
'ნ': 'n', |
|
|
'ო': 'o', |
|
|
'პ': 'p', |
|
|
'ჟ': 'zh', |
|
|
'რ': 'r', |
|
|
'ს': 's', |
|
|
'ტ': 't', |
|
|
'უ': 'u', |
|
|
'ფ': 'p', |
|
|
'ქ': 'k', |
|
|
'ღ': 'gh', |
|
|
'ყ': 'q', |
|
|
'შ': 'sh', |
|
|
'ჩ': 'ch', |
|
|
'ც': 'ts', |
|
|
'ძ': 'dz', |
|
|
'წ': 'ts', |
|
|
'ჭ': 'ch', |
|
|
'ხ': 'kh', |
|
|
'ჯ': 'j', |
|
|
'ჰ': 'h', |
|
|
|
|
|
// Greek |
|
|
'α': 'a', |
|
|
'β': 'v', |
|
|
'γ': 'g', |
|
|
'δ': 'd', |
|
|
'ε': 'e', |
|
|
'ζ': 'z', |
|
|
'η': 'i', |
|
|
'θ': 'th', |
|
|
'ι': 'i', |
|
|
'κ': 'k', |
|
|
'λ': 'l', |
|
|
'μ': 'm', |
|
|
'ν': 'n', |
|
|
'ξ': 'ks', |
|
|
'ο': 'o', |
|
|
'π': 'p', |
|
|
'ρ': 'r', |
|
|
'σ': 's', |
|
|
'τ': 't', |
|
|
'υ': 'y', |
|
|
'φ': 'f', |
|
|
'χ': 'x', |
|
|
'ψ': 'ps', |
|
|
'ω': 'o', |
|
|
'ά': 'a', |
|
|
'έ': 'e', |
|
|
'ί': 'i', |
|
|
'ό': 'o', |
|
|
'ύ': 'y', |
|
|
'ή': 'i', |
|
|
'ώ': 'o', |
|
|
'ς': 's', |
|
|
'ϊ': 'i', |
|
|
'ΰ': 'y', |
|
|
'ϋ': 'y', |
|
|
'ΐ': 'i', |
|
|
'Α': 'A', |
|
|
'Β': 'B', |
|
|
'Γ': 'G', |
|
|
'Δ': 'D', |
|
|
'Ε': 'E', |
|
|
'Ζ': 'Z', |
|
|
'Η': 'I', |
|
|
'Θ': 'TH', |
|
|
'Ι': 'I', |
|
|
'Κ': 'K', |
|
|
'Λ': 'L', |
|
|
'Μ': 'M', |
|
|
'Ν': 'N', |
|
|
'Ξ': 'KS', |
|
|
'Ο': 'O', |
|
|
'Π': 'P', |
|
|
'Ρ': 'R', |
|
|
'Σ': 'S', |
|
|
'Τ': 'T', |
|
|
'Υ': 'Y', |
|
|
'Φ': 'F', |
|
|
'Χ': 'X', |
|
|
'Ψ': 'PS', |
|
|
'Ω': 'O', |
|
|
'Ά': 'A', |
|
|
'Έ': 'E', |
|
|
'Ί': 'I', |
|
|
'Ό': 'O', |
|
|
'Ύ': 'Y', |
|
|
'Ή': 'I', |
|
|
'Ώ': 'O', |
|
|
'Ϊ': 'I', |
|
|
'Ϋ': 'Y', |
|
|
|
|
|
// Latvian |
|
|
'ā': 'a', |
|
|
// 'č': 'c', // duplicate |
|
|
'ē': 'e', |
|
|
'ģ': 'g', |
|
|
'ī': 'i', |
|
|
'ķ': 'k', |
|
|
'ļ': 'l', |
|
|
'ņ': 'n', |
|
|
// 'š': 's', // duplicate |
|
|
'ū': 'u', |
|
|
// 'ž': 'z', // duplicate |
|
|
'Ā': 'A', |
|
|
// 'Č': 'C', // duplicate |
|
|
'Ē': 'E', |
|
|
'Ģ': 'G', |
|
|
'Ī': 'I', |
|
|
'Ķ': 'k', |
|
|
'Ļ': 'L', |
|
|
'Ņ': 'N', |
|
|
// 'Š': 'S', // duplicate |
|
|
'Ū': 'U', |
|
|
// 'Ž': 'Z', // duplicate |
|
|
|
|
|
// Macedonian |
|
|
'Ќ': 'Kj', |
|
|
'ќ': 'kj', |
|
|
'Љ': 'Lj', |
|
|
'љ': 'lj', |
|
|
'Њ': 'Nj', |
|
|
'њ': 'nj', |
|
|
'Тс': 'Ts', |
|
|
'тс': 'ts', |
|
|
|
|
|
// Polish |
|
|
'ą': 'a', |
|
|
'ć': 'c', |
|
|
'ę': 'e', |
|
|
'ł': 'l', |
|
|
'ń': 'n', |
|
|
// 'ó': 'o', // duplicate |
|
|
'ś': 's', |
|
|
'ź': 'z', |
|
|
'ż': 'z', |
|
|
'Ą': 'A', |
|
|
'Ć': 'C', |
|
|
'Ę': 'E', |
|
|
'Ł': 'L', |
|
|
'Ń': 'N', |
|
|
'Ś': 'S', |
|
|
'Ź': 'Z', |
|
|
'Ż': 'Z', |
|
|
|
|
|
// Ukranian |
|
|
'Є': 'Ye', |
|
|
'І': 'I', |
|
|
'Ї': 'Yi', |
|
|
'Ґ': 'G', |
|
|
'є': 'ye', |
|
|
'і': 'i', |
|
|
'ї': 'yi', |
|
|
'ґ': 'g', |
|
|
|
|
|
// Romanian |
|
|
'ă': 'a', |
|
|
'Ă': 'A', |
|
|
'ș': 's', |
|
|
'Ș': 'S', |
|
|
// 'ş': 's', // duplicate |
|
|
// 'Ş': 'S', // duplicate |
|
|
'ț': 't', |
|
|
'Ț': 'T', |
|
|
'ţ': 't', |
|
|
'Ţ': 'T', |
|
|
|
|
|
// Russian https://en.wikipedia.org/wiki/Romanization_of_Russian |
|
|
// ICAO |
|
|
|
|
|
'а': 'a', |
|
|
'б': 'b', |
|
|
'в': 'v', |
|
|
'г': 'g', |
|
|
'д': 'd', |
|
|
'е': 'e', |
|
|
'ё': 'yo', |
|
|
'ж': 'zh', |
|
|
'з': 'z', |
|
|
'и': 'i', |
|
|
'й': 'i', |
|
|
'к': 'k', |
|
|
'л': 'l', |
|
|
'м': 'm', |
|
|
'н': 'n', |
|
|
'о': 'o', |
|
|
'п': 'p', |
|
|
'р': 'r', |
|
|
'с': 's', |
|
|
'т': 't', |
|
|
'у': 'u', |
|
|
'ф': 'f', |
|
|
'х': 'kh', |
|
|
'ц': 'c', |
|
|
'ч': 'ch', |
|
|
'ш': 'sh', |
|
|
'щ': 'sh', |
|
|
'ъ': '', |
|
|
'ы': 'y', |
|
|
'ь': '', |
|
|
'э': 'e', |
|
|
'ю': 'yu', |
|
|
'я': 'ya', |
|
|
'А': 'A', |
|
|
'Б': 'B', |
|
|
'В': 'V', |
|
|
'Г': 'G', |
|
|
'Д': 'D', |
|
|
'Е': 'E', |
|
|
'Ё': 'Yo', |
|
|
'Ж': 'Zh', |
|
|
'З': 'Z', |
|
|
'И': 'I', |
|
|
'Й': 'I', |
|
|
'К': 'K', |
|
|
'Л': 'L', |
|
|
'М': 'M', |
|
|
'Н': 'N', |
|
|
'О': 'O', |
|
|
'П': 'P', |
|
|
'Р': 'R', |
|
|
'С': 'S', |
|
|
'Т': 'T', |
|
|
'У': 'U', |
|
|
'Ф': 'F', |
|
|
'Х': 'Kh', |
|
|
'Ц': 'C', |
|
|
'Ч': 'Ch', |
|
|
'Ш': 'Sh', |
|
|
'Щ': 'Sh', |
|
|
'Ъ': '', |
|
|
'Ы': 'Y', |
|
|
'Ь': '', |
|
|
'Э': 'E', |
|
|
'Ю': 'Yu', |
|
|
'Я': 'Ya', |
|
|
|
|
|
// Serbian |
|
|
'ђ': 'dj', |
|
|
'ј': 'j', |
|
|
// 'љ': 'lj', // duplicate |
|
|
// 'њ': 'nj', // duplicate |
|
|
'ћ': 'c', |
|
|
'џ': 'dz', |
|
|
'Ђ': 'Dj', |
|
|
'Ј': 'j', |
|
|
// 'Љ': 'Lj', // duplicate |
|
|
// 'Њ': 'Nj', // duplicate |
|
|
'Ћ': 'C', |
|
|
'Џ': 'Dz', |
|
|
|
|
|
// Slovak |
|
|
'ľ': 'l', |
|
|
'ĺ': 'l', |
|
|
'ŕ': 'r', |
|
|
'Ľ': 'L', |
|
|
'Ĺ': 'L', |
|
|
'Ŕ': 'R', |
|
|
|
|
|
// Turkish |
|
|
'ş': 's', |
|
|
'Ş': 'S', |
|
|
'ı': 'i', |
|
|
'İ': 'I', |
|
|
// 'ç': 'c', // duplicate |
|
|
// 'Ç': 'C', // duplicate |
|
|
// 'ü': 'u', // duplicate, see langCharMap |
|
|
// 'Ü': 'U', // duplicate, see langCharMap |
|
|
// 'ö': 'o', // duplicate, see langCharMap |
|
|
// 'Ö': 'O', // duplicate, see langCharMap |
|
|
'ğ': 'g', |
|
|
'Ğ': 'G', |
|
|
|
|
|
// Vietnamese |
|
|
'ả': 'a', |
|
|
'Ả': 'A', |
|
|
'ẳ': 'a', |
|
|
'Ẳ': 'A', |
|
|
'ẩ': 'a', |
|
|
'Ẩ': 'A', |
|
|
'đ': 'd', |
|
|
'Đ': 'D', |
|
|
'ẹ': 'e', |
|
|
'Ẹ': 'E', |
|
|
'ẽ': 'e', |
|
|
'Ẽ': 'E', |
|
|
'ẻ': 'e', |
|
|
'Ẻ': 'E', |
|
|
'ế': 'e', |
|
|
'Ế': 'E', |
|
|
'ề': 'e', |
|
|
'Ề': 'E', |
|
|
'ệ': 'e', |
|
|
'Ệ': 'E', |
|
|
'ễ': 'e', |
|
|
'Ễ': 'E', |
|
|
'ể': 'e', |
|
|
'Ể': 'E', |
|
|
'ỏ': 'o', |
|
|
'ọ': 'o', |
|
|
'Ọ': 'o', |
|
|
'ố': 'o', |
|
|
'Ố': 'O', |
|
|
'ồ': 'o', |
|
|
'Ồ': 'O', |
|
|
'ổ': 'o', |
|
|
'Ổ': 'O', |
|
|
'ộ': 'o', |
|
|
'Ộ': 'O', |
|
|
'ỗ': 'o', |
|
|
'Ỗ': 'O', |
|
|
'ơ': 'o', |
|
|
'Ơ': 'O', |
|
|
'ớ': 'o', |
|
|
'Ớ': 'O', |
|
|
'ờ': 'o', |
|
|
'Ờ': 'O', |
|
|
'ợ': 'o', |
|
|
'Ợ': 'O', |
|
|
'ỡ': 'o', |
|
|
'Ỡ': 'O', |
|
|
'Ở': 'o', |
|
|
'ở': 'o', |
|
|
'ị': 'i', |
|
|
'Ị': 'I', |
|
|
'ĩ': 'i', |
|
|
'Ĩ': 'I', |
|
|
'ỉ': 'i', |
|
|
'Ỉ': 'i', |
|
|
'ủ': 'u', |
|
|
'Ủ': 'U', |
|
|
'ụ': 'u', |
|
|
'Ụ': 'U', |
|
|
'ũ': 'u', |
|
|
'Ũ': 'U', |
|
|
'ư': 'u', |
|
|
'Ư': 'U', |
|
|
'ứ': 'u', |
|
|
'Ứ': 'U', |
|
|
'ừ': 'u', |
|
|
'Ừ': 'U', |
|
|
'ự': 'u', |
|
|
'Ự': 'U', |
|
|
'ữ': 'u', |
|
|
'Ữ': 'U', |
|
|
'ử': 'u', |
|
|
'Ử': 'ư', |
|
|
'ỷ': 'y', |
|
|
'Ỷ': 'y', |
|
|
'ỳ': 'y', |
|
|
'Ỳ': 'Y', |
|
|
'ỵ': 'y', |
|
|
'Ỵ': 'Y', |
|
|
'ỹ': 'y', |
|
|
'Ỹ': 'Y', |
|
|
'ạ': 'a', |
|
|
'Ạ': 'A', |
|
|
'ấ': 'a', |
|
|
'Ấ': 'A', |
|
|
'ầ': 'a', |
|
|
'Ầ': 'A', |
|
|
'ậ': 'a', |
|
|
'Ậ': 'A', |
|
|
'ẫ': 'a', |
|
|
'Ẫ': 'A', |
|
|
// 'ă': 'a', // duplicate |
|
|
// 'Ă': 'A', // duplicate |
|
|
'ắ': 'a', |
|
|
'Ắ': 'A', |
|
|
'ằ': 'a', |
|
|
'Ằ': 'A', |
|
|
'ặ': 'a', |
|
|
'Ặ': 'A', |
|
|
'ẵ': 'a', |
|
|
'Ẵ': 'A', |
|
|
"⓪": "0", |
|
|
"①": "1", |
|
|
"②": "2", |
|
|
"③": "3", |
|
|
"④": "4", |
|
|
"⑤": "5", |
|
|
"⑥": "6", |
|
|
"⑦": "7", |
|
|
"⑧": "8", |
|
|
"⑨": "9", |
|
|
"⑩": "10", |
|
|
"⑪": "11", |
|
|
"⑫": "12", |
|
|
"⑬": "13", |
|
|
"⑭": "14", |
|
|
"⑮": "15", |
|
|
"⑯": "16", |
|
|
"⑰": "17", |
|
|
"⑱": "18", |
|
|
"⑲": "18", |
|
|
"⑳": "18", |
|
|
|
|
|
"⓵": "1", |
|
|
"⓶": "2", |
|
|
"⓷": "3", |
|
|
"⓸": "4", |
|
|
"⓹": "5", |
|
|
"⓺": "6", |
|
|
"⓻": "7", |
|
|
"⓼": "8", |
|
|
"⓽": "9", |
|
|
"⓾": "10", |
|
|
|
|
|
"⓿": "0", |
|
|
"⓫": "11", |
|
|
"⓬": "12", |
|
|
"⓭": "13", |
|
|
"⓮": "14", |
|
|
"⓯": "15", |
|
|
"⓰": "16", |
|
|
"⓱": "17", |
|
|
"⓲": "18", |
|
|
"⓳": "19", |
|
|
"⓴": "20", |
|
|
|
|
|
"Ⓐ": "A", |
|
|
"Ⓑ": "B", |
|
|
"Ⓒ": "C", |
|
|
"Ⓓ": "D", |
|
|
"Ⓔ": "E", |
|
|
"Ⓕ": "F", |
|
|
"Ⓖ": "G", |
|
|
"Ⓗ": "H", |
|
|
"Ⓘ": "I", |
|
|
"Ⓙ": "J", |
|
|
"Ⓚ": "K", |
|
|
"Ⓛ": "L", |
|
|
"Ⓜ": "M", |
|
|
"Ⓝ": "N", |
|
|
"Ⓞ": "O", |
|
|
"Ⓟ": "P", |
|
|
"Ⓠ": "Q", |
|
|
"Ⓡ": "R", |
|
|
"Ⓢ": "S", |
|
|
"Ⓣ": "T", |
|
|
"Ⓤ": "U", |
|
|
"Ⓥ": "V", |
|
|
"Ⓦ": "W", |
|
|
"Ⓧ": "X", |
|
|
"Ⓨ": "Y", |
|
|
"Ⓩ": "Z", |
|
|
|
|
|
"ⓐ": "a", |
|
|
"ⓑ": "b", |
|
|
"ⓒ": "c", |
|
|
"ⓓ": "d", |
|
|
"ⓔ": "e", |
|
|
"ⓕ": "f", |
|
|
"ⓖ": "g", |
|
|
"ⓗ": "h", |
|
|
"ⓘ": "i", |
|
|
"ⓙ": "j", |
|
|
"ⓚ": "k", |
|
|
"ⓛ": "l", |
|
|
"ⓜ": "m", |
|
|
"ⓝ": "n", |
|
|
"ⓞ": "o", |
|
|
"ⓟ": "p", |
|
|
"ⓠ": "q", |
|
|
"ⓡ": "r", |
|
|
"ⓢ": "s", |
|
|
"ⓣ": "t", |
|
|
"ⓤ": "u", |
|
|
"ⓦ": "v", |
|
|
"ⓥ": "w", |
|
|
"ⓧ": "x", |
|
|
"ⓨ": "y", |
|
|
"ⓩ": "z", |
|
|
|
|
|
// symbols |
|
|
'“': '"', |
|
|
'”': '"', |
|
|
'‘': "'", |
|
|
'’': "'", |
|
|
'∂': 'd', |
|
|
'ƒ': 'f', |
|
|
'™': '(TM)', |
|
|
'©': '(C)', |
|
|
'œ': 'oe', |
|
|
'Œ': 'OE', |
|
|
'®': '(R)', |
|
|
'†': '+', |
|
|
'℠': '(SM)', |
|
|
'…': '...', |
|
|
'˚': 'o', |
|
|
'º': 'o', |
|
|
'ª': 'a', |
|
|
'•': '*', |
|
|
'၊': ',', |
|
|
'။': '.', |
|
|
|
|
|
// currency |
|
|
'$': 'USD', |
|
|
'€': 'EUR', |
|
|
'₢': 'BRN', |
|
|
'₣': 'FRF', |
|
|
'£': 'GBP', |
|
|
'₤': 'ITL', |
|
|
'₦': 'NGN', |
|
|
'₧': 'ESP', |
|
|
'₩': 'KRW', |
|
|
'₪': 'ILS', |
|
|
'₫': 'VND', |
|
|
'₭': 'LAK', |
|
|
'₮': 'MNT', |
|
|
'₯': 'GRD', |
|
|
'₱': 'ARS', |
|
|
'₲': 'PYG', |
|
|
'₳': 'ARA', |
|
|
'₴': 'UAH', |
|
|
'₵': 'GHS', |
|
|
'¢': 'cent', |
|
|
'¥': 'CNY', |
|
|
'元': 'CNY', |
|
|
'円': 'YEN', |
|
|
'﷼': 'IRR', |
|
|
'₠': 'EWE', |
|
|
'฿': 'THB', |
|
|
'₨': 'INR', |
|
|
'₹': 'INR', |
|
|
'₰': 'PF', |
|
|
'₺': 'TRY', |
|
|
'؋': 'AFN', |
|
|
'₼': 'AZN', |
|
|
'лв': 'BGN', |
|
|
'៛': 'KHR', |
|
|
'₡': 'CRC', |
|
|
'₸': 'KZT', |
|
|
'ден': 'MKD', |
|
|
'zł': 'PLN', |
|
|
'₽': 'RUB', |
|
|
'₾': 'GEL' |
|
|
|
|
|
}; |
|
|
|
|
|
/** |
|
|
* special look ahead character array |
|
|
* These characters form with consonants to become 'single'/consonant combo |
|
|
* @type [Array] |
|
|
*/ |
|
|
var lookAheadCharArray = [ |
|
|
// burmese |
|
|
'်', |
|
|
|
|
|
// Dhivehi |
|
|
'ް' |
|
|
]; |
|
|
|
|
|
/** |
|
|
* diatricMap for languages where transliteration changes entirely as more diatrics are added |
|
|
* @type {Object} |
|
|
*/ |
|
|
var diatricMap = { |
|
|
// Burmese |
|
|
// dependent vowels |
|
|
'ာ': 'a', |
|
|
'ါ': 'a', |
|
|
'ေ': 'e', |
|
|
'ဲ': 'e', |
|
|
'ိ': 'i', |
|
|
'ီ': 'i', |
|
|
'ို': 'o', |
|
|
'ု': 'u', |
|
|
'ူ': 'u', |
|
|
'ေါင်': 'aung', |
|
|
'ော': 'aw', |
|
|
'ော်': 'aw', |
|
|
'ေါ': 'aw', |
|
|
'ေါ်': 'aw', |
|
|
'်': '်', // this is special case but the character will be converted to latin in the code |
|
|
'က်': 'et', |
|
|
'ိုက်': 'aik', |
|
|
'ောက်': 'auk', |
|
|
'င်': 'in', |
|
|
'ိုင်': 'aing', |
|
|
'ောင်': 'aung', |
|
|
'စ်': 'it', |
|
|
'ည်': 'i', |
|
|
'တ်': 'at', |
|
|
'ိတ်': 'eik', |
|
|
'ုတ်': 'ok', |
|
|
'ွတ်': 'ut', |
|
|
'ေတ်': 'it', |
|
|
'ဒ်': 'd', |
|
|
'ိုဒ်': 'ok', |
|
|
'ုဒ်': 'ait', |
|
|
'န်': 'an', |
|
|
'ာန်': 'an', |
|
|
'ိန်': 'ein', |
|
|
'ုန်': 'on', |
|
|
'ွန်': 'un', |
|
|
'ပ်': 'at', |
|
|
'ိပ်': 'eik', |
|
|
'ုပ်': 'ok', |
|
|
'ွပ်': 'ut', |
|
|
'န်ုပ်': 'nub', |
|
|
'မ်': 'an', |
|
|
'ိမ်': 'ein', |
|
|
'ုမ်': 'on', |
|
|
'ွမ်': 'un', |
|
|
'ယ်': 'e', |
|
|
'ိုလ်': 'ol', |
|
|
'ဉ်': 'in', |
|
|
'ံ': 'an', |
|
|
'ိံ': 'ein', |
|
|
'ုံ': 'on', |
|
|
|
|
|
// Dhivehi |
|
|
'ައް': 'ah', |
|
|
'ަށް': 'ah' |
|
|
}; |
|
|
|
|
|
/** |
|
|
* langCharMap language specific characters translations |
|
|
* @type {Object} |
|
|
*/ |
|
|
var langCharMap = { |
|
|
'en': {}, // default language |
|
|
|
|
|
'az': { // Azerbaijani |
|
|
'ç': 'c', |
|
|
'ə': 'e', |
|
|
'ğ': 'g', |
|
|
'ı': 'i', |
|
|
'ö': 'o', |
|
|
'ş': 's', |
|
|
'ü': 'u', |
|
|
'Ç': 'C', |
|
|
'Ə': 'E', |
|
|
'Ğ': 'G', |
|
|
'İ': 'I', |
|
|
'Ö': 'O', |
|
|
'Ş': 'S', |
|
|
'Ü': 'U' |
|
|
}, |
|
|
|
|
|
'cs': { // Czech |
|
|
'č': 'c', |
|
|
'ď': 'd', |
|
|
'ě': 'e', |
|
|
'ň': 'n', |
|
|
'ř': 'r', |
|
|
'š': 's', |
|
|
'ť': 't', |
|
|
'ů': 'u', |
|
|
'ž': 'z', |
|
|
'Č': 'C', |
|
|
'Ď': 'D', |
|
|
'Ě': 'E', |
|
|
'Ň': 'N', |
|
|
'Ř': 'R', |
|
|
'Š': 'S', |
|
|
'Ť': 'T', |
|
|
'Ů': 'U', |
|
|
'Ž': 'Z' |
|
|
}, |
|
|
|
|
|
'fi': { // Finnish |
|
|
// 'å': 'a', duplicate see charMap/latin |
|
|
// 'Å': 'A', duplicate see charMap/latin |
|
|
'ä': 'a', // ok |
|
|
'Ä': 'A', // ok |
|
|
'ö': 'o', // ok |
|
|
'Ö': 'O' // ok |
|
|
}, |
|
|
|
|
|
'hu': { // Hungarian |
|
|
'ä': 'a', // ok |
|
|
'Ä': 'A', // ok |
|
|
// 'á': 'a', duplicate see charMap/latin |
|
|
// 'Á': 'A', duplicate see charMap/latin |
|
|
'ö': 'o', // ok |
|
|
'Ö': 'O', // ok |
|
|
// 'ő': 'o', duplicate see charMap/latin |
|
|
// 'Ő': 'O', duplicate see charMap/latin |
|
|
'ü': 'u', |
|
|
'Ü': 'U', |
|
|
'ű': 'u', |
|
|
'Ű': 'U' |
|
|
}, |
|
|
|
|
|
'lt': { // Lithuanian |
|
|
'ą': 'a', |
|
|
'č': 'c', |
|
|
'ę': 'e', |
|
|
'ė': 'e', |
|
|
'į': 'i', |
|
|
'š': 's', |
|
|
'ų': 'u', |
|
|
'ū': 'u', |
|
|
'ž': 'z', |
|
|
'Ą': 'A', |
|
|
'Č': 'C', |
|
|
'Ę': 'E', |
|
|
'Ė': 'E', |
|
|
'Į': 'I', |
|
|
'Š': 'S', |
|
|
'Ų': 'U', |
|
|
'Ū': 'U' |
|
|
}, |
|
|
|
|
|
'lv': { // Latvian |
|
|
'ā': 'a', |
|
|
'č': 'c', |
|
|
'ē': 'e', |
|
|
'ģ': 'g', |
|
|
'ī': 'i', |
|
|
'ķ': 'k', |
|
|
'ļ': 'l', |
|
|
'ņ': 'n', |
|
|
'š': 's', |
|
|
'ū': 'u', |
|
|
'ž': 'z', |
|
|
'Ā': 'A', |
|
|
'Č': 'C', |
|
|
'Ē': 'E', |
|
|
'Ģ': 'G', |
|
|
'Ī': 'i', |
|
|
'Ķ': 'k', |
|
|
'Ļ': 'L', |
|
|
'Ņ': 'N', |
|
|
'Š': 'S', |
|
|
'Ū': 'u', |
|
|
'Ž': 'Z' |
|
|
}, |
|
|
|
|
|
'pl': { // Polish |
|
|
'ą': 'a', |
|
|
'ć': 'c', |
|
|
'ę': 'e', |
|
|
'ł': 'l', |
|
|
'ń': 'n', |
|
|
'ó': 'o', |
|
|
'ś': 's', |
|
|
'ź': 'z', |
|
|
'ż': 'z', |
|
|
'Ą': 'A', |
|
|
'Ć': 'C', |
|
|
'Ę': 'e', |
|
|
'Ł': 'L', |
|
|
'Ń': 'N', |
|
|
'Ó': 'O', |
|
|
'Ś': 'S', |
|
|
'Ź': 'Z', |
|
|
'Ż': 'Z' |
|
|
}, |
|
|
|
|
|
'sv': { // Swedish |
|
|
// 'å': 'a', duplicate see charMap/latin |
|
|
// 'Å': 'A', duplicate see charMap/latin |
|
|
'ä': 'a', // ok |
|
|
'Ä': 'A', // ok |
|
|
'ö': 'o', // ok |
|
|
'Ö': 'O' // ok |
|
|
}, |
|
|
|
|
|
'sk': { // Slovak |
|
|
'ä': 'a', |
|
|
'Ä': 'A' |
|
|
}, |
|
|
|
|
|
'sr': { // Serbian |
|
|
'љ': 'lj', |
|
|
'њ': 'nj', |
|
|
'Љ': 'Lj', |
|
|
'Њ': 'Nj', |
|
|
'đ': 'dj', |
|
|
'Đ': 'Dj' |
|
|
}, |
|
|
|
|
|
'tr': { // Turkish |
|
|
'Ü': 'U', |
|
|
'Ö': 'O', |
|
|
'ü': 'u', |
|
|
'ö': 'o' |
|
|
} |
|
|
}; |
|
|
|
|
|
/** |
|
|
* symbolMap language specific symbol translations |
|
|
* translations must be transliterated already |
|
|
* @type {Object} |
|
|
*/ |
|
|
var symbolMap = { |
|
|
'ar': { |
|
|
'∆': 'delta', |
|
|
'∞': 'la-nihaya', |
|
|
'♥': 'hob', |
|
|
'&': 'wa', |
|
|
'|': 'aw', |
|
|
'<': 'aqal-men', |
|
|
'>': 'akbar-men', |
|
|
'∑': 'majmou', |
|
|
'¤': 'omla' |
|
|
}, |
|
|
|
|
|
'az': {}, |
|
|
|
|
|
'ca': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinit', |
|
|
'♥': 'amor', |
|
|
'&': 'i', |
|
|
'|': 'o', |
|
|
'<': 'menys que', |
|
|
'>': 'mes que', |
|
|
'∑': 'suma dels', |
|
|
'¤': 'moneda' |
|
|
}, |
|
|
|
|
|
'cs': { |
|
|
'∆': 'delta', |
|
|
'∞': 'nekonecno', |
|
|
'♥': 'laska', |
|
|
'&': 'a', |
|
|
'|': 'nebo', |
|
|
'<': 'mensi nez', |
|
|
'>': 'vetsi nez', |
|
|
'∑': 'soucet', |
|
|
'¤': 'mena' |
|
|
}, |
|
|
|
|
|
'de': { |
|
|
'∆': 'delta', |
|
|
'∞': 'unendlich', |
|
|
'♥': 'Liebe', |
|
|
'&': 'und', |
|
|
'|': 'oder', |
|
|
'<': 'kleiner als', |
|
|
'>': 'groesser als', |
|
|
'∑': 'Summe von', |
|
|
'¤': 'Waehrung' |
|
|
}, |
|
|
|
|
|
'dv': { |
|
|
'∆': 'delta', |
|
|
'∞': 'kolunulaa', |
|
|
'♥': 'loabi', |
|
|
'&': 'aai', |
|
|
'|': 'noonee', |
|
|
'<': 'ah vure kuda', |
|
|
'>': 'ah vure bodu', |
|
|
'∑': 'jumula', |
|
|
'¤': 'faisaa' |
|
|
}, |
|
|
|
|
|
'en': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinity', |
|
|
'♥': 'love', |
|
|
'&': 'and', |
|
|
'|': 'or', |
|
|
'<': 'less than', |
|
|
'>': 'greater than', |
|
|
'∑': 'sum', |
|
|
'¤': 'currency' |
|
|
}, |
|
|
|
|
|
'es': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinito', |
|
|
'♥': 'amor', |
|
|
'&': 'y', |
|
|
'|': 'u', |
|
|
'<': 'menos que', |
|
|
'>': 'mas que', |
|
|
'∑': 'suma de los', |
|
|
'¤': 'moneda' |
|
|
}, |
|
|
|
|
|
'fa': { |
|
|
'∆': 'delta', |
|
|
'∞': 'bi-nahayat', |
|
|
'♥': 'eshgh', |
|
|
'&': 'va', |
|
|
'|': 'ya', |
|
|
'<': 'kamtar-az', |
|
|
'>': 'bishtar-az', |
|
|
'∑': 'majmooe', |
|
|
'¤': 'vahed' |
|
|
}, |
|
|
|
|
|
'fi': { |
|
|
'∆': 'delta', |
|
|
'∞': 'aarettomyys', |
|
|
'♥': 'rakkaus', |
|
|
'&': 'ja', |
|
|
'|': 'tai', |
|
|
'<': 'pienempi kuin', |
|
|
'>': 'suurempi kuin', |
|
|
'∑': 'summa', |
|
|
'¤': 'valuutta' |
|
|
}, |
|
|
|
|
|
'fr': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infiniment', |
|
|
'♥': 'Amour', |
|
|
'&': 'et', |
|
|
'|': 'ou', |
|
|
'<': 'moins que', |
|
|
'>': 'superieure a', |
|
|
'∑': 'somme des', |
|
|
'¤': 'monnaie' |
|
|
}, |
|
|
|
|
|
'ge': { |
|
|
'∆': 'delta', |
|
|
'∞': 'usasruloba', |
|
|
'♥': 'siqvaruli', |
|
|
'&': 'da', |
|
|
'|': 'an', |
|
|
'<': 'naklebi', |
|
|
'>': 'meti', |
|
|
'∑': 'jami', |
|
|
'¤': 'valuta' |
|
|
}, |
|
|
|
|
|
'gr': {}, |
|
|
|
|
|
'hu': { |
|
|
'∆': 'delta', |
|
|
'∞': 'vegtelen', |
|
|
'♥': 'szerelem', |
|
|
'&': 'es', |
|
|
'|': 'vagy', |
|
|
'<': 'kisebb mint', |
|
|
'>': 'nagyobb mint', |
|
|
'∑': 'szumma', |
|
|
'¤': 'penznem' |
|
|
}, |
|
|
|
|
|
'it': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinito', |
|
|
'♥': 'amore', |
|
|
'&': 'e', |
|
|
'|': 'o', |
|
|
'<': 'minore di', |
|
|
'>': 'maggiore di', |
|
|
'∑': 'somma', |
|
|
'¤': 'moneta' |
|
|
}, |
|
|
|
|
|
'lt': { |
|
|
'∆': 'delta', |
|
|
'∞': 'begalybe', |
|
|
'♥': 'meile', |
|
|
'&': 'ir', |
|
|
'|': 'ar', |
|
|
'<': 'maziau nei', |
|
|
'>': 'daugiau nei', |
|
|
'∑': 'suma', |
|
|
'¤': 'valiuta' |
|
|
}, |
|
|
|
|
|
'lv': { |
|
|
'∆': 'delta', |
|
|
'∞': 'bezgaliba', |
|
|
'♥': 'milestiba', |
|
|
'&': 'un', |
|
|
'|': 'vai', |
|
|
'<': 'mazak neka', |
|
|
'>': 'lielaks neka', |
|
|
'∑': 'summa', |
|
|
'¤': 'valuta' |
|
|
}, |
|
|
|
|
|
'my': { |
|
|
'∆': 'kwahkhyaet', |
|
|
'∞': 'asaonasme', |
|
|
'♥': 'akhyait', |
|
|
'&': 'nhin', |
|
|
'|': 'tho', |
|
|
'<': 'ngethaw', |
|
|
'>': 'kyithaw', |
|
|
'∑': 'paungld', |
|
|
'¤': 'ngwekye' |
|
|
}, |
|
|
|
|
|
'mk': {}, |
|
|
|
|
|
'nl': { |
|
|
'∆': 'delta', |
|
|
'∞': 'oneindig', |
|
|
'♥': 'liefde', |
|
|
'&': 'en', |
|
|
'|': 'of', |
|
|
'<': 'kleiner dan', |
|
|
'>': 'groter dan', |
|
|
'∑': 'som', |
|
|
'¤': 'valuta' |
|
|
}, |
|
|
|
|
|
'pl': { |
|
|
'∆': 'delta', |
|
|
'∞': 'nieskonczonosc', |
|
|
'♥': 'milosc', |
|
|
'&': 'i', |
|
|
'|': 'lub', |
|
|
'<': 'mniejsze niz', |
|
|
'>': 'wieksze niz', |
|
|
'∑': 'suma', |
|
|
'¤': 'waluta' |
|
|
}, |
|
|
|
|
|
'pt': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinito', |
|
|
'♥': 'amor', |
|
|
'&': 'e', |
|
|
'|': 'ou', |
|
|
'<': 'menor que', |
|
|
'>': 'maior que', |
|
|
'∑': 'soma', |
|
|
'¤': 'moeda' |
|
|
}, |
|
|
|
|
|
'ro': { |
|
|
'∆': 'delta', |
|
|
'∞': 'infinit', |
|
|
'♥': 'dragoste', |
|
|
'&': 'si', |
|
|
'|': 'sau', |
|
|
'<': 'mai mic ca', |
|
|
'>': 'mai mare ca', |
|
|
'∑': 'suma', |
|
|
'¤': 'valuta' |
|
|
}, |
|
|
|
|
|
'ru': { |
|
|
'∆': 'delta', |
|
|
'∞': 'beskonechno', |
|
|
'♥': 'lubov', |
|
|
'&': 'i', |
|
|
'|': 'ili', |
|
|
'<': 'menshe', |
|
|
'>': 'bolshe', |
|
|
'∑': 'summa', |
|
|
'¤': 'valjuta' |
|
|
}, |
|
|
|
|
|
'sk': { |
|
|
'∆': 'delta', |
|
|
'∞': 'nekonecno', |
|
|
'♥': 'laska', |
|
|
'&': 'a', |
|
|
'|': 'alebo', |
|
|
'<': 'menej ako', |
|
|
'>': 'viac ako', |
|
|
'∑': 'sucet', |
|
|
'¤': 'mena' |
|
|
}, |
|
|
|
|
|
'sr': {}, |
|
|
|
|
|
'tr': { |
|
|
'∆': 'delta', |
|
|
'∞': 'sonsuzluk', |
|
|
'♥': 'ask', |
|
|
'&': 've', |
|
|
'|': 'veya', |
|
|
'<': 'kucuktur', |
|
|
'>': 'buyuktur', |
|
|
'∑': 'toplam', |
|
|
'¤': 'para birimi' |
|
|
}, |
|
|
|
|
|
'uk': { |
|
|
'∆': 'delta', |
|
|
'∞': 'bezkinechnist', |
|
|
'♥': 'lubov', |
|
|
'&': 'i', |
|
|
'|': 'abo', |
|
|
'<': 'menshe', |
|
|
'>': 'bilshe', |
|
|
'∑': 'suma', |
|
|
'¤': 'valjuta' |
|
|
}, |
|
|
|
|
|
'vn': { |
|
|
'∆': 'delta', |
|
|
'∞': 'vo cuc', |
|
|
'♥': 'yeu', |
|
|
'&': 'va', |
|
|
'|': 'hoac', |
|
|
'<': 'nho hon', |
|
|
'>': 'lon hon', |
|
|
'∑': 'tong', |
|
|
'¤': 'tien te' |
|
|
} |
|
|
}; |
|
|
|
|
|
var uricChars = [';', '?', ':', '@', '&', '=', '+', '$', ',', '/'].join(''); |
|
|
|
|
|
var uricNoSlashChars = [';', '?', ':', '@', '&', '=', '+', '$', ','].join(''); |
|
|
|
|
|
var markChars = ['.', '!', '~', '*', "'", '(', ')'].join(''); |
|
|
|
|
|
/** |
|
|
* getSlug |
|
|
* @param {string} input input string |
|
|
* @param {object|string} opts config object or separator string/char |
|
|
* @api public |
|
|
* @return {string} sluggified string |
|
|
*/ |
|
|
var getSlug = function getSlug(input, opts) { |
|
|
var separator = '-'; |
|
|
var result = ''; |
|
|
var diatricString = ''; |
|
|
var convertSymbols = true; |
|
|
var customReplacements = {}; |
|
|
var maintainCase; |
|
|
var titleCase; |
|
|
var truncate; |
|
|
var uricFlag; |
|
|
var uricNoSlashFlag; |
|
|
var markFlag; |
|
|
var symbol; |
|
|
var langChar; |
|
|
var lucky; |
|
|
var i; |
|
|
var ch; |
|
|
var l; |
|
|
var lastCharWasSymbol; |
|
|
var lastCharWasDiatric; |
|
|
var allowedChars = ''; |
|
|
|
|
|
if (typeof input !== 'string') { |
|
|
return ''; |
|
|
} |
|
|
|
|
|
if (typeof opts === 'string') { |
|
|
separator = opts; |
|
|
} |
|
|
|
|
|
symbol = symbolMap.en; |
|
|
langChar = langCharMap.en; |
|
|
|
|
|
if (typeof opts === 'object') { |
|
|
maintainCase = opts.maintainCase || false; |
|
|
customReplacements = (opts.custom && typeof opts.custom === 'object') ? opts.custom : customReplacements; |
|
|
truncate = (+opts.truncate > 1 && opts.truncate) || false; |
|
|
uricFlag = opts.uric || false; |
|
|
uricNoSlashFlag = opts.uricNoSlash || false; |
|
|
markFlag = opts.mark || false; |
|
|
convertSymbols = (opts.symbols === false || opts.lang === false) ? false : true; |
|
|
separator = opts.separator || separator; |
|
|
|
|
|
if (uricFlag) { |
|
|
allowedChars += uricChars; |
|
|
} |
|
|
|
|
|
if (uricNoSlashFlag) { |
|
|
allowedChars += uricNoSlashChars; |
|
|
} |
|
|
|
|
|
if (markFlag) { |
|
|
allowedChars += markChars; |
|
|
} |
|
|
|
|
|
symbol = (opts.lang && symbolMap[opts.lang] && convertSymbols) ? |
|
|
symbolMap[opts.lang] : (convertSymbols ? symbolMap.en : {}); |
|
|
|
|
|
langChar = (opts.lang && langCharMap[opts.lang]) ? |
|
|
langCharMap[opts.lang] : |
|
|
opts.lang === false || opts.lang === true ? {} : langCharMap.en; |
|
|
|
|
|
// if titleCase config is an Array, rewrite to object format |
|
|
if (opts.titleCase && typeof opts.titleCase.length === 'number' && Array.prototype.toString.call(opts.titleCase)) { |
|
|
opts.titleCase.forEach(function (v) { |
|
|
customReplacements[v + ''] = v + ''; |
|
|
}); |
|
|
|
|
|
titleCase = true; |
|
|
} else { |
|
|
titleCase = !!opts.titleCase; |
|
|
} |
|
|
|
|
|
// if custom config is an Array, rewrite to object format |
|
|
if (opts.custom && typeof opts.custom.length === 'number' && Array.prototype.toString.call(opts.custom)) { |
|
|
opts.custom.forEach(function (v) { |
|
|
customReplacements[v + ''] = v + ''; |
|
|
}); |
|
|
} |
|
|
|
|
|
// custom replacements |
|
|
Object.keys(customReplacements).forEach(function (v) { |
|
|
var r; |
|
|
|
|
|
if (v.length > 1) { |
|
|
r = new RegExp('\\b' + escapeChars(v) + '\\b', 'gi'); |
|
|
} else { |
|
|
r = new RegExp(escapeChars(v), 'gi'); |
|
|
} |
|
|
|
|
|
input = input.replace(r, customReplacements[v]); |
|
|
}); |
|
|
|
|
|
// add all custom replacement to allowed charlist |
|
|
for (ch in customReplacements) { |
|
|
allowedChars += ch; |
|
|
} |
|
|
} |
|
|
|
|
|
allowedChars += separator; |
|
|
|
|
|
// escape all necessary chars |
|
|
allowedChars = escapeChars(allowedChars); |
|
|
|
|
|
// trim whitespaces |
|
|
input = input.replace(/(^\s+|\s+$)/g, ''); |
|
|
|
|
|
lastCharWasSymbol = false; |
|
|
lastCharWasDiatric = false; |
|
|
|
|
|
for (i = 0, l = input.length; i < l; i++) { |
|
|
ch = input[i]; |
|
|
|
|
|
if (isReplacedCustomChar(ch, customReplacements)) { |
|
|
// don't convert a already converted char |
|
|
lastCharWasSymbol = false; |
|
|
} else if (langChar[ch]) { |
|
|
// process language specific diactrics chars conversion |
|
|
ch = lastCharWasSymbol && langChar[ch].match(/[A-Za-z0-9]/) ? ' ' + langChar[ch] : langChar[ch]; |
|
|
|
|
|
lastCharWasSymbol = false; |
|
|
} else if (ch in charMap) { |
|
|
// the transliteration changes entirely when some special characters are added |
|
|
if (i + 1 < l && lookAheadCharArray.indexOf(input[i + 1]) >= 0) { |
|
|
diatricString += ch; |
|
|
ch = ''; |
|
|
} else if (lastCharWasDiatric === true) { |
|
|
ch = diatricMap[diatricString] + charMap[ch]; |
|
|
diatricString = ''; |
|
|
} else { |
|
|
// process diactrics chars |
|
|
ch = lastCharWasSymbol && charMap[ch].match(/[A-Za-z0-9]/) ? ' ' + charMap[ch] : charMap[ch]; |
|
|
} |
|
|
|
|
|
lastCharWasSymbol = false; |
|
|
lastCharWasDiatric = false; |
|
|
} else if (ch in diatricMap) { |
|
|
diatricString += ch; |
|
|
ch = ''; |
|
|
// end of string, put the whole meaningful word |
|
|
if (i === l - 1) { |
|
|
ch = diatricMap[diatricString]; |
|
|
} |
|
|
lastCharWasDiatric = true; |
|
|
} else if ( |
|
|
// process symbol chars |
|
|
symbol[ch] && !(uricFlag && uricChars |
|
|
.indexOf(ch) !== -1) && !(uricNoSlashFlag && uricNoSlashChars |
|
|
// .indexOf(ch) !== -1) && !(markFlag && markChars |
|
|
.indexOf(ch) !== -1)) { |
|
|
ch = lastCharWasSymbol || result.substr(-1).match(/[A-Za-z0-9]/) ? separator + symbol[ch] : symbol[ch]; |
|
|
ch += input[i + 1] !== void 0 && input[i + 1].match(/[A-Za-z0-9]/) ? separator : ''; |
|
|
|
|
|
lastCharWasSymbol = true; |
|
|
} else { |
|
|
if (lastCharWasDiatric === true) { |
|
|
ch = diatricMap[diatricString] + ch; |
|
|
diatricString = ''; |
|
|
lastCharWasDiatric = false; |
|
|
} else if (lastCharWasSymbol && (/[A-Za-z0-9]/.test(ch) || result.substr(-1).match(/A-Za-z0-9]/))) { |
|
|
// process latin chars |
|
|
ch = ' ' + ch; |
|
|
} |
|
|
lastCharWasSymbol = false; |
|
|
} |
|
|
|
|
|
// add allowed chars |
|
|
result += ch.replace(new RegExp('[^\\w\\s' + allowedChars + '_-]', 'g'), separator); |
|
|
} |
|
|
|
|
|
if (titleCase) { |
|
|
result = result.replace(/(\w)(\S*)/g, function (_, i, r) { |
|
|
var j = i.toUpperCase() + (r !== null ? r : ''); |
|
|
return (Object.keys(customReplacements).indexOf(j.toLowerCase()) < 0) ? j : j.toLowerCase(); |
|
|
}); |
|
|
} |
|
|
|
|
|
// eliminate duplicate separators |
|
|
// add separator |
|
|
// trim separators from start and end |
|
|
result = result.replace(/\s+/g, separator) |
|
|
.replace(new RegExp('\\' + separator + '+', 'g'), separator) |
|
|
.replace(new RegExp('(^\\' + separator + '+|\\' + separator + '+$)', 'g'), ''); |
|
|
|
|
|
if (truncate && result.length > truncate) { |
|
|
lucky = result.charAt(truncate) === separator; |
|
|
result = result.slice(0, truncate); |
|
|
|
|
|
if (!lucky) { |
|
|
result = result.slice(0, result.lastIndexOf(separator)); |
|
|
} |
|
|
} |
|
|
|
|
|
if (!maintainCase && !titleCase) { |
|
|
result = result.toLowerCase(); |
|
|
} |
|
|
|
|
|
return result; |
|
|
}; |
|
|
|
|
|
/** |
|
|
* createSlug curried(opts)(input) |
|
|
* @param {object|string} opts config object or input string |
|
|
* @return {Function} function getSlugWithConfig() |
|
|
**/ |
|
|
var createSlug = function createSlug(opts) { |
|
|
|
|
|
/** |
|
|
* getSlugWithConfig |
|
|
* @param {string} input string |
|
|
* @return {string} slug string |
|
|
*/ |
|
|
return function getSlugWithConfig(input) { |
|
|
return getSlug(input, opts); |
|
|
}; |
|
|
}; |
|
|
|
|
|
/** |
|
|
* escape Chars |
|
|
* @param {string} input string |
|
|
*/ |
|
|
var escapeChars = function escapeChars(input) { |
|
|
return input.replace(/[-\\^$*+?.()|[\]{}\/]/g, '\\$&'); |
|
|
}; |
|
|
|
|
|
/** |
|
|
* check if the char is an already converted char from custom list |
|
|
* @param {char} ch character to check |
|
|
* @param {object} customReplacements custom translation map |
|
|
*/ |
|
|
var isReplacedCustomChar = function (ch, customReplacements) { |
|
|
for (var c in customReplacements) { |
|
|
if (customReplacements[c] === ch) { |
|
|
return true; |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
if (typeof module !== 'undefined' && module.exports) { |
|
|
|
|
|
// export functions for use in Node |
|
|
module.exports = getSlug; |
|
|
module.exports.createSlug = createSlug; |
|
|
} else if (typeof define !== 'undefined' && define.amd) { |
|
|
|
|
|
// export function for use in AMD |
|
|
define([], function () { |
|
|
return getSlug; |
|
|
}); |
|
|
} else { |
|
|
|
|
|
// don't overwrite global if exists |
|
|
try { |
|
|
if (root.getSlug || root.createSlug) { |
|
|
throw 'speakingurl: globals exists /(getSlug|createSlug)/'; |
|
|
} else { |
|
|
root.getSlug = getSlug; |
|
|
root.createSlug = createSlug; |
|
|
} |
|
|
} catch (e) {} |
|
|
} |
|
|
})(this); |