zerochat 7.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. zerochat-7.3.0.dist-info/METADATA +70 -0
  2. zerochat-7.3.0.dist-info/RECORD +130 -0
  3. zerochat-7.3.0.dist-info/WHEEL +5 -0
  4. zerochat-7.3.0.dist-info/entry_points.txt +2 -0
  5. zerochat-7.3.0.dist-info/licenses/LICENSE +34 -0
  6. zerochat-7.3.0.dist-info/top_level.txt +2 -0
  7. zerochat.py +2004 -0
  8. zerochat_runtime/__init__.py +1 -0
  9. zerochat_runtime/assets/css/base.css +199 -0
  10. zerochat_runtime/assets/css/components/composer.css +1258 -0
  11. zerochat_runtime/assets/css/components/debug.css +777 -0
  12. zerochat_runtime/assets/css/components/header.css +97 -0
  13. zerochat_runtime/assets/css/components/icons.css +39 -0
  14. zerochat_runtime/assets/css/components/markdown.css +685 -0
  15. zerochat_runtime/assets/css/components/messages.css +473 -0
  16. zerochat_runtime/assets/css/components/modals.css +1319 -0
  17. zerochat_runtime/assets/css/components/sidebar.css +622 -0
  18. zerochat_runtime/assets/css/components/tools.css +1223 -0
  19. zerochat_runtime/assets/css/layout.css +171 -0
  20. zerochat_runtime/assets/css/print.css +120 -0
  21. zerochat_runtime/assets/css/styles.css +18 -0
  22. zerochat_runtime/assets/css/theme-overrides.css +555 -0
  23. zerochat_runtime/assets/css/tokens.css +165 -0
  24. zerochat_runtime/assets/help/architecture.html +247 -0
  25. zerochat_runtime/assets/help/composer.html +134 -0
  26. zerochat_runtime/assets/help/conversations.html +105 -0
  27. zerochat_runtime/assets/help/debug.html +108 -0
  28. zerochat_runtime/assets/help/en/architecture.html +247 -0
  29. zerochat_runtime/assets/help/en/composer.html +134 -0
  30. zerochat_runtime/assets/help/en/conversations.html +104 -0
  31. zerochat_runtime/assets/help/en/debug.html +105 -0
  32. zerochat_runtime/assets/help/en/gemini-free.html +39 -0
  33. zerochat_runtime/assets/help/en/index.html +191 -0
  34. zerochat_runtime/assets/help/en/learning.html +71 -0
  35. zerochat_runtime/assets/help/en/mcp.html +143 -0
  36. zerochat_runtime/assets/help/en/openrouter-free.html +39 -0
  37. zerochat_runtime/assets/help/en/profiles.html +173 -0
  38. zerochat_runtime/assets/help/en/rag.html +130 -0
  39. zerochat_runtime/assets/help/en/reasoning-telemetry.html +108 -0
  40. zerochat_runtime/assets/help/en/tools-agent.html +133 -0
  41. zerochat_runtime/assets/help/en/webllm.html +355 -0
  42. zerochat_runtime/assets/help/gemini-free.html +39 -0
  43. zerochat_runtime/assets/help/help.css +604 -0
  44. zerochat_runtime/assets/help/help.js +51 -0
  45. zerochat_runtime/assets/help/index.html +194 -0
  46. zerochat_runtime/assets/help/learning.html +71 -0
  47. zerochat_runtime/assets/help/mcp.html +143 -0
  48. zerochat_runtime/assets/help/openrouter-free.html +39 -0
  49. zerochat_runtime/assets/help/profiles.html +174 -0
  50. zerochat_runtime/assets/help/rag.html +130 -0
  51. zerochat_runtime/assets/help/reasoning-telemetry.html +111 -0
  52. zerochat_runtime/assets/help/tools-agent.html +133 -0
  53. zerochat_runtime/assets/help/webllm.html +359 -0
  54. zerochat_runtime/assets/js/agent-core.js +1553 -0
  55. zerochat_runtime/assets/js/api.js +844 -0
  56. zerochat_runtime/assets/js/app.js +2558 -0
  57. zerochat_runtime/assets/js/attachments.js +220 -0
  58. zerochat_runtime/assets/js/charts.js +338 -0
  59. zerochat_runtime/assets/js/chat-engine.js +566 -0
  60. zerochat_runtime/assets/js/config-store.js +207 -0
  61. zerochat_runtime/assets/js/context-manager.js +584 -0
  62. zerochat_runtime/assets/js/conversation-service.js +484 -0
  63. zerochat_runtime/assets/js/cookies.js +688 -0
  64. zerochat_runtime/assets/js/data-reset-service.js +136 -0
  65. zerochat_runtime/assets/js/debug.js +508 -0
  66. zerochat_runtime/assets/js/defaults.js +16 -0
  67. zerochat_runtime/assets/js/export.js +179 -0
  68. zerochat_runtime/assets/js/file-parser.js +2088 -0
  69. zerochat_runtime/assets/js/generation-controller.js +417 -0
  70. zerochat_runtime/assets/js/i18n.js +1483 -0
  71. zerochat_runtime/assets/js/icons.js +156 -0
  72. zerochat_runtime/assets/js/ingestionEngine.js +436 -0
  73. zerochat_runtime/assets/js/markdown.js +588 -0
  74. zerochat_runtime/assets/js/mcp.js +1271 -0
  75. zerochat_runtime/assets/js/message-turns.js +62 -0
  76. zerochat_runtime/assets/js/profile-backup.js +118 -0
  77. zerochat_runtime/assets/js/profile-export-bundle.js +481 -0
  78. zerochat_runtime/assets/js/profile-repository.js +213 -0
  79. zerochat_runtime/assets/js/providers-webllm.js +486 -0
  80. zerochat_runtime/assets/js/providers.js +1560 -0
  81. zerochat_runtime/assets/js/rag-index.js +295 -0
  82. zerochat_runtime/assets/js/rag-service.js +530 -0
  83. zerochat_runtime/assets/js/rag-ui.js +997 -0
  84. zerochat_runtime/assets/js/ragStorage.js +676 -0
  85. zerochat_runtime/assets/js/sandbox.js +449 -0
  86. zerochat_runtime/assets/js/state.js +704 -0
  87. zerochat_runtime/assets/js/storage-db.js +144 -0
  88. zerochat_runtime/assets/js/tool-cards.js +330 -0
  89. zerochat_runtime/assets/js/tool-security.js +653 -0
  90. zerochat_runtime/assets/js/tools/README.md +50 -0
  91. zerochat_runtime/assets/js/tools/builtin/agent-checkpoint.tool.js +212 -0
  92. zerochat_runtime/assets/js/tools/builtin/download-pdf.tool.js +111 -0
  93. zerochat_runtime/assets/js/tools/builtin/execute-javascript.tool.js +219 -0
  94. zerochat_runtime/assets/js/tools/builtin/fetch-web-page.tool.js +112 -0
  95. zerochat_runtime/assets/js/tools/builtin/list-documents.tool.js +117 -0
  96. zerochat_runtime/assets/js/tools/builtin/read-knowledge-chunk.tool.js +129 -0
  97. zerochat_runtime/assets/js/tools/builtin/read-knowledge-image.tool.js +95 -0
  98. zerochat_runtime/assets/js/tools/builtin/render-chart.tool.js +90 -0
  99. zerochat_runtime/assets/js/tools/builtin/search-knowledge-base.tool.js +124 -0
  100. zerochat_runtime/assets/js/tools/builtin/search-web.tool.js +125 -0
  101. zerochat_runtime/assets/js/tools/tool-manifest.js +53 -0
  102. zerochat_runtime/assets/js/tools/tool-runtime.js +77 -0
  103. zerochat_runtime/assets/js/ui-composer.js +319 -0
  104. zerochat_runtime/assets/js/ui-conversation.js +655 -0
  105. zerochat_runtime/assets/js/ui-dialogs.js +132 -0
  106. zerochat_runtime/assets/js/ui-generation-status.js +119 -0
  107. zerochat_runtime/assets/js/ui-inspector.js +804 -0
  108. zerochat_runtime/assets/js/ui-mcp.js +604 -0
  109. zerochat_runtime/assets/js/ui-profiles.js +824 -0
  110. zerochat_runtime/assets/js/ui-reasoning.js +146 -0
  111. zerochat_runtime/assets/js/ui-settings.js +825 -0
  112. zerochat_runtime/assets/js/ui-shell.js +215 -0
  113. zerochat_runtime/assets/js/ui-sidebar.js +429 -0
  114. zerochat_runtime/assets/js/ui-telemetry.js +404 -0
  115. zerochat_runtime/assets/js/ui-transfer.js +262 -0
  116. zerochat_runtime/assets/js/utils.js +216 -0
  117. zerochat_runtime/assets/js/vendor/orama.browser.js +11 -0
  118. zerochat_runtime/assets/js/web-browser.js +569 -0
  119. zerochat_runtime/assets/js/web-search.js +519 -0
  120. zerochat_runtime/assets/manifest.webmanifest +20 -0
  121. zerochat_runtime/assets/services/dummy_mcp/dummy_mcp_server.py +47 -0
  122. zerochat_runtime/assets/services/dummy_mcp/service.json +22 -0
  123. zerochat_runtime/assets/services/lsp/installer.json +9 -0
  124. zerochat_runtime/assets/services/lsp/service.json +22 -0
  125. zerochat_runtime/assets/services/memory/installer.json +9 -0
  126. zerochat_runtime/assets/services/memory/service.json +24 -0
  127. zerochat_runtime/assets/services/playwright/installer.json +10 -0
  128. zerochat_runtime/assets/services/playwright/service.json +39 -0
  129. zerochat_runtime/assets/sw.js +164 -0
  130. zerochat_runtime/assets/zerochat.html +671 -0
