localization.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  1. (function(){
  2. function module_init() {
  3. console.log("[lora-prompt-tool] load localization module");
  4. const my_localization_data = {
  5. "LoRA prompt helper": {
  6. "zh_TW": "LoRA提示詞工具",
  7. "ja": "LoRAプロンプトヘルパー",
  8. "ko": "LoRA 프롬프트 도우미",
  9. "zh_CN": "LoRA提示词工具"
  10. },
  11. "Edit Model Trigger Words": {
  12. "zh_TW": "編輯模型觸發詞",
  13. "ja": "モデルトリガーワードの編集",
  14. "ko": "모델 트리거 단어 수정",
  15. "zh_CN": "编辑模型触发词"
  16. },
  17. "Enter your custom name.": {
  18. "zh_TW": "輸入您的自訂名稱",
  19. "ja": "カスタム名を入力します。",
  20. "ko": "사용자 지정 이름을 입력합니다.",
  21. "zh_CN": "将模型触发词保存到模型资料文件中"
  22. },
  23. "Enter your trigger word. EX: character_name_\\(title of novel\\)": {
  24. "zh_TW": "輸入您的觸發提示詞。 EX: 角色名稱_\\(作品名稱\\)",
  25. "ja": "トリガーワードを入力してください。 例: キャラクター名_\\(小説のタイトル\\)",
  26. "ko": "트리거 단어를 입력하십시오. 예: character_name_\\(소설 제목\\)",
  27. "zh_CN": "输入您的触发提示词。 EX: 角色名称_\\(作品名称\\) "
  28. },
  29. "(optional) separated by commas. EX: Character Name/Style Attributes": {
  30. "zh_TW": "(選用) 以逗點分隔。 EX: 角色名稱/風格屬性",
  31. "ja": "(オプション) カンマで区切ります。 例: キャラクター名/スタイル属性",
  32. "ko": "(선택 사항) 쉼표로 구분합니다. 예: 캐릭터 이름/스타일 속성",
  33. "zh_CN": "(可选) 以逗点分隔。 EX: 角色名称/风格属性 "
  34. },
  35. "It is automatically set to No when adding, and it needs to be changed again": {
  36. "zh_TW": "添加時自動設定為否,有需要再改",
  37. "ja": "追加時に自動的に「いいえ」に設定されるため、再度変更する必要があります。",
  38. "ko": "추가 시 자동으로 No로 설정되며 다시 변경해야 합니다.",
  39. "zh_CN": "添加时自动设定为否,有需要再改"
  40. },
  41. "Update the JSON data from user input.": {
  42. "zh_TW": "從在編輯頁面上做的編輯更新本JSON表格",
  43. "ja": "ユーザー入力からJSONデータを更新する",
  44. "ko": "사용자 입력에서 JSON 데이터 업데이트",
  45. "zh_CN": "从在编辑页面上做的编辑更新本JSON表格"
  46. },
  47. "Reload trigger words from model information file.": {
  48. "zh_TW": "從模型資料檔案中重新載入模型觸發詞",
  49. "ja": "モデル情報ファイルからトリガーワードを再読み込みする",
  50. "ko": "모델 정보 파일에서 트리거 단어 다시 로드",
  51. "zh_CN": "从模型资料文件中重新加载模型触发词"
  52. },
  53. "Save the trigger words to model information file.": {
  54. "zh_TW": "將模型觸發詞存檔到模型資料檔案中",
  55. "ja": "トリガーワードをモデル情報ファイルに保存する",
  56. "ko": "트리거 단어를 모델 정보 파일에 저장",
  57. "zh_CN": "将模型触发词保存到模型资料文件中"
  58. },
  59. "prompts": {
  60. "zh_TW": "提示詞",
  61. "ja": "プロンプト",
  62. "ko": "프롬프트",
  63. "zh_CN": "提示词"
  64. },
  65. "prompt": {
  66. "zh_TW": "提示詞",
  67. "ja": "プロンプト",
  68. "ko": "프롬프트",
  69. "zh_CN": "提示词"
  70. },
  71. "title": {
  72. "zh_TW": "標題",
  73. "ja": "タイトル",
  74. "ko": "제목",
  75. "zh_CN": "标题"
  76. },
  77. "trainedWords": {
  78. "zh_TW": "已訓練的提示詞",
  79. "ja": "訓練済みのプロンプト",
  80. "ko": "훈련된 프롬프트",
  81. "zh_CN": "已训练的提示词"
  82. },
  83. "baseModel": {
  84. "zh_TW": "基底模型",
  85. "ja": "ベースモデル",
  86. "ko": "베이스 모델",
  87. "zh_CN": "基底模型"
  88. },
  89. "description": {
  90. "zh_TW": "描述",
  91. "ja": "説明",
  92. "ko": "설명",
  93. "zh_CN": "描述"
  94. },
  95. "modelId": {
  96. "zh_TW": "模型編號",
  97. "ja": "モデルID",
  98. "ko": "모델 ID",
  99. "zh_CN": "模型编号"
  100. },
  101. "negativePrompt": {
  102. "zh_TW": "反向提示詞",
  103. "ja": "ネガティブプロンプト",
  104. "ko": "부정적인 프롬프트",
  105. "zh_CN": "反向提示词"
  106. },
  107. "hashes": {
  108. "zh_TW": "雜湊值",
  109. "ja": "ハッシュ値",
  110. "ko": "해시 값",
  111. "zh_CN": "散列值"
  112. },
  113. "Size": {
  114. "zh_TW": "尺寸",
  115. "ja": "サイズ",
  116. "ko": "크기",
  117. "zh_CN": "尺寸"
  118. },
  119. "name": {
  120. "zh_TW": "名稱",
  121. "ja": "名前",
  122. "ko": "이름",
  123. "zh_CN": "名称"
  124. },
  125. "Success": {
  126. "zh_TW": "成功",
  127. "ja": "成功",
  128. "ko": "성공",
  129. "zh_CN": "成功"
  130. },
  131. "virusScanResult": {
  132. "zh_TW": "掃毒結果",
  133. "ja": "ウイルススキャン結果",
  134. "ko": "바이러스 스캔 결과",
  135. "zh_CN": "扫毒结果"
  136. },
  137. "downloadUrl": {
  138. "zh_TW": "下載網址",
  139. "ja": "ダウンロードURL",
  140. "ko": "다운로드 URL",
  141. "zh_CN": "下载网址"
  142. },
  143. "sizeKB": {
  144. "zh_TW": "檔案大小 (KB)",
  145. "ja": "ファイルサイズ(KB)",
  146. "ko": "파일 크기 (KB)",
  147. "zh_CN": "文件大小 (KB)"
  148. },
  149. "(from CivitAI)": {
  150. "zh_TW": "(來自CivitAI)",
  151. "ja": "(CivitAIから)",
  152. "ko": "(CivitAI에서)",
  153. "zh_CN": "(来自CivitAI)"
  154. },
  155. "(No Trigger Word)": {
  156. "zh_TW": "(無觸發詞)",
  157. "ja": "(トリガーワードなし)",
  158. "ko": "(트리거 단어 없음)",
  159. "zh_CN": "(无触发词)"
  160. },
  161. "edit prompt words...": {
  162. "zh_TW": "編輯...",
  163. "ja": "プロンプトを編集する...",
  164. "ko": "프롬프트 단어 편집...",
  165. "zh_CN": "编辑..."
  166. },
  167. "Not": {
  168. "zh_TW": "否",
  169. "ja": "いいえ",
  170. "ko": "아니요",
  171. "zh_CN": "否"
  172. },
  173. "##Civitai##": {
  174. "zh_TW": "(CivitAI提供的提詞)",
  175. "ja": "(CivitAIからのプロンプト)",
  176. "ko": "(CivitAI에서 제공하는 프롬프트)",
  177. "zh_CN": "(CivitAI提供的提词)"
  178. },
  179. "Sort Order": {
  180. "zh_TW": "排序方式",
  181. "ja": "ソート順",
  182. "ko": "정렬 순서",
  183. "zh_CN": "排序方式"
  184. },
  185. "Ascending": {
  186. "zh_TW": "升序排序",
  187. "ja": "昇順",
  188. "ko": "오름차순",
  189. "zh_CN": "升序排序"
  190. },
  191. "Descending": {
  192. "zh_TW": "降序排序",
  193. "ja": "降順",
  194. "ko": "내림차순",
  195. "zh_CN": "降序排序"
  196. },
  197. "Content copied to clipboard": {
  198. "zh_TW": "成功將所選擇的儲存格複製到剪貼簿",
  199. "ja": "選択されたセルがクリップボードにコピーされました",
  200. "ko": "선택한 셀이 클립 보드로 복사되었습니다",
  201. "zh_CN": "成功将所选择的单元格复制到剪贴板"
  202. },
  203. "Failed to copy": {
  204. "zh_TW": "複製失敗",
  205. "ja": "コピーに失敗しました",
  206. "ko": "복사 실패",
  207. "zh_CN": "复制失败"
  208. },
  209. "translating...": {
  210. "zh_TW": "翻譯中...",
  211. "ja": "翻訳中...",
  212. "ko": "번역 중...",
  213. "zh_CN": "翻译中..."
  214. },
  215. "translation error": {
  216. "zh_TW": "翻譯發生錯誤",
  217. "ja": "翻訳エラー",
  218. "ko": "번역 오류",
  219. "zh_CN": "翻译发生错误"
  220. },
  221. "add prompt by image": {
  222. "zh_TW": "加入範例圖片的提示詞",
  223. "ja": "画像からプロンプトを追加",
  224. "ko": "이미지로 프롬프트 추가",
  225. "zh_CN": "加入示例图片的提示词"
  226. },
  227. "use prompt and setting by image": {
  228. "zh_TW": "使用範例圖片的提示詞和生圖設定",
  229. "ja": "画像からプロンプトと設定を使用",
  230. "ko": "이미지로 프롬프트와 설정 사용",
  231. "zh_CN": "使用示例图片的提示词和生图设置"
  232. },
  233. "Chinese Traditional": {
  234. "zh_TW": "繁體中文",
  235. "ja": "繁体中国語",
  236. "ko": "중국어 번체",
  237. "zh_CN": "繁体中文"
  238. },
  239. "add model using suggested setting": {
  240. "zh_TW": "使用建議的模型設定",
  241. "ja": "提案された設定を使用してモデルを追加",
  242. "ko": "제안된 설정을 사용하여 모델 추가",
  243. "zh_CN": "使用建议的模型设置"
  244. },
  245. "Use suggested weight": {
  246. "zh_TW": "使用建議的權重",
  247. "ja": "提案された重みを使用",
  248. "ko": "제안된 가중치 사용",
  249. "zh_CN": "使用建议的权重"
  250. },
  251. "Use suggested params": {
  252. "zh_TW": "使用建議的模型參數",
  253. "ja": "提案されたパラメータを使用",
  254. "ko": "제안된 모델 매개변수 사용",
  255. "zh_CN": "使用建议的模型参数"
  256. },
  257. "Use suggested weight and params": {
  258. "zh_TW": "使用建議的權重和模型參數",
  259. "ja": "提案された重みとパラメータを使用",
  260. "ko": "제안된 가중치와 모델 매개변수 사용",
  261. "zh_CN": "使用建议的权重和模型参数"
  262. }
  263. };
  264. lorahelper.localizationPromise = new Promise((resolve, reject) => {
  265. lorahelper.localizationPromiseResolve = resolve;
  266. lorahelper.localizationPromiseReject = reject;
  267. });
  268. let other_translate = {};
  269. let try_localization_looping = false;
  270. let try_localization = window.setInterval(function(){
  271. if (try_localization_looping) return;
  272. try {
  273. if(!lorahelper.is_nullptr(window.localization) && !lorahelper.is_nullptr(opts.localization)){
  274. try_localization_looping = true;
  275. if (Object.keys(window.localization).length) {
  276. for (const [key, value] of Object.entries(my_localization_data)) {
  277. if(value[opts.localization]){
  278. window.localization[key] = value[opts.localization];
  279. } else {
  280. const prefix = ((""+(opts.localization||"")).toLowerCase().replace(/[_\-\s]+/,"_").split("_")||[])[0];
  281. if(value[prefix]){
  282. window.localization[key] = value[prefix];
  283. }
  284. }
  285. }
  286. } else {
  287. if(has_bilingual()){
  288. const dirs = opts["bilingual_localization_dirs"];
  289. const file = opts["bilingual_localization_file"];
  290. if (file !== "None" && dirs !== "None"){
  291. const dirs_list = JSON.parse(dirs);
  292. const regex_scope = /^##(?<scope>\S+)##(?<skey>\S+)$/ // ##scope##.skey
  293. const i18n = JSON.parse(lorahelper.readFile(dirs_list[file]), (key, value) => {
  294. if (key.startsWith('@@')) {} //skip
  295. else if (regex_scope.test(key)) {} //skip
  296. else return value;
  297. });
  298. other_translate = i18n;
  299. }
  300. }
  301. //opts["bilingual_localization_dirs"]
  302. }
  303. lorahelper.translate_ready = true;
  304. if(typeof(lorahelper.localizationPromiseResolve) === typeof(lorahelper.noop_func)){
  305. lorahelper.localizationPromiseResolve();
  306. }
  307. try_localization_looping = false;
  308. window.clearInterval(try_localization);
  309. }
  310. } catch (error) {
  311. console.log(error.stack);
  312. }
  313. },10);
  314. function get_if_not_empty(toget){
  315. if(lorahelper.is_empty(toget)) return undefined;
  316. if((''+toget).toLowerCase() === "none") return undefined;
  317. return toget;
  318. }
  319. function get_system_language(){
  320. let DateTimeFormat_obj = Intl?.DateTimeFormat;
  321. if(typeof(DateTimeFormat_obj) !== typeof(lorahelper.noop_func)) return undefined;
  322. return DateTimeFormat_obj()?.resolvedOptions()?.locale
  323. }
  324. function has_bilingual(){
  325. return !!opts.bilingual_localization_enabled && !!get_if_not_empty(opts.bilingual_localization_file) && !(Object.keys(window.localization||{}).length);
  326. }
  327. function get_language_code(for_translate){
  328. const selected_language_code = get_if_not_empty(opts.localization);
  329. if(selected_language_code){
  330. return selected_language_code
  331. } else {
  332. if(opts.bilingual_localization_enabled){
  333. const bilingual_language_code = get_if_not_empty(opts.bilingual_localization_file);
  334. if (bilingual_language_code){
  335. return (x=>((x||[]).length>1)?x.slice(0,-1):x)(bilingual_language_code.split(".")).join(".");
  336. }
  337. } else if (for_translate) {
  338. const browser_language_code = get_if_not_empty(navigator.language || navigator.userLanguage);
  339. if (browser_language_code){
  340. return browser_language_code;
  341. }
  342. const system_language_code = get_if_not_empty(get_system_language());
  343. if (system_language_code){
  344. return system_language_code;
  345. }
  346. return "en"; //default english
  347. }
  348. }
  349. return undefined;
  350. }
  351. function is_same_language(lang1, lang2){
  352. lang1_split = (''+lang1).trim().toLowerCase().replace(/[_\s\-\+]+/g,"_").split("_");
  353. lang2_split = (''+lang2).trim().toLowerCase().replace(/[_\s\-\+]+/g,"_").split("_");
  354. if (lang1_split[0] !== lang2_split[0]) return false;
  355. if (lang1_split.length <= 1) return true;
  356. if (lang2_split.length <= 1) return false;
  357. let flag = true;
  358. for (const variants of lang1_split){
  359. flag = flag && !!lang2_split.includes(variants);
  360. }
  361. return flag;
  362. }
  363. function get_myTranslation_in_mydist(msg, lang_code){
  364. const msg_obj = my_localization_data[msg];
  365. if (msg_obj){
  366. for (const [lang_name, translated_msg] of Object.entries(msg_obj)) {
  367. if(is_same_language(lang_name, lang_code)) return translated_msg;
  368. }
  369. }
  370. return undefined;
  371. }
  372. function my_getTranslation(msg){
  373. const selected_language_code = get_language_code();
  374. let trans = getTranslation(msg);
  375. if (selected_language_code){
  376. const my_translate = get_myTranslation_in_mydist(msg,selected_language_code);
  377. if(my_translate) return my_translate;
  378. }
  379. if (!trans) {
  380. trans = other_translate[msg];
  381. if (!trans) trans = msg;
  382. }
  383. return trans;
  384. }
  385. function set_bilingual(element){
  386. if (!has_bilingual()) return;
  387. if (!lorahelper.is_nullptr(element.querySelector(".bilingual__trans_wrapper"))) return;
  388. const msg = element.innerHTML;
  389. element.innerHTML = get_UI_display(msg);
  390. }
  391. function get_UI_display(msg){
  392. const tmsg = my_getTranslation(msg);
  393. if (has_bilingual()){
  394. if (tmsg != msg){
  395. if(opts.bilingual_localization_order.toLowerCase() === "translation first")
  396. return `<div class="bilingual__trans_wrapper">${tmsg}<em>${msg}</em></div>`;
  397. else return `<div class="bilingual__trans_wrapper">${msg}<em>${tmsg}</em></div>`
  398. }
  399. }
  400. return tmsg;
  401. }
  402. function translate_language_selector(){
  403. lorahelper.dataedit_translate_btn = lorahelper.gradioApp().getElementById("lorahelp_dataedit_translate_btn")
  404. //Create and append select list
  405. var selectList = document.createElement("select");
  406. selectList.id = "translate_language_selector";
  407. let select_box = document.createElement("div");
  408. selectList.style.position = "absolute";
  409. selectList.style.top = "0px";
  410. selectList.style.border = "none";
  411. selectList.style.backgroundColor = "transparent";
  412. selectList.style.opacity = 0;
  413. select_box.appendChild(selectList);
  414. lorahelper.dataedit_translate_btn.appendChild(select_box);
  415. lorahelper.dataedit_translate_translate_language_selector = selectList;
  416. let lang_display = document.createElement("span");
  417. lang_display.style.margin = "0.5em";
  418. select_box.appendChild(lang_display);
  419. //Create and append the options
  420. let i = 0;
  421. const selected_lang_code = get_language_code(true);
  422. let select_id = 0;
  423. for (const [lang_code, lang_name] of Object.entries(lorahelper.languages)) {
  424. var option = document.createElement("option");
  425. const lang_data = !!(lang_name.name) ? lang_name : {name: lang_name};
  426. option.value = lang_code;
  427. option.text = lang_data.display ? `${lang_code} - ${lang_data.display} (${lang_data.name})` : lang_data.name;
  428. option.setAttribute("title", lang_data.display ? lang_data.display : lang_data.name);
  429. option.setAttribute("lang-name", lang_data.name);
  430. if(is_same_language(lang_code, selected_lang_code)){
  431. lang_display.innerHTML = lang_data.display;
  432. select_id = i;
  433. }
  434. //option.text = my_getTranslation(lang_name);
  435. selectList.appendChild(option);
  436. ++i;
  437. }
  438. selectList.addEventListener("change", function(event){
  439. const lang_name = lorahelper.languages[selectList.value];
  440. const lang_data = !!(lang_name.name) ? lang_name : {name: lang_name};
  441. lang_display.innerHTML = lang_data.display;
  442. });
  443. lorahelper.dataedit_translate_translate_language_selector.selectedIndex = select_id;
  444. }
  445. lorahelper.translate_language_selector = translate_language_selector;
  446. lorahelper.get_language_code = get_language_code;
  447. lorahelper.my_getTranslation = my_getTranslation;
  448. lorahelper.get_UI_display = get_UI_display;
  449. lorahelper.languages = {
  450. "auto": "Auto",
  451. "af": {
  452. "name": "Afrikaans",
  453. "display": "Afrikaans"
  454. },
  455. "sq": {
  456. "name": "Albanian",
  457. "display": "shqip"
  458. },
  459. "am": {
  460. "name": "Amharic",
  461. "display": "አማርኛ"
  462. },
  463. "ar": {
  464. "name": "Arabic",
  465. "display": "العربية"
  466. },
  467. "hy": {
  468. "name": "Armenian",
  469. "display": "հայերեն"
  470. },
  471. "az": {
  472. "name": "Azerbaijani",
  473. "display": "azərbaycanca"
  474. },
  475. "eu": {
  476. "name": "Basque",
  477. "display": "euskara"
  478. },
  479. "be": {
  480. "name": "Belarusian",
  481. "display": "беларуская"
  482. },
  483. "bn": {
  484. "name": "Bengali",
  485. "display": "বাংলা"
  486. },
  487. "bs": {
  488. "name": "Bosnian",
  489. "display": "bosanski"
  490. },
  491. "bg": {
  492. "name": "Bulgarian",
  493. "display": "български"
  494. },
  495. "ca": {
  496. "name": "Catalan",
  497. "display": "català"
  498. },
  499. "ceb": {
  500. "name": "Cebuano",
  501. "display": "Cebuano"
  502. },
  503. "ny": {
  504. "name": "Chichewa",
  505. "display": "Chi-Chewa"
  506. },
  507. "zh": {
  508. "name": "Chinese",
  509. "display": "中文"
  510. },
  511. "zh_cn": {
  512. "name": "Chinese Simplified",
  513. "display": "简体中文 (中国大陆)"
  514. },
  515. "zh_tw": {
  516. "name": "Chinese Traditional",
  517. "display": "繁體中文 (臺灣)"
  518. },
  519. "zh_hk": {
  520. "name": "Chinese Traditional",
  521. "display": "繁體中文 (香港)"
  522. },
  523. "co": {
  524. "name": "Corsican",
  525. "display": "corsu"
  526. },
  527. "hr": {
  528. "name": "Croatian",
  529. "display": "hrvatski"
  530. },
  531. "cs": {
  532. "name": "Czech",
  533. "display": "čeština"
  534. },
  535. "da": {
  536. "name": "Danish",
  537. "display": "dansk"
  538. },
  539. "nl": {
  540. "name": "Dutch",
  541. "display": "Nederlands"
  542. },
  543. "en": {
  544. "name": "English",
  545. "display": "English"
  546. },
  547. "eo": {
  548. "name": "Esperanto",
  549. "display": "Esperanto"
  550. },
  551. "et": {
  552. "name": "Estonian",
  553. "display": "eesti"
  554. },
  555. "tl": {
  556. "name": "Filipino",
  557. "display": "Tagalog"
  558. },
  559. "fi": {
  560. "name": "Finnish",
  561. "display": "suomi"
  562. },
  563. "fr": {
  564. "name": "French",
  565. "display": "français"
  566. },
  567. "fy": {
  568. "name": "Frisian",
  569. "display": "Frysk"
  570. },
  571. "gl": {
  572. "name": "Galician",
  573. "display": "galego"
  574. },
  575. "ka": {
  576. "name": "Georgian",
  577. "display": "ქართული"
  578. },
  579. "de": {
  580. "name": "German",
  581. "display": "Deutsch"
  582. },
  583. "el": {
  584. "name": "Greek",
  585. "display": "Ελληνικά"
  586. },
  587. "gu": {
  588. "name": "Gujarati",
  589. "display": "ગુજરાતી"
  590. },
  591. "ht": {
  592. "name": "Haitian Creole",
  593. "display": "Kreyòl ayisyen"
  594. },
  595. "ha": {
  596. "name": "Hausa",
  597. "display": "Hausa"
  598. },
  599. "haw": {
  600. "name": "Hawaiian",
  601. "display": "Hawaiʻi"
  602. },
  603. "he": {
  604. "name": "Hebrew",
  605. "display": "עברית"
  606. },
  607. "iw": "Hebrew",
  608. "hi": {
  609. "name": "Hindi",
  610. "display": "हिन्दी"
  611. },
  612. "hmn": "Hmong",
  613. "hu": {
  614. "name": "Hungarian",
  615. "display": "magyar"
  616. },
  617. "is": {
  618. "name": "Icelandic",
  619. "display": "íslenska"
  620. },
  621. "ig": {
  622. "name": "Igbo",
  623. "display": "Igbo"
  624. },
  625. "id": {
  626. "name": "Indonesian",
  627. "display": "Bahasa Indonesia"
  628. },
  629. "ga": {
  630. "name": "Irish",
  631. "display": "Gaeilge"
  632. },
  633. "it": {
  634. "name": "Italian",
  635. "display": "italiano"
  636. },
  637. "ja": {
  638. "name": "Japanese",
  639. "display": "日本語"
  640. },
  641. "jw": "Javanese",
  642. "kn": {
  643. "name": "Kannada",
  644. "display": "ಕನ್ನಡ"
  645. },
  646. "kk": {
  647. "name": "Kazakh",
  648. "display": "қазақша"
  649. },
  650. "km": {
  651. "name": "Khmer",
  652. "display": "ភាសាខ្មែរ"
  653. },
  654. "rw": {
  655. "name": "Kinyarwanda",
  656. "display": "Ikinyarwanda"
  657. },
  658. "ko": {
  659. "name": "Korean",
  660. "display": "한국어"
  661. },
  662. "ku": {
  663. "name": "Kurdish (Kurmanji)",
  664. "display": "kurdî"
  665. },
  666. "ky": {
  667. "name": "Kyrgyz",
  668. "display": "кыргызча"
  669. },
  670. "lo": {
  671. "name": "Lao",
  672. "display": "ລາວ"
  673. },
  674. "la": {
  675. "name": "Latin",
  676. "display": "Latina"
  677. },
  678. "lv": {
  679. "name": "Latvian",
  680. "display": "latviešu"
  681. },
  682. "lt": {
  683. "name": "Lithuanian",
  684. "display": "lietuvių"
  685. },
  686. "lb": {
  687. "name": "Luxembourgish",
  688. "display": "Lëtzebuergesch"
  689. },
  690. "mk": {
  691. "name": "Macedonian",
  692. "display": "македонски"
  693. },
  694. "mg": {
  695. "name": "Malagasy",
  696. "display": "Malagasy"
  697. },
  698. "ms": {
  699. "name": "Malay",
  700. "display": "Bahasa Melayu"
  701. },
  702. "ml": {
  703. "name": "Malayalam",
  704. "display": "മലയാളം"
  705. },
  706. "mt": {
  707. "name": "Maltese",
  708. "display": "Malti"
  709. },
  710. "mi": {
  711. "name": "Maori",
  712. "display": "Māori"
  713. },
  714. "mr": {
  715. "name": "Marathi",
  716. "display": "मराठी"
  717. },
  718. "mn": {
  719. "name": "Mongolian",
  720. "display": "монгол"
  721. },
  722. "my": {
  723. "name": "Myanmar (Burmese)",
  724. "display": "မြန်မာဘာသာ"
  725. },
  726. "ne": {
  727. "name": "Nepali",
  728. "display": "नेपाली"
  729. },
  730. "no": "Norwegian",
  731. "or": {
  732. "name": "Odia (Oriya)",
  733. "display": "ଓଡ଼ିଆ"
  734. },
  735. "ps": {
  736. "name": "Pashto",
  737. "display": "پښتو"
  738. },
  739. "fa": {
  740. "name": "Persian",
  741. "display": "فارسی"
  742. },
  743. "pl": {
  744. "name": "Polish",
  745. "display": "polski"
  746. },
  747. "pt": {
  748. "name": "Portuguese",
  749. "display": "português"
  750. },
  751. "pa": {
  752. "name": "Punjabi",
  753. "display": "ਪੰਜਾਬੀ"
  754. },
  755. "ro": {
  756. "name": "Romanian",
  757. "display": "română"
  758. },
  759. "ru": {
  760. "name": "Russian",
  761. "display": "русский"
  762. },
  763. "sm": {
  764. "name": "Samoan",
  765. "display": "Gagana Samoa"
  766. },
  767. "gd": {
  768. "name": "Scots Gaelic",
  769. "display": "Gàidhlig"
  770. },
  771. "sr": {
  772. "name": "Serbian",
  773. "display": "српски / srpski"
  774. },
  775. "st": {
  776. "name": "Sesotho",
  777. "display": "Sesotho"
  778. },
  779. "sn": {
  780. "name": "Shona",
  781. "display": "chiShona"
  782. },
  783. "sd": {
  784. "name": "Sindhi",
  785. "display": "سنڌي"
  786. },
  787. "si": {
  788. "name": "Sinhala",
  789. "display": "සිංහල"
  790. },
  791. "sk": {
  792. "name": "Slovak",
  793. "display": "slovenčina"
  794. },
  795. "sl": {
  796. "name": "Slovenian",
  797. "display": "slovenščina"
  798. },
  799. "so": {
  800. "name": "Somali",
  801. "display": "Soomaaliga"
  802. },
  803. "es": {
  804. "name": "Spanish",
  805. "display": "español"
  806. },
  807. "su": {
  808. "name": "Sundanese",
  809. "display": "Sunda"
  810. },
  811. "sw": {
  812. "name": "Swahili",
  813. "display": "Kiswahili"
  814. },
  815. "sv": {
  816. "name": "Swedish",
  817. "display": "svenska"
  818. },
  819. "tg": {
  820. "name": "Tajik",
  821. "display": "тоҷикӣ"
  822. },
  823. "ta": {
  824. "name": "Tamil",
  825. "display": "தமிழ்"
  826. },
  827. "tt": {
  828. "name": "Tatar",
  829. "display": "татарча / tatarça"
  830. },
  831. "te": {
  832. "name": "Telugu",
  833. "display": "తెలుగు"
  834. },
  835. "th": {
  836. "name": "Thai",
  837. "display": "ไทย"
  838. },
  839. "tr": {
  840. "name": "Turkish",
  841. "display": "Türkçe"
  842. },
  843. "tk": {
  844. "name": "Turkmen",
  845. "display": "Türkmençe"
  846. },
  847. "uk": {
  848. "name": "Ukrainian",
  849. "display": "українська"
  850. },
  851. "ur": {
  852. "name": "Urdu",
  853. "display": "اردو"
  854. },
  855. "ug": {
  856. "name": "Uyghur",
  857. "display": "ئۇيغۇرچە / Uyghurche"
  858. },
  859. "uz": {
  860. "name": "Uzbek",
  861. "display": "oʻzbekcha / ўзбекча"
  862. },
  863. "vi": {
  864. "name": "Vietnamese",
  865. "display": "Tiếng Việt"
  866. },
  867. "cy": {
  868. "name": "Welsh",
  869. "display": "Cymraeg"
  870. },
  871. "xh": {
  872. "name": "Xhosa",
  873. "display": "isiXhosa"
  874. },
  875. "yi": {
  876. "name": "Yiddish",
  877. "display": "ייִדיש"
  878. },
  879. "yo": {
  880. "name": "Yoruba",
  881. "display": "Yorùbá"
  882. },
  883. "zu": {
  884. "name": "Zulu",
  885. "display": "isiZulu"
  886. }
  887. };
  888. }
  889. let module_loadded = false;
  890. document.addEventListener("DOMContentLoaded", () => {
  891. if (module_loadded) return;
  892. module_loadded = true;
  893. module_init();
  894. });
  895. document.addEventListener("load", () => {
  896. if (module_loadded) return;
  897. module_loadded = true;
  898. module_init();
  899. });
  900. })();