=== cache.lat ===
Contributors: tunegocioenlinea
Tags: cache, performance, static html, wordpress speed
Requires at least: 5.8
Tested up to: 6.6
Requires PHP: 7.4
Stable tag: 1.22.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Genera una copia estática de tu WordPress y la sirve directo desde tu propio hosting, sin ejecutar PHP en cada visita.

== Description ==

cache.lat convierte las páginas públicas de tu sitio en archivos HTML
estáticos y configura tu servidor (Apache) para servirlos directamente,
sin que WordPress tenga que ejecutarse en cada visita.

Este plugin se comunica con un servicio externo — el motor central de
cache.lat, en cache.lat/core/api.php — para generar el HTML de las páginas
que elijas. Ninguna otra información de tu sitio se envía a ningún
servidor externo. Powered by TuNegocioEnLinea.net.

Plan gratuito: hasta 10 páginas por sitio. Con una licencia (comprada en
tunegocioenlinea.net/producto/cache-lat/), el sitio completo, sin límite.

== Installation ==

1. Sube la carpeta `cache-lat-client` a `/wp-content/plugins/`.
2. Actívalo desde el listado de plugins.
3. Entra al menú "cache.lat" en el panel de administración y elige un plan.

== Upgrade Notice ==

= 1.19.0 =
Nuevo modelo de licencias: WordPress (sin WooCommerce) y Avanzada (con WooCommerce). Las licencias ya emitidas se mantienen como Avanzada hasta que venzan. Antes de actualizar, asegúrate de poder entrar a tus archivos por FTP o por el administrador de archivos de cPanel. Guía: https://cache.lat/recuperacion-sitio-wordpress.php

= 1.18.2 =
cache.lat is tested on the latest WordPress, but any plugin install or update can cause a site error depending on your hosting environment. Before updating, make sure you can reach your files by FTP or the cPanel File Manager and have a backup. Recovery guide: https://cache.lat/recuperacion-sitio-wordpress.php

== Changelog ==

= 1.23.0 =
* Nuevo: botón «Reintentar fallidas». Si al terminar una generación alguna página falló (por ejemplo, el hosting tardó en responder), se puede reintentar solo esas, sin volver a generar todo. Las páginas que cancelaste a mano no se reintentan.
* Seguridad de las actualizaciones: antes de instalar, el plugin comprueba la huella SHA-256 y el tamaño del paquete publicados por cache.lat y, cuando el plugin trae clave pública, también una firma Ed25519. Si algo no coincide, la actualización se rechaza y se avisa en el panel.

= 1.22.0 =
* Nuevo: gráficas de velocidad en «Prueba de rendimiento». Se ve la evolución por Semana, Mes o Año, en Móvil, Escritorio o Ambos (superpuestos en una gráfica o por separado), para el puntaje, el tiempo de respuesta con y sin caché y el LCP. Con el cursor se ve el detalle de cada punto y debajo van el último valor, promedio, mejor, peor y la tendencia del periodo.
* El servidor de cache.lat solo entrega las últimas 100 pruebas, así que el plugin acumula su propio historial (hasta 1.500 pruebas) para poder ver un año completo; se borra al desinstalar. No requiere subir archivos del servidor.

= 1.21.6 =
* Corrección importante: protección del .htaccess. Si el archivo pierde el bloque "# BEGIN WordPress" (las reglas que hacen funcionar los enlaces permanentes), TODAS las páginas internas del sitio y /wp-json/ responden 404 mientras la portada se sigue viendo desde el caché estático — y cache.lat solo descubre la portada. Ahora el plugin (1) nunca escribe un .htaccess que pierda ese bloque ni parte de una lectura vacía, (2) comprueba en cada instalación que el bloque de WordPress exista y, si falta, pide a WordPress que lo regenere (o agrega el bloque estándar), (3) lo reporta en el diagnóstico, y (4) "Verificar que se esté sirviendo" ahora también prueba una página interna y avisa si da 404.
* El panel avisa cuando el motor no puede leer la API REST del sitio (solo aparece la portada). El motor usa /?rest_route= como alternativa cuando /wp-json/ da 404. Requiere subir core/includes/SaasCacheService.php y core/api.php.

