Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
1328 lines
58 KiB
JavaScript
1328 lines
58 KiB
JavaScript
/**
|
|
* Key-synced UI locale packs for apps/web/src/lib/i18n/messages/.
|
|
* English (en.ts) is source of truth. Missing keys fall back at runtime via i18n.t().
|
|
*
|
|
* Run: node apps/web/scripts/gen-locale-packs.mjs
|
|
*/
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { EXTRA as EXTRA_COMMON, SAME_AS_EN } from "./locale-extra.mjs";
|
|
import { EXTRA as EXTRA_ES } from "./locale-extra-es.mjs";
|
|
import { EXTRA as EXTRA_REST } from "./locale-extra-rest.mjs";
|
|
import { EXTRA as EXTRA_ADMIN } from "./locale-extra-admin.mjs";
|
|
import { EXTRA as EXTRA_CHROME } from "./locale-extra-chrome.mjs";
|
|
import { EXTRA as EXTRA_DEEP_ADMIN } from "./locale-extra-deep-admin.mjs";
|
|
import { EXTRA as EXTRA_BROWSER } from "./locale-extra-browser-leftovers.mjs";
|
|
import { EXTRA as EXTRA_MARKETING } from "./locale-extra-marketing.mjs";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const messagesDir = path.resolve(__dirname, "../src/lib/i18n/messages");
|
|
const enPath = path.join(messagesDir, "en.ts");
|
|
|
|
function parseMessageDict(source) {
|
|
const dict = {};
|
|
const re = /"([^"\\]+)"\s*:\s*((?:"(?:\\.|[^"\\])*")|(?:`(?:\\.|[^`\\])*`))/gs;
|
|
let m;
|
|
while ((m = re.exec(source))) {
|
|
const key = m[1];
|
|
const raw = m[2];
|
|
dict[key] = raw.startsWith("`")
|
|
? raw.slice(1, -1).replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\n/g, "\n")
|
|
: JSON.parse(raw);
|
|
}
|
|
return dict;
|
|
}
|
|
|
|
function emitPack(exportName, comment, dict, keyOrder) {
|
|
const lines = [
|
|
`import type { MessageDict } from "./types";`,
|
|
``,
|
|
`/** ${comment} */`,
|
|
`export const ${exportName}: MessageDict = {`
|
|
];
|
|
for (const key of keyOrder) {
|
|
lines.push(`\t${JSON.stringify(key)}: ${JSON.stringify(dict[key])},`);
|
|
}
|
|
lines.push(`};`, ``);
|
|
return lines.join("\n");
|
|
}
|
|
|
|
/** Per-locale translations keyed by message id (same keys as en.ts). */
|
|
const PACKS = {
|
|
es: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Inicio de Descrybe",
|
|
"common.cancel": "Cancelar",
|
|
"common.save": "Guardar cambios",
|
|
"common.saveShort": "Guardar",
|
|
"common.continue": "Continuar",
|
|
"common.open": "Abrir",
|
|
"common.markDone": "Marcar como hecho",
|
|
"common.viewAll": "Ver todo",
|
|
"common.close": "Cerrar",
|
|
"a11y.skipToContent": "Saltar al contenido",
|
|
"theme.switchToDark": "Cambiar a tema oscuro",
|
|
"theme.switchToLight": "Cambiar a tema claro",
|
|
"header.signOut": "Cerrar sesión",
|
|
"header.signingOut": "Cerrando sesión…",
|
|
"status.emDash": "—",
|
|
"status.pending": "Pendiente",
|
|
"nav.section.overview": "Resumen",
|
|
"nav.section.catalog": "Catálogo",
|
|
"nav.section.feeds": "Feeds",
|
|
"nav.section.stores": "Tiendas",
|
|
"nav.section.processing": "Procesamiento",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integraciones",
|
|
"nav.section.account": "Cuenta",
|
|
"nav.section.platform": "Plataforma",
|
|
"nav.dashboard": "Panel",
|
|
"nav.products": "Productos",
|
|
"nav.categories": "Categorías",
|
|
"nav.attributes": "Atributos",
|
|
"nav.fields": "Campos",
|
|
"nav.feeds": "Feeds",
|
|
"nav.exports": "Exportaciones",
|
|
"nav.stores": "Tiendas",
|
|
"nav.jobs": "Trabajos",
|
|
"nav.campaigns": "Campañas",
|
|
"nav.calendar": "Calendario",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marca",
|
|
"nav.reviews": "Reseñas",
|
|
"nav.ai": "IA",
|
|
"nav.email": "Correo",
|
|
"nav.billing": "Facturación",
|
|
"nav.settings": "Configuración",
|
|
"nav.support": "Soporte",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Navegación principal",
|
|
"nav.sidebar": "Barra lateral de la app",
|
|
"nav.close": "Cerrar navegación",
|
|
"nav.closeMenu": "Cerrar menú",
|
|
"nav.open": "Abrir navegación",
|
|
"nav.commandPalette": "Abrir paleta de comandos",
|
|
"locale.switcher": "Idioma de la interfaz",
|
|
"locale.menu": "Elegir idioma de la interfaz",
|
|
"locale.label": "Idioma del panel",
|
|
"locale.help":
|
|
"Cambia las etiquetas de la navegación y la configuración. El idioma del contenido generado se define por separado en Empresa.",
|
|
"settings.contentLanguage": "Idioma del contenido",
|
|
"settings.contentLanguageHelp":
|
|
"Idioma usado para títulos de producto, descripciones y otro contenido generado",
|
|
"settings.tab.profile": "Perfil",
|
|
"settings.tab.company": "Empresa",
|
|
"settings.tab.alerts": "Alertas",
|
|
"settings.tab.apiKeys": "Claves API",
|
|
"settings.tab.team": "Equipo",
|
|
"settings.title": "Configuración",
|
|
"settings.description": "Cuenta, empresa, claves API y equipo.",
|
|
"dashboard.demoSandbox": "Zona de pruebas demo",
|
|
"dashboard.demoEmptyTitle": "La zona de pruebas demo está vacía",
|
|
"dashboard.overviewTitle": "Resumen",
|
|
"dashboard.quickLinks": "Enlaces rápidos",
|
|
"dashboard.whatsNew": "Novedades",
|
|
"dashboard.startTutorial": "Iniciar tutorial",
|
|
"dashboard.connectFeed": "Conectar un feed",
|
|
"dashboard.workflowTitle": "Flujo del catálogo",
|
|
"dashboard.recentActivity": "Actividad reciente",
|
|
"dashboard.loadFailed": "No se pudo cargar el panel",
|
|
"dashboard.workspaceFallback": "Este espacio de trabajo",
|
|
"dashboard.jobFallback": "Trabajo {id}",
|
|
"dashboard.workflow.feeds.connect": "Conectar importación",
|
|
"dashboard.workflow.products.build": "Crear catálogo",
|
|
"dashboard.workflow.products.count": "{count} en el catálogo",
|
|
"dashboard.workflow.process": "Procesar",
|
|
"dashboard.workflow.processActive": "{count} activos",
|
|
"dashboard.workflow.processWaiting": "{count} en espera",
|
|
"dashboard.workflow.processDone": "{count} listos",
|
|
"dashboard.workflow.processRun": "Ejecutar trabajos de IA",
|
|
"dashboard.workflow.export": "Exportar",
|
|
"dashboard.workflow.exportReady": "Plantillas y descarga",
|
|
"dashboard.workflow.exportMap": "Mapear y exportar",
|
|
"activation.title": "Primeros pasos",
|
|
"activation.description":
|
|
"Ruta de valor inicial desde tu espacio de trabajo: activar campos → conectar un origen → mapear → sincronizar muestra → procesar → exportar. El recorrido de demostración explica estas pantallas sin cambiar el progreso de la lista.",
|
|
"activation.dismiss": "Descartar lista",
|
|
"activation.progress": "{done} de {total} completados",
|
|
"activation.stepsLabel": "Pasos de activación",
|
|
"activation.pausedTitle": "Primeros pasos en pausa",
|
|
"activation.pausedBody":
|
|
"Reanuda la lista cuando quieras — desde activar campos hasta exportar.",
|
|
"activation.resume": "Reanudar lista",
|
|
"stats.products": "Productos",
|
|
"stats.categories": "Categorías",
|
|
"stats.attributes": "Atributos",
|
|
"stats.feeds": "Feeds",
|
|
"stats.credits": "Créditos",
|
|
"stats.openCatalog": "Abrir catálogo",
|
|
"stats.productsHint": "{processed} procesados · {unprocessed} sin procesar",
|
|
"stats.catalogTree": "Árbol del catálogo",
|
|
"stats.attributeLibrary": "Biblioteca de atributos",
|
|
"stats.importSources": "Orígenes de importación",
|
|
"stats.payAsYouGo": "Pago por uso",
|
|
"stats.walletBilling": "Monedero · Facturación",
|
|
"stats.enterpriseBilling": "Enterprise · Facturación",
|
|
"stats.usedBilling": "{used} usados · Facturación",
|
|
"processing.jobStatus.processing": "Procesando",
|
|
"processing.jobStatus.completed": "Completado",
|
|
"processing.jobStatus.failed": "Fallido",
|
|
"processing.jobStatus.cancelled": "Cancelado",
|
|
"processing.jobStatus.pending": "Pendiente",
|
|
"processing.jobStatus.queued": "En cola",
|
|
"processing.jobStatus.skipped": "Omitido",
|
|
"processing.jobStatus.unknown": "Desconocido",
|
|
"processing.step.normalize": "Normalizar",
|
|
"processing.step.parse_specs": "Analizar especificaciones",
|
|
"processing.step.fill_fields": "Completar campos",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "Mejora con IA",
|
|
"errors.requestFailed": "La solicitud falló",
|
|
"errors.maintenance": "El sistema está en mantenimiento. Inténtalo más tarde.",
|
|
"errors.readOnly":
|
|
"El sistema está en modo de solo lectura. Los cambios están temporalmente deshabilitados.",
|
|
"errors.companyAdminDenied":
|
|
"Solo los administradores de la empresa pueden {action}. Pide ayuda a un administrador.",
|
|
"errors.companyAdminDenied.actionDefault": "hacer esto",
|
|
"errors.couldNotUpdateLanguage": "No se pudo actualizar el idioma",
|
|
"toast.support.replyTitle": "Respuesta de soporte",
|
|
"toast.support.replyBody": "El equipo respondió a tu ticket de soporte.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Estado del ticket actualizado",
|
|
"toast.support.statusBody": "El estado de tu ticket de soporte cambió.",
|
|
"toast.support.updateTitle": "Actualización de soporte",
|
|
"flash.contentLanguageUpdated": "Idioma del contenido actualizado."
|
|
},
|
|
fr: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Accueil Descrybe",
|
|
"common.cancel": "Annuler",
|
|
"common.save": "Enregistrer les modifications",
|
|
"common.saveShort": "Enregistrer",
|
|
"common.continue": "Continuer",
|
|
"common.open": "Ouvrir",
|
|
"common.markDone": "Marquer comme terminé",
|
|
"common.viewAll": "Tout voir",
|
|
"common.close": "Fermer",
|
|
"a11y.skipToContent": "Aller au contenu",
|
|
"theme.switchToDark": "Passer au thème sombre",
|
|
"theme.switchToLight": "Passer au thème clair",
|
|
"header.signOut": "Se déconnecter",
|
|
"header.signingOut": "Déconnexion…",
|
|
"status.emDash": "—",
|
|
"status.pending": "En attente",
|
|
"nav.section.overview": "Aperçu",
|
|
"nav.section.catalog": "Catalogue",
|
|
"nav.section.feeds": "Flux",
|
|
"nav.section.stores": "Boutiques",
|
|
"nav.section.processing": "Traitement",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Intégrations",
|
|
"nav.section.account": "Compte",
|
|
"nav.section.platform": "Plateforme",
|
|
"nav.dashboard": "Tableau de bord",
|
|
"nav.products": "Produits",
|
|
"nav.categories": "Catégories",
|
|
"nav.attributes": "Attributs",
|
|
"nav.fields": "Champs",
|
|
"nav.feeds": "Flux",
|
|
"nav.exports": "Exportations",
|
|
"nav.stores": "Boutiques",
|
|
"nav.jobs": "Tâches",
|
|
"nav.campaigns": "Campagnes",
|
|
"nav.calendar": "Calendrier",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marque",
|
|
"nav.reviews": "Avis",
|
|
"nav.ai": "IA",
|
|
"nav.email": "E-mail",
|
|
"nav.billing": "Facturation",
|
|
"nav.settings": "Paramètres",
|
|
"nav.support": "Assistance",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Navigation principale",
|
|
"nav.sidebar": "Barre latérale de l'application",
|
|
"nav.close": "Fermer la navigation",
|
|
"nav.closeMenu": "Fermer le menu",
|
|
"nav.open": "Ouvrir la navigation",
|
|
"nav.commandPalette": "Ouvrir la palette de commandes",
|
|
"locale.switcher": "Langue de l'interface",
|
|
"locale.menu": "Choisir la langue de l'interface",
|
|
"locale.label": "Langue du tableau de bord",
|
|
"locale.help":
|
|
"Modifie les libellés de la navigation et des paramètres. La langue du contenu généré se règle séparément sous Entreprise.",
|
|
"settings.contentLanguage": "Langue du contenu",
|
|
"settings.contentLanguageHelp":
|
|
"Langue utilisée pour les titres de produits, descriptions et autres contenus générés",
|
|
"settings.tab.profile": "Profil",
|
|
"settings.tab.company": "Entreprise",
|
|
"settings.tab.alerts": "Alertes",
|
|
"settings.tab.apiKeys": "Clés API",
|
|
"settings.tab.team": "Équipe",
|
|
"settings.title": "Paramètres",
|
|
"settings.description": "Compte, entreprise, clés API et équipe.",
|
|
"dashboard.demoSandbox": "Bac à sable démo",
|
|
"dashboard.demoEmptyTitle": "Le bac à sable démo est vide",
|
|
"dashboard.overviewTitle": "Aperçu",
|
|
"dashboard.quickLinks": "Liens rapides",
|
|
"dashboard.whatsNew": "Nouveautés",
|
|
"dashboard.startTutorial": "Lancer le tutoriel",
|
|
"dashboard.connectFeed": "Connecter un flux",
|
|
"dashboard.workflowTitle": "Flux catalogue",
|
|
"dashboard.recentActivity": "Activité récente",
|
|
"dashboard.loadFailed": "Échec du chargement du tableau de bord",
|
|
"dashboard.workspaceFallback": "Cet espace de travail",
|
|
"dashboard.jobFallback": "Tâche {id}",
|
|
"dashboard.workflow.feeds.connect": "Connecter l'import",
|
|
"dashboard.workflow.products.build": "Construire le catalogue",
|
|
"dashboard.workflow.products.count": "{count} dans le catalogue",
|
|
"dashboard.workflow.process": "Traiter",
|
|
"dashboard.workflow.processActive": "{count} actifs",
|
|
"dashboard.workflow.processWaiting": "{count} en attente",
|
|
"dashboard.workflow.processDone": "{count} terminés",
|
|
"dashboard.workflow.processRun": "Lancer les tâches IA",
|
|
"dashboard.workflow.export": "Exporter",
|
|
"dashboard.workflow.exportReady": "Modèles et téléchargement",
|
|
"dashboard.workflow.exportMap": "Mapper puis exporter",
|
|
"activation.title": "Premiers pas",
|
|
"activation.description":
|
|
"Parcours de valeur initial depuis votre espace de travail : activer les champs → connecter une source → mapper → synchroniser un échantillon → traiter → exporter. Le parcours démo explique ces écrans sans modifier la progression de la checklist.",
|
|
"activation.dismiss": "Masquer la checklist",
|
|
"activation.progress": "{done} sur {total} terminés",
|
|
"activation.stepsLabel": "Étapes d'activation",
|
|
"activation.pausedTitle": "Premiers pas en pause",
|
|
"activation.pausedBody":
|
|
"Reprenez la checklist à tout moment — de l'activation des champs jusqu'à l'export.",
|
|
"activation.resume": "Reprendre la checklist",
|
|
"stats.products": "Produits",
|
|
"stats.categories": "Catégories",
|
|
"stats.attributes": "Attributs",
|
|
"stats.feeds": "Flux",
|
|
"stats.credits": "Crédits",
|
|
"stats.openCatalog": "Ouvrir le catalogue",
|
|
"stats.productsHint": "{processed} traités · {unprocessed} non traités",
|
|
"stats.catalogTree": "Arborescence du catalogue",
|
|
"stats.attributeLibrary": "Bibliothèque d'attributs",
|
|
"stats.importSources": "Sources d'import",
|
|
"stats.payAsYouGo": "Paiement à l'usage",
|
|
"stats.walletBilling": "Portefeuille · Facturation",
|
|
"stats.enterpriseBilling": "Enterprise · Facturation",
|
|
"stats.usedBilling": "{used} utilisés · Facturation",
|
|
"processing.jobStatus.processing": "En cours",
|
|
"processing.jobStatus.completed": "Terminé",
|
|
"processing.jobStatus.failed": "Échoué",
|
|
"processing.jobStatus.cancelled": "Annulé",
|
|
"processing.jobStatus.pending": "En attente",
|
|
"processing.jobStatus.queued": "En file",
|
|
"processing.jobStatus.skipped": "Ignoré",
|
|
"processing.jobStatus.unknown": "Inconnu",
|
|
"processing.step.normalize": "Normaliser",
|
|
"processing.step.parse_specs": "Analyser les specs",
|
|
"processing.step.fill_fields": "Remplir les champs",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "Amélioration IA",
|
|
"errors.requestFailed": "Échec de la requête",
|
|
"errors.maintenance": "Le système est en maintenance. Réessayez plus tard.",
|
|
"errors.readOnly":
|
|
"Le système est en mode lecture seule. Les modifications sont temporairement désactivées.",
|
|
"errors.companyAdminDenied":
|
|
"Seuls les administrateurs de l'entreprise peuvent {action}. Demandez de l'aide à un administrateur.",
|
|
"errors.companyAdminDenied.actionDefault": "faire ceci",
|
|
"errors.couldNotUpdateLanguage": "Impossible de mettre à jour la langue",
|
|
"toast.support.replyTitle": "Réponse du support",
|
|
"toast.support.replyBody": "L'équipe a répondu à votre ticket de support.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Statut du ticket mis à jour",
|
|
"toast.support.statusBody": "Le statut de votre ticket de support a changé.",
|
|
"toast.support.updateTitle": "Mise à jour du support",
|
|
"flash.contentLanguageUpdated": "Langue du contenu mise à jour."
|
|
},
|
|
de: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Descrybe-Startseite",
|
|
"common.cancel": "Abbrechen",
|
|
"common.save": "Änderungen speichern",
|
|
"common.saveShort": "Speichern",
|
|
"common.continue": "Weiter",
|
|
"common.open": "Öffnen",
|
|
"common.markDone": "Als erledigt markieren",
|
|
"common.viewAll": "Alle anzeigen",
|
|
"common.close": "Schließen",
|
|
"a11y.skipToContent": "Zum Inhalt springen",
|
|
"theme.switchToDark": "Zum dunklen Design wechseln",
|
|
"theme.switchToLight": "Zum hellen Design wechseln",
|
|
"header.signOut": "Abmelden",
|
|
"header.signingOut": "Abmelden…",
|
|
"status.emDash": "—",
|
|
"status.pending": "Ausstehend",
|
|
"nav.section.overview": "Übersicht",
|
|
"nav.section.catalog": "Katalog",
|
|
"nav.section.feeds": "Feeds",
|
|
"nav.section.stores": "Shops",
|
|
"nav.section.processing": "Verarbeitung",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integrationen",
|
|
"nav.section.account": "Konto",
|
|
"nav.section.platform": "Plattform",
|
|
"nav.dashboard": "Übersicht",
|
|
"nav.products": "Produkte",
|
|
"nav.categories": "Kategorien",
|
|
"nav.attributes": "Attribute",
|
|
"nav.fields": "Felder",
|
|
"nav.feeds": "Feeds",
|
|
"nav.exports": "Exporte",
|
|
"nav.stores": "Shops",
|
|
"nav.jobs": "Aufträge",
|
|
"nav.campaigns": "Kampagnen",
|
|
"nav.calendar": "Kalender",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marke",
|
|
"nav.reviews": "Bewertungen",
|
|
"nav.ai": "KI",
|
|
"nav.email": "E-Mail",
|
|
"nav.billing": "Abrechnung",
|
|
"nav.settings": "Einstellungen",
|
|
"nav.support": "Hilfe",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Hauptnavigation",
|
|
"nav.sidebar": "App-Seitenleiste",
|
|
"nav.close": "Navigation schließen",
|
|
"nav.closeMenu": "Menü schließen",
|
|
"nav.open": "Navigation öffnen",
|
|
"nav.commandPalette": "Befehlspalette öffnen",
|
|
"locale.switcher": "Oberflächensprache",
|
|
"locale.menu": "Oberflächensprache wählen",
|
|
"locale.label": "Dashboard-Sprache",
|
|
"locale.help":
|
|
"Ändert Beschriftungen in Navigation und Einstellungen. Die Sprache für generierte Inhalte wird separat unter Unternehmen festgelegt.",
|
|
"settings.contentLanguage": "Inhaltssprache",
|
|
"settings.contentLanguageHelp":
|
|
"Sprache für Produkttitel, Beschreibungen und andere generierte Inhalte",
|
|
"settings.tab.profile": "Profil",
|
|
"settings.tab.company": "Unternehmen",
|
|
"settings.tab.alerts": "Benachrichtigungen",
|
|
"settings.tab.apiKeys": "API-Schlüssel",
|
|
"settings.tab.team": "Team",
|
|
"settings.title": "Einstellungen",
|
|
"settings.description": "Konto, Unternehmen, API-Schlüssel und Team.",
|
|
"dashboard.demoSandbox": "Demo-Sandbox",
|
|
"dashboard.demoEmptyTitle": "Demo-Sandbox ist leer",
|
|
"dashboard.overviewTitle": "Übersicht",
|
|
"dashboard.quickLinks": "Schnelllinks",
|
|
"dashboard.whatsNew": "Neuigkeiten",
|
|
"dashboard.startTutorial": "Tutorial starten",
|
|
"dashboard.connectFeed": "Feed verbinden",
|
|
"dashboard.workflowTitle": "Katalog-Workflow",
|
|
"dashboard.recentActivity": "Letzte Aktivität",
|
|
"dashboard.loadFailed": "Dashboard konnte nicht geladen werden",
|
|
"dashboard.workspaceFallback": "Dieser Arbeitsbereich",
|
|
"dashboard.jobFallback": "Auftrag {id}",
|
|
"dashboard.workflow.feeds.connect": "Import verbinden",
|
|
"dashboard.workflow.products.build": "Katalog aufbauen",
|
|
"dashboard.workflow.products.count": "{count} im Katalog",
|
|
"dashboard.workflow.process": "Verarbeiten",
|
|
"dashboard.workflow.processActive": "{count} aktiv",
|
|
"dashboard.workflow.processWaiting": "{count} wartend",
|
|
"dashboard.workflow.processDone": "{count} erledigt",
|
|
"dashboard.workflow.processRun": "KI-Jobs ausführen",
|
|
"dashboard.workflow.export": "Exportieren",
|
|
"dashboard.workflow.exportReady": "Vorlagen & Download",
|
|
"dashboard.workflow.exportMap": "Zuordnen dann exportieren",
|
|
"activation.title": "Erste Schritte",
|
|
"activation.description":
|
|
"Erster Wertpfad aus Ihrem Arbeitsbereich: Felder aktivieren → Quelle verbinden → zuordnen → Stichprobe synchronisieren → verarbeiten → exportieren. Die Demo-Tour erklärt diese Bildschirme, ohne den Checklistenfortschritt zu ändern.",
|
|
"activation.dismiss": "Checkliste ausblenden",
|
|
"activation.progress": "{done} von {total} erledigt",
|
|
"activation.stepsLabel": "Aktivierungsschritte",
|
|
"activation.pausedTitle": "Erste Schritte pausiert",
|
|
"activation.pausedBody":
|
|
"Setzen Sie die Checkliste jederzeit fort — von Feldern aktivieren bis Export.",
|
|
"activation.resume": "Checkliste fortsetzen",
|
|
"stats.products": "Produkte",
|
|
"stats.categories": "Kategorien",
|
|
"stats.attributes": "Attribute",
|
|
"stats.feeds": "Feeds",
|
|
"stats.credits": "Guthaben",
|
|
"stats.openCatalog": "Katalog öffnen",
|
|
"stats.productsHint": "{processed} verarbeitet · {unprocessed} unverarbeitet",
|
|
"stats.catalogTree": "Katalogbaum",
|
|
"stats.attributeLibrary": "Attributbibliothek",
|
|
"stats.importSources": "Importquellen",
|
|
"stats.payAsYouGo": "Nutzung nach Verbrauch",
|
|
"stats.walletBilling": "Wallet · Abrechnung",
|
|
"stats.enterpriseBilling": "Enterprise · Abrechnung",
|
|
"stats.usedBilling": "{used} verbraucht · Abrechnung",
|
|
"processing.jobStatus.processing": "Verarbeitung",
|
|
"processing.jobStatus.completed": "Abgeschlossen",
|
|
"processing.jobStatus.failed": "Fehlgeschlagen",
|
|
"processing.jobStatus.cancelled": "Abgebrochen",
|
|
"processing.jobStatus.pending": "Ausstehend",
|
|
"processing.jobStatus.queued": "In Warteschlange",
|
|
"processing.jobStatus.skipped": "Übersprungen",
|
|
"processing.jobStatus.unknown": "Unbekannt",
|
|
"processing.step.normalize": "Normalisieren",
|
|
"processing.step.parse_specs": "Specs parsen",
|
|
"processing.step.fill_fields": "Felder füllen",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "KI-Verbesserung",
|
|
"errors.requestFailed": "Anfrage fehlgeschlagen",
|
|
"errors.maintenance": "Das System ist in Wartung. Versuchen Sie es später erneut.",
|
|
"errors.readOnly":
|
|
"Das System ist im Nur-Lesen-Modus. Änderungen sind vorübergehend deaktiviert.",
|
|
"errors.companyAdminDenied":
|
|
"Nur Unternehmens-Admins können {action}. Bitten Sie einen Admin um Hilfe.",
|
|
"errors.companyAdminDenied.actionDefault": "dies tun",
|
|
"errors.couldNotUpdateLanguage": "Sprache konnte nicht aktualisiert werden",
|
|
"toast.support.replyTitle": "Support-Antwort",
|
|
"toast.support.replyBody": "Das Team hat auf Ihr Support-Ticket geantwortet.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Ticketstatus aktualisiert",
|
|
"toast.support.statusBody": "Der Status Ihres Support-Tickets hat sich geändert.",
|
|
"toast.support.updateTitle": "Support-Update",
|
|
"flash.contentLanguageUpdated": "Inhaltssprache aktualisiert."
|
|
},
|
|
it: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Home Descrybe",
|
|
"common.cancel": "Annulla",
|
|
"common.save": "Salva modifiche",
|
|
"common.saveShort": "Salva",
|
|
"common.continue": "Continua",
|
|
"common.open": "Apri",
|
|
"common.markDone": "Segna come fatto",
|
|
"common.viewAll": "Vedi tutto",
|
|
"common.close": "Chiudi",
|
|
"a11y.skipToContent": "Vai al contenuto",
|
|
"theme.switchToDark": "Passa al tema scuro",
|
|
"theme.switchToLight": "Passa al tema chiaro",
|
|
"header.signOut": "Esci",
|
|
"header.signingOut": "Disconnessione…",
|
|
"status.emDash": "—",
|
|
"status.pending": "In sospeso",
|
|
"nav.section.overview": "Panoramica",
|
|
"nav.section.catalog": "Catalogo",
|
|
"nav.section.feeds": "Feed",
|
|
"nav.section.stores": "Negozi",
|
|
"nav.section.processing": "Elaborazione",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integrazioni",
|
|
"nav.section.account": "Account",
|
|
"nav.section.platform": "Piattaforma",
|
|
"nav.dashboard": "Cruscotto",
|
|
"nav.products": "Prodotti",
|
|
"nav.categories": "Categorie",
|
|
"nav.attributes": "Attributi",
|
|
"nav.fields": "Campi",
|
|
"nav.feeds": "Feed",
|
|
"nav.exports": "Esportazioni",
|
|
"nav.stores": "Negozi",
|
|
"nav.jobs": "Processi",
|
|
"nav.campaigns": "Campagne",
|
|
"nav.calendar": "Calendario",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marchio",
|
|
"nav.reviews": "Recensioni",
|
|
"nav.ai": "IA",
|
|
"nav.email": "Email",
|
|
"nav.billing": "Fatturazione",
|
|
"nav.settings": "Impostazioni",
|
|
"nav.support": "Supporto",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Navigazione principale",
|
|
"nav.sidebar": "Barra laterale app",
|
|
"nav.close": "Chiudi navigazione",
|
|
"nav.closeMenu": "Chiudi menu",
|
|
"nav.open": "Apri navigazione",
|
|
"nav.commandPalette": "Apri palette comandi",
|
|
"locale.switcher": "Lingua dell'interfaccia",
|
|
"locale.menu": "Scegli la lingua dell'interfaccia",
|
|
"locale.label": "Lingua della dashboard",
|
|
"locale.help":
|
|
"Modifica le etichette di navigazione e impostazioni. La lingua dei contenuti generati si imposta separatamente in Azienda.",
|
|
"settings.contentLanguage": "Lingua dei contenuti",
|
|
"settings.contentLanguageHelp":
|
|
"Lingua usata per titoli prodotto, descrizioni e altri contenuti generati",
|
|
"settings.tab.profile": "Profilo",
|
|
"settings.tab.company": "Azienda",
|
|
"settings.tab.alerts": "Avvisi",
|
|
"settings.tab.apiKeys": "Chiavi API",
|
|
"settings.tab.team": "Team",
|
|
"settings.title": "Impostazioni",
|
|
"settings.description": "Account, azienda, chiavi API e team.",
|
|
"dashboard.demoSandbox": "Sandbox demo",
|
|
"dashboard.demoEmptyTitle": "La sandbox demo è vuota",
|
|
"dashboard.overviewTitle": "Panoramica",
|
|
"dashboard.quickLinks": "Collegamenti rapidi",
|
|
"dashboard.whatsNew": "Novità",
|
|
"dashboard.startTutorial": "Avvia tutorial",
|
|
"dashboard.connectFeed": "Collega un feed",
|
|
"dashboard.workflowTitle": "Flusso catalogo",
|
|
"dashboard.recentActivity": "Attività recente",
|
|
"dashboard.loadFailed": "Impossibile caricare la dashboard",
|
|
"dashboard.workspaceFallback": "Questo spazio di lavoro",
|
|
"dashboard.jobFallback": "Processo {id}",
|
|
"dashboard.workflow.feeds.connect": "Collega importazione",
|
|
"dashboard.workflow.products.build": "Crea catalogo",
|
|
"dashboard.workflow.products.count": "{count} nel catalogo",
|
|
"dashboard.workflow.process": "Elabora",
|
|
"dashboard.workflow.processActive": "{count} attivi",
|
|
"dashboard.workflow.processWaiting": "{count} in attesa",
|
|
"dashboard.workflow.processDone": "{count} completati",
|
|
"dashboard.workflow.processRun": "Esegui job IA",
|
|
"dashboard.workflow.export": "Esporta",
|
|
"dashboard.workflow.exportReady": "Modelli e download",
|
|
"dashboard.workflow.exportMap": "Mappa poi esporta",
|
|
"activation.title": "Per iniziare",
|
|
"activation.description":
|
|
"Percorso di valore iniziale dal tuo spazio di lavoro: abilita campi → collega un'origine → mappa → sincronizza campione → elabora → esporta. Il tour demo spiega queste schermate senza modificare l'avanzamento della checklist.",
|
|
"activation.dismiss": "Nascondi checklist",
|
|
"activation.progress": "{done} di {total} completati",
|
|
"activation.stepsLabel": "Passaggi di attivazione",
|
|
"activation.pausedTitle": "Per iniziare in pausa",
|
|
"activation.pausedBody":
|
|
"Riprendi la checklist in qualsiasi momento — dall'abilitazione dei campi all'esportazione.",
|
|
"activation.resume": "Riprendi checklist",
|
|
"stats.products": "Prodotti",
|
|
"stats.categories": "Categorie",
|
|
"stats.attributes": "Attributi",
|
|
"stats.feeds": "Feed",
|
|
"stats.credits": "Crediti",
|
|
"stats.openCatalog": "Apri catalogo",
|
|
"stats.productsHint": "{processed} elaborati · {unprocessed} non elaborati",
|
|
"stats.catalogTree": "Albero catalogo",
|
|
"stats.attributeLibrary": "Libreria attributi",
|
|
"stats.importSources": "Origini di importazione",
|
|
"stats.payAsYouGo": "Pagamento a consumo",
|
|
"stats.walletBilling": "Wallet · Fatturazione",
|
|
"stats.enterpriseBilling": "Enterprise · Fatturazione",
|
|
"stats.usedBilling": "{used} usati · Fatturazione",
|
|
"processing.jobStatus.processing": "Elaborazione",
|
|
"processing.jobStatus.completed": "Completato",
|
|
"processing.jobStatus.failed": "Non riuscito",
|
|
"processing.jobStatus.cancelled": "Annullato",
|
|
"processing.jobStatus.pending": "In sospeso",
|
|
"processing.jobStatus.queued": "In coda",
|
|
"processing.jobStatus.skipped": "Saltato",
|
|
"processing.jobStatus.unknown": "Sconosciuto",
|
|
"processing.step.normalize": "Normalizza",
|
|
"processing.step.parse_specs": "Analizza specifiche",
|
|
"processing.step.fill_fields": "Compila campi",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "Miglioramento IA",
|
|
"errors.requestFailed": "Richiesta non riuscita",
|
|
"errors.maintenance": "Il sistema è in manutenzione. Riprova più tardi.",
|
|
"errors.readOnly":
|
|
"Il sistema è in modalità sola lettura. Le modifiche sono temporaneamente disabilitate.",
|
|
"errors.companyAdminDenied":
|
|
"Solo gli amministratori dell'azienda possono {action}. Chiedi aiuto a un amministratore.",
|
|
"errors.companyAdminDenied.actionDefault": "fare questo",
|
|
"errors.couldNotUpdateLanguage": "Impossibile aggiornare la lingua",
|
|
"toast.support.replyTitle": "Risposta del supporto",
|
|
"toast.support.replyBody": "Lo staff ha risposto al tuo ticket di supporto.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Stato ticket aggiornato",
|
|
"toast.support.statusBody": "Lo stato del tuo ticket di supporto è cambiato.",
|
|
"toast.support.updateTitle": "Aggiornamento supporto",
|
|
"flash.contentLanguageUpdated": "Lingua dei contenuti aggiornata."
|
|
},
|
|
pt: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Início Descrybe",
|
|
"common.cancel": "Cancelar",
|
|
"common.save": "Guardar alterações",
|
|
"common.saveShort": "Guardar",
|
|
"common.continue": "Continuar",
|
|
"common.open": "Abrir",
|
|
"common.markDone": "Marcar como concluído",
|
|
"common.viewAll": "Ver tudo",
|
|
"common.close": "Fechar",
|
|
"a11y.skipToContent": "Saltar para o conteúdo",
|
|
"theme.switchToDark": "Mudar para tema escuro",
|
|
"theme.switchToLight": "Mudar para tema claro",
|
|
"header.signOut": "Terminar sessão",
|
|
"header.signingOut": "A terminar sessão…",
|
|
"status.emDash": "—",
|
|
"status.pending": "Pendente",
|
|
"nav.section.overview": "Visão geral",
|
|
"nav.section.catalog": "Catálogo",
|
|
"nav.section.feeds": "Feeds",
|
|
"nav.section.stores": "Lojas",
|
|
"nav.section.processing": "Processamento",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integrações",
|
|
"nav.section.account": "Conta",
|
|
"nav.section.platform": "Plataforma",
|
|
"nav.dashboard": "Painel",
|
|
"nav.products": "Produtos",
|
|
"nav.categories": "Categorias",
|
|
"nav.attributes": "Atributos",
|
|
"nav.fields": "Campos",
|
|
"nav.feeds": "Feeds",
|
|
"nav.exports": "Exportações",
|
|
"nav.stores": "Lojas",
|
|
"nav.jobs": "Tarefas",
|
|
"nav.campaigns": "Campanhas",
|
|
"nav.calendar": "Calendário",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marca",
|
|
"nav.reviews": "Avaliações",
|
|
"nav.ai": "IA",
|
|
"nav.email": "E-mail",
|
|
"nav.billing": "Faturação",
|
|
"nav.settings": "Definições",
|
|
"nav.support": "Suporte",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Navegação principal",
|
|
"nav.sidebar": "Barra lateral da app",
|
|
"nav.close": "Fechar navegação",
|
|
"nav.closeMenu": "Fechar menu",
|
|
"nav.open": "Abrir navegação",
|
|
"nav.commandPalette": "Abrir paleta de comandos",
|
|
"locale.switcher": "Idioma da interface",
|
|
"locale.menu": "Escolher idioma da interface",
|
|
"locale.label": "Idioma do painel",
|
|
"locale.help":
|
|
"Altera as etiquetas da navegação e das definições. O idioma do conteúdo gerado é definido separadamente em Empresa.",
|
|
"settings.contentLanguage": "Idioma do conteúdo",
|
|
"settings.contentLanguageHelp":
|
|
"Idioma usado para títulos de produto, descrições e outro conteúdo gerado",
|
|
"settings.tab.profile": "Perfil",
|
|
"settings.tab.company": "Empresa",
|
|
"settings.tab.alerts": "Alertas",
|
|
"settings.tab.apiKeys": "Chaves API",
|
|
"settings.tab.team": "Equipa",
|
|
"settings.title": "Definições",
|
|
"settings.description": "Conta, empresa, chaves API e equipa.",
|
|
"dashboard.demoSandbox": "Sandbox de demonstração",
|
|
"dashboard.demoEmptyTitle": "A sandbox de demonstração está vazia",
|
|
"dashboard.overviewTitle": "Visão geral",
|
|
"dashboard.quickLinks": "Ligações rápidas",
|
|
"dashboard.whatsNew": "Novidades",
|
|
"dashboard.startTutorial": "Iniciar tutorial",
|
|
"dashboard.connectFeed": "Ligar um feed",
|
|
"dashboard.workflowTitle": "Fluxo do catálogo",
|
|
"dashboard.recentActivity": "Atividade recente",
|
|
"dashboard.loadFailed": "Falha ao carregar o painel",
|
|
"dashboard.workspaceFallback": "Este espaço de trabalho",
|
|
"dashboard.jobFallback": "Tarefa {id}",
|
|
"dashboard.workflow.feeds.connect": "Ligar importação",
|
|
"dashboard.workflow.products.build": "Criar catálogo",
|
|
"dashboard.workflow.products.count": "{count} no catálogo",
|
|
"dashboard.workflow.process": "Processar",
|
|
"dashboard.workflow.processActive": "{count} ativos",
|
|
"dashboard.workflow.processWaiting": "{count} em espera",
|
|
"dashboard.workflow.processDone": "{count} concluídos",
|
|
"dashboard.workflow.processRun": "Executar tarefas de IA",
|
|
"dashboard.workflow.export": "Exportar",
|
|
"dashboard.workflow.exportReady": "Modelos e transferência",
|
|
"dashboard.workflow.exportMap": "Mapear e exportar",
|
|
"activation.title": "Começar",
|
|
"activation.description":
|
|
"Caminho de valor inicial a partir do seu espaço de trabalho: ativar campos → ligar uma origem → mapear → sincronizar amostra → processar → exportar. O tour de demonstração explica estes ecrãs sem alterar o progresso da lista.",
|
|
"activation.dismiss": "Dispensar lista",
|
|
"activation.progress": "{done} de {total} concluídos",
|
|
"activation.stepsLabel": "Passos de ativação",
|
|
"activation.pausedTitle": "Começar em pausa",
|
|
"activation.pausedBody":
|
|
"Retome a lista quando quiser — desde ativar campos até exportar.",
|
|
"activation.resume": "Retomar lista",
|
|
"stats.products": "Produtos",
|
|
"stats.categories": "Categorias",
|
|
"stats.attributes": "Atributos",
|
|
"stats.feeds": "Feeds",
|
|
"stats.credits": "Créditos",
|
|
"stats.openCatalog": "Abrir catálogo",
|
|
"stats.productsHint": "{processed} processados · {unprocessed} não processados",
|
|
"stats.catalogTree": "Árvore do catálogo",
|
|
"stats.attributeLibrary": "Biblioteca de atributos",
|
|
"stats.importSources": "Origens de importação",
|
|
"stats.payAsYouGo": "Pagamento conforme o uso",
|
|
"stats.walletBilling": "Carteira · Faturação",
|
|
"stats.enterpriseBilling": "Enterprise · Faturação",
|
|
"stats.usedBilling": "{used} usados · Faturação",
|
|
"processing.jobStatus.processing": "A processar",
|
|
"processing.jobStatus.completed": "Concluído",
|
|
"processing.jobStatus.failed": "Falhou",
|
|
"processing.jobStatus.cancelled": "Cancelado",
|
|
"processing.jobStatus.pending": "Pendente",
|
|
"processing.jobStatus.queued": "Em fila",
|
|
"processing.jobStatus.skipped": "Ignorado",
|
|
"processing.jobStatus.unknown": "Desconhecido",
|
|
"processing.step.normalize": "Normalizar",
|
|
"processing.step.parse_specs": "Analisar especificações",
|
|
"processing.step.fill_fields": "Preencher campos",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "Melhoria com IA",
|
|
"errors.requestFailed": "Pedido falhou",
|
|
"errors.maintenance": "O sistema está em manutenção. Tente novamente mais tarde.",
|
|
"errors.readOnly":
|
|
"O sistema está em modo só de leitura. As alterações estão temporariamente desativadas.",
|
|
"errors.companyAdminDenied":
|
|
"Apenas administradores da empresa podem {action}. Peça ajuda a um administrador.",
|
|
"errors.companyAdminDenied.actionDefault": "fazer isto",
|
|
"errors.couldNotUpdateLanguage": "Não foi possível atualizar o idioma",
|
|
"toast.support.replyTitle": "Resposta de suporte",
|
|
"toast.support.replyBody": "A equipa respondeu ao seu ticket de suporte.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Estado do ticket atualizado",
|
|
"toast.support.statusBody": "O estado do seu ticket de suporte alterou-se.",
|
|
"toast.support.updateTitle": "Atualização de suporte",
|
|
"flash.contentLanguageUpdated": "Idioma do conteúdo atualizado."
|
|
},
|
|
nl: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Descrybe-startpagina",
|
|
"common.cancel": "Annuleren",
|
|
"common.save": "Wijzigingen opslaan",
|
|
"common.saveShort": "Opslaan",
|
|
"common.continue": "Doorgaan",
|
|
"common.open": "Openen",
|
|
"common.markDone": "Markeren als gedaan",
|
|
"common.viewAll": "Alles bekijken",
|
|
"common.close": "Sluiten",
|
|
"a11y.skipToContent": "Ga naar inhoud",
|
|
"theme.switchToDark": "Overschakelen naar donker thema",
|
|
"theme.switchToLight": "Overschakelen naar licht thema",
|
|
"header.signOut": "Uitloggen",
|
|
"header.signingOut": "Bezig met uitloggen…",
|
|
"status.emDash": "—",
|
|
"status.pending": "In behandeling",
|
|
"nav.section.overview": "Overzicht",
|
|
"nav.section.catalog": "Catalogus",
|
|
"nav.section.feeds": "Feeds",
|
|
"nav.section.stores": "Winkels",
|
|
"nav.section.processing": "Verwerking",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integraties",
|
|
"nav.section.account": "Account",
|
|
"nav.section.platform": "Platform",
|
|
"nav.dashboard": "Overzicht",
|
|
"nav.products": "Producten",
|
|
"nav.categories": "Categorieën",
|
|
"nav.attributes": "Kenmerken",
|
|
"nav.fields": "Velden",
|
|
"nav.feeds": "Feeds",
|
|
"nav.exports": "Exporten",
|
|
"nav.stores": "Winkels",
|
|
"nav.jobs": "Taken",
|
|
"nav.campaigns": "Campagnes",
|
|
"nav.calendar": "Kalender",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Merk",
|
|
"nav.reviews": "Beoordelingen",
|
|
"nav.ai": "AI",
|
|
"nav.email": "E-mail",
|
|
"nav.billing": "Facturering",
|
|
"nav.settings": "Instellingen",
|
|
"nav.support": "Ondersteuning",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Hoofdnavigatie",
|
|
"nav.sidebar": "App-zijbalk",
|
|
"nav.close": "Navigatie sluiten",
|
|
"nav.closeMenu": "Menu sluiten",
|
|
"nav.open": "Navigatie openen",
|
|
"nav.commandPalette": "Opdrachtpalet openen",
|
|
"locale.switcher": "Interfacetaal",
|
|
"locale.menu": "Kies interfacetaal",
|
|
"locale.label": "Dashboardtaal",
|
|
"locale.help":
|
|
"Wijzigt labels in navigatie en instellingen. De taal voor gegenereerde content stelt u apart in onder Bedrijf.",
|
|
"settings.contentLanguage": "Contenttaal",
|
|
"settings.contentLanguageHelp":
|
|
"Taal voor producttitels, beschrijvingen en andere gegenereerde content",
|
|
"settings.tab.profile": "Profiel",
|
|
"settings.tab.company": "Bedrijf",
|
|
"settings.tab.alerts": "Meldingen",
|
|
"settings.tab.apiKeys": "API-sleutels",
|
|
"settings.tab.team": "Team",
|
|
"settings.title": "Instellingen",
|
|
"settings.description": "Account, bedrijf, API-sleutels en team.",
|
|
"dashboard.demoSandbox": "Demo-sandbox",
|
|
"dashboard.demoEmptyTitle": "Demo-sandbox is leeg",
|
|
"dashboard.overviewTitle": "Overzicht",
|
|
"dashboard.quickLinks": "Snelkoppelingen",
|
|
"dashboard.whatsNew": "Wat is nieuw",
|
|
"dashboard.startTutorial": "Tutorial starten",
|
|
"dashboard.connectFeed": "Feed koppelen",
|
|
"dashboard.workflowTitle": "Catalogusworkflow",
|
|
"dashboard.recentActivity": "Recente activiteit",
|
|
"dashboard.loadFailed": "Dashboard laden mislukt",
|
|
"dashboard.workspaceFallback": "Deze werkruimte",
|
|
"dashboard.jobFallback": "Taak {id}",
|
|
"dashboard.workflow.feeds.connect": "Import koppelen",
|
|
"dashboard.workflow.products.build": "Catalogus opbouwen",
|
|
"dashboard.workflow.products.count": "{count} in catalogus",
|
|
"dashboard.workflow.process": "Verwerken",
|
|
"dashboard.workflow.processActive": "{count} actief",
|
|
"dashboard.workflow.processWaiting": "{count} wachtend",
|
|
"dashboard.workflow.processDone": "{count} klaar",
|
|
"dashboard.workflow.processRun": "AI-jobs uitvoeren",
|
|
"dashboard.workflow.export": "Exporteren",
|
|
"dashboard.workflow.exportReady": "Sjablonen & download",
|
|
"dashboard.workflow.exportMap": "Mappen en exporteren",
|
|
"activation.title": "Aan de slag",
|
|
"activation.description":
|
|
"Eerste waardepad vanuit uw werkruimte: velden inschakelen → bron koppelen → mappen → steekproef synchroniseren → verwerken → exporteren. De demotour legt deze schermen uit zonder de checklistvoortgang te wijzigen.",
|
|
"activation.dismiss": "Checklist verbergen",
|
|
"activation.progress": "{done} van {total} voltooid",
|
|
"activation.stepsLabel": "Activeringsstappen",
|
|
"activation.pausedTitle": "Aan de slag is gepauzeerd",
|
|
"activation.pausedBody":
|
|
"Hervat de checklist wanneer u wilt — van velden inschakelen tot exporteren.",
|
|
"activation.resume": "Checklist hervatten",
|
|
"stats.products": "Producten",
|
|
"stats.categories": "Categorieën",
|
|
"stats.attributes": "Kenmerken",
|
|
"stats.feeds": "Feeds",
|
|
"stats.credits": "Tegoed",
|
|
"stats.openCatalog": "Catalogus openen",
|
|
"stats.productsHint": "{processed} verwerkt · {unprocessed} onverwerkt",
|
|
"stats.catalogTree": "Catalogusboom",
|
|
"stats.attributeLibrary": "Kenmerkenbibliotheek",
|
|
"stats.importSources": "Importbronnen",
|
|
"stats.payAsYouGo": "Betalen naar gebruik",
|
|
"stats.walletBilling": "Wallet · Facturering",
|
|
"stats.enterpriseBilling": "Enterprise · Facturering",
|
|
"stats.usedBilling": "{used} gebruikt · Facturering",
|
|
"processing.jobStatus.processing": "Bezig",
|
|
"processing.jobStatus.completed": "Voltooid",
|
|
"processing.jobStatus.failed": "Mislukt",
|
|
"processing.jobStatus.cancelled": "Geannuleerd",
|
|
"processing.jobStatus.pending": "In behandeling",
|
|
"processing.jobStatus.queued": "In wachtrij",
|
|
"processing.jobStatus.skipped": "Overgeslagen",
|
|
"processing.jobStatus.unknown": "Onbekend",
|
|
"processing.step.normalize": "Normaliseren",
|
|
"processing.step.parse_specs": "Specs parseren",
|
|
"processing.step.fill_fields": "Velden vullen",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "AI-verbetering",
|
|
"errors.requestFailed": "Verzoek mislukt",
|
|
"errors.maintenance": "Het systeem is in onderhoud. Probeer het later opnieuw.",
|
|
"errors.readOnly":
|
|
"Het systeem staat in alleen-lezenmodus. Wijzigingen zijn tijdelijk uitgeschakeld.",
|
|
"errors.companyAdminDenied":
|
|
"Alleen bedrijfsbeheerders kunnen {action}. Vraag een beheerder om hulp.",
|
|
"errors.companyAdminDenied.actionDefault": "dit doen",
|
|
"errors.couldNotUpdateLanguage": "Taal kon niet worden bijgewerkt",
|
|
"toast.support.replyTitle": "Supportantwoord",
|
|
"toast.support.replyBody": "Medewerkers hebben gereageerd op uw supportticket.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Ticketstatus bijgewerkt",
|
|
"toast.support.statusBody": "De status van uw supportticket is gewijzigd.",
|
|
"toast.support.updateTitle": "Supportupdate",
|
|
"flash.contentLanguageUpdated": "Contenttaal bijgewerkt."
|
|
},
|
|
pl: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Strona główna Descrybe",
|
|
"common.cancel": "Anuluj",
|
|
"common.save": "Zapisz zmiany",
|
|
"common.saveShort": "Zapisz",
|
|
"common.continue": "Kontynuuj",
|
|
"common.open": "Otwórz",
|
|
"common.markDone": "Oznacz jako ukończone",
|
|
"common.viewAll": "Zobacz wszystko",
|
|
"common.close": "Zamknij",
|
|
"a11y.skipToContent": "Przejdź do treści",
|
|
"theme.switchToDark": "Przełącz na ciemny motyw",
|
|
"theme.switchToLight": "Przełącz na jasny motyw",
|
|
"header.signOut": "Wyloguj się",
|
|
"header.signingOut": "Wylogowywanie…",
|
|
"status.emDash": "—",
|
|
"status.pending": "Oczekujące",
|
|
"nav.section.overview": "Przegląd",
|
|
"nav.section.catalog": "Katalog",
|
|
"nav.section.feeds": "Feedy",
|
|
"nav.section.stores": "Sklepy",
|
|
"nav.section.processing": "Przetwarzanie",
|
|
"nav.section.marketing": "Marketing",
|
|
"nav.section.integrations": "Integracje",
|
|
"nav.section.account": "Konto",
|
|
"nav.section.platform": "Platforma",
|
|
"nav.dashboard": "Panel",
|
|
"nav.products": "Produkty",
|
|
"nav.categories": "Kategorie",
|
|
"nav.attributes": "Atrybuty",
|
|
"nav.fields": "Pola",
|
|
"nav.feeds": "Feedy",
|
|
"nav.exports": "Eksporty",
|
|
"nav.stores": "Sklepy",
|
|
"nav.jobs": "Zadania",
|
|
"nav.campaigns": "Kampanie",
|
|
"nav.calendar": "Kalendarz",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "Marka",
|
|
"nav.reviews": "Opinie",
|
|
"nav.ai": "AI",
|
|
"nav.email": "E-mail",
|
|
"nav.billing": "Rozliczenia",
|
|
"nav.settings": "Ustawienia",
|
|
"nav.support": "Wsparcie",
|
|
"nav.admin": "Admin",
|
|
"nav.main": "Główna nawigacja",
|
|
"nav.sidebar": "Pasek boczny aplikacji",
|
|
"nav.close": "Zamknij nawigację",
|
|
"nav.closeMenu": "Zamknij menu",
|
|
"nav.open": "Otwórz nawigację",
|
|
"nav.commandPalette": "Otwórz paletę poleceń",
|
|
"locale.switcher": "Język interfejsu",
|
|
"locale.menu": "Wybierz język interfejsu",
|
|
"locale.label": "Język panelu",
|
|
"locale.help":
|
|
"Zmienia etykiety w nawigacji i ustawieniach. Język generowanych treści ustawia się osobno w Firmie.",
|
|
"settings.contentLanguage": "Język treści",
|
|
"settings.contentLanguageHelp":
|
|
"Język używany do tytułów produktów, opisów i innych generowanych treści",
|
|
"settings.tab.profile": "Profil",
|
|
"settings.tab.company": "Firma",
|
|
"settings.tab.alerts": "Alerty",
|
|
"settings.tab.apiKeys": "Klucze API",
|
|
"settings.tab.team": "Zespół",
|
|
"settings.title": "Ustawienia",
|
|
"settings.description": "Konto, firma, klucze API i zespół.",
|
|
"dashboard.demoSandbox": "Piaskownica demo",
|
|
"dashboard.demoEmptyTitle": "Piaskownica demo jest pusta",
|
|
"dashboard.overviewTitle": "Przegląd",
|
|
"dashboard.quickLinks": "Szybkie linki",
|
|
"dashboard.whatsNew": "Co nowego",
|
|
"dashboard.startTutorial": "Uruchom samouczek",
|
|
"dashboard.connectFeed": "Podłącz feed",
|
|
"dashboard.workflowTitle": "Przepływ katalogu",
|
|
"dashboard.recentActivity": "Ostatnia aktywność",
|
|
"dashboard.loadFailed": "Nie udało się wczytać panelu",
|
|
"dashboard.workspaceFallback": "Ta przestrzeń robocza",
|
|
"dashboard.jobFallback": "Zadanie {id}",
|
|
"dashboard.workflow.feeds.connect": "Podłącz import",
|
|
"dashboard.workflow.products.build": "Zbuduj katalog",
|
|
"dashboard.workflow.products.count": "{count} w katalogu",
|
|
"dashboard.workflow.process": "Przetwarzaj",
|
|
"dashboard.workflow.processActive": "{count} aktywnych",
|
|
"dashboard.workflow.processWaiting": "{count} oczekujących",
|
|
"dashboard.workflow.processDone": "{count} ukończonych",
|
|
"dashboard.workflow.processRun": "Uruchom zadania AI",
|
|
"dashboard.workflow.export": "Eksportuj",
|
|
"dashboard.workflow.exportReady": "Szablony i pobieranie",
|
|
"dashboard.workflow.exportMap": "Mapuj, potem eksportuj",
|
|
"activation.title": "Pierwsze kroki",
|
|
"activation.description":
|
|
"Pierwsza ścieżka wartości z przestrzeni roboczej: włącz pola → podłącz źródło → mapuj → synchronizuj próbkę → przetwarzaj → eksportuj. Tour demonstracyjny wyjaśnia te ekrany bez zmiany postępu listy.",
|
|
"activation.dismiss": "Ukryj listę",
|
|
"activation.progress": "{done} z {total} ukończonych",
|
|
"activation.stepsLabel": "Kroki aktywacji",
|
|
"activation.pausedTitle": "Pierwsze kroki wstrzymane",
|
|
"activation.pausedBody":
|
|
"Wznów listę w dowolnym momencie — od włączenia pól do eksportu.",
|
|
"activation.resume": "Wznów listę",
|
|
"stats.products": "Produkty",
|
|
"stats.categories": "Kategorie",
|
|
"stats.attributes": "Atrybuty",
|
|
"stats.feeds": "Feedy",
|
|
"stats.credits": "Kredyty",
|
|
"stats.openCatalog": "Otwórz katalog",
|
|
"stats.productsHint": "{processed} przetworzonych · {unprocessed} nieprzetworzonych",
|
|
"stats.catalogTree": "Drzewo katalogu",
|
|
"stats.attributeLibrary": "Biblioteka atrybutów",
|
|
"stats.importSources": "Źródła importu",
|
|
"stats.payAsYouGo": "Płatność według użycia",
|
|
"stats.walletBilling": "Portfel · Rozliczenia",
|
|
"stats.enterpriseBilling": "Enterprise · Rozliczenia",
|
|
"stats.usedBilling": "{used} użytych · Rozliczenia",
|
|
"processing.jobStatus.processing": "Przetwarzanie",
|
|
"processing.jobStatus.completed": "Ukończono",
|
|
"processing.jobStatus.failed": "Niepowodzenie",
|
|
"processing.jobStatus.cancelled": "Anulowano",
|
|
"processing.jobStatus.pending": "Oczekujące",
|
|
"processing.jobStatus.queued": "W kolejce",
|
|
"processing.jobStatus.skipped": "Pominięto",
|
|
"processing.jobStatus.unknown": "Nieznany",
|
|
"processing.step.normalize": "Normalizuj",
|
|
"processing.step.parse_specs": "Parsuj specyfikacje",
|
|
"processing.step.fill_fields": "Wypełnij pola",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "Ulepszenie AI",
|
|
"errors.requestFailed": "Żądanie nie powiodło się",
|
|
"errors.maintenance": "System jest w konserwacji. Spróbuj ponownie później.",
|
|
"errors.readOnly":
|
|
"System jest w trybie tylko do odczytu. Zmiany są tymczasowo wyłączone.",
|
|
"errors.companyAdminDenied":
|
|
"Tylko administratorzy firmy mogą {action}. Poproś administratora o pomoc.",
|
|
"errors.companyAdminDenied.actionDefault": "to zrobić",
|
|
"errors.couldNotUpdateLanguage": "Nie można zaktualizować języka",
|
|
"toast.support.replyTitle": "Odpowiedź wsparcia",
|
|
"toast.support.replyBody": "Zespół odpowiedział na Twoje zgłoszenie wsparcia.",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "Zaktualizowano status zgłoszenia",
|
|
"toast.support.statusBody": "Status Twojego zgłoszenia wsparcia się zmienił.",
|
|
"toast.support.updateTitle": "Aktualizacja wsparcia",
|
|
"flash.contentLanguageUpdated": "Zaktualizowano język treści."
|
|
},
|
|
ja: {
|
|
"app.name": "Descrybe",
|
|
"app.home": "Descrybeホーム",
|
|
"common.cancel": "キャンセル",
|
|
"common.save": "変更を保存",
|
|
"common.saveShort": "保存",
|
|
"common.continue": "続行",
|
|
"common.open": "開く",
|
|
"common.markDone": "完了にする",
|
|
"common.viewAll": "すべて表示",
|
|
"common.close": "閉じる",
|
|
"a11y.skipToContent": "コンテンツへスキップ",
|
|
"theme.switchToDark": "ダークテーマに切り替え",
|
|
"theme.switchToLight": "ライトテーマに切り替え",
|
|
"header.signOut": "ログアウト",
|
|
"header.signingOut": "ログアウト中…",
|
|
"status.emDash": "—",
|
|
"status.pending": "保留中",
|
|
"nav.section.overview": "概要",
|
|
"nav.section.catalog": "カタログ",
|
|
"nav.section.feeds": "フィード",
|
|
"nav.section.stores": "ストア",
|
|
"nav.section.processing": "処理",
|
|
"nav.section.marketing": "マーケティング",
|
|
"nav.section.integrations": "連携",
|
|
"nav.section.account": "アカウント",
|
|
"nav.section.platform": "プラットフォーム",
|
|
"nav.dashboard": "ダッシュボード",
|
|
"nav.products": "商品",
|
|
"nav.categories": "カテゴリ",
|
|
"nav.attributes": "属性",
|
|
"nav.fields": "フィールド",
|
|
"nav.feeds": "フィード",
|
|
"nav.exports": "エクスポート",
|
|
"nav.stores": "ストア",
|
|
"nav.jobs": "ジョブ",
|
|
"nav.campaigns": "キャンペーン",
|
|
"nav.calendar": "カレンダー",
|
|
"nav.seo": "SEO",
|
|
"nav.brand": "ブランド",
|
|
"nav.reviews": "レビュー",
|
|
"nav.ai": "AI",
|
|
"nav.email": "メール",
|
|
"nav.billing": "請求",
|
|
"nav.settings": "設定",
|
|
"nav.support": "サポート",
|
|
"nav.admin": "管理",
|
|
"nav.main": "メインナビゲーション",
|
|
"nav.sidebar": "アプリのサイドバー",
|
|
"nav.close": "ナビゲーションを閉じる",
|
|
"nav.closeMenu": "メニューを閉じる",
|
|
"nav.open": "ナビゲーションを開く",
|
|
"nav.commandPalette": "コマンドパレットを開く",
|
|
"locale.switcher": "インターフェース言語",
|
|
"locale.menu": "インターフェース言語を選択",
|
|
"locale.label": "ダッシュボードの言語",
|
|
"locale.help":
|
|
"ナビゲーションと設定のラベルを変更します。生成コンテンツの言語は会社設定で別途指定します。",
|
|
"settings.contentLanguage": "コンテンツ言語",
|
|
"settings.contentLanguageHelp":
|
|
"商品タイトル、説明、その他の生成コンテンツに使用する言語",
|
|
"settings.tab.profile": "プロフィール",
|
|
"settings.tab.company": "会社",
|
|
"settings.tab.alerts": "アラート",
|
|
"settings.tab.apiKeys": "APIキー",
|
|
"settings.tab.team": "チーム",
|
|
"settings.title": "設定",
|
|
"settings.description": "アカウント、会社、APIキー、チーム。",
|
|
"dashboard.demoSandbox": "デモサンドボックス",
|
|
"dashboard.demoEmptyTitle": "デモサンドボックスは空です",
|
|
"dashboard.overviewTitle": "概要",
|
|
"dashboard.quickLinks": "クイックリンク",
|
|
"dashboard.whatsNew": "新着情報",
|
|
"dashboard.startTutorial": "チュートリアルを開始",
|
|
"dashboard.connectFeed": "フィードを接続",
|
|
"dashboard.workflowTitle": "カタログワークフロー",
|
|
"dashboard.recentActivity": "最近のアクティビティ",
|
|
"dashboard.loadFailed": "ダッシュボードの読み込みに失敗しました",
|
|
"dashboard.workspaceFallback": "このワークスペース",
|
|
"dashboard.jobFallback": "ジョブ {id}",
|
|
"dashboard.workflow.feeds.connect": "インポートを接続",
|
|
"dashboard.workflow.products.build": "カタログを構築",
|
|
"dashboard.workflow.products.count": "カタログ内 {count} 件",
|
|
"dashboard.workflow.process": "処理",
|
|
"dashboard.workflow.processActive": "アクティブ {count}",
|
|
"dashboard.workflow.processWaiting": "待機 {count}",
|
|
"dashboard.workflow.processDone": "完了 {count}",
|
|
"dashboard.workflow.processRun": "AIジョブを実行",
|
|
"dashboard.workflow.export": "エクスポート",
|
|
"dashboard.workflow.exportReady": "テンプレートとダウンロード",
|
|
"dashboard.workflow.exportMap": "マップしてエクスポート",
|
|
"activation.title": "はじめに",
|
|
"activation.description":
|
|
"ワークスペースからの最初の価値パス:フィールドを有効化 → ソースを接続 → マップ → サンプル同期 → 処理 → エクスポート。デモツアーはチェックリストの進捗を変えずにこれらの画面を説明します。",
|
|
"activation.dismiss": "チェックリストを閉じる",
|
|
"activation.progress": "{total} 件中 {done} 件完了",
|
|
"activation.stepsLabel": "アクティベーション手順",
|
|
"activation.pausedTitle": "はじめが一時停止中です",
|
|
"activation.pausedBody":
|
|
"いつでもチェックリストを再開できます — フィールド有効化からエクスポートまで。",
|
|
"activation.resume": "チェックリストを再開",
|
|
"stats.products": "商品",
|
|
"stats.categories": "カテゴリ",
|
|
"stats.attributes": "属性",
|
|
"stats.feeds": "フィード",
|
|
"stats.credits": "クレジット",
|
|
"stats.openCatalog": "カタログを開く",
|
|
"stats.productsHint": "処理済み {processed} · 未処理 {unprocessed}",
|
|
"stats.catalogTree": "カタログツリー",
|
|
"stats.attributeLibrary": "属性ライブラリ",
|
|
"stats.importSources": "インポート元",
|
|
"stats.payAsYouGo": "従量課金",
|
|
"stats.walletBilling": "ウォレット · 請求",
|
|
"stats.enterpriseBilling": "Enterprise · 請求",
|
|
"stats.usedBilling": "使用 {used} · 請求",
|
|
"processing.jobStatus.processing": "処理中",
|
|
"processing.jobStatus.completed": "完了",
|
|
"processing.jobStatus.failed": "失敗",
|
|
"processing.jobStatus.cancelled": "キャンセル済み",
|
|
"processing.jobStatus.pending": "保留中",
|
|
"processing.jobStatus.queued": "キュー待ち",
|
|
"processing.jobStatus.skipped": "スキップ",
|
|
"processing.jobStatus.unknown": "不明",
|
|
"processing.step.normalize": "正規化",
|
|
"processing.step.parse_specs": "仕様を解析",
|
|
"processing.step.fill_fields": "フィールドを埋める",
|
|
"processing.step.eprel": "EPREL",
|
|
"processing.step.ai_enhance": "AI強化",
|
|
"errors.requestFailed": "リクエストに失敗しました",
|
|
"errors.maintenance": "システムはメンテナンス中です。後でもう一度お試しください。",
|
|
"errors.readOnly":
|
|
"システムは読み取り専用モードです。変更は一時的に無効です。",
|
|
"errors.companyAdminDenied":
|
|
"{action}できるのは会社の管理者のみです。管理者に問い合わせてください。",
|
|
"errors.companyAdminDenied.actionDefault": "これを実行",
|
|
"errors.couldNotUpdateLanguage": "言語を更新できませんでした",
|
|
"toast.support.replyTitle": "サポート返信",
|
|
"toast.support.replyBody": "スタッフがサポートチケットに返信しました。",
|
|
"toast.support.replyRe": "Re: {subject}",
|
|
"toast.support.statusTitle": "チケットステータスが更新されました",
|
|
"toast.support.statusBody": "サポートチケットのステータスが変更されました。",
|
|
"toast.support.updateTitle": "サポート更新",
|
|
"flash.contentLanguageUpdated": "コンテンツ言語を更新しました。"
|
|
}
|
|
};
|
|
|
|
const LOCALES = [
|
|
{ code: "es", comment: "Spanish (es) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "fr", comment: "French (fr) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "de", comment: "German (de) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "it", comment: "Italian (it) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "pt", comment: "Portuguese (pt) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "nl", comment: "Dutch (nl) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "pl", comment: "Polish (pl) UI pack — keys must stay in sync with en.ts." },
|
|
{ code: "ja", comment: "Japanese (ja) UI pack — keys must stay in sync with en.ts." }
|
|
];
|
|
|
|
const en = parseMessageDict(fs.readFileSync(enPath, "utf8"));
|
|
const keyOrder = Object.keys(en);
|
|
console.log(`en keys: ${keyOrder.length}`);
|
|
|
|
const phraseMapPath = path.join(__dirname, "phrase-map.json");
|
|
const phraseMap = fs.existsSync(phraseMapPath)
|
|
? JSON.parse(fs.readFileSync(phraseMapPath, "utf8"))
|
|
: {};
|
|
|
|
function mergedPack(code) {
|
|
return {
|
|
...(PACKS[code] ?? {}),
|
|
...(EXTRA_COMMON[code] ?? {}),
|
|
...(EXTRA_ES[code] ?? {}),
|
|
...(EXTRA_REST[code] ?? {}),
|
|
...(EXTRA_ADMIN[code] ?? {}),
|
|
...(EXTRA_CHROME[code] ?? {}),
|
|
...(EXTRA_DEEP_ADMIN[code] ?? {}),
|
|
...(EXTRA_BROWSER[code] ?? {}),
|
|
...(EXTRA_MARKETING[code] ?? {})
|
|
};
|
|
}
|
|
|
|
let failed = false;
|
|
const summary = [];
|
|
for (const loc of LOCALES) {
|
|
const pack = mergedPack(loc.code);
|
|
const existingPath = path.join(messagesDir, `${loc.code}.ts`);
|
|
const existing = fs.existsSync(existingPath)
|
|
? parseMessageDict(fs.readFileSync(existingPath, "utf8"))
|
|
: {};
|
|
const dict = {};
|
|
const missing = [];
|
|
const fallbackEn = [];
|
|
const extra = Object.keys(pack).filter((k) => !(k in en));
|
|
for (const key of keyOrder) {
|
|
const existingVal = existing[key];
|
|
// Preserve real translations already on disk (do not wipe back to en).
|
|
if (
|
|
typeof existingVal === "string" &&
|
|
existingVal !== "" &&
|
|
existingVal !== en[key]
|
|
) {
|
|
dict[key] = existingVal;
|
|
continue;
|
|
}
|
|
const translated = pack[key];
|
|
const phrase = phraseMap[en[key]]?.[loc.code];
|
|
const packUseful =
|
|
translated != null &&
|
|
translated !== "" &&
|
|
(translated !== en[key] || SAME_AS_EN.has(key));
|
|
if (packUseful) {
|
|
dict[key] = translated;
|
|
} else if (typeof phrase === "string" && phrase.trim()) {
|
|
// Prefer phrase-map over unfinished English copies in PACKS/EXTRA.
|
|
dict[key] = phrase;
|
|
} else if (SAME_AS_EN.has(key)) {
|
|
dict[key] = en[key];
|
|
} else if (translated != null && translated !== "") {
|
|
dict[key] = translated;
|
|
if (translated === en[key]) {
|
|
missing.push(key);
|
|
fallbackEn.push(key);
|
|
}
|
|
} else {
|
|
// Keep key present for sync; runtime also falls back to en if removed.
|
|
dict[key] = en[key];
|
|
missing.push(key);
|
|
fallbackEn.push(key);
|
|
}
|
|
}
|
|
const translatedCount = keyOrder.length - fallbackEn.length;
|
|
summary.push({
|
|
code: loc.code,
|
|
keys: keyOrder.length,
|
|
translated: translatedCount,
|
|
fallbackEn: fallbackEn.length,
|
|
extra: extra.length
|
|
});
|
|
if (extra.length) {
|
|
failed = true;
|
|
console.error(`${loc.code}: extra keys not in en: ${extra.slice(0, 10).join(", ")}`);
|
|
}
|
|
if (fallbackEn.length) {
|
|
console.warn(
|
|
`${loc.code}: ${fallbackEn.length} keys still English (runtime en fallback also covers omissions)`
|
|
);
|
|
}
|
|
fs.writeFileSync(
|
|
path.join(messagesDir, `${loc.code}.ts`),
|
|
emitPack(loc.code, loc.comment, dict, keyOrder),
|
|
"utf8"
|
|
);
|
|
console.log(
|
|
`wrote ${loc.code}.ts (keys=${keyOrder.length} translated=${translatedCount} enFallback=${fallbackEn.length})`
|
|
);
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
path.join(__dirname, "_locale-pack-summary.json"),
|
|
JSON.stringify({ enKeys: keyOrder.length, locales: summary }, null, 2),
|
|
"utf8"
|
|
);
|
|
|
|
if (failed) {
|
|
process.exitCode = 1;
|
|
} else {
|
|
console.log("Locale packs key-synced to en (see _locale-pack-summary.json).");
|
|
}
|