diff --git a/index.html b/index.html index 0d81c06..6f19eb8 100644 --- a/index.html +++ b/index.html @@ -14,30 +14,35 @@
✦
-
GaC-Srtool
-
Star Rail FreeSR & Server Controller
+
GaC-Srtool
+
Star Rail FreeSR & Server Controller
-
+ + + +
- กำลังตรวจสอบ... + กำลังตรวจสอบ...
-
@@ -48,15 +53,15 @@
0
-
ตัวละครที่ครอบครอง (Avatars)
+
ตัวละครที่ครอบครอง (Avatars)
0
-
กรวยแสง (Lightcones)
+
กรวยแสง (Lightcones)
0
-
รีลิกส์ (Relics)
+
รีลิกส์ (Relics)
@@ -64,12 +69,12 @@
- 📍 สถานะเซิร์ฟเวอร์ & ตำแหน่งปัจจุบัน + 📍 สถานะเซิร์ฟเวอร์ & ตำแหน่งปัจจุบัน API Live
- API Gateway Endpoint + API Gateway Endpoint -
@@ -83,7 +88,7 @@
- พิกัดตัวละคร (X, Y, Z) + พิกัดตัวละคร (X, Y, Z) -
@@ -91,17 +96,17 @@
-
⚡ ดำเนินการด่วน (Quick Actions)
-

สั่งการส่งไปยัง REST API Gateway ทันที

+
⚡ ดำเนินการด่วน (Quick Actions)
+

สั่งการส่งไปยัง REST API Gateway ทันที

@@ -109,7 +114,7 @@
-
🎮 ทีมปัจจุบัน (Current Lineup)
+
🎮 ทีมปัจจุบัน (Current Lineup)
กำลังโหลดข้อมูลทีม...
@@ -120,16 +125,16 @@
- +
- - + +
@@ -144,13 +149,13 @@
- ⚡ ระบบปลดล็อค Ex-Rank Skill + ⚡ ระบบปลดล็อค Ex-Rank Skill
- - + +
-

+

เปิดใช้งานพรสวรรค์และกลไกพิเศษ Ex-Rank สำหรับตัวละครเฉพาะใน FreeSR (เช่น Jing Yuan โดน CC ไม่หยุดชะงัก, Dan Heng IL, Acheron)

@@ -167,8 +172,8 @@
-
📍 จุดวาร์ปปลอดภัยยอดนิยม (Safe Presets)
-

คลิกจุดวาร์ปเพื่อย้ายฉากของผู้เล่นในไฟล์เซฟได้ทันที

+
📍 จุดวาร์ปปลอดภัยยอดนิยม (Safe Presets)
+

คลิกจุดวาร์ปเพื่อย้ายฉากของผู้เล่นในไฟล์เซฟได้ทันที

@@ -176,23 +181,23 @@
-
🎯 กำหนดพิกัดวาร์ปเอง (Custom Teleport)
-

ใส่ PlaneID, FloorID และ EntryID ตามต้องการ

+
🎯 กำหนดพิกัดวาร์ปเอง (Custom Teleport)
+

ใส่ PlaneID, FloorID และ EntryID ตามต้องการ

- +
- +
- +
@@ -210,7 +215,7 @@
- @@ -223,24 +228,24 @@
- - + +
- - + + - +
- +
- พร้อมใช้งาน - Tip: สามารถแก้ไขค่าดิบแล้วกด 'บันทึกไปยังเซิร์ฟเวอร์' ได้ทันที + พร้อมใช้งาน + Tip: สามารถแก้ไขค่าดิบแล้วกด 'บันทึกไปยังเซิร์ฟเวอร์' ได้ทันที
@@ -251,51 +256,50 @@
-
⚙️ ตั้งค่าการเชื่อมต่อ API Gateway
-

ปรับเปลี่ยนพอร์ตหรือ IP ได้ตามไฟล์ server.json ของคุณ

+
⚙️ ตั้งค่าการเชื่อมต่อ API Gateway
+

ปรับเปลี่ยนพอร์ตหรือ IP ได้ตามไฟล์ server.json ของคุณ

- + - * ค่าเริ่มต้นของ GaC-hkrpg-go คือพอร์ต 21000 (SDK server) + * Port 21000 by default (GaC-hkrpg-go SDK Server)
- +
- - + +
-
🌐 วิธีนำขึ้นโฮสต์ GitHub Pages (ฟรี 100%)
-

สามารถเปิดใช้งานเว็บนี้บนอินเทอร์เน็ตได้โดยไม่ต้องเสียค่าโฮสต์ใดๆ

+
🌐 วิธีนำขึ้นโฮสต์ GitHub Pages (ฟรี 100%)
+

สามารถเปิดใช้งานเว็บนี้บนอินเทอร์เน็ตได้โดยไม่ต้องเสียค่าโฮสต์ใดๆ

  1. - 1. สร้าง Repository บน GitHub:
    - สร้าง GitHub Repo ใหม่ (Public หรือ Private ก็ได้) เช่นชื่อ GaC-srtool + 1. Create GitHub Repository:
    + Create new repo e.g. GaC-srtool
  2. - 2. Push โฟลเดอร์นี้ขึ้น GitHub:
    + 2. Push to GitHub:
    git remote add origin https://github.com/<user>/GaC-srtool.git
    - git add . && git commit -m "Init GaC-srtool" && git push -u origin main + git add . && git commit -m "Init" && git push -u origin main
  3. - 3. เปิดใช้งาน GitHub Pages:
    - เข้าไปที่ Repo บน GitHub > Settings > Pages
    - ใต้หัวข้อ Build and deployment เลือก Source เป็น Deploy from a branch > เลือก Branch: main, Folder: / (root) > กด Save + 3. Enable GitHub Pages:
    + Go to Repo > Settings > Pages > Source: Deploy from a branch > Branch: main / (root) > Click Save
  4. - 4. ใช้งานได้ทันที:
    - เว็บจะออนไลน์ที่ https://<user>.github.io/GaC-srtool/ ไม่เสียค่าใช้จ่ายตลอดชีพ! + 4. Done:
    + Your dashboard will be online at https://<user>.github.io/GaC-srtool/!