= 1.21.5 =
* Corrección: "Generar / actualizar caché" fallaba con un error 503 en algunos sitios (hosting compartido lento con imágenes sin optimizar, típicamente la primera generación). Causa: la optimización de imágenes (AVIF/WebP) se hacía DENTRO de la misma petición que arranca el trabajo, sin límite de tiempo, y pasaba el límite del servidor. Ahora el panel optimiza las imágenes antes, en tandas cortas con tope de tiempo (cada llamada procesa al menos una imagen y se corta a los ~8 s; en total se dedican como máximo 60 s), y si ese paso falla o tarda, la generación arranca igual; lo que falte lo termina el barrido diario. Arrancar la generación ya no depende de convertir imágenes.

= 1.21.4 =
* Generación del caché en hostings con pocos procesos simultáneos (típico de un compartido): el motor de cache.lat pedía hasta 4 páginas a la vez al sitio, cada una un render completo de WordPress, y eso podía saturar al hosting y devolver un error 503 incluso al panel (admin-ajax.php). Ahora la concurrencia se adapta sola: arranca en 2, sube de a una por lote si todo va bien, y se reduce a la mitad si el sitio responde 503/429/timeout; esas páginas se reintentan hasta 3 veces en vez de darse por perdidas, y el panel espera unos segundos antes del siguiente lote y lo avisa. Requiere subir los archivos del servidor (core/includes/SaasCacheService.php y Database.php).

= 1.21.3 =
* Cuando el sitio devuelve una página HTML en vez de datos durante la generación del caché, el mensaje de error ahora incluye el código HTTP y las primeras palabras de esa página (por ejemplo "Hubo un error crítico en este sitio" o "502 Bad Gateway"), para poder saber de qué se trata. Se quitó la captura de salida con ob_start() que se había agregado en la 1.21.2 al lote de generación, porque no se pudo demostrar que ayudara.

= 1.21.2 =
* Corrección: a veces, al generar el caché, aparecía el error "Unexpected token '<', "<!DOCTYPE "... is not valid JSON". Pasaba cuando el hosting devolvía una página HTML (corte momentáneo, error 502/503, un aviso de PHP o un firewall) en lugar de la respuesta esperada. Ahora el panel muestra un mensaje claro con el código HTTP, reintenta solo con espera creciente (hasta 15 s) en vez de insistir cada fracción de segundo, y el servidor del sitio pide más tiempo de ejecución para cada lote y descarta cualquier salida suelta antes de responder.

= 1.21.1 =
* Corrección: el aviso "cache.lat se actualizó solo y algo puede necesitar revisión" se quedaba para siempre aunque el .htaccess ya estuviera bien y el sitio sirviera el estático — nada volvía a evaluar ese resultado guardado. Ahora se descarta solo cuando el .htaccess está correcto (si venía de una actualización anterior), y "Reparar .htaccess", "Comprobar permisos", "Verificar que se esté sirviendo" y el cierre de cada generación lo reevalúan. Además el aviso trae un botón "Volver a comprobar ahora".

= 1.21.0 =
* El plugin ahora está en español e inglés, como el sitio de cache.lat: el panel, los avisos, los mensajes y el JavaScript. Por defecto sigue el idioma de WordPress de cada usuario (inglés si es en_*, español en el resto) y se puede fijar a mano en "Soporte y licencia" → "Idioma del plugin". Los enlaces a cache.lat (FAQ, documentación, términos, guía de recuperación) abren la versión en el idioma activo.

= 1.20.0 =
* Pasa de WordPress a Avanzada sin volver a pagar: si tu licencia es WordPress, el panel te muestra la cuenta exacta antes de confirmar. Tus días restantes se canjean al valor diario de cada licencia (precio ÷ 365; es decir, días restantes × precio WordPress ÷ precio Avanzada) y se suman 30 días de bono. Es de una sola vía y una sola vez por licencia.
* Los dominios que TNL registra directamente (sin clave) entran en premium al confirmar el dominio en el plugin.

