chore: initialize insar management system v2

This commit is contained in:
2026-04-14 13:16:01 +08:00
commit ecc72ec9cd
361 changed files with 2142522 additions and 0 deletions
+420
View File
@@ -0,0 +1,420 @@
const TRANSLATION_PAIRS = [
{ zh: '正在检查登录状态...', en: 'Checking login status...' },
{ zh: '请稍候,系统正在验证会话。', en: 'Please wait, verifying your session.' },
{ zh: 'InSAR 自动化管理系统', en: 'InSAR Automation Management System' },
{ zh: '科研工程模式', en: 'Research Engineering Mode' },
{ zh: '已授权', en: 'Licensed' },
{ zh: '未授权', en: 'Unlicensed' },
{ zh: '管理员', en: 'Admin' },
{ zh: '只读账号', en: 'Read-only account' },
{ zh: '任务', en: 'Tasks' },
{ zh: '授权至', en: 'License until' },
{ zh: '刷新自检状态', en: 'Refresh health status' },
{ zh: '自检中...', en: 'Checking...' },
{ zh: '刷新自检', en: 'Refresh Health' },
{ zh: '退出登录', en: 'Sign Out' },
{ zh: '数据管理', en: 'Data' },
{ zh: '生产规划', en: 'Production' },
{ zh: 'D-InSAR 分析', en: 'D-InSAR Analysis' },
{ zh: '水体监测', en: 'Water Monitoring' },
{ zh: '运行维护', en: 'Operations' },
{ zh: '入库监控', en: 'Ingest Monitor' },
{ zh: '数据列表', en: 'Data List' },
{ zh: '灾害点', en: 'Hazard Points' },
{ zh: '配对规划', en: 'Pair Planning' },
{ zh: '任务规划', en: 'Task Planning' },
{ zh: '任务批次', en: 'Task Batches' },
{ zh: '数据分发', en: 'Data Distribution' },
{ zh: 'D-InSAR生产', en: 'D-InSAR Production' },
{ zh: 'D-InSAR 结果', en: 'D-InSAR Results' },
{ zh: 'AI 质量评估', en: 'AI Quality Assessment' },
{ zh: '运维自检', en: 'Health Check' },
{ zh: '用户管理', en: 'User Management' },
{ zh: '审计日志', en: 'Audit Logs' },
{ zh: '刷新源数据', en: 'Refresh Source Data' },
{ zh: '统计', en: 'Statistics' },
{ zh: '源数据检索', en: 'Source Data Search' },
{ zh: '卫星:全部', en: 'Satellite: All' },
{ zh: '成像模式:全部', en: 'Imaging Mode: All' },
{ zh: '成像时间起:不限', en: 'Imaging Date From: Any' },
{ zh: '成像时间止:不限', en: 'Imaging Date To: Any' },
{ zh: '极化方式:全部', en: 'Polarization: All' },
{ zh: '产品级别:全部', en: 'Product Level: All' },
{ zh: 'AOI: 不限', en: 'AOI: Any' },
{ zh: 'AOI: 行政区', en: 'AOI: Region' },
{ zh: 'AOI: 上传SHP', en: 'AOI: Upload SHP' },
{ zh: '搜索', en: 'Search' },
{ zh: '重置', en: 'Reset' },
{ zh: '选择省份', en: 'Select Province' },
{ zh: '选择地市(可选)', en: 'Select City (Optional)' },
{ zh: '高级字段', en: 'Advanced Fields' },
{ zh: '卫星模式:全部', en: 'Satellite Mode: All' },
{ zh: '接收站:全部', en: 'Receiving Station: All' },
{ zh: '轨道圈号:全部', en: 'Orbit Circle: All' },
{ zh: '采集时间:全部', en: 'Acquisition Time: All' },
{ zh: '产品类型:全部', en: 'Product Type: All' },
{ zh: '产品唯一ID:全部', en: 'Product Unique ID: All' },
{ zh: '轨道方向:全部', en: 'Orbit Direction: All' },
{ zh: '有精轨:全部', en: 'Precise Orbit: All' },
{ zh: '有精轨:是', en: 'Precise Orbit: Yes' },
{ zh: '有精轨:否', en: 'Precise Orbit: No' },
{ zh: 'ENVI已处理:全部', en: 'ENVI Processed: All' },
{ zh: 'ENVI已处理:是', en: 'ENVI Processed: Yes' },
{ zh: 'ENVI已处理:否', en: 'ENVI Processed: No' },
{ zh: '源数据检索选项加载中...', en: 'Loading source data search options...' },
{ zh: '无源数据', en: 'No source data.' },
{ zh: '覆盖面全部显示/隐藏', en: 'Toggle all coverage' },
{ zh: '源影像一键显示', en: 'Show All Source Previews' },
{ zh: '源影像一键隐藏', en: 'Hide All Source Previews' },
{ zh: '上一页', en: 'Previous' },
{ zh: '下一页', en: 'Next' },
{ zh: '每页', en: 'Per page' },
{ zh: '条', en: 'items' },
{ zh: '跳到', en: 'Go to' },
{ zh: '页', en: 'page' },
{ zh: '跳转', en: 'Jump' },
{ zh: '提示:可跳转页码范围为', en: 'Tip: valid page range is' },
{ zh: '按 Enter 可快速跳转。', en: 'Press Enter to jump.' },
{ zh: '未找到 Dinsar 结果。', en: 'No D-InSAR results found.' },
{ zh: '清除筛选', en: 'Clear Filter' },
{ zh: '一键显示', en: 'Show All' },
{ zh: '一键隐藏', en: 'Hide All' },
{ zh: '隐藏日期', en: 'Hide Dates' },
{ zh: '显示日期', en: 'Show Dates' },
{ zh: 'AI 评分过滤', en: 'AI Score Filter' },
{ zh: '过滤低于此分数的低质量结果', en: 'Filter low-quality results below this score' },
{ zh: '主影像日期', en: 'Master date' },
{ zh: '辅影像日期', en: 'Slave date' },
{ zh: '标记为高质量', en: 'Mark as high quality' },
{ zh: '标记为低质量', en: 'Mark as low quality' },
{ zh: '良好', en: 'Good' },
{ zh: '欠佳', en: 'Poor' },
{ zh: '使用 AI 自动分析此结果', en: 'Use AI to analyze this result' },
{ zh: 'AI 诊断', en: 'AI Diagnose' },
{ zh: '在地图上显示/隐藏', en: 'Show/hide on map' },
{ zh: 'AI 质量评分', en: 'AI quality score' },
{ zh: '影像信息', en: 'Image Information' },
{ zh: '卫星:', en: 'Satellite:' },
{ zh: '卫星模式:', en: 'Satellite Mode:' },
{ zh: '接收站:', en: 'Receiving Station:' },
{ zh: '成像日期:', en: 'Imaging Date:' },
{ zh: '成像模式:', en: 'Imaging Mode:' },
{ zh: '轨道圈号:', en: 'Orbit Circle:' },
{ zh: '场景中心经度:', en: 'Scene Center Lon:' },
{ zh: '场景中心纬度:', en: 'Scene Center Lat:' },
{ zh: '采集时间:', en: 'Acquisition Time:' },
{ zh: '产品类型:', en: 'Product Type:' },
{ zh: '极化方式:', en: 'Polarization:' },
{ zh: '产品级别:', en: 'Product Level:' },
{ zh: '产品唯一ID', en: 'Product Unique ID:' },
{ zh: '轨道方向:', en: 'Orbit Direction:' },
{ zh: '有精轨:', en: 'Has Orbit:' },
{ zh: '轨道文件:', en: 'Orbit File:' },
{ zh: 'ENVI已处理:', en: 'ENVI Processed:' },
{ zh: '关闭', en: 'Close' },
{ zh: '是', en: 'Yes' },
{ zh: '否', en: 'No' },
{ zh: '未知', en: 'Unknown' },
{ zh: '加载中', en: 'Loading' },
{ zh: '失败', en: 'Failed' },
{ zh: '成功', en: 'Succeeded' },
// AiQualityPanel
{ zh: '基于标注结果训练随机森林模型,并对所有结果进行质量预测。', en: 'Train a random forest model based on labeled results and predict quality for all results.' },
{ zh: '已标注', en: 'Labeled' },
{ zh: '良好', en: 'Good' },
{ zh: '欠佳', en: 'Poor' },
{ zh: '处理中...', en: 'Processing...' },
{ zh: '训练模型', en: 'Train Model' },
{ zh: '至少需要2个样本 (包含好和坏) 才能训练。', en: 'At least 2 samples (good and bad) are required to train.' },
{ zh: '预测所有结果', en: 'Predict All Results' },
{ zh: '请先训练模型。', en: 'Please train the model first.' },
// PairingPanel
{ zh: '基于时间基线、空间基线与重叠率筛选干涉对,可选 AOI 限定范围。', en: 'Filter interferometric pairs by temporal baseline, spatial baseline, and overlap ratio. Optional AOI constraint.' },
{ zh: '配对', en: 'Pair' },
{ zh: 'PS准备', en: 'PS Prep' },
{ zh: '结果与刷新', en: 'Results & Refresh' },
{ zh: '已生成配对', en: 'Generated Pairs' },
{ zh: '已选中', en: 'Selected' },
{ zh: '刷新当前检索', en: 'Refresh Current Search' },
{ zh: '刷新结果', en: 'Refresh Results' },
// BatchPanel
{ zh: '刷新中...', en: 'Refreshing...' },
{ zh: '刷新批次', en: 'Refresh Batches' },
{ zh: '-- 选择批次 --', en: '-- Select Batch --' },
{ zh: '全部完成', en: 'Mark All Done' },
{ zh: '请选择一个批次查看明细。', en: 'Select a batch to view details.' },
{ zh: '该批次暂无明细。', en: 'No items in this batch.' },
{ zh: '未审核', en: 'Pending' },
{ zh: '审核中', en: 'In Review' },
{ zh: '可下发', en: 'Approved' },
{ zh: '不宜下发', en: 'Rejected' },
{ zh: '备注', en: 'Remark' },
{ zh: '保存', en: 'Save' },
// --- Base layers (appConstants) ---
{ zh: 'Google 影像', en: 'Google Imagery' },
{ zh: '高德 影像', en: 'Gaode Imagery' },
{ zh: '高德 矢量', en: 'Gaode Vector' },
// --- Preview status (appUiHelpers) ---
{ zh: '回退', en: 'Fallback' },
{ zh: '纠正', en: 'Ortho' },
{ zh: '未建', en: 'None' },
// --- App.jsx: map & region ---
{ zh: '区域定位', en: 'Region Locator' },
{ zh: '底图', en: 'Base Map' },
{ zh: '日志', en: 'Logs' },
{ zh: '暂无日志。', en: 'No logs.' },
{ zh: '收起', en: 'Collapse' },
{ zh: '当前定位', en: 'Current Location' },
{ zh: '定位中...', en: 'Locating...' },
{ zh: '定位到选中区域', en: 'Zoom to Region' },
{ zh: '清除定位高亮', en: 'Clear Highlight' },
{ zh: '可只选到省/市级进行定位。', en: 'Select province or city to locate.' },
{ zh: '可只选到省/市级,系统将自动使用当前选中层级边界。', en: 'Select province or city level; the system will use the selected boundary.' },
// --- App.jsx: pairing modal ---
{ zh: 'D-InSAR 配对参数', en: 'D-InSAR Pairing Parameters' },
{ zh: '配对提示', en: 'Pairing Info' },
{ zh: '回退模式', en: 'Fallback Mode' },
{ zh: '已选择', en: 'Selected' },
{ zh: '保存批次', en: 'Save Batch' },
{ zh: '清空结果', en: 'Clear Results' },
{ zh: '预览', en: 'Preview' },
{ zh: '全选', en: 'Select All' },
{ zh: '起始日期 (只考虑此日期后的影像)', en: 'Start Date (only images after this date)' },
{ zh: 'AOI 来源:', en: 'AOI Source:' },
{ zh: '上传SHP', en: 'Upload SHP' },
{ zh: '行政区选择', en: 'Region Selection' },
{ zh: '限定范围 (Shapefile,可选):', en: 'AOI Constraint (Shapefile, optional):' },
{ zh: '选择文件...', en: 'Select File...' },
{ zh: '行政区范围:', en: 'Region Boundary:' },
{ zh: 'AOI 覆盖率阈值 (0 表示不限制):', en: 'AOI Coverage Threshold (0 = unlimited):' },
{ zh: '成像模式一致', en: 'Consistent Imaging Mode' },
{ zh: '极化一致', en: 'Consistent Polarization' },
{ zh: '仅使用有精轨数据的影像', en: 'Only Precise-orbit Images' },
{ zh: '开始配对', en: 'Start Pairing' },
{ zh: '取消', en: 'Cancel' },
// --- App.jsx: PS modal ---
{ zh: '准备PS时序数据栈', en: 'Prepare PS Time-series Stack' },
{ zh: '研究区域来源:', en: 'Study Area Source:' },
{ zh: '研究区域 (Shapefile):', en: 'Study Area (Shapefile):' },
{ zh: '准备并导出', en: 'Prepare & Export' },
// --- App.jsx: province/city selects ---
{ zh: '-- 省级 --', en: '-- Province --' },
{ zh: '-- 地市 --', en: '-- City --' },
// --- App.jsx: misc UI ---
{ zh: '仅管理员可访问用户管理。', en: 'Admin access only.' },
{ zh: '仅管理员可访问审计日志。', en: 'Admin access only.' },
{ zh: '当前账号为只读用户,无法执行写操作。', en: 'Read-only account, no write access.' },
{ zh: '当前账号为只读权限,无法执行此操作。如需操作,请联系管理员升级权限。', en: 'Read-only account. Contact admin to request write access.' },
{ zh: '任务已入队,等待处理...', en: 'Task queued, pending...' },
// --- IDLAutomationPanel ---
{ zh: 'SARscape 处理中心', en: 'SARscape Processing Center' },
{ zh: '已安装', en: 'Installed' },
{ zh: '未检测到', en: 'Not Detected' },
{ zh: '运行中', en: 'Running' },
{ zh: '引擎', en: 'Engine' },
{ zh: '任务运行中', en: 'Task Running' },
{ zh: '强制解锁', en: 'Force Unlock' },
{ zh: '输入管理员密码', en: 'Enter admin password' },
{ zh: '确认取消', en: 'Confirm Cancel' },
{ zh: '按钮已锁定,等待任务完成', en: 'Buttons locked, waiting for task completion' },
{ zh: 'Task 状态总览', en: 'Task Status Overview' },
{ zh: '加载中...', en: 'Loading...' },
{ zh: '刷新', en: 'Refresh' },
{ zh: '填写下方数据目录后点击刷新', en: 'Enter data directory below and click Refresh' },
{ zh: '已导入', en: 'Imported' },
{ zh: '已处理', en: 'Processed' },
{ zh: '已提取', en: 'Extracted' },
{ zh: '结构', en: 'Structure' },
{ zh: '修改时间', en: 'Modified' },
{ zh: 'Step 1: 数据导入 (Import)', en: 'Step 1: Data Import' },
{ zh: '扫描目录下的 LuTan-1 原始数据 (*.meta.xml),转换为 ENVI SARscape 格式 (*.sml)。', en: 'Scan LuTan-1 raw data (*.meta.xml) and convert to ENVI SARscape format (*.sml).' },
{ zh: '支持 Task_*/master|slave 结构和平铺目录。', en: 'Supports Task_*/master|slave structure and flat directories.' },
{ zh: '数据目录 (root_dir)', en: 'Data Directory (root_dir)' },
{ zh: '最大处理数', en: 'Max Items' },
{ zh: '0 = 不限制', en: '0 = No limit' },
{ zh: '预检查', en: 'Pre-check' },
{ zh: '开始导入', en: 'Start Import' },
{ zh: 'Import 检查结果', en: 'Import Check Results' },
{ zh: 'Step 2: D-InSAR 生产', en: 'Step 2: D-InSAR Processing' },
{ zh: '对 Task_* 目录执行 D-InSAR 位移生成。', en: 'Execute D-InSAR displacement processing on Task_* directories.' },
{ zh: '未导入的数据将自动先执行 Import,再进行 D-InSAR 处理。', en: 'Unimported data will be auto-imported before D-InSAR processing.' },
{ zh: 'DEM 路径由系统配置管理,无需手动指定。', en: 'DEM path is managed by system configuration.' },
{ zh: '默认处理', en: 'Default Processing' },
{ zh: '自定义处理', en: 'Custom Processing' },
{ zh: '调用 ENVI SARscape metatask 一键执行全流程。参数:3×3 多视、默认自适应滤波、自动 GCP 精配准。', en: 'Runs ENVI SARscape metatask end-to-end: 3×3 multilooking, adaptive filtering, auto GCP co-registration.' },
{ zh: '逐步调用各处理模块,参数可控。多视:动态计算、GOLDSTEIN 滤波、自动 GCP、相干阈值 coh=0.05。', en: 'Step-by-step modules: dynamic multilooking, Goldstein filtering, auto GCP, coherence threshold 0.05.' },
{ zh: 'D-InSAR 检查结果', en: 'D-InSAR Check Results' },
{ zh: 'Step 3: 结果提取', en: 'Step 3: Result Extraction' },
{ zh: '将 D-InSAR 生产结果中的 disp 文件提取到扫描目录,以便系统识别。', en: 'Extract displacement files from D-InSAR results to the scan directory.' },
{ zh: '提取 Disp 结果', en: 'Extract Disp Results' },
{ zh: '目标目录', en: 'Target Directory' },
{ zh: '新增', en: 'Added' },
{ zh: '更新', en: 'Updated' },
{ zh: '跳过', en: 'Skipped' },
{ zh: '处理', en: 'Processed' },
{ zh: '任务历史', en: 'Run History' },
{ zh: '暂无运行记录', en: 'No run records' },
{ zh: '自动导入', en: 'Auto-imported' },
{ zh: '自定义', en: 'Custom' },
{ zh: '从列表移除', en: 'Remove' },
{ zh: '消息', en: 'Message' },
{ zh: '处理统计', en: 'Processing Statistics' },
{ zh: '近期运行结果', en: 'Recent Run Results' },
{ zh: '平均耗时 (秒)', en: 'Avg Duration (s)' },
{ zh: '平均耗时 (s)', en: 'Avg Duration (s)' },
{ zh: '结果入库趋势', en: 'Result Import Trend' },
{ zh: '入库数量', en: 'Imported Count' },
{ zh: '其他', en: 'Other' },
{ zh: '就绪', en: 'Ready' },
{ zh: '未就绪', en: 'Not Ready' },
{ zh: '状态', en: 'Status' },
{ zh: '查看日志', en: 'View Log' },
{ zh: '文件大小', en: 'File Size' },
{ zh: '已截断,仅显示末尾', en: 'Truncated, showing last' },
// --- IDLAutomationPanel: dynamic messages ---
{ zh: '执行失败', en: 'Execution failed' },
{ zh: '未知错误', en: 'Unknown error' },
{ zh: '只读账号无法提交任务。', en: 'Read-only account cannot submit tasks.' },
{ zh: '请填写数据目录。', en: 'Please enter data directory.' },
{ zh: '只读账号无法执行提取。', en: 'Read-only account cannot run extraction.' },
{ zh: '已自动触发结果扫描入库', en: 'Auto-triggered result scan' },
{ zh: '扫描入库触发失败', en: 'Result scan trigger failed' },
{ zh: '提取完成', en: 'Extraction complete' },
{ zh: '总览加载失败', en: 'Overview load failed' },
{ zh: '任务已强制取消,前端已解锁。', en: 'Task force-cancelled, UI unlocked.' },
{ zh: '强制解锁失败', en: 'Force unlock failed' },
{ zh: '任务已入队', en: 'Task queued' },
// --- HazardPointPanel ---
{ zh: '地质灾害点监测', en: 'Geological Hazard Monitoring' },
{ zh: '隐藏全部', en: 'Hide All' },
{ zh: '显示全部', en: 'Show All' },
{ zh: '同步中...', en: 'Syncing...' },
{ zh: '同步 Shapefile 数据', en: 'Sync Shapefile' },
{ zh: '搜索编号、名称、市县...', en: 'Search ID, name, city...' },
{ zh: '未找到匹配的灾害点', en: 'No matching hazard points' },
{ zh: '获取灾害点失败', en: 'Failed to load hazard points' },
{ zh: '当前账号为只读模式,无法同步灾害点。', en: 'Read-only account cannot sync hazard points.' },
{ zh: '正在发起灾害点同步任务...', en: 'Starting hazard point sync...' },
{ zh: '正在同步灾害点数据...', en: 'Syncing hazard point data...' },
{ zh: '同步失败', en: 'Sync failed' },
// --- DataMonitorPanel ---
{ zh: '数据监控面板', en: 'Data Monitor' },
{ zh: '路径摘要', en: 'Path Summary' },
{ zh: '未配置', en: 'Not configured' },
{ zh: '监控模式', en: 'Monitor Mode' },
{ zh: '手动', en: 'Manual' },
{ zh: '配置', en: 'Config' },
{ zh: '归档解包', en: 'Archive Unpack' },
{ zh: '来源目录', en: 'Source Dir' },
{ zh: '轨道', en: 'Orbit' },
{ zh: '活动任务', en: 'Active Tasks' },
{ zh: '当前无活动任务。', en: 'No active tasks.' },
{ zh: '扫描雷达数据', en: 'Scan Radar Data' },
{ zh: '扫描精轨数据', en: 'Scan Orbit Data' },
{ zh: '扫描D-InSAR结果', en: 'Scan D-InSAR Results' },
{ zh: '实时日志', en: 'Live Logs' },
{ zh: '暂无日志...', en: 'No logs...' },
{ zh: '运行中...', en: 'Running...' },
{ zh: '运行解包', en: 'Run Unpack' },
{ zh: '只读模式', en: 'Read-only' },
{ zh: '当前账号为只读模式,无法触发扫描。', en: 'Read-only account cannot trigger scans.' },
{ zh: '当前账号为只读模式,无法触发解包任务。', en: 'Read-only account cannot trigger unpack.' },
{ zh: '解包任务启动中...', en: 'Starting unpack task...' },
{ zh: '解包任务已启动', en: 'Unpack task started' },
{ zh: '雷达数据', en: 'Radar data' },
{ zh: '精轨数据', en: 'Orbit data' },
{ zh: 'D-InSAR结果', en: 'D-InSAR results' },
{ zh: '仅手动模式。路径从 .env 读取;如需修改请更新 .env 并重启后端。', en: 'Manual mode. Paths loaded from .env; update .env and restart backend to modify.' },
{ zh: '未加载到监控状态,请检查后端 /api/monitor/status。', en: 'Monitor status not loaded. Check backend /api/monitor/status.' },
{ zh: '触发失败', en: 'Trigger failed' },
// --- DataCopierPanel ---
{ zh: '已完成', en: 'Completed' },
{ zh: 'PS 分发', en: 'PS Distribution' },
{ zh: 'D-InSAR 分发', en: 'D-InSAR Distribution' },
{ zh: '当前账号为只读模式,无法发起复制任务。', en: 'Read-only account cannot run copy tasks.' },
{ zh: '当前账号为只读模式,无法执行复制任务。', en: 'Read-only account cannot run copy tasks.' },
{ zh: '请选择批次并设置目标目录。', en: 'Select batch and set target directory.' },
{ zh: '请至少选择一个任务状态。', en: 'Select at least one task status.' },
{ zh: '启动失败', en: 'Start failed' },
{ zh: '选择批次', en: 'Select Batch' },
{ zh: '-- 请选择 --', en: '-- Select --' },
{ zh: '任务状态筛选', en: 'Task Status Filter' },
{ zh: '目标目录', en: 'Target Directory' },
{ zh: '复制中...', en: 'Copying...' },
{ zh: '开始复制', en: 'Start Copy' },
{ zh: '等待任务...', en: 'Waiting for task...' },
{ zh: '默认仅复制"已完成"项。', en: 'Only "Completed" items are copied by default.' },
// --- WaterMonitorPanel (status labels) ---
{ zh: '等待中', en: 'Pending' },
{ zh: '完成', en: 'Done' },
{ zh: '共', en: 'Total' },
// --- App.jsx: log messages ---
{ zh: '搜索全部源数据', en: 'Search All' },
];
const ZH_TO_EN = [...TRANSLATION_PAIRS].sort((a, b) => b.zh.length - a.zh.length);
const EN_TO_ZH = [...TRANSLATION_PAIRS].sort((a, b) => b.en.length - a.en.length);
const EXCEPTION_HINT_PATTERNS = [
/\btraceback\b/i,
/\b(?:[A-Za-z_]\w*)(?:Error|Exception)\b/,
/\bNoneType\b/,
/\bobject is not callable\b/i,
/File "[^"]+", line \d+/,
/\bat\s+\S+\s+\([^)]*:\d+:\d+\)/,
/\bASGI\b/,
/\buvicorn\b/i,
/\bstatus_code\b/i,
/\bSQLSTATE\b/i,
];
const escapeForRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const shouldBypassTranslation = (text) => EXCEPTION_HINT_PATTERNS.some((pattern) => pattern.test(text));
const replaceAllPairs = (text, pairs, fromKey, toKey) => {
let output = text;
pairs.forEach((item) => {
const source = item[fromKey];
const target = item[toKey];
if (!source) return;
output = output.replace(new RegExp(escapeForRegExp(source), 'g'), target);
});
return output;
};
export const translateText = (text, language) => {
if (typeof text !== 'string' || !text) return text;
if (shouldBypassTranslation(text)) return text;
if (language === 'en') {
return replaceAllPairs(text, ZH_TO_EN, 'zh', 'en');
}
return replaceAllPairs(text, EN_TO_ZH, 'en', 'zh');
};
export const SUPPORTED_LANGUAGES = ['zh', 'en'];