@@ -308,17 +312,17 @@
- EIDOLON (E): + ${t('eidolonLabel')}
${pipsHtml}
@@ -292,7 +338,7 @@ function renderAvatarsGrid() { async function setAvatarRank(avatarId, rank) { try { await apiCall('/api/avatar/rank', 'POST', { avatar_id: avatarId, rank }); - showToast(`ปรับตัวละคร ${avatarId} เป็น E${rank} สำเร็จ`, 'success'); + showToast(t('avatarRankSuccess', { id: avatarId, rank }), 'success'); // Update local state and re-render const target = state.avatarsList.find(a => a.avatar_id === avatarId); @@ -301,27 +347,27 @@ async function setAvatarRank(avatarId, rank) { renderAvatarsGrid(); } } catch (err) { - showToast(`เกิดข้อผิดพลาด: ${err.message}`, 'error'); + showToast(`Error: ${err.message}`, 'error'); } } // Max all avatars API async function maxAllAvatars() { - if (!confirm('ยืนยันปรับตัวละครทั้งหมดให้เป็นเลเวล 80 และปลด E6 หรือไม่?')) return; + if (!confirm(t('confirmMaxAll'))) return; try { await apiCall('/api/avatar/max_all', 'POST', {}); - showToast('ปรับ Max ทุกตัวละครสำเร็จแล้ว!', 'success'); + showToast(t('maxAllSuccess'), 'success'); loadAvatars(); refreshStatus(); } catch (err) { - showToast(`เกิดข้อผิดพลาด: ${err.message}`, 'error'); + showToast(`Error: ${err.message}`, 'error'); } } // Render Ex-Ranks function renderExRanks(exList) { if (!exList || exList.length === 0) { - el.exrankList.innerHTML = '
ไม่มีข้อมูลตัวละคร Ex-Rank
'; + el.exrankList.innerHTML = '
No Ex-Rank Avatars
'; return; } @@ -329,10 +375,11 @@ function renderExRanks(exList) { exList.forEach(item => { const card = document.createElement('div'); card.className = 'ex-switch-card'; + const localizedMeta = getAvatarInfo(item.avatar_id); card.innerHTML = `
-
${item.name}
+
${localizedMeta.name}
Avatar ID: ${item.avatar_id} • Ex-Rank Skill ID: ${item.ex_rank_id}
@@ -348,10 +395,11 @@ function renderExRanks(exList) { const avatarId = item.avatar_id; try { await apiCall('/api/exrank/toggle', 'POST', { avatar_id: avatarId, unlocked }); - showToast(`${item.name}: ${unlocked ? 'เปิดใช้งาน' : 'ปิดใช้งาน'} Ex-Rank สำเร็จ`, 'success'); + const statusText = unlocked ? t('enabled') : t('disabled'); + showToast(t('exrankToggleSuccess', { name: localizedMeta.name, status: statusText }), 'success'); } catch (err) { e.target.checked = !unlocked; - showToast(`เกิดข้อผิดพลาด: ${err.message}`, 'error'); + showToast(`Error: ${err.message}`, 'error'); } }); @@ -370,15 +418,17 @@ function renderTeleportPresets() { item.style.justifyContent = 'space-between'; item.style.alignItems = 'center'; + const displayName = getTeleportName(preset); + item.innerHTML = `
-
${preset.name}
+
${displayName}
Plane: ${preset.plane_id} • Floor: ${preset.floor_id} • Entry: ${preset.entry_id}
`; @@ -390,7 +440,7 @@ function renderTeleportPresets() { x: preset.x, y: preset.y, z: preset.z - }, preset.name); + }, displayName); }); el.teleportPresetsList.appendChild(item); @@ -401,10 +451,10 @@ function renderTeleportPresets() { async function executeTeleport(payload, label = '') { try { await apiCall('/api/teleport', 'POST', payload); - showToast(`วาร์ปไปยัง ${label || 'จุดที่ระบุ'} สำเร็จ (บันทึกลง Persistent)`, 'success'); + showToast(t('warpSuccess', { label: label || `Plane ${payload.plane_id}` }), 'success'); refreshStatus(); } catch (err) { - showToast(`วาร์ปไม่สำเร็จ: ${err.message}`, 'error'); + showToast(t('warpFailed', { err: err.message }), 'error'); } } @@ -414,22 +464,22 @@ async function loadJsonData(mode) { if (mode === 'freesr') { el.btnSelectFreesr.className = 'btn btn-sm btn-primary active'; el.btnSelectPersistent.className = 'btn btn-sm btn-secondary'; - el.jsonStatusInfo.textContent = 'กำลังเปิด: freesr-data.json'; + el.jsonStatusInfo.textContent = t('jsonStatusOpening', { name: 'freesr-data.json' }); try { const res = await apiCall('/api/freesr'); el.jsonEditor.value = JSON.stringify(res.data, null, 2); } catch (err) { - showToast(`โหลด freesr-data ไม่สำเร็จ: ${err.message}`, 'error'); + showToast(`Load failed: ${err.message}`, 'error'); } } else { el.btnSelectPersistent.className = 'btn btn-sm btn-primary active'; el.btnSelectFreesr.className = 'btn btn-sm btn-secondary'; - el.jsonStatusInfo.textContent = 'กำลังเปิด: persistent'; + el.jsonStatusInfo.textContent = t('jsonStatusOpening', { name: 'persistent' }); try { const res = await apiCall('/api/persistent'); el.jsonEditor.value = JSON.stringify(res.persistent, null, 2); } catch (err) { - showToast(`โหลด persistent ไม่สำเร็จ: ${err.message}`, 'error'); + showToast(`Load failed: ${err.message}`, 'error'); } } } @@ -438,7 +488,7 @@ async function loadJsonData(mode) { async function saveJsonData() { const text = el.jsonEditor.value.trim(); if (!text) { - showToast('ไม่มีข้อมูล JSON ให้บันทึก', 'error'); + showToast('No JSON data to save', 'error'); return; } @@ -446,17 +496,17 @@ async function saveJsonData() { try { parsed = JSON.parse(text); } catch (err) { - showToast(`JSON ไม่ถูกต้อง: ${err.message}`, 'error'); + showToast(`${t('jsonInvalid')}: ${err.message}`, 'error'); return; } const endpoint = state.currentJsonMode === 'freesr' ? '/api/freesr' : '/api/persistent'; try { await apiCall(endpoint, 'POST', parsed); - showToast(`บันทึกไฟล์ ${state.currentJsonMode} เรียบร้อยแล้ว`, 'success'); + showToast(t('jsonSaveSuccess', { name: state.currentJsonMode }), 'success'); refreshStatus(); } catch (err) { - showToast(`บันทึกไม่สำเร็จ: ${err.message}`, 'error'); + showToast(`Save failed: ${err.message}`, 'error'); } } @@ -465,7 +515,7 @@ function setupTabs() { const tabs = document.querySelectorAll('.tab-btn'); tabs.forEach(tab => { tab.addEventListener('click', () => { - tabs.forEach(t => t.classList.remove('active')); + tabs.forEach(tBtn => tBtn.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active')); tab.classList.add('active'); @@ -490,7 +540,7 @@ function setupTabs() { function setupEvents() { // Quick Ping & Refresh el.btnQuickPing.addEventListener('click', () => { - showToast('กำลังตรวจสอบการเชื่อมต่อ...', 'info'); + showToast(t('checking'), 'info'); refreshStatus(); }); @@ -509,7 +559,7 @@ function setupEvents() { state.apiUrl = newUrl; localStorage.setItem('gac_srtool_api_url', newUrl); el.modalSettings.classList.remove('active'); - showToast('บันทึกการตั้งค่าแล้ว กำลังเชื่อมต่อใหม่...', 'info'); + showToast(t('settingsSaved'), 'info'); refreshStatus(); } }); @@ -520,16 +570,16 @@ function setupEvents() { el.btnQuickWarpExpress.addEventListener('click', () => { const express = PRESET_TELEPORTS[0]; - executeTeleport(express, express.name); + executeTeleport(express, getTeleportName(express)); }); el.btnQuickSyncPersistent.addEventListener('click', async () => { try { await apiCall('/api/persistent'); - showToast('ซิงค์ข้อมูล Persistent เรียบร้อย', 'success'); + showToast('Persistent data synced', 'success'); refreshStatus(); } catch (err) { - showToast(`ซิงค์ไม่สำเร็จ: ${err.message}`, 'error'); + showToast(`Sync failed: ${err.message}`, 'error'); } }); @@ -542,20 +592,20 @@ function setupEvents() { el.btnExrankEnableAll.addEventListener('click', async () => { try { await apiCall('/api/exrank/toggle', 'POST', { all: true, unlocked: true }); - showToast('เปิดใช้งาน Ex-Rank ทุกตัวละครสำเร็จ', 'success'); + showToast(t('exrankAllSuccess', { status: t('enabled') }), 'success'); refreshStatus(); } catch (err) { - showToast(`เกิดข้อผิดพลาด: ${err.message}`, 'error'); + showToast(`Error: ${err.message}`, 'error'); } }); el.btnExrankDisableAll.addEventListener('click', async () => { try { await apiCall('/api/exrank/toggle', 'POST', { all: true, unlocked: false }); - showToast('ปิดใช้งาน Ex-Rank ทุกตัวละครสำเร็จ', 'success'); + showToast(t('exrankAllSuccess', { status: t('disabled') }), 'success'); refreshStatus(); } catch (err) { - showToast(`เกิดข้อผิดพลาด: ${err.message}`, 'error'); + showToast(`Error: ${err.message}`, 'error'); } }); @@ -581,9 +631,9 @@ function setupEvents() { try { const parsed = JSON.parse(el.jsonEditor.value); el.jsonEditor.value = JSON.stringify(parsed, null, 2); - showToast('จัดรูปแบบ JSON สวยงามแล้ว', 'info'); + showToast('JSON beautified', 'info'); } catch (err) { - showToast('JSON ไม่ถูกต้อง ไม่สามารถจัดรูปแบบได้', 'error'); + showToast(t('jsonInvalid'), 'error'); } }); @@ -596,7 +646,7 @@ function setupEvents() { a.href = URL.createObjectURL(blob); a.download = `${state.currentJsonMode}-${Date.now()}.json`; a.click(); - showToast(`ดาวน์โหลด backup ไฟล์ ${a.download} แล้ว`, 'success'); + showToast(`Downloaded ${a.download}`, 'success'); }); el.jsonFileInput.addEventListener('change', (e) => { @@ -607,9 +657,9 @@ function setupEvents() { try { const parsed = JSON.parse(event.target.result); el.jsonEditor.value = JSON.stringify(parsed, null, 2); - showToast(`โหลดเนื้อหาไฟล์ ${file.name} เข้าสู่อิดิเตอร์แล้ว`, 'success'); + showToast(`Loaded ${file.name}`, 'success'); } catch (err) { - showToast('ไฟล์ไม่ใช่ JSON ที่ถูกต้อง', 'error'); + showToast(t('jsonInvalid'), 'error'); } }; reader.readAsText(file); @@ -627,7 +677,7 @@ function setupEvents() { localStorage.setItem('gac_srtool_api_url', state.apiUrl); localStorage.setItem('gac_srtool_ping_interval', state.pingIntervalSec); - showToast('บันทึกการตั้งค่าสำเร็จ!', 'success'); + showToast(t('settingsSaved'), 'success'); refreshStatus(); }); @@ -638,7 +688,7 @@ function setupEvents() { el.settingPingInterval.value = state.pingIntervalSec; localStorage.removeItem('gac_srtool_api_url'); localStorage.removeItem('gac_srtool_ping_interval'); - showToast('คืนค่าเริ่มต้นเรียบร้อย', 'info'); + showToast(t('settingsReset'), 'info'); refreshStatus(); }); } @@ -652,9 +702,10 @@ function startPingLoop() { // Initialize Application function init() { + setupLanguageSelector(); setupTabs(); setupEvents(); - renderTeleportPresets(); + applyTranslations(); refreshStatus(); startPingLoop(); } diff --git a/js/avatars-data.js b/js/avatars-data.js index 469f01d..c501f50 100644 --- a/js/avatars-data.js +++ b/js/avatars-data.js @@ -1,99 +1,563 @@ -// Metadata dictionary for Star Rail Avatars / Characters +import { getCurrentLanguage, translateElement, translatePath } from './i18n.js'; + export const AVATAR_METADATA = { // Trailblazers - 8001: { name: "Trailblazer (Physical)", path: "Destruction", element: "Physical", rarity: 5 }, - 8002: { name: "Trailblazer (Physical ♀)", path: "Destruction", element: "Physical", rarity: 5 }, - 8003: { name: "Trailblazer (Fire)", path: "Preservation", element: "Fire", rarity: 5 }, - 8004: { name: "Trailblazer (Fire ♀)", path: "Preservation", element: "Fire", rarity: 5 }, - 8005: { name: "Trailblazer (Harmony)", path: "Harmony", element: "Imaginary", rarity: 5 }, - 8006: { name: "Trailblazer (Harmony ♀)", path: "Harmony", element: "Imaginary", rarity: 5 }, - 8007: { name: "Trailblazer (Remembrance)", path: "Remembrance", element: "Ice", rarity: 5 }, - 8008: { name: "Trailblazer (Remembrance ♀)", path: "Remembrance", element: "Ice", rarity: 5 }, + 8001: { + names: { + en: "Trailblazer (Physical ♂)", + th: "ผู้บุกเบิก (กายภาพ ♂)", + "zh-CN": "开拓者 (物理 ♂)", + "zh-TW": "開拓者 (物理 ♂)", + ja: "開拓者 (物理 ♂)", + ko: "개척자 (물리 ♂)", + ru: "Первопроходец (Физ. ♂)" + }, + path: "Destruction", + element: "Physical", + rarity: 5 + }, + 8002: { + names: { + en: "Trailblazer (Physical ♀)", + th: "ผู้บุกเบิก (กายภาพ ♀)", + "zh-CN": "开拓者 (物理 ♀)", + "zh-TW": "開拓者 (物理 ♀)", + ja: "開拓者 (物理 ♀)", + ko: "개척자 (물리 ♀)", + ru: "Первопроходец (Физ. ♀)" + }, + path: "Destruction", + element: "Physical", + rarity: 5 + }, + 8003: { + names: { + en: "Trailblazer (Fire ♂)", + th: "ผู้บุกเบิก (ไฟ ♂)", + "zh-CN": "开拓者 (火 ♂)", + "zh-TW": "開拓者 (火 ♂)", + ja: "開拓者 (炎 ♂)", + ko: "개척자 (화염 ♂)", + ru: "Первопроходец (Огонь ♂)" + }, + path: "Preservation", + element: "Fire", + rarity: 5 + }, + 8004: { + names: { + en: "Trailblazer (Fire ♀)", + th: "ผู้บุกเบิก (ไฟ ♀)", + "zh-CN": "开拓者 (火 ♀)", + "zh-TW": "開拓者 (火 ♀)", + ja: "開拓者 (炎 ♀)", + ko: "개척자 (화염 ♀)", + ru: "Первопроходец (Огонь ♀)" + }, + path: "Preservation", + element: "Fire", + rarity: 5 + }, + 8005: { + names: { + en: "Trailblazer (Harmony ♂)", + th: "ผู้บุกเบิก (ประสาน ♂)", + "zh-CN": "开拓者 (同谐 ♂)", + "zh-TW": "開拓者 (同諧 ♂)", + ja: "開拓者 (調和 ♂)", + ko: "개척자 (화합 ♂)", + ru: "Первопроходец (Гармония ♂)" + }, + path: "Harmony", + element: "Imaginary", + rarity: 5 + }, + 8006: { + names: { + en: "Trailblazer (Harmony ♀)", + th: "ผู้บุกเบิก (ประสาน ♀)", + "zh-CN": "开拓者 (同谐 ♀)", + "zh-TW": "開拓者 (同諧 ♀)", + ja: "開拓者 (調和 ♀)", + ko: "개척자 (화합 ♀)", + ru: "Первопроходец (Гармония ♀)" + }, + path: "Harmony", + element: "Imaginary", + rarity: 5 + }, + 8007: { + names: { + en: "Trailblazer (Remembrance ♂)", + th: "ผู้บุกเบิก (ความทรงจำ ♂)", + "zh-CN": "开拓者 (记忆 ♂)", + "zh-TW": "開拓者 (記憶 ♂)", + ja: "開拓者 (記憶 ♂)", + ko: "개척자 (기억 ♂)", + ru: "Первопроходец (Память ♂)" + }, + path: "Remembrance", + element: "Ice", + rarity: 5 + }, + 8008: { + names: { + en: "Trailblazer (Remembrance ♀)", + th: "ผู้บุกเบิก (ความทรงจำ ♀)", + "zh-CN": "开拓者 (记忆 ♀)", + "zh-TW": "開拓者 (記憶 ♀)", + ja: "開拓者 (記憶 ♀)", + ko: "개척자 (기억 ♀)", + ru: "Первопроходец (Память ♀)" + }, + path: "Remembrance", + element: "Ice", + rarity: 5 + }, // Astral Express & Herta Station - 1001: { name: "March 7th", path: "Preservation", element: "Ice", rarity: 4 }, - 1224: { name: "March 7th (Hunt)", path: "Hunt", element: "Imaginary", rarity: 4 }, - 1002: { name: "Dan Heng", path: "Hunt", element: "Wind", rarity: 4 }, - 1003: { name: "Himeko", path: "Erudition", element: "Fire", rarity: 5 }, - 1004: { name: "Welt", path: "Nihility", element: "Imaginary", rarity: 5 }, - 1008: { name: "Arlan", path: "Destruction", element: "Lightning", rarity: 4 }, - 1009: { name: "Asta", path: "Harmony", element: "Fire", rarity: 4 }, - 1013: { name: "Herta", path: "Erudition", element: "Ice", rarity: 4 }, + 1001: { + names: { en: "March 7th", th: "March 7th (มาร์ช)", "zh-CN": "三月七", "zh-TW": "三月七", ja: "三月なのか", ko: "March 7th", ru: "Март 7" }, + path: "Preservation", + element: "Ice", + rarity: 4 + }, + 1224: { + names: { en: "March 7th (The Hunt)", th: "March 7th (ล่าสังหาร)", "zh-CN": "三月七 (巡猎)", "zh-TW": "三月七 (巡獵)", ja: "三月なのか (巡狩)", ko: "March 7th (수렵)", ru: "Март 7 (Охота)" }, + path: "Hunt", + element: "Imaginary", + rarity: 4 + }, + 1002: { + names: { en: "Dan Heng", th: "Dan Heng (ดันเฮง)", "zh-CN": "丹恒", "zh-TW": "丹恆", ja: "丹恒", ko: "단항", ru: "Дань Хэн" }, + path: "Hunt", + element: "Wind", + rarity: 4 + }, + 1003: { + names: { en: "Himeko", th: "Himeko (ฮิเมโกะ)", "zh-CN": "姬子", "zh-TW": "姬子", ja: "姫子", ko: "히메코", ru: "Химеко" }, + path: "Erudition", + element: "Fire", + rarity: 5 + }, + 1004: { + names: { en: "Welt", th: "Welt (เวลท์)", "zh-CN": "瓦尔特", "zh-TW": "瓦爾特", ja: "ヴェルト", ko: "웰트", ru: "Вельт" }, + path: "Nihility", + element: "Imaginary", + rarity: 5 + }, + 1008: { + names: { en: "Arlan", th: "Arlan (อาร์ลัน)", "zh-CN": "阿兰", "zh-TW": "阿蘭", ja: "アーラン", ko: "아를란", ru: "Арлан" }, + path: "Destruction", + element: "Lightning", + rarity: 4 + }, + 1009: { + names: { en: "Asta", th: "Asta (แอสต้า)", "zh-CN": "艾丝妲", "zh-TW": "艾絲妲", ja: "アスター", ko: "아스타", ru: "Аста" }, + path: "Harmony", + element: "Fire", + rarity: 4 + }, + 1013: { + names: { en: "Herta", th: "Herta (เฮอร์ทา)", "zh-CN": "黑塔", "zh-TW": "黑塔", ja: "ヘルタ", ko: "헤르타", ru: "Герта" }, + path: "Erudition", + element: "Ice", + rarity: 4 + }, // Belobog - 1101: { name: "Bronya", path: "Harmony", element: "Wind", rarity: 5 }, - 1102: { name: "Seele", path: "Hunt", element: "Quantum", rarity: 5 }, - 1103: { name: "Serval", path: "Erudition", element: "Lightning", rarity: 4 }, - 1104: { name: "Gepard", path: "Preservation", element: "Ice", rarity: 5 }, - 1105: { name: "Natasha", path: "Abundance", element: "Physical", rarity: 4 }, - 1106: { name: "Pela", path: "Nihility", element: "Ice", rarity: 4 }, - 1107: { name: "Clara", path: "Destruction", element: "Physical", rarity: 5 }, - 1108: { name: "Sampo", path: "Nihility", element: "Wind", rarity: 4 }, - 1109: { name: "Hook", path: "Destruction", element: "Fire", rarity: 4 }, - 1110: { name: "Lynx", path: "Abundance", element: "Quantum", rarity: 4 }, - 1111: { name: "Luka", path: "Nihility", element: "Physical", rarity: 4 }, - 1112: { name: "Topaz & Numby", path: "Hunt", element: "Fire", rarity: 5 }, + 1101: { + names: { en: "Bronya", th: "Bronya (โบรเนีย)", "zh-CN": "布洛妮娅", "zh-TW": "布洛妮婭", ja: "ブローニャ", ko: "브로냐", ru: "Броня" }, + path: "Harmony", + element: "Wind", + rarity: 5 + }, + 1102: { + names: { en: "Seele", th: "Seele (เซเล่)", "zh-CN": "希儿", "zh-TW": "希兒", ja: "ゼーレ", ko: "제레", ru: "Зеле" }, + path: "Hunt", + element: "Quantum", + rarity: 5 + }, + 1103: { + names: { en: "Serval", th: "Serval (เซอวัล)", "zh-CN": "希露瓦", "zh-TW": "希露瓦", ja: "セーバル", ko: "서벌", ru: "Сервал" }, + path: "Erudition", + element: "Lightning", + rarity: 4 + }, + 1104: { + names: { en: "Gepard", th: "Gepard (เกพาร์ด)", "zh-CN": "杰帕德", "zh-TW": "傑帕德", ja: "ジェパード", ko: "게파드", ru: "Гепард" }, + path: "Preservation", + element: "Ice", + rarity: 5 + }, + 1105: { + names: { en: "Natasha", th: "Natasha (นาตาชา)", "zh-CN": "娜塔莎", "zh-TW": "娜塔莎", ja: "ナターシャ", ko: "나타샤", ru: "Наташа" }, + path: "Abundance", + element: "Physical", + rarity: 4 + }, + 1106: { + names: { en: "Pela", th: "Pela (เพล่า)", "zh-CN": "佩拉", "zh-TW": "佩拉", ja: "ペラ", ko: "페라", ru: "Пела" }, + path: "Nihility", + element: "Ice", + rarity: 4 + }, + 1107: { + names: { en: "Clara", th: "Clara (คลาร่า)", "zh-CN": "克拉拉", "zh-TW": "克拉拉", ja: "クラーラ", ko: "클라라", ru: "Клара" }, + path: "Destruction", + element: "Physical", + rarity: 5 + }, + 1108: { + names: { en: "Sampo", th: "Sampo (ซัมโป)", "zh-CN": "桑博", "zh-TW": "桑博", ja: "サンポ", ko: "삼포", ru: "Сампо" }, + path: "Nihility", + element: "Wind", + rarity: 4 + }, + 1109: { + names: { en: "Hook", th: "Hook (ฮุก)", "zh-CN": "虎克", "zh-TW": "虎克", ja: "フック", ko: "후크", ru: "Хук" }, + path: "Destruction", + element: "Fire", + rarity: 4 + }, + 1110: { + names: { en: "Lynx", th: "Lynx (ลิงซ์)", "zh-CN": "玲可", "zh-TW": "玲可", ja: "リンクス", ko: "링스", ru: "Рысь" }, + path: "Abundance", + element: "Quantum", + rarity: 4 + }, + 1111: { + names: { en: "Luka", th: "Luka (ลูก้า)", "zh-CN": "卢卡", "zh-TW": "盧卡", ja: "ルカ", ko: "루카", ru: "Лука" }, + path: "Nihility", + element: "Physical", + rarity: 4 + }, + 1112: { + names: { en: "Topaz & Numby", th: "Topaz & Numby (โทพาส)", "zh-CN": "托帕&账账", "zh-TW": "托帕&帳帳", ja: "トパーズ&カブ", ko: "토파즈&복순이", ru: "Топаз и Счетовод" }, + path: "Hunt", + element: "Fire", + rarity: 5 + }, // Xianzhou Luofu - 1201: { name: "Qingque", path: "Erudition", element: "Quantum", rarity: 4 }, - 1202: { name: "Tingyun", path: "Harmony", element: "Lightning", rarity: 4 }, - 1203: { name: "Luocha", path: "Abundance", element: "Imaginary", rarity: 5 }, - 1204: { name: "Jing Yuan", path: "Erudition", element: "Lightning", rarity: 5, hasExRank: true }, - 1205: { name: "Blade", path: "Destruction", element: "Wind", rarity: 5 }, - 1206: { name: "Sushang", path: "Hunt", element: "Physical", rarity: 4 }, - 1207: { name: "Yukong", path: "Harmony", element: "Imaginary", rarity: 4 }, - 1208: { name: "Fu Xuan", path: "Preservation", element: "Quantum", rarity: 5 }, - 1209: { name: "Yanqing", path: "Hunt", element: "Ice", rarity: 5 }, - 1210: { name: "Guinaifen", path: "Nihility", element: "Fire", rarity: 4 }, - 1211: { name: "Bailu", path: "Abundance", element: "Lightning", rarity: 5 }, - 1212: { name: "Jingliu", path: "Destruction", element: "Ice", rarity: 5 }, - 1213: { name: "Dan Heng • Imbibitor Lunae", path: "Destruction", element: "Imaginary", rarity: 5, hasExRank: true }, - 1214: { name: "Xueyi", path: "Destruction", element: "Quantum", rarity: 4 }, - 1215: { name: "Hanya", path: "Harmony", element: "Physical", rarity: 4 }, - 1217: { name: "Huohuo", path: "Abundance", element: "Wind", rarity: 5 }, - 1218: { name: "Jiaoqiu", path: "Nihility", element: "Fire", rarity: 5 }, - 1220: { name: "Feixiao", path: "Hunt", element: "Wind", rarity: 5 }, - 1221: { name: "Yunli", path: "Destruction", element: "Physical", rarity: 5 }, - 1222: { name: "Lingsha", path: "Abundance", element: "Fire", rarity: 5 }, - 1223: { name: "Moze", path: "Hunt", element: "Lightning", rarity: 4 }, - 1225: { name: "Fugue", path: "Nihility", element: "Fire", rarity: 5 }, + 1201: { + names: { en: "Qingque", th: "Qingque (ชิงเชว่)", "zh-CN": "青雀", "zh-TW": "青雀", ja: "青雀", ko: "청작", ru: "Цинцюэ" }, + path: "Erudition", + element: "Quantum", + rarity: 4 + }, + 1202: { + names: { en: "Tingyun", th: "Tingyun (ถิงหยุน)", "zh-CN": "停云", "zh-TW": "停雲", ja: "停雲", ko: "정운", ru: "Тинъюнь" }, + path: "Harmony", + element: "Lightning", + rarity: 4 + }, + 1203: { + names: { en: "Luocha", th: "Luocha (หลัวชา)", "zh-CN": "罗刹", "zh-TW": "羅剎", ja: "羅刹", ko: "나찰", ru: "Лоча" }, + path: "Abundance", + element: "Imaginary", + rarity: 5 + }, + 1204: { + names: { en: "Jing Yuan", th: "Jing Yuan (จิ่งหยวน)", "zh-CN": "景元", "zh-TW": "景元", ja: "景元", ko: "경원", ru: "Цзин Юань" }, + path: "Erudition", + element: "Lightning", + rarity: 5, + hasExRank: true + }, + 1205: { + names: { en: "Blade", th: "Blade (เบลด)", "zh-CN": "刃", "zh-TW": "刃", ja: "刃", ko: "블레이드", ru: "Блэйд" }, + path: "Destruction", + element: "Wind", + rarity: 5 + }, + 1206: { + names: { en: "Sushang", th: "Sushang (ซู่ซาง)", "zh-CN": "素裳", "zh-TW": "素裳", ja: "素裳", ko: "소상", ru: "Сушан" }, + path: "Hunt", + element: "Physical", + rarity: 4 + }, + 1207: { + names: { en: "Yukong", th: "Yukong (ยู่คง)", "zh-CN": "驭空", "zh-TW": "馭空", ja: "御空", ko: "어공", ru: "Юйкун" }, + path: "Harmony", + element: "Imaginary", + rarity: 4 + }, + 1208: { + names: { en: "Fu Xuan", th: "Fu Xuan (ฟู่เสวียน)", "zh-CN": "符玄", "zh-TW": "符玄", ja: "符玄", ko: "부현", ru: "Фу Сюань" }, + path: "Preservation", + element: "Quantum", + rarity: 5 + }, + 1209: { + names: { en: "Yanqing", th: "Yanqing (เยี่ยนชิง)", "zh-CN": "彦卿", "zh-TW": "彥卿", ja: "彦卿", ko: "연경", ru: "Яньцин" }, + path: "Hunt", + element: "Ice", + rarity: 5 + }, + 1210: { + names: { en: "Guinaifen", th: "Guinaifen (กุ้ยหน่ายเฟิน)", "zh-CN": "桂乃芬", "zh-TW": "桂乃芬", ja: "桂乃芬", ko: "계네빈", ru: "Гуйнайфэнь" }, + path: "Nihility", + element: "Fire", + rarity: 4 + }, + 1211: { + names: { en: "Bailu", th: "Bailu (ไป่ลู่)", "zh-CN": "白露", "zh-TW": "白露", ja: "白露", ko: "백로", ru: "Байлу" }, + path: "Abundance", + element: "Lightning", + rarity: 5 + }, + 1212: { + names: { en: "Jingliu", th: "Jingliu (จิ้งหลิว)", "zh-CN": "镜流", "zh-TW": "鏡流", ja: "鏡流", ko: "경류", ru: "Цзинлю" }, + path: "Destruction", + element: "Ice", + rarity: 5 + }, + 1213: { + names: { en: "Dan Heng • Imbibitor Lunae", th: "Dan Heng • IL (ดันเฮง จ้าวยลจันทรา)", "zh-CN": "丹恒·饮月", "zh-TW": "丹恆·飲月", ja: "丹恒・飲月", ko: "단항·음월", ru: "Дань Хэн: Пожиратель Луны" }, + path: "Destruction", + element: "Imaginary", + rarity: 5, + hasExRank: true + }, + 1214: { + names: { en: "Xueyi", th: "Xueyi (เสวียอี้)", "zh-CN": "雪衣", "zh-TW": "雪衣", ja: "雪衣", ko: "설의", ru: "Сюэи" }, + path: "Destruction", + element: "Quantum", + rarity: 4 + }, + 1215: { + names: { en: "Hanya", th: "Hanya (ฮั่นหยา)", "zh-CN": "寒鸦", "zh-TW": "寒鴉", ja: "寒鴉", ko: "한아", ru: "Ханья" }, + path: "Harmony", + element: "Physical", + rarity: 4 + }, + 1217: { + names: { en: "Huohuo", th: "Huohuo (ฮั่วฮั่ว)", "zh-CN": "藿藿", "zh-TW": "藿藿", ja: "フォフォ", ko: "곽향", ru: "Хохо" }, + path: "Abundance", + element: "Wind", + rarity: 5 + }, + 1218: { + names: { en: "Jiaoqiu", th: "Jiaoqiu (เจียวชิว)", "zh-CN": "椒丘", "zh-TW": "椒丘", ja: "椒丘", ko: "초구", ru: "Цзяоцю" }, + path: "Nihility", + element: "Fire", + rarity: 5 + }, + 1220: { + names: { en: "Feixiao", th: "Feixiao (เฟยเซียว)", "zh-CN": "飞霄", "zh-TW": "飛霄", ja: "飛霄", ko: "비소", ru: "Фэйсяо" }, + path: "Hunt", + element: "Wind", + rarity: 5 + }, + 1221: { + names: { en: "Yunli", th: "Yunli (หยุนหลี่)", "zh-CN": "云璃", "zh-TW": "雲璃", ja: "雲璃", ko: "운리", ru: "Юньли" }, + path: "Destruction", + element: "Physical", + rarity: 5 + }, + 1222: { + names: { en: "Lingsha", th: "Lingsha (หลิงซา)", "zh-CN": "灵砂", "zh-TW": "靈砂", ja: "霊砂", ko: "영사", ru: "Линша" }, + path: "Abundance", + element: "Fire", + rarity: 5 + }, + 1223: { + names: { en: "Moze", th: "Moze (มั่วเจ๋อ)", "zh-CN": "貊泽", "zh-TW": "貊澤", ja: "モゼ", ko: "맥택", ru: "Моцзэ" }, + path: "Hunt", + element: "Lightning", + rarity: 4 + }, + 1225: { + names: { en: "Fugue", th: "Fugue (ฟูก)", "zh-CN": "忘归人", "zh-TW": "忘歸人", ja: "帰忘の流離人", ko: "망귀인", ru: "Фуга" }, + path: "Nihility", + element: "Fire", + rarity: 5 + }, // Penacony & Stellar Hunters - 1005: { name: "Kafka", path: "Nihility", element: "Lightning", rarity: 5 }, - 1006: { name: "Silver Wolf", path: "Nihility", element: "Quantum", rarity: 5 }, - 1301: { name: "Gallagher", path: "Abundance", element: "Fire", rarity: 4 }, - 1302: { name: "Argenti", path: "Erudition", element: "Physical", rarity: 5 }, - 1303: { name: "Ruan Mei", path: "Harmony", element: "Ice", rarity: 5 }, - 1304: { name: "Aventurine", path: "Preservation", element: "Imaginary", rarity: 5 }, - 1305: { name: "Dr. Ratio", path: "Hunt", element: "Imaginary", rarity: 5 }, - 1306: { name: "Sparkle", path: "Harmony", element: "Quantum", rarity: 5 }, - 1307: { name: "Black Swan", path: "Nihility", element: "Wind", rarity: 5 }, - 1308: { name: "Acheron", path: "Nihility", element: "Lightning", rarity: 5, hasExRank: true }, - 1309: { name: "Robin", path: "Harmony", element: "Physical", rarity: 5 }, - 1310: { name: "Firefly", path: "Destruction", element: "Fire", rarity: 5 }, - 1312: { name: "Misha", path: "Destruction", element: "Ice", rarity: 4 }, - 1313: { name: "Sunday", path: "Harmony", element: "Imaginary", rarity: 5 }, - 1314: { name: "Jade", path: "Erudition", element: "Quantum", rarity: 5 }, - 1315: { name: "Boothill", path: "Hunt", element: "Physical", rarity: 5 }, - 1317: { name: "Rappa", path: "Erudition", element: "Imaginary", rarity: 5 }, + 1005: { + names: { en: "Kafka", th: "Kafka (คาฟคา)", "zh-CN": "卡芙卡", "zh-TW": "卡芙卡", ja: "カフカ", ko: "카프카", ru: "Кафка" }, + path: "Nihility", + element: "Lightning", + rarity: 5 + }, + 1006: { + names: { en: "Silver Wolf", th: "Silver Wolf (ซิลเวอร์วูล์ฟ)", "zh-CN": "银狼", "zh-TW": "銀狼", ja: "銀狼", ko: "은랑", ru: "Серебряный Волк" }, + path: "Nihility", + element: "Quantum", + rarity: 5 + }, + 1301: { + names: { en: "Gallagher", th: "Gallagher (กัลลาเกอร์)", "zh-CN": "加拉赫", "zh-TW": "加拉赫", ja: "ギャラガー", ko: "갤러거", ru: "Галлахер" }, + path: "Abundance", + element: "Fire", + rarity: 4 + }, + 1302: { + names: { en: "Argenti", th: "Argenti (อาร์เจนติ)", "zh-CN": "银枝", "zh-TW": "銀枝", ja: "アルジェンティ", ko: "아젠티", ru: "Аргенти" }, + path: "Erudition", + element: "Physical", + rarity: 5 + }, + 1303: { + names: { en: "Ruan Mei", th: "Ruan Mei (หร่วนเหมย)", "zh-CN": "阮·梅", "zh-TW": "阮·梅", ja: "ルアン・メェイ", ko: "완·매", ru: "Жуань Мэй" }, + path: "Harmony", + element: "Ice", + rarity: 5 + }, + 1304: { + names: { en: "Aventurine", th: "Aventurine (อเวนจูรีน)", "zh-CN": "砂金", "zh-TW": "砂金", ja: "アベンチュリン", ko: "어벤츄린", ru: "Авантюрин" }, + path: "Preservation", + element: "Imaginary", + rarity: 5 + }, + 1305: { + names: { en: "Dr. Ratio", th: "Dr. Ratio (ดร.เรโช)", "zh-CN": "真理医生", "zh-TW": "真理醫生", ja: "Dr.レイシオ", ko: "Dr. 레이시오", ru: "Д-р Рацио" }, + path: "Hunt", + element: "Imaginary", + rarity: 5 + }, + 1306: { + names: { en: "Sparkle", th: "Sparkle (สปาร์เคิล)", "zh-CN": "花火", "zh-TW": "花火", ja: "花火", ko: "스파클", ru: "Искорка" }, + path: "Harmony", + element: "Quantum", + rarity: 5 + }, + 1307: { + names: { en: "Black Swan", th: "Black Swan (แบล็กสวอน)", "zh-CN": "黑天鹅", "zh-TW": "黑天鵝", ja: "ブラックスワン", ko: "블랙 스완", ru: "Чёрный Лебедь" }, + path: "Nihility", + element: "Wind", + rarity: 5 + }, + 1308: { + names: { en: "Acheron", th: "Acheron (อาเคอรอน)", "zh-CN": "黄泉", "zh-TW": "黃泉", ja: "黄泉", ko: "아케론", ru: "Ахерон" }, + path: "Nihility", + element: "Lightning", + rarity: 5, + hasExRank: true + }, + 1309: { + names: { en: "Robin", th: "Robin (โรบิน)", "zh-CN": "知更鸟", "zh-TW": "知更鳥", ja: "ロビン", ko: "로빈", ru: "Зарянка" }, + path: "Harmony", + element: "Physical", + rarity: 5 + }, + 1310: { + names: { en: "Firefly", th: "Firefly (ไฟร์ฟลาย)", "zh-CN": "流萤", "zh-TW": "流螢", ja: "ホタル", ko: "반디", ru: "Светлячок" }, + path: "Destruction", + element: "Fire", + rarity: 5 + }, + 1312: { + names: { en: "Misha", th: "Misha (มิชา)", "zh-CN": "米沙", "zh-TW": "米沙", ja: "ミーシャ", ko: "미샤", ru: "Миша" }, + path: "Destruction", + element: "Ice", + rarity: 4 + }, + 1313: { + names: { en: "Sunday", th: "Sunday (ซันเดย์)", "zh-CN": "星期日", "zh-TW": "星期日", ja: "サンデー", ko: "선데이", ru: "Воскресенье" }, + path: "Harmony", + element: "Imaginary", + rarity: 5 + }, + 1314: { + names: { en: "Jade", th: "Jade (เจด)", "zh-CN": "翡翠", "zh-TW": "翡翠", ja: "ジェイド", ko: "제이드", ru: "Яшма" }, + path: "Erudition", + element: "Quantum", + rarity: 5 + }, + 1315: { + names: { en: "Boothill", th: "Boothill (บูตฮิลล์)", "zh-CN": "波提欧", "zh-TW": "波提歐", ja: "ブートヒル", ko: "부트힐", ru: "Бутхилл" }, + path: "Hunt", + element: "Physical", + rarity: 5 + }, + 1317: { + names: { en: "Rappa", th: "Rappa (รัปป้า)", "zh-CN": "乱破", "zh-TW": "亂破", ja: "乱破", ko: "라파", ru: "Раппа" }, + path: "Erudition", + element: "Imaginary", + rarity: 5 + }, // Amphoreus / 3.x+ - 1401: { name: "Aglaea", path: "Remembrance", element: "Lightning", rarity: 5 }, - 1402: { name: "The Herta", path: "Erudition", element: "Ice", rarity: 5 }, - 1403: { name: "Tribbie", path: "Harmony", element: "Quantum", rarity: 5 }, - 1404: { name: "Mydei", path: "Destruction", element: "Imaginary", rarity: 5 }, - 1405: { name: "Anaxa", path: "Erudition", element: "Wind", rarity: 5 }, - 1407: { name: "Castorice", path: "Remembrance", element: "Quantum", rarity: 5 }, - 1408: { name: "Cipher", path: "Nihility", element: "Imaginary", rarity: 5 }, - 1409: { name: "Phainon", path: "Destruction", element: "Physical", rarity: 5 }, - 1410: { name: "Hyacine", path: "Remembrance", element: "Wind", rarity: 5 } + 1401: { + names: { en: "Aglaea", th: "Aglaea (อกลาเอีย)", "zh-CN": "阿格莱雅", "zh-TW": "阿格萊雅", ja: "アグライア", ko: "아글라이아", ru: "Аглая" }, + path: "Remembrance", + element: "Lightning", + rarity: 5 + }, + 1402: { + names: { en: "The Herta", th: "The Herta (เดอะเฮอร์ทา)", "zh-CN": "大黑塔", "zh-TW": "大黑塔", ja: "マダム・ヘルタ", ko: "더 헤르타", ru: "Великая Герта" }, + path: "Erudition", + element: "Ice", + rarity: 5 + }, + 1403: { + names: { en: "Tribbie", th: "Tribbie (ทริบบี้)", "zh-CN": "特里比", "zh-TW": "特里比", ja: "トリビー", ko: "트리비", ru: "Трибби" }, + path: "Harmony", + element: "Quantum", + rarity: 5 + }, + 1404: { + names: { en: "Mydei", th: "Mydei (ไมเดย์)", "zh-CN": "麦狄", "zh-TW": "麥狄", ja: "マイディ", ko: "마이데이", ru: "Мидей" }, + path: "Destruction", + element: "Imaginary", + rarity: 5 + }, + 1405: { + names: { en: "Anaxa", th: "Anaxa (อนากซา)", "zh-CN": "阿那克萨", "zh-TW": "阿那克薩", ja: "アナクサ", ko: "아낙사", ru: "Анакса" }, + path: "Erudition", + element: "Wind", + rarity: 5 + }, + 1407: { + names: { en: "Castorice", th: "Castorice (คาสโตริเซ่)", "zh-CN": "遐蝶", "zh-TW": "遐蝶", ja: "カストリセ", ko: "카스토리체", ru: "Касторисе" }, + path: "Remembrance", + element: "Quantum", + rarity: 5 + }, + 1408: { + names: { en: "Cipher", th: "Cipher (ไซเฟอร์)", "zh-CN": "赛弗", "zh-TW": "賽弗", ja: "サイファー", ko: "사이퍼", ru: "Сайфер" }, + path: "Nihility", + element: "Imaginary", + rarity: 5 + }, + 1409: { + names: { en: "Phainon", th: "Phainon (ฟานอน)", "zh-CN": "法埃农", "zh-TW": "法埃農", ja: "ファイノン", ko: "파이논", ru: "Файнон" }, + path: "Destruction", + element: "Physical", + rarity: 5 + }, + 1410: { + names: { en: "Hyacine", th: "Hyacine (ไฮยาซีน)", "zh-CN": "风信子", "zh-TW": "風信子", ja: "ヒヤシンス", ko: "히아신스", ru: "Гиацинт" }, + path: "Remembrance", + element: "Wind", + rarity: 5 + } }; -export function getAvatarInfo(avatarId) { - return AVATAR_METADATA[avatarId] || { - name: `Avatar ${avatarId}`, - path: "Unknown", - element: "Unknown", - rarity: 4 +export function getAvatarInfo(avatarId, langOverride = null) { + const lang = langOverride || getCurrentLanguage(); + const meta = AVATAR_METADATA[avatarId]; + + if (!meta) { + return { + name: `Avatar ${avatarId}`, + path: translatePath("Unknown"), + element: translateElement("Unknown"), + rarity: 4, + hasExRank: false + }; + } + + const localizedName = meta.names?.[lang] || meta.names?.en || meta.names?.th || `Avatar ${avatarId}`; + + return { + name: localizedName, + path: translatePath(meta.path), + element: translateElement(meta.element), + rarity: meta.rarity, + hasExRank: !!meta.hasExRank }; } diff --git a/js/i18n.js b/js/i18n.js new file mode 100644 index 0000000..292fbd5 --- /dev/null +++ b/js/i18n.js @@ -0,0 +1,1311 @@ +// Multi-language (i18n) definitions for GaC-srtool +// Covers all 13 official languages supported by Honkai: Star Rail + +export const SUPPORTED_LANGUAGES = [ + { code: 'th', name: 'ภาษาไทย (Thai)', flag: '🇹🇭' }, + { code: 'en', name: 'English', flag: '🇺🇸' }, + { code: 'zh-CN', name: '简体中文 (Simplified Chinese)', flag: '🇨🇳' }, + { code: 'zh-TW', name: '繁體中文 (Traditional Chinese)', flag: '🇹🇼' }, + { code: 'ja', name: '日本語 (Japanese)', flag: '🇯🇵' }, + { code: 'ko', name: '한국어 (Korean)', flag: '🇰🇷' }, + { code: 'vi', name: 'Tiếng Việt (Vietnamese)', flag: '🇻🇳' }, + { code: 'id', name: 'Bahasa Indonesia (Indonesian)', flag: '🇮🇩' }, + { code: 'es', name: 'Español (Spanish)', flag: '🇪🇸' }, + { code: 'fr', name: 'Français (French)', flag: '🇫🇷' }, + { code: 'de', name: 'Deutsch (German)', flag: '🇩🇪' }, + { code: 'ru', name: 'Русский (Russian)', flag: '🇷🇺' }, + { code: 'pt', name: 'Português (Portuguese)', flag: '🇧🇷' } +]; + +export const TRANSLATIONS = { + th: { + // Header + appName: "GaC-Srtool", + appSubtitle: "Star Rail FreeSR & Server Controller", + online: "เชื่อมต่อแล้ว (Online)", + offline: "ออฟไลน์ (Offline)", + checking: "กำลังตรวจสอบ...", + refresh: "🔄 รีเฟรช", + connectFailed: "เชื่อมต่อไม่สำเร็จ", + // Tabs + tabDashboard: "📊 แดชบอร์ด (Overview)", + tabAvatars: "👥 ตัวละคร (Avatars)", + tabExrank: "⚡ Ex-Rank (สกิลพิเศษ)", + tabTeleport: "🚀 วาร์ปฉาก (Teleport)", + tabJson: "📝 จัดการไฟล์ JSON", + tabSettings: "⚙️ ตั้งค่า & คู่มือ Host", + // Dashboard + statAvatars: "ตัวละครที่ครอบครอง", + statLightcones: "กรวยแสง (Lightcones)", + statRelics: "รีลิกส์ (Relics)", + serverStatusTitle: "📍 สถานะเซิร์ฟเวอร์ & ตำแหน่งปัจจุบัน", + quickActionsTitle: "⚡ ดำเนินการด่วน (Quick Actions)", + quickActionsSubtitle: "สั่งการส่งไปยัง REST API Gateway ทันที", + btnMaxAll: "⭐ ปรับเลเวล 80 & ปลด E6 ตัวละครทั้งหมด", + btnWarpExpress: "🚂 วาร์ปกลับรถไฟ Astral Express ทันที", + btnSyncPersistent: "💾 ซิงค์ข้อมูล Persistent ล่าสุด", + currentLineupTitle: "🎮 ทีมปัจจุบัน (Current Lineup)", + slot: "ตำแหน่งที่", + slotEmpty: "(ว่าง)", + coords: "พิกัดตัวละคร (X, Y, Z)", + // Avatars + searchPlaceholder: "🔍 ค้นหาชื่อหรือ ID ตัวละคร...", + filterAllRarity: "ทุกระดับดาว", + filter5Star: "5 ดาว (SSR)", + filter4Star: "4 ดาว (SR)", + btnReload: "🔄 รีโหลด", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "ยืนยันปรับตัวละครทั้งหมดให้เป็นเลเวล 80 และปลด E6 หรือไม่?", + maxAllSuccess: "ปรับ Max ทุกตัวละครสำเร็จแล้ว!", + avatarRankSuccess: "ปรับตัวละคร {id} เป็น E{rank} สำเร็จ", + // Ex-Rank + exrankTitle: "⚡ ระบบปลดล็อค Ex-Rank Skill", + exrankSubtitle: "เปิดใช้งานพรสวรรค์และกลไกพิเศษ Ex-Rank สำหรับตัวละครเฉพาะใน FreeSR (เช่น Jing Yuan โดน CC ไม่หยุดชะงัก, Dan Heng IL, Acheron)", + btnEnableAll: "เปิด Ex-Rank ทั้งหมด", + btnDisableAll: "ปิด Ex-Rank ทั้งหมด", + exrankToggleSuccess: "{name}: {status} Ex-Rank สำเร็จ", + exrankAllSuccess: "{status} Ex-Rank ทุกตัวละครสำเร็จ", + enabled: "เปิดใช้งาน", + disabled: "ปิดใช้งาน", + // Teleport + presetsTitle: "📍 จุดวาร์ปปลอดภัยยอดนิยม (Safe Presets)", + presetsSubtitle: "คลิกจุดวาร์ปเพื่อย้ายฉากของผู้เล่นในไฟล์เซฟได้ทันที", + customTeleportTitle: "🎯 กำหนดพิกัดวาร์ปเอง (Custom Teleport)", + customTeleportSubtitle: "ใส่ PlaneID, FloorID และ EntryID ตามต้องการ", + btnExecuteWarp: "🚀 ยืนยันการวาร์ป (Execute Teleport)", + warpBtn: "🚀 วาร์ป", + warpSuccess: "วาร์ปไปยัง {label} สำเร็จ (บันทึกลง Persistent)", + warpFailed: "วาร์ปไม่สำเร็จ: {err}", + // JSON + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (Save)", + btnBeautify: "✨ จัดรูปแบบ JSON", + btnDownload: "📥 ดาวน์โหลด Backup", + btnUpload: "📤 อัปโหลดไฟล์", + btnSaveServer: "💾 บันทึกไปยังเซิร์ฟเวอร์", + jsonTip: "Tip: สามารถแก้ไขค่าดิบแล้วกด 'บันทึกไปยังเซิร์ฟเวอร์' ได้ทันที", + jsonStatusReady: "พร้อมใช้งาน", + jsonStatusOpening: "กำลังเปิด: {name}", + jsonSaveSuccess: "บันทึกไฟล์ {name} เรียบร้อยแล้ว", + jsonInvalid: "JSON ไม่ถูกต้อง", + // Settings + apiSettingsTitle: "⚙️ ตั้งค่าการเชื่อมต่อ API Gateway", + apiSettingsSubtitle: "ปรับเปลี่ยนพอร์ตหรือ IP ได้ตามไฟล์ server.json ของคุณ", + lblApiGatewayUrl: "REST API Gateway URL", + lblPingInterval: "ความถี่ในการตรวจสอบสถานะ (วินาที)", + btnSaveSettings: "💾 บันทึกการตั้งค่า", + btnResetDefault: "คืนค่าเริ่มต้น", + hostGuideTitle: "🌐 วิธีนำขึ้นโฮสต์ GitHub Pages (ฟรี 100%)", + hostGuideSubtitle: "สามารถเปิดใช้งานเว็บนี้บนอินเทอร์เน็ตได้โดยไม่ต้องเสียค่าโฮสต์ใดๆ", + settingsSaved: "บันทึกการตั้งค่าสำเร็จ!", + settingsReset: "คืนค่าเริ่มต้นเรียบร้อย", + // Elements & Paths + elements: { + Physical: "กายภาพ", + Fire: "ไฟ", + Ice: "น้ำแข็ง", + Lightning: "สายฟ้า", + Wind: "ลม", + Quantum: "ควอนตัม", + Imaginary: "จินตภาพ", + Unknown: "ไม่ระบุ" + }, + paths: { + Destruction: "ทำลายล้าง", + Hunt: "ล่าสังหาร", + Erudition: "ปัญญา", + Harmony: "ประสาน", + Nihility: "ลบล้าง", + Preservation: "อนุรักษ์", + Abundance: "เฟื่องฟู", + Remembrance: "ความทรงจำ", + Unknown: "ไม่ระบุ" + } + }, + + en: { + appName: "GaC-Srtool", + appSubtitle: "Star Rail FreeSR & Server Controller", + online: "Online", + offline: "Offline", + checking: "Checking...", + refresh: "🔄 Refresh", + connectFailed: "Connection Failed", + tabDashboard: "📊 Dashboard", + tabAvatars: "👥 Avatars", + tabExrank: "⚡ Ex-Rank Skills", + tabTeleport: "🚀 Teleport", + tabJson: "📝 JSON Management", + tabSettings: "⚙️ Settings & Guide", + statAvatars: "Owned Avatars", + statLightcones: "Lightcones", + statRelics: "Relics", + serverStatusTitle: "📍 Server Status & Current Position", + quickActionsTitle: "⚡ Quick Actions", + quickActionsSubtitle: "Send command directly to REST API Gateway", + btnMaxAll: "⭐ Max All Avatars (Lv. 80 & E6)", + btnWarpExpress: "🚂 Warp to Astral Express Parlor Car", + btnSyncPersistent: "💾 Sync Persistent Data", + currentLineupTitle: "🎮 Current Lineup", + slot: "Slot", + slotEmpty: "(Empty)", + coords: "Coordinates (X, Y, Z)", + searchPlaceholder: "🔍 Search name or ID...", + filterAllRarity: "All Rarities", + filter5Star: "5-Star (SSR)", + filter4Star: "4-Star (SR)", + btnReload: "🔄 Reload", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "Upgrade all avatars to Level 80 and unlock E6?", + maxAllSuccess: "All avatars maximized successfully!", + avatarRankSuccess: "Updated avatar {id} to E{rank}", + exrankTitle: "⚡ Ex-Rank Skills System", + exrankSubtitle: "Toggle special Ex-Rank talents and perks in FreeSR (e.g. Jing Yuan CC immunity, Dan Heng IL, Acheron)", + btnEnableAll: "Enable All Ex-Ranks", + btnDisableAll: "Disable All Ex-Ranks", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "All avatars Ex-Rank {status}", + enabled: "enabled", + disabled: "disabled", + presetsTitle: "📍 Safe Presets", + presetsSubtitle: "Click to warp player scene and entry point instantly", + customTeleportTitle: "🎯 Custom Coordinates", + customTeleportSubtitle: "Specify PlaneID, FloorID, EntryID and coordinates", + btnExecuteWarp: "🚀 Execute Teleport", + warpBtn: "🚀 Warp", + warpSuccess: "Warped to {label} successfully (saved to Persistent)", + warpFailed: "Teleport failed: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (Save)", + btnBeautify: "✨ Beautify JSON", + btnDownload: "📥 Download Backup", + btnUpload: "📤 Upload File", + btnSaveServer: "💾 Save to Server", + jsonTip: "Tip: Edit raw JSON and click 'Save to Server' to apply instantly", + jsonStatusReady: "Ready", + jsonStatusOpening: "Opening: {name}", + jsonSaveSuccess: "File {name} saved successfully", + jsonInvalid: "Invalid JSON format", + apiSettingsTitle: "⚙️ API Gateway Connection Settings", + apiSettingsSubtitle: "Adjust port or IP according to your server.json", + lblApiGatewayUrl: "REST API Gateway URL", + lblPingInterval: "Health Check Interval (seconds)", + btnSaveSettings: "💾 Save Settings", + btnResetDefault: "Reset Defaults", + hostGuideTitle: "🌐 How to Host on GitHub Pages (100% Free)", + hostGuideSubtitle: "Host and run this dashboard globally on GitHub with zero hosting cost", + settingsSaved: "Settings saved successfully!", + settingsReset: "Reset to default settings", + elements: { + Physical: "Physical", + Fire: "Fire", + Ice: "Ice", + Lightning: "Lightning", + Wind: "Wind", + Quantum: "Quantum", + Imaginary: "Imaginary", + Unknown: "Unknown" + }, + paths: { + Destruction: "Destruction", + Hunt: "Hunt", + Erudition: "Erudition", + Harmony: "Harmony", + Nihility: "Nihility", + Preservation: "Preservation", + Abundance: "Abundance", + Remembrance: "Remembrance", + Unknown: "Unknown" + } + }, + + "zh-CN": { + appName: "GaC-Srtool", + appSubtitle: "星穹铁道 FreeSR 伴侣管理后台", + online: "在线 (Online)", + offline: "离线 (Offline)", + checking: "检查中...", + refresh: "🔄 刷新", + connectFailed: "连接失败", + tabDashboard: "📊 仪表盘", + tabAvatars: "👥 角色管理", + tabExrank: "⚡ 特殊命途 (Ex-Rank)", + tabTeleport: "🚀 场景传送", + tabJson: "📝 JSON 数据", + tabSettings: "⚙️ 设置与指南", + statAvatars: "已拥有角色", + statLightcones: "光锥数量", + statRelics: "遗器数量", + serverStatusTitle: "📍 服务器状态与当前位置", + quickActionsTitle: "⚡ 快捷操作", + quickActionsSubtitle: "即时下发指令至 REST API 网关", + btnMaxAll: "⭐ 全角色满级 (Lv.80) & 满命 (E6)", + btnWarpExpress: "🚂 立即传送回星穹列车观景车厢", + btnSyncPersistent: "💾 同步最新 Persistent 存档", + currentLineupTitle: "🎮 当前编队 (Lineup)", + slot: "位置", + slotEmpty: "(空位)", + coords: "角色坐标 (X, Y, Z)", + searchPlaceholder: "🔍 搜索角色名称或 ID...", + filterAllRarity: "所有星级", + filter5Star: "5星 (SSR)", + filter4Star: "4星 (SR)", + btnReload: "🔄 重新载入", + eidolonLabel: "星魂等级 (E):", + confirmMaxAll: "确定要将所有角色设为 80 级并解锁 6 命吗?", + maxAllSuccess: "全角色强化完成!", + avatarRankSuccess: "角色 {id} 已设置为 E{rank}", + exrankTitle: "⚡ Ex-Rank 特殊技能机制", + exrankSubtitle: "在 FreeSR 中启用专属 Ex-Rank 特权天赋(如景元免受控制打断、丹恒·饮月、黄泉)", + btnEnableAll: "全部启用 Ex-Rank", + btnDisableAll: "全部关闭 Ex-Rank", + exrankToggleSuccess: "{name}: Ex-Rank 已{status}", + exrankAllSuccess: "全角色 Ex-Rank 已{status}", + enabled: "启用", + disabled: "关闭", + presetsTitle: "📍 常用安全传送点", + presetsSubtitle: "一键传送玩家角色并写入存档", + customTeleportTitle: "🎯 自定义坐标传送", + customTeleportSubtitle: "自由输入 PlaneID、FloorID、EntryID 及坐标", + btnExecuteWarp: "🚀 执行传送", + warpBtn: "🚀 传送", + warpSuccess: "成功传送至 {label}(已保存至 Persistent)", + warpFailed: "传送失败: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (存档)", + btnBeautify: "✨ 格式化 JSON", + btnDownload: "📥 下载备份", + btnUpload: "📤 上传文件", + btnSaveServer: "💾 保存至服务器", + jsonTip: "提示: 修改原始 JSON 后点击「保存至服务器」即时生效", + jsonStatusReady: "就绪", + jsonStatusOpening: "正在打开: {name}", + jsonSaveSuccess: "文件 {name} 已成功保存", + jsonInvalid: "无效的 JSON 格式", + apiSettingsTitle: "⚙️ API 网关连接设置", + apiSettingsSubtitle: "可根据你的 server.json 自由修改端口或局域网 IP", + lblApiGatewayUrl: "REST API 网关 URL", + lblPingInterval: "健康检查间隔 (秒)", + btnSaveSettings: "💾 保存设置", + btnResetDefault: "恢复默认值", + hostGuideTitle: "🌐 如何免费部署至 GitHub Pages (100% 免费)", + hostGuideSubtitle: "无服务器成本,一键托管至全球 CDN", + settingsSaved: "设置保存成功!", + settingsReset: "已恢复默认设置", + elements: { + Physical: "物理", + Fire: "火", + Ice: "冰", + Lightning: "雷", + Wind: "风", + Quantum: "量子", + Imaginary: "虚数", + Unknown: "未知" + }, + paths: { + Destruction: "毁灭", + Hunt: "巡猎", + Erudition: "智识", + Harmony: "同谐", + Nihility: "虚无", + Preservation: "存护", + Abundance: "丰饶", + Remembrance: "记忆", + Unknown: "未知" + } + }, + + "zh-TW": { + appName: "GaC-Srtool", + appSubtitle: "星穹鐵道 FreeSR 伴侶管理後台", + online: "線上 (Online)", + offline: "離線 (Offline)", + checking: "檢查中...", + refresh: "🔄 重新整理", + connectFailed: "連線失敗", + tabDashboard: "📊 儀表板", + tabAvatars: "👥 角色管理", + tabExrank: "⚡ 特殊命途 (Ex-Rank)", + tabTeleport: "🚀 場景傳送", + tabJson: "📝 JSON 數據", + tabSettings: "⚙️ 設定與指南", + statAvatars: "已擁有角色", + statLightcones: "光錐數量", + statRelics: "遺物數量", + serverStatusTitle: "📍 伺服器狀態與當前位置", + quickActionsTitle: "⚡ 快捷操作", + quickActionsSubtitle: "即時下發指令至 REST API 網關", + btnMaxAll: "⭐ 全角色滿級 (Lv.80) & 滿魂 (E6)", + btnWarpExpress: "🚂 立即傳送回星穹列車觀景車廂", + btnSyncPersistent: "💾 同步最新 Persistent 存檔", + currentLineupTitle: "🎮 當前編隊 (Lineup)", + slot: "位置", + slotEmpty: "(空位)", + coords: "角色座標 (X, Y, Z)", + searchPlaceholder: "🔍 搜尋角色名稱或 ID...", + filterAllRarity: "所有星級", + filter5Star: "5星 (SSR)", + filter4Star: "4星 (SR)", + btnReload: "🔄 重新載入", + eidolonLabel: "星魂等級 (E):", + confirmMaxAll: "確定要將所有角色設為 80 級並解鎖 6 魂嗎?", + maxAllSuccess: "全角色強化完成!", + avatarRankSuccess: "角色 {id} 已設置為 E{rank}", + exrankTitle: "⚡ Ex-Rank 特殊技能機制", + exrankSubtitle: "在 FreeSR 中啟用專屬 Ex-Rank 特權天賦(如景元免受控制中斷、丹恆·飲月、黃泉)", + btnEnableAll: "全部啟用 Ex-Rank", + btnDisableAll: "全部關閉 Ex-Rank", + exrankToggleSuccess: "{name}: Ex-Rank 已{status}", + exrankAllSuccess: "全角色 Ex-Rank 已{status}", + enabled: "啟用", + disabled: "關閉", + presetsTitle: "📍 常用安全傳送點", + presetsSubtitle: "一鍵傳送玩家角色並寫入存檔", + customTeleportTitle: "🎯 自訂座標傳送", + customTeleportSubtitle: "自由輸入 PlaneID、FloorID、EntryID 及座標", + btnExecuteWarp: "🚀 執行傳送", + warpBtn: "🚀 傳送", + warpSuccess: "成功傳送至 {label}(已儲存至 Persistent)", + warpFailed: "傳送失敗: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (存檔)", + btnBeautify: "✨ 格式化 JSON", + btnDownload: "📥 下載備份", + btnUpload: "📤 上傳檔案", + btnSaveServer: "💾 儲存至伺服器", + jsonTip: "提示: 修改原始 JSON 後點擊「儲存至伺服器」即時生效", + jsonStatusReady: "就緒", + jsonStatusOpening: "正在打開: {name}", + jsonSaveSuccess: "檔案 {name} 已成功儲存", + jsonInvalid: "無效的 JSON 格式", + apiSettingsTitle: "⚙️ API 網關連線設定", + apiSettingsSubtitle: "可根據你的 server.json 自由修改通訊埠或區域網路 IP", + lblApiGatewayUrl: "REST API 網關 URL", + lblPingInterval: "健康檢查間隔 (秒)", + btnSaveSettings: "💾 儲存設定", + btnResetDefault: "恢復預設值", + hostGuideTitle: "🌐 如何免費部署至 GitHub Pages (100% 免費)", + hostGuideSubtitle: "無伺服器成本,一鍵託管至全球 CDN", + settingsSaved: "設定儲存成功!", + settingsReset: "已恢復預設設定", + elements: { + Physical: "物理", + Fire: "火", + Ice: "冰", + Lightning: "雷", + Wind: "風", + Quantum: "量子", + Imaginary: "虛數", + Unknown: "未知" + }, + paths: { + Destruction: "毀滅", + Hunt: "巡獵", + Erudition: "智識", + Harmony: "同諧", + Nihility: "虛無", + Preservation: "存護", + Abundance: "豐饒", + Remembrance: "記憶", + Unknown: "未知" + } + }, + + ja: { + appName: "GaC-Srtool", + appSubtitle: "スターレイル FreeSR サーバーコントローラー", + online: "オンライン (Online)", + offline: "オフライン (Offline)", + checking: "確認中...", + refresh: "🔄 更新", + connectFailed: "接続に失敗しました", + tabDashboard: "📊 ダッシュボード", + tabAvatars: "👥 キャラクター", + tabExrank: "⚡ Ex-Rank (特殊能力)", + tabTeleport: "🚀 ワープ", + tabJson: "📝 JSON 管理", + tabSettings: "⚙️ 設定とガイド", + statAvatars: "所持キャラクター", + statLightcones: "光円錐", + statRelics: "遺物", + serverStatusTitle: "📍 サーバー状態・現在地", + quickActionsTitle: "⚡ クイックアクション", + quickActionsSubtitle: "REST APIゲートウェイへ直接コマンド送信", + btnMaxAll: "⭐ 全キャラLv.80・完凸 (E6)", + btnWarpExpress: "🚂 星穹列車・客室へ即時ワープ", + btnSyncPersistent: "💾 Persistent データを同期", + currentLineupTitle: "🎮 現在の編成", + slot: "枠", + slotEmpty: "(空き)", + coords: "座標 (X, Y, Z)", + searchPlaceholder: "🔍 キャラ名またはIDで検索...", + filterAllRarity: "全レアリティ", + filter5Star: "★5 (SSR)", + filter4Star: "★4 (SR)", + btnReload: "🔄 再読込", + eidolonLabel: "星魂 (凸数):", + confirmMaxAll: "全キャラクターをLv.80・完凸にしますか?", + maxAllSuccess: "全キャラクターを最大化しました!", + avatarRankSuccess: "キャラ {id} を E{rank} に設定しました", + exrankTitle: "⚡ Ex-Rank 特殊スキル設定", + exrankSubtitle: "FreeSR独自のEx-Rank効果を有効化(景元の行動制限無効、丹恒・飲月、黄泉など)", + btnEnableAll: "全Ex-Rank有効", + btnDisableAll: "全Ex-Rank無効", + exrankToggleSuccess: "{name}: Ex-Rank を{status}にしました", + exrankAllSuccess: "全キャラ Ex-Rank を{status}にしました", + enabled: "有効", + disabled: "無効", + presetsTitle: "📍 安全な定番ワープ地点", + presetsSubtitle: "クリックでプレイヤーのシーンを即時移動", + customTeleportTitle: "🎯 座標指定ワープ", + customTeleportSubtitle: "PlaneID、FloorID、EntryIDおよび座標を指定", + btnExecuteWarp: "🚀 ワープ実行", + warpBtn: "🚀 移動", + warpSuccess: "{label} へワープしました", + warpFailed: "ワープ失敗: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (セーブ)", + btnBeautify: "✨ JSON 整形", + btnDownload: "📥 バックアップ保存", + btnUpload: "📤 ファイル読込", + btnSaveServer: "💾 サーバーへ保存", + jsonTip: "ヒント: JSONを編集して「サーバーへ保存」を押すと即時反映されます", + jsonStatusReady: "準備完了", + jsonStatusOpening: "展開中: {name}", + jsonSaveSuccess: "{name} を正常に保存しました", + jsonInvalid: "無効なJSONフォーマットです", + apiSettingsTitle: "⚙️ API ゲートウェイ接続設定", + apiSettingsSubtitle: "server.jsonのポートまたはIPに合わせて変更可能", + lblApiGatewayUrl: "REST API ゲートウェイ URL", + lblPingInterval: "更新間隔 (秒)", + btnSaveSettings: "💾 設定を保存", + btnResetDefault: "初期値に戻す", + hostGuideTitle: "🌐 GitHub Pages 無料ホスティング手順", + hostGuideSubtitle: "サーバー費用ゼロでWeb上に公開可能", + settingsSaved: "設定を保存しました!", + settingsReset: "デフォルト設定に戻しました", + elements: { + Physical: "物理", + Fire: "炎", + Ice: "氷", + Lightning: "雷", + Wind: "風", + Quantum: "量子", + Imaginary: "虚数", + Unknown: "不明" + }, + paths: { + Destruction: "壊滅", + Hunt: "巡狩", + Erudition: "知恵", + Harmony: "調和", + Nihility: "虚無", + Preservation: "存護", + Abundance: "豊穣", + Remembrance: "記憶", + Unknown: "不明" + } + }, + + ko: { + appName: "GaC-Srtool", + appSubtitle: "스타레일 FreeSR 서버 컨트롤러", + online: "온라인 (Online)", + offline: "오프라인 (Offline)", + checking: "확인 중...", + refresh: "🔄 새로고침", + connectFailed: "연결 실패", + tabDashboard: "📊 대시보드", + tabAvatars: "👥 캐릭터", + tabExrank: "⚡ Ex-Rank (특수 스킬)", + tabTeleport: "🚀 워프 (이동)", + tabJson: "📝 JSON 관리", + tabSettings: "⚙️ 설정 및 안내", + statAvatars: "보유 캐릭터", + statLightcones: "광추", + statRelics: "유물", + serverStatusTitle: "📍 서버 상태 및 현재 위치", + quickActionsTitle: "⚡ 빠른 작업", + quickActionsSubtitle: "REST API 게이트웨이로 즉시 명령 전송", + btnMaxAll: "⭐ 전체 캐릭터 80레벨 & 6돌 (풀돌)", + btnWarpExpress: "🚂 은하열차 객실로 즉시 워프", + btnSyncPersistent: "💾 Persistent 세이브 동기화", + currentLineupTitle: "🎮 현재 파티", + slot: "슬롯", + slotEmpty: "(비어있음)", + coords: "좌표 (X, Y, Z)", + searchPlaceholder: "🔍 캐릭터 이름 또는 ID 검색...", + filterAllRarity: "모든 등급", + filter5Star: "5성 (SSR)", + filter4Star: "4성 (SR)", + btnReload: "🔄 다시 로드", + eidolonLabel: "성혼 (돌파):", + confirmMaxAll: "모든 캐릭터를 80레벨 및 6돌파로 설정하시겠습니까?", + maxAllSuccess: "모든 캐릭터 강화 완료!", + avatarRankSuccess: "캐릭터 {id} 성혼을 E{rank}로 설정했습니다", + exrankTitle: "⚡ Ex-Rank 특수 스킬 시스템", + exrankSubtitle: "FreeSR 전용 Ex-Rank 특권 활성화 (경원 제어 무시, 단항·음월, 아케론 등)", + btnEnableAll: "모든 Ex-Rank 활성화", + btnDisableAll: "모든 Ex-Rank 비활성화", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "모든 캐릭터 Ex-Rank {status}", + enabled: "활성화됨", + disabled: "비활성화됨", + presetsTitle: "📍 안전한 주요 워프 지점", + presetsSubtitle: "클릭 시 즉시 플레이어 위치 이동 및 저장", + customTeleportTitle: "🎯 커스텀 좌표 워프", + customTeleportSubtitle: "PlaneID, FloorID, EntryID 및 좌표 지정", + btnExecuteWarp: "🚀 워프 실행", + warpBtn: "🚀 이동", + warpSuccess: "{label} (으)로 이동 완료", + warpFailed: "워프 실패: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent (세이브)", + btnBeautify: "✨ JSON 정리", + btnDownload: "📥 백업 다운로드", + btnUpload: "📤 파일 불러오기", + btnSaveServer: "💾 서버에 저장", + jsonTip: "팁: JSON 편집 후 '서버에 저장'을 누르면 즉시 적용됩니다", + jsonStatusReady: "준비됨", + jsonStatusOpening: "열기: {name}", + jsonSaveSuccess: "{name} 저장 완료", + jsonInvalid: "올바르지 않은 JSON 형식입니다", + apiSettingsTitle: "⚙️ API 게이트웨이 연결 설정", + apiSettingsSubtitle: "server.json 설정에 맞추어 포트 및 IP 수정 가능", + lblApiGatewayUrl: "REST API 게이트웨이 URL", + lblPingInterval: "상태 확인 주기 (초)", + btnSaveSettings: "💾 설정 저장", + btnResetDefault: "기본값 초기화", + hostGuideTitle: "🌐 GitHub Pages 무료 배포 안내 (100% 무료)", + hostGuideSubtitle: "서버 비용 없이 GitHub에서 글로벌 호스팅 가능", + settingsSaved: "설정이 저장되었습니다!", + settingsReset: "기본값으로 복원되었습니다", + elements: { + Physical: "물리", + Fire: "화염", + Ice: "얼음", + Lightning: "번개", + Wind: "바람", + Quantum: "양자", + Imaginary: "허수", + Unknown: "알 수 없음" + }, + paths: { + Destruction: "파멸", + Hunt: "수렵", + Erudition: "지식", + Harmony: "화합", + Nihility: "공허", + Preservation: "보존", + Abundance: "풍요", + Remembrance: "기억", + Unknown: "알 수 없음" + } + }, + + vi: { + appName: "GaC-Srtool", + appSubtitle: "Bảng điều khiển Star Rail FreeSR", + online: "Trực tuyến (Online)", + offline: "Ngoại tuyến (Offline)", + checking: "Đang kiểm tra...", + refresh: "🔄 Làm mới", + connectFailed: "Kết nối thất bại", + tabDashboard: "📊 Tổng quan", + tabAvatars: "👥 Nhân vật", + tabExrank: "⚡ Kỹ năng Ex-Rank", + tabTeleport: "🚀 Dịch chuyển", + tabJson: "📝 Quản lý JSON", + tabSettings: "⚙️ Cài đặt & Hướng dẫn", + statAvatars: "Nhân vật sở hữu", + statLightcones: "Nón Ánh Sáng", + statRelics: "Di Vật", + serverStatusTitle: "📍 Trạng thái máy chủ & Vị trí", + quickActionsTitle: "⚡ Thao tác nhanh", + quickActionsSubtitle: "Gửi lệnh trực tiếp đến API Gateway", + btnMaxAll: "⭐ Tối đa cấp 80 & Tinh Hồn 6 (E6)", + btnWarpExpress: "🚂 Về Đội Tàu Astral", + btnSyncPersistent: "💾 Đồng bộ dữ liệu lưu trữ", + currentLineupTitle: "🎮 Đội hình hiện tại", + slot: "Vị trí", + slotEmpty: "(Trống)", + coords: "Tọa độ (X, Y, Z)", + searchPlaceholder: "🔍 Tìm tên hoặc ID nhân vật...", + filterAllRarity: "Tất cả độ hiếm", + filter5Star: "5 Sao (SSR)", + filter4Star: "4 Sao (SR)", + btnReload: "🔄 Tải lại", + eidolonLabel: "TINH HỒN (E):", + confirmMaxAll: "Nâng cấp tất cả nhân vật lên cấp 80 và E6?", + maxAllSuccess: "Tối đa hóa tất cả nhân vật thành công!", + avatarRankSuccess: "Đã cập nhật nhân vật {id} thành E{rank}", + exrankTitle: "⚡ Hệ thống Ex-Rank", + exrankSubtitle: "Bật đặc quyền Ex-Rank trong FreeSR (Cảnh Nguyên kháng khống chế, Đan Hằng Ẩm Nguyệt, Acheron)", + btnEnableAll: "Bật tất cả Ex-Rank", + btnDisableAll: "Tắt tất cả Ex-Rank", + exrankToggleSuccess: "{name}: Đã {status} Ex-Rank", + exrankAllSuccess: "Tất cả nhân vật đã {status} Ex-Rank", + enabled: "bật", + disabled: "tắt", + presetsTitle: "📍 Điểm dịch chuyển an toàn", + presetsSubtitle: "Nhấp để dịch chuyển vị trí người chơi ngay lập tức", + customTeleportTitle: "🎯 Tự nhập tọa độ dịch chuyển", + customTeleportSubtitle: "Nhập PlaneID, FloorID, EntryID và tọa độ", + btnExecuteWarp: "🚀 Bắt đầu dịch chuyển", + warpBtn: "🚀 Đi", + warpSuccess: "Dịch chuyển đến {label} thành công", + warpFailed: "Dịch chuyển thất bại: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Làm đẹp JSON", + btnDownload: "📥 Tải bản sao lưu", + btnUpload: "📤 Tải lên tệp", + btnSaveServer: "💾 Lưu vào máy chủ", + jsonTip: "Mẹo: Chỉnh sửa JSON và nhấn 'Lưu vào máy chủ' để áp dụng ngay", + jsonStatusReady: "Sẵn sàng", + jsonStatusOpening: "Đang mở: {name}", + jsonSaveSuccess: "Lưu tệp {name} thành công", + jsonInvalid: "Định dạng JSON không hợp lệ", + apiSettingsTitle: "⚙️ Cấu hình kết nối API Gateway", + apiSettingsSubtitle: "Điều chỉnh cổng hoặc IP theo tệp server.json", + lblApiGatewayUrl: "URL REST API Gateway", + lblPingInterval: "Tần suất kiểm tra (giây)", + btnSaveSettings: "💾 Lưu cài đặt", + btnResetDefault: "Khôi phục mặc định", + hostGuideTitle: "🌐 Cách lưu trữ trên GitHub Pages (Miễn phí 100%)", + hostGuideSubtitle: "Lưu trữ bảng điều khiển miễn phí trọn đời trên GitHub", + settingsSaved: "Đã lưu cài đặt!", + settingsReset: "Đã khôi phục cài đặt mặc định", + elements: { + Physical: "Vật Lý", + Fire: "Hỏa", + Ice: "Băng", + Lightning: "Lôi", + Wind: "Phong", + Quantum: "Lượng Tử", + Imaginary: "Số Ảo", + Unknown: "Không xác định" + }, + paths: { + Destruction: "Hủy Diệt", + Hunt: "Săn Bắn", + Erudition: "Tri Thức", + Harmony: "Hòa Hợp", + Nihility: "Hư Vô", + Preservation: "Bảo Hộ", + Abundance: "Trù Phú", + Remembrance: "Ký Ức", + Unknown: "Không xác định" + } + }, + + id: { + appName: "GaC-Srtool", + appSubtitle: "Pengontrol Server Star Rail FreeSR", + online: "Online", + offline: "Offline", + checking: "Memeriksa...", + refresh: "🔄 Segarkan", + connectFailed: "Koneksi Gagal", + tabDashboard: "📊 Dasbor", + tabAvatars: "👥 Karakter", + tabExrank: "⚡ Ex-Rank Skill", + tabTeleport: "🚀 Teleportasi", + tabJson: "📝 Alat JSON", + tabSettings: "⚙️ Pengaturan & Panduan", + statAvatars: "Karakter Dimiliki", + statLightcones: "Lightcone", + statRelics: "Relik", + serverStatusTitle: "📍 Status Server & Posisi Saat Ini", + quickActionsTitle: "⚡ Tindakan Cepat", + quickActionsSubtitle: "Kirim perintah langsung ke REST API Gateway", + btnMaxAll: "⭐ Maksimalkan Semua (Lv. 80 & E6)", + btnWarpExpress: "🚂 Teleport ke Astral Express", + btnSyncPersistent: "💾 Sinkronkan Data Persistent", + currentLineupTitle: "🎮 Tim Saat Ini", + slot: "Slot", + slotEmpty: "(Kosong)", + coords: "Koordinat (X, Y, Z)", + searchPlaceholder: "🔍 Cari nama atau ID...", + filterAllRarity: "Semua Kelangkaan", + filter5Star: "Bintang 5 (SSR)", + filter4Star: "Bintang 4 (SR)", + btnReload: "🔄 Muat Ulang", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "Tingkatkan semua karakter ke Lv. 80 dan E6?", + maxAllSuccess: "Semua karakter berhasil dimaksimalkan!", + avatarRankSuccess: "Karakter {id} diperbarui ke E{rank}", + exrankTitle: "⚡ Sistem Ex-Rank", + exrankSubtitle: "Aktifkan bakat Ex-Rank di FreeSR (Jing Yuan kebal kontrol, Dan Heng IL, Acheron)", + btnEnableAll: "Aktifkan Semua Ex-Rank", + btnDisableAll: "Nonaktifkan Semua Ex-Rank", + exrankToggleSuccess: "{name}: Ex-Rank berhasil di{status}", + exrankAllSuccess: "Ex-Rank semua karakter berhasil di{status}", + enabled: "aktifkan", + disabled: "nonaktifkan", + presetsTitle: "📍 Titik Teleportasi Aman", + presetsSubtitle: "Klik untuk berpindah tempat secara instan", + customTeleportTitle: "🎯 Teleportasi Koordinat Kustom", + customTeleportSubtitle: "Tentukan PlaneID, FloorID, EntryID dan koordinat", + btnExecuteWarp: "🚀 Jalankan Teleport", + warpBtn: "🚀 Teleport", + warpSuccess: "Berhasil teleportasi ke {label}", + warpFailed: "Teleportasi gagal: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Rapikan JSON", + btnDownload: "📥 Unduh Cadangan", + btnUpload: "📤 Unggah File", + btnSaveServer: "💾 Simpan ke Server", + jsonTip: "Tips: Edit JSON dan klik 'Simpan ke Server' untuk menerapkan", + jsonStatusReady: "Siap", + jsonStatusOpening: "Membuka: {name}", + jsonSaveSuccess: "File {name} berhasil disimpan", + jsonInvalid: "Format JSON tidak valid", + apiSettingsTitle: "⚙️ Pengaturan Koneksi API Gateway", + apiSettingsSubtitle: "Sesuaikan port atau IP dengan server.json Anda", + lblApiGatewayUrl: "URL REST API Gateway", + lblPingInterval: "Interval Ping (detik)", + btnSaveSettings: "💾 Simpan Pengaturan", + btnResetDefault: "Kembalikan Default", + hostGuideTitle: "🌐 Cara Host di GitHub Pages (100% Gratis)", + hostGuideSubtitle: "Host web ini secara gratis di GitHub", + settingsSaved: "Pengaturan berhasil disimpan!", + settingsReset: "Pengaturan telah direset", + elements: { + Physical: "Fisik", + Fire: "Api", + Ice: "Es", + Lightning: "Petir", + Wind: "Angin", + Quantum: "Kuantum", + Imaginary: "Imajinasi", + Unknown: "Tidak Diketahui" + }, + paths: { + Destruction: "Kehancuran", + Hunt: "Perburuan", + Erudition: "Kebijaksanaan", + Harmony: "Harmoni", + Nihility: "Ketiadaan", + Preservation: "Pelestarian", + Abundance: "Kelimpahan", + Remembrance: "Ingatan", + Unknown: "Tidak Diketahui" + } + }, + + es: { + appName: "GaC-Srtool", + appSubtitle: "Panel de control Star Rail FreeSR", + online: "En línea (Online)", + offline: "Desconectado (Offline)", + checking: "Comprobando...", + refresh: "🔄 Actualizar", + connectFailed: "Error de conexión", + tabDashboard: "📊 Panel", + tabAvatars: "👥 Personajes", + tabExrank: "⚡ Ex-Rank", + tabTeleport: "🚀 Teletransporte", + tabJson: "📝 Herramientas JSON", + tabSettings: "⚙️ Ajustes y guía", + statAvatars: "Personajes obtenidos", + statLightcones: "Conos de luz", + statRelics: "Reliquias", + serverStatusTitle: "📍 Estado del servidor y posición", + quickActionsTitle: "⚡ Acciones rápidas", + quickActionsSubtitle: "Enviar comandos a la API Gateway", + btnMaxAll: "⭐ Maximizar todos (Niv. 80 y E6)", + btnWarpExpress: "🚂 Teletransportar al Expreso Astral", + btnSyncPersistent: "💾 Sincronizar datos persistentes", + currentLineupTitle: "🎮 Equipo actual", + slot: "Puesto", + slotEmpty: "(Vacío)", + coords: "Coordenadas (X, Y, Z)", + searchPlaceholder: "🔍 Buscar nombre o ID...", + filterAllRarity: "Todas las rarezas", + filter5Star: "5 Estrellas (SSR)", + filter4Star: "4 Estrellas (SR)", + btnReload: "🔄 Recargar", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "¿Subir todos los personajes a nivel 80 y E6?", + maxAllSuccess: "¡Todos los personajes maximizados con éxito!", + avatarRankSuccess: "Personaje {id} actualizado a E{rank}", + exrankTitle: "⚡ Sistema Ex-Rank", + exrankSubtitle: "Activar talentos especiales Ex-Rank en FreeSR (inmunidad CC de Jing Yuan, Dan Heng IL, Acheron)", + btnEnableAll: "Activar todos los Ex-Rank", + btnDisableAll: "Desactivar todos los Ex-Rank", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "Todos los Ex-Rank {status}", + enabled: "activado", + disabled: "desactivado", + presetsTitle: "📍 Puntos seguros predefinidos", + presetsSubtitle: "Haga clic para teletransportar al jugador al instante", + customTeleportTitle: "🎯 Coordenadas personalizadas", + customTeleportSubtitle: "Especifique PlaneID, FloorID, EntryID y coordenadas", + btnExecuteWarp: "🚀 Ejecutar teletransporte", + warpBtn: "🚀 Ir", + warpSuccess: "Teletransportado a {label} con éxito", + warpFailed: "Fallo al teletransportar: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Dar formato a JSON", + btnDownload: "📥 Descargar copia", + btnUpload: "📤 Cargar archivo", + btnSaveServer: "💾 Guardar en el servidor", + jsonTip: "Consejo: Edite el JSON y haga clic en 'Guardar en el servidor'", + jsonStatusReady: "Listo", + jsonStatusOpening: "Abriendo: {name}", + jsonSaveSuccess: "Archivo {name} guardado con éxito", + jsonInvalid: "Formato JSON no válido", + apiSettingsTitle: "⚙️ Conexión con la API Gateway", + apiSettingsSubtitle: "Ajuste el puerto o la IP según su server.json", + lblApiGatewayUrl: "URL de la API Gateway", + lblPingInterval: "Intervalo de comprobación (segundos)", + btnSaveSettings: "💾 Guardar ajustes", + btnResetDefault: "Restaurar por defecto", + hostGuideTitle: "🌐 Cómo hospedar en GitHub Pages (100% Gratis)", + hostGuideSubtitle: "Hospede este panel de control gratis en GitHub", + settingsSaved: "¡Ajustes guardados!", + settingsReset: "Ajustes restaurados", + elements: { + Physical: "Físico", + Fire: "Fuego", + Ice: "Hielo", + Lightning: "Rayo", + Wind: "Viento", + Quantum: "Cuántico", + Imaginary: "Imaginario", + Unknown: "Desconocido" + }, + paths: { + Destruction: "Destrucción", + Hunt: "Cacería", + Erudition: "Erudición", + Harmony: "Armonía", + Nihility: "Nihilidad", + Preservation: "Conservación", + Abundance: "Abundancia", + Remembrance: "Reminiscencia", + Unknown: "Desconocido" + } + }, + + fr: { + appName: "GaC-Srtool", + appSubtitle: "Contrôleur de serveur Star Rail FreeSR", + online: "En ligne (Online)", + offline: "Hors ligne (Offline)", + checking: "Vérification...", + refresh: "🔄 Actualiser", + connectFailed: "Échec de connexion", + tabDashboard: "📊 Tableau de bord", + tabAvatars: "👥 Personnages", + tabExrank: "⚡ Compétences Ex-Rank", + tabTeleport: "🚀 Téléportation", + tabJson: "📝 Outils JSON", + tabSettings: "⚙️ Paramètres & Guide", + statAvatars: "Personnages possédés", + statLightcones: "Cônes de lumière", + statReliques: "Reliques", + serverStatusTitle: "📍 Statut du serveur & Position", + quickActionsTitle: "⚡ Actions rapides", + quickActionsSubtitle: "Envoyer directement à l'API Gateway", + btnMaxAll: "⭐ Maximiser tous (Niv. 80 & E6)", + btnWarpExpress: "🚂 Téléporter vers l'Astral Express", + btnSyncPersistent: "💾 Synchroniser les données", + currentLineupTitle: "🎮 Équipe actuelle", + slot: "Emplacement", + slotEmpty: "(Vide)", + coords: "Coordonnées (X, Y, Z)", + searchPlaceholder: "🔍 Rechercher par nom ou ID...", + filterAllRarity: "Toutes les raretés", + filter5Star: "5 Étoiles (SSR)", + filter4Star: "4 Étoiles (SR)", + btnReload: "🔄 Recharger", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "Passer tous les personnages au niveau 80 et E6 ?", + maxAllSuccess: "Tous les personnages sont maximisés !", + avatarRankSuccess: "Personnage {id} mis à jour en E{rank}", + exrankTitle: "⚡ Système Ex-Rank", + exrankSubtitle: "Activer les atouts Ex-Rank dans FreeSR (immunité CC Jing Yuan, Dan Heng IL, Acheron)", + btnEnableAll: "Activer tous les Ex-Ranks", + btnDisableAll: "Désactiver tous les Ex-Ranks", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "Tous les Ex-Ranks {status}", + enabled: "activé", + disabled: "désactivé", + presetsTitle: "📍 Points de téléportation sûrs", + presetsSubtitle: "Cliquez pour déplacer le joueur instantanément", + customTeleportTitle: "🎯 Coordonnées personnalisées", + customTeleportSubtitle: "Définissez PlaneID, FloorID, EntryID et coordonnées", + btnExecuteWarp: "🚀 Lancer la téléportation", + warpBtn: "🚀 Téléporter", + warpSuccess: "Téléporté vers {label} avec succès", + warpFailed: "Échec de téléportation: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Mettre en forme JSON", + btnDownload: "📥 Télécharger sauvegarde", + btnUpload: "📤 Charger un fichier", + btnSaveServer: "💾 Enregistrer sur le serveur", + jsonTip: "Astuce : Modifiez le JSON et cliquez sur 'Enregistrer sur le serveur'", + jsonStatusReady: "Prêt", + jsonStatusOpening: "Ouverture : {name}", + jsonSaveSuccess: "Fichier {name} enregistré", + jsonInvalid: "Format JSON non valide", + apiSettingsTitle: "⚙️ Paramètres de connexion API Gateway", + apiSettingsSubtitle: "Ajustez le port ou l'IP selon votre server.json", + lblApiGatewayUrl: "URL de l'API Gateway", + lblPingInterval: "Intervalle de test (secondes)", + btnSaveSettings: "💾 Enregistrer les paramètres", + btnResetDefault: "Réinitialiser", + hostGuideTitle: "🌐 Héberger sur GitHub Pages (100% Gratuit)", + hostGuideSubtitle: "Hébergez ce panneau gratuitement sur GitHub", + settingsSaved: "Paramètres enregistrés !", + settingsReset: "Paramètres réinitialisés", + elements: { + Physical: "Physique", + Fire: "Feu", + Ice: "Glace", + Lightning: "Foudre", + Wind: "Vent", + Quantum: "Quantique", + Imaginary: "Imaginaire", + Unknown: "Inconnu" + }, + paths: { + Destruction: "Destruction", + Hunt: "Chasse", + Erudition: "Érudition", + Harmony: "Harmonie", + Nihility: "Nihilité", + Preservation: "Préservation", + Abundance: "Abondance", + Remembrance: "Souvenir", + Unknown: "Inconnu" + } + }, + + de: { + appName: "GaC-Srtool", + appSubtitle: "Star Rail FreeSR Server Controller", + online: "Online", + offline: "Offline", + checking: "Prüfe...", + refresh: "🔄 Aktualisieren", + connectFailed: "Verbindung fehlgeschlagen", + tabDashboard: "📊 Übersicht", + tabAvatars: "👥 Figuren", + tabExrank: "⚡ Ex-Rang Talente", + tabTeleport: "🚀 Teleportation", + tabJson: "📝 JSON-Tools", + tabSettings: "⚙️ Einstellungen", + statAvatars: "Figuren im Besitz", + statLightcones: "Lichtkegel", + statRelics: "Relikte", + serverStatusTitle: "📍 Serverstatus & Position", + quickActionsTitle: "⚡ Schnellaktionen", + quickActionsSubtitle: "Befehle direkt an das API-Gateway senden", + btnMaxAll: "⭐ Alle Figuren maximieren (Stufe 80 & E6)", + btnWarpExpress: "🚂 Zum Astralexpress teleportieren", + btnSyncPersistent: "💾 Speicherdaten synchronisieren", + currentLineupTitle: "🎮 Aktuelle Aufstellung", + slot: "Platz", + slotEmpty: "(Leer)", + coords: "Koordinaten (X, Y, Z)", + searchPlaceholder: "🔍 Nach Name oder ID suchen...", + filterAllRarity: "Alle Seltenheiten", + filter5Star: "5 Sterne (SSR)", + filter4Star: "4 Sterne (SR)", + btnReload: "🔄 Neu laden", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "Alle Figuren auf Stufe 80 und E6 aufwerten?", + maxAllSuccess: "Alle Figuren wurden maximiert!", + avatarRankSuccess: "Figur {id} auf E{rank} gesetzt", + exrankTitle: "⚡ Ex-Rang Talentsystem", + exrankSubtitle: "Aktivieren Sie Ex-Rang Talente in FreeSR (Jing Yuan CC-Immunität, Dan Heng IL, Acheron)", + btnEnableAll: "Alle Ex-Ränge aktivieren", + btnDisableAll: "Alle Ex-Ränge deaktivieren", + exrankToggleSuccess: "{name}: Ex-Rang {status}", + exrankAllSuccess: "Alle Ex-Ränge {status}", + enabled: "aktiviert", + disabled: "deaktiviert", + presetsTitle: "📍 Sichere Teleport-Ziele", + presetsSubtitle: "Klicken, um den Spieler sofort zu teleportieren", + customTeleportTitle: "🎯 Benutzerdefinierte Koordinaten", + customTeleportSubtitle: "Geben Sie PlaneID, FloorID, EntryID und Koordinaten ein", + btnExecuteWarp: "🚀 Teleport ausführen", + warpBtn: "🚀 Teleport", + warpSuccess: "Erfolgreich zu {label} teleportiert", + warpFailed: "Teleport fehlgeschlagen: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ JSON formatieren", + btnDownload: "📥 Backup herunterladen", + btnUpload: "📤 Datei hochladen", + btnSaveServer: "💾 Auf Server speichern", + jsonTip: "Tipp: JSON bearbeiten und 'Auf Server speichern' klicken", + jsonStatusReady: "Bereit", + jsonStatusOpening: "Öffne: {name}", + jsonSaveSuccess: "Datei {name} erfolgreich gespeichert", + jsonInvalid: "Ungültiges JSON-Format", + apiSettingsTitle: "⚙️ API-Gateway Verbindungseinstellungen", + apiSettingsSubtitle: "Passen Sie Port oder IP gemäß Ihrer server.json an", + lblApiGatewayUrl: "REST API Gateway URL", + lblPingInterval: "Prüfintervall (Sekunden)", + btnSaveSettings: "💾 Einstellungen speichern", + btnResetDefault: "Auf Standard zurücksetzen", + hostGuideTitle: "🌐 Auf GitHub Pages kostenlos hosten (100% Kostenlos)", + hostGuideSubtitle: "Hosten Sie dieses Tool ohne Kosten direkt auf GitHub", + settingsSaved: "Einstellungen gespeichert!", + settingsReset: "Auf Standardeinstellungen zurückgesetzt", + elements: { + Physical: "Physisch", + Fire: "Feuer", + Ice: "Eis", + Lightning: "Blitz", + Wind: "Wind", + Quantum: "Quanten", + Imaginary: "Imaginär", + Unknown: "Unbekannt" + }, + paths: { + Destruction: "Zerstörung", + Hunt: "Jagd", + Erudition: "Gelehrsamkeit", + Harmony: "Harmonie", + Nihility: "Nichtigkeit", + Preservation: "Bewahrung", + Abundance: "Überfluss", + Remembrance: "Erinnerung", + Unknown: "Unbekannt" + } + }, + + ru: { + appName: "GaC-Srtool", + appSubtitle: "Панель управления Star Rail FreeSR", + online: "В сети (Online)", + offline: "Не в сети (Offline)", + checking: "Проверка...", + refresh: "🔄 Обновить", + connectFailed: "Ошибка подключения", + tabDashboard: "📊 Панель управления", + tabAvatars: "👥 Персонажи", + tabExrank: "⚡ Навыки Ex-Rank", + tabTeleport: "🚀 Телепортация", + tabJson: "📝 Управление JSON", + tabSettings: "⚙️ Настройки и гайд", + statAvatars: "Персонажи во владении", + statLightcones: "Световые конусы", + statRelics: "Реликвии", + serverStatusTitle: "📍 Статус сервера и координаты", + quickActionsTitle: "⚡ Быстрые действия", + quickActionsSubtitle: "Отправка команд напрямую в REST API Gateway", + btnMaxAll: "⭐ Максимизировать всех (Ур. 80 и E6)", + btnWarpExpress: "🚂 Телепорт в Звёздный экспресс", + btnSyncPersistent: "💾 Синхронизировать сохранение", + currentLineupTitle: "🎮 Текущий отряд", + slot: "Слот", + slotEmpty: "(Пусто)", + coords: "Координаты (X, Y, Z)", + searchPlaceholder: "🔍 Поиск по имени или ID...", + filterAllRarity: "Все редкости", + filter5Star: "5 Звёзд (SSR)", + filter4Star: "4 Звезды (SR)", + btnReload: "🔄 Перезагрузить", + eidolonLabel: "ЭЙДОЛОН (E):", + confirmMaxAll: "Повысить всех персонажей до 80 ур. и E6?", + maxAllSuccess: "Все персонажи успешно улучшены!", + avatarRankSuccess: "Персонаж {id} обновлен до E{rank}", + exrankTitle: "⚡ Система навыков Ex-Rank", + exrankSubtitle: "Включение уникальных механик Ex-Rank в FreeSR (Цзин Юань без прерывания контроля, Дань Хэн Пожиратель Луны, Ахерон)", + btnEnableAll: "Включить все Ex-Rank", + btnDisableAll: "Отключить все Ex-Rank", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "Ex-Rank всех персонажей {status}", + enabled: "включен", + disabled: "отключен", + presetsTitle: "📍 Безопасные точки телепортации", + presetsSubtitle: "Нажмите для мгновенного перемещения персонажа", + customTeleportTitle: "🎯 Пользовательские координаты", + customTeleportSubtitle: "Укажите PlaneID, FloorID, EntryID и координаты", + btnExecuteWarp: "🚀 Выполнить телепортацию", + warpBtn: "🚀 Телепорт", + warpSuccess: "Телепортация в {label} успешна", + warpFailed: "Ошибка телепортации: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Форматировать JSON", + btnDownload: "📥 Скачать бэкап", + btnUpload: "📤 Загрузить файл", + btnSaveServer: "💾 Сохранить на сервер", + jsonTip: "Совет: Отредактируйте JSON и нажмите 'Сохранить на сервер'", + jsonStatusReady: "Готово", + jsonStatusOpening: "Открытие: {name}", + jsonSaveSuccess: "Файл {name} сохранен", + jsonInvalid: "Неверный формат JSON", + apiSettingsTitle: "⚙️ Настройка подключения API Gateway", + apiSettingsSubtitle: "Настройте порт или IP согласно вашему server.json", + lblApiGatewayUrl: "URL REST API Gateway", + lblPingInterval: "Интервал проверки (сек)", + btnSaveSettings: "💾 Сохранить настройки", + btnResetDefault: "Сбросить по умолчанию", + hostGuideTitle: "🌐 Бесплатный хостинг на GitHub Pages (100% Бесплатно)", + hostGuideSubtitle: "Разместите панель бесплатно на GitHub без затрат", + settingsSaved: "Настройки сохранены!", + settingsReset: "Настройки сброшены", + elements: { + Physical: "Физический", + Fire: "Огненный", + Ice: "Ледяной", + Lightning: "Электрический", + Wind: "Ветряной", + Quantum: "Квантовый", + Imaginary: "Мнимый", + Unknown: "Неизвестно" + }, + paths: { + Destruction: "Разрушение", + Hunt: "Охота", + Erudition: "Эрудиция", + Harmony: "Гармония", + Nihility: "Небытие", + Preservation: "Сохранение", + Abundance: "Изобилие", + Remembrance: "Память", + Unknown: "Неизвестно" + } + }, + + pt: { + appName: "GaC-Srtool", + appSubtitle: "Controlador de Servidor Star Rail FreeSR", + online: "Online", + offline: "Offline", + checking: "Verificando...", + refresh: "🔄 Atualizar", + connectFailed: "Falha na conexão", + tabDashboard: "📊 Painel", + tabAvatars: "👥 Personagens", + tabExrank: "⚡ Habilidades Ex-Rank", + tabTeleport: "🚀 Teleporte", + tabJson: "📝 Ferramentas JSON", + tabSettings: "⚙️ Configurações & Guia", + statAvatars: "Personagens obtidos", + statLightcones: "Cones de Luz", + statRelics: "Relíquias", + serverStatusTitle: "📍 Status do servidor e posição atual", + quickActionsTitle: "⚡ Ações rápidas", + quickActionsSubtitle: "Enviar comandos diretamente ao API Gateway", + btnMaxAll: "⭐ Maximizar todos (Nív. 80 e E6)", + btnWarpExpress: "🚂 Teleportar para o Expresso Astral", + btnSyncPersistent: "💾 Sincronizar dados salvos", + currentLineupTitle: "🎮 Equipe atual", + slot: "Posição", + slotEmpty: "(Vazio)", + coords: "Coordenadas (X, Y, Z)", + searchPlaceholder: "🔍 Buscar nome ou ID...", + filterAllRarity: "Todas as raridades", + filter5Star: "5 Estrelas (SSR)", + filter4Star: "4 Estrelas (SR)", + btnReload: "🔄 Recarregar", + eidolonLabel: "EIDOLON (E):", + confirmMaxAll: "Evoluir todos os personagens para nível 80 e E6?", + maxAllSuccess: "Todos os personagens maximizados com sucesso!", + avatarRankSuccess: "Personagem {id} atualizado para E{rank}", + exrankTitle: "⚡ Sistema de Ex-Rank", + exrankSubtitle: "Ativar vantagens exclusivas Ex-Rank no FreeSR (imunidade a CC para Jing Yuan, Dan Heng IL, Acheron)", + btnEnableAll: "Ativar todos os Ex-Ranks", + btnDisableAll: "Desativar todos os Ex-Ranks", + exrankToggleSuccess: "{name}: Ex-Rank {status}", + exrankAllSuccess: "Todos os Ex-Ranks {status}", + enabled: "ativado", + disabled: "desativado", + presetsTitle: "📍 Pontos seguros pré-definidos", + presetsSubtitle: "Clique para teleportar o personagem instantaneamente", + customTeleportTitle: "🎯 Coordenadas personalizadas", + customTeleportSubtitle: "Especifique PlaneID, FloorID, EntryID e coordenadas", + btnExecuteWarp: "🚀 Executar teleporte", + warpBtn: "🚀 Teleportar", + warpSuccess: "Teleportado para {label} com sucesso", + warpFailed: "Falha no teleporte: {err}", + btnFreesr: "📄 freesr-data.json", + btnPersistent: "💾 persistent", + btnBeautify: "✨ Formatar JSON", + btnDownload: "📥 Baixar backup", + btnUpload: "📤 Carregar arquivo", + btnSaveServer: "💾 Salvar no servidor", + jsonTip: "Dica: Edite o JSON e clique em 'Salvar no servidor'", + jsonStatusReady: "Pronto", + jsonStatusOpening: "Abrindo: {name}", + jsonSaveSuccess: "Arquivo {name} salvo com sucesso", + jsonInvalid: "Formato JSON inválido", + apiSettingsTitle: "⚙️ Configurações de Conexão com API Gateway", + apiSettingsSubtitle: "Ajuste a porta ou o IP de acordo com seu server.json", + lblApiGatewayUrl: "URL do REST API Gateway", + lblPingInterval: "Intervalo de verificação (segundos)", + btnSaveSettings: "💾 Salvar configurações", + btnResetDefault: "Restaurar padrão", + hostGuideTitle: "🌐 Como hospedar no GitHub Pages (100% Grátis)", + hostGuideSubtitle: "Hospede esta ferramenta gratuitamente no GitHub", + settingsSaved: "Configurações salvas!", + settingsReset: "Configurações restauradas", + elements: { + Physical: "Físico", + Fire: "Fogo", + Ice: "Gelo", + Lightning: "Raio", + Wind: "Vento", + Quantum: "Quântico", + Imaginary: "Imaginário", + Unknown: "Desconhecido" + }, + paths: { + Destruction: "Destruição", + Hunt: "Caça", + Erudition: "Erudição", + Harmony: "Harmonia", + Nihility: "Inexistência", + Preservation: "Preservação", + Abundance: "Abundância", + Remembrance: "Recordação", + Unknown: "Desconhecido" + } + } +}; + +let currentLang = localStorage.getItem('gac_srtool_lang') || 'th'; + +export function getCurrentLanguage() { + return currentLang; +} + +export function setLanguage(langCode) { + if (TRANSLATIONS[langCode]) { + currentLang = langCode; + localStorage.setItem('gac_srtool_lang', langCode); + } +} + +export function t(key, vars = {}) { + const dict = TRANSLATIONS[currentLang] || TRANSLATIONS.en || TRANSLATIONS.th; + let text = dict[key] || TRANSLATIONS.en[key] || TRANSLATIONS.th[key] || key; + + // Substitute variables e.g. {id}, {rank}, {name} + for (const [vKey, vVal] of Object.entries(vars)) { + text = text.replace(new RegExp(`\\{${vKey}\\}`, 'g'), vVal); + } + return text; +} + +export function translateElement(elem) { + const dict = TRANSLATIONS[currentLang] || TRANSLATIONS.en; + return dict.elements?.[elem] || TRANSLATIONS.en.elements?.[elem] || elem; +} + +export function translatePath(path) { + const dict = TRANSLATIONS[currentLang] || TRANSLATIONS.en; + return dict.paths?.[path] || TRANSLATIONS.en.paths?.[path] || path; +} diff --git a/js/teleports-data.js b/js/teleports-data.js index c382685..f006a30 100644 --- a/js/teleports-data.js +++ b/js/teleports-data.js @@ -1,8 +1,16 @@ -// Safe preset teleports for Star Rail maps +import { getCurrentLanguage } from './i18n.js'; + export const PRESET_TELEPORTS = [ { - name: "Astral Express - Parlor Car (รถไฟขบวนแอสทรัล)", - world: "Astral Express", + names: { + th: "Astral Express - ขบวนรถไฟแอสทรัล (ห้องรับรอง)", + en: "Astral Express - Parlor Car", + "zh-CN": "星穹列车 - 观景车厢", + "zh-TW": "星穹列車 - 觀景車廂", + ja: "星穹列車 - 客室", + ko: "은하열차 - 객실", + ru: "Звёздный экспресс - Общий вагон" + }, plane_id: 20001, floor_id: 20001001, entry_id: 2000101, @@ -11,8 +19,15 @@ export const PRESET_TELEPORTS = [ z: 0 }, { - name: "Herta Space Station - Master Control Zone (สถานีอวกาศ Herta - โซนควบคุมหลัก)", - world: "Herta Space Station", + names: { + th: "สถานีอวกาศ Herta - โซนควบคุมหลัก (Master Control Zone)", + en: "Herta Space Station - Master Control Zone", + "zh-CN": "空间站「黑塔」 - 主控舱段", + "zh-TW": "太空站「黑塔」 - 主控艙段", + ja: "宇宙ステーション「ヘルタ」 - 主制御部分", + ko: "우주정거장 「헤르타」 - 메인 컨트롤 구역", + ru: "Космическая станция «Герта» - Главная контрольная зона" + }, plane_id: 10001, floor_id: 10001001, entry_id: 1000101, @@ -21,8 +36,15 @@ export const PRESET_TELEPORTS = [ z: 0 }, { - name: "Jarilo-VI - Administrative District (เขตการปกครอง)", - world: "Jarilo-VI (Belobog)", + names: { + th: "Jarilo-VI (Belobog) - เขตการปกครอง (Administrative District)", + en: "Jarilo-VI - Administrative District", + "zh-CN": "雅利洛-VI - 行政区", + "zh-TW": "雅利洛-VI - 行政區", + ja: "ヤリーロ-VI - 行政区", + ko: "야릴로-VI - 행정구역", + ru: "Ярило-VI - Административный район" + }, plane_id: 10101, floor_id: 10101001, entry_id: 1010101, @@ -31,8 +53,15 @@ export const PRESET_TELEPORTS = [ z: 32670 }, { - name: "Jarilo-VI - Boulder Town (เมือง Boulder)", - world: "Jarilo-VI (Underworld)", + names: { + th: "Jarilo-VI (Underworld) - เมือง Boulder (Boulder Town)", + en: "Jarilo-VI - Boulder Town", + "zh-CN": "雅利洛-VI - 磐岩镇", + "zh-TW": "雅利洛-VI - 磐岩鎮", + ja: "ヤリーロ-VI - ボルダータウン", + ko: "야릴로-VI - 볼더 타운", + ru: "Ярило-VI - Камнеград" + }, plane_id: 10102, floor_id: 10102001, entry_id: 1010201, @@ -41,8 +70,15 @@ export const PRESET_TELEPORTS = [ z: 57320 }, { - name: "Xianzhou Luofu - Central Starskiff Haven (ท่าเรือเรือบินดาวกลาง)", - world: "Xianzhou Luofu", + names: { + th: "Xianzhou Luofu - ท่าเรือเรือบินดาวกลาง (Central Starskiff Haven)", + en: "Xianzhou Luofu - Central Starskiff Haven", + "zh-CN": "仙舟「罗浮」 - 星槎海中枢", + "zh-TW": "仙舟「羅浮」 - 星槎海中樞", + ja: "仙舟「羅浮」 - 星槎海中枢", + ko: "선주 「나부」 - 별뗏목 바다 중추", + ru: "Сяньчжоу: Лофу - Центральная гавань Приюта звёздных яликов" + }, plane_id: 10202, floor_id: 10202001, entry_id: 1020201, @@ -51,8 +87,15 @@ export const PRESET_TELEPORTS = [ z: -25080 }, { - name: "Penacony - The Reverie (Dreamscape Hotel)", - world: "Penacony", + names: { + th: "Penacony - The Reverie (Dreamscape Hotel)", + en: "Penacony - The Reverie (Dreamscape)", + "zh-CN": "匹诺康尼 - 「白日梦」酒店-梦境", + "zh-TW": "匹諾康尼 - 「白日夢」飯店-夢境", + ja: "ピノコニー - 「レバリー」ホテル-夢境", + ko: "페나코니 - 「레버리」 호텔-꿈속", + ru: "Пенакония - Отель «Грёзы» (Мир грёз)" + }, plane_id: 10301, floor_id: 10301001, entry_id: 1030101, @@ -61,8 +104,15 @@ export const PRESET_TELEPORTS = [ z: 0 }, { - name: "Penacony - Golden Hour (ชั่วโมงทอง)", - world: "Penacony", + names: { + th: "Penacony - ชั่วโมงทอง (Golden Hour)", + en: "Penacony - Golden Hour", + "zh-CN": "匹诺康尼 - 黄金的时刻", + "zh-TW": "匹諾康尼 - 黃金的時刻", + ja: "ピノコニー - 黄金の刻", + ko: "페나코니 - 황금의 순간", + ru: "Пенакония - Золотой миг" + }, plane_id: 10302, floor_id: 10302001, entry_id: 1030201, @@ -71,3 +121,8 @@ export const PRESET_TELEPORTS = [ z: -378220 } ]; + +export function getTeleportName(preset, langOverride = null) { + const lang = langOverride || getCurrentLanguage(); + return preset.names?.[lang] || preset.names?.en || preset.names?.th || "Teleport Point"; +}