= 1.19.0 =
* Nuevo modelo de licencias: "WordPress" (sin WooCommerce, para blogs y sitios de contenido) y "Avanzada" (con WooCommerce). El tipo lo decide la licencia, no el plugin: es el mismo para todos. Las licencias ya emitidas quedan como Avanzada hasta su vencimiento, así nadie pierde funciones.
* Sin licencia Avanzada (plan gratis o licencia WordPress) no se cachean las páginas de tienda, producto ni categorías de WooCommerce; el carrito, el checkout y la cuenta nunca se cachean en ningún plan. Se aplica en el servidor de cache.lat.
* Nueva sección "Avisos y novedades" con avisos (versión nueva, vigencia de la licencia, WooCommerce sin cachear) y este historial de cambios. Si tienes WooCommerce y una licencia sin WooCommerce, un aviso lo explica y puedes marcarlo como intencional.
* Corrección: al actualizar desde wp-admin el plugin quedaba desactivado. Ahora se reactiva solo.
* La limpieza de sesiones de WooCommerce pasa a ser parte de la licencia Avanzada; la limpieza general sigue en todos los niveles.

= 1.18.2 =
* Prueba de rendimiento: límite por tiempo (máximo 5 pruebas por minuto) en lugar de un cupo diario, y corrección del error "database is locked" (SQLSTATE 5) que aparecía al ejecutar una prueba mientras había otras peticiones en el motor.
* Salvoconducto de instalación: si faltan archivos del plugin (subida incompleta por FTP, descompresión cortada), el plugin ya no provoca un error fatal que tumbe el sitio — no se carga y muestra un aviso en el panel.
* Nuevo enlace y aviso en el panel hacia la guía de recuperación de un sitio WordPress (FTP / cPanel).
* Corregida la codificación de caracteres de la cabecera del plugin y del script de desinstalación.

= 1.18.1 =
* Prueba de rendimiento: ahora también en móvil (viewport de teléfono y petición con agente móvil, más una estimación de descarga en 4G lento), prueba de una página puntual (ruta o URL) y gráfico de líneas del historial con una serie por dispositivo, además de barras de cada métrica frente a los umbrales de Core Web Vitals. Solo se prueban páginas del dominio donde está instalado el plugin; nunca sitios de terceros.

= 1.18.0 =
* Nuevo: "Prueba de rendimiento by cache.lat" (submenú). cache.lat mide tu portada desde fuera de tu servidor (tiempo de respuesta, peso, compresión, si se sirve como estático y la comparativa contra WordPress en vivo) y tu navegador mide LCP, CLS, FCP y TBT. Da un puntaje 0-100 propio de cache.lat y guarda un historial con gráfico de líneas. Límite diario por plan para no saturar el servidor.

= 1.17.1 =
* La versión instalada ahora se muestra junto al logo en el panel, con un botón "Buscar actualización".
* Aviso dentro del panel cuando hay una versión nueva, con el changelog y un botón "Actualizar ahora". Ya no hay que esperar al ciclo de 12 h de WordPress: el plugin consulta cada hora y sincroniza el aviso nativo de Plugins.
* Misma velocidad de generación en plan gratis que con licencia (el gratis solo se limita en cantidad de páginas).

= 1.17.0 =
* Licencia: el plugin ahora guarda localmente el último plan verificado CON su fecha de vencimiento (opción + archivo de respaldo en wp-content). Si cache.lat no responde, se sigue tratando el sitio como con licencia mientras esa vigencia no haya pasado, en vez de caer a gratis.
* Licencia: si el servidor reporta gratis (o el token dejó de ser válido) pero la licencia guardada sigue vigente, el plugin la reactiva solo con la licencia cifrada que ya tiene — lo mismo que antes había que hacer a mano reingresando la clave. Máximo un intento cada 30 minutos.
* Purgar caché ahora es local y completo: borra todos los archivos estáticos de /cache (index.html, .gz, .br y carpetas) sin depender del servidor, y cancela cualquier trabajo o cambio pendiente para que nada los reescriba enseguida. Antes solo borraba las páginas de la selección actual (10 en gratis) y no hacía nada si el servidor estaba ocupado.

