Files
vac-optimizer/src/i18n/es.json
T
nessar 6811142299 feat(planning): make optimization rules composable
Evaluate explicit, ordered optimization configurations through one shared
planner model. Add six editable presets, durable one-time legacy migration,
and consistent completed and cancelled plan provenance.

Include functional regressions and the agreed trace-removal and benchmark
follow-up specs. Performance acceptance remains in #78 under unchanged gates.

Refs: #70, #71, #72, #73, #74, #75, #76, #77, #78
2026-10-10 16:07:34 +02:00

458 lines
22 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"locale": "es-ES",
"bookedDays": {
"enter": "Editar días ya reservados",
"booked": "Ya reservado",
"help": "Elija CP, RTT, Otro o Borrar y haga clic o arrastre entre fechas, incluso de varios meses. Suelte para guardar; Escape cancela. Cada día que ya tenga el tipo elegido se borra; los demás reciben ese tipo. Se omiten fines de semana y festivos. El rayado indica los días ya reservados, que se aplican en el próximo cálculo.",
"fixed": "Entrada fija del usuario, sin descontar el saldo restante ni decisión de optimización.",
"removed": "Declaración eliminada",
"erase": "Borrar",
"rangeSaved": "Días ya reservados guardados: {count} ({type}).",
"rangeRemoved": "Declaraciones eliminadas: {count}."
},
"app": {
"title": "vac-optimizer",
"description": "Más espacio para descansar.",
"skipToPlan": "Ir a tu plan"
},
"userInput": {
"title": "Configura tus vacaciones",
"description": "Elige el período de planificación y añade cada saldo de vacaciones y su periodo de validez.",
"addVacationDay": "Añadir saldo de vacaciones",
"calculate": "Calcular plan",
"durationEstimate": "Espera aproximada: {range} {unit}",
"durationUnits": {
"seconds": "s",
"minutes": "min"
},
"remainingDaysWarning": "{count} día{plural} de permiso restante{plural}:",
"deleteEntry": "Eliminar entrada",
"chooseDate": "Caduca el",
"availableDate": "Disponible desde",
"days": "Días",
"type": "Tipo de permiso",
"daySuffix": "día",
"daysSuffix": "días",
"expires": "exp.",
"remainingWhy": "Ver por qué",
"remainingValidity": "Utilizable del {available} al {expiry}.",
"remainingHorizon": "Plan calculado del {start} al {end}.",
"remainingEarnedFrom": "Permiso obtenido gracias a la regla «{rule}».",
"remainingHistoryHelp": "Estas fechas se examinaron realmente durante el cálculo. Los valores comparan cada intento con su estado inicial; el plan final puede ser diferente.",
"remainingNoEvaluations": "No se registró ningún intento atribuible a este saldo. Su categoría de caducidad por sí sola no explica por qué sigue sin utilizarse.",
"remainingSuggestions": {
"available-after-horizon": "Puedes ampliar el período planificado más allá de su fecha de disponibilidad y volver a calcular.",
"no-working-date": "Comprueba el período planificado y las fechas de validez de este saldo.",
"all-dates-occupied": "Puedes ampliar el período si la validez lo permite, o ajustar los días ya reservados y tus reglas, y volver a calcular.",
"preserved": "No es necesario hacer nada. Para solicitar su uso, añade una regla dentro de su período de validez y vuelve a calcular.",
"calculation-incomplete": "Repite el cálculo si quieres que termine la planificación."
},
"remainingCandidateReasons": {
"quality-no-improvement": "Esta opción no se seleccionó en esta fase del cálculo.",
"quality-protected-objective": "Esta opción empeoraría una prioridad que debe conservarse.",
"quality-outperformed": "El cálculo encontró después una opción mejor clasificada.",
"earned-entitlement-order": "Esta opción no respeta las fechas de disponibilidad de los permisos obtenidos.",
"unknown": "El motivo preciso de este intento no está disponible."
}
},
"dayTypes": {
"weekend": "Fin de semana",
"closedDay": "Día festivo",
"rtt": "RTT",
"cp": "Vacaciones pagadas",
"other": "Otro",
"today": "Hoy",
"any": "Cualquier"
},
"settings": {
"title": "Ajustes",
"description": "Los cambios se guardan automáticamente.",
"showWeekNumbers": "Mostrar números de semana",
"close": "Cerrar",
"selectLanguage": "Idioma",
"selectTheme": "Tema",
"themeOptions": {
"system": "Sistema",
"light": "Claro",
"dark": "Oscuro"
},
"systemAppearance": "Apariencia actual del sistema",
"planningHorizon": "Período de planificación",
"planningStart": "Fecha de inicio (incluida)",
"lastPlanningDate": "Última fecha de planificación (incluida)",
"planningDatesHelp": "Elige cualquier fecha, incluso pasada. El calendario se actualiza al seleccionar Calcular plan.",
"invalidDate": "Introduce dos fechas válidas.",
"horizonOrder": "La última fecha de planificación debe ser igual o posterior a la fecha de inicio.",
"invalidHorizon": "Corrige las fechas de planificación antes de calcular."
},
"rules": {
"title": "Reglas de planificación",
"subtitle": "Gestionar reglas de optimización",
"active": "activas",
"moveRuleUp": "Subir regla",
"moveRuleDown": "Bajar regla",
"dragRule": "Arrastrar para reordenar",
"ruleMoved": "{name}: posición {position} de {count}.",
"priorityInfo": "Las reglas de arriba tienen prioridad. Reordénalas con el tirador o las flechas.",
"ifThenTemplate": "Si un día festivo cae en <strong>{day}</strong>, colocar <strong>{placeDays}</strong> día(s) <strong>{placeType}</strong> <strong>{placement}</strong> y obtener <strong>{rewardDays}</strong> día(s) <strong>{rewardType}</strong> de bonificación.",
"timeWindowTemplate": "Colocar <strong>{placeDays}</strong> día(s) <strong>{placeType}</strong> entre el <strong>{startDate}</strong> y el <strong>{endDate}</strong>.",
"editRule": "Editar regla",
"deleteRule": "Eliminar regla",
"addRule": "Añadir una regla",
"place": "Colocar",
"ruleName": "Nombre de la regla",
"holidayFalls": "Día festivo cae en",
"days": "Días",
"type": "Tipo",
"position": "Posición",
"getBonus": "Obtener en bonificación",
"force": "Fuerza de la regla",
"obligation": "Obligación",
"preference": "Preferencia",
"startDate": "Fecha de inicio",
"endDate": "Fecha de fin",
"cancel": "Cancelar",
"save": "Guardar",
"add": "Añadir",
"addRuleButton": "Añadir",
"newIfThenRule": "Nueva regla \"Si ... Entonces\"",
"newTimeWindowRule": "Nuevo período impuesto",
"defaultNewRuleName": "Nueva regla",
"defaultNewPeriodName": "Nuevo período",
"daysOfWeek": {
"1": "Lunes",
"2": "Martes",
"3": "Miércoles",
"4": "Jueves",
"5": "Viernes",
"6": "Sábado",
"0": "Domingo"
},
"placement": {
"before": "Antes",
"after": "Después",
"around": "Alrededor",
"auto": "Auto (Mejor opción)"
},
"optimization": {
"newRule": "Nueva regla de Optimización",
"defaultName": "Prevención de pérdidas",
"elementsLabel": "Elementos del plan",
"conditionsLabel": "Condiciones (deben cumplirse todas)",
"measureLabel": "Medida",
"aggregationLabel": "Agregación",
"directionLabel": "Dirección",
"thresholdLabel": "Umbral de preferencia en días laborables",
"thresholdSummary": "umbral de preferencia: {count} días laborables",
"summary": "{direction} {aggregation}: {measure} — {elements}{conditions}.",
"invalidConfiguration": "Elija elementos, condiciones, medidas y agregaciones compatibles, con un umbral entero positivo cuando sea necesario.",
"nameRequired": "Introduzca un nombre para la regla.",
"elements": {
"leave-balances": "Saldos de vacaciones",
"public-holiday-weeks": "Semanas con festivos",
"time-off-periods": "Períodos sin trabajo",
"work-sequences": "Secuencias de trabajo",
"leave-placements": "Vacaciones colocadas"
},
"conditions": {
"at-risk": "En riesgo de caducar",
"complete": "Completas",
"internal": "Internas",
"non-empty": "No vacías",
"supporting": "De apoyo"
},
"measures": {
"unplaced-quantity": "Cantidad no colocada",
"public-holiday-week-value": "Valor de las semanas festivas",
"non-working-day-gain": "Ganancia de días sin trabajo",
"work-sequence-length": "Longitud de las secuencias de trabajo",
"work-sequence-deficit": "Déficit de las secuencias de trabajo",
"placement-count": "Número de colocaciones"
},
"aggregations": {
"sum": "Suma",
"count": "Cantidad",
"maximum": "Máximo"
},
"directions": {
"minimize": "Minimizar",
"maximize": "Maximizar"
}
}
},
"planning": {
"statistics": {
"open": "Estadísticas",
"title": "Estadísticas del plan",
"leaveDays": "Nuevos días de permiso",
"averageWorkSequence": "Secuencia de trabajo media",
"averageTimeOffPeriod": "Período de descanso medio",
"longestTimeOffPeriod": "Período de descanso más largo",
"weekendConnectedHolidays": "Festivos conectados con un fin de semana",
"workingDays": "días laborables",
"calendarDays": "días naturales",
"partialPlan": "Plan parcial",
"help": "Estadísticas del plan calculado. Los días ya reservados definen los períodos de descanso y trabajo sin consumir de nuevo los saldos restantes.",
"earnedLeave": "Permisos adquiridos antes de su uso",
"leaveDaysUnit": "días",
"earnedLeaveByRule": "Permisos adquiridos por regla"
},
"calculationDate": "Fecha del cálculo",
"futureEntitlement": "Derecho futuro generado",
"includedEntitlement": "Derecho ya incluido en los saldos declarados",
"title": "Tu año optimizado",
"daysPlaced": "Días de vacaciones asignados",
"daysGained": "Días no laborables ganados",
"longestWorkSequence": "Período de trabajo más largo",
"legend": "Leyenda del calendario",
"invalidInput": "Los datos de planificación no son válidos.",
"conflict": "Las obligaciones no se pueden satisfacer juntas.",
"incomplete": "El cálculo se detuvo antes de completar todas las etapas de calidad.",
"cancel": "Cancelar",
"cancelling": "Cancelando…",
"cancelled": "Cálculo cancelado",
"cancelledPartial": "Cálculo cancelado — plan parcial",
"error": "El planificador encontró un error inesperado.",
"complete": "Plan calculado.",
"whyPlacement": "Entender tus días de permiso",
"placementNavigation": "Navegación por las explicaciones de las asignaciones",
"placement": "Día de permiso",
"placements": "asignaciones",
"decision": "Decisión",
"of": "de",
"first": "Primera asignación",
"previous": "Asignación anterior",
"next": "Asignación siguiente",
"last": "Última asignación",
"remaining": "Días sin usar en el plan final",
"balanceRemaining": "restantes",
"counterfactual": "Fechas alternativas",
"counterfactualLoading": "Analizando cada fecha del horizonte…",
"counterfactualReady": "Las fechas alternativas están listas.",
"counterfactualError": "No se pudieron calcular las fechas alternativas.",
"retryCounterfactual": "Reintentar el análisis de fechas",
"historicalEligibilityLoading": "Comprobando qué fechas podía usar este permiso…",
"historicalEligibilityReady": "La elegibilidad histórica de las fechas está lista.",
"historicalEligibilityError": "No se pudo comprobar la elegibilidad histórica de las fechas.",
"retryHistoricalEligibility": "Reintentar la comprobación de elegibilidad",
"eligible": "Válida",
"ineligible": "No válida",
"historical": "Estado de la búsqueda original",
"reason": "Motivo",
"explanationError": "No se pudo generar la explicación.",
"conflictDetails": "Por qué ningún plan satisface las obligaciones",
"conflictingRules": "Reglas en conflicto",
"bottleneck": "Cuello de botella",
"incompleteDetails": "Lo completado antes de detener el cálculo",
"incumbentExplanation": "Esto explica el mejor plan válido encontrado; las etapas de calidad posteriores no se completaron.",
"completedStages": "Etapas completadas",
"uncompletedStages": "Etapas interrumpidas o no iniciadas",
"none": "Ninguno",
"currentPlacement": "Asignación explicada actualmente",
"explainedPeriod": "Período de descanso explicado",
"outsideHorizon": "Fecha de contexto fuera del horizonte de planificación",
"traceTitle": "Avanzado: traza de decisiones original",
"traceLoading": "El plan está listo; su traza de decisiones aún se está cargando…",
"traceReady": "El plan está listo y se ha cargado su traza de decisiones.",
"traceUnavailable": "No hay una traza de decisiones disponible para este resultado.",
"phases": "Fases de la traza",
"firstPhase": "Primera fase",
"previousPhase": "Fase anterior",
"nextPhase": "Fase siguiente",
"lastPhase": "Última fase",
"decisions": "Decisiones atómicas",
"firstDecision": "Primera decisión",
"previousDecision": "Decisión anterior",
"nextDecision": "Decisión siguiente",
"lastDecision": "Última decisión",
"replay": "Estado de la decisión",
"before": "Antes",
"after": "Después",
"finalPlan": "Plan final",
"dates": "Fechas",
"candidates": "Candidatos",
"previousCandidates": "Página de candidatos anterior",
"nextCandidates": "Página de candidatos siguiente",
"page": "Página",
"compareAlternatives": "Comparar este candidato en todo el horizonte",
"deltas": "Cambios de estado",
"activations": "activaciones obtenidas",
"noDecisions": "Esta fase no registró ninguna decisión atómica.",
"traceStatuses": {
"chosen": "Elegido",
"evaluated-rejected": "Evaluado y rechazado",
"pruned": "Podado",
"not-examined": "No examinado",
"ineligible": "No válido"
},
"tracePhaseStatuses": {
"completed": "Completada",
"interrupted": "Interrumpida",
"not-run": "No ejecutada"
},
"traceChanges": {
"added": "Añadido por esta decisión",
"moved-from": "Movido desde esta fecha",
"moved-to": "Movido a esta fecha",
"removed": "Eliminado por esta decisión",
"shared": "Compartido por esta decisión",
"unchanged": "Sin cambios por esta decisión"
},
"calendarHelp": "Selecciona un día de permiso para ver su aportación al plan.",
"explanationHelp": "Consulta tu descanso y qué cambia con cada día.",
"traceHelp": "Explora el cálculo, decisión a decisión.",
"technicalDetails": "Detalles del cálculo",
"compareDates": "Comparar otras fechas",
"stopComparing": "Cerrar comparación",
"replayNotice": "Estás viendo un paso del cálculo.",
"explanation": {
"breakTitle": "Tu descanso",
"leaveDays": "días de permiso usados",
"freeDays": "días de fin de semana y festivos",
"daysOff": "días libres seguidos",
"wholeBreak": "Estos totales corresponden a todo el descanso, incluido el día seleccionado.",
"leaveUsed": "Esta fecha usa 1 día del saldo «{balance}».",
"expires": "Usa este saldo hasta el",
"linkedRules": "Reglas vinculadas:",
"atRiskContribution": "Protege permisos que podrían vencer.",
"impact": "Qué cambia con este día",
"impactHelp": "Compara todo el plan con y sin este día de permiso. Las demás fechas no cambian; solo se muestran los totales que varían.",
"criterion": "En todo tu plan",
"withoutDay": "Sin este día",
"withDay": "Con este día",
"noChange": "Estos totales son iguales. Las reglas y los últimos criterios de desempate (vencimiento del saldo y después fecha) aún pueden influir en la elección.",
"priorityHelp": "Las obligaciones se resuelven conjuntamente. Las preferencias activas se comparan en el orden de sus reglas. Solo esas reglas añaden vacaciones; la caducidad y luego las fechas resuelven los empates.",
"tryDate": "Probar otra fecha",
"plannedDate": "Fecha prevista actualmente:",
"currentPlan": "Plan actual",
"alternative": "Con esta fecha",
"sameDate": "Esta es la fecha prevista. Elige otra fecha arriba para ver la diferencia.",
"moveHelp": "Prueba a mover este día. Las demás fechas de permiso no cambian.",
"traceHelp": "Compara este candidato con el estado anterior a su decisión original.",
"beforeDecision": "Antes de esta decisión",
"withCandidate": "Con este candidato",
"comparisonUnavailable": "La comparación de la fecha original no está disponible, por lo que no se puede mostrar el cambio.",
"objectives": {
"obligation-validity": {
"label": "Obligaciones sin cumplir",
"help": "Número de reglas obligatorias incumplidas. Un plan válido tiene cero."
},
"unplaced-at-risk": {
"label": "Días sin usar que podrían vencer",
"help": "Días sin planificar que vencen durante el período. Menos es mejor."
},
"preference": {
"label": "Preferencia: {rule}",
"help": "Días o coincidencias completas, según la regla. Más es mejor."
},
"holiday-week-value": {
"label": "Prioridad de semanas con festivos (puntos)",
"help": "Puntuación ponderada: festivos en miércoles valen 3, martes/jueves 2 y lunes/viernes 1. Más es mejor."
},
"non-working-day-gain": {
"label": "Fines de semana y festivos en tus descansos",
"help": "Días libres sin gastar permisos. Más es mejor."
},
"longest-work-sequence": {
"label": "Máximo de días laborables entre permisos",
"help": "No se cuentan fines de semana ni festivos. Menos es mejor."
},
"short-sequence-deficit": {
"label": "Penalización por tramos cortos de trabajo",
"help": "Cada tramo de 1–4 días laborables entre permisos suma los días que faltan para llegar a 5. Menos es mejor."
},
"supporting-placements": {
"label": "Días usados de saldos que vencen más tarde",
"help": "Permisos que podrían guardarse más allá de este período. Menos es mejor."
},
"balance-expiry": {
"label": "Primero los permisos que vencen antes",
"help": "Desempate cuando los totales anteriores son iguales."
},
"placement-date": {
"label": "Primero las fechas más tempranas",
"help": "Último desempate cuando los demás criterios son iguales."
},
"optimization": {
"label": "{rule}: {summary}",
"help": "Esta preferencia de optimización evalúa su configuración guardada. Las preferencias activas siguen el orden mostrado; las anteriores tienen prioridad."
}
},
"stages": {
"validation": "Comprobar saldos y reglas",
"obligations": "Cumplir las reglas obligatorias",
"at-risk": "Usar los permisos antes de que venzan",
"expiry": "Preferir los permisos que vencen antes",
"dates": "Preferir las fechas más tempranas"
},
"unavailable": {
"non-working": "Ya es un día libre (fin de semana o festivo). No hace falta pedir permiso.",
"occupied": "Ya hay otro permiso previsto aquí. Elige un día laborable disponible.",
"unavailable": "Este saldo de permisos no se puede usar en esta fecha.",
"expired": "Esta fecha es posterior al vencimiento del saldo.",
"type-incompatible": "Este tipo de permiso no se puede usar en esta fecha.",
"rule-invalid": "Usar esta fecha incumpliría una regla del plan.",
"invalid-optimization-configuration": "Elija elementos, condiciones, medidas y agregaciones compatibles, con un umbral entero positivo cuando sea necesario.",
"unsupported-optimization-configuration": "Esta regla combina elementos del plan y medidas incompatibles."
},
"preferenceHelp": {
"time_window": "Días de permiso dentro del período preferido. Más es mejor.",
"if_then": "Coincidencias completas de esta regla. Más es mejor."
}
},
"details": {
"intro": "La columna izquierda muestra el plan sin este día de permiso. La derecha muestra el plan actual.",
"balance": "Saldo de permisos",
"available": "Disponible desde",
"expires": "Vence el",
"criteria": "Las prioridades del cálculo",
"criteriaHelp": "Lee de arriba abajo: la primera diferencia tiene prioridad. Selecciona un criterio para ver cómo se calcula.",
"traceImpactTitle": "Efecto de esta rama en el plan completo",
"traceImpactHelp": "Estos valores comparan el estado completo antes y después de esta rama. Muestran su efecto, no por qué el planificador la eligió.",
"traceStageTitle": "Comparación real en esta etapa",
"traceStageHelp": "Estos valores brutos se compararon en esta decisión; la primera diferencia explica el estado de la opción. La tabla del plan completo muestra el efecto de esta elección.",
"firstDifference": "Primera diferencia",
"higher": "Más es mejor",
"lower": "Menos es mejor",
"tieBreaks": "Si los totales anteriores son iguales",
"audit": "Datos sin procesar · depuración",
"auditHelp": "Valores, identificadores y contribuciones originales de este cálculo.",
"supporting": "Este día usa permisos que podrían guardarse más allá del período planificado para mejorar tus descansos.",
"remainingReasons": {
"unavoidable-expiry": "Caducó el {expiry}, antes del inicio del plan el {start}. No puede colocarse en este período.",
"available-after-horizon": "Disponible solo a partir del {available}, después de la última fecha del plan, el {end}.",
"no-working-date": "Ningún día laborable está dentro del período planificado y entre sus fechas de disponibilidad y caducidad.",
"all-dates-occupied": "Todos los días laborables en los que puede utilizarse este saldo ya están ocupados por permisos planificados o días ya reservados.",
"preserved": "Guardado para más adelante: caduca después del período planificado y el cálculo no seleccionó ninguna colocación adicional según tus prioridades.",
"active-priorities": "El cálculo conservó este saldo sin utilizar según tus reglas activas. Cambia las reglas o su orden para solicitar otro plan.",
"calculation-incomplete": "El cálculo se interrumpió antes de terminar la planificación. Su falta de uso no es una decisión definitiva.",
"not-established": "Este cálculo no determinó un motivo preciso para dejarlo sin utilizar."
}
},
"comparison": {
"title": "Comparar fechas",
"candidate": "Fecha del candidato",
"preview": "Solo una vista previa. Tu plan no cambia.",
"nearby": "Fechas cercanas disponibles",
"noAlternatives": "No hay otra fecha disponible para este día de permiso. Puedes comprobar una fecha para ver el motivo.",
"chooseDate": "Elige una fecha arriba para ver qué cambiaría.",
"dateRange": "Período planificado:",
"invalidDate": "Elige una fecha válida dentro del período indicado arriba.",
"changes": "Qué cambiaría",
"available": "Fecha disponible",
"unavailable": "Esta fecha no se puede usar",
"backToPlan": "Volver a mi plan",
"backToTrace": "Volver al cálculo"
}
},
"benchmark": {
"title": "Prueba del planificador de vacaciones",
"instructions": "Ejecuta los cinco escenarios fijos y copia el informe resultante.",
"run": "Ejecutar prueba",
"running": "En curso…",
"copy": "Copiar informe"
},
"loading": "Calculando...",
"weekdaysShort": ["L", "M", "M", "J", "V", "S", "D"]
}