import fs from "node:fs"; import { EXTRA as EXTRA_ES } from "./locale-extra-es.mjs"; function parse(s) { const d = {}; const re = /"([^"\\]+)"\s*:\s*((?:"(?:\\.|[^"\\])*")|(?:`(?:\\.|[^`\\])*`))/gs; let m; while ((m = re.exec(s))) { const raw = m[2]; d[m[1]] = raw.startsWith("`") ? raw.slice(1, -1).replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\n/g, "\n") : JSON.parse(raw); } return d; } const en = parse(fs.readFileSync("../src/lib/i18n/messages/en.ts", "utf8")); const seed = JSON.parse(fs.readFileSync("_phrase-seed.json", "utf8")); /** @type {Record} */ const MORE = { Descrybe: { fr: "Descrybe", de: "Descrybe", it: "Descrybe", pt: "Descrybe", nl: "Descrybe", pl: "Descrybe", ja: "Descrybe" }, "—": { fr: "—", de: "—", it: "—", pt: "—", nl: "—", pl: "—", ja: "—" }, Marketing: { fr: "Marketing", de: "Marketing", it: "Marketing", pt: "Marketing", nl: "Marketing", pl: "Marketing", ja: "マーケティング" }, Exports: { fr: "Exports", de: "Exporte", it: "Esportazioni", pt: "Exportações", nl: "Exports", pl: "Eksporty", ja: "エクスポート" }, SEO: { fr: "SEO", de: "SEO", it: "SEO", pt: "SEO", nl: "SEO", pl: "SEO", ja: "SEO" }, Admin: { fr: "Admin", de: "Admin", it: "Admin", pt: "Admin", nl: "Admin", pl: "Admin", ja: "管理" }, EPREL: { fr: "EPREL", de: "EPREL", it: "EPREL", pt: "EPREL", nl: "EPREL", pl: "EPREL", ja: "EPREL" }, "Re: {subject}": { fr: "Re: {subject}", de: "Re: {subject}", it: "Re: {subject}", pt: "Re: {subject}", nl: "Re: {subject}", pl: "Re: {subject}", ja: "Re: {subject}" }, "Sign in": { fr: "Se connecter", de: "Anmelden", it: "Accedi", pt: "Iniciar sessão", nl: "Inloggen", pl: "Zaloguj się", ja: "ログイン" }, "Use your Descrybe email and password.": { fr: "Utilisez votre e-mail et mot de passe Descrybe.", de: "Verwenden Sie Ihre Descrybe-E-Mail und Ihr Passwort.", it: "Usa la tua email e password Descrybe.", pt: "Utilize o seu e-mail e palavra-passe Descrybe.", nl: "Gebruik uw Descrybe e-mailadres en wachtwoord.", pl: "Użyj adresu e-mail i hasła Descrybe.", ja: "Descrybeのメールアドレスとパスワードを使用してください。" }, "Signing in…": { fr: "Connexion…", de: "Anmeldung…", it: "Accesso in corso…", pt: "A iniciar sessão…", nl: "Bezig met inloggen…", pl: "Logowanie…", ja: "ログイン中…" }, "Login failed": { fr: "Échec de la connexion", de: "Anmeldung fehlgeschlagen", it: "Accesso non riuscito", pt: "Falha no início de sessão", nl: "Inloggen mislukt", pl: "Logowanie nie powiodło się", ja: "ログインに失敗しました" }, "Create company": { fr: "Créer une entreprise", de: "Unternehmen erstellen", it: "Crea azienda", pt: "Criar empresa", nl: "Bedrijf aanmaken", pl: "Utwórz firmę", ja: "会社を作成" }, "Accept invite": { fr: "Accepter l'invitation", de: "Einladung annehmen", it: "Accetta invito", pt: "Aceitar convite", nl: "Uitnodiging accepteren", pl: "Zaakceptuj zaproszenie", ja: "招待を承認" }, "Set password": { fr: "Définir le mot de passe", de: "Passwort festlegen", it: "Imposta password", pt: "Definir palavra-passe", nl: "Wachtwoord instellen", pl: "Ustaw hasło", ja: "パスワードを設定" }, "Company name": { fr: "Nom de l'entreprise", de: "Unternehmensname", it: "Nome azienda", pt: "Nome da empresa", nl: "Bedrijfsnaam", pl: "Nazwa firmy", ja: "会社名" }, "Create account": { fr: "Créer un compte", de: "Konto erstellen", it: "Crea account", pt: "Criar conta", nl: "Account aanmaken", pl: "Utwórz konto", ja: "アカウントを作成" }, "Creating…": { fr: "Création…", de: "Wird erstellt…", it: "Creazione…", pt: "A criar…", nl: "Bezig met aanmaken…", pl: "Tworzenie…", ja: "作成中…" }, "Registration failed": { fr: "Échec de l'inscription", de: "Registrierung fehlgeschlagen", it: "Registrazione non riuscita", pt: "Falha no registo", nl: "Registratie mislukt", pl: "Rejestracja nie powiodła się", ja: "登録に失敗しました" }, "Already have an account?": { fr: "Vous avez déjà un compte ?", de: "Haben Sie bereits ein Konto?", it: "Hai già un account?", pt: "Já tem uma conta?", nl: "Heeft u al een account?", pl: "Masz już konto?", ja: "すでにアカウントをお持ちですか?" }, "No account?": { fr: "Pas de compte ?", de: "Kein Konto?", it: "Nessun account?", pt: "Sem conta?", nl: "Geen account?", pl: "Brak konta?", ja: "アカウントがありませんか?" }, "Admin → Users": { fr: "Admin → Utilisateurs", de: "Admin → Benutzer", it: "Admin → Utenti", pt: "Admin → Utilizadores", nl: "Admin → Gebruikers", pl: "Admin → Użytkownicy", ja: "管理 → ユーザー" }, "your email": { fr: "votre e-mail", de: "Ihre E-Mail", it: "la tua email", pt: "o seu e-mail", nl: "uw e-mail", pl: "twój e-mail", ja: "あなたのメール" }, Profile: { fr: "Profil", de: "Profil", it: "Profilo", pt: "Perfil", nl: "Profiel", pl: "Profil", ja: "プロフィール" }, Email: { fr: "E-mail", de: "E-Mail", it: "Email", pt: "E-mail", nl: "E-mail", pl: "E-mail", ja: "メール" }, Member: { fr: "Membre", de: "Mitglied", it: "Membro", pt: "Membro", nl: "Lid", pl: "Członek", ja: "メンバー" }, Remove: { fr: "Retirer", de: "Entfernen", it: "Rimuovi", pt: "Remover", nl: "Verwijderen", pl: "Usuń", ja: "削除" }, Promote: { fr: "Promouvoir", de: "Befördern", it: "Promuovi", pt: "Promover", nl: "Promoveren", pl: "Awansuj", ja: "昇格" }, Demote: { fr: "Rétrograder", de: "Herabstufen", it: "Degrada", pt: "Despromover", nl: "Degraderen", pl: "Degraduj", ja: "降格" }, Role: { fr: "Rôle", de: "Rolle", it: "Ruolo", pt: "Papel", nl: "Rol", pl: "Rola", ja: "ロール" }, Status: { fr: "Statut", de: "Status", it: "Stato", pt: "Estado", nl: "Status", pl: "Status", ja: "ステータス" }, Actions: { fr: "Actions", de: "Aktionen", it: "Azioni", pt: "Ações", nl: "Acties", pl: "Akcje", ja: "操作" }, Name: { fr: "Nom", de: "Name", it: "Nome", pt: "Nome", nl: "Naam", pl: "Nazwa", ja: "名前" }, Key: { fr: "Clé", de: "Schlüssel", it: "Chiave", pt: "Chave", nl: "Sleutel", pl: "Klucz", ja: "キー" }, Plan: { fr: "Offre", de: "Plan", it: "Piano", pt: "Plano", nl: "Plan", pl: "Plan", ja: "プラン" }, Used: { fr: "Utilisé", de: "Verbraucht", it: "Usato", pt: "Usado", nl: "Gebruikt", pl: "Użyte", ja: "使用済み" }, Trial: { fr: "Essai", de: "Testphase", it: "Prova", pt: "Teste", nl: "Proef", pl: "Okres próbny", ja: "トライアル" }, Export: { fr: "Exporter", de: "Exportieren", it: "Esporta", pt: "Exportar", nl: "Exporteren", pl: "Eksportuj", ja: "エクスポート" }, "API Keys": { fr: "Clés API", de: "API-Schlüssel", it: "Chiavi API", pt: "Chaves API", nl: "API-sleutels", pl: "Klucze API", ja: "APIキー" }, "Copy link": { fr: "Copier le lien", de: "Link kopieren", it: "Copia link", pt: "Copiar link", nl: "Link kopiëren", pl: "Kopiuj link", ja: "リンクをコピー" }, "Send invite": { fr: "Envoyer l'invitation", de: "Einladung senden", it: "Invia invito", pt: "Enviar convite", nl: "Uitnodiging verzenden", pl: "Wyślij zaproszenie", ja: "招待を送信" }, "Invite user": { fr: "Inviter un utilisateur", de: "Benutzer einladen", it: "Invita utente", pt: "Convidar utilizador", nl: "Gebruiker uitnodigen", pl: "Zaproś użytkownika", ja: "ユーザーを招待" }, "First Name": { fr: "Prénom", de: "Vorname", it: "Nome", pt: "Nome próprio", nl: "Voornaam", pl: "Imię", ja: "名" }, "Last Name": { fr: "Nom", de: "Nachname", it: "Cognome", pt: "Apelido", nl: "Achternaam", pl: "Nazwisko", ja: "姓" }, "Team Members": { fr: "Membres de l'équipe", de: "Teammitglieder", it: "Membri del team", pt: "Membros da equipa", nl: "Teamleden", pl: "Członkowie zespołu", ja: "チームメンバー" }, "Personal Information": { fr: "Informations personnelles", de: "Persönliche Daten", it: "Informazioni personali", pt: "Informação pessoal", nl: "Persoonlijke gegevens", pl: "Dane osobowe", ja: "個人情報" }, "Update your personal details": { fr: "Mettez à jour vos informations personnelles", de: "Aktualisieren Sie Ihre persönlichen Daten", it: "Aggiorna i tuoi dati personali", pt: "Atualize os seus dados pessoais", nl: "Werk uw persoonlijke gegevens bij", pl: "Zaktualizuj swoje dane osobowe", ja: "個人情報を更新" }, "Your first name": { fr: "Votre prénom", de: "Ihr Vorname", it: "Il tuo nome", pt: "O seu nome próprio", nl: "Uw voornaam", pl: "Twoje imię", ja: "名" }, "Your last name": { fr: "Votre nom", de: "Ihr Nachname", it: "Il tuo cognome", pt: "O seu apelido", nl: "Uw achternaam", pl: "Twoje nazwisko", ja: "姓" }, "Profile updated.": { fr: "Profil mis à jour.", de: "Profil aktualisiert.", it: "Profilo aggiornato.", pt: "Perfil atualizado.", nl: "Profiel bijgewerkt.", pl: "Profil zaktualizowany.", ja: "プロフィールを更新しました。" }, "Could not update profile": { fr: "Impossible de mettre à jour le profil", de: "Profil konnte nicht aktualisiert werden", it: "Impossibile aggiornare il profilo", pt: "Não foi possível atualizar o perfil", nl: "Profiel kon niet worden bijgewerkt", pl: "Nie można zaktualizować profilu", ja: "プロフィールを更新できませんでした" }, "Saving…": { fr: "Enregistrement…", de: "Speichern…", it: "Salvataggio…", pt: "A guardar…", nl: "Bezig met opslaan…", pl: "Zapisywanie…", ja: "保存中…" }, "Accepting…": { fr: "Acceptation…", de: "Wird angenommen…", it: "Accettazione…", pt: "A aceitar…", nl: "Bezig met accepteren…", pl: "Akceptowanie…", ja: "承認中…" }, "Open dashboard": { fr: "Ouvrir le tableau de bord", de: "Dashboard öffnen", it: "Apri dashboard", pt: "Abrir painel", nl: "Dashboard openen", pl: "Otwórz panel", ja: "ダッシュボードを開く" }, "Company settings": { fr: "Paramètres de l'entreprise", de: "Unternehmenseinstellungen", it: "Impostazioni azienda", pt: "Definições da empresa", nl: "Bedrijfsinstellingen", pl: "Ustawienia firmy", ja: "会社の設定" }, "Go to sign in": { fr: "Aller à la connexion", de: "Zur Anmeldung", it: "Vai all'accesso", pt: "Ir para início de sessão", nl: "Naar inloggen", pl: "Przejdź do logowania", ja: "ログインへ" }, "Password saved": { fr: "Mot de passe enregistré", de: "Passwort gespeichert", it: "Password salvata", pt: "Palavra-passe guardada", nl: "Wachtwoord opgeslagen", pl: "Hasło zapisane", ja: "パスワードを保存しました" }, "You're on the team": { fr: "Vous faites partie de l'équipe", de: "Sie sind im Team", it: "Fai parte del team", pt: "Já faz parte da equipa", nl: "U bent in het team", pl: "Jesteś w zespole", ja: "チームに参加しました" }, "Enable fields": { fr: "Activer les champs", de: "Felder aktivieren", it: "Abilita campi", pt: "Ativar campos", nl: "Velden inschakelen", pl: "Włącz pola", ja: "フィールドを有効化" }, "Process products": { fr: "Traiter les produits", de: "Produkte verarbeiten", it: "Elabora prodotti", pt: "Processar produtos", nl: "Producten verwerken", pl: "Przetwarzaj produkty", ja: "商品を処理" }, "Connect feed": { fr: "Connecter un flux", de: "Feed verbinden", it: "Collega feed", pt: "Ligar feed", nl: "Feed koppelen", pl: "Podłącz feed", ja: "フィードを接続" }, "Upload CSV": { fr: "Téléverser un CSV", de: "CSV hochladen", it: "Carica CSV", pt: "Carregar CSV", nl: "CSV uploaden", pl: "Prześlij CSV", ja: "CSVをアップロード" }, "View plans": { fr: "Voir les offres", de: "Pläne ansehen", it: "Vedi i piani", pt: "Ver planos", nl: "Plannen bekijken", pl: "Zobacz plany", ja: "プランを見る" }, "Compare plans": { fr: "Comparer les offres", de: "Pläne vergleichen", it: "Confronta i piani", pt: "Comparar planos", nl: "Plannen vergelijken", pl: "Porównaj plany", ja: "プランを比較" }, "Start a job": { fr: "Démarrer une tâche", de: "Job starten", it: "Avvia un processo", pt: "Iniciar uma tarefa", nl: "Een job starten", pl: "Uruchom zadanie", ja: "ジョブを開始" }, "Resume tutorial": { fr: "Reprendre le tutoriel", de: "Tutorial fortsetzen", it: "Riprendi tutorial", pt: "Retomar tutorial", nl: "Tutorial hervatten", pl: "Wznów samouczek", ja: "チュートリアルを再開" }, "Restart tutorial": { fr: "Relancer le tutoriel", de: "Tutorial neu starten", it: "Riavvia tutorial", pt: "Reiniciar tutorial", nl: "Tutorial opnieuw starten", pl: "Uruchom ponownie samouczek", ja: "チュートリアルを再開する" }, "Open products": { fr: "Ouvrir les produits", de: "Produkte öffnen", it: "Apri prodotti", pt: "Abrir produtos", nl: "Producten openen", pl: "Otwórz produkty", ja: "商品を開く" }, "Welcome to {name}": { fr: "Bienvenue sur {name}", de: "Willkommen bei {name}", it: "Benvenuto in {name}", pt: "Bem-vindo a {name}", nl: "Welkom bij {name}", pl: "Witamy w {name}", ja: "{name} へようこそ" }, "Company Settings": { fr: "Paramètres de l'entreprise", de: "Unternehmenseinstellungen", it: "Impostazioni azienda", pt: "Definições da empresa", nl: "Bedrijfsinstellingen", pl: "Ustawienia firmy", ja: "会社の設定" }, "Active company": { fr: "Entreprise active", de: "Aktives Unternehmen", it: "Azienda attiva", pt: "Empresa ativa", nl: "Actief bedrijf", pl: "Aktywna firma", ja: "アクティブな会社" }, "Credits overview": { fr: "Aperçu des crédits", de: "Credit-Übersicht", it: "Panoramica crediti", pt: "Resumo de créditos", nl: "Credits-overzicht", pl: "Przegląd kredytów", ja: "クレジット概要" }, "Company Information": { fr: "Informations sur l'entreprise", de: "Unternehmensinformationen", it: "Informazioni azienda", pt: "Informação da empresa", nl: "Bedrijfsgegevens", pl: "Informacje o firmie", ja: "会社情報" }, "Update your company details": { fr: "Mettez à jour les détails de votre entreprise", de: "Aktualisieren Sie Ihre Unternehmensdaten", it: "Aggiorna i dettagli dell'azienda", pt: "Atualize os detalhes da empresa", nl: "Werk uw bedrijfsgegevens bij", pl: "Zaktualizuj dane firmy", ja: "会社の詳細を更新" }, "Company Name": { fr: "Nom de l'entreprise", de: "Unternehmensname", it: "Nome azienda", pt: "Nome da empresa", nl: "Bedrijfsnaam", pl: "Nazwa firmy", ja: "会社名" }, "Your company name": { fr: "Le nom de votre entreprise", de: "Ihr Unternehmensname", it: "Il nome della tua azienda", pt: "O nome da sua empresa", nl: "Uw bedrijfsnaam", pl: "Nazwa Twojej firmy", ja: "会社名" }, "Content Settings": { fr: "Paramètres de contenu", de: "Inhaltseinstellungen", it: "Impostazioni contenuti", pt: "Definições de conteúdo", nl: "Contentinstellingen", pl: "Ustawienia treści", ja: "コンテンツ設定" }, "Merge products with the same GTIN": { fr: "Fusionner les produits avec le même GTIN", de: "Produkte mit derselben GTIN zusammenführen", it: "Unisci prodotti con lo stesso GTIN", pt: "Unir produtos com o mesmo GTIN", nl: "Producten met dezelfde GTIN samenvoegen", pl: "Scal produkty z tym samym GTIN", ja: "同じGTINの商品をマージ" }, "Email integration": { fr: "Intégration e-mail", de: "E-Mail-Integration", it: "Integrazione email", pt: "Integração de e-mail", nl: "E-mailintegratie", pl: "Integracja e-mail", ja: "メール連携" }, "AI integrations": { fr: "Intégrations IA", de: "KI-Integrationen", it: "Integrazioni IA", pt: "Integrações de IA", nl: "AI-integraties", pl: "Integracje AI", ja: "AI連携" }, "Operator alerts": { fr: "Alertes opérateur", de: "Operator-Benachrichtigungen", it: "Avvisi operatore", pt: "Alertas do operador", nl: "Operator-meldingen", pl: "Alerty operatora", ja: "オペレーターアラート" }, "In-app toasts": { fr: "Toasts dans l'application", de: "In-App-Toasts", it: "Toast in-app", pt: "Toasts na aplicação", nl: "In-app toasts", pl: "Powiadomienia w aplikacji", ja: "アプリ内トースト" }, "Email alerts": { fr: "Alertes e-mail", de: "E-Mail-Benachrichtigungen", it: "Avvisi email", pt: "Alertas por e-mail", nl: "E-mailmeldingen", pl: "Alerty e-mail", ja: "メールアラート" }, "Create API Key": { fr: "Créer une clé API", de: "API-Schlüssel erstellen", it: "Crea chiave API", pt: "Criar chave API", nl: "API-sleutel maken", pl: "Utwórz klucz API", ja: "APIキーを作成" }, "Create API key": { fr: "Créer une clé API", de: "API-Schlüssel erstellen", it: "Crea chiave API", pt: "Criar chave API", nl: "API-sleutel maken", pl: "Utwórz klucz API", ja: "APIキーを作成" }, "API key": { fr: "Clé API", de: "API-Schlüssel", it: "Chiave API", pt: "Chave API", nl: "API-sleutel", pl: "Klucz API", ja: "APIキー" }, "Key name": { fr: "Nom de la clé", de: "Schlüsselname", it: "Nome chiave", pt: "Nome da chave", nl: "Sleutelnaam", pl: "Nazwa klucza", ja: "キー名" }, "Store it somewhere safe.": { fr: "Conservez-la en lieu sûr.", de: "Bewahren Sie ihn sicher auf.", it: "Conservala in un posto sicuro.", pt: "Guarde-a num local seguro.", nl: "Bewaar hem op een veilige plek.", pl: "Przechowuj go w bezpiecznym miejscu.", ja: "安全な場所に保管してください。" }, "Last Used": { fr: "Dernière utilisation", de: "Zuletzt verwendet", it: "Ultimo utilizzo", pt: "Última utilização", nl: "Laatst gebruikt", pl: "Ostatnio użyty", ja: "最終使用" }, "Expires {date}": { fr: "Expire le {date}", de: "Läuft ab am {date}", it: "Scade il {date}", pt: "Expira a {date}", nl: "Verloopt op {date}", pl: "Wygasa {date}", ja: "{date} に期限切れ" }, "Invite for {email}.": { fr: "Invitation pour {email}.", de: "Einladung für {email}.", it: "Invito per {email}.", pt: "Convite para {email}.", nl: "Uitnodiging voor {email}.", pl: "Zaproszenie dla {email}.", ja: "{email} 宛の招待です。" }, "Joined / expires": { fr: "Inscription / expiration", de: "Beigetreten / läuft ab", it: "Iscrizione / scadenza", pt: "Adesão / expira", nl: "Toegetreden / verloopt", pl: "Dołączył / wygasa", ja: "参加 / 期限" }, "Make admin": { fr: "Rendre admin", de: "Zum Admin machen", it: "Rendi admin", pt: "Tornar admin", nl: "Admin maken", pl: "Uczyń adminem", ja: "管理者にする" }, "Make member": { fr: "Rendre membre", de: "Zum Mitglied machen", it: "Rendi membro", pt: "Tornar membro", nl: "Lid maken", pl: "Uczyń członkiem", ja: "メンバーにする" }, "Revoke invite": { fr: "Révoquer l'invitation", de: "Einladung widerrufen", it: "Revoca invito", pt: "Revogar convite", nl: "Uitnodiging intrekken", pl: "Unieważnij zaproszenie", ja: "招待を取り消す" }, "Member actions": { fr: "Actions du membre", de: "Mitgliederaktionen", it: "Azioni del membro", pt: "Ações do membro", nl: "Acties voor lid", pl: "Akcje członka", ja: "メンバーの操作" }, "No teammates yet": { fr: "Pas encore de coéquipiers", de: "Noch keine Teammitglieder", it: "Ancora nessun compagno di team", pt: "Ainda sem colegas", nl: "Nog geen teamleden", pl: "Brak jeszcze członków zespołu", ja: "まだチームメンバーがいません" }, "Share accept link": { fr: "Partager le lien d'acceptation", de: "Annahmelink teilen", it: "Condividi link di accettazione", pt: "Partilhar link de aceitação", nl: "Acceptatielink delen", pl: "Udostępnij link akceptacji", ja: "承認リンクを共有" }, "Accept link copied.": { fr: "Lien d'acceptation copié.", de: "Annahmelink kopiert.", it: "Link di accettazione copiato.", pt: "Link de aceitação copiado.", nl: "Acceptatielink gekopieerd.", pl: "Skopiowano link akceptacji.", ja: "承認リンクをコピーしました。" }, "Invite teammate": { fr: "Inviter un coéquipier", de: "Teammitglied einladen", it: "Invita un collega", pt: "Convidar colega", nl: "Teamlid uitnodigen", pl: "Zaproś członka zespołu", ja: "チームメイトを招待" }, "colleague@example.com": { fr: "collegue@exemple.com", de: "kollege@beispiel.com", it: "collega@esempio.com", pt: "colega@exemplo.com", nl: "collega@voorbeeld.com", pl: "kolega@przyklad.com", ja: "colleague@example.com" }, "Go to Billing": { fr: "Aller à la facturation", de: "Zur Abrechnung", it: "Vai alla fatturazione", pt: "Ir para Faturação", nl: "Naar facturering", pl: "Przejdź do rozliczeń", ja: "請求へ" }, "Dashboard actions": { fr: "Actions du tableau de bord", de: "Dashboard-Aktionen", it: "Azioni dashboard", pt: "Ações do painel", nl: "Dashboardacties", pl: "Akcje panelu", ja: "ダッシュボードの操作" }, "No catalog data yet": { fr: "Pas encore de données catalogue", de: "Noch keine Katalogdaten", it: "Ancora nessun dato di catalogo", pt: "Ainda sem dados de catálogo", nl: "Nog geen catalogusgegevens", pl: "Brak jeszcze danych katalogu", ja: "まだカタログデータがありません" }, "Connect feed anyway": { fr: "Connecter un flux quand même", de: "Feed trotzdem verbinden", it: "Collega comunque un feed", pt: "Ligar feed mesmo assim", nl: "Feed toch koppelen", pl: "Podłącz feed mimo to", ja: "それでもフィードを接続" }, "Import and map": { fr: "Importer et mapper", de: "Importieren und zuordnen", it: "Importa e mappa", pt: "Importar e mapear", nl: "Importeren en mappen", pl: "Importuj i mapuj", ja: "インポートとマップ" }, "Browse and process": { fr: "Parcourir et traiter", de: "Durchsuchen und verarbeiten", it: "Sfoglia ed elabora", pt: "Explorar e processar", nl: "Bladeren en verwerken", pl: "Przeglądaj i przetwarzaj", ja: "閲覧と処理" }, "Monitor tasks": { fr: "Surveiller les tâches", de: "Aufgaben überwachen", it: "Monitora le attività", pt: "Monitorizar tarefas", nl: "Taken monitoren", pl: "Monitoruj zadania", ja: "タスクを監視" }, "Templates & download": { fr: "Modèles et téléchargement", de: "Vorlagen & Download", it: "Modelli e download", pt: "Modelos e transferência", nl: "Sjablonen & download", pl: "Szablony i pobieranie", ja: "テンプレートとダウンロード" }, "Sync a sample": { fr: "Synchroniser un échantillon", de: "Stichprobe synchronisieren", it: "Sincronizza un campione", pt: "Sincronizar uma amostra", nl: "Een steekproef synchroniseren", pl: "Synchronizuj próbkę", ja: "サンプルを同期" }, "Map source fields": { fr: "Mapper les champs source", de: "Quellfelder zuordnen", it: "Mappa campi origine", pt: "Mapear campos de origem", nl: "Bronvelden mappen", pl: "Mapuj pola źródła", ja: "ソースフィールドをマップ" }, "Add or connect a source": { fr: "Ajouter ou connecter une source", de: "Quelle hinzufügen oder verbinden", it: "Aggiungi o collega un'origine", pt: "Adicionar ou ligar uma origem", nl: "Bron toevoegen of koppelen", pl: "Dodaj lub podłącz źródło", ja: "ソースを追加または接続" }, "Latest processing jobs": { fr: "Dernières tâches de traitement", de: "Neueste Verarbeitungsjobs", it: "Ultimi processi di elaborazione", pt: "Últimas tarefas de processamento", nl: "Laatste verwerkingsjobs", pl: "Najnowsze zadania przetwarzania", ja: "最新の処理ジョブ" }, "Credits running low": { fr: "Crédits bientôt épuisés", de: "Credits werden knapp", it: "Crediti in esaurimento", pt: "Créditos a esgotar-se", nl: "Credits raken op", pl: "Kończą się kredyty", ja: "クレジットが少なくなっています" }, "Product limit reached": { fr: "Limite de produits atteinte", de: "Produktlimit erreicht", it: "Limite prodotti raggiunto", pt: "Limite de produtos atingido", nl: "Productlimiet bereikt", pl: "Osiągnięto limit produktów", ja: "商品上限に達しました" }, "You're out of AI credits": { fr: "Vous n'avez plus de crédits IA", de: "Ihre KI-Credits sind aufgebraucht", it: "Hai esaurito i crediti IA", pt: "Ficou sem créditos de IA", nl: "Uw AI-credits zijn op", pl: "Skończyły Ci się kredyty AI", ja: "AIクレジットがなくなりました" }, "You're on the Free plan": { fr: "Vous êtes sur l'offre Free", de: "Sie nutzen den Free-Plan", it: "Sei sul piano Free", pt: "Está no plano Free", nl: "U zit op het Free-plan", pl: "Korzystasz z planu Free", ja: "Freeプランをご利用中です" }, "Trial · {plan}": { fr: "Essai · {plan}", de: "Testphase · {plan}", it: "Prova · {plan}", pt: "Teste · {plan}", nl: "Proef · {plan}", pl: "Okres próbny · {plan}", ja: "トライアル · {plan}" }, "Revoke this invitation?": { fr: "Révoquer cette invitation ?", de: "Diese Einladung widerrufen?", it: "Revocare questo invito?", pt: "Revogar este convite?", nl: "Deze uitnodiging intrekken?", pl: "Unieważnić to zaproszenie?", ja: "この招待を取り消しますか?" }, "Invitation revoked.": { fr: "Invitation révoquée.", de: "Einladung widerrufen.", it: "Invito revocato.", pt: "Convite revogado.", nl: "Uitnodiging ingetrokken.", pl: "Zaproszenie unieważnione.", ja: "招待を取り消しました。" }, "Could not send invite": { fr: "Impossible d'envoyer l'invitation", de: "Einladung konnte nicht gesendet werden", it: "Impossibile inviare l'invito", pt: "Não foi possível enviar o convite", nl: "Uitnodiging kon niet worden verzonden", pl: "Nie można wysłać zaproszenia", ja: "招待を送信できませんでした" }, "Could not revoke invite": { fr: "Impossible de révoquer l'invitation", de: "Einladung konnte nicht widerrufen werden", it: "Impossibile revocare l'invito", pt: "Não foi possível revogar o convite", nl: "Uitnodiging kon niet worden ingetrokken", pl: "Nie można unieważnić zaproszenia", ja: "招待を取り消せませんでした" }, "Could not remove user": { fr: "Impossible de retirer l'utilisateur", de: "Benutzer konnte nicht entfernt werden", it: "Impossibile rimuovere l'utente", pt: "Não foi possível remover o utilizador", nl: "Gebruiker kon niet worden verwijderd", pl: "Nie można usunąć użytkownika", ja: "ユーザーを削除できませんでした" }, "Could not update role": { fr: "Impossible de mettre à jour le rôle", de: "Rolle konnte nicht aktualisiert werden", it: "Impossibile aggiornare il ruolo", pt: "Não foi possível atualizar o papel", nl: "Rol kon niet worden bijgewerkt", pl: "Nie można zaktualizować roli", ja: "ロールを更新できませんでした" }, "Could not verify invite": { fr: "Impossible de vérifier l'invitation", de: "Einladung konnte nicht verifiziert werden", it: "Impossibile verificare l'invito", pt: "Não foi possível verificar o convite", nl: "Uitnodiging kon niet worden geverifieerd", pl: "Nie można zweryfikować zaproszenia", ja: "招待を確認できませんでした" }, "Could not accept invite": { fr: "Impossible d'accepter l'invitation", de: "Einladung konnte nicht angenommen werden", it: "Impossibile accettare l'invito", pt: "Não foi possível aceitar o convite", nl: "Uitnodiging kon niet worden geaccepteerd", pl: "Nie można zaakceptować zaproszenia", ja: "招待を承認できませんでした" }, "Could not set password": { fr: "Impossible de définir le mot de passe", de: "Passwort konnte nicht festgelegt werden", it: "Impossibile impostare la password", pt: "Não foi possível definir a palavra-passe", nl: "Wachtwoord kon niet worden ingesteld", pl: "Nie można ustawić hasła", ja: "パスワードを設定できませんでした" }, "Enter a valid email address.": { fr: "Saisissez une adresse e-mail valide.", de: "Geben Sie eine gültige E-Mail-Adresse ein.", it: "Inserisci un indirizzo email valido.", pt: "Introduza um endereço de e-mail válido.", nl: "Voer een geldig e-mailadres in.", pl: "Wprowadź prawidłowy adres e-mail.", ja: "有効なメールアドレスを入力してください。" }, "Companies need at least one admin": { fr: "Les entreprises ont besoin d'au moins un administrateur", de: "Unternehmen benötigen mindestens einen Admin", it: "Le aziende necessitano di almeno un amministratore", pt: "As empresas precisam de pelo menos um administrador", nl: "Bedrijven hebben minstens één beheerder nodig", pl: "Firmy potrzebują co najmniej jednego administratora", ja: "会社には少なくとも1人の管理者が必要です" }, "Set password first:": { fr: "Définissez d'abord le mot de passe :", de: "Zuerst Passwort festlegen:", it: "Imposta prima la password:", pt: "Defina primeiro a palavra-passe:", nl: "Stel eerst een wachtwoord in:", pl: "Najpierw ustaw hasło:", ja: "先にパスワードを設定:" }, "Platform admins can re-issue from": { fr: "Les administrateurs de la plateforme peuvent réémettre depuis", de: "Plattform-Admins können erneut ausstellen unter", it: "Gli amministratori della piattaforma possono riemettere da", pt: "Os administradores da plataforma podem reemitir a partir de", nl: "Platformbeheerders kunnen opnieuw uitgeven via", pl: "Administratorzy platformy mogą ponownie wystawić z", ja: "プラットフォーム管理者は次から再発行できます:" }, "Have a token? Open accept invite": { fr: "Vous avez un jeton ? Ouvrir accepter l'invitation", de: "Haben Sie ein Token? Einladung annehmen öffnen", it: "Hai un token? Apri accetta invito", pt: "Tem um token? Abrir aceitar convite", nl: "Heeft u een token? Open uitnodiging accepteren", pl: "Masz token? Otwórz akceptację zaproszenia", ja: "トークンがありますか?招待の承認を開く" }, "Have an invite or set-password link?": { fr: "Vous avez une invitation ou un lien de définition de mot de passe ?", de: "Haben Sie eine Einladung oder einen Passwort-Link?", it: "Hai un invito o un link per impostare la password?", pt: "Tem um convite ou um link para definir a palavra-passe?", nl: "Heeft u een uitnodiging of set-wachtwoordlink?", pl: "Masz zaproszenie lub link do ustawienia hasła?", ja: "招待またはパスワード設定リンクがありますか?" }, "Registers a company and its admin user.": { fr: "Enregistre une entreprise et son utilisateur administrateur.", de: "Registriert ein Unternehmen und dessen Admin-Benutzer.", it: "Registra un'azienda e il relativo utente amministratore.", pt: "Regista uma empresa e o respetivo utilizador administrador.", nl: "Registreert een bedrijf en de bijbehorende beheerdersgebruiker.", pl: "Rejestruje firmę i jej użytkownika administratora.", ja: "会社とその管理者ユーザーを登録します。" }, "Checking invite…": { fr: "Vérification de l'invitation…", de: "Einladung wird geprüft…", it: "Verifica invito…", pt: "A verificar convite…", nl: "Uitnodiging controleren…", pl: "Sprawdzanie zaproszenia…", ja: "招待を確認中…" }, "Invite token": { fr: "Jeton d'invitation", de: "Einladungs-Token", it: "Token di invito", pt: "Token de convite", nl: "Uitnodigingstoken", pl: "Token zaproszenia", ja: "招待トークン" }, "Reset token": { fr: "Jeton de réinitialisation", de: "Reset-Token", it: "Token di reimpostazione", pt: "Token de redefinição", nl: "Resettoken", pl: "Token resetowania", ja: "リセットトークン" }, "At least 8 characters. No other complexity rules.": { fr: "Au moins 8 caractères. Aucune autre règle de complexité.", de: "Mindestens 8 Zeichen. Keine weiteren Komplexitätsregeln.", it: "Almeno 8 caratteri. Nessun'altra regola di complessità.", pt: "Pelo menos 8 caracteres. Sem outras regras de complexidade.", nl: "Minimaal 8 tekens. Geen andere complexiteitsregels.", pl: "Co najmniej 8 znaków. Brak innych reguł złożoności.", ja: "8文字以上。その他の複雑さの規則はありません。" }, "Switch account:": { fr: "Changer de compte :", de: "Konto wechseln:", it: "Cambia account:", pt: "Mudar de conta:", nl: "Account wisselen:", pl: "Zmień konto:", ja: "アカウント切替:" }, "Re-issue path:": { fr: "Chemin de réémission :", de: "Neuausstellungs-Pfad:", it: "Percorso di riemissione:", pt: "Caminho de reemissão:", nl: "Pad voor opnieuw uitgeven:", pl: "Ścieżka ponownego wystawienia:", ja: "再発行の手順:" }, "Wrong account for this invite": { fr: "Mauvais compte pour cette invitation", de: "Falsches Konto für diese Einladung", it: "Account errato per questo invito", pt: "Conta errada para este convite", nl: "Verkeerd account voor deze uitnodiging", pl: "Złe konto dla tego zaproszenia", ja: "この招待には別のアカウントが必要です" }, "{email} removed.": { fr: "{email} retiré.", de: "{email} entfernt.", it: "{email} rimosso.", pt: "{email} removido.", nl: "{email} verwijderd.", pl: "Usunięto {email}.", ja: "{email} を削除しました。" }, "{email} is now {role}.": { fr: "{email} est maintenant {role}.", de: "{email} ist jetzt {role}.", it: "{email} ora è {role}.", pt: "{email} é agora {role}.", nl: "{email} is nu {role}.", pl: "{email} jest teraz {role}.", ja: "{email} は現在 {role} です。" }, "{action} {email} to {role}?": { fr: "{action} {email} en {role} ?", de: "{email} zu {role} {action}?", it: "{action} {email} a {role}?", pt: "{action} {email} para {role}?", nl: "{email} naar {role} {action}?", pl: "{action} {email} do {role}?", ja: "{email} を {role} に{action}しますか?" }, "Remove {email} from this company?": { fr: "Retirer {email} de cette entreprise ?", de: "{email} aus diesem Unternehmen entfernen?", it: "Rimuovere {email} da questa azienda?", pt: "Remover {email} desta empresa?", nl: "{email} uit dit bedrijf verwijderen?", pl: "Usunąć {email} z tej firmy?", ja: "{email} をこの会社から削除しますか?" }, "Live totals for {name}": { fr: "Totaux en direct pour {name}", de: "Live-Summen für {name}", it: "Totali in tempo reale per {name}", pt: "Totais em direto para {name}", nl: "Live totalen voor {name}", pl: "Bieżące sumy dla {name}", ja: "{name} のリアルタイム合計" }, "Trial ends {date}. {credits} credits remaining.": { fr: "L'essai se termine le {date}. {credits} crédits restants.", de: "Testphase endet am {date}. {credits} Credits übrig.", it: "La prova termina il {date}. {credits} crediti rimanenti.", pt: "O teste termina a {date}. {credits} créditos restantes.", nl: "Proef eindigt op {date}. {credits} credits resterend.", pl: "Okres próbny kończy się {date}. Pozostało {credits} kredytów.", ja: "トライアルは {date} に終了します。残りクレジット {credits}。" }, "{credits} credits remaining on your trial.": { fr: "{credits} crédits restants sur votre essai.", de: "{credits} Credits verbleiben in Ihrer Testphase.", it: "{credits} crediti rimanenti nella prova.", pt: "{credits} créditos restantes no seu teste.", nl: "{credits} credits resterend op uw proef.", pl: "Pozostało {credits} kredytów w okresie próbnym.", ja: "トライアルの残りクレジットは {credits} です。" }, "Feeds, products, jobs, and export.": { fr: "Flux, produits, tâches et export.", de: "Feeds, Produkte, Jobs und Export.", it: "Feed, prodotti, processi ed esportazione.", pt: "Feeds, produtos, tarefas e exportação.", nl: "Feeds, producten, jobs en export.", pl: "Feedy, produkty, zadania i eksport.", ja: "フィード、商品、ジョブ、エクスポート。" } }; // Merge seed.es + MORE into full phrase-map const map = { ...seed }; for (const [enText, langs] of Object.entries(MORE)) { map[enText] = { ...(map[enText] || {}), ...langs }; } // Also attach es from EXTRA_ES for any en phrases covered by keys for (const [k, es] of Object.entries(EXTRA_ES.es)) { const e = en[k]; if (!e) continue; map[e] = { ...(map[e] || {}), es }; } fs.writeFileSync("phrase-map.json", JSON.stringify(map, null, 2)); console.log("phrase-map entries", Object.keys(map).length); // Count coverage vs needed phrases const needed = JSON.parse(fs.readFileSync("_phrases-needed.json", "utf8")); let covered = 0; const gaps = []; for (const p of needed) { const m = map[p]; if (m && m.fr && m.de && m.it && m.pt && m.nl && m.pl && m.ja) covered++; else gaps.push(p); } console.log("needed", needed.length, "fully covered", covered, "gaps", gaps.length); fs.writeFileSync("_phrase-gaps.json", JSON.stringify(gaps, null, 2));