= 1.16.0 =
* Corrección importante reportada por clientes: un corte transitorio de cache.lat (servidor ocupado, timeout de red) podía hacer que el plugin mostrara "plan gratis" aunque la licencia siguiera vigente — el panel y la barra de admin asumían plan gratis ante cualquier falla de verificación, y si nadie entraba a wp-admin mientras durara el corte, esa apariencia se quedaba así hasta reactivar la licencia a mano. Ahora se guarda el último plan verificado con éxito y, ante una falla, se muestra ESE (marcado "sin verificar recién") en vez de asumir gratis. El servidor nunca había bajado el plan real en estos casos — era un problema de qué mostraba el plugin, no de qué licencia tenías activa.
* Nuevo: limpieza y mantenimiento de base de datos (transients vencidos, metadatos huérfanos, revisiones viejas, sesiones de carrito de WooCommerce expiradas) — manual o automática una vez por semana vía WP-Cron. Nunca toca pedidos, productos, usuarios ni la papelera.
* Nuevo submenú "Cron real (servidor)": arma el comando exacto para configurar un cron de verdad en cPanel u otro panel de hosting, para que las tareas programadas del plugin (auto-actualización, optimización de imágenes, limpieza de base de datos, refrescos) corran aunque el sitio no reciba visitas.

= 1.15.0 =
* Actualización automática del propio plugin: a partir de esta versión, cache.lat se mantiene al día solo, usando el mecanismo nativo de actualizaciones automáticas de WordPress (misma protección contra errores fatales que trae el núcleo desde la versión 5.9 — si algo sale mal, ese sitio vuelve solo a la versión anterior). No hace falta que el cliente entre a wp-admin, descargue nada ni reinstale.
* Chequeo propio después de cada actualización automática: reinstala el .htaccess con el código ya actualizado y confirma que el sitio siga sirviendo el estático; si algo quedó mal, lo avisa en el panel.
* IMPORTANTE para sitios en una versión anterior a esta: el mecanismo de auto-actualización recién queda activo una vez que el sitio YA tiene instalada la 1.15.0 o posterior — la primera actualización hasta acá todavía hay que hacerla a mano (o reemplazando el .zip), como siempre. De ahí en adelante, las versiones futuras se instalan solas.

= 1.14.0 =
* Corrección reportada por clientes: subir un archivo o un plugin desde /wp-admin/ podía fallar de forma intermitente ("el archivo no existe" aunque sí quedaba subido), y desactivar cache.lat lo arreglaba. Causa real: admin-ajax.php (usado para subir archivos, y para el Heartbeat API) dispara 'admin_init' igual que cualquier carga del panel, y ese gancho podía reescribir el .htaccess al mismo tiempo que esa subida estaba en curso — la escritura no era atómica, así que por una fracción de segundo Apache podía leer el archivo a medio escribir. Ahora el .htaccess se reescribe con archivo temporal + rename() (atómico en cualquier hosting normal), y las revisiones automáticas de .htaccess/cron ya no corren durante peticiones AJAX, solo en cargas reales del panel.

= 1.13.0 =
* Optimización de imágenes (AVIF/WebP) ahora corre sola, una vez al día por WP-Cron, sin depender de que alguien entre al panel y le dé "Optimizar imágenes" — convierte lo pendiente en lotes cortos hasta terminar, igual que la generación de caché.
* Al generar/actualizar el caché (a mano, por el refresco automático o por un cambio puntual), el plugin revisa primero si hay imágenes nuevas sin optimizar y convierte un lote antes de generar el HTML — así las fotos recién subidas ya salen en AVIF/WebP desde esta misma generación, en vez de esperar a la siguiente corrida. Si son muchas de golpe (una subida masiva), el resto lo sigue el barrido diario sin retrasar la generación.

