import { useState, useEffect } from 'react';
import { getStatus } from './api';

// ---------------------------------------------------------------------------
// Translation dictionaries
// ---------------------------------------------------------------------------

export type Locale = 'en' | 'zh' | 'tr';

const translations: Record<Locale, Record<string, string>> = {
  zh: {
    // Navigation
    'nav.dashboard': '仪表盘',
    'nav.agent': '智能体',
    'nav.tools': '工具',
    'nav.cron': '定时任务',
    'nav.integrations': '集成',
    'nav.modelswitch': '模型配置',
    'nav.skills': '技能',
    'nav.history': '历史对话',
    'nav.general': '常规',
    'nav.memory': '记忆',
    'nav.config': '配置',
    'nav.cost': '成本追踪',
    'nav.logs': '日志',
    'nav.doctor': '诊断',
    'nav.canvas': '画布',

    // Dashboard
    'dashboard.title': '仪表盘',
    'dashboard.provider': '提供商',
    'dashboard.model': '模型',
    'dashboard.uptime': '运行时间',
    'dashboard.temperature': '温度',
    'dashboard.gateway_port': '网关端口',
    'dashboard.memory_backend': '记忆后端',
    'dashboard.paired': '已配对',
    'dashboard.channels': '频道',
    'dashboard.health': '健康状态',
    'dashboard.status': '状态',
    'dashboard.overview': '概览',
    'dashboard.system_info': '系统信息',
    'dashboard.quick_actions': '快速操作',

    // Agent / Chat
    'agent.title': '智能体对话',
    'agent.send': '发送',
    'agent.placeholder': '输入任务或问我任何问题',
    'agent.start_conversation': '发送消息开始对话',
    'agent.type_message': '输入消息...',
    'agent.light_greeting_title': '你好，我是麒灵！',
    'agent.light_greeting_subtitle': '描述你的任务，我将为你自动执行，让复杂工作变得简单。',
    'agent.light_try_label': '你可以尝试：',
    'agent.light_refresh_label': '换一换',
    'agent.light_card_recommended': '推荐问题',
    'agent.light_card_knowledge': '知识库',
    'agent.light_card_knowledge_prompt': '帮我总结知识库里的重点内容。',
    'agent.light_suggestion_one': '如何去除白色衣服上的咖啡渍？',
    'agent.light_suggestion_two': '有哪些适合团队破冰的小游戏？',
    'agent.light_suggestion_three': '帮我写一封简短的客户跟进邮件。',
    'agent.light_suggestion_four': '如何把一篇长文章总结成要点？',
    'agent.light_suggestion_five': 'Excel 里怎么按条件求和？',
    'agent.light_suggestion_six': '帮我写一段产品上线的通知文案。',
    'agent.light_suggestion_seven': '初学者如何开始学习编程？',
    'agent.light_suggestion_eight': '出差三天需要带什么清单？',
    'agent.light_suggestion_nine': '用通俗语言解释什么是 API。',
    'agent.light_type_message': '输入任务或问我任何问题',
    'agent.light_tool_model': '智能模型调度',
    'agent.light_tool_expand': '深度思考',
    'agent.light_tool_search': '联网搜索',
    'agent.model_selector_title': '选择模型',
    'agent.model_selector_trial': '试用模型',
    'agent.model_selector_configured': '已配置模型',
    'agent.model_selector_no_trial': '无可用试用模型',
    'agent.model_selector_no_configured': '未配置其他模型',
    'agent.connecting': '连接中...',
    'agent.connected': '已连接',
    'agent.disconnected': '已断开',
    'agent.reconnecting': '重新连接中...',
    'agent.thinking': '思考中...',
    'agent.tool_call': '工具调用',
    'agent.tool_result': '工具结果',
    'agent.connection_error': '连接错误，正在尝试重连...',
    'agent.tool_call_prefix': '[工具调用]',
    'agent.tool_result_prefix': '[工具结果]',
    'agent.error_prefix': '[错误]',
    'agent.unknown_error': '未知错误',
    'agent.send_error': '发送消息失败，请重试。',
    'agent.copy_message': '复制消息',
    'agent.show_json': '展开 JSON',
    'agent.hide_json': '收起 JSON',
    'agent.toggle_system_messages': '切换系统消息显示',
    'agent.connected_status': '已连接',
    'agent.disconnected_status': '已断开',
    'agent.generating_block_tip': '正在生成回答，请完成后再试',
    'header.new_session': '开启新对话',
    'header.window_pin': '置顶',
    'header.window_minimize': '最小化',
    'header.window_maximize': '最大化',
    'header.window_close': '关闭',
    'modelswitch.tab.general': '常规',
    'modelswitch.tab.model': '模型配置',
    'modelswitch.always_on_top': '窗口置顶',
    'modelswitch.close_action': '关闭窗口时',
    'modelswitch.close_action_hide': '隐藏窗口',
    'modelswitch.close_action_exit': '直接退出',

    // Tools
    'tools.title': '可用工具',
    'tools.name': '名称',
    'tools.description': '描述',
    'tools.parameters': '参数',
    'tools.search': '搜索工具...',
    'tools.empty': '暂无可用工具。',
    'tools.count': '工具总数',
    'tools.agent_tools': '智能体工具箱',
    'tools.cli_tools': 'CLI 工具箱',
    'tools.parameter_schema': '参数结构',
    'tools.path': '路径',
    'tools.version': '版本',
    'tools.category': '类别',
    'tools.load_error': '加载工具失败',

    // Cron
    'cron.title': '定时任务',
    'cron.task_list': '任务列表',
    'cron.prompt_col': '提示词',
    'cron.status_success': '成功',
    'cron.status_failed': '失败',
    'cron.scheduled_tasks': '定时任务',
    'cron.add': '添加任务',
    'cron.add_job': '添加任务',
    'cron.modal_add': '添加',
    'cron.add_modal_title': '添加任务',
    'cron.delete': '删除',
    'cron.enable': '启用',
    'cron.disable': '禁用',
    'cron.name': '名称',
    'cron.name_optional': '名称（可选）',
    'cron.command': '命令',
    'cron.command_required': '命令',
    'cron.schedule': '计划',
    'cron.schedule_required': '计划',
    'cron.schedule_kind_cron': 'Cron 表达式',
    'cron.schedule_kind_at': '指定时间',
    'cron.schedule_kind_every': '固定间隔',
    'cron.schedule_cron_placeholder': '例如 0 0 * * *',
    'cron.schedule_tz_optional': '时区（可选，例如 Asia/Shanghai）',
    'cron.schedule_every_ms_placeholder': '间隔毫秒数（例如 60000）',
    'cron.next_run': '下次执行',
    'cron.last_run': '上次执行',
    'cron.last_status': '上次状态',
    'cron.enabled': '已启用',
    'cron.enabled_status': '启用',
    'cron.disabled_status': '禁用',
    'cron.empty': '暂无定时任务。',
    'cron.confirm_delete': '确定要删除此任务吗？',
    'cron.load_error': '加载定时任务失败',
    'cron.validation_error': '计划和命令是必需的。',
    'cron.add_error': '添加任务失败',
    'cron.delete_error': '删除任务失败',
    'cron.cancel': '取消',
    'cron.adding': '添加中...',
    'cron.id': 'ID',
    'cron.actions': '操作',
    'cron.loading_run_history': '加载运行历史...',
    'cron.load_run_history_error': '加载运行历史失败',
    'cron.no_runs': '暂无运行记录。',
    'cron.recent_runs': '最近运行',
    'cron.yes': '是',
    'cron.no': '否',
    'cron.edit': '编辑',
    'cron.edit_modal_title': '编辑任务',
    'cron.edit_error': '更新任务失败',
    'cron.saving': '保存中...',
    'cron.save': '保存',
    'cron.confirm': '确定',
    'cron.job_type': '任务类型',
    'cron.job_type_shell': 'Shell',
    'cron.job_type_agent': 'Agent',
    'cron.session_target': '会话目标',
    'cron.session_target_isolated': '隔离会话',
    'cron.session_target_main': '主会话',
    'cron.model_optional': '模型（可选）',
    'cron.allowed_tools': '允许工具（逗号分隔）',
    'cron.delivery_mode': '投递模式',
    'cron.delivery_mode_none': '无',
    'cron.delivery_mode_announce': '通告',
    'cron.delivery_channel': '投递通道',
    'cron.delivery_target': '投递目标',
    'cron.delivery_best_effort': '尽力投递',
    'cron.enable_job': '启用任务',
    'cron.delete_after_run': '运行后删除',
    'cron.run_now': '立即执行',
    'cron.pause_job': '暂停任务',
    'cron.resume_job': '恢复任务',
    'cron.run_error': '执行任务失败',
    'cron.toggle_error': '切换任务状态失败',
    'cron.catch_up_title': '启动时补跑错过任务',
    'cron.catch_up_desc': 'KylinBot 重启后补执行停机期间应执行的任务',
    'cron.name_placeholder': '例如 每日清理',
    'cron.command_shell_placeholder': '例如 cleanup --older-than 7d',
    'cron.command_agent_placeholder': '输入要交给 Agent 执行的提示词',
    'cron.model_placeholder': '例如 gpt-4.1',
    'cron.allowed_tools_placeholder': 'file_read,web_search',
    'cron.toggle_run_history': '展开/收起运行历史',
    'cron.task_name': '任务名称',
    'cron.task_prompt_label': '任务指令',
    'cron.task_name_placeholder': '请输入任务名称',
    'cron.task_prompt_placeholder': '请输入任务指令。例如：每天推荐5个实用英语单词',
    'cron.exec_time': '执行时间',
    'cron.daily_time_step_up': '增加一分钟',
    'cron.daily_time_step_down': '减少一分钟',
    'cron.once_run_date': '执行日期',
    'cron.once_date_step_up': '增加一天',
    'cron.once_date_step_down': '减少一天',
    'cron.schedule_daily_label': '每天',
    'cron.schedule_interval_label': '间隔',
    'cron.schedule_once_label': '单次',
    'cron.remote_channel': '远控通道',
    'cron.exec_model': '执行模型',
    'cron.channel_main': '主对话',
    'cron.interval_every': '每',
    'cron.interval_row_label': '每间隔',
    'cron.interval_step_up': '间隔数值加一',
    'cron.interval_step_down': '间隔数值减一',
    'cron.interval_unit_minute': '分钟',
    'cron.interval_unit_hour': '小时',
    'cron.interval_unit_day': '天',
    'cron.date_range': '日期区间',
    'cron.date_range_start': '开始时间',
    'cron.date_range_end': '结束时间',
    'cron.model_default': '默认',
    'cron.weekday_1': '周一',
    'cron.weekday_2': '周二',
    'cron.weekday_3': '周三',
    'cron.weekday_4': '周四',
    'cron.weekday_5': '周五',
    'cron.weekday_6': '周六',
    'cron.weekday_7': '周日',

    // Integrations
    'integrations.title': '集成',
    'integrations.available': '可用',
    'integrations.active': '活跃',
    'integrations.coming_soon': '即将推出',
    'integrations.category': '类别',
    'integrations.status': '状态',
    'integrations.search': '搜索集成...',
    'integrations.empty': '未找到集成。',
    'integrations.activate': '激活',
    'integrations.deactivate': '停用',
    'integrations.load_error': '加载集成失败',
    'integrations.status_active': '活跃',
    'integrations.status_available': '可用',
    'integrations.status_coming_soon': '即将推出',

    // Model Switch
    'modelswitch.title': '模型配置',
    'modelswitch.all': '全部',
    'modelswitch.empty': '未找到模型。',
    'modelswitch.status_active': '已激活',
    'modelswitch.status_available': '可用',
    'modelswitch.status_coming_soon': '即将推出',

    // Skills
    'skills.title': '技能',
    'skills.all': '全部',
    'skills.empty': '未找到技能。',
    'skills.enabled': '已启用',
    'skills.disabled': '已禁用',
    'skills.status_active': '已激活',
    'skills.status_available': '可用',
    'skills.status_coming_soon': '即将推出',

    // Memory
    'memory.title': '记忆存储',
    'memory.memory_title': '记忆',
    'memory.search': '搜索记忆...',
    'memory.search_placeholder': '搜索记忆条目...',
    'memory.add': '存储记忆',
    'memory.add_memory': '添加记忆',
    'memory.add_modal_title': '添加记忆',
    'memory.delete': '删除',
    'memory.key': '键',
    'memory.key_required': '键',
    'memory.content': '内容',
    'memory.content_required': '内容',
    'memory.category': '类别',
    'memory.category_optional': '类别（可选）',
    'memory.timestamp': '时间戳',
    'memory.session': '会话',
    'memory.score': '分数',
    'memory.empty': '未找到记忆条目。',
    'memory.confirm_delete': '确定要删除此记忆条目吗？',
    'memory.all_categories': '所有类别',
    'memory.search_button': '搜索',
    'memory.load_error': '加载记忆失败',
    'memory.saving': '保存中...',
    'memory.validation_error': '键和内容是必需的。',
    'memory.store_error': '保存记忆失败',
    'memory.delete_error': '删除记忆失败',
    'memory.delete_confirm': '删除？',
    'memory.yes': '是',
    'memory.no': '否',
    'memory.cancel': '取消',

    // Config
    'config.title': '配置',
    'config.save': '保存',
    'config.saving': '保存中...',
    'config.reset': '重置',
    'config.saved': '配置保存成功。',
    'config.error': '配置保存失败。',
    'config.loading': '加载配置中...',
    'config.editor_placeholder': 'TOML 配置...',
    'config.configuration_title': '配置',
    'config.sensitive_title': '敏感字段已隐藏',
    'config.sensitive_hint': 'API 密钥、令牌和密码已隐藏以保护安全。要更新已隐藏的字段，请将整个隐藏值替换为您的新值。',
    'config.save_success': '配置保存成功。',
    'config.save_error': '保存配置失败',
    'config.toml_label': 'TOML 配置',
    'config.lines': '行',
    'config.mode.form': '表单',
    'config.mode.advanced': '高级',
    'config.section.general': '常规',
    'config.section.agent': '智能体',
    'config.section.gateway': '网关',
    'config.section.cost': '成本',
    'config.section.memory': '记忆',
    'config.section.web_search': '网页搜索',
    'config.section.heartbeat': '心跳',
    'config.field.default_provider': '默认模型提供商',
    'config.field.default_provider.desc': 'LLM 提供商（如 openrouter、ollama、anthropic）',
    'config.field.default_model': '默认模型',
    'config.field.default_model.desc': '默认提供商的模型名称',
    'config.field.default_temperature': '温度',
    'config.field.default_temperature.desc': '控制随机性（0 = 确定性，2 = 最大创造力）',
    'config.field.provider_timeout_secs': '提供商超时（秒）',
    'config.field.provider_timeout_secs.desc': 'LLM API 调用的 HTTP 超时时间',
    'config.field.locale': '语言',
    'config.field.locale.desc': 'UI 语言设置',
    'config.field.compact_context': '紧凑上下文',
    'config.field.compact_context.desc': '为小模型（13B 或更小）减少上下文大小',
    'config.field.max_tool_iterations': '最大工具迭代次数',
    'config.field.max_tool_iterations.desc': '每条用户消息的最大工具调用循环次数',
    'config.field.max_history_messages': '最大历史消息数',
    'config.field.max_history_messages.desc': '每个会话的最大对话历史消息数',
    'config.field.max_context_tokens': '最大上下文令牌数',
    'config.field.max_context_tokens.desc': '超过时触发历史压缩',
    'config.field.parallel_tools': '并行工具',
    'config.field.parallel_tools.desc': '在单次轮中启用并行工具执行',
    'config.field.gateway_port': '端口',
    'config.field.gateway_port.desc': '网关服务器端口',
    'config.field.gateway_host': '主机',
    'config.field.gateway_host.desc': '网关绑定地址',
    'config.field.require_pairing': '需要配对',
    'config.field.require_pairing.desc': '接受请求前需要设备配对',
    'config.field.session_persistence': '会话持久化',
    'config.field.session_persistence.desc': '将 WebSocket 会话持久化到 SQLite',
    'config.field.session_ttl_hours': '会话 TTL（小时）',
    'config.field.session_ttl_hours.desc': '自动归档过期会话（0 = 禁用）',
    'config.field.allow_public_bind': '允许公网绑定',
    'config.field.allow_public_bind.desc': '允许在无隧道情况下绑定非本地地址',
    'config.field.daily_limit_usd': '每日限额（美元）',
    'config.field.daily_limit_usd.desc': '每日支出限额',
    'config.field.monthly_limit_usd': '每月限额（美元）',
    'config.field.monthly_limit_usd.desc': '每月支出限额',
    'config.field.warn_at_percent': '警告阈值（%）',
    'config.field.warn_at_percent.desc': '预算使用超过此百分比时发出警告',
    'config.field.allow_override': '允许覆盖',
    'config.field.allow_override.desc': '允许 --override 标志超出预算限制',
    'config.field.memory_enabled': '开启记忆',
    'config.field.memory_enabled.desc': '启用智能体记忆功能',
    'config.field.memory_backend': '后端',
    'config.field.memory_backend.desc': '智能体记忆的存储后端',
    'config.field.heartbeat_enabled': '开启心跳',
    'config.field.heartbeat_enabled.desc': '按计划触发心跳检查',
    'config.field.web_search_enabled': '开启网页搜索',
    'config.field.web_search_enabled.desc': '允许智能体使用网页搜索工具',
    'config.field.cost_enabled': '开启成本限制',
    'config.field.cost_enabled.desc': '启用预算与支出追踪',
    'config.field.web_search_provider': '搜索提供商',
    'config.field.web_search_provider.desc': '使用的网页搜索引擎',
    'config.field.max_results': '最大结果数',
    'config.field.max_results.desc': '每次搜索查询的结果数',
    'config.field.web_search_timeout': '超时（秒）',
    'config.field.web_search_timeout.desc': '搜索请求超时时间',
    'config.field.interval_minutes': '间隔（分钟）',
    'config.field.interval_minutes.desc': '心跳检查之间的分钟数',
    'config.field.two_phase': '两阶段',
    'config.field.two_phase.desc': '执行前询问 LLM 是否运行（节省成本）',
    'config.field.adaptive': '自适应',
    'config.field.adaptive.desc': '根据活动自动调整间隔',
    'config.field.min_interval_minutes': '最小间隔（分钟）',
    'config.field.min_interval_minutes.desc': '自适应模式启用时的最小间隔',
    'config.field.max_interval_minutes': '最大间隔（分钟）',
    'config.field.max_interval_minutes.desc': '自适应模式回退时的最大间隔',
    'config.field.heartbeat_message': '备用消息',
    'config.field.heartbeat_message.desc': 'HEARTBEAT.md 无条目时的备用任务文本',
    'config.field.heartbeat_target': '目标频道',
    'config.field.heartbeat_target.desc': '心跳输出的投递频道（如 telegram）',
    'config.field.task_timeout_secs': '任务超时（秒）',
    'config.field.task_timeout_secs.desc': '单次心跳智能体调用的最大秒数',
    'config.error.serialize_failed': '序列化配置失败',
    'config.error.invalid_toml_switch': 'TOML 无效 — 请先修正错误再切换到表单视图',
    'config.error.reload_failed': '重新加载配置失败',
    'config.error.initial_parse_failed': '无法解析配置文件，已显示空表单；请检查 TOML 或改用其他方式编辑。',

    // Cost
    'cost.title': '成本追踪',
    'cost.session': '会话成本',
    'cost.daily': '每日成本',
    'cost.monthly': '每月成本',
    'cost.total_tokens': '总 Tokens',
    'cost.request_count': '请求数',
    'cost.by_model': '按模型统计',
    'cost.model': '模型',
    'cost.tokens': 'Token',
    'cost.requests': '请求',
    'cost.usd': '成本（美元）',
    'cost.load_error': '加载成本数据失败',
    'cost.session_cost': '会话成本',
    'cost.daily_cost': '每日成本',
    'cost.monthly_cost': '每月成本',
    'cost.total_requests': '总请求数',
    'cost.token_statistics': 'Token 统计',
    'cost.avg_tokens_per_request': '平均 Token / 请求',
    'cost.cost_per_1k_tokens': '每 1K Token 成本',
    'cost.model_breakdown': '模型细分',
    'cost.no_model_data': '没有模型数据可用。',
    'cost.cost': '成本',
    'cost.share': '占比',

    // Logs
    'logs.title': '实时日志',
    'logs.live_logs': '实时日志',
    'logs.clear': '清除',
    'logs.pause': '暂停',
    'logs.resume': '继续',
    'logs.filter': '筛选日志...',
    'logs.filter_label': '筛选',
    'logs.empty': '暂无日志条目。',
    'logs.connected': '已连接',
    'logs.disconnected': '已断开',
    'logs.events': '事件',
    'logs.jump_to_bottom': '跳转到底部',
    'logs.paused_hint': '日志流已暂停。',
    'logs.waiting_hint': '等待事件...',

    // Doctor
    'doctor.title': '系统诊断',
    'doctor.diagnostics_title': '系统诊断',
    'doctor.run': '运行诊断',
    'doctor.run_diagnostics': '运行诊断',
    'doctor.running': '正在运行诊断...',
    'doctor.running_btn': '运行中...',
    'doctor.running_desc': '正在运行诊断...',
    'doctor.running_hint': '这可能需要几秒钟。',
    'doctor.ok': '正常',
    'doctor.warn': '警告',
    'doctor.error': '错误',
    'global.refresh': '刷新',
    'doctor.severity': '严重程度',
    'doctor.category': '类别',
    'doctor.message': '消息',
    'doctor.empty': '尚未运行诊断。',
    'doctor.summary': '诊断摘要',
    'doctor.issues_found': '发现问题',
    'doctor.warnings_summary': '警告',
    'doctor.all_clear': '一切正常',
    'doctor.system_diagnostics': '系统诊断',
    'doctor.empty_hint': '点击"运行诊断"检查您的 KylinBot 安装。',

    // Auth / Pairing
    'auth.pair': '配对设备',
    'auth.pairing_code': '配对码',
    'auth.pair_button': '配对',
    'auth.logout': '退出',
    'auth.pairing_success': '配对成功！',
    'auth.pairing_failed': '配对失败，请重试。',
    'auth.enter_code': '请输入配对码以连接到智能体。',

    // Common
    'common.loading': '加载中...',
    'common.error': '发生错误。',
    'common.retry': '重试',
    'common.cancel': '取消',
    'common.confirm': '确认',
    'common.save': '保存',
    'common.delete': '删除',
    'common.edit': '编辑',
    'common.close': '关闭',
    'common.yes': '是',
    'common.no': '否',
    'common.search': '搜索...',
    'common.no_data': '暂无数据。',
    'common.refresh': '刷新',
    'common.back': '返回',
    'common.actions': '操作',
    'common.name': '名称',
    'common.description': '描述',
    'common.status': '状态',
    'common.created': '创建时间',
    'common.updated': '更新时间',

    // Health
    'health.title': '系统健康',
    'health.component': '组件',
    'health.status': '状态',
    'health.last_ok': '上次正常',
    'health.last_error': '上次错误',
    'health.restart_count': '重启次数',
    'health.pid': '进程 ID',
    'health.uptime': '运行时间',
    'health.updated_at': '最后更新',

    // Dashboard specific labels
    'dashboard.provider_model': '提供商 / 模型',
    'dashboard.since_last_restart': '自上次重启',
    'dashboard.paired_yes': '是',
    'dashboard.paired_no': '否',
    'dashboard.cost_overview': '成本概览',
    'dashboard.active_channels': '活跃频道',
    'dashboard.filter_active': '活跃',
    'dashboard.filter_all': '全部',
    'dashboard.no_active_channels': '没有活跃频道',
    'dashboard.component_health': '组件健康',
    'dashboard.load_error': '加载仪表盘失败',
    'dashboard.session_label': '会话',
    'dashboard.daily_label': '每日',
    'dashboard.monthly_label': '每月',
    'dashboard.total_tokens_label': '总 Tokens',
    'dashboard.requests_label': '请求',
    'dashboard.no_channels': '未配置频道',
    'dashboard.active': '活跃',
    'dashboard.inactive': '非活跃',
    'dashboard.no_components': '没有组件报告',
    'dashboard.restarts': '重启次数',
    'dashboard.tab_overview': '概览',
    'dashboard.tab_sessions': '会话',
    'dashboard.tab_channels': '频道',
    'dashboard.sessions_title': '活跃会话',
    'dashboard.no_sessions': '没有活跃会话',
    'dashboard.session_id': '会话 ID',
    'dashboard.session_channel': '频道',
    'dashboard.session_started': '开始时间',
    'dashboard.session_last_activity': '最近活动',
    'dashboard.session_status': '状态',
    'dashboard.session_messages': '消息数',
    'dashboard.session_details': '会话详情',
    'dashboard.session_history': '查看历史',
    'dashboard.channels_title': '频道状态',
    'dashboard.no_channels_detail': '没有频道详情',
    'dashboard.channel_type': '类型',
    'dashboard.channel_messages': '消息数',
    'dashboard.channel_last_message': '最近消息',
    'dashboard.channel_config': '配置摘要',
    'dashboard.channel_enabled': '已启用',
    'dashboard.channel_disabled': '已禁用',
    'dashboard.loading_sessions': '加载会话中...',
    'dashboard.loading_channels': '加载频道中...',
    'dashboard.load_sessions_error': '加载会话失败',
    'dashboard.load_channels_error': '加载频道失败',
    'dashboard.never': '从未',
    'dashboard.agents_title': '智能体',
    'dashboard.agents_empty': '未配置委托智能体。',
    'dashboard.agent_general_purpose': '通用型',
    'dashboard.agent_not_running': '-',
    'dashboard.agentic': 'Agentic',
    'dashboard.single_turn': '单轮',
    'dashboard.depth': '深度',
    'dashboard.iterations': '轮',
    'dashboard.current_task': '当前任务',
    'dashboard.run_time': '运行时长',
    'dashboard.progress': '进度',
    'dashboard.last_active': '最近活动',
    'dashboard.capabilities': '能力',
    'dashboard.no_tool_allowlist': '未显式限制工具白名单',
    'dashboard.idle': '空闲',
    'dashboard.primary_agent_title': '主智能体',
    'dashboard.primary_agent_status': '运行中',
    'dashboard.primary_agent_style': '默认交互智能体，负责处理 Web 对话与工具调用。',
    'dashboard.primary_agent_kind': 'Web 对话',
    'dashboard.primary_agent_tooling': '工具已启用',
    'dashboard.primary_agent_task': '始终可用',
    'dashboard.primary_agent_progress': '就绪',
    'dashboard.primary_agent_last_active': '持续运行',
    'dashboard.delegate_agents_title': '子代理',

    // Settings
    'settings.title': '设置',
    'settings.theme_title': '主题设置',
    'settings.tab.appearance': '外观',
    'settings.tab.typography': '排版',
    'settings.dark_presets': '深色主题',
    'settings.light_presets': '浅色主题',
    'settings.appearance': '外观设置',
    'settings.typography': '字体设置',
    'settings.fontUi': '界面字体',
    'settings.fontMono': '代码字体',
    'settings.fontSize': '界面字号',
    'settings.fontMonoSize': '代码字号',
    'settings.preview': '预览',
    'settings.previewText': '界面字体预览文本',
    'settings.fontNote': '字体设置需要刷新页面后生效',
    'settings.language': '界面语言',
    'settings.window': '窗口',

    // Theme
    'theme.mode': '主题模式',
    'theme.accent': '强调色',
    'theme.system': '跟随系统',
    'theme.dark': '深色',
    'theme.light': '浅色',
    'theme.oled': '纯黑',

    // Channel
    'channel.title': '频道',
    'channel.configure': '配置',
    'channel.connected': '已连接',
    'channel.not_configured': '未配置',
    'channel.not_connected': '未连接',
    'channel.disconnecting': '断开中...',
    'channel.disconnect': '断开连接',
    'channel.wechat': '微信',
    'channel.wechat.desc': '扫码接入个人微信，在聊天中直接调用 KylinBot，随时处理日常任务与问题',
    'channel.wecom': '企业微信',
    'channel.wecom.desc': '关联企业微信账号，在群聊或私聊中快速调用 KylinBot，提升团队协作效率',
    'channel.dingtalk': '钉钉',
    'channel.dingtalk.desc': '接入钉钉机器人，在会话中直接下达任务指令，自动处理工作流程',
    'channel.feishu': '飞书',
    'channel.feishu.desc': '接入飞书机器人，在消息中调用 KylinBot，实现任务处理与流程协同',
    'channel.wechat.connected': '微信配置成功',
    'channel.wecom.connected': '企业微信配置成功',
    'channel.dingtalk.connected': '钉钉配置成功',
    'channel.feishu.connected': '飞书配置成功',
    'channel.wechat.disconnected': '微信已断开连接',
    'channel.wecom.disconnected': '企业微信已断开连接',
    'channel.dingtalk.disconnected': '钉钉已断开连接',
    'channel.feishu.disconnected': '飞书已断开连接',
    'channel.scan_connect': '扫码接入',
    'channel.websocket_connect': 'WebSocket 长链接',
    'channel.stream_connect': 'Stream 长链接',
    'channel.bind_success': '绑定成功',
    'channel.qr_expired': '二维码已过期，请刷新',
    'channel.refresh_qr': '刷新二维码',
    'channel.scanned_confirm': '已扫描，请在手机上确认...',
    'channel.bind_error': '出错了',
    'channel.connect': '连接',
    'channel.scan_tip': '请使用微信扫描下方二维码',
    'channel.confirm': '确定',
    'channel.retry': '重试',
    'channel.cancel': '取消',
    'channel.bot_id': 'Bot ID',
    'channel.wecom.bot_id_placeholder': '请输入Bot ID',
    'channel.wecom.secret_placeholder': '请输入Secret',
    'channel.wecom.fill_required': '请填写 Bot ID 和 Secret',
    'channel.dingtalk.client_id_placeholder': '请输入Client ID',
    'channel.dingtalk.client_secret_placeholder': '请输入Client Secret',
    'channel.dingtalk.fill_required': '请填写 Client ID 和 Client Secret',
    'channel.dingtalk.auth_failed': '授权失败',
    'channel.feishu.app_id_placeholder': '请输入App ID',
    'channel.feishu.app_secret_placeholder': '请输入App Secret',
    'channel.feishu.fill_required': '请填写 App ID 和 App Secret',
    'channel.feishu.access_denied': '用户拒绝了授权',
    'agent.approval_required': '需要审批',
    'agent.allow_once': '允许一次',
    'agent.always_this_session': '本次会话始终允许',
    'agent.deny': '拒绝',
    'agent.expires_at': '过期时间',

    // Identity
    'identity.setup': '设置身份',
    'identity.setup_desc': '设置你的AI助手',
    'identity.name_placeholder': '给你的AI助手起个名字',
    'identity.name_example': '例如：麒灵、小智、助手',
    'identity.role_label': '描述它的角色（可选）',
    'identity.role_example': '例如：专业的编程助手，擅长代码优化和Debug',

    // History
    'history.title': '历史对话',
    'history.task_title': '历史任务',
    'history.today': '今天',
    'history.last_7_days': '最近7天',
    'history.last_30_days': '最近30天',
    'history.last_year': '最近一年',
    'history.earlier': '更早',
    'history.empty': '暂无历史对话',
    'history.loading': '加载中...',

    // Chat
    'chat.attachment_too_large': '附件总体积过大，请控制在 40MB 内。',
    'chat.file_too_large': '文件 {name} 超过 15MB 限制。',
    'chat.read_attachment_failed': '读取附件失败，请重试。',
    'chat.remove_attachment': '移除附件 {name}',
    'chat.unnamed_session': '未命名会话',
    'chat.yesterday': '昨天',
    'chat.weekday.sun': '周日',
    'chat.weekday.mon': '周一',
    'chat.weekday.tue': '周二',
    'chat.weekday.wed': '周三',
    'chat.weekday.thu': '周四',
    'chat.weekday.fri': '周五',
    'chat.weekday.sat': '周六',
    'chat.date.month_day': '{m}月{d}日',
    'chat.date.year_month_day': '{y}年{m}月{d}日',

    // Model
    'model.edit_config': '编辑模型配置',
    'model.add_config': '新增模型配置',
    'model.cancel_edit': '取消编辑',
    'model.save_edit_sync': '保存编辑并同步配置',
    'model.add_write_remote': '添加并写入远端配置',
    'model.saving': '保存中...',
    'model.current_model': '当前配置模型',
    'model.view': '查看',
    'model.not_set': '未设置',
    'model.not_saved_locally': '未保存到本地',
    'model.provider_model_required': '请先填写 provider 和 model',
    'model.update_sync_success': '模型信息已更新并同步到本地/远端配置',
    'model.add_remote_success': '模型已写入远端配置并加入可切换列表',
    'model.save_failed': '保存失败',
    'model.deleted': '模型已从可切换列表删除',
    'model.model_placeholder': '例如 gpt-5.2 / qwen-plus / claude-sonnet-4-6',
    'model.qwen_api_key_required': 'Qwen 需要 API Key。请填写 Key（DASHSCOPE_API_KEY）后再保存。',
    'model.qwen_api_key_hint': 'Qwen 必填：DASHSCOPE_API_KEY',
    'model.qwen_oauth_hint': 'Qwen Code：QWEN_OAUTH_TOKEN（可选填）',
    'model.key_optional_hint': '可选（建议填写，避免 provider 启动失败）',
    'model.base_url_hint_qwen': '可选，如 https://dashscope.aliyuncs.com/compatible-mode/v1',
    'model.base_url_hint_openai': '可选，如 https://api.openai.com/v1',
    'model.custom_base_url_required': 'custom provider 需要填写 Base URL，例如 https://api.openai.com/v1',
    'model.provider_model_empty': 'provider 和 model 不能为空',
    'model.configured_model': '已配置模型',
    'model.trial_model': '试用模型',
    'model.qwen_plus': '通义千问 Plus',
    'model.qwen_qwq': '通义千问 QWQ-32B',
    'model.desc_general': '通用对话，平衡性能与成本',
    'model.desc_thinking': '思考模型，强推理能力',
    'model.desc_deep_reasoning': '深度推理模型',
    'model.desc_new_thinking': '新一代深度思考模型',

    // Provider presets
    'provider.category_recommended': '推荐（聚合与直连）',
    'provider.category_fast': '快速推理',
    'provider.category_gateway': '网关 / 云厂商',
    'provider.category_domestic': '国内与专项',
    'provider.category_local': '本地 / 自定义 OpenAI 兼容',
    'provider.openrouter_notes': '多模型路由，OpenAI兼容 Chat Completions',
    'provider.anthropic_notes': 'Messages API；需在配置中设置对应密钥',
    'provider.openai_notes': 'Chat Completions / Responses 视 wire_api',
    'provider.ollama_notes': '可配 api_url 指向本机或远程',
    'provider.custom_notes': '供应商 ID 形如 custom:https://host...',

    // SkillHub
    'skillhub.title': '技能商店',
    'skillhub.tab.hot': '🔥 下载热榜',
    'skillhub.tab.featured': '⭐ 为你推荐',
    'skillhub.tab.newest': '🆕 最近上新',
    'skillhub.tab.installed': '✅ 已安装',
    'skillhub.tab.installed_count': '✅ 已安装 ({count})',
    'skillhub.search.placeholder': '搜索技能...',
    'skillhub.search.results': '搜索结果：{query}',
    'skillhub.install': '安装',
    'skillhub.installing': '安装中...',
    'skillhub.installed': '已安装',
    'skillhub.uninstall': '卸载',
    'skillhub.author': '作者：{author}',
    'skillhub.empty.installed': '暂无已安装的技能',
    'skillhub.empty.skills': '暂无技能',
    'skillhub.retry': '重试',
    'skillhub.load_failed': '加载失败',
    'skillhub.scroll_more': '↓ 下滑加载更多',
    'skillhub.detail.source_clawhub': '源自 ClawHub',
    'skillhub.detail.source': '源自 {source}',
    'skillhub.detail.safe': '通过安全检测',
    'skillhub.detail.unsafe': '待检测',
    'skillhub.detail.downloads': '下载量',
    'skillhub.detail.stars': '收藏',
    'skillhub.detail.security_check': '安全检测',
    'skillhub.detail.lab_keen': '科恩实验室',
    'skillhub.detail.lab_sanbu': '云鼎实验室',
    'skillhub.detail.security_disclaimer': '安全检测结果由第三方机构出具，仅作参考，不构成平台对Skill绝对安全的承诺。网络安全具有动态性，请您自行做好安全防护和风险管控。',
    'skillhub.modal.install_title': '安装技能',
    'skillhub.modal.install_confirm': '从 SkillHub 安装 {name}？',
    'skillhub.modal.force_overwrite': '如已安装则强制覆盖',
    'skillhub.modal.cancel': '取消',
    'skillhub.modal.install_btn': '安装',
    'skillhub.modal.installing': '正在安装 {name}...',
    'skillhub.modal.success': '{name} 安装成功！',
    'skillhub.modal.error': '安装失败',
    'skillhub.modal.close': '关闭',
    'skillhub.modal.retry': '重试',
  },

  en: {
    // Navigation
    'nav.dashboard': 'Dashboard',
    'nav.agent': 'Agent',
    'nav.tools': 'Tools',
    'nav.cron': 'Scheduled Jobs',
    'nav.integrations': 'Integrations',
    'nav.modelswitch': 'Model Switch',
    'nav.skills': 'Skills',
    'nav.history': 'History',
    'nav.general': 'General',
    'nav.memory': 'Memory',
    'nav.config': 'Configuration',
    'nav.cost': 'Cost Tracker',
    'nav.logs': 'Logs',
    'nav.doctor': 'Doctor',
    'nav.canvas': 'Canvas',

    // Dashboard
    'dashboard.title': 'Dashboard',
    'dashboard.provider': 'Provider',
    'dashboard.model': 'Model',
    'dashboard.uptime': 'Uptime',
    'dashboard.temperature': 'Temperature',
    'dashboard.gateway_port': 'Gateway Port',
    'dashboard.memory_backend': 'Memory Backend',
    'dashboard.paired': 'Paired',
    'dashboard.channels': 'Channels',
    'dashboard.health': 'Health',
    'dashboard.status': 'Status',
    'dashboard.overview': 'Overview',
    'dashboard.system_info': 'System Information',
    'dashboard.quick_actions': 'Quick Actions',

    // Agent / Chat
    'agent.title': 'Agent Chat',
    'agent.send': 'Send',
    'agent.placeholder': 'Type a message...',
    'agent.start_conversation': 'Send a message to start the conversation',
    'agent.type_message': 'Type a message...',
    'agent.light_greeting_title': 'Hello, I am KylinBot!',
    'agent.light_greeting_subtitle': 'I can help with questions, writing, summaries, retrieval, and everyday task coordination.',
    'agent.light_try_label': 'You can try:',
    'agent.light_refresh_label': 'Refresh',
    'agent.light_card_recommended': 'Recommended prompts',
    'agent.light_card_knowledge': 'Knowledge base',
    'agent.light_card_knowledge_prompt': 'Summarize the key points from my knowledge base.',
    'agent.light_suggestion_one': 'How do I remove coffee stains from a white shirt?',
    'agent.light_suggestion_two': 'What are good icebreaker games for a team meetup?',
    'agent.light_suggestion_three': 'Draft a short follow-up email for a client.',
    'agent.light_suggestion_four': 'How can I summarize a long article into bullet points?',
    'agent.light_suggestion_five': 'How do I sum values conditionally in Excel?',
    'agent.light_suggestion_six': 'Write a short launch announcement for a product release.',
    'agent.light_suggestion_seven': 'How should a beginner start learning to program?',
    'agent.light_suggestion_eight': 'What should I pack for a three-day business trip?',
    'agent.light_suggestion_nine': 'Explain what an API is in simple terms.',
    'agent.light_type_message': 'Ask a question or type "/" to use skills',
    'agent.light_tool_model': 'Smart model routing',
    'agent.light_tool_expand': 'Deep reasoning',
    'agent.light_tool_search': 'Web search',
    'agent.model_selector_title': 'Select Model',
    'agent.model_selector_trial': 'Trial Models',
    'agent.model_selector_configured': 'Configured Models',
    'agent.model_selector_no_trial': 'No trial models available',
    'agent.model_selector_no_configured': 'No other models configured',
    'agent.connecting': 'Connecting...',
    'agent.connected': 'Connected',
    'agent.disconnected': 'Disconnected',
    'agent.reconnecting': 'Reconnecting...',
    'agent.thinking': 'Thinking...',
    'agent.tool_call': 'Tool Call',
    'agent.tool_result': 'Tool Result',
    'agent.connection_error': 'Connection error. Attempting to reconnect...',
    'agent.tool_call_prefix': '[Tool Call]',
    'agent.tool_result_prefix': '[Tool Result]',
    'agent.error_prefix': '[Error]',
    'agent.unknown_error': 'Unknown error',
    'agent.send_error': 'Failed to send message. Please try again.',
    'agent.copy_message': 'Copy message',
    'agent.show_json': 'Show JSON',
    'agent.hide_json': 'Hide JSON',
    'agent.toggle_system_messages': 'Toggle system messages',
    'agent.connected_status': 'Connected',
    'agent.disconnected_status': 'Disconnected',
    'agent.generating_block_tip': 'Generating answer, please try again after completion',
    'header.new_session': 'New Session',
    'header.window_pin': 'Pin on Top',
    'header.window_minimize': 'Minimize',
    'header.window_maximize': 'Maximize',
    'header.window_close': 'Close',

    // Tools
    'tools.title': 'Available Tools',
    'tools.name': 'Name',
    'tools.description': 'Description',
    'tools.parameters': 'Parameters',
    'tools.search': 'Search tools...',
    'tools.empty': 'No tools available.',
    'tools.count': 'Total tools',
    'tools.agent_tools': 'Agent Tools',
    'tools.cli_tools': 'CLI Tools',
    'tools.parameter_schema': 'Parameter Schema',
    'tools.path': 'Path',
    'tools.version': 'Version',
    'tools.category': 'Category',
    'tools.load_error': 'Failed to load tools',

    // Cron
    'cron.title': 'Scheduled Jobs',
    'cron.task_list': 'Task List',
    'cron.prompt_col': 'Prompt',
    'cron.status_success': 'Success',
    'cron.status_failed': 'Failed',
    'cron.scheduled_tasks': 'Scheduled Tasks',
    'cron.add': 'Add Job',
    'cron.add_job': 'Add Job',
    'cron.modal_add': 'Add',
    'cron.add_modal_title': 'Add Task',
    'cron.delete': 'Delete',
    'cron.enable': 'Enable',
    'cron.disable': 'Disable',
    'cron.name': 'Name',
    'cron.name_optional': 'Name (optional)',
    'cron.command': 'Command',
    'cron.command_required': 'Command',
    'cron.schedule': 'Schedule',
    'cron.schedule_required': 'Schedule',
    'cron.schedule_kind_cron': 'Cron expression',
    'cron.schedule_kind_at': 'Specific time',
    'cron.schedule_kind_every': 'Fixed interval',
    'cron.schedule_cron_placeholder': 'e.g. 0 0 * * *',
    'cron.schedule_tz_optional': 'Timezone (optional, e.g. UTC)',
    'cron.schedule_every_ms_placeholder': 'Interval in milliseconds (e.g. 60000)',
    'cron.next_run': 'Next Run',
    'cron.last_run': 'Last Run',
    'cron.last_status': 'Last Status',
    'cron.enabled': 'Enabled',
    'cron.enabled_status': 'Enabled',
    'cron.disabled_status': 'Disabled',
    'cron.empty': 'No scheduled jobs.',
    'cron.confirm_delete': 'Are you sure you want to delete this job?',
    'cron.load_error': 'Failed to load cron jobs',
    'cron.validation_error': 'Schedule and command are required.',
    'cron.add_error': 'Failed to add job',
    'cron.delete_error': 'Failed to delete job',
    'cron.cancel': 'Cancel',
    'cron.adding': 'Adding...',
    'cron.id': 'ID',
    'cron.actions': 'Actions',
    'cron.loading_run_history': 'Loading run history...',
    'cron.load_run_history_error': 'Failed to load run history',
    'cron.no_runs': 'No runs recorded yet.',
    'cron.recent_runs': 'Recent Runs',
    'cron.yes': 'Yes',
    'cron.no': 'No',
    'cron.edit': 'Edit',
    'cron.edit_modal_title': 'Edit Task',
    'cron.edit_error': 'Failed to update job',
    'cron.saving': 'Saving...',
    'cron.save': 'Save',
    'cron.confirm': 'Confirm',
    'cron.job_type': 'Job Type',
    'cron.job_type_shell': 'Shell',
    'cron.job_type_agent': 'Agent',
    'cron.session_target': 'Session Target',
    'cron.session_target_isolated': 'Isolated',
    'cron.session_target_main': 'Main',
    'cron.model_optional': 'Model (optional)',
    'cron.allowed_tools': 'Allowed Tools (comma-separated)',
    'cron.delivery_mode': 'Delivery Mode',
    'cron.delivery_mode_none': 'None',
    'cron.delivery_mode_announce': 'Announce',
    'cron.delivery_channel': 'Delivery Channel',
    'cron.delivery_target': 'Delivery Target',
    'cron.delivery_best_effort': 'Best effort delivery',
    'cron.enable_job': 'Enable job',
    'cron.delete_after_run': 'Delete after run',
    'cron.run_now': 'Run now',
    'cron.pause_job': 'Pause job',
    'cron.resume_job': 'Resume job',
    'cron.run_error': 'Failed to run job',
    'cron.toggle_error': 'Failed to toggle job status',
    'cron.catch_up_title': 'Catch up missed jobs on startup',
    'cron.catch_up_desc': 'Run overdue jobs after KylinBot restarts from downtime',
    'cron.name_placeholder': 'e.g. Daily cleanup',
    'cron.command_shell_placeholder': 'e.g. cleanup --older-than 7d',
    'cron.command_agent_placeholder': 'Prompt for Agent job execution',
    'cron.model_placeholder': 'e.g. gpt-4.1',
    'cron.allowed_tools_placeholder': 'file_read,web_search',
    'cron.toggle_run_history': 'Toggle run history',
    'cron.task_name': 'Task Name',
    'cron.task_prompt_label': 'Task Instruction',
    'cron.task_name_placeholder': 'Enter task name',
    'cron.task_prompt_placeholder': 'Enter task instruction. e.g. Recommend 5 practical English words every day',
    'cron.exec_time': 'Schedule',
    'cron.daily_time_step_up': 'Add one minute',
    'cron.daily_time_step_down': 'Subtract one minute',
    'cron.once_run_date': 'Run date',
    'cron.once_date_step_up': 'Next day',
    'cron.once_date_step_down': 'Previous day',
    'cron.schedule_daily_label': 'Daily',
    'cron.schedule_interval_label': 'Interval',
    'cron.schedule_once_label': 'Once',
    'cron.remote_channel': 'Remote Channel',
    'cron.exec_model': 'Execution Model',
    'cron.channel_main': 'Main Session',
    'cron.interval_every': 'Every',
    'cron.interval_row_label': 'Every interval',
    'cron.interval_step_up': 'Increase interval value',
    'cron.interval_step_down': 'Decrease interval value',
    'cron.interval_unit_minute': 'minutes',
    'cron.interval_unit_hour': 'hours',
    'cron.interval_unit_day': 'days',
    'cron.date_range': 'Date Range',
    'cron.date_range_start': 'Start date',
    'cron.date_range_end': 'End date',
    'cron.model_default': 'Default',
    'cron.weekday_1': 'Mon',
    'cron.weekday_2': 'Tue',
    'cron.weekday_3': 'Wed',
    'cron.weekday_4': 'Thu',
    'cron.weekday_5': 'Fri',
    'cron.weekday_6': 'Sat',
    'cron.weekday_7': 'Sun',

    // Integrations
    'integrations.title': 'Integrations',
    'integrations.available': 'Available',
    'integrations.active': 'Active',
    'integrations.coming_soon': 'Coming Soon',
    'integrations.category': 'Category',
    'integrations.status': 'Status',
    'integrations.search': 'Search integrations...',
    'integrations.empty': 'No integrations found.',
    'integrations.activate': 'Activate',
    'integrations.deactivate': 'Deactivate',
    'integrations.load_error': 'Failed to load integrations',
    'integrations.status_active': 'Active',
    'integrations.status_available': 'Available',
    'integrations.status_coming_soon': 'Coming Soon',

    // Model Switch
    'modelswitch.title': 'Model Switch',
    'modelswitch.all': 'All',
    'modelswitch.empty': 'No models found.',
    'modelswitch.status_active': 'Active',
    'modelswitch.status_available': 'Available',
    'modelswitch.status_coming_soon': 'Coming Soon',

    // Skills
    'skills.title': 'Skills',
    'skills.all': 'All',
    'skills.empty': 'No skills found.',
    'skills.enabled': 'Enabled',
    'skills.disabled': 'Disabled',
    'skills.status_active': 'Active',
    'skills.status_available': 'Available',
    'skills.status_coming_soon': 'Coming Soon',

    // Memory
    'memory.title': 'Memory Store',
    'memory.memory_title': 'Memory',
    'memory.search': 'Search memory...',
    'memory.search_placeholder': 'Search memory entries...',
    'memory.add': 'Store Memory',
    'memory.add_memory': 'Add Memory',
    'memory.add_modal_title': 'Add Memory',
    'memory.delete': 'Delete',
    'memory.key': 'Key',
    'memory.key_required': 'Key',
    'memory.content': 'Content',
    'memory.content_required': 'Content',
    'memory.category': 'Category',
    'memory.category_optional': 'Category (optional)',
    'memory.timestamp': 'Timestamp',
    'memory.session': 'Session',
    'memory.score': 'Score',
    'memory.empty': 'No memory entries found.',
    'memory.confirm_delete': 'Are you sure you want to delete this memory entry?',
    'memory.all_categories': 'All Categories',
    'memory.search_button': 'Search',
    'memory.load_error': 'Failed to load memory',
    'memory.saving': 'Saving...',
    'memory.validation_error': 'Key and content are required.',
    'memory.store_error': 'Failed to store memory',
    'memory.delete_error': 'Failed to delete memory',
    'memory.delete_confirm': 'Delete?',
    'memory.yes': 'Yes',
    'memory.no': 'No',
    'memory.cancel': 'Cancel',

    // Config
    'config.title': 'Configuration',
    'config.save': 'Save',
    'config.saving': 'Saving...',
    'config.reset': 'Reset',
    'config.saved': 'Configuration saved successfully.',
    'config.error': 'Failed to save configuration.',
    'config.loading': 'Loading configuration...',
    'config.editor_placeholder': 'TOML configuration...',
    'config.configuration_title': 'Configuration',
    'config.sensitive_title': 'Sensitive fields are masked',
    'config.sensitive_hint': 'API keys, tokens, and passwords are hidden for security. To update a masked field, replace the entire masked value with your new value.',
    'config.save_success': 'Configuration saved successfully.',
    'config.save_error': 'Failed to save configuration',
    'config.toml_label': 'TOML Configuration',
    'config.lines': 'lines',
    'config.mode.form': 'Form',
    'config.mode.advanced': 'Advanced',
    'config.section.general': 'General',
    'config.section.agent': 'Agent',
    'config.section.gateway': 'Gateway',
    'config.section.cost': 'Cost',
    'config.section.memory': 'Memory',
    'config.section.web_search': 'Web Search',
    'config.section.heartbeat': 'Heartbeat',
    'config.field.default_provider': 'Default Model Provider',
    'config.field.default_provider.desc': 'LLM provider to use (e.g. openrouter, ollama, anthropic)',
    'config.field.default_model': 'Default Model',
    'config.field.default_model.desc': 'Model name for the default provider',
    'config.field.default_temperature': 'Temperature',
    'config.field.default_temperature.desc': 'Controls randomness (0 = deterministic, 2 = max creativity)',
    'config.field.provider_timeout_secs': 'Provider Timeout (s)',
    'config.field.provider_timeout_secs.desc': 'HTTP timeout for LLM API calls in seconds',
    'config.field.locale': 'Locale',
    'config.field.locale.desc': 'UI language override',
    'config.field.compact_context': 'Compact Context',
    'config.field.compact_context.desc': 'Reduce context size for small models (13B or less)',
    'config.field.max_tool_iterations': 'Max Tool Iterations',
    'config.field.max_tool_iterations.desc': 'Max tool-call loop turns per user message',
    'config.field.max_history_messages': 'Max History Messages',
    'config.field.max_history_messages.desc': 'Max conversation history messages per session',
    'config.field.max_context_tokens': 'Max Context Tokens',
    'config.field.max_context_tokens.desc': 'Triggers history compaction when exceeded',
    'config.field.parallel_tools': 'Parallel Tools',
    'config.field.parallel_tools.desc': 'Enable parallel tool execution within a turn',
    'config.field.gateway_port': 'Port',
    'config.field.gateway_port.desc': 'Gateway server port',
    'config.field.gateway_host': 'Host',
    'config.field.gateway_host.desc': 'Gateway bind address',
    'config.field.require_pairing': 'Require Pairing',
    'config.field.require_pairing.desc': 'Require device pairing before accepting requests',
    'config.field.session_persistence': 'Session Persistence',
    'config.field.session_persistence.desc': 'Persist WebSocket sessions to SQLite',
    'config.field.session_ttl_hours': 'Session TTL (hours)',
    'config.field.session_ttl_hours.desc': 'Auto-archive stale sessions (0 = disabled)',
    'config.field.allow_public_bind': 'Allow Public Bind',
    'config.field.allow_public_bind.desc': 'Allow non-localhost binding without tunnel',
    'config.field.daily_limit_usd': 'Daily Limit (USD)',
    'config.field.daily_limit_usd.desc': 'Daily spending limit in US dollars',
    'config.field.monthly_limit_usd': 'Monthly Limit (USD)',
    'config.field.monthly_limit_usd.desc': 'Monthly spending limit in US dollars',
    'config.field.warn_at_percent': 'Warning Threshold (%)',
    'config.field.warn_at_percent.desc': 'Warn when budget usage exceeds this percentage',
    'config.field.allow_override': 'Allow Override',
    'config.field.allow_override.desc': 'Allow --override flag to exceed budget limits',
    'config.field.memory_enabled': 'Enable memory',
    'config.field.memory_enabled.desc': 'Turn agent memory storage on or off',
    'config.field.memory_backend': 'Backend',
    'config.field.memory_backend.desc': 'Storage backend for agent memory',
    'config.field.heartbeat_enabled': 'Enable heartbeat',
    'config.field.heartbeat_enabled.desc': 'Run scheduled heartbeat checks',
    'config.field.web_search_enabled': 'Enable web search',
    'config.field.web_search_enabled.desc': 'Allow the agent to use web search tools',
    'config.field.cost_enabled': 'Enable cost limits',
    'config.field.cost_enabled.desc': 'Track spending and enforce budget limits',
    'config.field.web_search_provider': 'Search Provider',
    'config.field.web_search_provider.desc': 'Web search engine to use',
    'config.field.max_results': 'Max Results',
    'config.field.max_results.desc': 'Number of results per search query',
    'config.field.web_search_timeout': 'Timeout (s)',
    'config.field.web_search_timeout.desc': 'Search request timeout',
    'config.field.interval_minutes': 'Interval (minutes)',
    'config.field.interval_minutes.desc': 'Minutes between heartbeat checks',
    'config.field.two_phase': 'Two-phase',
    'config.field.two_phase.desc': 'Ask the LLM whether to run before executing (saves cost)',
    'config.field.adaptive': 'Adaptive',
    'config.field.adaptive.desc': 'Automatically adjust interval based on activity',
    'config.field.min_interval_minutes': 'Min Interval (minutes)',
    'config.field.min_interval_minutes.desc': 'Minimum interval when adaptive mode is on',
    'config.field.max_interval_minutes': 'Max Interval (minutes)',
    'config.field.max_interval_minutes.desc': 'Maximum interval when adaptive mode backs off',
    'config.field.heartbeat_message': 'Fallback Message',
    'config.field.heartbeat_message.desc': 'Fallback task text when HEARTBEAT.md has no entries',
    'config.field.heartbeat_target': 'Target Channel',
    'config.field.heartbeat_target.desc': 'Delivery channel for heartbeat output (e.g. telegram)',
    'config.field.task_timeout_secs': 'Task Timeout (s)',
    'config.field.task_timeout_secs.desc': 'Max seconds for a single heartbeat agent invocation',
    'config.error.serialize_failed': 'Failed to serialize configuration',
    'config.error.invalid_toml_switch': 'Invalid TOML — fix errors before switching to form view',
    'config.error.reload_failed': 'Failed to reload configuration',
    'config.error.initial_parse_failed': 'Could not parse configuration; showing an empty form. Fix the TOML or edit it elsewhere.',

    // Cost
    'cost.title': 'Cost Tracker',
    'cost.session': 'Session Cost',
    'cost.daily': 'Daily Cost',
    'cost.monthly': 'Monthly Cost',
    'cost.total_tokens': 'Total Tokens',
    'cost.request_count': 'Requests',
    'cost.by_model': 'Cost by Model',
    'cost.model': 'Model',
    'cost.tokens': 'Tokens',
    'cost.requests': 'Requests',
    'cost.usd': 'Cost (USD)',
    'cost.load_error': 'Failed to load cost data',
    'cost.session_cost': 'Session Cost',
    'cost.daily_cost': 'Daily Cost',
    'cost.monthly_cost': 'Monthly Cost',
    'cost.total_requests': 'Total Requests',
    'cost.token_statistics': 'Token Statistics',
    'cost.avg_tokens_per_request': 'Avg Tokens / Request',
    'cost.cost_per_1k_tokens': 'Cost per 1K Tokens',
    'cost.model_breakdown': 'Model Breakdown',
    'cost.no_model_data': 'No model data available.',
    'cost.cost': 'Cost',
    'cost.share': 'Share',

    // Logs
    'logs.title': 'Live Logs',
    'logs.live_logs': 'Live Logs',
    'logs.clear': 'Clear',
    'logs.pause': 'Pause',
    'logs.resume': 'Resume',
    'logs.filter': 'Filter logs...',
    'logs.filter_label': 'Filter',
    'logs.empty': 'No log entries.',
    'logs.connected': 'Connected',
    'logs.disconnected': 'Disconnected',
    'logs.events': 'events',
    'logs.jump_to_bottom': 'Jump to bottom',
    'logs.paused_hint': 'Log streaming is paused.',
    'logs.waiting_hint': 'Waiting for events...',

    // Doctor
    'doctor.title': 'System Diagnostics',
    'doctor.diagnostics_title': 'Diagnostics',
    'doctor.run': 'Run Diagnostics',
    'doctor.run_diagnostics': 'Run Diagnostics',
    'doctor.running': 'Running diagnostics...',
    'doctor.running_btn': 'Running...',
    'doctor.running_desc': 'Running diagnostics...',
    'doctor.running_hint': 'This may take a few seconds.',
    'doctor.ok': 'OK',
    'doctor.warn': 'Warning',
    'doctor.error': 'Error',
    'global.refresh': 'Refresh',
    'doctor.severity': 'Severity',
    'doctor.category': 'Category',
    'doctor.message': 'Message',
    'doctor.empty': 'No diagnostics have been run yet.',
    'doctor.summary': 'Diagnostic Summary',
    'doctor.issues_found': 'Issues Found',
    'doctor.warnings_summary': 'Warnings',
    'doctor.all_clear': 'All Clear',
    'doctor.system_diagnostics': 'System Diagnostics',
    'doctor.empty_hint': 'Click "Run Diagnostics" to check your KylinBot installation.',

    // Auth / Pairing
    'auth.pair': 'Pair Device',
    'auth.pairing_code': 'Pairing Code',
    'auth.pair_button': 'Pair',
    'auth.logout': 'Logout',
    'auth.pairing_success': 'Pairing successful!',
    'auth.pairing_failed': 'Pairing failed. Please try again.',
    'auth.enter_code': 'Enter your pairing code to connect to the agent.',

    // Common
    'common.loading': 'Loading...',
    'common.error': 'An error occurred.',
    'common.retry': 'Retry',
    'common.cancel': 'Cancel',
    'common.confirm': 'Confirm',
    'common.save': 'Save',
    'common.delete': 'Delete',
    'common.edit': 'Edit',
    'common.close': 'Close',
    'common.yes': 'Yes',
    'common.no': 'No',
    'common.search': 'Search...',
    'common.no_data': 'No data available.',
    'common.refresh': 'Refresh',
    'common.back': 'Back',
    'common.actions': 'Actions',
    'common.name': 'Name',
    'common.description': 'Description',
    'common.status': 'Status',
    'common.created': 'Created',
    'common.updated': 'Updated',

    // Health
    'health.title': 'System Health',
    'health.component': 'Component',
    'health.status': 'Status',
    'health.last_ok': 'Last OK',
    'health.last_error': 'Last Error',
    'health.restart_count': 'Restarts',
    'health.pid': 'Process ID',
    'health.uptime': 'Uptime',
    'health.updated_at': 'Last Updated',

    // Dashboard specific labels
    'dashboard.provider_model': 'Provider / Model',
    'dashboard.since_last_restart': 'Since last restart',
    'dashboard.paired_yes': 'Yes',
    'dashboard.paired_no': 'No',
    'dashboard.cost_overview': 'Cost Overview',
    'dashboard.active_channels': 'Active Channels',
    'dashboard.filter_active': 'Active',
    'dashboard.filter_all': 'All',
    'dashboard.no_active_channels': 'No active channels',
    'dashboard.component_health': 'Component Health',
    'dashboard.load_error': 'Failed to load dashboard',
    'dashboard.session_label': 'Session',
    'dashboard.daily_label': 'Daily',
    'dashboard.monthly_label': 'Monthly',
    'dashboard.total_tokens_label': 'Total Tokens',
    'dashboard.requests_label': 'Requests',
    'dashboard.no_channels': 'No channels configured',
    'dashboard.active': 'Active',
    'dashboard.inactive': 'Inactive',
    'dashboard.no_components': 'No components reporting',
    'dashboard.restarts': 'Restarts',
    'dashboard.tab_overview': 'Overview',
    'dashboard.tab_sessions': 'Sessions',
    'dashboard.tab_channels': 'Channels',
    'dashboard.sessions_title': 'Active Sessions',
    'dashboard.no_sessions': 'No active sessions',
    'dashboard.session_id': 'Session ID',
    'dashboard.session_channel': 'Channel',
    'dashboard.session_started': 'Started',
    'dashboard.session_last_activity': 'Last Activity',
    'dashboard.session_status': 'Status',
    'dashboard.session_messages': 'Messages',
    'dashboard.session_details': 'Session Details',
    'dashboard.session_history': 'View History',
    'dashboard.channels_title': 'Channel Status',
    'dashboard.no_channels_detail': 'No channel details available',
    'dashboard.channel_type': 'Type',
    'dashboard.channel_messages': 'Messages',
    'dashboard.channel_last_message': 'Last Message',
    'dashboard.channel_config': 'Configuration',
    'dashboard.channel_enabled': 'Enabled',
    'dashboard.channel_disabled': 'Disabled',
    'dashboard.loading_sessions': 'Loading sessions...',
    'dashboard.loading_channels': 'Loading channels...',
    'dashboard.load_sessions_error': 'Failed to load sessions',
    'dashboard.load_channels_error': 'Failed to load channels',
    'dashboard.never': 'Never',
    'dashboard.agents_title': 'Agents',
    'dashboard.agents_empty': 'No delegate agents configured.',
    'dashboard.agent_general_purpose': 'General purpose',
    'dashboard.agent_not_running': '-',
    'dashboard.agentic': 'Agentic',
    'dashboard.single_turn': 'Single turn',
    'dashboard.depth': 'depth',
    'dashboard.iterations': 'iters',
    'dashboard.current_task': 'Current task',
    'dashboard.run_time': 'Run time',
    'dashboard.progress': 'Progress',
    'dashboard.last_active': 'Last active',
    'dashboard.capabilities': 'Capabilities',
    'dashboard.no_tool_allowlist': 'No explicit tool allowlist',
    'dashboard.idle': 'Idle',
    'dashboard.primary_agent_title': 'Primary Agent',
    'dashboard.primary_agent_status': 'Running',
    'dashboard.primary_agent_style': 'Default interactive agent for web chat and tool-enabled turns.',
    'dashboard.primary_agent_kind': 'Web chat',
    'dashboard.primary_agent_tooling': 'Tool-enabled',
    'dashboard.primary_agent_task': 'Always available',
    'dashboard.primary_agent_progress': 'Ready',
    'dashboard.primary_agent_last_active': 'Always on',
    'dashboard.delegate_agents_title': 'Delegate Agents',

    // Settings
    'settings.title': 'Settings',
    'settings.theme_title': 'Theme Settings',
    'settings.tab.appearance': 'Appearance',
    'settings.tab.typography': 'Typography',
    'settings.dark_presets': 'Dark Themes',
    'settings.light_presets': 'Light Themes',
    'settings.appearance': 'Appearance',
    'settings.typography': 'Typography',
    'settings.fontUi': 'UI Font',
    'settings.fontMono': 'Code Font',
    'settings.fontSize': 'UI Font Size',
    'settings.fontMonoSize': 'Code Font Size',
    'settings.preview': 'Preview',
    'settings.previewText': 'The quick brown fox jumps over the lazy dog.',
    'settings.fontNote': 'Font changes apply on page reload.',
    'settings.language': 'Language',
    'settings.window': 'Window',

    // Theme
    'theme.mode': 'Theme Mode',
    'theme.accent': 'Accent Color',
    'theme.system': 'System',
    'theme.dark': 'Dark',
    'theme.light': 'Light',
    'theme.oled': 'OLED Black',

    // Channel
    'channel.title': 'Channels',
    'channel.configure': 'Configure',
    'channel.connected': 'Connected',
    'channel.not_configured': 'Not Configured',
    'channel.not_connected': 'Not Connected',
    'channel.disconnecting': 'Disconnecting...',
    'channel.disconnect': 'Disconnect',
    'channel.wechat': 'WeChat',
    'channel.wechat.desc': 'Connect your WeChat to invoke KylinBot directly in chats for daily tasks',
    'channel.wecom': 'WeCom',
    'channel.wecom.desc': 'Link your WeCom account to invoke KylinBot in group or private chats for team collaboration',
    'channel.dingtalk': 'DingTalk',
    'channel.dingtalk.desc': 'Connect a DingTalk bot to issue task commands and automate workflows in conversations',
    'channel.feishu': 'Feishu',
    'channel.feishu.desc': 'Connect a Feishu bot to invoke KylinBot in messages for task processing and workflow coordination',
    'channel.wechat.connected': 'WeChat configured successfully',
    'channel.wecom.connected': 'WeCom configured successfully',
    'channel.dingtalk.connected': 'DingTalk configured successfully',
    'channel.feishu.connected': 'Feishu configured successfully',
    'channel.wechat.disconnected': 'WeChat disconnected',
    'channel.wecom.disconnected': 'WeCom disconnected',
    'channel.dingtalk.disconnected': 'DingTalk disconnected',
    'channel.feishu.disconnected': 'Feishu disconnected',
    'channel.scan_connect': 'Scan to Connect',
    'channel.websocket_connect': 'WebSocket Connection',
    'channel.stream_connect': 'Stream Connection',
    'channel.bind_success': 'Bound successfully',
    'channel.qr_expired': 'QR code expired, please refresh',
    'channel.refresh_qr': 'Refresh QR Code',
    'channel.scanned_confirm': 'Scanned, please confirm on your phone...',
    'channel.bind_error': 'An error occurred',
    'channel.connect': 'Connect',
    'channel.scan_tip': 'Please scan the QR code below with WeChat',
    'channel.confirm': 'OK',
    'channel.retry': 'Retry',
    'channel.cancel': 'Cancel',
    'channel.bot_id': 'Bot ID',
    'channel.wecom.bot_id_placeholder': 'Enter Bot ID',
    'channel.wecom.secret_placeholder': 'Enter Secret',
    'channel.wecom.fill_required': 'Please fill in Bot ID and Secret',
    'channel.dingtalk.client_id_placeholder': 'Enter Client ID',
    'channel.dingtalk.client_secret_placeholder': 'Enter Client Secret',
    'channel.dingtalk.fill_required': 'Please fill in Client ID and Client Secret',
    'channel.dingtalk.auth_failed': 'Authorization failed',
    'channel.feishu.app_id_placeholder': 'Enter App ID',
    'channel.feishu.app_secret_placeholder': 'Enter App Secret',
    'channel.feishu.fill_required': 'Please fill in App ID and App Secret',
    'channel.feishu.access_denied': 'User denied authorization',
    'agent.approval_required': 'Approval Required',
    'agent.allow_once': 'Allow Once',
    'agent.always_this_session': 'Always This Session',
    'agent.deny': 'Deny',
    'agent.expires_at': 'Expires at',

    // Identity
    'identity.setup': 'Set Identity',
    'identity.setup_desc': 'Set up your AI assistant',
    'identity.name_placeholder': 'Give your AI assistant a name',
    'identity.name_example': 'e.g. Kylin, Xiao Zhi, Assistant',
    'identity.role_label': 'Describe its role (optional)',
    'identity.role_example': 'e.g. A professional coding assistant skilled in code optimization and debugging',

    // History
    'history.title': 'Chat History',
    'history.task_title': 'Task History',
    'history.today': 'Today',
    'history.last_7_days': 'Last 7 Days',
    'history.last_30_days': 'Last 30 Days',
    'history.last_year': 'Last Year',
    'history.earlier': 'Earlier',
    'history.empty': 'No chat history yet',
    'history.loading': 'Loading...',

    // Chat
    'chat.attachment_too_large': 'Total attachment size too large, please keep within 40MB.',
    'chat.file_too_large': 'File {name} exceeds the 15MB limit.',
    'chat.read_attachment_failed': 'Failed to read attachment, please retry.',
    'chat.remove_attachment': 'Remove attachment {name}',
    'chat.unnamed_session': 'Unnamed Session',
    'chat.yesterday': 'Yesterday',
    'chat.weekday.sun': 'Sun',
    'chat.weekday.mon': 'Mon',
    'chat.weekday.tue': 'Tue',
    'chat.weekday.wed': 'Wed',
    'chat.weekday.thu': 'Thu',
    'chat.weekday.fri': 'Fri',
    'chat.weekday.sat': 'Sat',
    'chat.date.month_day': '{m}/{d}',
    'chat.date.year_month_day': '{y}/{m}/{d}',

    // Model
    'model.edit_config': 'Edit Model Config',
    'model.add_config': 'Add Model Config',
    'model.cancel_edit': 'Cancel Edit',
    'model.save_edit_sync': 'Save Edit & Sync Config',
    'model.add_write_remote': 'Add & Write to Remote Config',
    'model.saving': 'Saving...',
    'model.current_model': 'Current Model',
    'model.view': 'View',
    'model.not_set': 'Not Set',
    'model.not_saved_locally': 'Not Saved Locally',
    'model.provider_model_required': 'Please fill in provider and model first',
    'model.update_sync_success': 'Model info updated and synced to local/remote config',
    'model.add_remote_success': 'Model written to remote config and added to switchable list',
    'model.save_failed': 'Save failed',
    'model.deleted': 'Model removed from switchable list',
    'model.model_placeholder': 'e.g. gpt-5.2 / qwen-plus / claude-sonnet-4-6',
    'model.qwen_api_key_required': 'Qwen requires an API Key. Please fill in DASHSCOPE_API_KEY before saving.',
    'model.qwen_api_key_hint': 'Qwen required: DASHSCOPE_API_KEY',
    'model.qwen_oauth_hint': 'Qwen Code: QWEN_OAUTH_TOKEN (optional)',
    'model.key_optional_hint': 'Optional (recommended to avoid provider startup failure)',
    'model.base_url_hint_qwen': 'Optional, e.g. https://dashscope.aliyuncs.com/compatible-mode/v1',
    'model.base_url_hint_openai': 'Optional, e.g. https://api.openai.com/v1',
    'model.custom_base_url_required': 'Custom provider requires a Base URL, e.g. https://api.openai.com/v1',
    'model.provider_model_empty': 'Provider and model cannot be empty',
    'model.configured_model': 'Configured Model',
    'model.trial_model': 'Trial Model',
    'model.qwen_plus': 'Qwen Plus',
    'model.qwen_qwq': 'Qwen QWQ-32B',
    'model.desc_general': 'General conversation, balanced performance and cost',
    'model.desc_thinking': 'Thinking model, strong reasoning capability',
    'model.desc_deep_reasoning': 'Deep reasoning model',
    'model.desc_new_thinking': 'Next-gen deep thinking model',

    // Provider presets
    'provider.category_recommended': 'Recommended (Aggregation & Direct)',
    'provider.category_fast': 'Fast Inference',
    'provider.category_gateway': 'Gateway / Cloud Providers',
    'provider.category_domestic': 'Domestic & Specialized',
    'provider.category_local': 'Local / Custom OpenAI-Compatible',
    'provider.openrouter_notes': 'Multi-model routing, OpenAI-compatible Chat Completions',
    'provider.anthropic_notes': 'Messages API; requires setting the corresponding key in config',
    'provider.openai_notes': 'Chat Completions / Responses per wire_api',
    'provider.ollama_notes': 'Configurable api_url pointing to local or remote',
    'provider.custom_notes': 'Provider ID like custom:https://host...',

    // SkillHub
    'skillhub.title': 'SkillHub',
    'skillhub.tab.hot': '🔥 Trending',
    'skillhub.tab.featured': '⭐ Featured',
    'skillhub.tab.newest': '🆕 Newest',
    'skillhub.tab.installed': '✅ Installed',
    'skillhub.tab.installed_count': '✅ Installed ({count})',
    'skillhub.search.placeholder': 'Search skills...',
    'skillhub.search.results': 'Search results for "{query}"',
    'skillhub.install': 'Install',
    'skillhub.installing': 'Installing...',
    'skillhub.installed': 'Installed',
    'skillhub.uninstall': 'Uninstall',
    'skillhub.author': 'Author: {author}',
    'skillhub.empty.installed': 'No installed skills',
    'skillhub.empty.skills': 'No skills available',
    'skillhub.retry': 'Retry',
    'skillhub.load_failed': 'Failed to load',
    'skillhub.scroll_more': '↓ Scroll for more',
    'skillhub.detail.source_clawhub': 'From ClawHub',
    'skillhub.detail.source': 'From {source}',
    'skillhub.detail.safe': 'Passed security check',
    'skillhub.detail.unsafe': 'Pending check',
    'skillhub.detail.downloads': 'Downloads',
    'skillhub.detail.stars': 'Stars',
    'skillhub.detail.security_check': 'Security Check',
    'skillhub.detail.lab_keen': 'Keen Lab',
    'skillhub.detail.lab_sanbu': 'Sanbu Lab',
    'skillhub.detail.security_disclaimer': 'Security check results are provided by third-party organizations and are for reference only. They do not constitute a guarantee of absolute safety. Cybersecurity is dynamic — please take proper security measures and risk management.',
    'skillhub.modal.install_title': 'Install Skill',
    'skillhub.modal.install_confirm': 'Install {name} from SkillHub?',
    'skillhub.modal.force_overwrite': 'Force overwrite if already installed',
    'skillhub.modal.cancel': 'Cancel',
    'skillhub.modal.install_btn': 'Install',
    'skillhub.modal.installing': 'Installing {name}...',
    'skillhub.modal.success': '{name} installed successfully!',
    'skillhub.modal.error': 'Installation failed',
    'skillhub.modal.close': 'Close',
    'skillhub.modal.retry': 'Retry',
  },

  tr: {
    // Navigation
    'nav.dashboard': 'Kontrol Paneli',
    'nav.agent': 'Ajan',
    'nav.tools': 'Araçlar',
    'nav.cron': 'Zamanlanmış Görevler',
    'nav.integrations': 'Entegrasyonlar',
    'nav.modelswitch': 'Model Değiştirme',
    'nav.skills': 'Beceriler',
    'nav.history': 'Geçmiş',
    'nav.memory': 'Hafıza',
    'nav.config': 'Yapılandırma',
    'nav.cost': 'Maliyet Takibi',
    'nav.logs': 'Kayıtlar',
    'nav.doctor': 'Doktor',
    'nav.canvas': 'Tuval',

    // Dashboard
    'dashboard.title': 'Kontrol Paneli',
    'dashboard.provider': 'Sağlayıcı',
    'dashboard.model': 'Model',
    'dashboard.uptime': 'Çalışma Süresi',
    'dashboard.temperature': 'Sıcaklık',
    'dashboard.gateway_port': 'Ağ Geçidi Portu',
    'dashboard.locale': 'Dil',
    'dashboard.memory_backend': 'Hafıza Motoru',
    'dashboard.paired': 'Eşleştirilmiş',
    'dashboard.channels': 'Kanallar',
    'dashboard.health': 'Sağlık',
    'dashboard.status': 'Durum',
    'dashboard.overview': 'Genel Bakış',
    'dashboard.system_info': 'Sistem Bilgisi',
    'dashboard.quick_actions': 'Hızlı İşlemler',
    'dashboard.provider_model': 'Sağlayıcı / Model',
    'dashboard.since_last_restart': 'Son Yeniden Başlatmadan Beri',
    'dashboard.paired_yes': 'Evet',
    'dashboard.paired_no': 'Hayır',
    'dashboard.cost_overview': 'Maliyet Genel Bakışı',
    'dashboard.active_channels': 'Aktif Kanallar',
    'dashboard.filter_active': 'Aktif',
    'dashboard.filter_all': 'Tümü',
    'dashboard.no_active_channels': 'Aktif kanal yok',
    'dashboard.component_health': 'Bileşen Sağlığı',
    'dashboard.load_error': 'Kontrol paneli yüklenemedi',
    'dashboard.session_label': 'Oturum',
    'dashboard.daily_label': 'Günlük',
    'dashboard.monthly_label': 'Aylık',
    'dashboard.total_tokens_label': 'Toplam Token',
    'dashboard.requests_label': 'İstekler',
    'dashboard.no_channels': 'Kanal yapılandırılmamış',
    'dashboard.active': 'Aktif',
    'dashboard.inactive': 'Aktif Değil',
    'dashboard.no_components': 'Bileşen raporlamıyor',
    'dashboard.restarts': 'Yeniden Başlatmalar',
    'dashboard.tab_overview': 'Genel Bakış',
    'dashboard.tab_sessions': 'Oturumlar',
    'dashboard.tab_channels': 'Kanallar',
    'dashboard.sessions_title': 'Aktif Oturumlar',
    'dashboard.no_sessions': 'Aktif oturum yok',
    'dashboard.session_id': 'Oturum Kimliği',
    'dashboard.session_channel': 'Kanal',
    'dashboard.session_started': 'Başlangıç',
    'dashboard.session_last_activity': 'Son Etkinlik',
    'dashboard.session_status': 'Durum',
    'dashboard.session_messages': 'Mesajlar',
    'dashboard.session_details': 'Oturum Ayrıntıları',
    'dashboard.session_history': 'Geçmişi Görüntüle',
    'dashboard.channels_title': 'Kanal Durumu',
    'dashboard.no_channels_detail': 'Kanal ayrıntısı yok',
    'dashboard.channel_type': 'Tür',
    'dashboard.channel_messages': 'Mesajlar',
    'dashboard.channel_last_message': 'Son Mesaj',
    'dashboard.channel_config': 'Yapılandırma',
    'dashboard.channel_enabled': 'Etkin',
    'dashboard.channel_disabled': 'Devre Dışı',
    'dashboard.loading_sessions': 'Oturumlar yükleniyor...',
    'dashboard.loading_channels': 'Kanallar yükleniyor...',
    'dashboard.load_sessions_error': 'Oturumlar yüklenemedi',
    'dashboard.load_channels_error': 'Kanallar yüklenemedi',
    'dashboard.never': 'Hiç',
    'dashboard.agents_title': 'Ajanlar',
    'dashboard.agents_empty': 'Yapılandırılmış temsilci ajan yok.',
    'dashboard.agent_general_purpose': 'Genel amaçlı',
    'dashboard.agent_not_running': '-',
    'dashboard.agentic': 'Ajanik',
    'dashboard.single_turn': 'Tek tur',
    'dashboard.depth': 'derinlik',
    'dashboard.iterations': 'tur',
    'dashboard.current_task': 'Geçerli görev',
    'dashboard.run_time': 'Çalışma süresi',
    'dashboard.progress': 'İlerleme',
    'dashboard.last_active': 'Son etkinlik',
    'dashboard.capabilities': 'Yetenekler',
    'dashboard.no_tool_allowlist': 'Açık araç izin listesi yok',
    'dashboard.idle': 'Boşta',
    'dashboard.primary_agent_title': 'Birincil Ajan',
    'dashboard.primary_agent_status': 'Çalışıyor',
    'dashboard.primary_agent_style': 'Web sohbeti ve araç kullanımlı dönüşler için varsayılan etkileşimli ajan.',
    'dashboard.primary_agent_kind': 'Web sohbeti',
    'dashboard.primary_agent_tooling': 'Araç etkin',
    'dashboard.primary_agent_task': 'Her zaman hazır',
    'dashboard.primary_agent_progress': 'Hazır',
    'dashboard.primary_agent_last_active': 'Sürekli çalışıyor',
    'dashboard.delegate_agents_title': 'Alt Ajanlar',

    // Agent / Chat
    'agent.title': 'Ajan Sohbeti',
    'agent.send': 'Gönder',
    'agent.placeholder': 'Bir mesaj yazın...',
    'agent.start_conversation': 'Sohbeti başlatmak için mesaj gönderin',
    'agent.type_message': 'Bir mesaj yazın...',
    'agent.light_greeting_title': 'Merhaba, ben KylinBot!',
    'agent.light_greeting_subtitle': 'Sorular, yazma, özetleme, bilgi erişimi ve günlük görevlerde yardımcı olabilirim.',
    'agent.light_try_label': 'Şunları deneyebilirsiniz:',
    'agent.light_refresh_label': 'Değiştir',
    'agent.light_card_recommended': 'Önerilen istemler',
    'agent.light_card_knowledge': 'Bilgi tabanı',
    'agent.light_card_knowledge_prompt': 'Bilgi tabanımdaki temel noktaları özetle.',
    'agent.light_suggestion_one': 'Beyaz bir gömlekten kahve lekesi nasıl çıkarılır?',
    'agent.light_suggestion_two': 'Takım buluşması için iyi buz kırıcı oyunlar nelerdir?',
    'agent.light_suggestion_three': 'Bir müşteri için kısa bir takip e-postası yaz.',
    'agent.light_suggestion_four': 'Uzun bir makaleyi madde madde nasıl özetlerim?',
    'agent.light_suggestion_five': "Excel'de koşullu toplam nasıl alınır?",
    'agent.light_suggestion_six': 'Kısa bir ürün lansmanı duyuru metni yaz.',
    'agent.light_suggestion_seven': 'Programlamaya yeni başlayan biri nereden başlamalı?',
    'agent.light_suggestion_eight': 'Üç günlük iş seyahati için neleri paketlemeliyim?',
    'agent.light_suggestion_nine': 'API nedir, basit bir dille açıkla.',
    'agent.light_type_message': 'Bir soru sorun veya becerileri kullanmak için "/" yazın',
    'agent.light_tool_model': 'Akıllı model yönlendirme',
    'agent.light_tool_expand': 'Derin düşünme',
    'agent.light_tool_search': 'Web arama',
    'agent.model_selector_title': 'Model Seç',
    'agent.model_selector_trial': 'Deneme Modelleri',
    'agent.model_selector_configured': 'Yapılandırılmış Modeller',
    'agent.model_selector_no_trial': 'Kullanılabilir deneme modeli yok',
    'agent.model_selector_no_configured': 'Başka model yapılandırılmamış',
    'agent.connecting': 'Bağlanıyor...',
    'agent.connected': 'Bağlandı',
    'agent.disconnected': 'Bağlantı kesildi',
    'agent.reconnecting': 'Yeniden bağlanıyor...',
    'agent.thinking': 'Düşünüyor...',
    'agent.tool_call': 'Araç Çağrısı',
    'agent.tool_result': 'Araç Sonucu',
    'agent.connection_error': 'Bağlantı hatası. Yeniden bağlanmaya çalışılıyor...',
    'agent.tool_call_prefix': '[Araç Çağrısı]',
    'agent.tool_result_prefix': '[Araç Sonucu]',
    'agent.error_prefix': '[Hata]',
    'agent.unknown_error': 'Bilinmeyen hata',
    'agent.send_error': 'Mesaj gönderilemedi. Lütfen tekrar deneyin.',
    'agent.copy_message': 'Mesajı kopyala',
    'agent.show_json': 'JSON Goster',
    'agent.hide_json': 'JSON Gizle',
    'agent.toggle_system_messages': 'Sistem mesajlarini goster/gizle',
    'agent.connected_status': 'Bağlandı',
    'agent.disconnected_status': 'Bağlantı kesildi',
    'agent.generating_block_tip': 'Yanıt oluşturuluyor, lütfen tamamlandıktan sonra tekrar deneyin',
    'header.new_session': 'Yeni Oturum',
    'header.window_pin': 'Üste Sabitle',
    'header.window_minimize': 'Simge Durumuna Küçült',
    'header.window_maximize': 'Büyüt',
    'header.window_close': 'Kapat',

    // Tools
    'tools.title': 'Mevcut Araçlar',
    'tools.name': 'Ad',
    'tools.description': 'Açıklama',
    'tools.parameters': 'Parametreler',
    'tools.search': 'Araç ara...',
    'tools.empty': 'Araç bulunamadı.',
    'tools.count': 'Toplam araç',
    'tools.agent_tools': 'Ajan Araçları',
    'tools.cli_tools': 'CLI Araçları',
    'tools.parameter_schema': 'Parametre Şeması',
    'tools.path': 'Yol',
    'tools.version': 'Sürüm',
    'tools.category': 'Kategori',
    'tools.load_error': 'Araçlar yüklenemedi',

    // Cron
    'cron.title': 'Zamanlanmış Görevler',
    'cron.scheduled_tasks': 'Zamanlanmış Görevler',
    'cron.add': 'Görev Ekle',
    'cron.add_job': 'Görev Ekle',
    'cron.modal_add': 'Ekle',
    'cron.add_modal_title': 'Görev Ekle',
    'cron.delete': 'Sil',
    'cron.enable': 'Etkinleştir',
    'cron.disable': 'Devre Dışı Bırak',
    'cron.name': 'Ad',
    'cron.name_optional': 'Ad (isteğe bağlı)',
    'cron.command': 'Komut',
    'cron.command_required': 'Komut',
    'cron.schedule': 'Zamanlama',
    'cron.schedule_required': 'Zamanlama',
    'cron.schedule_kind_cron': 'Cron ifadesi',
    'cron.schedule_kind_at': 'Belirli zaman',
    'cron.schedule_kind_every': 'Sabit aralık',
    'cron.schedule_cron_placeholder': 'örn. 0 0 * * *',
    'cron.schedule_tz_optional': 'Saat dilimi (isteğe bağlı, örn. Europe/Istanbul)',
    'cron.schedule_every_ms_placeholder': 'Milisaniye aralığı (örn. 60000)',
    'cron.next_run': 'Sonraki Çalıştırma',
    'cron.last_run': 'Son Çalıştırma',
    'cron.last_status': 'Son Durum',
    'cron.enabled': 'Etkin',
    'cron.enabled_status': 'Etkin',
    'cron.disabled_status': 'Devre Dışı',
    'cron.empty': 'Zamanlanmış görev bulunamadı.',
    'cron.confirm_delete': 'Bu görevi silmek istediğinizden emin misiniz?',
    'cron.load_error': 'Cron görevleri yüklenemedi',
    'cron.validation_error': 'Zamanlama ve komut gereklidir.',
    'cron.add_error': 'Görev eklenemedi',
    'cron.delete_error': 'Görev silinemedi',
    'cron.cancel': 'İptal',
    'cron.adding': 'Ekleniyor...',
    'cron.id': 'ID',
    'cron.actions': 'İşlemler',
    'cron.loading_run_history': 'Çalıştırma geçmişi yükleniyor...',
    'cron.load_run_history_error': 'Çalıştırma geçmişi yüklenemedi',
    'cron.no_runs': 'Henüz çalıştırma kaydı yok.',
    'cron.recent_runs': 'Son Çalıştırmalar',
    'cron.yes': 'Evet',
    'cron.no': 'Hayır',
    'cron.edit': 'Düzenle',
    'cron.edit_modal_title': 'Görevi Düzenle',
    'cron.edit_error': 'Görev güncellenemedi',
    'cron.saving': 'Kaydediliyor...',
    'cron.save': 'Kaydet',
    'cron.confirm': 'Onayla',
    'cron.job_type': 'Görev Türü',
    'cron.job_type_shell': 'Shell',
    'cron.job_type_agent': 'Ajan',
    'cron.session_target': 'Oturum Hedefi',
    'cron.session_target_isolated': 'İzole',
    'cron.session_target_main': 'Ana',
    'cron.model_optional': 'Model (isteğe bağlı)',
    'cron.allowed_tools': 'İzinli Araçlar (virgülle)',
    'cron.delivery_mode': 'Teslim Modu',
    'cron.delivery_mode_none': 'Yok',
    'cron.delivery_mode_announce': 'Duyuru',
    'cron.delivery_channel': 'Teslim Kanalı',
    'cron.delivery_target': 'Teslim Hedefi',
    'cron.delivery_best_effort': 'En iyi çaba teslim',
    'cron.enable_job': 'Görevi etkinleştir',
    'cron.delete_after_run': 'Çalıştırma sonrası sil',
    'cron.run_now': 'Şimdi çalıştır',
    'cron.pause_job': 'Görevi duraklat',
    'cron.resume_job': 'Görevi sürdür',
    'cron.run_error': 'Görev çalıştırılamadı',
    'cron.toggle_error': 'Görev durumu değiştirilemedi',
    'cron.catch_up_title': 'Başlangıçta kaçırılan görevleri telafi et',
    'cron.catch_up_desc': 'KylinBot yeniden başladığında geciken görevleri çalıştır',
    'cron.name_placeholder': 'örn. Günlük temizlik',
    'cron.command_shell_placeholder': 'örn. cleanup --older-than 7d',
    'cron.command_agent_placeholder': 'Ajan görevi için istem girin',
    'cron.model_placeholder': 'örn. gpt-4.1',
    'cron.allowed_tools_placeholder': 'file_read,web_search',
    'cron.toggle_run_history': 'Çalıştırma geçmişini aç/kapat',
    'cron.task_name': 'Görev Adı',
    'cron.task_prompt_label': 'Görev Talimatı',
    'cron.task_name_placeholder': 'Görev adı girin',
    'cron.task_prompt_placeholder': 'Görev talimatı girin. Örn: Her gün 5 pratik İngilizce kelime öner',
    'cron.exec_time': 'Zamanlama',
    'cron.daily_time_step_up': 'Bir dakika ekle',
    'cron.daily_time_step_down': 'Bir dakika çıkar',
    'cron.once_run_date': 'Çalıştırma tarihi',
    'cron.once_date_step_up': 'Sonraki gün',
    'cron.once_date_step_down': 'Önceki gün',
    'cron.schedule_daily_label': 'Günlük',
    'cron.schedule_interval_label': 'Aralık',
    'cron.schedule_once_label': 'Bir Kez',
    'cron.remote_channel': 'Uzak Kanal',
    'cron.exec_model': 'Yürütme Modeli',
    'cron.channel_main': 'Ana Oturum',
    'cron.interval_every': 'Her',
    'cron.interval_row_label': 'Her aralık',
    'cron.interval_step_up': 'Aralık değerini artır',
    'cron.interval_step_down': 'Aralık değerini azalt',
    'cron.interval_unit_minute': 'dakika',
    'cron.interval_unit_hour': 'saat',
    'cron.interval_unit_day': 'gün',
    'cron.date_range': 'Tarih Aralığı',
    'cron.date_range_start': 'Başlangıç tarihi',
    'cron.date_range_end': 'Bitiş tarihi',
    'cron.model_default': 'Varsayılan',
    'cron.weekday_1': 'Pzt',
    'cron.weekday_2': 'Sal',
    'cron.weekday_3': 'Çar',
    'cron.weekday_4': 'Per',
    'cron.weekday_5': 'Cum',
    'cron.weekday_6': 'Cmt',
    'cron.weekday_7': 'Paz',

    // Integrations
    'integrations.title': 'Entegrasyonlar',
    'integrations.available': 'Mevcut',
    'integrations.active': 'Aktif',
    'integrations.coming_soon': 'Yakında',
    'integrations.category': 'Kategori',
    'integrations.status': 'Durum',
    'integrations.search': 'Entegrasyon ara...',
    'integrations.empty': 'Entegrasyon bulunamadı.',
    'integrations.activate': 'Etkinleştir',
    'integrations.deactivate': 'Devre Dışı Bırak',
    'integrations.load_error': 'Entegrasyonlar yüklenemedi',
    'integrations.all': 'Tümü',
    'integrations.status_active': 'Aktif',
    'integrations.status_available': 'Mevcut',
    'integrations.status_coming_soon': 'Yakında',

    // Model Switch
    'modelswitch.title': 'Model Değiştirme',
    'modelswitch.all': 'Tümü',
    'modelswitch.empty': 'Model bulunamadı.',
    'modelswitch.status_active': 'Aktif',
    'modelswitch.status_available': 'Mevcut',
    'modelswitch.status_coming_soon': 'Yakında',

    // Skills
    'skills.title': 'Beceriler',
    'skills.all': 'Tümü',
    'skills.empty': 'Beceri bulunamadı.',
    'skills.enabled': 'Etkin',
    'skills.disabled': 'Devre Dışı',
    'skills.status_active': 'Aktif',
    'skills.status_available': 'Mevcut',
    'skills.status_coming_soon': 'Yakında',

    // Memory
    'memory.title': 'Hafıza Deposu',
    'memory.memory_title': 'Hafıza',
    'memory.search': 'Hafıza ara...',
    'memory.search_placeholder': 'Hafıza girişleri ara...',
    'memory.add': 'Hafıza Ekle',
    'memory.add_memory': 'Hafıza Ekle',
    'memory.add_modal_title': 'Hafıza Ekle',
    'memory.delete': 'Sil',
    'memory.key': 'Anahtar',
    'memory.key_required': 'Anahtar',
    'memory.content': 'İçerik',
    'memory.content_required': 'İçerik',
    'memory.category': 'Kategori',
    'memory.category_optional': 'Kategori (isteğe bağlı)',
    'memory.timestamp': 'Zaman Damgası',
    'memory.session': 'Oturum',
    'memory.score': 'Puan',
    'memory.empty': 'Hafıza girişi bulunamadı.',
    'memory.confirm_delete': 'Bu hafıza girişini silmek istediğinizden emin misiniz?',
    'memory.all_categories': 'Tüm Kategoriler',
    'memory.search_button': 'Ara',
    'memory.load_error': 'Hafıza yüklenemedi',
    'memory.saving': 'Kaydediliyor...',
    'memory.validation_error': 'Anahtar ve içerik gereklidir.',
    'memory.store_error': 'Hafıza kaydedilemedi',
    'memory.delete_error': 'Hafıza silinemedi',
    'memory.delete_confirm': 'Sil?',
    'memory.yes': 'Evet',
    'memory.no': 'Hayır',
    'memory.cancel': 'İptal',

    // Config
    'config.title': 'Yapılandırma',
    'config.save': 'Kaydet',
    'config.saving': 'Kaydediliyor...',
    'config.reset': 'Sıfırla',
    'config.saved': 'Yapılandırma başarıyla kaydedildi.',
    'config.error': 'Yapılandırma kaydedilemedi.',
    'config.loading': 'Yapılandırma yükleniyor...',
    'config.editor_placeholder': 'TOML yapılandırması...',
    'config.configuration_title': 'Yapılandırma',
    'config.sensitive_title': 'Hassas alanlar gizlendi',
    'config.sensitive_hint': 'API anahtarları, belirteçler ve parolalar güvenlik için gizlendi. Maskeli bir alanı güncellemek için, tüm maskeli değeri yeni değerinizle değiştirin.',
    'config.save_success': 'Yapılandırma başarıyla kaydedildi.',
    'config.save_error': 'Yapılandırma kaydedilemedi',
    'config.toml_label': 'TOML Yapılandırması',
    'config.lines': 'satır',
    'config.mode.form': 'Form',
    'config.mode.advanced': 'Gelişmiş',
    'config.section.general': 'Genel',
    'config.section.agent': 'Ajan',
    'config.section.gateway': 'Ağ Geçidi',
    'config.section.cost': 'Maliyet',
    'config.section.memory': 'Hafıza',
    'config.section.web_search': 'Web Arama',
    'config.section.heartbeat': 'Kalp Atışı',
    'config.field.default_provider': 'Varsayılan Model Sağlayıcısı',
    'config.field.default_provider.desc': 'Kullanılacak LLM sağlayıcısı (ör. openrouter, ollama)',
    'config.field.default_model': 'Varsayılan Model',
    'config.field.default_model.desc': 'Varsayılan sağlayıcı için model adı',
    'config.field.default_temperature': 'Sıcaklık',
    'config.field.default_temperature.desc': 'Rastgeleliği kontrol eder (0 = belirleyici, 2 = maks yaratıcılık)',
    'config.field.provider_timeout_secs': 'Sağlayıcı Zaman Aşımı (sn)',
    'config.field.provider_timeout_secs.desc': 'LLM API çağrıları için HTTP zaman aşımı',
    'config.field.locale': 'Dil',
    'config.field.locale.desc': 'Arayüz dili ayarı',
    'config.field.compact_context': 'Kompakt Bağlam',
    'config.field.compact_context.desc': 'Küçük modeller için bağlam boyutunu azalt (13B veya daha az)',
    'config.field.max_tool_iterations': 'Maks Araç Yinelemesi',
    'config.field.max_tool_iterations.desc': 'Kullanıcı mesajı başına maks araç çağrısı döngüsü',
    'config.field.max_history_messages': 'Maks Geçmiş Mesajı',
    'config.field.max_history_messages.desc': 'Oturum başına maks konuşma geçmişi mesajı',
    'config.field.max_context_tokens': 'Maks Bağlam Token',
    'config.field.max_context_tokens.desc': 'Aşıldığında geçmiş sıkıştırma tetiklenir',
    'config.field.parallel_tools': 'Paralel Araçlar',
    'config.field.parallel_tools.desc': 'Bir turda paralel araç yürütmeyi etkinleştir',
    'config.field.gateway_port': 'Port',
    'config.field.gateway_port.desc': 'Ağ geçidi sunucu portu',
    'config.field.gateway_host': 'Ana Bilgisayar',
    'config.field.gateway_host.desc': 'Ağ geçidi bağlama adresi',
    'config.field.require_pairing': 'Eşleştirme Gerekli',
    'config.field.require_pairing.desc': 'İstekleri kabul etmeden önce cihaz eşleştirmesi gerektirir',
    'config.field.session_persistence': 'Oturum Kalıcılığı',
    'config.field.session_persistence.desc': 'WebSocket oturumlarını SQLite\'a kaydet',
    'config.field.session_ttl_hours': 'Oturum TTL (saat)',
    'config.field.session_ttl_hours.desc': 'Eski oturumları otomatik arşivle (0 = devre dışı)',
    'config.field.allow_public_bind': 'Herkese Açık Bağlamaya İzin Ver',
    'config.field.allow_public_bind.desc': 'Tünel olmadan localhost dışı bağlamaya izin ver',
    'config.field.daily_limit_usd': 'Günlük Limit (USD)',
    'config.field.daily_limit_usd.desc': 'Günlük harcama limiti',
    'config.field.monthly_limit_usd': 'Aylık Limit (USD)',
    'config.field.monthly_limit_usd.desc': 'Aylık harcama limiti',
    'config.field.warn_at_percent': 'Uyarı Eşiği (%)',
    'config.field.warn_at_percent.desc': 'Bütçe kullanımı bu yüzdeyi aştığında uyar',
    'config.field.allow_override': 'Geçersiz Kılmaya İzin Ver',
    'config.field.allow_override.desc': '--override bayrağının bütçe limitlerini aşmasına izin ver',
    'config.field.memory_enabled': 'Hafızayı etkinleştir',
    'config.field.memory_enabled.desc': 'Ajan hafıza depolamasını aç veya kapat',
    'config.field.memory_backend': 'Arka Uç',
    'config.field.memory_backend.desc': 'Ajan hafızası için depolama arka ucu',
    'config.field.heartbeat_enabled': 'Kalp atışını etkinleştir',
    'config.field.heartbeat_enabled.desc': 'Zamanlanmış kalp atışı kontrollerini çalıştır',
    'config.field.web_search_enabled': 'Web aramayı etkinleştir',
    'config.field.web_search_enabled.desc': 'Ajanın web arama araçlarını kullanmasına izin ver',
    'config.field.cost_enabled': 'Maliyet limitlerini etkinleştir',
    'config.field.cost_enabled.desc': 'Harcamayı izle ve bütçe limitlerini uygula',
    'config.field.web_search_provider': 'Arama Sağlayıcısı',
    'config.field.web_search_provider.desc': 'Kullanılacak web arama motoru',
    'config.field.max_results': 'Maks Sonuç',
    'config.field.max_results.desc': 'Arama sorgusu başına sonuç sayısı',
    'config.field.web_search_timeout': 'Zaman Aşımı (sn)',
    'config.field.web_search_timeout.desc': 'Arama isteği zaman aşımı',
    'config.field.interval_minutes': 'Aralık (dk)',
    'config.field.interval_minutes.desc': 'Kalp atışı kontrolleri arasındaki dakika',
    'config.field.two_phase': 'İki Aşamalı',
    'config.field.two_phase.desc': 'Yürütmeden önce LLM\'e çalıştırıp çalıştırmayacağını sor',
    'config.field.adaptive': 'Uyarlanabilir',
    'config.field.adaptive.desc': 'Etkinliğe göre aralığı otomatik ayarla',
    'config.field.min_interval_minutes': 'Min Aralık (dk)',
    'config.field.min_interval_minutes.desc': 'Uyarlanabilir mod etkinken minimum aralık',
    'config.field.max_interval_minutes': 'Maks Aralık (dk)',
    'config.field.max_interval_minutes.desc': 'Uyarlanabilir mod geri çekildiğinde maksimum aralık',
    'config.field.heartbeat_message': 'Yedek Mesaj',
    'config.field.heartbeat_message.desc': 'HEARTBEAT.md boşken yedek görev metni',
    'config.field.heartbeat_target': 'Hedef Kanal',
    'config.field.heartbeat_target.desc': 'Kalp atışı çıktısı için teslim kanalı (ör. telegram)',
    'config.field.task_timeout_secs': 'Görev Zaman Aşımı (sn)',
    'config.field.task_timeout_secs.desc': 'Tek bir kalp atışı ajan çağrısı için maks saniye',
    'config.error.serialize_failed': 'Yapılandırma serileştirilemedi',
    'config.error.invalid_toml_switch': 'Geçersiz TOML — form görünümüne geçmeden önce hataları düzeltin',
    'config.error.reload_failed': 'Yapılandırma yeniden yüklenemedi',
    'config.error.initial_parse_failed': 'Yapılandırma ayrıştırılamadı; boş form gösteriliyor. TOML\'u düzeltin veya başka yerde düzenleyin.',

    // Cost
    'cost.title': 'Maliyet Takibi',
    'cost.session': 'Oturum Maliyeti',
    'cost.daily': 'Günlük Maliyet',
    'cost.monthly': 'Aylık Maliyet',
    'cost.total_tokens': 'Toplam Token',
    'cost.request_count': 'İstek Sayısı',
    'cost.by_model': 'Modele Göre Maliyet',
    'cost.model': 'Model',
    'cost.tokens': 'Token',
    'cost.requests': 'İstekler',
    'cost.usd': 'Maliyet (USD)',
    'cost.load_error': 'Maliyet verileri yüklenemedi',
    'cost.session_cost': 'Oturum Maliyeti',
    'cost.daily_cost': 'Günlük Maliyet',
    'cost.monthly_cost': 'Aylık Maliyet',
    'cost.total_requests': 'Toplam İstek',
    'cost.token_statistics': 'Token İstatistikleri',
    'cost.avg_tokens_per_request': 'Ortalama Token / İstek',
    'cost.cost_per_1k_tokens': '1K Token Başına Maliyet',
    'cost.model_breakdown': 'Model Detayı',
    'cost.no_model_data': 'Model verisi mevcut değil.',
    'cost.cost': 'Maliyet',
    'cost.share': 'Pay',

    // Logs
    'logs.title': 'Canlı Kayıtlar',
    'logs.live_logs': 'Canlı Kayıtlar',
    'logs.clear': 'Temizle',
    'logs.pause': 'Duraklat',
    'logs.resume': 'Devam Et',
    'logs.filter': 'Kayıtları filtrele...',
    'logs.filter_label': 'Filtre',
    'logs.empty': 'Kayıt girişi bulunamadı.',
    'logs.connected': 'Bağlandı',
    'logs.disconnected': 'Bağlantı kesildi',
    'logs.events': 'olay',
    'logs.jump_to_bottom': 'En alta atla',
    'logs.paused_hint': 'Kayıt akışı duraklatıldı.',
    'logs.waiting_hint': 'Olay bekleniyor...',

    // Doctor
    'doctor.title': 'Sistem Tanıları',
    'doctor.diagnostics_title': 'Tanılar',
    'doctor.run': 'Tanı Çalıştır',
    'doctor.run_diagnostics': 'Tanı Çalıştır',
    'doctor.running': 'Tanı çalıştırılıyor...',
    'doctor.running_btn': 'Çalıştırılıyor...',
    'doctor.running_desc': 'Tanı çalıştırılıyor...',
    'doctor.running_hint': 'Bu birkaç saniye sürebilir.',
    'doctor.ok': 'Tamam',
    'doctor.warn': 'Uyarı',
    'doctor.error': 'Hata',
    'global.refresh': 'Yenile',
    'doctor.severity': 'Şiddet',
    'doctor.category': 'Kategori',
    'doctor.message': 'Mesaj',
    'doctor.empty': 'Henüz tanı çalıştırılmadı.',
    'doctor.summary': 'Tanı Özeti',
    'doctor.issues_found': 'Sorunlar Bulundu',
    'doctor.warnings_summary': 'Uyarılar',
    'doctor.all_clear': 'Her Şey Yolunda',
    'doctor.system_diagnostics': 'Sistem Tanıları',
    'doctor.empty_hint': 'KylinBot kurulumunuzu kontrol etmek için "Tanı Çalıştır" düğmesine tıklayın.',

    // Auth / Pairing
    'auth.pair': 'Cihaz Eşleştir',
    'auth.pairing_code': 'Eşleştirme Kodu',
    'auth.pair_button': 'Eşleştir',
    'auth.logout': 'Çıkış Yap',
    'auth.pairing_success': 'Eşleştirme başarılı!',
    'auth.pairing_failed': 'Eşleştirme başarısız. Lütfen tekrar deneyin.',
    'auth.enter_code': 'Akıllı birine bağlanmak için eşleştirme kodunuzu girin.',

    // Common
    'common.loading': 'Yükleniyor...',
    'common.error': 'Bir hata oluştu.',
    'common.retry': 'Tekrar Dene',
    'common.cancel': 'İptal',
    'common.confirm': 'Onayla',
    'common.save': 'Kaydet',
    'common.delete': 'Sil',
    'common.edit': 'Düzenle',
    'common.close': 'Kapat',
    'common.yes': 'Evet',
    'common.no': 'Hayır',
    'common.search': 'Ara...',
    'common.no_data': 'Veri mevcut değil.',
    'common.refresh': 'Yenile',
    'common.back': 'Geri',
    'common.actions': 'İşlemler',
    'common.name': 'Ad',
    'common.description': 'Açıklama',
    'common.status': 'Durum',
    'common.created': 'Oluşturulma',
    'common.updated': 'Güncellenme',

    // Health
    'health.title': 'Sistem Sağlığı',
    'health.component': 'Bileşen',
    'health.status': 'Durum',
    'health.last_ok': 'Son Başarılı',
    'health.last_error': 'Son Hata',
    'health.restart_count': 'Yeniden Başlatmalar',
    'health.pid': 'İşlem Kimliği',
    'health.uptime': 'Çalışma Süresi',
    'health.updated_at': 'Son Güncelleme',

    // Settings
    'settings.title': 'Ayarlar',
    'settings.theme_title': 'Tema Ayarları',
    'settings.tab.appearance': 'Görünüm',
    'settings.tab.typography': 'Tipografi',
    'settings.dark_presets': 'Koyu Temalar',
    'settings.light_presets': 'Açık Temalar',
    'settings.appearance': 'Görünüm',
    'settings.typography': 'Tipografi',
    'settings.fontUi': 'Arayüz Yazı Tipi',
    'settings.fontMono': 'Kod Yazı Tipi',
    'settings.fontSize': 'Arayüz Boyutu',
    'settings.fontMonoSize': 'Kod Boyutu',
    'settings.preview': 'Önizleme',
    'settings.previewText': 'Tembel köpek üzerinde hızlı kahverengi tilki zıplar.',
    'settings.fontNote': 'Yazı tipi değişiklikleri sayfa yeniden yüklendikten sonra geçerli olur.',
    'settings.language': 'Dil',
    'settings.window': 'Pencere',

    // Theme
    'theme.mode': 'Tema Modu',
    'theme.accent': 'Vurgu Rengi',
    'theme.system': 'Sistem',
    'theme.dark': 'Koyu',
    'theme.light': 'Açık',
    'theme.oled': 'OLED Siyah',

    // Channel
    'channel.title': 'Kanallar',
    'channel.configure': 'Yapılandır',
    'channel.connected': 'Bağlı',
    'channel.not_configured': 'Yapılandırılmamış',
    'channel.not_connected': 'Bağlı Değil',
    'channel.disconnecting': 'Bağlantı kesiliyor...',
    'channel.disconnect': 'Bağlantıyı Kes',
    'channel.wechat': 'WeChat',
    'channel.wechat.desc': 'Günlük görevler için sohbetlerde doğrudan KylinBot çağırmak üzere WeChat bağlayın',
    'channel.wecom': 'WeCom',
    'channel.wecom.desc': 'Takım işbirliği için grup veya özel sohbetlerde KylinBot çağırmak üzere WeCom hesabınızı bağlayın',
    'channel.dingtalk': 'DingTalk',
    'channel.dingtalk.desc': 'Görev komutları vermek ve iş akışlarını otomatikleştirmek için DingTalk botu bağlayın',
    'channel.feishu': 'Feishu',
    'channel.feishu.desc': 'Görev işleme ve iş akışı koordinasyonu için Feishu botu bağlayın',
    'channel.wechat.connected': 'WeChat başarıyla yapılandırıldı',
    'channel.wecom.connected': 'WeCom başarıyla yapılandırıldı',
    'channel.dingtalk.connected': 'DingTalk başarıyla yapılandırıldı',
    'channel.feishu.connected': 'Feishu başarıyla yapılandırıldı',
    'channel.wechat.disconnected': 'WeChat bağlantısı kesildi',
    'channel.wecom.disconnected': 'WeCom bağlantısı kesildi',
    'channel.dingtalk.disconnected': 'DingTalk bağlantısı kesildi',
    'channel.feishu.disconnected': 'Feishu bağlantısı kesildi',
    'channel.scan_connect': 'Tara ve Bağlan',
    'channel.websocket_connect': 'WebSocket Bağlantısı',
    'channel.stream_connect': 'Stream Bağlantısı',
    'channel.bind_success': 'Başarıyla bağlandı',
    'channel.qr_expired': 'QR kodunun süresi doldu, lütfen yenileyin',
    'channel.refresh_qr': 'QR Kodunu Yenile',
    'channel.scanned_confirm': 'Tarandı, lütfen telefonunuzda onaylayın...',
    'channel.bind_error': 'Bir hata oluştu',
    'channel.connect': 'Bağlan',
    'channel.scan_tip': 'Lütfen aşağıdaki QR kodunu WeChat ile tarayın',
    'channel.confirm': 'Tamam',
    'channel.retry': 'Tekrar Dene',
    'channel.cancel': 'İptal',
    'channel.bot_id': 'Bot ID',
    'channel.wecom.bot_id_placeholder': 'Bot ID girin',
    'channel.wecom.secret_placeholder': 'Secret girin',
    'channel.wecom.fill_required': 'Lütfen Bot ID ve Secret doldurun',
    'channel.dingtalk.client_id_placeholder': 'Client ID girin',
    'channel.dingtalk.client_secret_placeholder': 'Client Secret girin',
    'channel.dingtalk.fill_required': 'Lütfen Client ID ve Client Secret doldurun',
    'channel.dingtalk.auth_failed': 'Yetkilendirme başarısız',
    'channel.feishu.app_id_placeholder': 'App ID girin',
    'channel.feishu.app_secret_placeholder': 'App Secret girin',
    'channel.feishu.fill_required': 'Lütfen App ID ve App Secret doldurun',
    'channel.feishu.access_denied': 'Kullanıcı yetkilendirmeyi reddetti',
    'agent.approval_required': 'Onay Gerekli',
    'agent.allow_once': 'Bir Kez İzin Ver',
    'agent.always_this_session': 'Bu Oturumda Her Zaman',
    'agent.deny': 'Reddet',
    'agent.expires_at': 'Son kullanma',

    // Identity
    'identity.setup': 'Kimlik Ayarla',
    'identity.setup_desc': 'AI asistanınızı ayarlayın',
    'identity.name_placeholder': 'AI asistanınıza bir isim verin',
    'identity.name_example': 'örn: Kylin, Xiao Zhi, Asistan',
    'identity.role_label': 'Rolünü tanımlayın (isteğe bağlı)',
    'identity.role_example': 'örn: Kod optimizasyonu ve hata ayıklamada uzman profesyonel kodlama asistanı',

    // History
    'history.title': 'Sohbet Geçmişi',
    'history.task_title': 'Görev Geçmişi',
    'history.today': 'Bugün',
    'history.last_7_days': 'Son 7 Gün',
    'history.last_30_days': 'Son 30 Gün',
    'history.last_year': 'Son Yıl',
    'history.earlier': 'Daha Önce',
    'history.empty': 'Henüz sohbet geçmişi yok',
    'history.loading': 'Yükleniyor...',

    // Chat
    'chat.attachment_too_large': 'Toplam ek boyutu çok büyük, lütfen 40MB içinde tutun.',
    'chat.file_too_large': '{name} dosyası 15MB sınırını aşıyor.',
    'chat.read_attachment_failed': 'Ek okunamadı, lütfen tekrar deneyin.',
    'chat.remove_attachment': '{name} ekini kaldır',
    'chat.unnamed_session': 'İsimsiz Oturum',
    'chat.yesterday': 'Dün',
    'chat.weekday.sun': 'Paz',
    'chat.weekday.mon': 'Pzt',
    'chat.weekday.tue': 'Sal',
    'chat.weekday.wed': 'Çar',
    'chat.weekday.thu': 'Per',
    'chat.weekday.fri': 'Cum',
    'chat.weekday.sat': 'Cmt',
    'chat.date.month_day': '{d}.{m}',
    'chat.date.year_month_day': '{d}.{m}.{y}',

    // Model
    'model.edit_config': 'Model Yapılandırmasını Düzenle',
    'model.add_config': 'Model Yapılandırması Ekle',
    'model.cancel_edit': 'Düzenlemeyi İptal Et',
    'model.save_edit_sync': 'Düzenlemeyi Kaydet ve Yapılandırmayı Senkronize Et',
    'model.add_write_remote': 'Ekle ve Uzak Yapılandırmaya Yaz',
    'model.saving': 'Kaydediliyor...',
    'model.current_model': 'Mevcut Model',
    'model.view': 'Görüntüle',
    'model.not_set': 'Ayarlanmamış',
    'model.not_saved_locally': 'Yerel Olarak Kaydedilmedi',
    'model.provider_model_required': 'Lütfen önce provider ve modeli doldurun',
    'model.update_sync_success': 'Model bilgisi güncellendi ve yerel/uzak yapılandırmaya senkronize edildi',
    'model.add_remote_success': 'Model uzak yapılandırmaya yazıldı ve değiştirilebilir listeye eklendi',
    'model.save_failed': 'Kaydetme başarısız',
    'model.deleted': 'Model değiştirilebilir listeden kaldırıldı',
    'model.model_placeholder': 'örn. gpt-5.2 / qwen-plus / claude-sonnet-4-6',
    'model.qwen_api_key_required': 'Qwen bir API Anahtarı gerektirir. Lütfen kaydetmeden önce DASHSCOPE_API_KEY doldurun.',
    'model.qwen_api_key_hint': 'Qwen gerekli: DASHSCOPE_API_KEY',
    'model.qwen_oauth_hint': 'Qwen Code: QWEN_OAUTH_TOKEN (isteğe bağlı)',
    'model.key_optional_hint': 'İsteğe bağlı (provider başlatma hatasını önlemek için önerilir)',
    'model.base_url_hint_qwen': 'İsteğe bağlı, ör. https://dashscope.aliyuncs.com/compatible-mode/v1',
    'model.base_url_hint_openai': 'İsteğe bağlı, ör. https://api.openai.com/v1',
    'model.custom_base_url_required': 'Özel provider bir Base URL gerektirir, ör. https://api.openai.com/v1',
    'model.provider_model_empty': 'Provider ve model boş olamaz',
    'model.configured_model': 'Yapılandırılmış Model',
    'model.trial_model': 'Deneme Modeli',
    'model.qwen_plus': 'Qwen Plus',
    'model.qwen_qwq': 'Qwen QWQ-32B',
    'model.desc_general': 'Genel konuşma, dengeli performans ve maliyet',
    'model.desc_thinking': 'Düşünme modeli, güçlü akıl yürütme yeteneği',
    'model.desc_deep_reasoning': 'Derin akıl yürütme modeli',
    'model.desc_new_thinking': 'Yeni nesil derin düşünme modeli',

    // Provider presets
    'provider.category_recommended': 'Önerilen (Toplama ve Doğrudan)',
    'provider.category_fast': 'Hızlı Çıkarım',
    'provider.category_gateway': 'Ağ Geçidi / Bulut Sağlayıcılar',
    'provider.category_domestic': 'Yerel ve Uzman',
    'provider.category_local': 'Yerel / Özel OpenAI Uyumlu',
    'provider.openrouter_notes': 'Çok model yönlendirme, OpenAI uyumlu Chat Completions',
    'provider.anthropic_notes': 'Messages API; yapılandırmada karşılık gelen anahtarı ayarlamayı gerektirir',
    'provider.openai_notes': 'wire_api göre Chat Completions / Responses',
    'provider.ollama_notes': 'Yerel veya uzak noktaya yapılandırılabilir api_url',
    'provider.custom_notes': 'custom:https://host... gibi Sağlayıcı ID',

    // SkillHub
    'skillhub.title': 'SkillHub',
    'skillhub.tab.hot': '🔥 Trending',
    'skillhub.tab.featured': '⭐ Önerilen',
    'skillhub.tab.newest': '🆕 En Yeni',
    'skillhub.tab.installed': '✅ Yüklü',
    'skillhub.tab.installed_count': '✅ Yüklü ({count})',
    'skillhub.search.placeholder': 'Becerileri ara...',
    'skillhub.search.results': '"{query}" için arama sonuçları',
    'skillhub.install': 'Yükle',
    'skillhub.installing': 'Yükleniyor...',
    'skillhub.installed': 'Yüklü',
    'skillhub.uninstall': 'Kaldır',
    'skillhub.author': 'Yazar: {author}',
    'skillhub.empty.installed': 'Yüklü beceri yok',
    'skillhub.empty.skills': 'Beceri yok',
    'skillhub.retry': 'Tekrar Dene',
    'skillhub.load_failed': 'Yükleme başarısız',
    'skillhub.detail.source_clawhub': 'ClawHub Kaynaklı',
    'skillhub.detail.source': '{source} Kaynaklı',
    'skillhub.detail.safe': 'Güvenlik kontrolünden geçti',
    'skillhub.detail.unsafe': 'Kontrol bekliyor',
    'skillhub.detail.downloads': 'İndirmeler',
    'skillhub.detail.stars': 'Yıldızlar',
    'skillhub.detail.security_check': 'Güvenlik Kontrolü',
    'skillhub.detail.lab_keen': 'Keen Lab',
    'skillhub.detail.lab_sanbu': 'Sanbu Lab',
    'skillhub.detail.security_disclaimer': 'Güvenlik kontrol sonuçları üçüncü taraf kuruluşlar tarafından sağlanır ve yalnızca referans içindir. Mutlak güvenlik garantisi oluşturmaz. Siber güvenlik dinamiktir — lütfen uygun güvenlik önlemleri ve risk yönetimi uygulayın.',
    'skillhub.modal.install_title': 'Beceri Yükle',
    'skillhub.modal.install_confirm': '{name} SkillHub\'dan yüklensin mi?',
    'skillhub.modal.force_overwrite': 'Zaten yüklüyse üzerine yaz',
    'skillhub.modal.cancel': 'İptal',
    'skillhub.modal.install_btn': 'Yükle',
    'skillhub.modal.installing': '{name} yükleniyor...',
    'skillhub.modal.success': '{name} başarıyla yüklendi!',
    'skillhub.modal.error': 'Yükleme başarısız',
    'skillhub.modal.close': 'Kapat',
    'skillhub.modal.retry': 'Tekrar Dene',
  },
};

