Ctrl K
ComunidadGuías…

scripts/merge-schedule-translations.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
const fs = require('fs');
const path = require('path');

const LOCALES_DIR = path.join(__dirname, '..', 'worklenz-frontend', 'public', 'locales');
const SOURCE_LANG = 'en';
const TARGET_LANGS = ['es', 'de', 'pt', 'zh', 'alb'];

function readJson(filePath) {
  try {
    return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch (e) {
    console.error(`Error reading ${filePath}:`, e.message);
    return null;
  }
}

function writeJson(filePath, obj) {
  fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + '\n');
  console.log(`Updated: ${filePath}`);
}

const source = readJson(path.join(LOCALES_DIR, SOURCE_LANG, 'schedule.json'));

if (!source) {
  console.error('Could not read English schedule.json');
  process.exit(1);
}

const translations = {
  es: {
    workloadManagement: 'Gestión de Carga de Trabajo',
    resourceManagement: 'Gestión de Recursos',
    timeTracking: 'Seguimiento de Tiempo',
    capacityPlanning: 'Planificación de Capacidad',
    loadBalancing: 'Equilibrio de Carga',
    overview: 'Resumen',
    allocation: 'Asignación de Recursos',
    balancing: 'Equilibrio de Carga',
    utilization: 'Utilización',
    available: 'Disponible',
    normal: 'Normal',
    fullyAllocated: 'Totalmente Asignado',
    overAllocated: 'Sobreasignado',
    unknown: 'Desconocido',
    actions: 'Acciones',
    manage: 'Gestionar',
    rebalance: 'Redistribuir',
    allocatedHours: 'Horas Asignadas',
    percentage: 'Porcentaje',
    duration: 'Duración',
    notSet: 'No establecido',
    rebalanceWorkload: 'Redistribuir Carga de Trabajo',
    rebalanceConfirm: 'Esto redistribuirá automáticamente las tareas para optimizar la carga de trabajo. ¿Continuar?',
    workloadRebalanced: 'Carga de trabajo redistribuida con éxito',
    totalMembers: 'Total Miembros',
    refresh: 'Actualizar',
    selectMember: 'Seleccionar Miembro',
    chooseMember: 'Elegir miembro',
    autoBalancing: 'Equilibrio Automático de Carga',
    autoBalancingDesc: 'Redistribuir automáticamente la carga de trabajo entre los miembros del equipo para optimizar el uso de recursos.',
    rebalanceAll: 'Redistribuir Todo',
    previewChanges: 'Vista Previa de Cambios',
    balancingRules: 'Reglas de Equilibrio',
    maxUtilization: 'Utilización Máxima (%)',
    balancingStrategy: 'Estrategia de Equilibrio',
    evenDistribution: 'Distribución Uniforme',
    skillsBased: 'Basado en Habilidades',
    priorityBased: 'Basado en Prioridad',
    timeTrackingFeature: 'Función de Seguimiento de Tiempo',
    timeTrackingDesc: 'Registra el tiempo dedicado a tareas y proyectos. Visualiza informes detallados y análisis.',
    capacityPlanningDesc: 'Planifica la capacidad de recursos para proyectos próximos e identifica posibles cuellos de botella.',
    comingSoon: 'Próximamente...',
    weekend: 'Fin de semana',
    status: 'Estado',
    workloadStatus: 'Estado de Carga de Trabajo',
    teamOverview: 'Resumen del Equipo',
    resourceConflicts: 'Conflictos de Recursos',
    scheduleConflicts: 'Conflictos de Horario',
    overallocation: 'Sobreasignación',
    underutilized: 'Subutilizado',
    optimizeWorkload: 'Optimizar Carga de Trabajo',
    viewDetails: 'Ver Detalles',
    ganttView: 'Vista Gantt',
    listView: 'Vista de Lista',
    timelineView: 'Vista de Línea de Tiempo',
    zoomIn: 'Acercar',
    zoomOut: 'Alejar',
    fitToScreen: 'Ajustar a Pantalla',
    exportSchedule: 'Exportar Horario',
    printSchedule: 'Imprimir Horario',
    fullscreen: 'Pantalla Completa',
    exitFullscreen: 'Salir de Pantalla Completa',
    showWeekends: 'Mostrar Fines de Semana',
    hideWeekends: 'Ocultar Fines de Semana',
    viewSettings: 'Configuración de Vista',
    colorLegend: 'Leyenda de Colores',
    criticalPath: 'Ruta Crítica',
    dependencies: 'Dependencias',
    milestones: 'Hitos',
    baseline: 'Línea Base',
    progress: 'Progreso',
    variance: 'Variación',
    schedule: 'Horario',
    noDataAvailable: 'No hay datos disponibles',
    rebalanceError: 'Error al redistribuir la carga de trabajo',
    allocationUpdated: 'Asignación actualizada con éxito',
    allocationError: 'Error al actualizar la asignación',
    zoomLevel: 'Nivel de Zoom',
    loadingData: 'Cargando datos...',
    loading: 'Cargando...',
    previous: 'Anterior',
    current: 'Actual',
    next: 'Siguiente',
    allRoles: 'Rol: Todos los roles',
    allMembers: 'Todos los miembros',
    allProjects: 'Todos los proyectos',
    allClients: 'Todos los clientes',
    viewOptions: 'Opciones de vista',
    moreFilters: 'Más filtros',
    allStatuses: 'Todos los estados',
    allPriorities: 'Todas las prioridades',
    allCategories: 'Todas las categorías',
    noDatesSet: 'Sin fechas establecidas',
    loadTooltipTitle: 'Carga',
    loadTooltipFormula: 'Total de horas programadas en este proyecto durante el período.',
    loadTooltipBar: 'La barra del {{pct}}% es relativa al proyecto más ocupado mostrado aquí, no a un objetivo fijo.',
    exceedsWorkingHours: 'Excede las horas de trabajo',
    estHoursPerDay: 'Horas Estimadas',
    phase: 'Fase',
    assignees: 'Asignados',
    type: 'Tipo',
    projectBlock: 'Bloque de proyecto',
    assignee: 'Asignado',
    dates: 'Fechas',
    workloadSettings: 'Configuración de carga de trabajo',
    timelineEmptyFilteredTitle: 'Estás al día aquí',
    timelineEmptyTitle: 'Nada que mostrar todavía',
    timelineEmptyFilteredDesc: 'No hay proyectos que coincidan con los filtros actuales. Intenta ampliar Proyectos, Estado, Prioridad, Categoría o Clientes.',
    timelineEmptyProjectsDesc: 'No hay proyectos para mostrar todavía.',
    clearFilters: 'Limpiar filtros',
    workloadEmptyFilteredTitle: 'Estás al día aquí',
    workloadEmptyTitle: 'Nada que mostrar todavía',
    workloadEmptyFilteredDesc: 'Nadie coincide con los filtros actuales. Intenta ampliar Estado del Proyecto, Prioridad o Utilización.',
    workloadEmptyMembersDesc: 'No hay miembros del equipo para mostrar todavía.',
    workloadEmptyProjectsDesc: 'No hay proyectos para mostrar todavía.',
    allProjectStatuses: 'Estado del Proyecto',
    allProjectPriorities: 'Prioridad del Proyecto',
    allUtilLevels: 'Utilización',
  },
  de: {
    workloadManagement: 'Arbeitsauslastungsverwaltung',
    resourceManagement: 'Ressourcenverwaltung',
    timeTracking: 'Zeiterfassung',
    capacityPlanning: 'Kapazitätsplanung',
    loadBalancing: 'Lastverteilung',
    overview: 'Übersicht',
    allocation: 'Ressourcenverteilung',
    balancing: 'Lastausgleich',
    utilization: 'Auslastung',
    available: 'Verfügbar',
    normal: 'Normal',
    fullyAllocated: 'Voll ausgelastet',
    overAllocated: 'Überlastet',
    unknown: 'Unbekannt',
    actions: 'Aktionen',
    manage: 'Verwalten',
    rebalance: 'Neu verteilen',
    allocatedHours: 'Zugewiesene Stunden',
    percentage: 'Prozentsatz',
    duration: 'Dauer',
    notSet: 'Nicht festgelegt',
    rebalanceWorkload: 'Arbeitsauslastung neu verteilen',
    rebalanceConfirm: 'Dadurch werden Aufgaben automatisch neu verteilt, um die Arbeitsauslastung zu optimieren. Fortfahren?',
    workloadRebalanced: 'Arbeitsauslastung erfolgreich neu verteilt',
    totalMembers: 'Mitglieder insgesamt',
    refresh: 'Aktualisieren',
    selectMember: 'Mitglied auswählen',
    chooseMember: 'Mitglied wählen',
    autoBalancing: 'Automatischer Lastausgleich',
    autoBalancingDesc: 'Automatische Neuverteilung der Arbeitsauslastung zwischen Teammitgliedern zur Optimierung der Ressourcennutzung.',
    rebalanceAll: 'Alle neu verteilen',
    previewChanges: 'Änderungen anzeigen',
    balancingRules: 'Lastverteilungsregeln',
    maxUtilization: 'Maximale Auslastung (%)',
    balancingStrategy: 'Lastverteilungsstrategie',
    evenDistribution: 'Gleichmäßige Verteilung',
    skillsBased: 'Kompetenzbasiert',
    priorityBased: 'Prioritätsbasiert',
    timeTrackingFeature: 'Zeiterfassungsfunktion',
    timeTrackingDesc: 'Erfassen Sie die für Aufgaben und Projekte aufgewendete Zeit. Sehen Sie sich detaillierte Berichte und Analysen an.',
    capacityPlanningDesc: 'Planen Sie die Ressourcenkapazität für zukünftige Projekte und identifizieren Sie mögliche Engpässe.',
    comingSoon: 'Demnächst...',
    weekend: 'Wochenende',
    status: 'Status',
    workloadStatus: 'Arbeitsauslastungsstatus',
    teamOverview: 'Teamübersicht',
    resourceConflicts: 'Ressourcenkonflikte',
    scheduleConflicts: 'Terminüberschneidungen',
    overallocation: 'Überlastung',
    underutilized: 'Unterausgelastet',
    optimizeWorkload: 'Arbeitsauslastung optimieren',
    viewDetails: 'Details anzeigen',
    ganttView: 'Gantt-Ansicht',
    listView: 'Listenansicht',
    timelineView: 'Zeitachsenansicht',
    zoomIn: 'Vergrößern',
    zoomOut: 'Verkleinern',
    fitToScreen: 'An Bildschirm anpassen',
    exportSchedule: 'Zeitplan exportieren',
    printSchedule: 'Zeitplan drucken',
    fullscreen: 'Vollbild',
    exitFullscreen: 'Vollbild beenden',
    showWeekends: 'Wochenenden anzeigen',
    hideWeekends: 'Wochenenden ausblenden',
    viewSettings: 'Anzeigeeinstellungen',
    colorLegend: 'Farblegende',
    criticalPath: 'Kritischer Pfad',
    dependencies: 'Abhängigkeiten',
    milestones: 'Meilensteine',
    baseline: 'Basislinie',
    progress: 'Fortschritt',
    variance: 'Abweichung',
    schedule: 'Zeitplan',
    noDataAvailable: 'Keine Daten verfügbar',
    rebalanceError: 'Fehler beim Neuverteilen der Arbeitsauslastung',
    allocationUpdated: 'Zuweisung erfolgreich aktualisiert',
    allocationError: 'Fehler beim Aktualisieren der Zuweisung',
    zoomLevel: 'Zoomstufe',
    loadingData: 'Daten werden geladen...',
    loading: 'Laden...',
    previous: 'Zurück',
    current: 'Aktuell',
    next: 'Weiter',
    allRoles: 'Rolle: Alle Rollen',
    allMembers: 'Alle Mitglieder',
    allProjects: 'Alle Projekte',
    allClients: 'Alle Kunden',
    viewOptions: 'Anzeigeoptionen',
    moreFilters: 'Weitere Filter',
    allStatuses: 'Alle Status',
    allPriorities: 'Alle Prioritäten',
    allCategories: 'Alle Kategorien',
    noDatesSet: 'Keine Daten festgelegt',
    loadTooltipTitle: 'Last',
    loadTooltipFormula: 'Gesamte für dieses Projekt im Zeitraum geplante Stunden.',
    loadTooltipBar: 'Der {{pct}}%-Balken bezieht sich auf das hier angezeigte ausgelastetste Projekt, nicht auf ein festes Ziel.',
    exceedsWorkingHours: 'Überschreitet die Arbeitsstunden',
    estHoursPerDay: 'Geschätzte Stunden',
    phase: 'Phase',
    assignees: 'Zugewiesene',
    type: 'Typ',
    projectBlock: 'Projektblock',
    assignee: 'Zugewiesene Person',
    dates: 'Daten',
    workloadSettings: 'Arbeitsauslastungseinstellungen',
    timelineEmptyFilteredTitle: 'Du bist auf dem neuesten Stand',
    timelineEmptyTitle: 'Noch nichts zu sehen',
    timelineEmptyFilteredDesc: 'Keine Projekte entsprechen den aktuellen Filtern. Versuche, Projekte, Status, Priorität, Kategorie oder Kunden zu erweitern.',
    timelineEmptyProjectsDesc: 'Noch keine Projekte zum Anzeigen.',
    clearFilters: 'Filter löschen',
    workloadEmptyFilteredTitle: 'Du bist auf dem neuesten Stand',
    workloadEmptyTitle: 'Noch nichts zu sehen',
    workloadEmptyFilteredDesc: 'Niemand entspricht den aktuellen Filtern. Versuche, Projektstatus, Priorität oder Auslastung zu erweitern.',
    workloadEmptyMembersDesc: 'Noch keine Teammitglieder zum Anzeigen.',
    workloadEmptyProjectsDesc: 'Noch keine Projekte zum Anzeigen.',
    allProjectStatuses: 'Projektstatus',
    allProjectPriorities: 'Projektpriorität',
    allUtilLevels: 'Auslastung',
  },
  pt: {
    workloadManagement: 'Gestão de Carga de Trabalho',
    resourceManagement: 'Gestão de Recursos',
    timeTracking: 'Controlo de Tempo',
    capacityPlanning: 'Planeamento de Capacidade',
    loadBalancing: 'Balanceamento de Carga',
    overview: 'Visão Geral',
    allocation: 'Atribuição de Recursos',
    balancing: 'Balanceamento',
    utilization: 'Utilização',
    available: 'Disponível',
    normal: 'Normal',
    fullyAllocated: 'Totalmente Atribuído',
    overAllocated: 'Sobreatribuído',
    unknown: 'Desconhecido',
    actions: 'Ações',
    manage: 'Gerir',
    rebalance: 'Redistribuir',
    allocatedHours: 'Horas Atribuídas',
    percentage: 'Percentagem',
    duration: 'Duração',
    notSet: 'Não definido',
    rebalanceWorkload: 'Redistribuir Carga de Trabalho',
    rebalanceConfirm: 'Isto irá redistribuir automaticamente as tarefas para otimizar a carga de trabalho. Continuar?',
    workloadRebalanced: 'Carga de trabalho redistribuída com sucesso',
    totalMembers: 'Total de Membros',
    refresh: 'Atualizar',
    selectMember: 'Selecionar Membro',
    chooseMember: 'Escolher membro',
    autoBalancing: 'Balanceamento Automático de Carga',
    autoBalancingDesc: 'Redistribua automaticamente a carga de trabalho entre os membros da equipa para otimizar a utilização de recursos.',
    rebalanceAll: 'Redistribuir Tudo',
    previewChanges: 'Pré-visualizar Alterações',
    balancingRules: 'Regras de Balanceamento',
    maxUtilization: 'Utilização Máxima (%)',
    balancingStrategy: 'Estratégia de Balanceamento',
    evenDistribution: 'Distribuição Uniforme',
    skillsBased: 'Baseado em Competências',
    priorityBased: 'Baseado em Prioridade',
    timeTrackingFeature: 'Funcionalidade de Controlo de Tempo',
    timeTrackingDesc: 'Registe o tempo gasto em tarefas e projetos. Visualize relatórios detalhados e análises.',
    capacityPlanningDesc: 'Planeie a capacidade de recursos para projetos futuros e identifique possíveis gargalos.',
    comingSoon: 'Em breve...',
    weekend: 'Fim de semana',
    status: 'Estado',
    workloadStatus: 'Estado da Carga de Trabalho',
    teamOverview: 'Visão Geral da Equipa',
    resourceConflicts: 'Conflitos de Recursos',
    scheduleConflicts: 'Conflitos de Agenda',
    overallocation: 'Sobreatribuição',
    underutilized: 'Subutilizado',
    optimizeWorkload: 'Otimizar Carga de Trabalho',
    viewDetails: 'Ver Detalhes',
    ganttView: 'Vista Gantt',
    listView: 'Vista de Lista',
    timelineView: 'Vista de Cronograma',
    zoomIn: 'Aumentar',
    zoomOut: 'Diminuir',
    fitToScreen: 'Ajustar ao Ecrã',
    exportSchedule: 'Exportar Agenda',
    printSchedule: 'Imprimir Agenda',
    fullscreen: 'Ecrã Inteiro',
    exitFullscreen: 'Sair do Ecrã Inteiro',
    showWeekends: 'Mostrar Fins de Semana',
    hideWeekends: 'Ocultar Fins de Semana',
    viewSettings: 'Definições de Visualização',
    colorLegend: 'Legenda de Cores',
    criticalPath: 'Caminho Crítico',
    dependencies: 'Dependências',
    milestones: 'Marcos',
    baseline: 'Linha de Base',
    progress: 'Progresso',
    variance: 'Variância',
    schedule: 'Agenda',
    noDataAvailable: 'Sem dados disponíveis',
    rebalanceError: 'Erro ao redistribuir carga de trabalho',
    allocationUpdated: 'Atribuição atualizada com sucesso',
    allocationError: 'Erro ao atualizar atribuição',
    zoomLevel: 'Nível de Zoom',
    loadingData: 'A carregar dados...',
    loading: 'A carregar...',
    previous: 'Anterior',
    current: 'Atual',
    next: 'Seguinte',
    allRoles: 'Função: Todas as funções',
    allMembers: 'Todos os membros',
    allProjects: 'Todos os projetos',
    allClients: 'Todos os clientes',
    viewOptions: 'Opções de visualização',
    moreFilters: 'Mais filtros',
    allStatuses: 'Todos os estados',
    allPriorities: 'Todas as prioridades',
    allCategories: 'Todas as categorias',
    noDatesSet: 'Sem datas definidas',
    loadTooltipTitle: 'Carga',
    loadTooltipFormula: 'Total de horas agendadas neste projeto durante o período.',
    loadTooltipBar: 'A barra de {{pct}}% é relativa ao projeto mais ocupado aqui, não a um alvo fixo.',
    exceedsWorkingHours: 'Excede as horas de trabalho',
    estHoursPerDay: 'Horas Estimadas',
    phase: 'Fase',
    assignees: 'Atribuídos',
    type: 'Tipo',
    projectBlock: 'Bloqueio de projeto',
    assignee: 'Atribuído',
    dates: 'Datas',
    workloadSettings: 'Definições de carga de trabalho',
    timelineEmptyFilteredTitle: 'Estás em dia aqui',
    timelineEmptyTitle: 'Nada para mostrar ainda',
    timelineEmptyFilteredDesc: 'Nenhum projeto corresponde aos filtros atuais. Tenta ampliar Projetos, Estado, Prioridade, Categoria ou Clientes.',
    timelineEmptyProjectsDesc: 'Ainda não há projetos para mostrar.',
    clearFilters: 'Limpar filtros',
    workloadEmptyFilteredTitle: 'Estás em dia aqui',
    workloadEmptyTitle: 'Nada para mostrar ainda',
    workloadEmptyFilteredDesc: 'Ninguém corresponde aos filtros atuais. Tenta ampliar Estado do Projeto, Prioridade ou Utilização.',
    workloadEmptyMembersDesc: 'Ainda não há membros da equipa para mostrar.',
    workloadEmptyProjectsDesc: 'Ainda não há projetos para mostrar.',
    allProjectStatuses: 'Estado do Projeto',
    allProjectPriorities: 'Prioridade do Projeto',
    allUtilLevels: 'Utilização',
  },
  zh: {
    workloadManagement: '工作负载管理',
    resourceManagement: '资源管理',
    timeTracking: '时间跟踪',
    capacityPlanning: '产能规划',
    loadBalancing: '负载均衡',
    overview: '概览',
    allocation: '资源分配',
    balancing: '负载均衡',
    utilization: '利用率',
    available: '可用',
    normal: '正常',
    fullyAllocated: '已满负荷',
    overAllocated: '超负荷',
    unknown: '未知',
    actions: '操作',
    manage: '管理',
    rebalance: '重新平衡',
    allocatedHours: '分配时长',
    percentage: '百分比',
    duration: '持续时间',
    notSet: '未设置',
    rebalanceWorkload: '重新平衡工作负载',
    rebalanceConfirm: '这将自动重新分配任务以优化工作负载。是否继续?',
    workloadRebalanced: '工作负载已成功重新平衡',
    totalMembers: '成员总数',
    refresh: '刷新',
    selectMember: '选择成员',
    chooseMember: '选择成员',
    autoBalancing: '自动负载均衡',
    autoBalancingDesc: '在团队成员之间自动重新分配工作负载,以优化资源利用率。',
    rebalanceAll: '全部重新平衡',
    previewChanges: '预览更改',
    balancingRules: '平衡规则',
    maxUtilization: '最大利用率 (%)',
    balancingStrategy: '平衡策略',
    evenDistribution: '均匀分配',
    skillsBased: '基于技能',
    priorityBased: '基于优先级',
    timeTrackingFeature: '时间跟踪功能',
    timeTrackingDesc: '跟踪任务和项目所花费的时间。查看详细报告和分析。',
    capacityPlanningDesc: '为即将到来的项目规划资源容量,并识别潜在瓶颈。',
    comingSoon: '即将推出...',
    weekend: '周末',
    status: '状态',
    workloadStatus: '工作负载状态',
    teamOverview: '团队概览',
    resourceConflicts: '资源冲突',
    scheduleConflicts: '日程冲突',
    overallocation: '超额分配',
    underutilized: '利用不足',
    optimizeWorkload: '优化工作负载',
    viewDetails: '查看详情',
    ganttView: '甘特图视图',
    listView: '列表视图',
    timelineView: '时间线视图',
    zoomIn: '放大',
    zoomOut: '缩小',
    fitToScreen: '适应屏幕',
    exportSchedule: '导出日程',
    printSchedule: '打印日程',
    fullscreen: '全屏',
    exitFullscreen: '退出全屏',
    showWeekends: '显示周末',
    hideWeekends: '隐藏周末',
    viewSettings: '视图设置',
    colorLegend: '颜色图例',
    criticalPath: '关键路径',
    dependencies: '依赖关系',
    milestones: '里程碑',
    baseline: '基线',
    progress: '进度',
    variance: '偏差',
    schedule: '日程',
    noDataAvailable: '无可用数据',
    rebalanceError: '重新平衡工作负载失败',
    allocationUpdated: '分配已成功更新',
    allocationError: '更新分配失败',
    zoomLevel: '缩放级别',
    loadingData: '正在加载数据...',
    loading: '正在加载...',
    previous: '上一个',
    current: '当前',
    next: '下一个',
    allRoles: '角色:所有角色',
    allMembers: '所有成员',
    allProjects: '所有项目',
    allClients: '所有客户',
    viewOptions: '视图选项',
    moreFilters: '更多筛选',
    allStatuses: '所有状态',
    allPriorities: '所有优先级',
    allCategories: '所有类别',
    noDatesSet: '未设置日期',
    loadTooltipTitle: '负载',
    loadTooltipFormula: '该周期内此项目安排的总时长。',
    loadTooltipBar: '{{pct}}% 的条形图是相对于此处显示的最忙项目,而非固定目标。',
    exceedsWorkingHours: '超出工作时长',
    estHoursPerDay: '预估工时',
    phase: '阶段',
    assignees: '指派人员',
    type: '类型',
    projectBlock: '项目块',
    assignee: '指派人员',
    dates: '日期',
    workloadSettings: '工作负载设置',
    timelineEmptyFilteredTitle: '此处已无遗漏',
    timelineEmptyTitle: '暂无内容',
    timelineEmptyFilteredDesc: '没有项目符合当前筛选条件。请尝试扩大项目、状态、优先级、类别或客户范围。',
    timelineEmptyProjectsDesc: '暂无项目可显示。',
    clearFilters: '清除筛选',
    workloadEmptyFilteredTitle: '此处已无遗漏',
    workloadEmptyTitle: '暂无内容',
    workloadEmptyFilteredDesc: '没有人员符合当前筛选条件。请尝试扩大项目状态、优先级或利用率范围。',
    workloadEmptyMembersDesc: '暂无团队成员可显示。',
    workloadEmptyProjectsDesc: '暂无项目可显示。',
    allProjectStatuses: '项目状态',
    allProjectPriorities: '项目优先级',
    allUtilLevels: '利用率',
  },
  alb: {
    workloadManagement: 'Menaxhimi i Ngarkesës së Punës',
    resourceManagement: 'Menaxhimi i Burimeve',
    timeTracking: 'Ndjekja e Kohës',
    capacityPlanning: 'Planifikimi i Kapacitetit',
    loadBalancing: 'Balancimi i Ngarkesës',
    overview: 'Përmbledhje',
    allocation: 'Shpërndarja e Burimeve',
    balancing: 'Balancimi',
    utilization: 'Përdorimi',
    available: 'I disponueshëm',
    normal: 'Normal',
    fullyAllocated: 'I plotësisht shpërndarë',
    overAllocated: 'Mbivendosur',
    unknown: 'I panjohur',
    actions: 'Veprimet',
    manage: 'Menaxho',
    rebalance: 'Ribalanso',
    allocatedHours: 'Orët e shpërndara',
    percentage: 'Përqindja',
    duration: 'Kohëzgjatja',
    notSet: 'E pacaktuar',
    rebalanceWorkload: 'Ribalanso Ngarkesën e Punës',
    rebalanceConfirm: 'Kjo do të ridistribojë automatikisht detyrat për të optimizuar ngarkesën e punës. Vazhdoni?',
    workloadRebalanced: 'Ngarkesa e punës u ribalansua me sukses',
    totalMembers: 'Anëtarët në total',
    refresh: 'Rifresko',
    selectMember: 'Zgjidh Anëtar',
    chooseMember: 'Zgjidh anëtar',
    autoBalancing: 'Balancim Automatik i Ngarkesës',
    autoBalancingDesc: 'Ridistribuo automatikisht ngarkesën e punës në mes anëtarëve të ekipit për të optimizuar përdorimin e burimeve.',
    rebalanceAll: 'Ribalanso të Gjitha',
    previewChanges: 'Parashi Ndryshimet',
    balancingRules: 'Rregullat e Balancimit',
    maxUtilization: 'Përdorimi Maksimum (%)',
    balancingStrategy: 'Strategjia e Balancimit',
    evenDistribution: 'Shpërndarje E Barabartë',
    skillsBased: 'Bazuar në Aftësitë',
    priorityBased: 'Bazuar në Prioritet',
    timeTrackingFeature: 'Karakteristika e Ndjekjes së Kohës',
    timeTrackingDesc: 'Gjuroni kohën e shpenzuar në detyra dhe projekte. Shikoni raporte të detajuara dhe analiza.',
    capacityPlanningDesc: 'Planifikoni kapacitetin e burimeve për projektet e ardhshme dhe identifikoni potentialin bllokadesh.',
    comingSoon: 'Së shpejti...',
    weekend: 'Fundjavë',
    status: 'Statusi',
    workloadStatus: 'Statusi i Ngarkesës së Punës',
    teamOverview: 'Përmbledhja e Ekipit',
    resourceConflicts: 'Konflikte të Burimeve',
    scheduleConflicts: 'Konflikte të Orarit',
    overallocation: 'Mbivendosje',
    underutilized: 'I përdorur pak',
    optimizeWorkload: 'Optimizo Ngarkesën e Punës',
    viewDetails: 'Shiko Detajet',
    ganttView: 'Pamja Gantt',
    listView: 'Pamja e Listës',
    timelineView: 'Pamja e Kohës',
    zoomIn: 'Zmadho',
    zoomOut: 'Zvogëlo',
    fitToScreen: 'Përshtat në Ekran',
    exportSchedule: 'Eksporto Orarin',
    printSchedule: 'Shtyp Orarin',
    fullscreen: 'Ekran i Plotë',
    exitFullscreen: 'Dil nga Ekrani i Plotë',
    showWeekends: 'Shfaq Fundjavët',
    hideWeekends: 'Fshih Fundjavët',
    viewSettings: 'Cilësimet e Pamjes',
    colorLegend: 'Legjenda e Ngjyrave',
    criticalPath: 'Rruga Kritike',
    dependencies: 'Varësitë',
    milestones: 'Ullesat',
    baseline: 'Linja Bazë',
    progress: 'Progresi',
    variance: 'Varianca',
    schedule: 'Orari',
    noDataAvailable: 'Nuk ka të dhëna të disponueshme',
    rebalanceError: 'Dështoi ribalansimi i ngarkesës së punës',
    allocationUpdated: 'Shpërndarja u përditësua me sukses',
    allocationError: 'Dështoi përditësimi i shpërndarjes',
    zoomLevel: 'Niveli i Zoom-it',
    loadingData: 'Duke ngarkuar të dhënat...',
    loading: 'Duke ngarkuar...',
    previous: 'I mëparshëm',
    current: 'Aktual',
    next: 'I radhës',
    allRoles: 'Roli: Të gjitha rolet',
    allMembers: 'Të gjithë anëtarët',
    allProjects: 'Të gjitha projektet',
    allClients: 'Të gjithë klientët',
    viewOptions: 'Opsionet e pamjes',
    moreFilters: 'Më shumë filtra',
    allStatuses: 'Të gjitha statuset',
    allPriorities: 'Të gjitha prioritetet',
    allCategories: 'Të gjitha kategoritë',
    noDatesSet: 'Nuk ka data të caktuar',
    loadTooltipTitle: 'Ngarkesa',
    loadTooltipFormula: 'Orët e planifikuara gjithsej për këtë projekt gjatë periudhës.',
    loadTooltipBar: 'Shiriti i {{pct}}% është në rajon me projektin më të zënë këtu, jo me një objektiv fiks.',
    exceedsWorkingHours: 'Tejkalon orët e punës',
    estHoursPerDay: 'Orë të Vlerësuara',
    phase: 'Faza',
    assignees: 'Përgjegjësit',
    type: 'Lloji',
    projectBlock: 'Bllok projekt',
    assignee: 'Përgjegjësi',
    dates: 'Datat',
    workloadSettings: 'Cilësimet e ngarkesës së punës',
    timelineEmptyFilteredTitle: 'Je gjithcka i përditësuar këtu',
    timelineEmptyTitle: 'Asgjë për të treguar ende',
    timelineEmptyFilteredDesc: 'Asnjë projekt nuk përputhet me filtrat e tanishëm. Provoni të zgjidhni Projetet, Statusin, Prioritetin, Kategorinë ose Klientët.',
    timelineEmptyProjectsDesc: 'Ende nuk ka projekte për të treguar.',
    clearFilters: 'Pastro filtrat',
    workloadEmptyFilteredTitle: 'Je gjithcka i përditësuar këtu',
    workloadEmptyTitle: 'Asgjë për të treguar ende',
    workloadEmptyFilteredDesc: 'Asnjëri nuk përputhet me filtrat e tanishëm. Provoni të zgjidhni Statusin e Projektit, Prioritetin ose Përdorimin.',
    workloadEmptyMembersDesc: 'Ende nuk ka anëtarë ekipi për të treguar.',
    workloadEmptyProjectsDesc: 'Ende nuk ka projekte për të treguar.',
    allProjectStatuses: 'Statusi i Projektit',
    allProjectPriorities: 'Prioriteti i Projektit',
    allUtilLevels: 'Përdorimi',
  },
};

for (const lang of TARGET_LANGS) {
  const filePath = path.join(LOCALES_DIR, lang, 'schedule.json');
  let locale = readJson(filePath);
  if (!locale) {
    console.error(`Skipping ${lang}: could not read file`);
    continue;
  }

  const trans = translations[lang] || {};
  let addedCount = 0;
  let updatedCount = 0;
  for (const [key, value] of Object.entries(source)) {
    if (!(key in locale)) {
      locale[key] = trans[key] || value;
      addedCount++;
    } else if (trans[key] && locale[key] === value) {
      locale[key] = trans[key];
      updatedCount++;
    }
  }

  // Also remove extra keys not in source
  const sourceKeys = Object.keys(source);
  let removedCount = 0;
  for (const key of Object.keys(locale)) {
    if (!sourceKeys.includes(key)) {
      delete locale[key];
      removedCount++;
    }
  }

  writeJson(filePath, locale);
  console.log(`  ${lang}: added ${addedCount} keys, updated ${updatedCount} translations, removed ${removedCount} extra keys`);
}

console.log('\nDone!');