= 1.12.0 =
* Corrección crítica reportada por clientes: el query string de la URL se ignoraba por completo al decidir si servir el HTML estático. `/?s=buscar`, `/?add-to-cart=123`, `/?download_file=...`, `/?wc-ajax=...`, `/tienda/?orderby=precio` o `/producto/x/?attribute_y=z` devolvían la copia en caché de esa misma ruta sin el parámetro (portada en vez de resultados de búsqueda, tienda sin ordenar, producto sin variación, agregar al carrito que no agregaba nada, fragmentos AJAX del carrito que llegaban como HTML en vez de JSON…). Ahora el estático solo se sirve si el query string viene vacío o son solo parámetros de campaña (utm_*, fbclid, gclid, msclkid, mc_cid, mc_eid) — cualquier otro parámetro cae a WordPress en vivo.
* Corrección relacionada: las cookies `woocommerce_cart_hash` y `wp_woocommerce_session_*` no estaban en la lista que evita servir el estático a una sesión activa — un cliente que acababa de comprar (carrito ya vacío, pero con esas cookies todavía puestas) podía seguir viendo la portada en vez de su sitio en vivo.
* El plugin ahora reescribe el .htaccess solo con actualizarse (updater de WordPress, FTP o WP-CLI) — ya no depende de que cada cliente pulse "Reparar .htaccess" a mano para recibir una corrección de este tipo.

= 1.11.0 =
* Enlaces a preguntas frecuentes, documentación, política de privacidad, términos de servicio y política de reembolsos: visibles al confirmar/activar el sitio por primera vez y en todo momento dentro de "Soporte y licencia".
* Nuevo en el sitio cache.lat: secciones de FAQ y documentación completa, y páginas de política de privacidad, términos de servicio (que también cubren el acuerdo de usuario y sirven como términos de uso para Google Ads) y política de reembolsos (gestionados por TuNegocioEnLinea.net).

= 1.10.0 =
* Corrección: un trabajo grande abandonado (pestaña cerrada a medias) podía quedar huérfano para siempre si después ocurría un cambio de contenido que creara un trabajo nuevo — el panel y WP-Cron solo miraban "el más reciente". Ahora siempre se retoma el más VIEJO sin terminar primero, así nada queda atrás en silencio.
* La generación ya no depende de tener la pestaña abierta: al arrancar un trabajo (o al reabrir el panel con uno pendiente), se encadena WP-Cron como segunda vía — si cierras el navegador, el trabajo sigue avanzando solo con cada visita que reciba el sitio.
* Botón "Abortar" en la barra de progreso: corta la generación en curso. Lo ya generado se queda tal cual; el resto se marca cancelado y deja de aparecer como pendiente.

= 1.9.0 =
* Nuevo: combinar y minificar CSS (apagado por defecto, opt-in). Solo une hojas de estilo CONSECUTIVAS en el HTML, del mismo origen que tu sitio y con el mismo atributo "media" — nunca reordena ni mezcla con lo que quede en medio (un <style> inline corta la tanda ahí). Si una hoja falla al traerse, esa tanda se deja sin tocar. El archivo combinado se nombra por el hash de su contenido, así nunca queda una versión vieja cacheada bajo el mismo nombre.
* El minificador de HTML se mantiene conservador (ya lo era desde 1.4.0): solo colapsa espacios entre etiquetas, nunca toca comentarios ni el contenido de <script>/<style>/<pre>.

= 1.8.0 =
* Detección de otros plugins de caché de página completa (LiteSpeed Cache, WP Rocket, W3 Total Cache, WP Super Cache, WP Fastest Cache, SiteGround Optimizer, Breeze, Cache Enabler, Comet Cache, Swift Performance, WP-Optimize, Hummingbird). Se revisa en la activación y en cada carga del panel.
* Si detecta uno activo, muestra un aviso recomendando dejar solo uno, y mientras tanto pasa a "modo seguro": sigue generando y sirviendo el HTML estático (lo esencial), pero apaga sus propias optimizaciones (fuentes, JS diferido, minificado, imágenes en AVIF/WebP) para no mezclar dos manipulaciones distintas sobre la misma página. Tus preferencias quedan guardadas y se retoman solas en cuanto resuelvas el conflicto.

