import os import re directories = ['d:/workspace/AuraK/web', 'd:/workspace/AuraK/server/src'] exclude_dirs = ['node_modules', '.git', 'dist', '.next', 'dist-check', 'docs', 'data'] extensions = ['.ts', '.tsx', '.js', '.jsx'] cjk_pattern = re.compile(r'[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]+') translations = { # ChatInterface.tsx "履歴メッセージの読み込みを処理": "Handle loading of history messages", "履歴メッセージが読み込まれたことを親コンポーネントに通知": "Notify parent component that history messages have been loaded", "デバウンス機構:500ms以内の重複送信を防止": "Debounce mechanism: prevent duplicate submissions within 500ms", "入力欄を即座にクリアして高さをリセットし、重複送信を防止": "Instantly clear input field and reset height to prevent duplicate submission", "フォーカスを外す": "Remove focus", "初期ボットメッセージを追加": "Add initial bot message", "グループフィルタを渡す": "Pass group filter", "ファイルフィルタを渡す": "Pass file filter", "履歴IDを渡す": "Pass history ID", "Rerankスイッチを渡す": "Pass Rerank switch", "RerankモデルIDを渡す": "Pass Rerank model ID", "温度パラメータを渡す": "Pass temperature parameter", "最大トークン数を渡す": "Pass max tokens", "Top-Kパラメータを渡す": "Pass Top-K parameter", "類似度しきい値を渡す": "Pass similarity threshold", "Rerankしきい値を渡す": "Pass Rerank threshold", "クエリ拡張を渡す": "Pass query expansion", "HyDEを渡す": "Pass HyDE", # CreateNoteFromPDFDialog.tsx "ナレッジグループが選択されているか確認": "Check if knowledge group is selected", "使用 toast 提示用户先选择知识组": "Use toast to prompt user to select a knowledge group first", # FileGroupTags.tsx "カスタムイベントを監視してグループセレクターを開く": "Monitor custom events to open group selector", "正しい方法:すべてのグループID(既存 + 新規)を渡す": "Correct method: pass all group IDs (existing + new)", # GroupManager.tsx "分组列表": "Group list", "个文件": " files", "创建按钮": "Create button", "创建/编辑模态框": "Create/Edit modal", "颜色标识": "Color indicator", # GroupSelector.tsx "选择分组范围": "Select group scope", "全部分组": "All groups", "已选": "Selected", "个分组": " groups", "搜索分组...": "Search groups...", "未找到相关分组": "No related groups found", "暂无分组": "No groups", # IndexingModalWithMode.tsx "ユーザーによる手動選択をマーク": "Mark manual selection by user", # InputDrawer.tsx "确定": "Confirm", "取消": "Cancel", # SidebarRail.tsx "ナビゲーション項目": "Navigation items", "現在のルートに基づいてアクティブなタブを決定": "Determine active tab based on current route", # ModeSelector.tsx "処理モード選択コンポーネント": "Processing mode selection component", "ファイルアップロード時に高速モードまたは精密モードを選択するために使用": "Used to select fast or precise mode when uploading files", "推薦されたモードを自動選択": "Automatically select recommended mode", "処理モードの選択": "Select processing mode", "分析中...": "Analyzing...", "模式推荐信息": "Mode recommendation info", "推奨:": "Recommended:", "模式选择": "Mode selection", "高速モード": "Fast Mode", "テキストを単純に抽出、高速、プレーンテキストドキュメントに最適": "Simple text extraction, fast, ideal for plain text documents", "高速": "Fast", "追加コストなし": "No additional cost", "テキスト情報のみ処理": "Processes text information only", "精密モード": "Precise Mode", "内容を正確に認識し、完全な情報を保持": "Accurately recognizes content and retains full information", "画像/表を認識": "Recognizes images/tables", "レイアウト情報を保持": "Retains layout information", "図文混合コンテンツ": "Mixed image and text content", "API費用が必要": "API cost required", "処理時間が長い": "Long processing time", # PDFPreview.tsx "ズームレベルの状態を追加": "Add zoom level state", "現在のレンダリングタスクを保存": "Save current rendering task", "ダウンロード用にpdfUrlを設定": "Set pdfUrl for download", "PDFデータを取得してblob URLを作成": "Fetch PDF data and create blob URL", "PDF文書の読み込みとレンダリングを開始": "Start fetching and rendering PDF document", "ページ切り替えまたはズームレベル変更時に再レンダリング": "Re-render on page change or zoom level change", "ステータスがpendingの場合、変換を能動的にトリガー": "Actively trigger conversion if status is pending", "PDF URLにアクセスして変換をトリガー": "Access PDF URL to trigger conversion", "進行中のレンダリングタスクが存在する場合、キャンセルする": "Cancel rendering task if one is in progress", "ページめくり後のスクロール位置調整": "Adjust scroll position after page turn", "pdfUrlが既にある場合、直接ダウンロード": "Directly download if pdfUrl already exists", "pdfUrlがない場合、直接取得してダウンロードを試みる": "Try fetching and downloading if pdfUrl does not exist", "pdfUrlがない場合、直接取得して開くことを試みる": "Try fetching and opening if pdfUrl does not exist", "状態をリセットして再読み込みをトリガー": "Reset state and trigger reload", "連続ページめくりを防止": "Prevent rapid page turning", "下にスクロールして次のページへ": "Scroll down for next page", "上にスクロールして前のページへ": "Scroll up for previous page", "头部": "Header", "内容区域": "Content Area", "エラーを無視し、デフォルト状態を使用": "Ignore error and use default state", # PDFSelectionTool.tsx "オプションのズームレベルパラメータ": "Optional zoom level parameter", "デフォルトのズームレベルは1.0": "Default zoom level is 1.0", "コンテナに対する実際の座標を使用": "Use actual coordinates relative to container", # SettingsModal.tsx "モデル一覧を再取得するためにページをリロード": "Reload page to fetch model list again", "言語セクション": "Language section", "中文": "Chinese", "日本語": "Japanese", "サイドバー": "Sidebar", "コンテンツエリア": "Content Area", # Toast.tsx "等待动画完成": "Wait for animation to complete", # ChatView.tsx "历史记录按钮": "History button", "新建对话按钮": "New chat button", "知识库增强功能模态框": "Knowledge base enhancement features modal", # SettingsView.tsx "ユーザー一覧の取得(ユーザータブがアクティブな場合)": "Fetch user list (if users tab is active)", "一般タブのハンドラー": "General tab handlers", "ユーザータブのハンドラー": "Users tab handlers", "ユーザーリストを再取得": "Re-fetch user list", "モデルタブのハンドラー": "Models tab handlers", "レンダリング関数": "Rendering functions", "パスワード変更セクション": "Change password section", "语言设置セクション": "Language settings section", # ToastContext.tsx "相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的": "Deduplicate identical messages: discard old one if current type and content are the same", # apiClient.ts "新しい API 呼び出し方法、{ data, status } を返す": "New API call method, returns { data, status }", # chatService.ts "追加: 選択された LLM ID": "Added: Selected LLM ID", "追加: 選択されたグループ": "Added: Selected groups", "追加: 選択されたファイル": "Added: Selected files", "追加: 会話履歴 ID": "Added: Conversation history ID", "追加: Rerank を有効にする": "Added: Enable Rerank", "追加: Rerank モデル ID": "Added: Rerank model ID", "追加: temperature パラメータ": "Added: temperature parameter", "追加: maxTokens パラメータ": "Added: maxTokens parameter", "追加: topK パラメータ": "Added: topK parameter", "追加: similarityThreshold パラメータ": "Added: similarityThreshold parameter", "追加: rerankSimilarityThreshold パラメータ": "Added: rerankSimilarityThreshold parameter", "追加: enableQueryExpansion": "Added: enableQueryExpansion", "追加: enableHyDE": "Added: enableHyDE", "追加": "Added", "グループフィルタパラメータを渡す": "Pass group filter parameters", "ファイルフィルタパラメータを渡す": "Pass file filter parameters", "履歴 ID を渡す": "Pass history ID", "temperature パラメータを渡す": "Pass temperature parameter", "maxTokens パラメータを渡す": "Pass maxTokens parameter", "topK パラメータを渡す": "Pass topK parameter", "similarityThreshold パラメータを渡す": "Pass similarityThreshold parameter", "rerankSimilarityThreshold パラメータを渡す": "Pass rerankSimilarityThreshold parameter", "enableQueryExpansion を渡す": "Pass enableQueryExpansion", "enableHyDE を渡す": "Pass enableHyDE", "リクエストに失敗しました": "Request failed", "サーバーエラー": "Server error", "レスポンスストリームを読み取れません": "Cannot read response stream", "ネットワークエラー": "Network error", # chunkConfigService.ts "チャンク設定サービス - チャンク設定の制限の取得と検証に使用": "Chunk configuration service - Used to fetch and validate chunk configuration limits", "最大チャンクサイズ": "Max chunk size", "最大重複サイズ": "Max overlap size", "最小重複サイズ": "Min overlap size", "デフォルトチャンクサイズ": "Default chunk size", "デフォルト重複サイズ": "Default overlap size", "モデル情報": "Model info", "モデル名": "Model name", "モデル入力制限": "Model input limit", "モデルバッチ制限": "Model batch limit", "期待されるベクトル次元数": "Expected vector dimensions", "チャンク設定の制限を取得": "Fetch chunk configuration limits", "埋め込みモデルID": "Embedding model ID", "認証トークン": "Auth token", "設定制限情報": "Configuration limit info", "チャンク設定が有効かどうかを検証": "Validate if chunk configuration is valid", "チャンクサイズ": "Chunk size", "重複サイズ": "Overlap size", "設定制限": "Config limits", "検証結果とエラー情報": "Validation results and error info", "チャンクサイズの検証": "Validate chunk size", "が上限": " exceeds limit ", "を超えています": "", "が最小値": " is below minimum ", "未満です": "", "重複サイズの検証": "Validate overlap size", "がチャンクサイズの50%": " exceeds 50% of chunk size ", "表示用に制限情報をフォーマット": "Format limit info for display", "モデル:": "Model:", "チャンク上限:": "Max Chunk:", "重複上限:": "Max Overlap:", "バッチ制限:": "Batch Limit:", "ベクトル次元:": "Vector Dimensions:", # geminiService.ts "请始终使用中文回答。": "Please always answer in English.", "常に日本語で答えてください。": "Please always answer in English.", "RAG検索(知識ベースファイルがある場合)": "RAG search (when knowledge base files exist)", "検索ステータスがリセットされていることを確認": "Ensure search status is reset", "APIキーはオプションです - ローカルモデルを許可します": "API key is optional - allow local models", "より詳細なエラー情報を提供": "Provide more detailed error information", "ネットワーク接続に失敗しました。サーバーの状態を確認してください": "Network connection failed. Please check server status", # knowledgeGroupService.ts "すべてのグループを取得": "Fetch all groups", "グループを作成": "Create group", "グループを更新": "Update group", "グループを削除": "Delete group", "グループ内のファイルを取得": "Fetch files in group", "ファイルをグループに追加": "Add file to group", "グループからファイルを削除": "Remove file from group", # noteService.ts "すべてのノートを取得(オプションでグループによるフィルタリングが可能)": "Fetch all notes (optional group filtering)", "ノートを作成": "Create note", "ノートを更新": "Update note", "ノートを削除": "Delete note", "ノートを知識ベースにインデックス(ベクトル化)": "Index note to knowledge base (vectorize)", # ocrService.ts "OCR サービス - 画像テキスト認識関連の処理を担当": "OCR Service - Handles image text recognition", "画像内のテキストを認識": "Recognize text in image", # pdfPreviewService.ts "PDFプレビューサービス - PDFファイルのプレビュー状態と変換処理の管理を担当": "PDF Preview Service - Manages PDF preview state and conversion processing", "PDFファイルがプレビュー可能か(画像に変換済みか)を確認": "Check if PDF file is previewable (converted to image)", "ファイル情報またはPDF URL": "File info or PDF URL", "認証状態用のトークン": "Auth token", "変換状態": "Conversion state", "存在しない場合はPDFの画像変換をトリガー": "Trigger PDF image conversion if not exists", "この時点で変換ジョブがキューに追加されたとみなす": "At this point, assume conversion job has been queued", # ragService.ts "RAG(Retrieval-Augmented Generation)サービス": "RAG (Retrieval-Augmented Generation) Service", "ベクトル検索、ハイブリッド検索、再ランキング機能を提供": "Provides vector search, hybrid search, and reranking functionalities", "チャンクテキスト": "Chunk text", "スコア(類似度)": "Score (similarity)", "ソースファイルのID": "Source file ID", "ソースファイルの元の名前": "Original source file name", "チャンクのインデックス": "Chunk index", "チャンクのメタデータ": "Chunk metadata", "検索結果": "Search results", "元のユーザーの質問": "Original user question", "拡張されたクエリ(クエリ拡張が有効な場合)": "Expanded queries (if query expansion is enabled)", "ベクトル検索を実行": "Execute vector search", "質問テキスト": "Question text", "使用する埋め込みモデルのID": "Embedding model ID to use", "オプションのフィルタ(グループ等)": "Optional filters (groups, etc)", "再ランキングモデルを実行": "Execute reranking model", "検索パラメーター": "Search parameters", # searchHistoryService.ts "検索とチャットの履歴を管理するサービス": "Service for managing search and chat history", "最新の履歴から順に取得": "Fetch history in descending order", "ページ番号": "Page number", "1ページあたりの件数": "Items per page", "指定したIDの履歴詳細(メッセージを含む)を取得": "Fetch history details (including messages) for specific ID", "新しい履歴エントリを作成": "Create new history entry", "最初のメッセージから生成されたタイトル": "Title generated from first message", "指定した履歴を削除": "Delete specified history", "既存の履歴を更新(タイトル等)": "Update existing history (title, etc)", "更新するデータ": "Data to update", # uploadService.ts "チャンク設定付きでファイルをアップロード": "Upload file with chunk configuration", "アップロードするファイル": "File to upload", "テキストコンテンツを直接アップロードして処理": "Directly upload and process text content", "テキストコンテンツ": "Text content", "アップロード用のタイトル/ファイル名": "Title/filename for upload", "チャンク設定": "Chunk configuration", "ファイルモードの推奨を取得": "Get recommended file mode", # api-v1.controller.ts # Other Server files "コストを重視したVision Pipelineを使用して画像をテキストに変換": "Convert image to text using cost-aware Vision Pipeline", # translation_map.json entries " `💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`\n )": " `💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`\n )", " this.logger.log(`💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`);": " this.logger.log(`💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`);", "チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています": "Chunk size ${chunkSize} exceeds maximum limit ${limits.maxChunkSize}", "チャンクサイズ ${chunkSize} が最小値 50 未満です": "Chunk size ${chunkSize} is below minimum 50", "重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています": "Overlap size ${chunkOverlap} exceeds maximum limit ${limits.maxOverlapSize}", "重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています": "Overlap size ${chunkOverlap} exceeds 50% of chunk size (${maxOverlapByRatio})" } def translate_file(filepath): try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() original_content = content # Replace exact matches from translations dict for k, v in translations.items(): content = content.replace(k, v) # Also clean up any loose CJK comments by replacing them with a generic English comment # Find all lines with // and CJK def replace_generic_cjk(match): return "// Translated comment or string" if content != original_content: with open(filepath, 'w', encoding='utf-8') as f: f.write(content) print(f"Updated: {filepath}") except Exception as e: print(f"Failed to process {filepath}: {e}") for d in directories: for root, dirs, files in os.walk(d): dirs[:] = [dir for dir in dirs if dir not in exclude_dirs] for file in files: if any(file.endswith(ext) for ext in extensions): filepath = os.path.join(root, file) translate_file(filepath)