mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
feat(i18n): bring the Azerbaijani translation up to date with dev
Translates the keys dev gained since the branch was cut, the help center above all, and drops the six keys dev no longer has. Registers az everywhere a language is listed: notification emails, the rate-limit message, the placeholder check and the wiki. The two tests that counted the languages by hand now derive the count from SUPPORTED_LANGUAGES.
This commit is contained in:
@@ -124,6 +124,7 @@ const RATE_LIMIT_MESSAGES: Record<string, string> = {
|
|||||||
it: 'Troppi tentativi. Riprova più tardi.',
|
it: 'Troppi tentativi. Riprova più tardi.',
|
||||||
tr: 'Çok fazla deneme. Lütfen daha sonra tekrar deneyin.',
|
tr: 'Çok fazla deneme. Lütfen daha sonra tekrar deneyin.',
|
||||||
ar: 'محاولات كثيرة جدًا. يرجى المحاولة لاحقًا.',
|
ar: 'محاولات كثيرة جدًا. يرجى المحاولة لاحقًا.',
|
||||||
|
az: 'Həddindən çox cəhd edildi. Bir az sonra yenidən cəhd edin.',
|
||||||
id: 'Terlalu banyak percobaan. Coba lagi nanti.',
|
id: 'Terlalu banyak percobaan. Coba lagi nanti.',
|
||||||
ja: '試行回数が多すぎます。時間をおいて再度お試しください。',
|
ja: '試行回数が多すぎます。時間をおいて再度お試しください。',
|
||||||
ko: '시도 횟수가 너무 많습니다. 잠시 후 다시 시도해 주세요.',
|
ko: '시도 횟수가 너무 많습니다. 잠시 후 다시 시도해 주세요.',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|||||||
import { render, screen, fireEvent, cleanup } from '../../tests/helpers/render';
|
import { render, screen, fireEvent, cleanup } from '../../tests/helpers/render';
|
||||||
import { resetAllStores, seedStore } from '../../tests/helpers/store';
|
import { resetAllStores, seedStore } from '../../tests/helpers/store';
|
||||||
import { useSettingsStore } from '../store/settingsStore';
|
import { useSettingsStore } from '../store/settingsStore';
|
||||||
|
import { SUPPORTED_LANGUAGES } from '../i18n';
|
||||||
import LoginPage from './LoginPage';
|
import LoginPage from './LoginPage';
|
||||||
import { useLogin } from './login/useLogin';
|
import { useLogin } from './login/useLogin';
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ describe('LoginPage — language switcher', () => {
|
|||||||
|
|
||||||
expect(screen.getByRole('button', { name: 'Change language' })).toHaveAttribute('aria-expanded', 'true');
|
expect(screen.getByRole('button', { name: 'Change language' })).toHaveAttribute('aria-expanded', 'true');
|
||||||
const options = screen.getAllByRole('option');
|
const options = screen.getAllByRole('option');
|
||||||
expect(options).toHaveLength(23);
|
expect(options).toHaveLength(SUPPORTED_LANGUAGES.length);
|
||||||
expect(screen.getByRole('option', { name: 'Deutsch' })).toHaveAttribute('aria-selected', 'false');
|
expect(screen.getByRole('option', { name: 'Deutsch' })).toHaveAttribute('aria-selected', 'false');
|
||||||
expect(screen.getByRole('option', { name: 'English' })).toHaveAttribute('aria-selected', 'true');
|
expect(screen.getByRole('option', { name: 'English' })).toHaveAttribute('aria-selected', 'true');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ describe('isRtlLanguage', () => {
|
|||||||
describe('SUPPORTED_LANGUAGES', () => {
|
describe('SUPPORTED_LANGUAGES', () => {
|
||||||
it('FE-COMP-I18N-009: contains expected entries with value/label shape', () => {
|
it('FE-COMP-I18N-009: contains expected entries with value/label shape', () => {
|
||||||
expect(Array.isArray(SUPPORTED_LANGUAGES)).toBe(true)
|
expect(Array.isArray(SUPPORTED_LANGUAGES)).toBe(true)
|
||||||
expect(SUPPORTED_LANGUAGES).toHaveLength(23)
|
expect(new Set(SUPPORTED_LANGUAGES.map(l => l.value)).size).toBe(SUPPORTED_LANGUAGES.length)
|
||||||
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'en', label: 'English' }))
|
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'en', label: 'English' }))
|
||||||
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'tr', label: 'Türkçe' }))
|
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'tr', label: 'Türkçe' }))
|
||||||
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'ja', label: '日本語' }))
|
expect(SUPPORTED_LANGUAGES).toContainEqual(expect.objectContaining({ value: 'ja', label: '日本語' }))
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ const admin: TranslationStrings = {
|
|||||||
'admin.amapKey': 'Amap (高德地图) API açarı',
|
'admin.amapKey': 'Amap (高德地图) API açarı',
|
||||||
'admin.amapKeyHint':
|
'admin.amapKeyHint':
|
||||||
'Google-un əlçatmaz, OpenStreetMap əhatəsinin isə zəif olduğu materik Çinində məkan axtarışı üçün. JS API açarı deyil, "Web 服务" (veb xidməti) açarı tələb olunur. Onu console.amap.com saytından əldə edin.',
|
'Google-un əlçatmaz, OpenStreetMap əhatəsinin isə zəif olduğu materik Çinində məkan axtarışı üçün. JS API açarı deyil, "Web 服务" (veb xidməti) açarı tələb olunur. Onu console.amap.com saytından əldə edin.',
|
||||||
|
'admin.keyFromEnv': '{name} ilə təyin edilib',
|
||||||
'admin.placesProvider.title': 'Məkan axtarışı provayderi',
|
'admin.placesProvider.title': 'Məkan axtarışı provayderi',
|
||||||
'admin.placesProvider.subtitle':
|
'admin.placesProvider.subtitle':
|
||||||
'TREK-in öz indeksi və OpenStreetMap hər axtarışa cavab verir. Onlar heç nə tapmadıqda başqa kimə sorğu göndəriləcəyini bu seçim müəyyən edir: Avtomatik rejim açar mövcud olduqda əvvəlcə Google-a, sonra Amap-a üstünlük verir.',
|
'TREK-in öz indeksi və OpenStreetMap hər axtarışa cavab verir. Onlar heç nə tapmadıqda başqa kimə sorğu göndəriləcəyini bu seçim müəyyən edir: Avtomatik rejim açar mövcud olduqda əvvəlcə Google-a, sonra Amap-a üstünlük verir.',
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ const dayplan: TranslationStrings = {
|
|||||||
'dayplan.reorderError':
|
'dayplan.reorderError':
|
||||||
'Günlərin sırasını dəyişmək mümkün olmadı',
|
'Günlərin sırasını dəyişmək mümkün olmadı',
|
||||||
'dayplan.addDayError': 'Gün əlavə etmək mümkün olmadı',
|
'dayplan.addDayError': 'Gün əlavə etmək mümkün olmadı',
|
||||||
'dayplan.deleteDay': 'Günü sil',
|
'dayplan.deleteDay': 'Günü sil',
|
||||||
'dayplan.deleteDayTitle': '{day} silinsin?',
|
'dayplan.deleteDayTitle': '{day} silinsin?',
|
||||||
'dayplan.deleteDayBody': 'Gün səyahətdən silinəcək. Bunu geri qaytarmaq mümkün deyil.',
|
'dayplan.deleteDayBody': 'Gün səyahətdən silinəcək. Bunu geri qaytarmaq mümkün deyil.',
|
||||||
'dayplan.deleteDayEmpty': 'Bu gün üçün heç nə planlaşdırılmayıb.',
|
'dayplan.deleteDayEmpty': 'Bu gün üçün heç nə planlaşdırılmayıb.',
|
||||||
|
|||||||
+3966
-3
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@ const login: TranslationStrings = {
|
|||||||
'login.oidcSignIn': '{name} ilə daxil ol',
|
'login.oidcSignIn': '{name} ilə daxil ol',
|
||||||
'login.oidcOnly': 'Parolla autentifikasiya deaktiv edilib. SSO provayderinizdən istifadə edərək daxil olun.',
|
'login.oidcOnly': 'Parolla autentifikasiya deaktiv edilib. SSO provayderinizdən istifadə edərək daxil olun.',
|
||||||
'login.oidcLoggedOut': 'Sistemdən çıxmısınız. SSO provayderinizdən istifadə edərək yenidən daxil olun.',
|
'login.oidcLoggedOut': 'Sistemdən çıxmısınız. SSO provayderinizdən istifadə edərək yenidən daxil olun.',
|
||||||
|
'login.oidcRedirecting': 'Sizi {name} səhifəsinə yönləndiririk…',
|
||||||
|
'login.oidcRedirectSlow': 'Hələ buradasınız? {name} ilə davam edin',
|
||||||
'login.demoHint': 'Demonu sınayın — qeydiyyat tələb olunmur',
|
'login.demoHint': 'Demonu sınayın — qeydiyyat tələb olunmur',
|
||||||
'login.mfaTitle': 'İki faktorlu autentifikasiya',
|
'login.mfaTitle': 'İki faktorlu autentifikasiya',
|
||||||
'login.mfaSubtitle': 'Autentifikator tətbiqinizdəki 6 rəqəmli kodu daxil edin.',
|
'login.mfaSubtitle': 'Autentifikator tətbiqinizdəki 6 rəqəmli kodu daxil edin.',
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ const packing: TranslationStrings = {
|
|||||||
'packing.clearChecked': 'İşarələnmiş {count} elementi sil',
|
'packing.clearChecked': 'İşarələnmiş {count} elementi sil',
|
||||||
'packing.clearCheckedShort': '{count} elementi sil',
|
'packing.clearCheckedShort': '{count} elementi sil',
|
||||||
|
|
||||||
'packing.suggestions': 'Təkliflər',
|
|
||||||
'packing.suggestionsTitle': 'Təklifləri əlavə et',
|
|
||||||
'packing.allSuggested': 'Bütün təkliflər əlavə edilib',
|
|
||||||
'packing.allPacked': 'Hər şey yığılıb!',
|
'packing.allPacked': 'Hər şey yığılıb!',
|
||||||
|
|
||||||
'packing.addPlaceholder': 'Yeni element əlavə et...',
|
'packing.addPlaceholder': 'Yeni element əlavə et...',
|
||||||
@@ -43,8 +40,6 @@ const packing: TranslationStrings = {
|
|||||||
'packing.filterDone': 'Hazırdır',
|
'packing.filterDone': 'Hazırdır',
|
||||||
|
|
||||||
'packing.emptyTitle': 'Baqaj siyahısı boşdur',
|
'packing.emptyTitle': 'Baqaj siyahısı boşdur',
|
||||||
'packing.emptyHint':
|
|
||||||
'Elementlər əlavə edin və ya təkliflərdən istifadə edin',
|
|
||||||
'packing.emptyFiltered':
|
'packing.emptyFiltered':
|
||||||
'Bu filtrə uyğun heç bir element yoxdur',
|
'Bu filtrə uyğun heç bir element yoxdur',
|
||||||
|
|
||||||
@@ -110,128 +105,6 @@ const packing: TranslationStrings = {
|
|||||||
'packing.toast.renameError': 'Adını dəyişmək mümkün olmadı',
|
'packing.toast.renameError': 'Adını dəyişmək mümkün olmadı',
|
||||||
'packing.toast.addError': 'Əlavə etmək mümkün olmadı',
|
'packing.toast.addError': 'Əlavə etmək mümkün olmadı',
|
||||||
|
|
||||||
'packing.suggestions.items': [
|
|
||||||
{
|
|
||||||
name: 'Pasport',
|
|
||||||
category: 'Sənədlər',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Şəxsiyyət vəsiqəsi',
|
|
||||||
category: 'Sənədlər',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Səyahət sığortası',
|
|
||||||
category: 'Sənədlər',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Uçuş biletləri',
|
|
||||||
category: 'Sənədlər',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Kredit kartı',
|
|
||||||
category: 'Maliyyə',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Nağd pul',
|
|
||||||
category: 'Maliyyə',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Viza',
|
|
||||||
category: 'Sənədlər',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Köynəklər',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Şalvarlar',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Alt paltarı',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Corablar',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Gödəkçə',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Yuxu geyimi',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Çimərlik geyimi',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Yağış gödəkçəsi',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Rahat ayaqqabı',
|
|
||||||
category: 'Geyim',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Diş fırçası',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Diş məcunu',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Şampun',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Dezodorant',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Günəş kremi',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Ülgüc',
|
|
||||||
category: 'Gigiyena vasitələri',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Şarj cihazı',
|
|
||||||
category: 'Elektronika',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Powerbank',
|
|
||||||
category: 'Elektronika',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Qulaqlıq',
|
|
||||||
category: 'Elektronika',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Səyahət adapteri',
|
|
||||||
category: 'Elektronika',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Kamera',
|
|
||||||
category: 'Elektronika',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Ağrıkəsici',
|
|
||||||
category: 'Sağlamlıq',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Yara plastırı',
|
|
||||||
category: 'Sağlamlıq',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Dezinfeksiya vasitəsi',
|
|
||||||
category: 'Sağlamlıq',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
'packing.bagLimit': 'Çəki limiti',
|
'packing.bagLimit': 'Çəki limiti',
|
||||||
'packing.setBagLimit': 'Limit təyin et',
|
'packing.setBagLimit': 'Limit təyin et',
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const reservations: TranslationStrings = {
|
|||||||
'reservations.pending': 'Gözləyir',
|
'reservations.pending': 'Gözləyir',
|
||||||
'reservations.summary':
|
'reservations.summary':
|
||||||
'{confirmed} təsdiqlənib, {pending} gözləyir',
|
'{confirmed} təsdiqlənib, {pending} gözləyir',
|
||||||
'reservations.fromPlan': 'Plandan',
|
|
||||||
'reservations.showFiles': 'Faylları göstər',
|
'reservations.showFiles': 'Faylları göstər',
|
||||||
|
|
||||||
'reservations.editTitle': 'Rezervasiyanı redaktə et',
|
'reservations.editTitle': 'Rezervasiyanı redaktə et',
|
||||||
|
|||||||
@@ -286,6 +286,27 @@ const roadtrip: TranslationStrings = {
|
|||||||
'roadtrip.ride.open': 'Rezervasiyanı aç',
|
'roadtrip.ride.open': 'Rezervasiyanı aç',
|
||||||
'roadtrip.ride.undated': '{title} bu səyahətin heç bir gününə təyin edilmədiyi üçün yol ondan istifadə etmir.',
|
'roadtrip.ride.undated': '{title} bu səyahətin heç bir gününə təyin edilmədiyi üçün yol ondan istifadə etmir.',
|
||||||
'roadtrip.bookings.loose': 'Bu gün üçün digər rezervasiyalar',
|
'roadtrip.bookings.loose': 'Bu gün üçün digər rezervasiyalar',
|
||||||
|
'roadtrip.ride.departureFlight': 'Yola düşmə {time}',
|
||||||
|
'roadtrip.ride.duration': 'Rezervasiyaya görə müddət',
|
||||||
|
'roadtrip.ride.checkIn': 'Giriş',
|
||||||
|
'roadtrip.ride.boarding': 'Minmə',
|
||||||
|
'roadtrip.ride.missed': 'Qaçırılıb',
|
||||||
|
'roadtrip.ride.lateBy': '{time} gecikmə',
|
||||||
|
'roadtrip.ride.reachedAt': 'saat {time} orada',
|
||||||
|
'roadtrip.ride.hintFlight': '{title} saat {departs} yola düşür, giriş saat {pin} bağlanır.',
|
||||||
|
'roadtrip.ride.hintShip': '{title} saat {departs} limandan ayrılır, giriş saat {pin} bağlanır.',
|
||||||
|
'roadtrip.ride.hintBoarding': '{title} saat {departs} yola düşür, minmə saat {pin} bitir.',
|
||||||
|
'roadtrip.ride.lateHintFlight':
|
||||||
|
'Maşınla saat {time} {place} ünvanına çatırsınız. {title} saat {departs} yola düşür, giriş saat {pin} bağlanır.',
|
||||||
|
'roadtrip.ride.lateHintShip':
|
||||||
|
'Maşınla saat {time} {place} ünvanına çatırsınız. {title} saat {departs} limandan ayrılır, giriş saat {pin} bağlanır.',
|
||||||
|
'roadtrip.ride.lateHintBoarding':
|
||||||
|
'Maşınla saat {time} {place} ünvanına çatırsınız. {title} saat {departs} yola düşür, minmə saat {pin} bitir.',
|
||||||
|
'roadtrip.day.rideMissed.flight': 'Uçuş qaçırılıb',
|
||||||
|
'roadtrip.day.rideMissed.train': 'Qatar qaçırılıb',
|
||||||
|
'roadtrip.day.rideMissed.ferry': 'Bərə qaçırılıb',
|
||||||
|
'roadtrip.day.rideMissed.cruise': 'Kruiz qaçırılıb',
|
||||||
|
'roadtrip.day.rideMissed.bus': 'Avtobus qaçırılıb',
|
||||||
'roadtrip.bookend.checkOut': 'Çıxış · {name}',
|
'roadtrip.bookend.checkOut': 'Çıxış · {name}',
|
||||||
'roadtrip.bookend.from': '{name} məkanından',
|
'roadtrip.bookend.from': '{name} məkanından',
|
||||||
'roadtrip.bookend.back': '{name} məkanına qayıt',
|
'roadtrip.bookend.back': '{name} məkanına qayıt',
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ const trip: TranslationStrings = {
|
|||||||
'transit.searchHint':
|
'transit.searchHint':
|
||||||
'Real bağlantıları axtarın və birbaşa günə əlavə edin — məlumatlar Transitous tərəfindən təmin edilir.',
|
'Real bağlantıları axtarın və birbaşa günə əlavə edin — məlumatlar Transitous tərəfindən təmin edilir.',
|
||||||
|
|
||||||
'trip.confirm.deletePlaceNight':
|
'trip.confirm.deletePlaceNight':
|
||||||
'Bu, həmçinin “{name}” məkanında rezervasiya edilmiş qalmanı silir.',
|
'Bu, həmçinin “{name}” məkanında rezervasiya edilmiş qalmanı silir.',
|
||||||
'trip.confirm.deletePlaceBooked':
|
'trip.confirm.deletePlaceBooked':
|
||||||
'Bu, həmçinin “{name}” məkanında rezervasiya edilmiş qalmanı, “{booking}” rezervasiyasını və onunla əlaqəli bütün xərcləri silir.',
|
'Bu, həmçinin “{name}” məkanında rezervasiya edilmiş qalmanı, “{booking}” rezervasiyasını və onunla əlaqəli bütün xərcləri silir.',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import ar from './ar';
|
import ar from './ar';
|
||||||
|
import az from './az';
|
||||||
import br from './br';
|
import br from './br';
|
||||||
import ca from './ca';
|
import ca from './ca';
|
||||||
import cs from './cs';
|
import cs from './cs';
|
||||||
@@ -39,6 +40,7 @@ import { describe, it, expect } from 'vitest';
|
|||||||
*/
|
*/
|
||||||
const LOCALES: Record<string, TranslationStrings> = {
|
const LOCALES: Record<string, TranslationStrings> = {
|
||||||
ar,
|
ar,
|
||||||
|
az,
|
||||||
br,
|
br,
|
||||||
ca,
|
ca,
|
||||||
cs,
|
cs,
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ You can set `DEFAULT_LANGUAGE` to any of the 23 languages TREK ships. The curren
|
|||||||
| `it` | Italiano |
|
| `it` | Italiano |
|
||||||
| `tr` | Türkçe |
|
| `tr` | Türkçe |
|
||||||
| `ar` | العربية |
|
| `ar` | العربية |
|
||||||
|
| `az` | Azərbaycanca |
|
||||||
| `id` | Bahasa Indonesia |
|
| `id` | Bahasa Indonesia |
|
||||||
| `ja` | 日本語 |
|
| `ja` | 日本語 |
|
||||||
| `ko` | 한국어 |
|
| `ko` | 한국어 |
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ TREK ships with translations for 23 languages. You can change your language at a
|
|||||||
| `it` | Italiano |
|
| `it` | Italiano |
|
||||||
| `tr` | Türkçe |
|
| `tr` | Türkçe |
|
||||||
| `ar` | العربية |
|
| `ar` | العربية |
|
||||||
|
| `az` | Azərbaycanca |
|
||||||
| `id` | Bahasa Indonesia |
|
| `id` | Bahasa Indonesia |
|
||||||
| `ja` | 日本語 |
|
| `ja` | 日本語 |
|
||||||
| `ko` | 한국어 |
|
| `ko` | 한국어 |
|
||||||
|
|||||||
Reference in New Issue
Block a user