/* AI Project Universe V6.31 — native-safe authoritative project translation */
(()=>{
  'use strict';
  if(window.__APU_COMPLETE_PROJECT_TRANSLATION_V631__)return;
  window.__APU_COMPLETE_PROJECT_TRANSLATION_V631__=true;

  const LANGS=new Set(['id','en','ms','de','vi','zh','ja']);
  const LOCALES={id:'id-ID',en:'en-GB',ms:'ms-MY',de:'de-DE',vi:'vi-VN',zh:'zh-CN',ja:'ja-JP'};
  const CACHE_KEY='apu-v631-complete-translation-cache';
  const originalText=new WeakMap();
  const originalAttrs=new WeakMap();
  const expectedText=new WeakMap();
  const expectedAttrs=new WeakMap();
  let language=normalize(readLanguage());
  let runId=0,applying=false,observer=null,scanTimer=0;
  const pending=new Set();
  const memory=new Map();

  const exact={
    'Academic Evidence Hub':['Pusat Bukti Akademik','Academic Evidence Hub','Hab Bukti Akademik','Hub für akademische Nachweise','Trung tâm Minh chứng Học thuật','学术证明中心','学術エビデンスハブ'],
    'Graduate Applicant 2025 – UTM / ETH Zurich / MIT / Tsinghua / Aizu':['Pelamar Pascasarjana 2025 – UTM / ETH Zurich / MIT / Tsinghua / Aizu','Graduate Applicant 2025 – UTM / ETH Zurich / MIT / Tsinghua / Aizu','Pemohon Pascasiswazah 2025 – UTM / ETH Zurich / MIT / Tsinghua / Aizu','Bewerber für ein Graduiertenstudium 2025 – UTM / ETH Zürich / MIT / Tsinghua / Aizu','Ứng viên sau đại học 2025 – UTM / ETH Zurich / MIT / Tsinghua / Aizu','2025年研究生申请者 – UTM / ETH Zurich / MIT / Tsinghua / Aizu','2025年大学院志願者 – UTM / ETH Zurich / MIT / Tsinghua / Aizu'],
    'AI Researcher in Training · Software Engineer · IT Practitioner':['Peneliti AI dalam Pelatihan · Software Engineer · Praktisi TI','AI Researcher in Training · Software Engineer · IT Practitioner','Penyelidik AI dalam Latihan · Jurutera Perisian · Pengamal IT','KI-Forscher in Ausbildung · Softwareentwickler · IT-Praktiker','Nhà nghiên cứu AI đang đào tạo · Kỹ sư phần mềm · Chuyên viên CNTT','人工智能研究员（培训中）· 软件工程师 · IT 从业者','研修中のAI研究者・ソフトウェアエンジニア・IT実務家'],
    'View Projects':['Lihat Proyek','View Projects','Lihat Projek','Projekte ansehen','Xem dự án','查看项目','プロジェクトを見る'],
    'Research Statement':['Pernyataan Riset','Research Statement','Pernyataan Penyelidikan','Forschungserklärung','Tuyên bố nghiên cứu','研究陈述','研究ステートメント'],
    'Explore the Evidence Hub':['Jelajahi Pusat Bukti','Explore the Evidence Hub','Terokai Hab Bukti','Evidence Hub erkunden','Khám phá Trung tâm Minh chứng','浏览证明中心','エビデンスハブを探索'],
    'Projects':['Proyek','Projects','Projek','Projekte','Dự án','项目','プロジェクト'],
    'Curriculum Vitae':['Daftar Riwayat Hidup','Curriculum Vitae','Curriculum Vitae','Lebenslauf','Sơ yếu lý lịch','个人简历','履歴書'],
    'Certificates':['Sertifikat','Certificates','Sijil','Zertifikate','Chứng chỉ','证书','証明書'],
    'Research':['Riset','Research','Penyelidikan','Forschung','Nghiên cứu','研究','研究'],
    'Evidence Pack':['Paket Bukti','Evidence Pack','Pakej Bukti','Nachweispaket','Bộ minh chứng','证明材料包','エビデンスパック'],
    'Admission Docs':['Dokumen Penerimaan','Admission Docs','Dokumen Kemasukan','Bewerbungsunterlagen','Hồ sơ tuyển sinh','申请材料','入学書類'],
    'At a glance':['Sekilas','At a glance','Sepintas lalu','Auf einen Blick','Tổng quan nhanh','概览','概要'],
    'Education, skills, and experience':['Pendidikan, keterampilan, dan pengalaman','Education, skills, and experience','Pendidikan, kemahiran dan pengalaman','Ausbildung, Fähigkeiten und Erfahrung','Học vấn, kỹ năng và kinh nghiệm','教育、技能与经验','学歴・スキル・経験'],
    'AI, web, and IT engineering projects':['Proyek rekayasa AI, web, dan TI','AI, web, and IT engineering projects','Projek kejuruteraan AI, web dan IT','Projekte in KI-, Web- und IT-Engineering','Các dự án kỹ thuật AI, web và CNTT','AI、Web 与 IT 工程项目','AI・Web・ITエンジニアリングプロジェクト'],
    'Category':['Kategori','Category','Kategori','Kategorie','Danh mục','分类','カテゴリ'],
    'Categories':['Kategori','Categories','Kategori','Kategorien','Danh mục','类别','カテゴリー'],
    'All Categories':['Semua Kategori','All Categories','Semua Kategori','Alle Kategorien','Tất cả danh mục','所有分类','すべてのカテゴリ'],
    'Select a category':['Pilih kategori','Select a category','Pilih kategori','Kategorie auswählen','Chọn danh mục','选择分类','カテゴリを選択'],
    'Access Status':['Status Akses','Access Status','Status Akses','Zugriffsstatus','Trạng thái truy cập','访问状态','アクセスステータス'],
    'Active':['Aktif','Active','Aktif','Aktiv','Hoạt động','启用','アクティブ'],
    'Inactive':['Tidak Aktif','Inactive','Tidak Aktif','Inaktiv','Không hoạt động','停用','非アクティブ'],
    'Dashboard':['Dasbor','Dashboard','Papan pemuka','Dashboard','Bảng điều khiển','仪表板','ダッシュボード'],
    'Overview':['Ikhtisar','Overview','Gambaran keseluruhan','Übersicht','Tổng quan','概览','概要'],
    'Dataset':['Kumpulan Data','Dataset','Set data','Datensatz','Tập dữ liệu','数据集','データセット'],
    'Models':['Model','Models','Model','Modelle','Mô hình','模型','モデル'],
    'Results':['Hasil','Results','Keputusan','Ergebnisse','Kết quả','结果','結果'],
    'Failure Analysis':['Analisis Kegagalan','Failure Analysis','Analisis Kegagalan','Fehleranalyse','Phân tích lỗi','失败分析','失敗分析'],
    'Limitations':['Keterbatasan','Limitations','Batasan','Einschränkungen','Hạn chế','局限性','制限事項'],
    'Source Code':['Kode Sumber','Source Code','Kod Sumber','Quellcode','Mã nguồn','源代码','ソースコード'],
    'Technical Report':['Laporan Teknis','Technical Report','Laporan Teknikal','Technischer Bericht','Báo cáo kỹ thuật','技术报告','技術レポート'],
    'Project Navigation':['Navigasi Proyek','Project Navigation','Navigasi Projek','Projektnavigation','Điều hướng dự án','项目导航','プロジェクトナビゲーション'],
    'University Fit Analysis':['Analisis Kecocokan Universitas','University Fit Analysis','Analisis Kesesuaian Universiti','Analyse der Hochschulpassung','Phân tích mức độ phù hợp với trường đại học','大学匹配分析','大学適合性分析'],
    'Training Images':['Gambar Pelatihan','Training Images','Imej Latihan','Trainingsbilder','Hình ảnh huấn luyện','训练图像','学習画像'],
    'Classes':['Kelas','Classes','Kelas','Klassen','Lớp','类别','クラス'],
    'Backbone':['Arsitektur Dasar','Backbone','Tulang Belakang','Backbone','Mạng nền','骨干网络','バックボーン'],
    'Datasets':['Kumpulan Data','Datasets','Set Data','Datensätze','Bộ dữ liệu','数据集','データセット'],
    'Stack':['Tumpukan Teknologi','Stack','Tindanan Teknologi','Technologie-Stack','Ngăn xếp công nghệ','技术栈','技術スタック'],
    'Total Tickets':['Total Tiket','Total Tickets','Jumlah Tiket','Tickets gesamt','Tổng phiếu','工单总数','チケット合計'],
    'New Tickets':['Tiket Baru','New Tickets','Tiket Baharu','Neue Tickets','Phiếu mới','新工单','新規チケット'],
    'In Progress':['Sedang Diproses','In Progress','Sedang Diproses','In Bearbeitung','Đang xử lý','处理中','対応中'],
    'Resolved':['Terselesaikan','Resolved','Diselesaikan','Gelöst','Đã giải quyết','已解决','解決済み'],
    'Asset Inventory':['Inventaris Aset','Asset Inventory','Inventori Aset','Asset-Inventar','Kho tài sản','资产清单','資産管理'],
    'Recent Tickets':['Tiket Terbaru','Recent Tickets','Tiket Terkini','Neueste Tickets','Phiếu gần đây','最近工单','最近のチケット'],
    'Title':['Judul','Title','Tajuk','Titel','Tiêu đề','标题','タイトル'],
    'Division':['Divisi','Division','Bahagian','Abteilung','Bộ phận','部门','部門'],
    'Reporter':['Pelapor','Reporter','Pelapor','Meldende Person','Người báo cáo','报告人','報告者'],
    'Priority':['Prioritas','Priority','Keutamaan','Priorität','Ưu tiên','优先级','優先度'],
    'Status':['Status','Status','Status','Status','Trạng thái','状态','ステータス'],
    'Date':['Tanggal','Date','Tarikh','Datum','Ngày','日期','日付'],
    'Create Link':['Buat Tautan','Create Link','Cipta Pautan','Link erstellen','Tạo liên kết','创建链接','リンク作成'],
    'Create Short Link':['Buat Tautan Pendek','Create Short Link','Cipta Pautan Pendek','Kurzlink erstellen','Tạo liên kết rút gọn','创建短链接','短縮リンクを作成'],
    'Original URL':['URL Asli','Original URL','URL Asal','Original-URL','URL gốc','原始URL','元のURL'],
    'Custom Alias':['Alias Kustom','Custom Alias','Alias Tersuai','Benutzerdefinierter Alias','Bí danh tùy chỉnh','自定义别名','カスタムエイリアス'],
    'Owner':['Pemilik','Owner','Pemilik','Verantwortlicher','Người phụ trách','负责人','担当者'],
    'Campaign Name':['Nama Kampanye','Campaign Name','Nama Kempen','Kampagnenname','Tên chiến dịch','活动名称','キャンペーン名'],
    'Expiry Date':['Tanggal Kedaluwarsa','Expiry Date','Tarikh Luput','Ablaufdatum','Ngày hết hạn','到期日期','有効期限'],
    'Create':['Buat','Create','Cipta','Erstellen','Tạo','创建','作成'],
    'Save':['Simpan','Save','Simpan','Speichern','Lưu','保存','保存'],
    'Cancel':['Batal','Cancel','Batal','Abbrechen','Hủy','取消','キャンセル'],
    'Delete':['Hapus','Delete','Padam','Löschen','Xóa','删除','削除'],
    'Edit':['Edit','Edit','Sunting','Bearbeiten','Chỉnh sửa','编辑','編集'],
    'Search':['Cari','Search','Cari','Suchen','Tìm kiếm','搜索','検索'],
    'Filter':['Filter','Filter','Tapis','Filter','Lọc','筛选','フィルター'],
    'Reports':['Laporan','Reports','Laporan','Berichte','Báo cáo','报告','レポート'],
    'Analytics':['Analitik','Analytics','Analitik','Analytik','Phân tích','分析','分析'],
    'Campaigns':['Kampanye','Campaigns','Kempen','Kampagnen','Chiến dịch','营销活动','キャンペーン'],
    'Feedback':['Umpan Balik','Feedback','Maklum Balas','Feedback','Phản hồi','反馈','フィードバック'],
    'Keywords':['Kata Kunci','Keywords','Kata Kunci','Schlüsselwörter','Từ khóa','关键词','キーワード'],
    'Recommendations':['Rekomendasi','Recommendations','Cadangan','Empfehlungen','Đề xuất','建议','推奨事項'],
    'Model Evaluation':['Evaluasi Model','Model Evaluation','Penilaian Model','Modellbewertung','Đánh giá mô hình','模型评估','モデル評価'],
    'Total Feedback':['Total Umpan Balik','Total Feedback','Jumlah Maklum Balas','Feedback gesamt','Tổng phản hồi','反馈总数','フィードバック合計'],
    'Positive Rate':['Tingkat Positif','Positive Rate','Kadar Positif','Positive Quote','Tỷ lệ tích cực','正面比例','ポジティブ率'],
    'Negative Rate':['Tingkat Negatif','Negative Rate','Kadar Negatif','Negative Quote','Tỷ lệ tiêu cực','负面比例','ネガティブ率'],
    'Average Rating':['Penilaian Rata-rata','Average Rating','Penilaian Purata','Durchschnittsbewertung','Đánh giá trung bình','平均评分','平均評価'],
    'Sentiment Trend':['Tren Sentimen','Sentiment Trend','Trend Sentimen','Stimmungstrend','Xu hướng cảm xúc','情感趋势','感情トレンド'],
    'Sentiment Distribution':['Distribusi Sentimen','Sentiment Distribution','Taburan Sentimen','Stimmungsverteilung','Phân bố cảm xúc','情感分布','感情分布'],
    'Recent Feedback':['Umpan Balik Terbaru','Recent Feedback','Maklum Balas Terkini','Neuestes Feedback','Phản hồi gần đây','最近反馈','最近のフィードバック'],
    'Top Topics':['Topik Teratas','Top Topics','Topik Teratas','Top-Themen','Chủ đề hàng đầu','热门主题','上位トピック'],
    'Privacy':['Privasi','Privacy','Privasi','Datenschutz','Quyền riêng tư','隐私','プライバシー'],
    'Terms':['Persyaratan','Terms','Terma','Bedingungen','Điều khoản','条款','利用規約'],
    'Website':['Website','Website','Laman Web','Website','Trang web','网站','ウェブサイト'],
    'Light':['Terang','Light','Cerah','Hell','Sáng','浅色','ライト'],
    'Dark':['Gelap','Dark','Gelap','Dunkel','Tối','深色','ダーク'],
    'Open Fullscreen':['Buka Layar Penuh','Open Fullscreen','Buka Skrin Penuh','Vollbild öffnen','Mở toàn màn hình','打开全屏','全画面で開く'],
    'Close':['Tutup','Close','Tutup','Schließen','Đóng','关闭','閉じる']
  };
  Object.assign(exact,{"Kebijakan Privasi":["Kebijakan Privasi","Privacy Policy","Dasar Privasi","Datenschutzerklärung","Chính sách quyền riêng tư","隐私政策","プライバシーポリシー"],"Persyaratan Layanan":["Persyaratan Layanan","Terms of Service","Terma Perkhidmatan","Nutzungsbedingungen","Điều khoản dịch vụ","服务条款","利用規約"],"Pengaturan cookie":["Pengaturan cookie","Cookie settings","Tetapan kuki","Cookie-Einstellungen","Cài đặt cookie","Cookie 设置","Cookie設定"],"BERLAKU: 15 Juni 2026":["BERLAKU: 15 Juni 2026","EFFECTIVE: 15 June 2026","BERKUAT KUASA: 15 Jun 2026","GÜLTIG AB: 15. Juni 2026","CÓ HIỆU LỰC: 15 tháng 6 năm 2026","生效日期：2026年6月15日","施行日：2026年6月15日"],"Pilihan tetap milik pengunjung.":["Pilihan tetap milik pengunjung.","The choice remains with the visitor.","Pilihan kekal milik pengunjung.","Die Entscheidung bleibt beim Besucher.","Quyền lựa chọn thuộc về khách truy cập.","选择权始终属于访问者。","選択権は訪問者にあります。"],"Unduhan bukan persetujuan akses.":["Unduhan bukan persetujuan akses.","A download is not access approval.","Muat turun bukan kelulusan akses.","Ein Download ist keine Zugriffsfreigabe.","Tải xuống không đồng nghĩa với phê duyệt truy cập.","下载并不表示已获准访问。","ダウンロードはアクセス承認を意味しません。"],"1. Pengelola dan kontak":["1. Pengelola dan kontak","1. Controller and contact","1. Pengendali dan hubungan","1. Verantwortlicher und Kontakt","1. Đơn vị quản lý và liên hệ","1. 管理方与联系方式","1. 管理者と連絡先"],"2. Data yang dapat diproses":["2. Data yang dapat diproses","2. Data that may be processed","2. Data yang boleh diproses","2. Daten, die verarbeitet werden können","2. Dữ liệu có thể được xử lý","2. 可能处理的数据","2. 処理される可能性のあるデータ"],"3. Tujuan penggunaan":["3. Tujuan penggunaan","3. Purposes of use","3. Tujuan penggunaan","3. Verwendungszwecke","3. Mục đích sử dụng","3. 使用目的","3. 利用目的"],"7. Berbagi data":["7. Berbagi data","7. Data sharing","7. Perkongsian data","7. Datenweitergabe","7. Chia sẻ dữ liệu","7. 数据共享","7. データ共有"],"8. Hak dan pilihan Anda":["8. Hak dan pilihan Anda","8. Your rights and choices","8. Hak dan pilihan anda","8. Ihre Rechte und Wahlmöglichkeiten","8. Quyền và lựa chọn của bạn","8. 您的权利与选择","8. お客様の権利と選択"],"1. Penerimaan ketentuan":["1. Penerimaan ketentuan","1. Acceptance of terms","1. Penerimaan terma","1. Annahme der Bedingungen","1. Chấp nhận điều khoản","1. 接受条款","1. 規約への同意"],"2. Tujuan website":["2. Tujuan website","2. Website purpose","2. Tujuan laman web","2. Zweck der Website","2. Mục đích của trang web","2. 网站用途","2. ウェブサイトの目的"],"3. Prosedur akses ZIP":["3. Prosedur akses ZIP","3. ZIP access procedure","3. Prosedur akses ZIP","3. Verfahren für ZIP-Zugriff","3. Quy trình truy cập ZIP","3. ZIP 访问流程","3. ZIPアクセス手順"],"5. Penggunaan yang dilarang":["5. Penggunaan yang dilarang","5. Prohibited uses","5. Penggunaan yang dilarang","5. Verbotene Nutzungen","5. Hành vi bị cấm","5. 禁止用途","5. 禁止される使用"],"8. Batasan tanggung jawab":["8. Batasan tanggung jawab","8. Limitation of liability","8. Had tanggungjawab","8. Haftungsbeschränkung","8. Giới hạn trách nhiệm","8. 责任限制","8. 責任の制限"]});

  const order=['id','en','ms','de','vi','zh','ja'];
  const reverse=new Map();
  Object.entries(exact).forEach(([source,values])=>{
    [source,...values].forEach(value=>{
      const n=norm(value);if(n&&!reverse.has(n))reverse.set(n,values);
    });
  });

  function normalize(value){const code=String(value||'').toLowerCase().replace('_','-').split('-')[0];return LANGS.has(code)?code:'id'}
  function readLanguage(){try{return localStorage.getItem('apu-ui-language')||document.documentElement.dataset.apuLanguage||document.documentElement.lang||'id'}catch(_){return 'id'}}
  function norm(value){return String(value||'').replace(/\s+/g,' ').trim().toLocaleLowerCase()}
  function exactTranslation(text,target){const values=reverse.get(norm(text));if(!values)return null;return values[order.indexOf(target)]||null}
  function loadCache(){try{const data=JSON.parse(localStorage.getItem(CACHE_KEY)||'{}');Object.entries(data).forEach(([k,v])=>memory.set(k,v))}catch(_){}}
  function saveCache(){try{const entries=[...memory.entries()].slice(-1400);localStorage.setItem(CACHE_KEY,JSON.stringify(Object.fromEntries(entries)))}catch(_){}}
  loadCache();

  const technical=/^(?:[\d\s.,:%+\-×÷=<>()[\]{}|/\\]+|[A-Z0-9_.-]{1,8}|(?:GET|POST|PUT|PATCH|DELETE|JSON|CSV|PDF|ZIP|API|URL|URI|HTTP|HTTPS|CIDR|IPv4|IPv6|SQL|D1|R2|KV|AI|ML|NLP|GPU|CPU|RAM|MIT|UTM|ETH|SAIL|ResNet-50|PyTorch))$/;
  const urlLike=/(?:https?:\/\/|www\.|@|\b[a-z0-9-]+\.(?:com|org|net|dev|io|ai)\b)/i;
  const nativeProject=(document.documentElement.dataset.scrollTheme||document.documentElement.dataset.apuStandaloneProject||'')==='url-shortener'||location.pathname.includes('/projects/url-shortener');
  const skipSelector='script,style,code,pre,kbd,samp,textarea,select,option,[contenteditable="true"],[data-apu-no-translate],[data-apu-native-i18n],[translate="no"],[role="listbox"],[role="option"],[role="menu"],[role="menuitem"],[role="combobox"],[data-radix-select-content],[data-radix-select-item],[data-radix-select-viewport],[data-radix-popper-content-wrapper],[data-state="open"],[aria-expanded="true"],#apu-ui-dock-v62,#apu-ui-toast-v62,#apu-translation-gate-v62,[data-apu-legal-i18n-ui]';
  const attrSkipSelector='script,style,code,pre,kbd,samp,[data-apu-no-translate],[data-apu-native-i18n],[translate="no"],[role="listbox"],[role="option"],[role="menu"],[role="menuitem"],[role="combobox"],[data-radix-select-content],[data-radix-select-item],[data-radix-select-viewport],[data-radix-popper-content-wrapper],[data-state="open"],[aria-expanded="true"],#apu-ui-dock-v62,#apu-ui-toast-v62,#apu-translation-gate-v62,[data-apu-legal-i18n-ui]';
  function shouldSkipElement(el){if(!el)return true;if(nativeProject&&el.closest('#root'))return true;return Boolean(el.closest(skipSelector))}
  function shouldSkipAttributeElement(el){if(!el)return true;if(nativeProject&&el.closest('#root'))return true;return Boolean(el.closest(attrSkipSelector))}
  function shouldTranslate(text,el){const clean=String(text||'').replace(/\s+/g,' ').trim();if(clean.length<2||clean.length>1600||technical.test(clean)||urlLike.test(clean))return false;if(shouldSkipElement(el))return false;return /[A-Za-zÀ-ž\u00C0-\u024F\u3040-\u30ff\u3400-\u9fff]/.test(clean)}

  function protect(text){
    const tokens=[];
    const safe=String(text).replace(/https?:\/\/\S+|\b(?:AI Project Universe|LinkManager Pro|SentiScope|Cloudflare|GitHub|YouTube|JavaScript|TypeScript|React|PyTorch|ResNet-50|MIT CSAIL|ETH Zurich|Tsinghua|University of Aizu|UTM)\b|\b[A-Z][A-Z0-9_.-]{1,12}\b|`[^`]+`|\b\d+(?:[.,]\d+)?%?\b/g,m=>{const k=`⟦APU${tokens.length}⟧`;tokens.push(m);return k});
    return {safe,restore:value=>tokens.reduce((v,t,i)=>v.replaceAll(`⟦APU${i}⟧`,t),String(value||''))};
  }
  async function remoteTranslate(text,target,signal){
    const {safe,restore}=protect(text);
    let lastError;
    const providers=[
      async()=>{
        const response=await fetch('/api/apu-translate',{method:'POST',headers:{'content-type':'application/json',accept:'application/json'},body:JSON.stringify({text:safe,target}),cache:'no-store',signal});
        const contentType=response.headers.get('content-type')||'';
        if(!contentType.includes('application/json'))throw new Error('edge-non-json');
        const data=await response.json();if(!response.ok)throw new Error(data?.error||`edge-${response.status}`);
        const value=restore(data?.translatedText||'').trim();if(!value)throw new Error('edge-empty');return value;
      },
      async()=>{
        const url=`https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${encodeURIComponent(target)}&dt=t&q=${encodeURIComponent(safe)}`;
        const response=await fetch(url,{method:'GET',mode:'cors',credentials:'omit',cache:'no-store',referrerPolicy:'no-referrer',signal});
        if(!response.ok)throw new Error(`google-${response.status}`);
        const data=await response.json();
        const translated=Array.isArray(data?.[0])?data[0].map(row=>row?.[0]||'').join(''):'';
        const value=restore(translated).trim();if(!value)throw new Error('google-empty');return value;
      },
      async()=>{
        const probableSource=/\b(?:yang|dan|untuk|dengan|dari|ke|pada|semua|pilih|buka|hapus|buat|tautan|kategori|status|laporan|proyek|riset|dokumen)\b/i.test(text)?'id':'en';
        const params=new URLSearchParams({q:safe,langpair:`${probableSource}|${target}`,mt:'1'});
        const response=await fetch(`https://api.mymemory.translated.net/get?${params}`,{method:'GET',mode:'cors',credentials:'omit',cache:'no-store',referrerPolicy:'no-referrer',signal});
        if(!response.ok)throw new Error(`mymemory-${response.status}`);
        const data=await response.json();const value=restore(data?.responseData?.translatedText||'').trim();if(!value)throw new Error('mymemory-empty');return value;
      }
    ];
    for(let attempt=0;attempt<2;attempt++){
      for(const provider of providers){
        try{return await provider()}catch(error){lastError=error;if(signal?.aborted)throw error}
      }
      await new Promise(r=>setTimeout(r,250*(attempt+1)));
    }
    throw lastError||new Error('translate-failed');
  }

  async function translateText(text,target,signal){
    const local=exactTranslation(text,target);if(local)return local;
    const key=`${target}\u0000${text}`;if(memory.has(key))return memory.get(key);
    if(target==='en'&&/^(?:GitHub|Cloudflare|React|PyTorch|ResNet-50|MIT|UTM|ETH|URL|API|PDF|ZIP)$/i.test(text.trim())){memory.set(key,text);return text}
    try{
      const value=await remoteTranslate(text,target,signal);
      if(value&&norm(value)!==norm(text)){memory.set(key,value);return value}
    }catch(_){ }
    return text;
  }

  function collect(root=document.body){
    const tasks=[];if(!root)return tasks;
    const walker=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,{acceptNode(node){const el=node.parentElement;return shouldTranslate(node.nodeValue,el)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}});
    while(walker.nextNode())tasks.push({kind:'text',node:walker.currentNode,value:walker.currentNode.nodeValue||''});
    root.querySelectorAll?.('[placeholder],[title],[aria-label],[aria-description],[alt],input[type="button"][value],input[type="submit"][value],input[type="reset"][value]').forEach(el=>{
      if(shouldSkipAttributeElement(el))return;
      for(const attr of ['placeholder','title','aria-label','aria-description','alt','value']){
        const value=el.getAttribute(attr);if(value&&shouldTranslate(value,el))tasks.push({kind:'attr',node:el,attr,value});
      }
    });
    return tasks;
  }

  function remember(task){
    if(task.kind==='text'){if(!originalText.has(task.node))originalText.set(task.node,task.value);return originalText.get(task.node)}
    let map=originalAttrs.get(task.node);if(!map){map={};originalAttrs.set(task.node,map)}if(!(task.attr in map))map[task.attr]=task.value;return map[task.attr]
  }
  function apply(task,value){
    applying=true;
    try{
      if(task.kind==='text'){task.node.nodeValue=value;expectedText.set(task.node,value)}
      else{task.node.setAttribute(task.attr,value);const map=expectedAttrs.get(task.node)||{};map[task.attr]=value;expectedAttrs.set(task.node,map)}
    }finally{applying=false}
  }

  async function translateRoot(root=document.body){
    const myRun=runId;const target=language;const tasks=collect(root);if(!tasks.length)return;
    const controller=new AbortController();const timer=setTimeout(()=>controller.abort(),70000);
    const results=new Array(tasks.length);let index=0;
    document.documentElement.dataset.apuTranslationState='loading';
    async function worker(){
      while(index<tasks.length&&myRun===runId){
        const taskIndex=index++;const task=tasks[taskIndex];const source=remember(task);
        const local=exactTranslation(source,target);
        results[taskIndex]=local||await translateText(source,target,controller.signal);
        if(index%10===0)await new Promise(r=>setTimeout(r,0));
      }
    }
    try{
      await Promise.all([worker(),worker(),worker(),worker()]);
      if(myRun!==runId)return;
      await new Promise(resolve=>requestAnimationFrame(()=>{
        tasks.forEach((task,i)=>{const value=results[i];if(value)apply(task,value)});
        resolve();
      }));
      document.documentElement.dataset.apuTranslationState='ready';
      window.dispatchEvent(new CustomEvent('apu:project-translation-complete',{detail:{language:target,tasks:tasks.length,version:'v6.31'}}));
    }catch(error){
      if(error?.name!=='AbortError')console.warn('APU translation pass incomplete',error);
      document.documentElement.dataset.apuTranslationState='error';
    }finally{clearTimeout(timer);saveCache()}
  }

  function restoreAll(){
    applying=true;
    try{
      document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT).currentNode;
      document.querySelectorAll('*').forEach(el=>{
        for(const node of el.childNodes){if(node.nodeType===Node.TEXT_NODE&&originalText.has(node))node.nodeValue=originalText.get(node)}
        const attrs=originalAttrs.get(el);if(attrs)Object.entries(attrs).forEach(([name,value])=>el.setAttribute(name,value));
      });
    }finally{applying=false}
  }

  function setLanguage(value){
    const next=normalize(value);language=next;document.documentElement.dataset.apuLanguage=next;document.documentElement.lang=LOCALES[next]||next;
    try{localStorage.setItem('apu-ui-language',next)}catch(_){ }
    runId++;restoreAll();clearTimeout(scanTimer);scanTimer=setTimeout(()=>translateRoot(document.body),60);
  }

  function schedule(root){
    if(root instanceof Element){if(shouldSkipElement(root))return;pending.add(root)}else pending.add(document.body);
    clearTimeout(scanTimer);scanTimer=setTimeout(()=>{const roots=[...pending].filter(r=>!shouldSkipElement(r));pending.clear();const token=runId;roots.slice(0,12).forEach(r=>{if(token===runId)translateRoot(r)})},180);
  }
  function boot(){
    if(nativeProject){const appRoot=document.getElementById('root');if(appRoot){appRoot.dataset.apuNativeI18n='linkmanager';appRoot.dataset.apuNoTranslate='true';appRoot.setAttribute('translate','no')}document.documentElement.dataset.apuTranslationState='native';return}
    setLanguage(readLanguage());
    observer=new MutationObserver(mutations=>{
      if(applying)return;
      for(const m of mutations){
        if(m.type==='characterData'){
          if(m.target.nodeValue!==expectedText.get(m.target)){originalText.delete(m.target);schedule(m.target.parentElement)}
        }else if(m.type==='childList')m.addedNodes.forEach(n=>{if(n.nodeType===Node.ELEMENT_NODE){if(!shouldSkipElement(n))schedule(n)}else if(n.parentElement&&!shouldSkipElement(n.parentElement))schedule(n.parentElement)});
        else if(m.type==='attributes'){
          const expected=expectedAttrs.get(m.target)?.[m.attributeName];if(m.target.getAttribute(m.attributeName)!==expected){const map=originalAttrs.get(m.target);if(map)delete map[m.attributeName];schedule(m.target)}
        }
      }
    });
    observer.observe(document.body,{subtree:true,childList:true,characterData:true,attributes:true,attributeFilter:['placeholder','title','aria-label','aria-description','alt']});
  }
  window.addEventListener('message',e=>{if(e.origin===location.origin&&e.data?.type==='apu:viewer-settings'&&e.data.language)setLanguage(e.data.language)});
  window.addEventListener('apu:languagechange',e=>setLanguage(e.detail?.language||readLanguage()));
  window.addEventListener('storage',e=>{if(e.key==='apu-ui-language'&&e.newValue)setLanguage(e.newValue)});
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot();
})();