@@ -0,0 +1,1483 @@
1
+ /**
2
+ * Módulo de Internacionalización y Multi-idioma (ChatI18n) para ZeroChat.
3
+ * Gestiona diccionarios en Español e Inglés, formateo de fechas y reactividad de UI.
4
+ */
5
+
6
+ (function (root, factory) {
7
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
8
+ module.exports = factory();
9
+ } else {
10
+ root.ChatI18n = factory();
11
+ }
12
+ })(typeof self !== 'undefined' ? self : this, function () {
13
+ 'use strict';
14
+
15
+ const extractVersionFromTitle = () => {
16
+ if (typeof document !== 'undefined' && document.title) {
17
+ const match = document.title.match(/v?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/i);
18
+ if (match) return match[1];
19
+ }
20
+ return 'dev';
21
+ };
22
+ const APP_VERSION = (typeof globalThis !== 'undefined' && globalThis.__ZEROCHAT_VERSION__) || extractVersionFromTitle();
23
+ const APP_TITLE = `ZeroChat v${APP_VERSION}`;
24
+
25
+ const TRANSLATIONS = {
26
+ es: {
27
+ notice_accept: 'Aceptar',
28
+ notice_cancel: 'Cancelar',
29
+ notice_confirm: 'Confirmación',
30
+ notice_info: 'Información',
31
+ notice_error: 'Error',
32
+ notice_success: 'Éxito',
33
+ notice_warning: 'Aviso',
34
+ notice_prompt: 'Introducir texto',
35
+ notice_export_error: 'Error al exportar la rama: {err}',
36
+ notice_branch_restored: 'Rama "{name}" restaurada con éxito.',
37
+ notice_import_error: 'Error al restaurar: {err}',
38
+
39
+ // Metadatos y Encabezados
40
+ app_title: APP_TITLE,
41
+ app_description: 'ZeroChat - Cliente web universal, agente IA autónomo y RAG local en un solo archivo con cero instalación',
42
+
43
+ // Estado de Bienvenida inicial
44
+ welcome_heading: 'ZeroChat',
45
+ welcome_desc: 'Entorno conversacional y agente autónomo local.',
46
+ welcome_status: 'Chat vacío · A la espera de un comando',
47
+ welcome_help_link: 'Ayuda y Documentación',
48
+ welcome_help_title: 'Abrir centro de ayuda y documentación online',
49
+ welcome_help_href: 'help/index.html',
50
+ execution_info_title: 'Modo de ejecución y almacenamiento',
51
+ execution_info_http: 'En modo servidor, los chats, perfiles y preferencias se comparten con cualquier ZeroChat del mismo protocolo, host y puerto. La ruta no los separa.',
52
+ execution_info_file: 'En modo archivo local, el navegador decide cómo aísla o comparte los datos. Usa siempre el mismo lugar para almacenar y ejecutar zerochat.html si quieres que permanezcan las configuraciones.',
53
+ execution_info_portable_tool: 'ZeroChat funciona directamente en tu navegador web. La interfaz arranca de forma estática y segura.',
54
+ execution_info_requirements: 'La conversación seguirá necesitando el proveedor que hayas configurado: un modelo local puede funcionar sin red; una API remota y las funciones web, no.',
55
+
56
+ // Barra de herramientas superior
57
+ profile_badge_title: 'Perfil de conexión activo',
58
+ edit_profiles: 'Editar perfiles',
59
+ profile_menu_title: 'Perfiles de conexión',
60
+ profile_mirror_description: 'Muestra la petición OpenAI sin enviarla.',
61
+ profile_mirror_type: 'Espejo (sin red)',
62
+ mirror_response_intro: '# Bienvenido a ZeroChat\n\nEsta es una vista segura del perfil **Espejo**: la solicitud que aparece abajo se ha generado para su inspección, pero **no se ha enviado a ningún servicio**.',
63
+ mirror_response_about: '## ZeroChat, a tu manera\n\nZeroChat reúne conversaciones, herramientas y conocimiento local en una interfaz flexible. Puedes conectarlo a modelos locales o proveedores remotos mediante perfiles de conexión independientes. Para conocer todas sus posibilidades y guías de configuración, consulta la [ayuda y documentación general](help/index.html).',
64
+ mirror_response_profile: '## Continúa con un perfil\n\nCrea un perfil para guardar el proveedor, el endpoint, el modelo y las preferencias que quieras utilizar. Así podrás alternar configuraciones sin volver a introducir sus valores.',
65
+ mirror_response_webllm: '> **WebLLM (experimental):** también puedes crear un perfil WebLLM para ejecutar un modelo compatible localmente en el navegador mediante WebGPU. Descarga primero el modelo; la disponibilidad y el rendimiento dependen de tu navegador y hardware.',
66
+ mirror_response_request: '## Solicitud preparada (no enviada)',
67
+ context_hub_btn_title: 'Métricas de contexto y tokens de la conversación (Clic para ver detalles)',
68
+ context_hub_title: 'Métricas de Contexto y Tokens',
69
+ context_section_global: 'Ventana de Contexto Global',
70
+ context_metric_used: 'Contexto Usado',
71
+ context_metric_limit: 'Capacidad',
72
+ context_metric_free: 'Disponible',
73
+ context_metric_status: 'Estado',
74
+ context_limit_source_server: 'Capacidad publicada por el servidor.',
75
+ context_limit_source_manual: 'Capacidad asumida definida para este perfil.',
76
+ context_limit_source_assumed: 'Capacidad asumida: el servidor no la ha publicado.',
77
+ context_limit_override_label: 'Capacidad asumida (tokens)',
78
+ context_limit_override_save: 'Usar',
79
+ context_limit_override_invalid: 'Indica una capacidad válida, por ejemplo 90K.',
80
+ context_limit_override_profile_required: 'Selecciona un perfil de conexión antes de guardar la capacidad asumida.',
81
+ context_limit_override_save_error: 'No se pudo guardar la capacidad asumida.',
82
+ context_status_ok: 'Óptimo',
83
+ context_status_warning: 'Elevado',
84
+ context_status_critical: 'Crítico',
85
+ context_section_cache: 'Caché de Contexto (Prompt/KV)',
86
+ context_metric_cached_read: 'Leídos (Ahorro)',
87
+ context_metric_cached_write: 'Escritos en caché',
88
+ context_section_turn: 'Último Turno Generado',
89
+ context_metric_turn_prompt: 'Entrada (Prompt)',
90
+ context_metric_turn_completion: 'Salida (Respuesta)',
91
+ context_metric_turn_speed: 'Velocidad',
92
+ context_metric_turn_latency: 'Latencia (TTFT)',
93
+ no_model: '(Sin modelo)',
94
+ btn_logs: 'Logs y Debug',
95
+ btn_logs_title: 'Abrir/Cerrar panel lateral de logs y depuración',
96
+ btn_settings: 'Configuración',
97
+ btn_settings_title: 'Abrir configuración general',
98
+ btn_rag: 'RAG',
99
+ btn_rag_title: 'Gestionar conocimiento local (RAG)',
100
+ rag_modal_title: 'Conocimiento local',
101
+ rag_modal_title_activate: 'RAG',
102
+ rag_modal_title_manage: 'RAG. Gestionar',
103
+ rag_menu_label: 'RAG',
104
+ rag_help_link_text: '¿Necesitas ayuda con RAG?',
105
+ rag_help_link_label: 'Ver guía completa',
106
+ rag_status_disabled: 'Conocimiento desactivado',
107
+ rag_status_disabled_desc: 'Selecciona una o varias ramas para que el agente pueda buscar en tus documentos.',
108
+ rag_disable: 'Desactivar',
109
+ rag_disable_all: 'Desactivar todas',
110
+ rag_activate_all: 'Activar todas',
111
+ rag_available_branches: 'Ramas disponibles',
112
+ rag_available_branches_hint: 'Puedes activar una o varias ramas simultáneamente para búsquedas cruzadas.',
113
+ rag_branch_label: 'Rama:',
114
+ rag_new_branch: 'Nueva rama',
115
+ rag_edit_branch: 'Editar',
116
+ rag_delete_branch: 'Eliminar',
117
+ rag_export_branch: 'Respaldo',
118
+ rag_import_branch: 'Restaurar',
119
+ rag_branch_name: 'Nombre de la rama:',
120
+ rag_branch_name_placeholder: 'Nombre de la rama (ej: Manuales)',
121
+ rag_branch_lang: 'Idioma de la documentación:',
122
+ rag_lang_spanish: 'Español',
123
+ rag_lang_english: 'Inglés',
124
+ rag_lang_french: 'Francés',
125
+ rag_lang_german: 'Alemán',
126
+ rag_lang_italian: 'Italiano',
127
+ rag_lang_portuguese: 'Portugués',
128
+ rag_branch_desc: 'Descripción (opcional):',
129
+ rag_branch_desc_placeholder: 'Descripción sobre el contenido de esta rama',
130
+ rag_btn_save: 'Guardar',
131
+ rag_branch_created: 'Rama "{name}" creada con éxito',
132
+ rag_branch_updated: 'Rama "{name}" guardada con éxito',
133
+ rag_branch_name_empty: 'Por favor, escribe un nombre para la rama',
134
+ rag_active_tip_title: 'Eficacia del RAG y modelo:',
135
+ rag_active_tip_desc: 'La eficacia del RAG se basa en gran medida en la <strong>inteligencia, visión multimodal</strong> (para interpretar tablas, gráficos e imágenes) y la <strong>capacidad de razonamiento agéntico</strong> del modelo elegido: es clave para formular búsquedas precisas, examinar fragmentos contiguos y contrastar evidencias sin desorientarse. Si utilizas modelos compactos o con menor autonomía agéntica, activa el <strong>Punto de Control agéntico (agent_checkpoint)</strong> desde el menú de Razonamiento para consolidar hallazgos y mantener un plan de investigación claro.',
136
+ rag_help_storage_desc: 'Los archivos, metadatos y fragmentos se guardan en IndexedDB. Orama construye en memoria un índice de búsqueda local para la rama activa.',
137
+ rag_help_private_title: 'Sin permisos ni costes de ingesta',
138
+ rag_help_private_desc: 'Seleccionar un archivo solo permite leer esa carga. No se solicitan permisos sobre carpetas y no se llama a ningún LLM para resumir o indexar.',
139
+ rag_help_llm_title: 'Configurar el modelo para responder sobre documentos',
140
+ rag_help_llm_desc: 'Para preguntas factuales sobre documentos, usa una temperatura baja (0 a 0,2): reduce variaciones y hace más probable que el modelo se atenga a los fragmentos recuperados. Una temperatura de 0,7 o superior conviene para redacción creativa, no para extraer cifras o hechos. El modelo también debe admitir llamadas a herramientas; si no las admite, no podrá consultar esta base documental.',
141
+ rag_help_checkpoint_title: 'Punto de control agéntico para modelos de poco contexto',
142
+ rag_help_checkpoint_desc: 'Los modelos compactos o con ventana de contexto reducida se saturan con facilidad al acumular múltiples fragmentos de documentos. Activa el <strong>Punto de Control agéntico (agent_checkpoint)</strong> desde el menú de Razonamiento: permite que el modelo consolide sus hallazgos intermedios y registre el siguiente paso para continuar investigando con coherencia. Especialmente recomendado con modelos de menos de 14B parámetros o ventanas de contexto inferiores a 32k tokens.',
143
+ rag_branch_loaded: 'Esta rama cargó {summary}',
144
+ rag_branch_summary_format: '{count} documento{plural} de {bytes}',
145
+ rag_doc_metrics_format: '{chunks} fragmentos · {size} · {images}',
146
+ rag_image_count_singular: '{count} imagen',
147
+ rag_image_count_plural: '{count} imágenes',
148
+ rag_image_count_reload: 'imágenes: recarga necesaria',
149
+ rag_branch_active_badge: 'Activa',
150
+ rag_branch_activate_badge: 'Activar',
151
+ rag_branch_no_desc: 'Sin descripción',
152
+ rag_no_branches_active: 'No hay ramas. Crea la primera desde RAG en Configuración.',
153
+ rag_status_desc_multi: 'El agente consultará en paralelo las {count} ramas activas en cada búsqueda.',
154
+ rag_mixed_languages_warning: 'Hay ramas documentales activas con idiomas distintos: {languages}. Este aviso no cambia la activación; ten en cuenta el idioma de cada conjunto al formular consultas.',
155
+ rag_status_desc_single: 'El agente puede buscar fragmentos de esta rama mediante Orama.',
156
+ rag_status_active_count: '{count} ramas activas ({list})',
157
+ rag_toolbar_active_single: 'Conocimiento local activo (1 rama)',
158
+ rag_toolbar_active_multi: 'Conocimiento local activo ({count} ramas)',
159
+ rag_workspace_empty: 'Escribe un nombre arriba y pulsa "Crear rama" para empezar.',
160
+ rag_dropzone_title: 'Arrastra o selecciona archivos',
161
+ rag_dropzone_hint: 'PDF o archivos de texto · guardado privado en IndexedDB',
162
+ rag_branch_empty_docs: 'La rama todavía no contiene documentos.',
163
+ rag_delete_doc_title: 'Eliminar documento',
164
+ rag_delete_doc_confirm: '¿Eliminar este documento y todos sus fragmentos?',
165
+ rag_delete_branch_confirm: '¿Eliminar la rama y todos sus documentos?',
166
+ rag_ingestion_global: 'Carga global: {finished} de {total}',
167
+ rag_ingestion_status: '{processed} indexados',
168
+ rag_ingestion_status_errors: '{processed} indexados · {failed} con error',
169
+ rag_ingestion_complete: 'Ingesta completada: {processed} indexados · {failed} no indexados',
170
+ rag_btn_stop_ingestion: 'Detener',
171
+ rag_ingestion_stopping: 'Deteniendo ingesta...',
172
+ rag_ingestion_cancelled: 'Ingesta detenida por el usuario',
173
+ rag_duplicate_title: 'Documento duplicado',
174
+ rag_duplicate_prompt: 'Ya existe un documento con el mismo nombre y ruta en esta rama ("{name}"). ¿Deseas reemplazarlo o ignorarlo?',
175
+ rag_btn_replace: 'Reemplazar',
176
+ rag_btn_ignore: 'Ignorar',
177
+ rag_duplicate_apply_all: 'Aplicar a todos los duplicados restantes de esta carga',
178
+ rag_duplicate_skipped: '{name} omitido (duplicado)',
179
+ rag_duplicate_replaced: '{name} reemplazado con éxito',
180
+ rag_ingestion_status_detail: '{processed} nuevos · {replaced} reemplazados · {skipped} omitidos',
181
+ rag_ingestion_complete_detail: 'Ingesta finalizada: {processed} nuevos · {replaced} reemplazados · {skipped} omitidos{errors}',
182
+ rag_quota_indexeddb: 'IndexedDB: {usage} de {quota}',
183
+ rag_quota_indexeddb_local: 'IndexedDB local',
184
+
185
+ // Barra de entrada y formulario
186
+ btn_attach_title: 'Adjuntar archivos (PDF, código, texto, imágenes)',
187
+ reasoning_btn_title: 'Nivel de esfuerzo de razonamiento (Medio por defecto)',
188
+ reasoning_menu_title: 'Nivel de Razonamiento',
189
+ reasoning_intensity_title: 'Intensidad',
190
+ reasoning_intensity_aria: 'Intensidad de razonamiento',
191
+ reasoning_intensity_none: 'Ninguno',
192
+ reasoning_intensity_max: 'Máximo',
193
+ reasoning_checkpoint_agent_title: 'Punto de control agéntico',
194
+ reasoning_checkpoint_agent_desc: 'Consolida hallazgos en modelos abiertos o RAG',
195
+ reasoning_checkpoint_agent_tooltip: 'Activar o desactivar herramienta agent_checkpoint',
196
+ agent_checkpoint_title: 'Punto de Control Agéntico',
197
+ agent_checkpoint_desc: 'Permite al modelo consolidar hallazgos, solicitar asistencia y registrar el siguiente paso para razonar sin pérdida de foco.',
198
+ input_placeholder: 'Escribe un mensaje...',
199
+ btn_stop: 'Detener',
200
+ btn_stop_title: 'Detener la generación de respuesta',
201
+ btn_send_title: 'Enviar mensaje',
202
+
203
+ // Niveles de razonamiento
204
+ reasoning_level_none: 'Desactivado (Ninguno)',
205
+ reasoning_desc_none: 'Sin razonamiento extendido',
206
+ reasoning_transport_title: 'Envío de configuración',
207
+ reasoning_transport_omit: 'No enviar configuración',
208
+ reasoning_transport_omit_desc: 'No incluye parámetros de razonamiento no confirmados.',
209
+ reasoning_transport_send_none: 'Enviar reasoning_effort: none',
210
+ reasoning_transport_send_none_desc: 'Prueba experimental; el proveedor puede ignorarlo o rechazarlo.',
211
+ reasoning_level_on: 'Activado (Estándar)',
212
+ reasoning_desc_on: 'Razonamiento extendido activo',
213
+ reasoning_level_minimal: 'Mínimo',
214
+ reasoning_desc_minimal: 'Razonamiento ultra-rápido y conciso',
215
+ reasoning_level_low: 'Bajo',
216
+ reasoning_desc_low: 'Razonamiento ligero y rápido',
217
+ reasoning_level_medium: 'Medio',
218
+ reasoning_desc_medium: 'Equilibrio entre rapidez y profundidad de análisis',
219
+ reasoning_level_high: 'Alto',
220
+ reasoning_desc_high: 'Máximo razonamiento y deducción profunda',
221
+ reasoning_level_xhigh: 'Extra Alto (X-High)',
222
+ reasoning_desc_xhigh: 'Esfuerzo de razonamiento exhaustivo',
223
+
224
+ // Panel lateral de Logs y Debug
225
+ debug_panel_title: 'Logs y Debug',
226
+ debug_status_idle: 'Inactivo',
227
+ debug_status_streaming: 'Generando...',
228
+ debug_status_thinking: 'Razonando...',
229
+ debug_status_done: 'Completado',
230
+ debug_status_loop_detected: 'Bucle infinito detectado',
231
+ agent_loop_warning_notice: 'Protección de bucle infinito: las herramientas se invocaron repetidamente sin avances. El ciclo agéntico se detuvo de forma ordenada.',
232
+ debug_status_error: 'Error',
233
+ btn_copy_debug_title: 'Copiar logs al portapapeles',
234
+ btn_clear_debug_title: 'Limpiar logs',
235
+ btn_autoscroll_title: 'Auto-scroll activado',
236
+ btn_close_debug_title: 'Cerrar panel de logs',
237
+ debug_messages_toggle: 'Debug messages',
238
+ debug_messages_toggle_title: 'Activar/Desactivar depuración interactiva de mensajes salientes',
239
+ debug_modal_title: 'Debug',
240
+ debug_modal_desc: 'Revisa o modifica el payload JSON antes de enviarlo al servidor. Puedes editar cualquier mensaje, parámetros o herramientas.',
241
+ btn_format_json: 'Formatear',
242
+ btn_copy_all: 'Copiar todo',
243
+ btn_send: 'Enviar',
244
+ btn_send_and_stop_debug: 'Enviar y parar debug',
245
+ btn_maximize_title: 'Maximizar / Restaurar',
246
+ debug_json_error_invalid: 'Error de sintaxis en JSON: {error}',
247
+ debug_tab_all: 'Todo',
248
+ debug_tabs_label: 'Filtros de logs',
249
+ debug_tab_thinking: 'Razonamiento',
250
+ debug_tab_tool: 'Herramientas',
251
+ debug_tab_network: 'Red',
252
+ debug_tab_raw: 'Raw',
253
+ debug_sys_init: 'Inspector de logs y razonamiento iniciado.',
254
+ debug_sys_cleared: 'Logs limpiados. Esperando peticiones...',
255
+ debug_tag_system: 'SISTEMA',
256
+ debug_tag_thinking: 'PENSAMIENTO',
257
+ debug_tag_tool: 'HERRAMIENTA',
258
+ debug_tag_network: 'RED',
259
+ debug_tag_stats: 'STATS',
260
+ debug_tag_error: 'ERROR',
261
+ debug_tag_warning: 'AVISO',
262
+ debug_tag_info: 'INFO',
263
+
264
+ // Mensajes del chat y acciones
265
+ btn_reuse: 'Reutilizar',
266
+ btn_reuse_title: 'Colocar mensaje en la caja de texto',
267
+ btn_delete: 'Borrar',
268
+ btn_delete_usr_title: 'Eliminar esta pregunta',
269
+ btn_delete_ast_title: 'Eliminar esta respuesta',
270
+ btn_copy: 'Copiar',
271
+ btn_copy_title: 'Copiar respuesta completa al portapapeles',
272
+ btn_copy_user_title: 'Copiar mensaje al portapapeles',
273
+ btn_branch_title: 'Crear una rama desde esta respuesta',
274
+ chat_branch_title: 'Rama: {title}',
275
+ chat_branch_error: 'No se pudo crear la rama de conversación.',
276
+ copied_text: '¡Copiado!',
277
+ empty_response: '(Respuesta vacía)',
278
+ msg_deleted_log: 'Mensaje [{id}] eliminado de la memoria y la interfaz ({count} turnos retirados).',
279
+
280
+ // Estadísticas
281
+ stat_ttft: '1º token: {sec}s',
282
+ stat_ttft_title: 'Tiempo hasta recibir el 1º token (Latencia / TTFT)',
283
+ stat_speed: '{speed} t/s',
284
+ stat_speed_title: 'Velocidad de generación (calculada desde el 1º token)',
285
+ stat_total_time: '{sec}s',
286
+ stat_total_time_title: 'Tiempo total de respuesta',
287
+ stat_tokens: '{tokens} tok',
288
+ stat_tokens_title: 'Tokens de respuesta generados en este turno',
289
+ stat_cache_tokens: '{tokens} cache',
290
+ stat_cache_title: 'Tokens leídos desde la caché de contexto del servidor (Prompt/KV Caching)',
291
+
292
+ // Respuestas agénticas y herramientas
293
+ tool_js_title: 'Herramienta Ejecutada: execute_javascript ({ms}ms)',
294
+ tool_js_title_running: 'Ejecutar JavaScript',
295
+ tool_badge_executing: 'Ejecutando...',
296
+ tool_badge_fetching: 'Consultando...',
297
+ tool_badge_downloading: 'Descargando...',
298
+ tool_badge_searching: 'Buscando...',
299
+ tool_loading_js: 'Ejecutando código JavaScript...',
300
+ tool_loading_web: 'Conectando y descargando página web...',
301
+ tool_loading_pdf: 'Descargando y analizando documento PDF...',
302
+ tool_loading_search: 'Consultando motores de búsqueda en tiempo real...',
303
+ tool_web_receiving: 'Recibiendo contenido...',
304
+ tool_search_searching: 'Buscando fuentes...',
305
+ tool_btn_collapse: 'Minimizar herramienta',
306
+ tool_btn_expand: 'Expandir herramienta',
307
+ tool_sandbox_output: 'Resultado:',
308
+ tool_web_title: 'Navegador Web: fetch_web_page',
309
+ tool_pdf_title: 'Documento PDF: download_pdf',
310
+ tool_web_requested_url: 'URL Solicitada por el Modelo:',
311
+ tool_web_content_received: 'Contenido Obtenido ({size}):',
312
+ tool_search_title: 'Buscador DuckDuckGo: search_web',
313
+ tool_search_query: 'Búsqueda Solicitada por el Modelo:',
314
+ tool_search_empty: 'No se encontraron resultados directos en DuckDuckGo para esta búsqueda.',
315
+ tool_search_sources_label: 'Fuentes y resultados encontrados:',
316
+ tool_rag_list_title: 'Base de Conocimiento (Índice de Documentos)',
317
+ tool_rag_list_loading: 'Consultando documentos indexados...',
318
+ tool_rag_list_retrieving: 'Recuperando documentos desde IndexedDB...',
319
+ tool_rag_list_indexed: '{count} doc{plural} indexado{plural}',
320
+ tool_rag_search_title: 'Conocimiento local: "{query}"',
321
+ tool_rag_search_loading: 'Buscando con Orama...',
322
+ tool_rag_search_building: 'Construyendo el índice local...',
323
+ tool_rag_search_matches: '{count} coincidencia{plural} · {scope}',
324
+ tool_rag_read_title: 'Fragmento de conocimiento',
325
+ tool_rag_image_title: 'Imagen RAG',
326
+ tool_rag_read_loading: 'Leyendo {chunkId}...',
327
+ tool_rag_read_retrieving: 'Recuperando texto desde IndexedDB...',
328
+ tool_rag_read_retrieved: 'Fragmento recuperado ({chars} caracteres)',
329
+ tool_rag_read_not_found: 'No encontrado',
330
+ tool_err_query: 'Error al consultar',
331
+ tool_status_success: 'Completado',
332
+ tool_status_error: 'Error ({ms}ms)',
333
+ tool_agent_checkpoint_title: 'Punto de control agéntico',
334
+ tool_agent_checkpoint_loading: 'Consolidando hallazgos...',
335
+ tool_agent_checkpoint_ready: 'Listo para responder',
336
+ tool_agent_checkpoint_continue: 'Continuando análisis',
337
+ tool_agent_checkpoint_findings: 'Hallazgos clave:',
338
+ tool_agent_checkpoint_missing: 'Información faltante:',
339
+ tool_agent_checkpoint_next: 'Siguiente hipótesis / paso:',
340
+
341
+ // Modal de Configuración
342
+ modal_title: 'Configuración del Chat',
343
+ tab_agent: 'Agente',
344
+ tab_model: 'Modelo',
345
+ tab_appearance: 'Visualización',
346
+ tab_inspector: 'Inspector',
347
+ tab_mcp: 'MCP',
348
+ tab_permissions: 'Permisos',
349
+ mcp_connection_title: 'Servidor Local',
350
+ mcp_connection_desc: 'Servidor local privado para conectar ZeroChat con herramientas del sistema (archivos, terminal, git y automatización) vía protocolo estandarizado.',
351
+ mcp_status_disconnected: 'Desconectado',
352
+ mcp_status_connecting: 'Conectando...',
353
+ mcp_status_checking: 'Comprobando conexión...',
354
+ mcp_status_connected: 'Conectado',
355
+ mcp_status_error: 'Error de conexión',
356
+ mcp_bootstrap_title: 'MCP requiere el servidor local',
357
+ mcp_bootstrap_desc: 'Para usar MCP, inicia ZeroChat desde zerochat.py en un terminal. La aplicación se conectará automáticamente cuando el servidor esté disponible.',
358
+ mcp_reconnect_after_restart: 'Si el servidor se ha reiniciado, recarga esta página (F5) para volver a conectar.',
359
+ mcp_bootstrap_help: 'Abrir ayuda de MCP',
360
+ mcp_btn_copy_cmd: 'Copiar comando',
361
+ mcp_cmd_copied: '¡Copiado!',
362
+ mcp_tools_discovered: '{count} herramientas activas',
363
+ mcp_no_tools: 'Sin herramientas registradas',
364
+ mcp_tools_section_title: 'Herramientas Disponibles del Sistema',
365
+ mcp_tools_count: '{count} detectadas',
366
+ mcp_tools_empty_disconnected: 'MCP necesita que ZeroChat se inicie desde zerochat.py para descubrir y activar herramientas del sistema.',
367
+ mcp_tools_empty_connected: 'El servidor local está conectado pero no expone ninguna herramienta.',
368
+ mcp_servers_section_title: 'Servidores MCP Disponibles',
369
+ mcp_servers_section_desc: 'Servicios MCP externos configurados en el servidor local listos para arrancar de forma individual.',
370
+ mcp_servers_empty: 'No hay servidores MCP externos disponibles en el servidor local.',
371
+ mcp_servers_count_tools: '{count} herramientas activas',
372
+ mcp_external_status_available: 'Disponible',
373
+ mcp_external_status_installing: 'Instalando',
374
+ mcp_external_status_starting: 'Iniciando',
375
+ mcp_external_status_running: 'En ejecución',
376
+ mcp_external_status_stopped: 'Detenido',
377
+ mcp_external_status_needs_attention: 'Requiere atención',
378
+ mcp_external_status_error: 'Error',
379
+ mcp_btn_start_server: 'Iniciar',
380
+ mcp_btn_stop_server: 'Detener',
381
+ mcp_tool_badge: 'MCP',
382
+ tool_auth_title: 'Autorización de Ejecución',
383
+ tool_auth_desc: 'Esta herramienta MCP requiere tu confirmación antes de interactuar con el sistema:',
384
+ tool_auth_badge: 'Requiere Autorización',
385
+ tool_auth_allow_once: 'Permitir una vez',
386
+ tool_auth_allow_always: 'Permitir siempre este tool',
387
+ tool_auth_deny: 'Denegar',
388
+ tool_auth_denied_badge: 'Denegado',
389
+ tool_auth_denied_msg: 'Ejecución denegada por el usuario.',
390
+ tool_security_policy_blocked: 'Herramienta bloqueada por política de seguridad.',
391
+ mcp_security_section_title: 'Seguridad y Autorización de Ejecución',
392
+ mcp_security_desc: 'Controla cuándo se ejecutan las herramientas del servidor MCP en tu sistema local.',
393
+ mcp_security_policy_ask: 'Pedir autorización antes de ejecutar (Recomendado)',
394
+ mcp_security_policy_ask_hint: 'El chat te pedirá confirmar cada comando o herramienta MCP no autorizada previamente.',
395
+ mcp_security_policy_allow_all: 'Todo autorizado (Modo sin restricciones)',
396
+ mcp_security_policy_allow_all_hint: 'Ejecuta inmediatamente cualquier herramienta MCP sin pausas de confirmación.',
397
+ mcp_security_saved_auths_title: 'Herramientas con Permiso Recordado',
398
+ mcp_security_no_saved_auths: 'No hay autorizaciones permanentes registradas.',
399
+ mcp_security_btn_revoke: 'Revocar',
400
+ mcp_security_btn_clear_all: 'Restablecer todas',
401
+ mcp_security_badge_allowed: 'Permitida',
402
+ mcp_security_badge_ask: 'Preguntar',
403
+ mcp_security_select_title: 'Cambiar política de ejecución para esta herramienta',
404
+ mcp_security_constrained: 'Acotada',
405
+ tool_auth_allow_cmd_btn: 'Permitir siempre "{cmd}"',
406
+ tool_auth_allow_cmd_title: 'Permitir permanentemente solo comandos que comiencen por "{cmd}"',
407
+ tool_auth_allow_path_btn: 'Permitir siempre en ruta actual',
408
+ tool_auth_allow_path_title: 'Permitir permanentemente solo operaciones dentro de la carpeta de trabajo actual',
409
+ inspector_desc: 'Analiza el endpoint configurado para determinar con precisión qué capacidades soporta, distinguiendo entre capacidades declaradas, inferidas y comprobadas mediante pruebas activas seguras.',
410
+ btn_run_inspector: 'Ejecutar Diagnóstico de Capacidades',
411
+ btn_running_inspector: 'Diagnosticando endpoint...',
412
+ inspector_status_confirmed: 'Comprobada',
413
+ inspector_status_inferred: 'Inferida',
414
+ inspector_status_declared: 'Declarada',
415
+ inspector_status_unsupported: 'No soportada',
416
+ inspector_status_unknown: 'Desconocida',
417
+ inspector_cap_streaming: 'Streaming (SSE)',
418
+ inspector_cap_tools: 'Herramientas (Tool Calling)',
419
+ inspector_cap_vision: 'Visión Multimodal',
420
+ inspector_cap_reasoning: 'Control de Razonamiento',
421
+ inspector_cap_jsonMode: 'Modo Estructurado (JSON)',
422
+ inspector_cap_promptCaching: 'Caché de Contexto',
423
+ inspector_cap_embeddings: 'Embeddings',
424
+ inspector_cap_modelListing: 'Descubrimiento de Modelos',
425
+ inspector_meta_provider: 'Proveedor',
426
+ inspector_meta_endpoint: 'Endpoint Chat',
427
+ inspector_meta_models: 'Modelos',
428
+ inspector_meta_latency: 'Latencia Diagnóstico',
429
+ inspector_discovered_models: '{count} modelo(s) descubierto(s)',
430
+ inspector_no_models: 'Sin modelos listados',
431
+ inspector_unknown: 'Desconocido',
432
+ inspector_model_selected: 'Modelo: {model}',
433
+ inspector_conn_failed: 'Fallo de conexión: No se pudo conectar con el servidor.',
434
+ inspector_module_unavailable: 'Módulo de inspección no disponible.',
435
+ field_language: 'Idioma de la Interfaz (Language)',
436
+ field_language_hint: 'Selecciona el idioma visual de la aplicación.',
437
+ field_language_short: 'Idioma',
438
+ field_theme_short: 'Tema',
439
+ field_profile: 'Perfil de Conexión / Servidor',
440
+ tab_connection: 'Conexión',
441
+ sidebar_settings_title: 'Configuración',
442
+ sidebar_help: 'Ayuda',
443
+ sidebar_help_href: 'help/index.html',
444
+ btn_back_to_chats: 'Volver al historial',
445
+ btn_save_short: 'Guardar',
446
+ btn_diagnose_short: 'Diagnóstico',
447
+ connection_active_profile: 'Perfil activo',
448
+ connection_active_hint: 'Los perfiles se seleccionan y editan desde la caja de prompt.',
449
+ btn_manage_profiles: 'Gestionar perfiles de conexión',
450
+ profiles_modal_title: 'Perfil',
451
+ btn_close: 'Cerrar',
452
+ field_profile_name_label: 'Nombre del Perfil',
453
+ field_profile_description_label: 'Descripción',
454
+ field_profile_description_placeholder: 'Describe brevemente este perfil...',
455
+ profile_tab_name: 'General',
456
+ profile_tab_settings: 'Configuración',
457
+ profile_tab_model: 'Modelo',
458
+ field_profile_placeholder: 'Nombre del perfil (ej: LM Studio, Ollama, OpenRouter...)',
459
+ profile_select_default: '▾ Elegir perfil guardado...',
460
+ btn_new_profile: 'Nuevo',
461
+ btn_new_profile_title: 'Crear un perfil nuevo',
462
+ btn_export_profiles: 'Exportar',
463
+ btn_export_profiles_title: 'Exportar todos los perfiles a un archivo cifrado',
464
+ profiles_backup_title: 'Copia y restauración de perfiles',
465
+ profiles_backup_description: 'Estas acciones afectan a todos los perfiles editables, no solo al perfil seleccionado.',
466
+ confirm_import_profiles: 'Se cargarán {count} perfiles y se sustituirán los que tengan el mismo identificador. ¿Deseas continuar?',
467
+ msg_profiles_exported: 'Copia cifrada de perfiles creada.',
468
+ msg_profiles_exported_html: 'Perfiles exportados. Abre el archivo HTML descargado para importarlos automáticamente.',
469
+ msg_profiles_imported: 'Perfiles cargados: {added} nuevos y {replaced} actualizados.',
470
+ msg_profiles_auto_imported: 'Importación completada: {added} nuevo(s), {replaced} actualizado(s).',
471
+ err_profiles_backup: 'No se pudo procesar la copia de perfiles: {err}',
472
+ err_no_profiles_to_export: 'No hay perfiles para exportar (excepto el perfil Espejo).',
473
+ err_auto_import_failed: 'Error al importar perfiles automáticamente: {err}',
474
+ confirm_auto_import_profiles: '¿Importar {count} perfil(es) de conexión desde el archivo externo?',
475
+ btn_save_profile: 'Guardar Perfil',
476
+ btn_save_profile_title: 'Guardar todos los valores actuales en este perfil',
477
+ btn_delete_profile: 'Borrar',
478
+ btn_delete_profile_title: 'Eliminar el perfil seleccionado',
479
+ prompt_new_profile_name: 'Nombre del nuevo perfil:',
480
+ msg_profile_saved: 'Perfil "{name}" guardado con éxito.',
481
+ msg_profile_created: 'Perfil "{name}" creado.',
482
+ msg_profile_deleted: 'Perfil "{name}" eliminado correctamente.',
483
+ profile_save_changes_required: 'Realiza algún cambio en el perfil para habilitar el guardado.',
484
+ profile_save_pending: 'Hay cambios pendientes. Guarda el perfil para conservarlos.',
485
+ confirm_profile_query_not_saved: 'La consulta se ha completado, pero el perfil no se ha guardado. ¿Deseas descartar los cambios y cerrar?',
486
+ confirm_profile_unsaved_changes: 'Hay cambios sin guardar en el perfil. ¿Deseas descartarlos y cerrar?',
487
+ confirm_settings_unsaved_changes: 'Hay cambios sin guardar en la configuración. ¿Deseas descartarlos y cerrar?',
488
+ confirm_rag_branch_unsaved_changes: 'Hay cambios sin guardar en la rama. ¿Deseas descartarlos y cerrar?',
489
+ confirm_delete_profile: '¿Estás seguro de que deseas eliminar el perfil "{name}"?',
490
+ err_profile_name_exists: 'Ya existe un perfil llamado "{name}".',
491
+ err_profile_read_only: 'El perfil Espejo no se puede modificar ni eliminar.',
492
+ btn_edit_profile_title: 'Editar este perfil',
493
+ btn_delete_profile_item_title: 'Eliminar este perfil',
494
+ btn_close_profiles_menu: 'Cerrar selector',
495
+ field_api_type: 'Tipo de Interfaz / Protocolo',
496
+ profile_api_key_lock: 'Bloquear cambios',
497
+ profile_api_key_locked: 'Cambios bloqueados',
498
+ field_api_url: 'URL del Servidor / Endpoint de Chat',
499
+ webllm_local_hint: 'Ejecución local en este navegador.',
500
+ webllm_help_link: 'Guía de configuración WebLLM',
501
+ webllm_query_optional: 'Modelo descargado listo. La consulta al servidor es opcional.',
502
+ generation_status_connecting: 'Conectando…',
503
+ generation_status_preparing: 'Preparando modelo…',
504
+ generation_status_loading: 'Cargando modelo…',
505
+ generation_status_compiling: 'Compilando GPU…',
506
+ generation_status_thinking: 'Pensando',
507
+ generation_status_generating: 'Generando respuesta…',
508
+ generation_status_rag: 'Consultando RAG…',
509
+ generation_status_tool: 'Ejecutando {name}…',
510
+ generation_status_loop_detected: 'Parada ordenada: bucle infinito detectado',
511
+ generation_status_percent: '{text} · {percent} %',
512
+ generation_status_elapsed: '{text} · {seconds} s',
513
+ webllm_download: 'Descargar',
514
+ webllm_delete: 'Borrar modelo',
515
+ webllm_cancel: 'Cancelar preparación',
516
+ webllm_cancelling: 'Cancelando…',
517
+ webllm_deleting: 'Borrando…',
518
+ webllm_delete_failed: 'No se pudo borrar el modelo.',
519
+ webllm_model_incomplete: 'La descarga no está completa. Vuelve a intentarlo.',
520
+ webllm_model_unknown: 'Estado local no comprobado',
521
+ confirm_webllm_delete: '¿Borrar el modelo descargado "{model}" de este navegador?',
522
+ webllm_preparing: 'Descargando y preparando…',
523
+ webllm_starting: 'Iniciando el motor local…',
524
+ webllm_loading_parameters: 'Cargando parámetros del modelo…',
525
+ webllm_loading_model: 'Cargando modelo desde almacenamiento {current}/{total}{percent}{elapsed}',
526
+ webllm_ready: 'Modelo preparado',
527
+ webllm_model_cached: 'Descargado',
528
+ webllm_model_missing: 'No descargado',
529
+ webllm_vram_required: 'VRAM aprox. {size}',
530
+ webllm_gpu_shaders: 'Compilando módulos GPU {current}/{total}{percent}{elapsed}',
531
+ webllm_elapsed_seconds: '{seconds} s',
532
+ btn_query_title: 'Consultar modelos disponibles y capacidades de la API en el servidor',
533
+ btn_query_text: 'Query',
534
+ btn_querying_text: 'Consultando...',
535
+ field_api_key: 'Clave de API (API Key)',
536
+ field_api_key_hint: 'Opcional si usas un servidor local (LM Studio / Ollama / LocalAI).',
537
+ field_api_key_required_hint: 'Obligatoria para este proveedor.',
538
+ field_api_key_free_help: 'Cómo obtener una API key gratuita',
539
+ btn_toggle_key_title: 'Mostrar/Ocultar clave',
540
+ field_model: 'Nombre del Modelo',
541
+ field_model_hint: 'Selecciona de la lista del servidor o escribe cualquier nombre personalizado.',
542
+ field_model_placeholder: 'Escribe o pulsa Query para consultar modelos...',
543
+ model_select_default: '▾ Elegir modelo detectado...',
544
+ model_select_count: '▾ Elegir modelo detectado ({count})...',
545
+ btn_webllm_params_title: 'Parámetros avanzados de rendimiento WebLLM',
546
+ webllm_params_title: 'Parámetros de ejecución WebGPU',
547
+ webllm_opt_default: 'Por defecto del modelo',
548
+ field_webllm_context_window: 'Ventana de contexto (context_window_size)',
549
+ field_webllm_prefill_chunk: 'Bloque de prefill (prefill_chunk_size)',
550
+ field_theme: 'Tema Visual de la Interfaz',
551
+ field_theme_hint: 'Selecciona el modo de visualización.',
552
+ theme_light: 'Modo Claro',
553
+ theme_dark: 'Modo Oscuro',
554
+ agent_intro: 'Configura las herramientas agénticas y el contexto temporal que se transmiten al modelo.',
555
+ agent_search_title: 'Búsqueda en DuckDuckGo en Tiempo Real',
556
+ agent_search_desc: 'Permite al modelo invocar search_web para buscar información actualizada, definiciones, noticias y enlaces web mediante la API de DuckDuckGo.',
557
+ agent_js_title: 'Ejecución de JavaScript (Cálculos locales)',
558
+ agent_js_desc: 'Permite al modelo ejecutar JavaScript en un worker local para facilitar cálculos, procesamiento de datos y algoritmos bajo la supervisión y conocimiento de un usuario técnico.',
559
+ agent_web_title: 'Navegador Web en Tiempo Real',
560
+ agent_web_desc: 'Permite al modelo invocar fetch_web_page para consultar páginas web públicas y extraer su contenido textual en tiempo real.',
561
+ agent_pdf_title: 'Descarga y Lectura de Documentos PDF',
562
+ agent_pdf_desc: 'Permite al modelo descargar documentos PDF desde la web y extraer todo su texto al contexto en tiempo real.',
563
+ agent_chart_title: 'Visualización de Datos y Gráficos Nativos (SVG)',
564
+ agent_chart_desc: 'Permite al modelo invocar render_chart para generar y mostrar gráficos interactivos de barras, líneas o sectores sin librerías externas.',
565
+ model_cache_title: 'Caché de contexto automática',
566
+ model_cache_desc: 'El cliente aplica automáticamente las marcas de caché compatibles con el proveedor. En servidores locales, la caché KV se administra en el servidor.',
567
+ field_max_agent_turns: 'Límite de turnos agénticos',
568
+ field_max_agent_turns_hint: 'Número máximo de pasos o llamadas consecutivas a herramientas antes de forzar la síntesis final (entre 5 y 35).',
569
+ field_system_prompt: 'Prompt del Sistema (Opcional)',
570
+ field_system_prompt_hint: 'Instrucciones base personalizadas que guían el comportamiento del asistente (opcional).',
571
+ field_system_prompt_placeholder: 'Escribe aquí tus instrucciones personalizadas para el modelo (opcional)...',
572
+ field_system_data_prompt: 'Perfil del sistema · datos ZeroChat',
573
+ field_system_data_prompt_hint: 'Instrucciones internas de ZeroChat. Es mejor no modificarlas; añade lo que veas necesario.',
574
+ field_system_data_prompt_placeholder: 'Instrucciones internas de ZeroChat...',
575
+ field_temperature: 'Temperatura: {val}',
576
+ field_temperature_hint: 'Controla la creatividad de las respuestas (0 = determinista/preciso, 1 = creativo).',
577
+ cookie_notice: 'Toda la configuración se almacena localmente de forma persistente (compatible tanto con <strong>file://</strong> como con servidores web).',
578
+ btn_clear_all_data: 'Borrar todo',
579
+ btn_clear_all_data_title: 'Borrar todas las cookies, sesiones y configuraciones locales',
580
+ confirm_clear_all_data: '¿Borrar todos los datos de este origen: configuración, chats, adjuntos, RAG, modelos descargados, cookies, IndexedDB, cachés y archivos locales del navegador? También afecta a otras aplicaciones que compartan este origen. Cierra las otras pestañas de ZeroChat antes de continuar.\n\nNo se puede deshacer. La aplicación se recargará. HTTP y file:// tienen almacenamientos separados.',
581
+ clear_all_data_failed: 'No se pudo completar el borrado. Cierra las otras pestañas y detén las operaciones activas antes de reintentar. Puedes eliminar los datos del sitio desde los ajustes del navegador.',
582
+ clear_all_data_failed_detail: 'No se pudo completar el borrado. Detalle: {detail}',
583
+ btn_cancel: 'Cancelar',
584
+ btn_save: 'Guardar Configuración',
585
+ modal_close_aria: 'Cerrar modal',
586
+
587
+ // Mensajes de estado y errores
588
+ err_no_model_title: 'No hay ningún modelo seleccionado:',
589
+ err_no_model_desc: 'Por favor, abre la <strong>Configuración</strong> para introducir un modelo o pulsa el botón <strong>Query</strong> para consultar los modelos disponibles en tu servidor ({url}).',
590
+ err_server_connect_title: 'Error al conectar con el servidor:',
591
+ err_server_connect: 'Error al conectar con el servidor:',
592
+ err_server_connect_hint: 'Abre la <strong>Configuración</strong> para verificar la URL del servidor ({url}), el modelo y tu API Key.',
593
+ err_invalid_url: 'Por favor, introduce una URL de servidor válida.',
594
+ err_connecting_models: 'Conectando con {url} para obtener modelos...',
595
+ msg_models_success: '<strong>{count} modelos detectados con éxito</strong> en <code>{endpoint}</code>.',
596
+ msg_models_success_text: '{count} modelos detectados en {endpoint}.',
597
+ err_api_connect: '<strong>Error al conectar con la API:</strong> {err}',
598
+ err_ollama_origins: 'Ollama bloqueó el acceso desde el navegador. Añade <code>OLLAMA_ORIGINS=*</code> a su configuración y reinicia Ollama.',
599
+ err_file_process: 'No se pudo procesar el archivo {name}: {err}',
600
+ err_file_too_large: 'El archivo "{name}" supera el tamaño máximo permitido ({max}).',
601
+
602
+ // Markdown & JavaScript
603
+ md_thought_title: 'Proceso de razonamiento',
604
+ md_thought_reasoning: 'Razonando...',
605
+ md_run_js_title: 'Ejecutar JavaScript (en worker local)',
606
+ md_run_js_btn: 'Ejecutar JS',
607
+ md_copy_code_title: 'Copiar código',
608
+ md_copy_code_btn: 'Copiar',
609
+ md_output_title: 'Salida (Consola / Retorno):',
610
+ md_clear_output: 'Limpiar salida',
611
+
612
+ // Barra lateral e Historial de Conversaciones (Sidebar)
613
+ sidebar_title: 'Chats y Configuración',
614
+ btn_sidebar_title: 'Chats y Configuración',
615
+ btn_new_chat_sidebar_title: 'Crear nueva conversación',
616
+ btn_open_new_tab_title: 'Abrir ZeroChat en una nueva pestaña',
617
+ btn_close_sidebar_title: 'Cerrar barra lateral',
618
+ sidebar_search_placeholder: 'Buscar en historial...',
619
+ sidebar_no_chats: 'No hay conversaciones guardadas',
620
+ sidebar_group_today: 'Hoy',
621
+ sidebar_group_yesterday: 'Ayer',
622
+ sidebar_group_last7days: 'Últimos 7 días',
623
+ sidebar_group_last30days: 'Últimos 30 días',
624
+ sidebar_group_older: 'Anteriores',
625
+ btn_import_chat: 'Importar',
626
+ btn_import_chat_title: 'Importar conversación desde archivo JSON',
627
+ btn_export_chat_title: 'Exportar conversación (Markdown, JSON, PDF)',
628
+ btn_delete_all_chats: 'Borrar todos',
629
+ btn_delete_all_chats_title: 'Eliminar todas las conversaciones guardadas',
630
+ chat_untitled: 'Nueva conversación',
631
+ sidebar_rename_chat_title: 'Renombrar chat',
632
+ sidebar_export_chat_title: 'Exportar chat',
633
+ sidebar_delete_chat_title: 'Eliminar chat',
634
+ chat_delete_confirm: '¿Seguro que deseas eliminar esta conversación?',
635
+ chat_delete_all_confirm: '¿Estás seguro de que deseas eliminar todas las conversaciones guardadas? Esta acción no se puede deshacer.',
636
+ chat_delete_history_err: 'No se pudo borrar el historial persistente. Revisa la consola para más detalles.',
637
+ prompt_rename_conversation: 'Nombre de la conversación:',
638
+ no_text_response: '(Sin respuesta de texto)',
639
+ chat_imported_success: 'Conversación importada con éxito.',
640
+ chat_import_json_err: 'Error al leer el archivo JSON: {err}',
641
+ chat_new_blocked_generating: 'No puedes crear una conversación nueva mientras se está generando una respuesta. Detén la generación e inténtalo de nuevo.',
642
+ chat_switch_blocked_generating: 'No puedes cambiar de conversación mientras se está generando una respuesta. Detén la generación e inténtalo de nuevo.',
643
+ chat_delete_blocked_generating: 'No puedes eliminar una conversación mientras se está generando una respuesta. Detén la generación e inténtalo de nuevo.',
644
+ chat_import_blocked_generating: 'No puedes importar una conversación mientras se está generando una respuesta. Detén la generación e inténtalo de nuevo.',
645
+
646
+ // Modal de Exportación
647
+ export_modal_title: 'Exportar Conversación',
648
+ btn_close_export_title: 'Cerrar modal de exportación',
649
+ export_md_title: 'Descargar Markdown (.md)',
650
+ export_md_desc: 'Formato limpio con formato, código y tablas legible en cualquier visor.',
651
+ export_json_title: 'Descargar JSON de Sesión (.json)',
652
+ export_json_desc: 'Historial estructurado completo con herramientas, imágenes y metadatos para restaurar.',
653
+ export_pdf_title: 'Imprimir / Guardar como PDF',
654
+ export_pdf_desc: 'Genera un documento PDF limpio maquetado para lectura e informes.',
655
+ export_date: 'Fecha de exportación',
656
+ not_specified: 'No especificado',
657
+ role_user: '👤 Usuario',
658
+ role_assistant: '🤖 Asistente',
659
+
660
+ // Gráficos interactivos
661
+
662
+ // Contexto del sistema de fecha/hora del mundo real
663
+ },
664
+
665
+ en: {
666
+ notice_accept: 'OK',
667
+ notice_cancel: 'Cancel',
668
+ notice_confirm: 'Confirmation',
669
+ notice_info: 'Information',
670
+ notice_error: 'Error',
671
+ notice_success: 'Success',
672
+ notice_warning: 'Warning',
673
+ notice_prompt: 'Enter text',
674
+ notice_export_error: 'Could not export branch: {err}',
675
+ notice_branch_restored: 'Branch "{name}" restored successfully.',
676
+ notice_import_error: 'Could not restore: {err}',
677
+
678
+ // Metadata & Headers
679
+ app_title: APP_TITLE,
680
+ app_description: 'ZeroChat - Universal web chat client, autonomous AI agent, and local RAG in a single zero-install file',
681
+
682
+ // Welcome state
683
+ welcome_heading: 'ZeroChat',
684
+ welcome_desc: 'Conversational environment & local autonomous agent.',
685
+ welcome_status: 'Empty chat · Awaiting a command',
686
+ welcome_help_link: 'Help & Documentation',
687
+ welcome_help_title: 'Open online help and documentation center',
688
+ welcome_help_href: 'help/en/index.html',
689
+ execution_info_title: 'Execution mode and storage',
690
+ execution_info_http: 'In server mode, chats, profiles, and preferences are shared with every ZeroChat page using the same protocol, host, and port. The path does not separate them.',
691
+ execution_info_file: 'In local file mode, the browser decides how data is isolated or shared. Always store and run zerochat.html from the same location if you want settings to persist.',
692
+ execution_info_portable_tool: 'ZeroChat runs directly in your web browser. The interface starts statically and securely.',
693
+ execution_info_requirements: 'The conversation still needs the provider you configured: a local model can work offline; a remote API and web features cannot.',
694
+
695
+ // Barra de herramientas superior
696
+ profile_badge_title: 'Active connection profile',
697
+ edit_profiles: 'Edit profiles',
698
+ profile_menu_title: 'Connection profiles',
699
+ profile_mirror_description: 'Shows the OpenAI request without sending it.',
700
+ profile_mirror_type: 'Mirror (offline)',
701
+ mirror_response_intro: '# Welcome to ZeroChat\n\nThis is a safe view of the **Mirror** profile: the request below was generated for inspection, but **has not been sent to any service**.',
702
+ mirror_response_about: '## ZeroChat, your way\n\nZeroChat brings conversations, tools, and local knowledge together in a flexible interface. Connect it to local models or remote providers with independent connection profiles. To explore all capabilities and setup guides, check out the [general help and documentation](help/en/index.html).',
703
+ mirror_response_profile: '## Continue with a profile\n\nCreate a profile to save the provider, endpoint, model, and preferences you want to use. You can then switch configurations without entering their values again.',
704
+ mirror_response_webllm: '> **WebLLM (experimental):** you can also create a WebLLM profile to run a compatible model locally in the browser with WebGPU. Download the model first; availability and performance depend on your browser and hardware.',
705
+ mirror_response_request: '## Prepared request (not sent)',
706
+ context_hub_btn_title: 'Conversation context and token metrics (Click to view details)',
707
+ context_hub_title: 'Context & Token Metrics',
708
+ context_section_global: 'Global Context Window',
709
+ context_metric_used: 'Context Used',
710
+ context_metric_limit: 'Capacity',
711
+ context_metric_free: 'Available',
712
+ context_metric_status: 'Status',
713
+ context_limit_source_server: 'Capacity published by the server.',
714
+ context_limit_source_manual: 'Assumed capacity set for this profile.',
715
+ context_limit_source_assumed: 'Assumed capacity: the server did not publish it.',
716
+ context_limit_override_label: 'Assumed capacity (tokens)',
717
+ context_limit_override_save: 'Use',
718
+ context_limit_override_invalid: 'Enter a valid capacity, for example 90K.',
719
+ context_limit_override_profile_required: 'Select a connection profile before saving the assumed capacity.',
720
+ context_limit_override_save_error: 'Could not save the assumed capacity.',
721
+ context_status_ok: 'Optimal',
722
+ context_status_warning: 'High',
723
+ context_status_critical: 'Critical',
724
+ context_section_cache: 'Context Cache (Prompt/KV)',
725
+ context_metric_cached_read: 'Read (Saved)',
726
+ context_metric_cached_write: 'Written to cache',
727
+ context_section_turn: 'Last Generated Turn',
728
+ context_metric_turn_prompt: 'Input (Prompt)',
729
+ context_metric_turn_completion: 'Output (Response)',
730
+ context_metric_turn_speed: 'Speed',
731
+ context_metric_turn_latency: 'Latency (TTFT)',
732
+ no_model: '(No model)',
733
+ btn_logs: 'Logs & Debug',
734
+ btn_logs_title: 'Open/Close logs & debugging side panel',
735
+ btn_settings: 'Settings',
736
+ btn_settings_title: 'Open general settings',
737
+ btn_rag: 'RAG',
738
+ btn_rag_title: 'Manage local knowledge (RAG)',
739
+ rag_modal_title: 'Local knowledge',
740
+ rag_modal_title_activate: 'RAG',
741
+ rag_modal_title_manage: 'RAG. Manage',
742
+ rag_menu_label: 'RAG',
743
+ rag_help_link_text: 'Need help with RAG?',
744
+ rag_help_link_label: 'View complete guide',
745
+ rag_status_disabled: 'Knowledge disabled',
746
+ rag_status_disabled_desc: 'Select one or more branches so the agent can search your documents.',
747
+ rag_disable: 'Disable',
748
+ rag_disable_all: 'Disable all',
749
+ rag_activate_all: 'Activate all',
750
+ rag_available_branches: 'Available branches',
751
+ rag_available_branches_hint: 'You can activate one or more branches simultaneously for cross-branch searches.',
752
+ rag_branch_label: 'Branch:',
753
+ rag_new_branch: 'New branch',
754
+ rag_edit_branch: 'Edit',
755
+ rag_delete_branch: 'Delete',
756
+ rag_export_branch: 'Backup',
757
+ rag_import_branch: 'Restore',
758
+ rag_branch_name: 'Branch name:',
759
+ rag_branch_name_placeholder: 'Branch name (e.g. Manuals)',
760
+ rag_branch_lang: 'Documentation language:',
761
+ rag_lang_spanish: 'Spanish',
762
+ rag_lang_english: 'English',
763
+ rag_lang_french: 'French',
764
+ rag_lang_german: 'German',
765
+ rag_lang_italian: 'Italian',
766
+ rag_lang_portuguese: 'Portuguese',
767
+ rag_branch_desc: 'Description (optional):',
768
+ rag_branch_desc_placeholder: 'Description of the content in this branch',
769
+ rag_btn_save: 'Save',
770
+ rag_branch_created: 'Branch "{name}" created successfully',
771
+ rag_branch_updated: 'Branch "{name}" saved successfully',
772
+ rag_branch_name_empty: 'Please enter a branch name',
773
+ rag_active_tip_title: 'RAG performance & model capability:',
774
+ rag_active_tip_desc: 'RAG effectiveness relies heavily on the <strong>intelligence, multimodal vision</strong> (to interpret tables, charts, and images), and <strong>agentic reasoning capability</strong> of the selected model: it is essential for formulating precise queries, inspecting adjacent chunks, and evaluating evidence accurately. If using smaller models or models with limited agentic capabilities, enable the <strong>Agent Checkpoint (agent_checkpoint)</strong> from the Reasoning menu to consolidate findings and maintain a clear research plan.',
775
+ rag_help_storage_desc: 'Files, metadata, and chunks are stored in IndexedDB. Orama builds an in-memory local search index for the active branch.',
776
+ rag_help_private_title: 'No permissions or ingestion costs',
777
+ rag_help_private_desc: 'Selecting a file only grants access to that upload. No folder permissions are requested and no LLM is called to summarize or index it.',
778
+ rag_help_llm_title: 'Configure the model for document answers',
779
+ rag_help_llm_desc: 'For factual questions about documents, use a low temperature (0 to 0.2): it reduces variation and makes the model more likely to follow retrieved excerpts. A temperature of 0.7 or above is better for creative writing, not extracting figures or facts. The model must also support tool calls; otherwise it cannot query this knowledge base.',
780
+ rag_help_checkpoint_title: 'Agent checkpoint for low-context or small models',
781
+ rag_help_checkpoint_desc: 'Compact models or models with a small context window can easily get saturated when accumulating multiple document chunks. Enable the <strong>Agent Checkpoint (agent_checkpoint)</strong> from the Reasoning menu: it lets the model consolidate intermediate findings and record the next step to continue investigating coherently. Especially recommended for models with fewer than 14B parameters or context windows below 32k tokens.',
782
+ rag_branch_loaded: 'This branch loaded {summary}',
783
+ rag_branch_summary_format: '{count} document{plural} of {bytes}',
784
+ rag_doc_metrics_format: '{chunks} chunks · {size} · {images}',
785
+ rag_image_count_singular: '{count} image',
786
+ rag_image_count_plural: '{count} images',
787
+ rag_image_count_reload: 'images: reload required',
788
+ rag_branch_active_badge: 'Active',
789
+ rag_branch_activate_badge: 'Activate',
790
+ rag_branch_no_desc: 'No description',
791
+ rag_no_branches_active: 'No branches available. Create the first one from RAG in Settings.',
792
+ rag_status_desc_multi: 'The agent will query the {count} active branches in parallel for each search.',
793
+ rag_mixed_languages_warning: 'Active documentary branches use different languages: {languages}. This notice does not change activation; consider each collection language when formulating queries.',
794
+ rag_status_desc_single: 'The agent can search chunks in this branch using Orama.',
795
+ rag_status_active_count: '{count} active branches ({list})',
796
+ rag_toolbar_active_single: 'Local knowledge active (1 branch)',
797
+ rag_toolbar_active_multi: 'Local knowledge active ({count} branches)',
798
+ rag_workspace_empty: 'Type a name above and click "Create branch" to start.',
799
+ rag_dropzone_title: 'Drag or select files',
800
+ rag_dropzone_hint: 'PDF or text files · private storage in IndexedDB',
801
+ rag_branch_empty_docs: 'This branch does not contain documents yet.',
802
+ rag_delete_doc_title: 'Delete document',
803
+ rag_delete_doc_confirm: 'Delete this document and all its chunks?',
804
+ rag_delete_branch_confirm: 'Delete this branch and all its documents?',
805
+ rag_ingestion_global: 'Overall upload: {finished} of {total}',
806
+ rag_ingestion_status: '{processed} indexed',
807
+ rag_ingestion_status_errors: '{processed} indexed · {failed} with error',
808
+ rag_ingestion_complete: 'Ingestion complete: {processed} indexed · {failed} not indexed',
809
+ rag_btn_stop_ingestion: 'Stop',
810
+ rag_ingestion_stopping: 'Stopping ingestion...',
811
+ rag_ingestion_cancelled: 'Ingestion stopped by user',
812
+ rag_duplicate_title: 'Duplicate document',
813
+ rag_duplicate_prompt: 'A document with the same name and path already exists in this branch ("{name}"). Do you want to replace it or ignore it?',
814
+ rag_btn_replace: 'Replace',
815
+ rag_btn_ignore: 'Ignore',
816
+ rag_duplicate_apply_all: 'Apply to all remaining duplicates in this load',
817
+ rag_duplicate_skipped: '{name} skipped (duplicate)',
818
+ rag_duplicate_replaced: '{name} replaced successfully',
819
+ rag_ingestion_status_detail: '{processed} new · {replaced} replaced · {skipped} skipped',
820
+ rag_ingestion_complete_detail: 'Ingestion complete: {processed} new · {replaced} replaced · {skipped} skipped{errors}',
821
+ rag_quota_indexeddb: 'IndexedDB: {usage} of {quota}',
822
+ rag_quota_indexeddb_local: 'Local IndexedDB',
823
+
824
+ // Barra de entrada y formulario
825
+ btn_attach_title: 'Attach files (PDF, code, text, images)',
826
+ reasoning_btn_title: 'Reasoning effort level (Medium by default)',
827
+ reasoning_menu_title: 'Reasoning Level',
828
+ reasoning_intensity_title: 'Intensity',
829
+ reasoning_intensity_aria: 'Reasoning intensity',
830
+ reasoning_intensity_none: 'None',
831
+ reasoning_intensity_max: 'Maximum',
832
+ reasoning_checkpoint_agent_title: 'Agent Checkpoint',
833
+ reasoning_checkpoint_agent_desc: 'Consolidates findings in open models or RAG',
834
+ reasoning_checkpoint_agent_tooltip: 'Enable or disable agent_checkpoint tool',
835
+ agent_checkpoint_title: 'Agent Checkpoint',
836
+ agent_checkpoint_desc: 'Allows the model to consolidate findings, request guidance, and record the next step to maintain reasoning focus.',
837
+ input_placeholder: 'Write a message...',
838
+ btn_stop: 'Stop',
839
+ btn_stop_title: 'Stop response generation',
840
+ btn_send_title: 'Send message',
841
+
842
+ // Niveles de razonamiento
843
+ reasoning_level_none: 'Disabled (None)',
844
+ reasoning_desc_none: 'No extended reasoning',
845
+ reasoning_transport_title: 'Configuration delivery',
846
+ reasoning_transport_omit: 'Do not send configuration',
847
+ reasoning_transport_omit_desc: 'Does not include unconfirmed reasoning parameters.',
848
+ reasoning_transport_send_none: 'Send reasoning_effort: none',
849
+ reasoning_transport_send_none_desc: 'Experimental test; the provider may ignore or reject it.',
850
+ reasoning_level_on: 'Enabled (On)',
851
+ reasoning_desc_on: 'Extended reasoning enabled',
852
+ reasoning_level_minimal: 'Minimal',
853
+ reasoning_desc_minimal: 'Ultra-fast and concise reasoning',
854
+ reasoning_level_low: 'Low',
855
+ reasoning_desc_low: 'Lightweight and fast reasoning',
856
+ reasoning_level_medium: 'Medium',
857
+ reasoning_desc_medium: 'Balanced speed and analytical depth',
858
+ reasoning_level_high: 'High',
859
+ reasoning_desc_high: 'Maximum reasoning and deep deduction',
860
+ reasoning_level_xhigh: 'Extra High (X-High)',
861
+ reasoning_desc_xhigh: 'Exhaustive reasoning effort',
862
+
863
+ // Panel lateral de Logs y Debug
864
+ debug_panel_title: 'Logs & Debug',
865
+ debug_status_idle: 'Idle',
866
+ debug_status_streaming: 'Generating...',
867
+ debug_status_thinking: 'Thinking...',
868
+ debug_status_done: 'Completed',
869
+ debug_status_loop_detected: 'Infinite loop detected',
870
+ agent_loop_warning_notice: 'Infinite Loop Protection: tools were repeatedly invoked without progress. The agent cycle stopped cleanly.',
871
+ debug_status_error: 'Error',
872
+ btn_copy_debug_title: 'Copy logs to clipboard',
873
+ btn_clear_debug_title: 'Clear logs',
874
+ btn_autoscroll_title: 'Auto-scroll enabled',
875
+ btn_close_debug_title: 'Close logs panel',
876
+ debug_messages_toggle: 'Debug messages',
877
+ debug_messages_toggle_title: 'Enable/Disable interactive debugging of outgoing messages',
878
+ debug_modal_title: 'Debug',
879
+ debug_modal_desc: 'Review or edit the JSON payload before sending it to the server. You can modify any message, parameters, or tools.',
880
+ btn_format_json: 'Format',
881
+ btn_copy_all: 'Copy all',
882
+ btn_send: 'Send',
883
+ btn_send_and_stop_debug: 'Send & stop debug',
884
+ btn_maximize_title: 'Maximize / Restore',
885
+ debug_json_error_invalid: 'JSON syntax error: {error}',
886
+ debug_tab_all: 'All',
887
+ debug_tabs_label: 'Log filters',
888
+ debug_tab_thinking: 'Thinking',
889
+ debug_tab_tool: 'Tools',
890
+ debug_tab_network: 'Network',
891
+ debug_tab_raw: 'Raw',
892
+ debug_sys_init: 'Logs and reasoning inspector started.',
893
+ debug_sys_cleared: 'Logs cleared. Waiting for requests...',
894
+ debug_tag_system: 'SYSTEM',
895
+ debug_tag_thinking: 'THINKING',
896
+ debug_tag_tool: 'TOOL',
897
+ debug_tag_network: 'NETWORK',
898
+ debug_tag_stats: 'STATS',
899
+ debug_tag_error: 'ERROR',
900
+ debug_tag_warning: 'WARNING',
901
+ debug_tag_info: 'INFO',
902
+
903
+ // Mensajes del chat y acciones
904
+ btn_reuse: 'Reuse',
905
+ btn_reuse_title: 'Put message into the input box',
906
+ btn_delete: 'Delete',
907
+ btn_delete_usr_title: 'Delete this question',
908
+ btn_delete_ast_title: 'Delete this response',
909
+ btn_copy: 'Copy',
910
+ btn_copy_title: 'Copy full response to clipboard',
911
+ btn_copy_user_title: 'Copy message to clipboard',
912
+ btn_branch_title: 'Create a branch from this response',
913
+ chat_branch_title: 'Branch: {title}',
914
+ chat_branch_error: 'Could not create the conversation branch.',
915
+ copied_text: 'Copied!',
916
+ empty_response: '(Empty response)',
917
+ msg_deleted_log: 'Message [{id}] removed from memory and UI ({count} turns cleared).',
918
+
919
+ // Estadísticas
920
+ stat_ttft: '1st token: {sec}s',
921
+ stat_ttft_title: 'Time to first token (Latency / TTFT)',
922
+ stat_speed: '{speed} t/s',
923
+ stat_speed_title: 'Generation speed (calculated from 1st token)',
924
+ stat_total_time: '{sec}s',
925
+ stat_total_time_title: 'Total response time',
926
+ stat_tokens: '{tokens} tok',
927
+ stat_tokens_title: 'Response tokens generated in this turn',
928
+ stat_cache_tokens: '{tokens} cache',
929
+ stat_cache_title: 'Tokens read from server context cache (Prompt / KV Caching)',
930
+
931
+ // Respuestas agénticas y herramientas
932
+ tool_js_title: 'Tool Executed: execute_javascript ({ms}ms)',
933
+ tool_js_title_running: 'Execute JavaScript',
934
+ tool_badge_executing: 'Executing...',
935
+ tool_badge_fetching: 'Fetching...',
936
+ tool_badge_downloading: 'Downloading...',
937
+ tool_badge_searching: 'Searching...',
938
+ tool_loading_js: 'Executing JavaScript code...',
939
+ tool_loading_web: 'Connecting and fetching web page...',
940
+ tool_loading_pdf: 'Downloading and parsing PDF document...',
941
+ tool_loading_search: 'Searching web engines in real time...',
942
+ tool_web_receiving: 'Receiving content...',
943
+ tool_search_searching: 'Searching sources...',
944
+ tool_btn_collapse: 'Minimize tool',
945
+ tool_btn_expand: 'Expand tool',
946
+ tool_sandbox_output: 'Output:',
947
+ tool_web_title: 'Web Browser: fetch_web_page',
948
+ tool_pdf_title: 'PDF Document: download_pdf',
949
+ tool_web_requested_url: 'URL Requested by Model:',
950
+ tool_web_content_received: 'Retrieved Content ({size}):',
951
+ tool_search_title: 'DuckDuckGo Search: search_web',
952
+ tool_search_query: 'Search Requested by Model:',
953
+ tool_search_empty: 'No search results found on DuckDuckGo for this query.',
954
+ tool_search_sources_label: 'Sources and results found:',
955
+ tool_rag_list_title: 'Knowledge Base (Document Index)',
956
+ tool_rag_list_loading: 'Querying indexed documents...',
957
+ tool_rag_list_retrieving: 'Retrieving documents from IndexedDB...',
958
+ tool_rag_list_indexed: '{count} doc{plural} indexed',
959
+ tool_rag_search_title: 'Local knowledge: "{query}"',
960
+ tool_rag_search_loading: 'Searching with Orama...',
961
+ tool_rag_search_building: 'Building local index...',
962
+ tool_rag_search_matches: '{count} match{plural} · {scope}',
963
+ tool_rag_read_title: 'Knowledge chunk',
964
+ tool_rag_image_title: 'RAG Image',
965
+ tool_rag_read_loading: 'Reading {chunkId}...',
966
+ tool_rag_read_retrieving: 'Retrieving text from IndexedDB...',
967
+ tool_rag_read_retrieved: 'Chunk retrieved ({chars} characters)',
968
+ tool_rag_read_not_found: 'Not found',
969
+ tool_err_query: 'Query error',
970
+ tool_status_success: 'Completed',
971
+ tool_status_error: 'Error ({ms}ms)',
972
+ tool_agent_checkpoint_title: 'Agent Checkpoint',
973
+ tool_agent_checkpoint_loading: 'Consolidating findings...',
974
+ tool_agent_checkpoint_ready: 'Ready to respond',
975
+ tool_agent_checkpoint_continue: 'Continuing analysis',
976
+ tool_agent_checkpoint_findings: 'Key findings:',
977
+ tool_agent_checkpoint_missing: 'Missing info:',
978
+ tool_agent_checkpoint_next: 'Next hypothesis / step:',
979
+
980
+ // Modal de Configuración
981
+ modal_title: 'Chat Settings',
982
+ tab_agent: 'Agent',
983
+ tab_model: 'Model',
984
+ tab_appearance: 'Appearance',
985
+ tab_inspector: 'Inspector',
986
+ tab_mcp: 'MCP',
987
+ tab_permissions: 'Permissions',
988
+ mcp_connection_title: 'Local Server',
989
+ mcp_connection_desc: 'Private local server to connect ZeroChat with system tools (files, terminal, git, and automation) via standard protocol.',
990
+ mcp_status_disconnected: 'Disconnected',
991
+ mcp_status_connecting: 'Connecting...',
992
+ mcp_status_checking: 'Checking connection...',
993
+ mcp_status_connected: 'Connected',
994
+ mcp_status_error: 'Connection error',
995
+ mcp_bootstrap_title: 'MCP requires the local server',
996
+ mcp_bootstrap_desc: 'To use MCP, start ZeroChat from zerochat.py in a terminal. The application will connect automatically when the server is available.',
997
+ mcp_reconnect_after_restart: 'If the server was restarted, reload this page (F5) to connect again.',
998
+ mcp_bootstrap_help: 'Open MCP help',
999
+ mcp_btn_copy_cmd: 'Copy command',
1000
+ mcp_cmd_copied: 'Copied!',
1001
+ mcp_tools_discovered: '{count} tools active',
1002
+ mcp_no_tools: 'No tools registered',
1003
+ mcp_tools_section_title: 'Available System Tools',
1004
+ mcp_tools_count: '{count} detected',
1005
+ mcp_tools_empty_disconnected: 'MCP requires ZeroChat to be started from zerochat.py to discover and enable local system tools.',
1006
+ mcp_tools_empty_connected: 'The local server is connected but does not expose any tools.',
1007
+ mcp_servers_section_title: 'Available MCP Servers',
1008
+ mcp_servers_section_desc: 'External MCP services configured on the local server ready to start individually.',
1009
+ mcp_servers_empty: 'No external MCP servers available on the local server.',
1010
+ mcp_servers_count_tools: '{count} active tools',
1011
+ mcp_external_status_available: 'Available',
1012
+ mcp_external_status_installing: 'Installing',
1013
+ mcp_external_status_starting: 'Starting',
1014
+ mcp_external_status_running: 'Running',
1015
+ mcp_external_status_stopped: 'Stopped',
1016
+ mcp_external_status_needs_attention: 'Needs attention',
1017
+ mcp_external_status_error: 'Error',
1018
+ mcp_btn_start_server: 'Start',
1019
+ mcp_btn_stop_server: 'Stop',
1020
+ mcp_tool_badge: 'MCP',
1021
+ tool_auth_title: 'Execution Authorization',
1022
+ tool_auth_desc: 'This MCP tool requires your confirmation before interacting with the system:',
1023
+ tool_auth_badge: 'Requires Authorization',
1024
+ tool_auth_allow_once: 'Allow once',
1025
+ tool_auth_allow_always: 'Always allow this tool',
1026
+ tool_auth_deny: 'Deny',
1027
+ tool_auth_denied_badge: 'Denied',
1028
+ tool_auth_denied_msg: 'Execution denied by the user.',
1029
+ tool_security_policy_blocked: 'Tool blocked by security policy.',
1030
+ mcp_security_section_title: 'Execution Security & Authorization',
1031
+ mcp_security_desc: 'Control when MCP server tools can execute actions on your local system.',
1032
+ mcp_security_policy_ask: 'Ask for authorization before executing (Recommended)',
1033
+ mcp_security_policy_ask_hint: 'The chat will ask you to confirm each command or MCP tool not previously allowed.',
1034
+ mcp_security_policy_allow_all: 'Allow all (Unrestricted mode)',
1035
+ mcp_security_policy_allow_all_hint: 'Immediately executes any MCP tool without confirmation prompts.',
1036
+ mcp_security_saved_auths_title: 'Tools with Remembered Permissions',
1037
+ mcp_security_no_saved_auths: 'No permanent authorizations registered.',
1038
+ mcp_security_btn_revoke: 'Revoke',
1039
+ mcp_security_btn_clear_all: 'Clear all',
1040
+ mcp_security_badge_allowed: 'Allowed',
1041
+ mcp_security_badge_ask: 'Ask',
1042
+ mcp_security_select_title: 'Change execution policy for this tool',
1043
+ mcp_security_constrained: 'Restricted',
1044
+ tool_auth_allow_cmd_btn: 'Always allow "{cmd}"',
1045
+ tool_auth_allow_cmd_title: 'Permanently allow only commands starting with "{cmd}"',
1046
+ tool_auth_allow_path_btn: 'Always allow in current path',
1047
+ tool_auth_allow_path_title: 'Permanently allow only operations inside the current working folder',
1048
+ inspector_desc: 'Analyzes the configured endpoint to determine which capabilities are supported, distinguishing between declared, inferred, and confirmed capabilities via safe active probes.',
1049
+ btn_run_inspector: 'Run Capability Diagnostics',
1050
+ btn_running_inspector: 'Diagnosing endpoint...',
1051
+ inspector_status_confirmed: 'Confirmed',
1052
+ inspector_status_inferred: 'Inferred',
1053
+ inspector_status_declared: 'Declared',
1054
+ inspector_status_unsupported: 'Unsupported',
1055
+ inspector_status_unknown: 'Unknown',
1056
+ inspector_cap_streaming: 'Streaming (SSE)',
1057
+ inspector_cap_tools: 'Tools (Tool Calling)',
1058
+ inspector_cap_vision: 'Multimodal Vision',
1059
+ inspector_cap_reasoning: 'Reasoning Control',
1060
+ inspector_cap_jsonMode: 'Structured Output (JSON)',
1061
+ inspector_cap_promptCaching: 'Context Caching',
1062
+ inspector_cap_embeddings: 'Embeddings',
1063
+ inspector_cap_modelListing: 'Model Discovery',
1064
+ inspector_meta_provider: 'Provider',
1065
+ inspector_meta_endpoint: 'Chat Endpoint',
1066
+ inspector_meta_models: 'Models',
1067
+ inspector_meta_latency: 'Diagnostic Latency',
1068
+ inspector_discovered_models: '{count} model(s) discovered',
1069
+ inspector_no_models: 'No models listed',
1070
+ inspector_unknown: 'Unknown',
1071
+ inspector_model_selected: 'Model: {model}',
1072
+ inspector_conn_failed: 'Connection failed: Unable to connect to server.',
1073
+ inspector_module_unavailable: 'Inspection module unavailable.',
1074
+ field_language: 'Interface Language (Idioma)',
1075
+ field_language_hint: 'Select the visual language of the application.',
1076
+ field_language_short: 'Language',
1077
+ field_theme_short: 'Theme',
1078
+ field_profile: 'Connection Profile / Server',
1079
+ tab_connection: 'Connection',
1080
+ sidebar_settings_title: 'Settings',
1081
+ sidebar_help: 'Help',
1082
+ sidebar_help_href: 'help/en/index.html',
1083
+ btn_back_to_chats: 'Back to chat history',
1084
+ btn_save_short: 'Save',
1085
+ btn_diagnose_short: 'Diagnose',
1086
+ connection_active_profile: 'Active profile',
1087
+ connection_active_hint: 'Profiles are selected and edited from the prompt box.',
1088
+ btn_manage_profiles: 'Manage connection profiles',
1089
+ profiles_modal_title: 'Profile',
1090
+ btn_close: 'Close',
1091
+ field_profile_name_label: 'Profile Name',
1092
+ field_profile_description_label: 'Description',
1093
+ field_profile_description_placeholder: 'Briefly describe this profile...',
1094
+ profile_tab_name: 'General',
1095
+ profile_tab_settings: 'Settings',
1096
+ profile_tab_model: 'Model',
1097
+ field_profile_placeholder: 'Profile name (e.g. LM Studio, Ollama, OpenRouter...)',
1098
+ profile_select_default: '▾ Choose saved profile...',
1099
+ btn_new_profile: 'New',
1100
+ btn_new_profile_title: 'Create a new profile',
1101
+ btn_export_profiles: 'Export',
1102
+ btn_export_profiles_title: 'Export all profiles to an encrypted file',
1103
+ profiles_backup_title: 'Profile backup and restore',
1104
+ profiles_backup_description: 'These actions affect all editable profiles, not only the selected profile.',
1105
+ confirm_import_profiles: '{count} profiles will be loaded, replacing those with the same identifier. Do you want to continue?',
1106
+ msg_profiles_exported: 'Encrypted profile backup created.',
1107
+ msg_profiles_exported_html: 'Profiles exported. Open the downloaded HTML file to import them automatically.',
1108
+ msg_profiles_imported: 'Profiles loaded: {added} new and {replaced} updated.',
1109
+ msg_profiles_auto_imported: 'Import completed: {added} new, {replaced} updated.',
1110
+ err_profiles_backup: 'Could not process the profile backup: {err}',
1111
+ err_no_profiles_to_export: 'No profiles to export (except Mirror profile).',
1112
+ err_auto_import_failed: 'Failed to auto-import profiles: {err}',
1113
+ confirm_auto_import_profiles: 'Import {count} connection profile(s) from external file?',
1114
+ btn_save_profile: 'Save Profile',
1115
+ btn_save_profile_title: 'Save all current values into this profile',
1116
+ btn_delete_profile: 'Delete',
1117
+ btn_delete_profile_title: 'Delete selected profile',
1118
+ prompt_new_profile_name: 'New profile name:',
1119
+ msg_profile_saved: 'Profile "{name}" saved successfully.',
1120
+ msg_profile_created: 'Profile "{name}" created.',
1121
+ msg_profile_deleted: 'Profile "{name}" deleted successfully.',
1122
+ profile_save_changes_required: 'Make a profile change to enable saving.',
1123
+ profile_save_pending: 'There are pending changes. Save the profile to keep them.',
1124
+ confirm_profile_query_not_saved: 'The query completed, but the profile has not been saved. Do you want to discard changes and close?',
1125
+ confirm_profile_unsaved_changes: 'There are unsaved changes in the profile. Do you want to discard them and close?',
1126
+ confirm_settings_unsaved_changes: 'There are unsaved configuration changes. Do you want to discard them and close?',
1127
+ confirm_rag_branch_unsaved_changes: 'There are unsaved branch changes. Do you want to discard them and close?',
1128
+ confirm_delete_profile: 'Are you sure you want to delete profile "{name}"?',
1129
+ err_profile_name_exists: 'A profile named "{name}" already exists.',
1130
+ err_profile_read_only: 'The Mirror profile cannot be changed or deleted.',
1131
+ btn_edit_profile_title: 'Edit this profile',
1132
+ btn_delete_profile_item_title: 'Delete this profile',
1133
+ btn_close_profiles_menu: 'Close selector',
1134
+ field_api_type: 'Interface Type / Protocol',
1135
+ profile_api_key_lock: 'Lock changes',
1136
+ profile_api_key_locked: 'Changes locked',
1137
+ field_api_url: 'Server URL / Chat Endpoint',
1138
+ webllm_local_hint: 'Local execution in this browser.',
1139
+ webllm_help_link: 'WebLLM Setup Guide',
1140
+ webllm_query_optional: 'Downloaded model ready. Querying the server is optional.',
1141
+ generation_status_connecting: 'Connecting…',
1142
+ generation_status_preparing: 'Preparing model…',
1143
+ generation_status_loading: 'Loading model…',
1144
+ generation_status_compiling: 'Compiling GPU…',
1145
+ generation_status_thinking: 'Thinking',
1146
+ generation_status_generating: 'Generating response…',
1147
+ generation_status_rag: 'Querying RAG…',
1148
+ generation_status_tool: 'Executing {name}…',
1149
+ generation_status_loop_detected: 'Orderly stop: infinite loop detected',
1150
+ generation_status_percent: '{text} · {percent} %',
1151
+ generation_status_elapsed: '{text} · {seconds} s',
1152
+ webllm_download: 'Download',
1153
+ webllm_delete: 'Delete model',
1154
+ webllm_cancel: 'Cancel preparation',
1155
+ webllm_cancelling: 'Cancelling…',
1156
+ webllm_deleting: 'Deleting…',
1157
+ webllm_delete_failed: 'The model could not be deleted.',
1158
+ webllm_model_incomplete: 'The download is incomplete. Try again.',
1159
+ webllm_model_unknown: 'Local status not verified',
1160
+ confirm_webllm_delete: 'Delete downloaded model "{model}" from this browser?',
1161
+ webllm_preparing: 'Downloading and preparing…',
1162
+ webllm_starting: 'Starting the local engine…',
1163
+ webllm_loading_parameters: 'Loading model parameters…',
1164
+ webllm_loading_model: 'Loading model from storage {current}/{total}{percent}{elapsed}',
1165
+ webllm_ready: 'Model ready',
1166
+ webllm_model_cached: 'Downloaded',
1167
+ webllm_model_missing: 'Not downloaded',
1168
+ webllm_vram_required: 'Approx. VRAM {size}',
1169
+ webllm_gpu_shaders: 'Compiling GPU modules {current}/{total}{percent}{elapsed}',
1170
+ webllm_elapsed_seconds: '{seconds} s',
1171
+ btn_query_title: 'Query available models and API capabilities from the server',
1172
+ btn_query_text: 'Query',
1173
+ btn_querying_text: 'Querying...',
1174
+ field_api_key: 'API Key',
1175
+ field_api_key_hint: 'Optional when using a local server (LM Studio / Ollama / LocalAI).',
1176
+ field_api_key_required_hint: 'Required for this provider.',
1177
+ field_api_key_free_help: 'How to get a free API key',
1178
+ btn_toggle_key_title: 'Show/Hide API Key',
1179
+ field_model: 'Model Name',
1180
+ field_model_hint: 'Select from the server model list or type any custom name.',
1181
+ field_model_placeholder: 'Type or click Query to discover models...',
1182
+ model_select_default: '▾ Choose detected model...',
1183
+ model_select_count: '▾ Choose detected model ({count})...',
1184
+ btn_webllm_params_title: 'Advanced WebLLM performance parameters',
1185
+ webllm_params_title: 'WebGPU execution parameters',
1186
+ webllm_opt_default: 'Model default',
1187
+ field_webllm_context_window: 'Context window (context_window_size)',
1188
+ field_webllm_prefill_chunk: 'Prefill chunk size (prefill_chunk_size)',
1189
+ field_theme: 'Visual Interface Theme',
1190
+ field_theme_hint: 'Select the display appearance mode.',
1191
+ theme_light: 'Light Mode',
1192
+ theme_dark: 'Dark Mode',
1193
+ agent_intro: 'Configure agentic tools and temporal context passed to the model.',
1194
+ agent_search_title: 'Real-time DuckDuckGo Search',
1195
+ agent_search_desc: 'Allows the model to call search_web to search for up-to-date information, definitions, news, and links using the DuckDuckGo API.',
1196
+ agent_js_title: 'JavaScript Execution (Local calculations)',
1197
+ agent_js_desc: 'Allows the model to execute JavaScript in a local worker to facilitate calculations, data processing, and algorithms under the supervision and awareness of a technical user.',
1198
+ agent_web_title: 'Real-time Web Browsing',
1199
+ agent_web_desc: 'Allows the model to call fetch_web_page to retrieve public web pages and extract their text content in real-time.',
1200
+ agent_pdf_title: 'PDF Document Download & Reading',
1201
+ agent_pdf_desc: 'Allows the model to download PDF documents from the web and extract all readable text into context in real-time.',
1202
+ agent_chart_title: 'Data Visualization & Native SVG Charts',
1203
+ agent_chart_desc: 'Allows the model to call render_chart to generate and display interactive bar, line, doughnut or pie charts without external libraries.',
1204
+ model_cache_title: 'Automatic context caching',
1205
+ model_cache_desc: 'The client automatically applies cache markers supported by the provider. On local servers, the KV cache is managed by the server.',
1206
+ field_max_agent_turns: 'Agentic Turns Limit',
1207
+ field_max_agent_turns_hint: 'Maximum number of tool steps before forcing final synthesis (between 5 and 35).',
1208
+ field_system_prompt: 'System Prompt (Optional)',
1209
+ field_system_prompt_hint: 'Custom base instructions guiding the assistant behavior (optional).',
1210
+ field_system_prompt_placeholder: 'Enter custom system instructions for the model (optional)...',
1211
+ field_system_data_prompt: 'System profile · ZeroChat data',
1212
+ field_system_data_prompt_hint: 'Internal ZeroChat instructions. It is best not to change them unless you know exactly what you are doing.',
1213
+ field_system_data_prompt_placeholder: 'Internal ZeroChat instructions...',
1214
+ field_temperature: 'Temperature: {val}',
1215
+ field_temperature_hint: 'Controls randomness/creativity (0 = deterministic/precise, 1 = creative).',
1216
+ cookie_notice: 'All settings are stored locally and persistently (compatible with both <strong>file://</strong> and web servers).',
1217
+ btn_clear_all_data: 'Clear all data',
1218
+ btn_clear_all_data_title: 'Wipe all cookies, chat sessions and local storage data',
1219
+ confirm_clear_all_data: 'Delete all data for this origin: settings, chats, attachments, RAG, downloaded models, cookies, IndexedDB, caches and browser-local files? This also affects other applications sharing this origin. Close other ZeroChat tabs before continuing.\n\nThis cannot be undone. The application will reload. HTTP and file:// have separate storage.',
1220
+ clear_all_data_failed: 'Deletion could not be completed. Close other tabs and stop active operations before retrying. You can remove site data from your browser settings.',
1221
+ clear_all_data_failed_detail: 'Deletion could not be completed. Detail: {detail}',
1222
+ btn_cancel: 'Cancel',
1223
+ btn_save: 'Save Settings',
1224
+ modal_close_aria: 'Close modal',
1225
+
1226
+ // Mensajes de estado y errores
1227
+ err_no_model_title: 'No model selected:',
1228
+ err_no_model_desc: 'Please open <strong>Settings</strong> to enter a model or click <strong>Query</strong> to discover available models on your server ({url}).',
1229
+ err_server_connect_title: 'Error connecting to server:',
1230
+ err_server_connect: 'Error connecting to server:',
1231
+ err_server_connect_hint: 'Open <strong>Settings</strong> to verify server URL ({url}), model name, and API Key.',
1232
+ err_invalid_url: 'Please enter a valid server URL.',
1233
+ err_connecting_models: 'Connecting to {url} to fetch models...',
1234
+ msg_models_success: '<strong>{count} models detected successfully</strong> at <code>{endpoint}</code>.',
1235
+ msg_models_success_text: '{count} models detected at {endpoint}.',
1236
+ err_api_connect: '<strong>Error connecting to API:</strong> {err}',
1237
+ err_ollama_origins: 'Ollama blocked browser access. Add <code>OLLAMA_ORIGINS=*</code> to its configuration and restart Ollama.',
1238
+ err_file_process: 'Could not process file {name}: {err}',
1239
+ err_file_too_large: 'File "{name}" exceeds the maximum allowed size ({max}).',
1240
+
1241
+ // Markdown & JavaScript
1242
+ md_thought_title: 'Reasoning process',
1243
+ md_thought_reasoning: 'Reasoning...',
1244
+ md_run_js_title: 'Run JavaScript (in local worker)',
1245
+ md_run_js_btn: 'Run JS',
1246
+ md_copy_code_title: 'Copy code',
1247
+ md_copy_code_btn: 'Copy',
1248
+ md_output_title: 'Output (Console / Return):',
1249
+ md_clear_output: 'Clear output',
1250
+
1251
+ // Sidebar & Conversation History
1252
+ sidebar_title: 'Chats and Settings',
1253
+ btn_sidebar_title: 'Chats and Settings',
1254
+ btn_new_chat_sidebar_title: 'Create new conversation',
1255
+ btn_open_new_tab_title: 'Open ZeroChat in a new tab',
1256
+ btn_close_sidebar_title: 'Close sidebar',
1257
+ sidebar_search_placeholder: 'Search history...',
1258
+ sidebar_no_chats: 'No saved conversations',
1259
+ sidebar_group_today: 'Today',
1260
+ sidebar_group_yesterday: 'Yesterday',
1261
+ sidebar_group_last7days: 'Previous 7 days',
1262
+ sidebar_group_last30days: 'Previous 30 days',
1263
+ sidebar_group_older: 'Older',
1264
+ btn_import_chat: 'Import',
1265
+ btn_import_chat_title: 'Import conversation from JSON file',
1266
+ btn_export_chat_title: 'Export conversation (Markdown, JSON, PDF)',
1267
+ btn_delete_all_chats: 'Delete all',
1268
+ btn_delete_all_chats_title: 'Delete all saved conversations',
1269
+ chat_untitled: 'New conversation',
1270
+ sidebar_rename_chat_title: 'Rename chat',
1271
+ sidebar_export_chat_title: 'Export chat',
1272
+ sidebar_delete_chat_title: 'Delete chat',
1273
+ chat_delete_confirm: 'Are you sure you want to delete this conversation?',
1274
+ chat_delete_all_confirm: 'Are you sure you want to delete all saved conversations? This action cannot be undone.',
1275
+ chat_delete_history_err: 'Could not delete persistent history. Check the console for details.',
1276
+ prompt_rename_conversation: 'Conversation name:',
1277
+ no_text_response: '(No text response)',
1278
+ chat_imported_success: 'Conversation imported successfully.',
1279
+ chat_import_json_err: 'Error reading JSON file: {err}',
1280
+ chat_new_blocked_generating: 'You cannot create a new conversation while a response is being generated. Stop generation and try again.',
1281
+ chat_switch_blocked_generating: 'You cannot switch conversations while a response is being generated. Stop generation and try again.',
1282
+ chat_delete_blocked_generating: 'You cannot delete a conversation while a response is being generated. Stop generation and try again.',
1283
+ chat_import_blocked_generating: 'You cannot import a conversation while a response is being generated. Stop generation and try again.',
1284
+
1285
+ // Export Modal
1286
+ export_modal_title: 'Export Conversation',
1287
+ btn_close_export_title: 'Close export modal',
1288
+ export_md_title: 'Download Markdown (.md)',
1289
+ export_md_desc: 'Clean format with markdown, code and tables readable in any viewer.',
1290
+ export_json_title: 'Download Session JSON (.json)',
1291
+ export_json_desc: 'Complete structured history with tools, images and metadata to restore.',
1292
+ export_pdf_title: 'Print / Save as PDF',
1293
+ export_pdf_desc: 'Generates a clean PDF document formatted for reading and reports.',
1294
+ export_date: 'Export date',
1295
+ not_specified: 'Not specified',
1296
+ role_user: '👤 User',
1297
+ role_assistant: '🤖 Assistant',
1298
+
1299
+ // Interactive Charts
1300
+
1301
+ // Real-world temporal system context
1302
+ }
1303
+ };
1304
+
1305
+ let currentLang = 'es';
1306
+
1307
+ /**
1308
+ * Detecta el idioma inicial según la política:
1309
+ * 1. Si hay preferencia guardada en storage ('es' o 'en'), usarla.
1310
+ * 2. Si no, comprobar el idioma del navegador. Si empieza por 'en', usar 'en'.
1311
+ * 3. En caso contrario, usar 'es' por defecto.
1312
+ */
1313
+ function detectInitialLanguage() {
1314
+ try {
1315
+ if (Storage.getStorageItem) {
1316
+ const saved = Storage.getStorageItem('language');
1317
+ if (saved === 'es' || saved === 'en') {
1318
+ return saved;
1319
+ }
1320
+ }
1321
+ } catch (e) {}
1322
+
1323
+ // Node.js expone un navigator global, pero no representa el idioma de una
1324
+ // interfaz web. Solo detectamos el idioma del navegador en un contexto DOM.
1325
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
1326
+ return 'es';
1327
+ }
1328
+
1329
+ try {
1330
+ const browserLang = (
1331
+ (navigator.languages && navigator.languages.length ? navigator.languages[0] : null) ||
1332
+ navigator.language ||
1333
+ navigator.userLanguage ||
1334
+ ''
1335
+ ).toLowerCase();
1336
+
1337
+ if (browserLang.startsWith('en')) {
1338
+ return 'en';
1339
+ }
1340
+ } catch (e) {}
1341
+
1342
+ return 'es';
1343
+ }
1344
+
1345
+ const changeListeners = [];
1346
+
1347
+ function onChange(callback) {
1348
+ if (typeof callback === 'function') {
1349
+ changeListeners.push(callback);
1350
+ }
1351
+ return () => {
1352
+ const idx = changeListeners.indexOf(callback);
1353
+ if (idx !== -1) changeListeners.splice(idx, 1);
1354
+ };
1355
+ }
1356
+
1357
+ function getLanguage() {
1358
+ return currentLang;
1359
+ }
1360
+
1361
+ function setLanguage(lang, persist = true) {
1362
+ const target = (lang === 'en') ? 'en' : 'es';
1363
+ currentLang = target;
1364
+
1365
+ if (persist && typeof Storage !== 'undefined' && Storage?.setStorageItem) {
1366
+ Storage.setStorageItem('language', target);
1367
+ }
1368
+
1369
+ if (typeof document !== 'undefined') {
1370
+ document.documentElement.lang = target;
1371
+ applyTranslations(document);
1372
+ }
1373
+
1374
+ if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function') {
1375
+ try {
1376
+ window.dispatchEvent(new CustomEvent('zerochat:languagechange', { detail: { lang: target } }));
1377
+ } catch (e) {}
1378
+ }
1379
+
1380
+ changeListeners.forEach(fn => {
1381
+ try {
1382
+ fn(target);
1383
+ } catch (err) {
1384
+ console.error('Error in i18n onChange listener:', err);
1385
+ }
1386
+ });
1387
+
1388
+ return target;
1389
+ }
1390
+
1391
+ /**
1392
+ * Obtiene la traducción para una clave, interpolando parámetros opcionales {nombre}.
1393
+ */
1394
+ function t(key, params) {
1395
+ const dict = TRANSLATIONS[currentLang] || TRANSLATIONS.es;
1396
+ let str = dict[key];
1397
+ if (str === undefined) {
1398
+ str = TRANSLATIONS.es[key] !== undefined ? TRANSLATIONS.es[key] : key;
1399
+ }
1400
+
1401
+ if (params && typeof params === 'object') {
1402
+ Object.keys(params).forEach(k => {
1403
+ const val = params[k];
1404
+ str = str.replace(new RegExp(`\\{${k}\\}`, 'g'), val !== undefined && val !== null ? val : '');
1405
+ });
1406
+ }
1407
+
1408
+ return str;
1409
+ }
1410
+
1411
+ /**
1412
+ * Obtiene texto visible de interfaz con fallback local.
1413
+ * Los textos dirigidos al modelo no deben pasar por esta API.
1414
+ */
1415
+ function uiText(key, fallback, params) {
1416
+ const value = t(key, params);
1417
+ return value === key && fallback !== undefined ? fallback : value;
1418
+ }
1419
+
1420
+ const I18N_DOM_BINDINGS = [
1421
+ { attr: 'data-i18n', prop: 'textContent' },
1422
+ { attr: 'data-i18n-html', prop: 'innerHTML' },
1423
+ { attr: 'data-i18n-title', targetAttr: 'title' },
1424
+ { attr: 'data-i18n-placeholder', targetAttr: 'placeholder' },
1425
+ { attr: 'data-i18n-aria', targetAttr: 'aria-label' },
1426
+ { attr: 'data-i18n-href', targetAttr: 'href' }
1427
+ ];
1428
+
1429
+ /**
1430
+ * Aplica las traducciones a todos los elementos del DOM marcados con atributos data-i18n*.
1431
+ */
1432
+ function applyTranslations(rootElement = document) {
1433
+ if (!rootElement || typeof rootElement.querySelectorAll !== 'function') return;
1434
+
1435
+ for (const binding of I18N_DOM_BINDINGS) {
1436
+ rootElement.querySelectorAll(`[${binding.attr}]`).forEach(el => {
1437
+ const key = el.getAttribute(binding.attr);
1438
+ if (!key) return;
1439
+ const val = t(key);
1440
+ if (binding.prop) {
1441
+ if (val !== key || !el[binding.prop].trim()) {
1442
+ el[binding.prop] = val;
1443
+ }
1444
+ } else if (binding.targetAttr) {
1445
+ if (val !== key || !el.getAttribute(binding.targetAttr)) {
1446
+ el.setAttribute(binding.targetAttr, val);
1447
+ }
1448
+ }
1449
+ });
1450
+ }
1451
+
1452
+ // Actualizar título de la página
1453
+ if (typeof document !== 'undefined') {
1454
+ document.title = t('app_title');
1455
+ const metaDesc = document.querySelector('meta[name="description"]');
1456
+ if (metaDesc) {
1457
+ metaDesc.setAttribute('content', t('app_description'));
1458
+ }
1459
+ }
1460
+ }
1461
+
1462
+ function getAvailableLanguages() {
1463
+ return [
1464
+ { code: 'es', label: 'Español', flag: '🇪🇸' },
1465
+ { code: 'en', label: 'English', flag: '🇬🇧' }
1466
+ ];
1467
+ }
1468
+
1469
+ // Inicialización automática de idioma
1470
+ currentLang = detectInitialLanguage();
1471
+
1472
+ return {
1473
+ t,
1474
+ uiText,
1475
+ getLanguage,
1476
+ setLanguage,
1477
+ onChange,
1478
+ detectInitialLanguage,
1479
+ applyTranslations,
1480
+ getAvailableLanguages,
1481
+ TRANSLATIONS
1482
+ };
1483
+ });