= 1.7.0 =
* Corrección importante: aunque la imagen AVIF/WebP existiera y pesara menos, el sitio seguía sirviendo el JPEG/PNG de siempre. Causa real: la cabecera de caché del navegador que se agregó en 1.4.0 marcaba jpg/png como "immutable" por 1 año — un visitante (o un CDN delante del sitio, muy común con Cloudflare) que ya tenía la copia vieja en caché nunca volvía a pedirla, sin importar que el servidor ya pudiera negociar una mejor versión.
* Arreglo de fondo, no solo el síntoma: ahora, al generar cada página, las etiquetas <img> de la biblioteca de medios se reescriben directo a <picture> con las versiones AVIF/WebP que ya existan para esa imagen puntual — cada formato con su propia URL, sin depender de que el navegador o un CDN respeten la negociación por cabecera Accept.
* Las páginas que ya estaban cacheadas antes de optimizar imágenes por primera vez necesitan una regeneración más para tomar el cambio (se avisa en el panel).

= 1.6.1 =
* Corrección: las imágenes convertidas a AVIF/WebP se guardaban con el permiso correcto en el ARCHIVO, pero nunca se corregía el permiso de la CARPETA de subidas que las contiene — si esa carpeta quedó restringida (herencia del hosting, un plugin de seguridad), el servidor no podía entrar a servirlas aunque el archivo estuviera bien, y la imagen se seguía viendo en JPEG/PNG en el sitio en silencio. Ahora se corrige la carpeta también al convertir.
* Diagnóstico automático de permisos de imágenes al terminar cada optimización, más los botones "Reparar permisos de imágenes" y "Comprobar permisos de imágenes" para lo que ya se había convertido antes de esta versión.

= 1.6.0 =
* "Restablecer conexión": cuando el token guardado queda inválido (por ejemplo, si la licencia se reactivó desde otro lugar y el servidor emitió un token más nuevo), aparece un aviso arriba de todo con un botón de un clic. Reintenta con la licencia guardada, valida si sigue vigente y reconecta — si venció, deja el sitio funcionando en gratis en vez de roto, con la opción de activar una nueva licencia justo ahí.
* La licencia (clave del sitio + clave de activación) ahora se guarda cifrada al activarla, para que "Restablecer conexión" pueda reintentarla sin pedirle al cliente que la busque de nuevo.

= 1.5.0 =
* Nueva sección "Soporte y licencia" en el panel: enlaces directos para conseguir/renovar una licencia o contactar soporte (con tu dominio y clave de sitio ya listos para copiar), botón "Verificar estado" y un botón real de "Volver a plan gratis".
* Corrección: "Olvidar conexión local" solo borraba credenciales en este WordPress sin avisarle nada al servidor — el sitio quedaba en premium para siempre del lado de cache.lat aunque pareciera "reseteado". El nuevo "Volver a plan gratis" sí baja el plan en el servidor (sin liberar la licencia ni borrar el caché ya generado).

= 1.4.2 =
* Corrección importante: el optimizador de imágenes solo convertía el archivo ORIGINAL que subiste, pero WordPress genera además una copia física por cada tamaño (miniatura, mediana, grande...) y el tema casi siempre muestra uno de esos tamaños, no el original. Ahora se convierte el original Y cada tamaño generado — antes de esto, el sitio seguía sirviendo JPEG/PNG sin importar cuántas veces se optimizara. El lote pasa de 8 a 3 adjuntos por llamada (cada uno ahora implica varios archivos).

= 1.4.1 =
* Imágenes: ahora puedes elegir el formato preferido (Automático / siempre AVIF / siempre WebP) y la calidad de cada uno con un control deslizante — si tus fotos se veían borrosas, sube la calidad y vuelve a optimizar. Cambiar el ajuste borra los archivos generados con el ajuste anterior para que no quede una versión vieja sirviéndose por error.
* Aclaración de uso: las reglas del .htaccess que sirven AVIF/WebP (agregadas en 1.4.0) solo quedan instaladas si actualizas el plugin completo, no solo el HtmlOptimizer.php del motor. Si ya optimizaste imágenes pero el sitio sigue sirviendo JPEG/PNG, actualiza este plugin y usa "Reparar .htaccess".

