// Erythros Lite Wiki Quick Reference App // Main React application with bilingual support const { useState, useMemo, useEffect, useCallback, useContext, createContext, useRef } = React; // ===== LANGUAGE CONTEXT ===== const LangContext = createContext('zh'); function useLang() { const ctx = useContext(LangContext); return ctx; } function t(key) { const lang = useLang(); const str = window.UI_STRINGS?.[lang]; return str?.[key] ?? key; } // ===== 自动补全 UI_STRINGS(无需修改 data.js) ===== (function ensureUIStrings() { if (!window.UI_STRINGS) window.UI_STRINGS = {}; const defaultStrings = { zh: { appTitle: 'Erythros Lite 维基速查', appSubtitle: 'Wiki Quick Ref', searchPlaceholder: '搜索物品名称、ID 或合成配方...', totalItems: 'Total Items', categories: 'Categories', itemCategories: '物品分类', gameData: '游戏数据', mapSizes: '地图尺寸', medicineEffects: '药品效果', craftingRecipes: '合成配方', buildingDurability: '建筑耐久', searchResults: '搜索结果', searchResultsFor: 'Search Results for', found: 'FOUND', itemsItems: 'ITEMS', idRange: 'ID RANGE', noResults: '未找到匹配物品', noResultsDesc: '试试其他关键词,或切换到其他分类', noRecipeResults: '没有匹配的配方', noRecipeResultsDesc: '试试其他关键词', copyId: '复制ID', copied: '已复制', copyRecipe: '配方', copyCmd: '指令', itemId: '物品 ID', itemNameEn: '英文名称', category: '所属分类', sizeTiers: '尺寸规格', notes: '说明', normalPlayers: '普通玩家', premiumOnly: 'LARGE 和 INSANE', premiumDesc: '尺寸需要 Premium 赞助权限才能创建。', insaneNote: '其中 4096×4096 (INSANE) 地图对服务器性能要求较高,适合大型服务器与极限生存体验。', iconLegend: '图标含义', health: '生命值', healthDesc: 'Health points', radiation: '辐射值', radiationDesc: 'Sickness / radiation', bleed: '止血', bleedDesc: 'Stops bleeding', brokenLeg: '治疗断腿', brokenLegDesc: 'Removes broken leg', stamina: '恢复体力', staminaDesc: 'Stamina boost', filterAll: '全部', filterHigh: '高级药品', filterMid: '中级药品', filterLow: '初级药品', filterBerry: '浆果类', filterSpecial: '特殊', medicationTips: '用药指南', tipWarning: '注意事项', tipWarningText: '大部分回血药同时会增加辐射值,不能无脑连续嗑药', tipHighValue: '高性价比回血', tipHighValueText: 'Brilliant Green 单次 +75% 血量,回血最高,但辐射上涨也很明显', tipEmergency: '应急处理', tipEmergencyText: '吗啡治疗断腿、肾上腺素瞬间回满体力;疫苗可以大幅降低自身辐射值', tipBerry: '浆果类', tipBerryText: '碾碎浆果只能少量回血,前期没药品临时应急使用', tipVodka: '伏特加特殊效果', tipVodkaText: '血量无增减,小幅降低自身辐射(-1%)', tipCombat: '对战要点', tipCombatText: '对战时出现流血优先治疗流血,不要只顾回血', testWeapons: '测试武器', damage: '伤害', hitsToDestroy: '破坏次数对比', buildingType: '建筑类型', hp: '血量', invalid: '无效', practicalTips: '实用建议', craftsmanLevelSystem: '工匠等级系统', searchInCategory: '在分类中搜索配方或材料...', recipeCount: '配方', level: '级', expShort: 'EXP', ptlCommunity: 'PTL 中国', ptlSubtitle: 'Erythros Lite 官方授权社区', ptlQQ1: 'QQ一群:666522680', ptlQQ2: 'QQ二群:1107305296', noSpecialEffect: '无特殊效果', stopsBleed: '止血', healsBrokenLeg: '治断腿', fullStamina: '回满体力', playerLogin: '玩家登录', playerRegister: '玩家注册', playerProfile: '个人资料', playerViewProfile: '玩家资料', accountLabel: '账号标识 (QQ / DiscordID / 邮箱)', passwordLabel: '密码', confirmPasswordLabel: '确认密码', loginButton: '登录', registerButton: '注册', noAccountYet: '还没有账号?', alreadyHaveAccount: '已有账号?', registerNow: '立即注册', backToLogin: '返回登录', gameIdLabel: '游戏 ID(6-12位纯数字,注册后不可修改)', passwordPlaceholder: '请输入密码', confirmPasswordPlaceholder: '请再次输入密码', gameIdPlaceholder: '只允许填写数字', qqPlaceholder: '请输入QQ号(5-15位)', externalContactPlaceholder: '不要填写Discord昵称', playerTypeLabel: '选择你的玩家类型', cnPlayer: '国内玩家(有QQ)', intlPlayer: '海外玩家(无QQ)', editProfile: '编辑(仅可修改密码)', logout: '退出登录', saveChanges: '保存修改', currentPasswordLabel: '原密码', newPasswordLabel: '新密码', confirmGameId: '确认你的游戏ID', gameIdConfirmMsg: '你填写的游戏ID:{gameId}', gameIdConfirmWarning: '⚠️ 注册成功之后游戏ID永久不能修改!', gameIdConfirmDesc: '请确认这确实是你游戏内的真实数字ID,填错只能找管理员后台处理。', cancel: '取消', confirmSubmit: '确认提交', gameIdLocked: '游戏ID、联系信息注册完成后不可修改', viewOnlyPublic: '仅展示公开游戏ID信息', loading: '加载中...', adminLogin: '管理员登录', adminUsername: '用户名', adminPassword: '密码', adminLoginBtn: '登录', adminDefaultHint: '默认账号 admin / admin123', adminLogout: '退出登录', adminDashboard: '统计面板', adminItems: '物品管理', adminRecipes: '合成配方', adminMedicines: '药品效果', adminBuildings: '建筑耐久', adminPlayers: '玩家管理', adminPassword: '修改密码', adminData: '数据管理', adminTotalVisits: '总访问量', adminTodayVisits: '今日访问', adminWeekVisits: '本周访问', adminTotalPlayers: '注册玩家', adminTopItems: '热门物品 Top 10', adminTopPages: '访问页面分布', adminTrend: '近7天访问趋势', adminRecentPlayers: '最近注册玩家', adminRecentVisits: '最近访问记录', adminLoading: '加载中...', adminLoadFailed: '加载失败', adminNoData: '暂无数据', adminEdit: '编辑', adminDelete: '删除', adminConfirmDelete: '确认删除', adminDeleteMsg: '确定要删除「{name}」吗?此操作不可撤销。', adminCancel: '取消', adminConfirm: '确认', adminAdd: '新增', adminAddItem: '新增物品', adminEditItem: '编辑物品', adminItemId: '物品 ID', adminItemNameZh: '中文名称', adminItemNameEn: '英文名称', adminItemCategory: '分类', adminSave: '保存', adminAddRecipe: '新增配方', adminEditRecipe: '编辑配方', adminRecipeResultZh: '产物(中文)', adminRecipeResultEn: '产物(英文)', adminRecipeResultCount: '产出数量', adminRecipeCategory: '分类', adminRecipeLevel: '工匠等级', adminRecipeMaterials: '材料清单', adminRecipeMaterialZh: '中文名', adminRecipeMaterialEn: '英文名', adminRecipeMaterialCount: '数量', adminRecipeAddMaterial: '+ 添加材料', adminRecipeRemoveMaterial: '✕', adminRecipeMaterialError: '请完整填写所有材料(名称和数量)', adminMedicinesHealth: '回血%', adminMedicinesRadiation: '辐射%', adminMedicinesTier: '等级', adminMedicinesEffects: '特效', adminMedicinesAdd: '新增药品', adminMedicinesEdit: '编辑药品', adminMedicinesEffectBleed: '止血', adminMedicinesEffectBrokenLeg: '治断腿', adminMedicinesEffectStamina: '回体力', adminBuildingsHp: '血量', adminBuildingsWeaponDamage: '武器破坏数据', adminBuildingsAdd: '新增建筑', adminBuildingsEdit: '编辑建筑', adminBuildingsComplexHint: '建筑数据含复杂JSON,建议直接操作数据库或后续完善表单', adminPlayersSearch: '搜索...', adminPlayersQQ: 'QQ号', adminPlayersGameId: '游戏ID', adminPlayersRegisterTime: '注册时间', adminPasswordChange: '修改管理员密码', adminPasswordOld: '原密码', adminPasswordNew: '新密码(至少6位)', adminPasswordConfirm: '确认新密码', adminPasswordSubmit: '修改密码', adminPasswordSuccess: '密码修改成功!', adminPasswordError: '修改失败', adminDataReset: '数据管理', adminDataResetDesc: '从初始种子数据重建数据库。警告:会覆盖所有手动修改的数据!', adminDataResetDanger: '一键导入初始数据', adminDataResetConfirmTitle: '确认重置数据?', adminDataResetConfirmMsg: '此操作将覆盖所有物品、配方、药品、建筑数据为初始版本,所有手动修改将丢失。确定继续吗?', adminDataResetSuccess: '操作完成', adminDataResetFail: '操作失败', community: '社区', communityTitle: '社区讨论', newPost: '发新帖', postTitle: '标题', postContent: '内容', postCategory: '分类', categoryGeneral: '综合', categoryGuide: '攻略', categoryHelp: '求助', categoryDiscussion: '讨论', categoryFeedback: '反馈', postSubmit: '发布', postCancel: '取消', reply: '回复', writeReply: '写回复...', noPosts: '暂无帖子,快来发第一个吧!', noReplies: '还没有回复,抢个沙发!', postDeleted: '帖子已删除', replyDeleted: '回复已删除', confirmDeletePost: '确认删除此帖子?', confirmDeleteReply: '确认删除此回复?', delete: '删除', edit: '编辑', like: '点赞', unlike: '取消赞', viewCount: '浏览', replyCount: '回复', postedBy: '发布于', author: '作者', loadMore: '加载更多', backToCommunity: '返回社区', welcomeTitle: '欢迎!', welcomeButton: '我知道了', welcomeDefault: '欢迎来到 Erythros Lite 维基!祝你游戏愉快!🎮', // 新增键 idLabel: 'ID', giveCommand: '/give', crafting: '合成配方', craftingEn: 'Crafting', craftingRecipe: '合成配方', materialsLabel: '原料', quantityLabel: '数量', wikiSubtitle: 'PTL社群模组维基速查', homeIntro: '本维基收录武器、防具、道具ID、合成配方、药品效果、建筑耐久、地图规格。使用顶部搜索框可以检索物品ID、中英文名称,按 / 快捷键快速聚焦搜索。', wikiBy: '维基制作:PTL社群', gameCredits: '游戏制作团队', creditTitle: '🎯 游戏名称', creditCreator: '👨💻 创始人 / 开发者', creditCreatorDesc: '(个人开发者)', creditPublisher: '🏢 发行 / 工作室', creditPublisherDesc: '(发行商)', creditWebsite: '🌐 官方网站', creditEmail: '📧 联系邮箱', creditEmailDesc: '(开发者)', creditCommunity: '🇨🇳 中文社区', creditCommunityDesc: '(玩家社群 / 维基维护)', wikiDisclaimer: '本维基由 PTL 中国社区维护,非官方出品,仅供玩家参考。', wikiContents: '📖 维基收录范围', wikiContent1: '武器、防具、道具完整属性与数值', wikiContent2: '合成配方、药品效果、建筑耐久参数', wikiContent3: '地图规格、物品ID、中英文名称对照', wikiContent4: '支持ID、名称快速检索,分类筛选', wikiTip: '提示:修改浏览器地址 Hash #items 进入物品维基页面', mapSizeSpec: 'Map Size Specifications', scaleLabel: 'SCALE', mapPermNormal: '可创建 TINY、SMALL、MEDIUM 三种尺寸的地图。', mapPermNormalEn: '普通玩家可创建 TINY、SMALL、MEDIUM 三种尺寸的地图。', mapPermPremium: 'LARGE 和 INSANE', mapPermPremiumEn: '尺寸需要 Premium 赞助权限才能创建。', insaneNote: '其中 4096×4096 (INSANE) 地图对服务器性能要求较高,适合大型服务器与极限生存体验。', insaneNoteEn: '4096×4096 (INSANE) 地图对服务器性能要求较高,适合大型服务器与极限生存体验。', medicineGuide: '药品效果指南', medItems: '药品', buildingsLabel: '建筑类型', buildingDurabilityData: '建筑耐久数据', craftingList: '合成配方列表', postNotFound: '帖子不存在', loadFailed: '加载失败', anonymous: '匿名', allLabel: '全部', loginToPost: '登录后发帖', beFirstPost: '点击“发新帖”成为第一个!', pinned: '置顶', homeLabel: '首页', homeLabelEn: '首页', homeLabelRu: '首页', mapSizesEn: '地图尺寸', mapSizesRu: '地图尺寸', medicineEffectsEn: '药品效果', medicineEffectsRu: '药品效果', craftingRecipesEn: '合成配方', craftingRecipesRu: '合成配方', buildingDurabilityEn: '建筑耐久', buildingDurabilityRu: '建筑耐久', communityEn: '社区', communityRu: '社区', wikiRef: '维基速查', registerLogin: '注册 / 登录', adminPanel: '管理后台', totalItemsLabel: '物品总计', itemsUnit: '项', langZh: '中文', langEn: 'EN', langRu: 'RU', adminLoading: 'Admin Panel (加载中...)', pageNotFound: '页面不存在', gameIdFormatError: '游戏ID只能填写6‑12位纯数字!', passwordMismatch: '两次输入的密码不一致', currentPasswordRequired: '请填写原密码', passwordChanged: '密码修改成功!', updateFailed: '修改失败', myPosts: '我的帖子', noMyPosts: '还没有发布过帖子', goToCommunity: '去社区发个帖吧!', }, en: { appTitle: 'Erythros Lite Wiki', appSubtitle: 'Quick Reference', searchPlaceholder: 'Search item name, ID, or recipe...', totalItems: 'Total Items', categories: 'Categories', itemCategories: 'Item Categories', gameData: 'Game Data', mapSizes: 'Map Sizes', medicineEffects: 'Medicine Effects', craftingRecipes: 'Crafting Recipes', buildingDurability: 'Building Durability', searchResults: 'Search Results', searchResultsFor: 'Results for', found: 'FOUND', itemsItems: 'ITEMS', idRange: 'ID RANGE', noResults: 'No matching items found', noResultsDesc: 'Try different keywords or switch categories', noRecipeResults: 'No matching recipes', noRecipeResultsDesc: 'Try different keywords', copyId: 'Copy ID', copied: 'Copied', copyRecipe: 'Recipe', copyCmd: 'Cmd', itemId: 'Item ID', itemNameEn: 'English Name', category: 'Category', sizeTiers: 'Size Tiers', notes: 'Notes', normalPlayers: 'Regular players', premiumOnly: 'LARGE and INSANE', premiumDesc: 'sizes require Premium sponsor access.', insaneNote: '4096×4096 (INSANE) maps require high server performance, suitable for large servers and extreme survival.', iconLegend: 'Icon Legend', health: 'Health', healthDesc: 'Health points', radiation: 'Radiation', radiationDesc: 'Sickness / radiation', bleed: 'Stop Bleed', bleedDesc: 'Stops bleeding', brokenLeg: 'Heal Leg', brokenLegDesc: 'Removes broken leg', stamina: 'Stamina', staminaDesc: 'Stamina boost', filterAll: 'All', filterHigh: 'Advanced', filterMid: 'Intermediate', filterLow: 'Basic', filterBerry: 'Berries', filterSpecial: 'Special', medicationTips: 'Medication Tips', tipWarning: 'Warning', tipWarningText: 'Most healing meds also increase radiation — don\'t spam them blindly.', tipHighValue: 'Best Healing', tipHighValueText: 'Brilliant Green heals +75% HP (highest), but also significantly increases radiation.', tipEmergency: 'Emergency Use', tipEmergencyText: 'Morphine heals broken leg; Adrenaline refills stamina; Vaccine greatly reduces radiation.', tipBerry: 'Berries', tipBerryText: 'Crushed berries only heal slightly — use as emergency med when you have nothing else.', tipVodka: 'Vodka Special', tipVodkaText: 'No HP change; slightly reduces radiation (-1%).', tipCombat: 'Combat Priority', tipCombatText: 'Always treat bleeding first in combat — don\'t just heal HP.', testWeapons: 'Test Weapons', damage: 'dmg', hitsToDestroy: 'Hits to Destroy', buildingType: 'Building Type', hp: 'HP', invalid: 'Invalid', practicalTips: 'Tips & Strategies', craftsmanLevelSystem: 'Craftsman Level System', searchInCategory: 'Search recipes or materials in this category...', recipeCount: 'Recipes', level: 'lv', expShort: 'EXP', ptlCommunity: 'PTL China', ptlSubtitle: 'Erythros Lite Official Community', ptlQQ1: 'QQ Group 1: 666522680', ptlQQ2: 'QQ Group 2: 1107305296', noSpecialEffect: 'No special effects', stopsBleed: 'Stops Bleed', healsBrokenLeg: 'Heals Leg', fullStamina: 'Full Stamina', playerLogin: 'Player Login', playerRegister: 'Player Register', playerProfile: 'Profile', playerViewProfile: 'Player Profile', accountLabel: 'Account ID (QQ / DiscordID / Email)', passwordLabel: 'Password', confirmPasswordLabel: 'Confirm Password', loginButton: 'Login', registerButton: 'Register', noAccountYet: "Don't have an account?", alreadyHaveAccount: 'Already have an account?', registerNow: 'Register Now', backToLogin: 'Back to Login', gameIdLabel: 'Game ID (6-12 digits, permanent after registration)', passwordPlaceholder: 'Enter your password', confirmPasswordPlaceholder: 'Re-enter your password', gameIdPlaceholder: 'Digits only', qqPlaceholder: 'Enter QQ number (5-15 digits)', externalContactPlaceholder: "Don't enter Discord nickname", playerTypeLabel: 'Select your player type', cnPlayer: 'China player (has QQ)', intlPlayer: 'International player (no QQ)', editProfile: 'Edit (password only)', logout: 'Logout', saveChanges: 'Save Changes', currentPasswordLabel: 'Current Password', newPasswordLabel: 'New Password', confirmGameId: 'Confirm your Game ID', gameIdConfirmMsg: 'Your Game ID: {gameId}', gameIdConfirmWarning: '⚠️ Game ID is permanent after registration!', gameIdConfirmDesc: 'Please confirm this is your actual in-game numeric ID. Mistakes can only be fixed by admin.', cancel: 'Cancel', confirmSubmit: 'Confirm Submit', gameIdLocked: 'Game ID and contact info are locked after registration', viewOnlyPublic: 'Showing public game ID only', loading: 'Loading...', adminLogin: 'Admin Login', adminUsername: 'Username', adminPassword: 'Password', adminLoginBtn: 'Login', adminDefaultHint: 'Default admin / admin123', adminLogout: 'Logout', adminDashboard: 'Dashboard', adminItems: 'Items', adminRecipes: 'Recipes', adminMedicines: 'Medicines', adminBuildings: 'Buildings', adminPlayers: 'Players', adminPassword: 'Change Password', adminData: 'Data', adminTotalVisits: 'Total Visits', adminTodayVisits: 'Today', adminWeekVisits: 'This Week', adminTotalPlayers: 'Total Players', adminTopItems: 'Top 10 Items', adminTopPages: 'Page Distribution', adminTrend: '7-Day Trend', adminRecentPlayers: 'Recent Players', adminRecentVisits: 'Recent Visits', adminLoading: 'Loading...', adminLoadFailed: 'Load failed', adminNoData: 'No data', adminEdit: 'Edit', adminDelete: 'Delete', adminConfirmDelete: 'Confirm Delete', adminDeleteMsg: 'Are you sure you want to delete "{name}"? This action cannot be undone.', adminCancel: 'Cancel', adminConfirm: 'Confirm', adminAdd: 'Add', adminAddItem: 'Add Item', adminEditItem: 'Edit Item', adminItemId: 'Item ID', adminItemNameZh: 'Chinese Name', adminItemNameEn: 'English Name', adminItemCategory: 'Category', adminSave: 'Save', adminAddRecipe: 'Add Recipe', adminEditRecipe: 'Edit Recipe', adminRecipeResultZh: 'Result (Chinese)', adminRecipeResultEn: 'Result (English)', adminRecipeResultCount: 'Count', adminRecipeCategory: 'Category', adminRecipeLevel: 'Craftsman Level', adminRecipeMaterials: 'Materials', adminRecipeMaterialZh: 'Chinese Name', adminRecipeMaterialEn: 'English Name', adminRecipeMaterialCount: 'Count', adminRecipeAddMaterial: '+ Add Material', adminRecipeRemoveMaterial: '✕', adminRecipeMaterialError: 'Please complete all materials (name and count)', adminMedicinesHealth: 'Health %', adminMedicinesRadiation: 'Radiation %', adminMedicinesTier: 'Tier', adminMedicinesEffects: 'Effects', adminMedicinesAdd: 'Add Medicine', adminMedicinesEdit: 'Edit Medicine', adminMedicinesEffectBleed: 'Stop Bleed', adminMedicinesEffectBrokenLeg: 'Heal Leg', adminMedicinesEffectStamina: 'Stamina', adminBuildingsHp: 'HP', adminBuildingsWeaponDamage: 'Weapon Damage Data', adminBuildingsAdd: 'Add Building', adminBuildingsEdit: 'Edit Building', adminBuildingsComplexHint: 'Building data contains complex JSON, please use database or improve form later', adminPlayersSearch: 'Search...', adminPlayersQQ: 'QQ', adminPlayersGameId: 'Game ID', adminPlayersRegisterTime: 'Registered', adminPasswordChange: 'Change Admin Password', adminPasswordOld: 'Old Password', adminPasswordNew: 'New Password (min 6 chars)', adminPasswordConfirm: 'Confirm New Password', adminPasswordSubmit: 'Change Password', adminPasswordSuccess: 'Password changed successfully!', adminPasswordError: 'Change failed', adminDataReset: 'Data Management', adminDataResetDesc: 'Reset database to initial seed data. Warning: All manual changes will be overwritten!', adminDataResetDanger: 'Reset to Initial Data', adminDataResetConfirmTitle: 'Confirm Reset?', adminDataResetConfirmMsg: 'This will reset all items, recipes, medicines, buildings to initial version. All manual changes will be lost. Continue?', adminDataResetSuccess: 'Operation complete', adminDataResetFail: 'Operation failed', community: 'Community', communityTitle: 'Community Forum', newPost: 'New Post', postTitle: 'Title', postContent: 'Content', postCategory: 'Category', categoryGeneral: 'General', categoryGuide: 'Guide', categoryHelp: 'Help', categoryDiscussion: 'Discussion', categoryFeedback: 'Feedback', postSubmit: 'Post', postCancel: 'Cancel', reply: 'Reply', writeReply: 'Write a reply...', noPosts: 'No posts yet. Be the first!', noReplies: 'No replies yet. Be the first!', postDeleted: 'Post deleted', replyDeleted: 'Reply deleted', confirmDeletePost: 'Confirm delete this post?', confirmDeleteReply: 'Confirm delete this reply?', delete: 'Delete', edit: 'Edit', like: 'Like', unlike: 'Unlike', viewCount: 'Views', replyCount: 'Replies', postedBy: 'Posted by', author: 'Author', loadMore: 'Load more', backToCommunity: 'Back to Community', welcomeTitle: 'Welcome!', welcomeButton: 'Got it!', welcomeDefault: 'Welcome to Erythros Lite Wiki! Enjoy your game! 🎮', // 新增键 idLabel: 'ID', giveCommand: '/give', crafting: 'Crafting', craftingEn: 'Crafting', craftingRecipe: 'Craft Recipe', materialsLabel: 'Materials', quantityLabel: 'Quantity', wikiSubtitle: 'PTL Community Mod Quick Reference', homeIntro: 'This wiki contains item IDs, crafting recipes, medicine effects, building durability and map specs. Press / to quick‑focus search box.', wikiBy: 'Wiki by: PTL Community', gameCredits: 'Game Credits', creditTitle: '🎯 Title', creditCreator: '👨💻 Creator / Developer', creditCreatorDesc: '(Independent Developer)', creditPublisher: '🏢 Publisher / Studio', creditPublisherDesc: '(Publisher)', creditWebsite: '🌐 Official Website', creditEmail: '📧 Contact', creditEmailDesc: '(Developer)', creditCommunity: '🇨🇳 Chinese Community', creditCommunityDesc: '(Player Community / Wiki Maintainers)', wikiDisclaimer: 'This wiki is maintained by PTL China Community, an unofficial fan project.', wikiContents: '📖 Wiki Contents', wikiContent1: 'Full stats for weapons, armors and items', wikiContent2: 'Craft recipes, medicine effects, building durability', wikiContent3: 'Map specs, item IDs, bilingual names', wikiContent4: 'Search by ID / name, filter categories', wikiTip: 'Tip: Change url hash to #items for item wiki', mapSizeSpec: 'Size Specifications', scaleLabel: 'SCALE', mapPermNormal: 'can create TINY, SMALL, and MEDIUM size maps.', mapPermNormalEn: 'Regular players can create TINY, SMALL, and MEDIUM size maps.', mapPermPremium: 'LARGE and INSANE', mapPermPremiumEn: 'sizes require Premium sponsor access.', insaneNote: '4096×4096 (INSANE) maps require high server performance, suitable for large servers and extreme survival.', insaneNoteEn: '4096×4096 (INSANE) maps require high server performance, suitable for large servers and extreme survival.', medicineGuide: 'Medicine Effects Guide', medItems: 'Medicine', buildingsLabel: 'Buildings', buildingDurabilityData: 'Building Durability Data', craftingList: 'Crafting Recipes List', postNotFound: 'Post not found', loadFailed: 'Load failed', anonymous: 'Anonymous', allLabel: 'All', loginToPost: 'Login to post', beFirstPost: 'Click "New Post" to be the first!', pinned: 'Pinned', homeLabel: 'Home', homeLabelEn: 'Home', homeLabelRu: 'Home', mapSizesEn: 'Map Sizes', mapSizesRu: 'Map Sizes', medicineEffectsEn: 'Medicine Effects', medicineEffectsRu: 'Medicine Effects', craftingRecipesEn: 'Crafting Recipes', craftingRecipesRu: 'Crafting Recipes', buildingDurabilityEn: 'Building Durability', buildingDurabilityRu: 'Building Durability', communityEn: 'Community', communityRu: 'Community', wikiRef: 'Wiki Ref', registerLogin: 'Register / Login', adminPanel: 'Admin Panel', totalItemsLabel: 'Total', itemsUnit: 'items', langZh: '中文', langEn: 'EN', langRu: 'RU', adminLoading: 'Admin Panel (Loading...)', pageNotFound: 'Page not found', gameIdFormatError: 'Game ID must be 6-12 digits only!', passwordMismatch: 'Passwords do not match', currentPasswordRequired: 'Please enter current password', passwordChanged: 'Password changed successfully!', updateFailed: 'Update failed', myPosts: 'My Posts', noMyPosts: 'No posts yet', goToCommunity: 'Go to community!', }, ru: { appTitle: 'Erythros Lite Wiki', appSubtitle: 'Краткий справочник', searchPlaceholder: 'Поиск по названию, ID или рецепту...', totalItems: 'Всего предметов', categories: 'Категории', itemCategories: 'Категории предметов', gameData: 'Игровые данные', mapSizes: 'Размеры карт', medicineEffects: 'Эффекты медицины', craftingRecipes: 'Рецепты крафта', buildingDurability: 'Прочность построек', searchResults: 'Результаты поиска', searchResultsFor: 'Результаты для', found: 'НАЙДЕНО', itemsItems: 'ПРЕДМЕТЫ', idRange: 'ДИАПАЗОН ID', noResults: 'Предметы не найдены', noResultsDesc: 'Попробуйте другие ключевые слова или категории', noRecipeResults: 'Рецепты не найдены', noRecipeResultsDesc: 'Попробуйте другие ключевые слова', copyId: 'Копировать ID', copied: 'Скопировано', copyRecipe: 'Рецепт', copyCmd: 'Команда', itemId: 'ID предмета', itemNameEn: 'Английское название', category: 'Категория', sizeTiers: 'Размеры', notes: 'Примечания', normalPlayers: 'Обычные игроки', premiumOnly: 'LARGE и INSANE', premiumDesc: 'требуют Premium доступа.', insaneNote: 'Карты 4096×4096 (INSANE) требуют высокой производительности сервера.', iconLegend: 'Значки', health: 'Здоровье', healthDesc: 'Очки здоровья', radiation: 'Радиация', radiationDesc: 'Болезнь / радиация', bleed: 'Остановить кровотечение', bleedDesc: 'Останавливает кровотечение', brokenLeg: 'Вылечить ногу', brokenLegDesc: 'Убирает перелом ноги', stamina: 'Выносливость', staminaDesc: 'Восстанавливает выносливость', filterAll: 'Все', filterHigh: 'Высокий класс', filterMid: 'Средний класс', filterLow: 'Низкий класс', filterBerry: 'Ягоды', filterSpecial: 'Особые', medicationTips: 'Советы по лекарствам', tipWarning: 'Внимание', tipWarningText: 'Большинство лечебных средств также повышают радиацию.', tipHighValue: 'Лучшее лечение', tipHighValueText: 'Brilliant Green восстанавливает +75% HP, но сильно повышает радиацию.', tipEmergency: 'Экстренное использование', tipEmergencyText: 'Морфин лечит ногу, Адреналин восстанавливает выносливость, Вакцина снижает радиацию.', tipBerry: 'Ягоды', tipBerryText: 'Измельчённые ягоды слабо лечат — используйте в крайнем случае.', tipVodka: 'Водка', tipVodkaText: 'Не влияет на HP, слабо снижает радиацию (-1%).', tipCombat: 'Бой', tipCombatText: 'Сначала останавливайте кровотечение, не только лечите HP.', testWeapons: 'Тестовое оружие', damage: 'урон', hitsToDestroy: 'Ударов до разрушения', buildingType: 'Тип постройки', hp: 'HP', invalid: 'Недействительно', practicalTips: 'Советы и стратегии', craftsmanLevelSystem: 'Система уровней ремесленника', searchInCategory: 'Поиск рецептов в этой категории...', recipeCount: 'Рецепты', level: 'ур.', expShort: 'ОПЫТ', ptlCommunity: 'PTL Китай', ptlSubtitle: 'Официальное сообщество Erythros Lite', ptlQQ1: 'QQ группа 1: 666522680', ptlQQ2: 'QQ группа 2: 1107305296', noSpecialEffect: 'Нет особых эффектов', stopsBleed: 'Останавливает кровотечение', healsBrokenLeg: 'Лечит ногу', fullStamina: 'Восстанавливает выносливость', playerLogin: 'Вход игрока', playerRegister: 'Регистрация игрока', playerProfile: 'Профиль', playerViewProfile: 'Профиль игрока', accountLabel: 'Аккаунт (QQ / DiscordID / Email)', passwordLabel: 'Пароль', confirmPasswordLabel: 'Подтверждение пароля', loginButton: 'Войти', registerButton: 'Зарегистрироваться', noAccountYet: 'Нет аккаунта?', alreadyHaveAccount: 'Уже есть аккаунт?', registerNow: 'Зарегистрироваться', backToLogin: 'Назад ко входу', gameIdLabel: 'Game ID (6-12 цифр, постоянно после регистрации)', passwordPlaceholder: 'Введите пароль', confirmPasswordPlaceholder: 'Повторите пароль', gameIdPlaceholder: 'Только цифры', qqPlaceholder: 'Введите QQ номер (5-15 цифр)', externalContactPlaceholder: 'Не вводите никнейм Discord', playerTypeLabel: 'Выберите тип игрока', cnPlayer: 'Игрок из Китая (есть QQ)', intlPlayer: 'Международный игрок (нет QQ)', editProfile: 'Редактировать (только пароль)', logout: 'Выйти', saveChanges: 'Сохранить изменения', currentPasswordLabel: 'Текущий пароль', newPasswordLabel: 'Новый пароль', confirmGameId: 'Подтвердите Game ID', gameIdConfirmMsg: 'Ваш Game ID: {gameId}', gameIdConfirmWarning: '⚠️ Game ID постоянен после регистрации!', gameIdConfirmDesc: 'Пожалуйста, подтвердите ваш реальный игровой ID. Ошибки исправляет только администратор.', cancel: 'Отмена', confirmSubmit: 'Подтвердить', gameIdLocked: 'Game ID и контактные данные закреплены после регистрации', viewOnlyPublic: 'Показан только публичный Game ID', loading: 'Загрузка...', adminLogin: 'Вход администратора', adminUsername: 'Имя пользователя', adminPassword: 'Пароль', adminLoginBtn: 'Войти', adminDefaultHint: 'По умолчанию admin / admin123', adminLogout: 'Выйти', adminDashboard: 'Статистика', adminItems: 'Предметы', adminRecipes: 'Рецепты', adminMedicines: 'Лекарства', adminBuildings: 'Постройки', adminPlayers: 'Игроки', adminPassword: 'Сменить пароль', adminData: 'Данные', adminTotalVisits: 'Всего посещений', adminTodayVisits: 'Сегодня', adminWeekVisits: 'На этой неделе', adminTotalPlayers: 'Всего игроков', adminTopItems: 'Топ 10 предметов', adminTopPages: 'Распределение страниц', adminTrend: 'Динамика за 7 дней', adminRecentPlayers: 'Новые игроки', adminRecentVisits: 'Недавние посещения', adminLoading: 'Загрузка...', adminLoadFailed: 'Ошибка загрузки', adminNoData: 'Нет данных', adminEdit: 'Редактировать', adminDelete: 'Удалить', adminConfirmDelete: 'Подтвердите удаление', adminDeleteMsg: 'Удалить "{name}"? Действие необратимо.', adminCancel: 'Отмена', adminConfirm: 'Подтвердить', adminAdd: 'Добавить', adminAddItem: 'Добавить предмет', adminEditItem: 'Редактировать предмет', adminItemId: 'ID предмета', adminItemNameZh: 'Китайское название', adminItemNameEn: 'Английское название', adminItemCategory: 'Категория', adminSave: 'Сохранить', adminAddRecipe: 'Добавить рецепт', adminEditRecipe: 'Редактировать рецепт', adminRecipeResultZh: 'Результат (кит.)', adminRecipeResultEn: 'Результат (англ.)', adminRecipeResultCount: 'Количество', adminRecipeCategory: 'Категория', adminRecipeLevel: 'Уровень ремесленника', adminRecipeMaterials: 'Материалы', adminRecipeMaterialZh: 'Кит. название', adminRecipeMaterialEn: 'Англ. название', adminRecipeMaterialCount: 'Кол-во', adminRecipeAddMaterial: '+ Добавить материал', adminRecipeRemoveMaterial: '✕', adminRecipeMaterialError: 'Заполните все материалы (название и кол-во)', adminMedicinesHealth: 'Здоровье %', adminMedicinesRadiation: 'Радиация %', adminMedicinesTier: 'Уровень', adminMedicinesEffects: 'Эффекты', adminMedicinesAdd: 'Добавить лекарство', adminMedicinesEdit: 'Редактировать лекарство', adminMedicinesEffectBleed: 'Остановить кровотечение', adminMedicinesEffectBrokenLeg: 'Вылечить ногу', adminMedicinesEffectStamina: 'Выносливость', adminBuildingsHp: 'HP', adminBuildingsWeaponDamage: 'Данные по оружию', adminBuildingsAdd: 'Добавить постройку', adminBuildingsEdit: 'Редактировать постройку', adminBuildingsComplexHint: 'Данные содержат JSON, используйте базу данных', adminPlayersSearch: 'Поиск...', adminPlayersQQ: 'QQ', adminPlayersGameId: 'Game ID', adminPlayersRegisterTime: 'Регистрация', adminPasswordChange: 'Сменить пароль администратора', adminPasswordOld: 'Старый пароль', adminPasswordNew: 'Новый пароль (мин. 6 символов)', adminPasswordConfirm: 'Подтвердите новый пароль', adminPasswordSubmit: 'Сменить пароль', adminPasswordSuccess: 'Пароль изменён!', adminPasswordError: 'Ошибка изменения', adminDataReset: 'Управление данными', adminDataResetDesc: 'Сбросить базу данных к начальным данным. ВНИМАНИЕ: все изменения будут потеряны!', adminDataResetDanger: 'Сбросить к начальным данным', adminDataResetConfirmTitle: 'Подтвердить сброс?', adminDataResetConfirmMsg: 'Все предметы, рецепты, лекарства и постройки будут сброшены. Все изменения потеряны. Продолжить?', adminDataResetSuccess: 'Операция завершена', adminDataResetFail: 'Операция не удалась', community: 'Сообщество', communityTitle: 'Форум', newPost: 'Новый пост', postTitle: 'Заголовок', postContent: 'Содержание', postCategory: 'Категория', categoryGeneral: 'Общее', categoryGuide: 'Гайды', categoryHelp: 'Помощь', categoryDiscussion: 'Обсуждение', categoryFeedback: 'Отзывы', postSubmit: 'Опубликовать', postCancel: 'Отмена', reply: 'Ответить', writeReply: 'Написать ответ...', noPosts: 'Пока нет постов. Будьте первым!', noReplies: 'Пока нет ответов. Будьте первым!', postDeleted: 'Пост удалён', replyDeleted: 'Ответ удалён', confirmDeletePost: 'Удалить этот пост?', confirmDeleteReply: 'Удалить этот ответ?', delete: 'Удалить', edit: 'Редактировать', like: 'Нравится', unlike: 'Не нравится', viewCount: 'Просмотров', replyCount: 'Ответов', postedBy: 'Опубликовал', author: 'Автор', loadMore: 'Загрузить ещё', backToCommunity: 'Назад в сообщество', welcomeTitle: 'Добро пожаловать!', welcomeButton: 'Понятно', welcomeDefault: 'Добро пожаловать в вики Erythros Lite! Приятной игры! 🎮', // 新增键 idLabel: 'ID', giveCommand: '/give', crafting: 'Крафт', craftingEn: 'Крафт', craftingRecipe: 'Рецепт крафта', materialsLabel: 'Материалы', quantityLabel: 'Количество', wikiSubtitle: 'Краткий справочник мода PTL', homeIntro: 'Эта вики содержит ID предметов, рецепты крафта, эффекты медицины, прочность построек и характеристики карт. Нажмите / для быстрого перехода к поиску.', wikiBy: 'Вики от: PTL Community', gameCredits: 'Создатели игры', creditTitle: '🎯 Название', creditCreator: '👨💻 Создатель / Разработчик', creditCreatorDesc: '(Независимый разработчик)', creditPublisher: '🏢 Издатель / Студия', creditPublisherDesc: '(Издатель)', creditWebsite: '🌐 Официальный сайт', creditEmail: '📧 Контакт', creditEmailDesc: '(Разработчик)', creditCommunity: '🇨🇳 Китайское сообщество', creditCommunityDesc: '(Игровое сообщество / Администраторы вики)', wikiDisclaimer: 'Эта вики поддерживается сообществом PTL China, неофициальный фанатский проект.', wikiContents: '📖 Содержание вики', wikiContent1: 'Полные характеристики оружия, брони и предметов', wikiContent2: 'Рецепты крафта, эффекты медицины, прочность построек', wikiContent3: 'Характеристики карт, ID предметов, двуязычные названия', wikiContent4: 'Поиск по ID / названию, фильтрация по категориям', wikiTip: 'Совет: измените хеш URL на #items для перехода к вики предметов', mapSizeSpec: 'Спецификации размеров', scaleLabel: 'МАСШТАБ', mapPermNormal: 'могут создавать карты размеров TINY, SMALL и MEDIUM.', mapPermNormalEn: 'Обычные игроки могут создавать карты размеров TINY, SMALL и MEDIUM.', mapPermPremium: 'LARGE и INSANE', mapPermPremiumEn: 'требуют Premium доступа.', insaneNote: 'Карты 4096×4096 (INSANE) требуют высокой производительности сервера, подходят для больших серверов и экстремального выживания.', insaneNoteEn: 'Карты 4096×4096 (INSANE) требуют высокой производительности сервера, подходят для больших серверов и экстремального выживания.', medicineGuide: 'Руководство по эффектам медицины', medItems: 'ЛЕКАРСТВА', buildingsLabel: 'Постройки', buildingDurabilityData: 'Данные по прочности построек', craftingList: 'Список рецептов крафта', postNotFound: 'Пост не найден', loadFailed: 'Ошибка загрузки', anonymous: 'Аноним', allLabel: 'Все', loginToPost: 'Войдите, чтобы написать', beFirstPost: 'Нажмите «Новый пост», чтобы стать первым!', pinned: 'Закреплено', homeLabel: 'Главная', homeLabelEn: 'Главная', homeLabelRu: 'Главная', mapSizesEn: 'Размеры карт', mapSizesRu: 'Размеры карт', medicineEffectsEn: 'Эффекты медицины', medicineEffectsRu: 'Эффекты медицины', craftingRecipesEn: 'Рецепты крафта', craftingRecipesRu: 'Рецепты крафта', buildingDurabilityEn: 'Прочность построек', buildingDurabilityRu: 'Прочность построек', communityEn: 'Сообщество', communityRu: 'Сообщество', wikiRef: 'Вики', registerLogin: 'Регистрация / Вход', adminPanel: 'Панель администратора', totalItemsLabel: 'Всего предметов', itemsUnit: 'предметов', langZh: 'Китайский', langEn: 'Английский', langRu: 'Русский', adminLoading: 'Панель администратора (Загрузка...)', pageNotFound: 'Страница не найдена', gameIdFormatError: 'Game ID должен содержать только 6-12 цифр!', passwordMismatch: 'Пароли не совпадают', currentPasswordRequired: 'Введите текущий пароль', passwordChanged: 'Пароль изменён успешно!', updateFailed: 'Ошибка обновления', myPosts: 'Мои посты', noMyPosts: 'Нет постов', goToCommunity: 'Перейти в сообщество!', }, }; const langs = ['zh', 'en', 'ru']; langs.forEach(lang => { if (!window.UI_STRINGS[lang]) window.UI_STRINGS[lang] = {}; const target = window.UI_STRINGS[lang]; const source = defaultStrings[lang]; for (const key in source) { if (!target.hasOwnProperty(key)) { target[key] = source[key]; } } }); })(); // ===== ICONS ===== const ICONS = { helm: (), bag: (), shield: (), shirt: (), pants: (), gun: (), axe: (), scope: (), bullet: (), laser: (), muzzle: (), med: (), food: (), drink: (), furn: (), wall: (), mat: (), obuild: (), seed: (), grenade: (), oammo: (), tool: (), map: (), craft: (), dura: (), search: (), copy: (), check: (), menu: (), heart: (), radiation: (), hand: (), bone: (), bolt: (), alert: (), empty: (), cross: (), hammer: (), globe: (), }; function Icon({ name, className = '' }) { return {ICONS[name] || ICONS.tool}; } // ===== 样式常量 ===== const confirmOverlayStyle = { position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(2px)', }; const confirmBoxStyle = { background: 'linear-gradient(180deg, var(--bg-2), var(--bg-1))', border: '1px solid var(--border-1)', borderRadius: 6, padding: 24, width: 420, maxWidth: '90vw', boxShadow: '0 20px 60px rgba(0,0,0,0.5), 0 0 40px rgba(196,90,58,0.1)', }; const btnPrimaryStyle = { padding: '7px 18px', background: 'linear-gradient(135deg, var(--accent-rust), var(--accent-rust-dim))', border: '1px solid var(--accent-rust)', borderRadius: 3, color: '#fff', cursor: 'pointer', fontSize: 12, fontWeight: 500, boxShadow: '0 2px 6px rgba(196,90,58,0.3)', fontFamily: 'var(--sans)', }; const btnSecondaryStyle = { padding: '7px 18px', background: 'var(--bg-2)', border: '1px solid var(--border-1)', borderRadius: 3, color: 'var(--text-1)', cursor: 'pointer', fontSize: 12, fontFamily: 'var(--sans)', }; const btnGhostStyle = { padding: '4px 12px', background: 'transparent', border: '1px solid var(--border-1)', borderRadius: 2, color: 'var(--text-2)', cursor: 'pointer', fontSize: 11, fontFamily: 'var(--sans)', }; const inputStyle = { width: '100%', height: 36, padding: '0 10px', background: 'var(--bg-0)', border: '1px solid var(--border-1)', borderRadius: 3, color: 'var(--text-0)', fontSize: 12, fontFamily: 'var(--sans)', outline: 'none', }; const labelStyle = { display: 'block', color: 'var(--text-2)', fontSize: 11, marginBottom: 5, letterSpacing: 0.5, }; const panelStyle = { background: 'linear-gradient(180deg, var(--bg-1), var(--bg-2))', border: '1px solid var(--border-0)', borderRadius: 5, padding: 18, boxShadow: '0 2px 8px rgba(0,0,0,0.15)', }; // ========== 片段 1 结束 ========== // ===== COPY BUTTON ===== function CopyButton({ text, label = '复制', small = false }) { const [copied, setCopied] = useState(false); const lang = useLang(); const str = window.UI_STRINGS[lang]; const handleClick = (e) => { e.stopPropagation(); navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 1500); }; return ( ); } // ===== ITEM CARD ===== function ItemCard({ item, category, isExpanded, onToggle }) { const lang = useLang(); const str = window.UI_STRINGS[lang]; const itemName = lang === 'zh' ? item.nameZh : lang === 'en' ? item.nameEn : item.nameRu || item.nameEn; let catName, catNameOther; if (lang === 'zh') { catName = category.name; catNameOther = category.nameEn; } else if (lang === 'en') { catName = category.nameEn; catNameOther = category.name; } else { catName = category.nameRu || category.nameEn; catNameOther = category.nameEn; } return (
{str.noResultsDesc}
{str.noResultsDesc}
{str.welcomeDefault}
{str.homeIntro}
{str.wikiBy}
Version v26.02.10
{str.wikiDisclaimer}
{str.wikiTip}
| {str.buildingType} | {str.hp} | {(data?.weapons ?? []).map(w =>{w.shortName} {w.damage} {str.damage} | )}
|---|---|---|
{lang === 'zh' ? b.nameZh : b.nameEn} {lang === 'zh' ? b.nameEn : b.nameZh} |
= 3000 ? 'linear-gradient(90deg, #8a9a7a, #b0c090)' : b.hp >= 1000 ? 'linear-gradient(90deg, #c49a4a, #e0b860)' : 'linear-gradient(90deg, #b07050, #d49060)' }}> |
{(data?.weapons ?? []).map(w => {
const hits = b.hits[w.key];
const isInvalid = hits === null;
return = 100 ? 'hits-high' : 'hits-mid'}`}>
{isInvalid ? | ;
})}
{currentUser ? str.beFirstPost || '点击“发新帖”成为第一个!' : str.loginToPost || '请先登录再发帖'}
{str.goToCommunity || '去社区发个帖吧!'}