const fs = require('fs'); const path = require('path'); const dir = path.join(__dirname, '..', 'public', 'intl', 'messages'); const enUS = JSON.parse(fs.readFileSync(path.join(dir, 'en-US.json'), 'utf8')); const translations = { 'zh-CN': { label: { 'campaign': '推广活动', 'exclude-bounce': '排除跳出', 'hour': '小时', 'minute': '分钟', 'month': '月', 'number-of-records': '{x} {x, plural, one {条记录} other {条记录}}', 'sms': '短信', 'source': '来源', 'term': '搜索词', 'unique-events': '独立事件', 'url': 'URL', 'utm': 'UTM', 'utm-campaign': 'UTM 推广活动', 'utm-content': 'UTM 内容', 'utm-medium': 'UTM 媒介', 'utm-source': 'UTM 来源', 'utm-term': 'UTM 关键词', 'version': '版本' }, message: {} }, 'zh-TW': { label: { 'account': '帳號', 'action': '動作', 'add-link': '新增連結', 'add-pixel': '新增像素', 'analysis': '分析', 'application': '應用程式', 'audience': '受眾', 'campaign': '活動', 'channel': '頻道', 'channels': '頻道', 'chart': '圖表', 'cohorts': '群組', 'criteria': '條件', 'currency': '貨幣', 'destination-url': '目標網址', 'direct': '直接', 'distinct-id': '唯一識別碼', 'documentation': '說明文件', 'does-not-include': '不包含', 'doest-not-exist': '不存在', 'download': '下載', 'email': '電子郵件', 'environment': '環境', 'event-name': '事件名稱', 'exclude-bounce': '排除跳出', 'exists': '存在', 'first-click': '首次點擊', 'funnels': '漏斗', 'grouped': '已分組', 'growth': '成長', 'hostname': '主機名稱', 'hour': '小時', 'includes': '包含', 'insight': '洞察', 'invalid-url': '無效的網址', 'is-false': '為否', 'is-true': '為是', 'journeys': '使用者旅程', 'last-click': '最後點擊', 'link': '連結', 'links': '連結', 'location': '位置', 'medium': '媒介', 'minute': '分鐘', 'model': '型號', 'month': '月', 'ok': '確定', 'online': '線上', 'organic-search': '自然搜尋', 'organic-shopping': '自然購物', 'organic-social': '自然社群', 'organic-video': '自然影片', 'other': '其他', 'page': '頁面', 'paid-ads': '付費廣告', 'paid-search': '付費搜尋', 'paid-shopping': '付費購物', 'paid-social': '付費社群', 'paid-video': '付費影片', 'pixel': '像素', 'pixels': '像素', 'preferences': '偏好設定', 'profiles': '個人檔案', 'referral': '推薦', 'remaining': '剩餘', 'save-cohort': '儲存群組', 'save-segment': '儲存區段', 'screen': '螢幕', 'segment': '區段', 'segments': '區段', 'select-filter': '選取篩選條件', 'session-data': '工作階段資料', 'share': '分享', 'sms': '簡訊', 'source': '來源', 'sources': '來源', 'support': '支援', 'switch-account': '切換帳號', 'table': '表格', 'tag': '標籤', 'tags': '標籤', 'team-settings': '團隊設定', 'term': '搜尋詞', 'terms': '條款', 'traffic': '流量', 'unique-events': '不重複事件', 'url': 'URL', 'utm': 'UTM', 'utm-campaign': 'UTM 活動', 'utm-content': 'UTM 內容', 'utm-medium': 'UTM 媒介', 'utm-source': 'UTM 來源', 'utm-term': 'UTM 關鍵字', 'version': '版本' }, message: { 'bad-request': '錯誤的請求', 'forbidden': '禁止存取', 'not-found': '找不到', 'nothing-selected': '尚未選取任何項目。', 'sever-error': '伺服器錯誤', 'unauthorized': '未經授權' } }, 'ja-JP': { label: { 'account': 'アカウント', 'action': 'アクション', 'add-link': 'リンクを追加', 'add-pixel': 'ピクセルを追加', 'analysis': '分析', 'application': 'アプリケーション', 'audience': 'オーディエンス', 'campaign': 'キャンペーン', 'channel': 'チャネル', 'chart': 'チャート', 'cohorts': 'コホート', 'criteria': '条件', 'destination-url': '遷移先URL', 'documentation': 'ドキュメント', 'download': 'ダウンロード', 'environment': '環境', 'exclude-bounce': '直帰を除外', 'growth': '成長', 'hour': '時間', 'invalid-url': '無効なURL', 'link': 'リンク', 'location': '場所', 'minute': '分', 'month': '月', 'number-of-records': '{x} {x, plural, one {件} other {件}}', 'ok': 'OK', 'online': 'オンライン', 'os': 'OS', 'pixel': 'ピクセル', 'powered-by': '{name} 提供', 'preferences': '環境設定', 'profiles': 'プロフィール', 'referral': 'リファラル', 'save-cohort': 'コホートを保存', 'save-segment': 'セグメントを保存', 'screen': 'スクリーン', 'segment': 'セグメント', 'segments': 'セグメント', 'sms': 'SMS', 'source': 'ソース', 'support': 'サポート', 'switch-account': 'アカウントを切り替え', 'table': 'テーブル', 'term': '検索語句', 'traffic': 'トラフィック', 'unique-events': 'ユニークイベント', 'url': 'URL', 'utm': 'UTM', 'utm-campaign': 'UTM キャンペーン', 'utm-content': 'UTM コンテンツ', 'utm-medium': 'UTM メディア', 'utm-source': 'UTM ソース', 'utm-term': 'UTM ターム', 'version': 'バージョン' }, message: { 'bad-request': '不正なリクエスト', 'forbidden': 'アクセス禁止', 'not-found': '見つかりません', 'nothing-selected': '何も選択されていません。', 'sever-error': 'サーバーエラー', 'unauthorized': '認証が必要です' } }, 'ko-KR': { label: { 'account': '계정', 'action': '작업', 'add-link': '링크 추가', 'add-pixel': '픽셀 추가', 'analysis': '분석', 'application': '애플리케이션', 'audience': '잠재고객', 'campaign': '캠페인', 'channel': '채널', 'chart': '차트', 'cohorts': '코호트', 'criteria': '기준', 'destination-url': '도착 URL', 'documentation': '문서', 'download': '다운로드', 'environment': '환경', 'exclude-bounce': '이탈 제외', 'growth': '성장', 'hour': '시간', 'invalid-url': '잘못된 URL', 'link': '링크', 'location': '위치', 'minute': '분', 'month': '월', 'online': '온라인', 'pixel': '픽셀', 'powered-by': '{name} 제공', 'preferences': '환경설정', 'profiles': '프로필', 'referral': '추천', 'save-cohort': '코호트 저장', 'save-segment': '세그먼트 저장', 'screen': '화면', 'segment': '세그먼트', 'segments': '세그먼트', 'sms': 'SMS', 'source': '소스', 'support': '지원', 'switch-account': '계정 전환', 'table': '표', 'term': '검색어', 'traffic': '트래픽', 'unique-events': '고유 이벤트', 'url': 'URL', 'utm': 'UTM', 'utm-campaign': 'UTM 캠페인', 'utm-content': 'UTM 콘텐츠', 'utm-medium': 'UTM 매체', 'utm-source': 'UTM 소스', 'utm-term': 'UTM 검색어', 'version': '버전' }, message: { 'bad-request': '잘못된 요청', 'forbidden': '접근 금지', 'not-found': '찾을 수 없음', 'nothing-selected': '선택된 항목이 없습니다.', 'sever-error': '서버 오류', 'unauthorized': '인증되지 않음' } }, 'vi-VN': { label: { 'account': 'Tài khoản', 'action': 'Hành động', 'add-link': 'Thêm liên kết', 'add-pixel': 'Thêm pixel', 'analysis': 'Phân tích', 'application': 'Ứng dụng', 'audience': 'Đối tượng', 'campaign': 'Chiến dịch', 'channel': 'Kênh', 'chart': 'Biểu đồ', 'cohorts': 'Nhóm thuần tập', 'criteria': 'Tiêu chí', 'destination-url': 'URL đích', 'documentation': 'Tài liệu', 'download': 'Tải xuống', 'email': 'Email', 'environment': 'Môi trường', 'exclude-bounce': 'Loại trừ thoát trang', 'growth': 'Tăng trưởng', 'hour': 'Giờ', 'invalid-url': 'URL không hợp lệ', 'link': 'Liên kết', 'location': 'Vị trí', 'minute': 'Phút', 'month': 'Tháng', 'ok': 'OK', 'pixel': 'Pixel', 'preferences': 'Tùy chọn', 'profiles': 'Hồ sơ', 'save-cohort': 'Lưu nhóm thuần tập', 'save-segment': 'Lưu phân đoạn', 'screen': 'Màn hình', 'segment': 'Phân đoạn', 'segments': 'Phân đoạn', 'sms': 'SMS', 'source': 'Nguồn', 'support': 'Hỗ trợ', 'switch-account': 'Chuyển tài khoản', 'table': 'Bảng', 'term': 'Từ khóa', 'traffic': 'Lưu lượng truy cập', 'unique-events': 'Sự kiện duy nhất', 'url': 'URL', 'utm': 'UTM', 'utm-campaign': 'UTM Chiến dịch', 'utm-content': 'UTM Nội dung', 'utm-medium': 'UTM Phương tiện', 'utm-source': 'UTM Nguồn', 'utm-term': 'UTM Từ khóa', 'version': 'Phiên bản', 'website': 'Trang web' }, message: {} } }; for (const [locale, trans] of Object.entries(translations)) { const filePath = path.join(dir, locale + '.json'); const data = JSON.parse(fs.readFileSync(filePath, 'utf8')); let count = 0; for (const [section, keys] of Object.entries(trans)) { for (const [key, value] of Object.entries(keys)) { if (data[section] && key in data[section]) { data[section][key] = value; count++; } } } const sorted = {}; for (const section of Object.keys(enUS)) { if (data[section]) { sorted[section] = {}; for (const key of Object.keys(enUS[section])) { if (key in data[section]) sorted[section][key] = data[section][key]; } for (const key of Object.keys(data[section])) { if (!(key in sorted[section])) sorted[section][key] = data[section][key]; } } } fs.writeFileSync(filePath, JSON.stringify(sorted, null, 2) + '\n', 'utf8'); console.log('Updated ' + locale + ': ' + count + ' keys'); }