= 1.4.0 =
* Optimización de páginas al generar el caché (aplicada en el servidor de cache.lat, sin costo para tu hosting): lazy-load de imágenes/iframes, font-display: swap y preconnect para Google Fonts, scripts diferidos (jQuery, WooCommerce, pasarelas y reCAPTCHA siempre excluidos), minificado conservador y limpieza del script de emojis. Configurable desde el panel.
* Compresión: cada página se guarda también en .gz y en .br si el servidor tiene Brotli; se sirve la mejor variante según lo que acepte el navegador.
* Imágenes: botón para convertir la biblioteca de medios a AVIF (si el servidor sabe codificarlo) o WebP, usando Imagick o GD ya instalados — un archivo nuevo se conserva solo si pesa menos que el original. Las imágenes se quedan siempre en tu propio servidor.
* .htaccess: caché de navegador para imágenes/CSS/JS/fuentes, redirección opcional a HTTPS con HSTS (Always SSL), y cookies adicionales configurables para excluir del caché.

= 1.4.0 =
* Corrección: cada generación recibía el estático anterior en vez de la página en vivo (el .htaccess no respetaba la cabecera de bypass del motor), lo que acumulaba una marca por corrida y podía dejar contenido viejo. Ahora el bloque excluye esas peticiones y las marcas repetidas se limpian.

= 1.4.0 =
* Generación más rápida: el motor descarga varias páginas en paralelo por lote (premium) y el plugin usa el tamaño de lote que sugiere el servidor. Al terminar muestra cuánto tarda tu sitio por página.
* Frescura: al publicar, editar, despublicar o borrar contenido (y al cambiar stock, comentarios aprobados o categorías) se borra al instante el estático afectado y se regenera solo eso. Menús, tema, personalizador y widgets regeneran todo sin borrar antes. Escritura atómica de archivos.
* Corrección: los jobs automáticos (WP-Cron) generaban en el servidor pero nunca escribían las páginas en disco.
* Corrección: la regla del .htaccess usa -s (archivo no vacío); antes la carpeta cache recién creada podía servir la portada en blanco.
* Botones Reparar .htaccess (con respaldo) y Comprobar permisos; el plugin repara y diagnostica permisos y .htaccess tras cada generación.

= 1.4.0 =
* Prioridad real entre planes: el servidor topa el tamaño del lote según
  el plan del sitio (gratis: 1 página/llamada, premium: hasta 5) — nunca
  confía en lo que pida el plugin. Premium sondea cada 1s, gratis cada 4s.
* Metadato invisible "powered by cache.lat" (con fecha de generación) en
  cada HTML servido, visible solo al inspeccionar el código fuente.
* Detección automática de páginas sensibles de WooCommerce (carrito,
  checkout, mi cuenta) vía una nueva ruta REST del plugin — se excluyen
  siempre de los candidatos, nunca se pueden cachear por accidente.
* Modo "cachear todo el sitio" (premium) con exclusiones, en vez de tener
  que elegir página por página.
* Nuevo submenú "Páginas cacheadas": fecha de generación y peso de cada
  página, leído directo del disco.
* Refresco automático programado (6h/12h/24h/7 días/mensual) vía WP-Cron,
  encadenado en pasos cortos para no arriesgar timeouts en sitios grandes.
* Agregada la ruta REST /wp-json/cache-lat/v1/ping que el barrido de 30
  días de cache.lat necesita — nunca se había implementado; todo sitio
  fallaba ese ping desde siempre.

= 1.1.0 =
* Plan gratuito sin cuenta: ya no pide correo ni contraseña, solo confirma
  el dominio detectado (con aviso de que www./sin-www. cuentan como sitios
  distintos). El mismo botón sirve para registrar y para reconectar tras
  reinstalar el plugin.
* Activación de licencia con clave del sitio + clave de activación (sin
  correo). Mensaje específico cuando la licencia ya está en otro dominio.
* Panel: muestra los días restantes de la licencia, con aviso cuando ya
  venció y la caja para activar una nueva aparece de inmediato (sin
  esperar al barrido diario del servidor).
* Logo con transparencia real (sin caja blanca) en menú y panel.
* Corregidos varios accesos a campos de la API con nombres equivocados
  (plan/plan_slug, días restantes) que hacían que el panel nunca mostrara
  el plan real ni los días de licencia correctamente.

= 1.0.0 =
* Primera versión: registro/activación de licencia, selección de páginas,
  generación y purga de caché por lotes con barra de progreso, reglas de
  reescritura de .htaccess, y limpieza completa al desinstalar.
