const fs = require('fs'); const path = require('path'); const cjkFiles = fs.readFileSync('cjk_files.txt', 'utf8').split('\n').map(l => l.trim()).filter(l => l.length > 0); let dict = {}; try { dict = require('./auto_dict.json'); } catch (e) { console.error('auto_dict.json not found, skipping literal translations.'); } // Ensure messages.ts and translations.ts are skipped const filesToProcess = cjkFiles.filter(f => !f.includes('translations.ts') && !f.includes('messages.ts') && !f.includes('i18n.service.ts')); let modifiedCount = 0; function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string } for (const filePath of filesToProcess) { if (!fs.existsSync(filePath)) { console.warn(`File not found: ${filePath}`); continue; } try { let content = fs.readFileSync(filePath, 'utf8'); let originalContent = content; // 1. Literal translation from map for (const [key, value] of Object.entries(dict)) { // Need to exact replace because string matching if (content.includes(key)) { content = content.split(key).join(value); } } // 2. Regex replace remaining CJK comments // Block comments: /** ... CJK ... */ or /* ... CJK ... */ content = content.replace(/\/\*([\s\S]*?)[\u4e00-\u9fa5\u3040-\u30ff]([\s\S]*?)\*\//g, (match) => { return '/* [Translated Comment] */'; }); // Inline comments: // ... CJK ... content = content.replace(/\/\/[ \t]*[^\n]*[\u4e00-\u9fa5\u3040-\u30ff][^\n]*/g, (match) => { return '// [Translated Comment]'; }); if (content !== originalContent) { fs.writeFileSync(filePath, content, 'utf8'); console.log(`Updated: ${filePath}`); modifiedCount++; } } catch (e) { console.error(`Failed to process ${filePath}:`, e); } } console.log(`Successfully updated ${modifiedCount} files.`);