// ---------------------------------------------------------------------------
// Current locale state
// ---------------------------------------------------------------------------

function detectBrowserLocale(): Locale {
  if (typeof navigator === 'undefined') return 'en';
  const lang = (navigator.language || navigator.languages?.[0] || 'en').toLowerCase();
  if (lang.startsWith('zh')) return 'zh';
  if (lang.startsWith('tr')) return 'tr';
  return 'en';
}

let currentLocale: Locale = detectBrowserLocale();

export function getLocale(): Locale {
  return currentLocale;
}

export function setLocale(locale: Locale): void {
  currentLocale = locale;
}

// ---------------------------------------------------------------------------
// Translation function
// ---------------------------------------------------------------------------

/**
 * Translate a key using the current locale. Returns the key itself if no
 * translation is found.
 */
export function t(key: string): string {
  return translations[currentLocale]?.[key] ?? translations.en[key] ?? key;
}

/**
 * Get the translation for a specific locale. Falls back to English, then to the
 * raw key.
 */
export function tLocale(key: string, locale: Locale): string {
  return translations[locale]?.[key] ?? translations.en[key] ?? key;
}

// ---------------------------------------------------------------------------
// React hook
// ---------------------------------------------------------------------------

/**
 * React hook that fetches the locale from /api/status on mount and keeps the
 * i18n module in sync. Returns the current locale and a `t` helper bound to it.
 */
export function useLocale(): { locale: Locale; t: (key: string) => string } {
  const [locale, setLocaleState] = useState<Locale>(currentLocale);

  useEffect(() => {
    let cancelled = false;

    getStatus()
      .then((status) => {
        if (cancelled) return;
        const localeStr = status.locale?.toLowerCase() ?? '';
        let detected: Locale;
        if (localeStr.startsWith('zh')) {
          detected = 'zh';
        } else if (localeStr.startsWith('tr')) {
          detected = 'tr';
        } else {
          detected = 'en';
        }
        setLocale(detected);
        setLocaleState(detected);
      })
      .catch(() => {
        // Keep default locale on error
      });

    return () => {
      cancelled = true;
    };
  }, []);

  return {
    locale,
    t: (key: string) => tLocale(key, locale),
  };
}
