{"id":342793,"date":"2026-05-04T19:32:10","date_gmt":"2026-05-04T17:32:10","guid":{"rendered":"https:\/\/legroup.es\/zonacorredores\/?page_id=342793"},"modified":"2026-05-07T10:28:38","modified_gmt":"2026-05-07T08:28:38","slug":"mejores-marcas-personales","status":"publish","type":"page","link":"https:\/\/legroup.es\/zonacorredores\/mejores-marcas-personales\/","title":{"rendered":"Mejores Marcas Personales"},"content":{"rendered":"<p>[et_pb_section fb_built=\u00bb1&#8243; _builder_version=\u00bb4.27.6&#8243; _module_preset=\u00bbdefault\u00bb da_disable_devices=\u00bboff|off|off\u00bb global_colors_info=\u00bb{}\u00bb custom_padding=\u00bb0px|||||\u00bb da_is_popup=\u00bboff\u00bb da_exit_intent=\u00bboff\u00bb da_has_close=\u00bbon\u00bb da_alt_close=\u00bboff\u00bb da_dark_close=\u00bboff\u00bb da_not_modal=\u00bbon\u00bb da_is_singular=\u00bboff\u00bb da_with_loader=\u00bboff\u00bb da_has_shadow=\u00bbon\u00bb][et_pb_row _builder_version=\u00bb4.27.6&#8243; _module_preset=\u00bbdefault\u00bb global_colors_info=\u00bb{}\u00bb custom_padding=\u00bb26px|||||\u00bb][et_pb_column type=\u00bb4_4&#8243; _builder_version=\u00bb4.27.6&#8243; _module_preset=\u00bbdefault\u00bb global_colors_info=\u00bb{}\u00bb][et_pb_code _builder_version=\u00bb4.27.6&#8243; _module_preset=\u00bbdefault\u00bb global_colors_info=\u00bb{}\u00bb]\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Oswald:wght@400;700&family=Lato:wght@400;700&display=swap\" rel=\"stylesheet\">\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.1\/dist\/chart.umd.min.js\"><\/script>\n\n    <style>\n        .running-container { font-family: 'Lato', sans-serif; margin: 20px 0; color: #333; font-size: 15px; }\n        .running-container h2, .running-container h3 { font-family: 'Oswald', sans-serif; margin-top: 30px; }\n        .running-container h2 { font-size: 42px; font-weight: 700; line-height: 1.1; }\n        .seccion { border: 1px solid #eee; padding: 20px; margin-top: 20px; border-radius: 8px; background: #fafafa; }\n        .form-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 10px; }\n        \n        .table-container { width: 100%; overflow-x: auto; margin-top: 20px; -webkit-overflow-scrolling: touch; }\n        .running-table { width: 100%; border-collapse: collapse; border: 2px solid #F89238; min-width: 500px; }\n        .running-table th { background: #F89238; color: #ffffff !important; font-family: 'Oswald', sans-serif; text-transform: uppercase; padding: 10px; text-align: center; font-size: 14px; }\n        .running-table td { border: 1px solid #F89238; padding: 8px; text-align: center; background: #fff; font-size: 13px; }\n        \n        .running-container input, .running-container select, .running-container button { padding: 10px; border-radius: 4px; border: 1px solid #ccc; }\n        .running-container button { background: #F89238; color: white; border: none; cursor: pointer; font-weight: bold; }\n        \n        #filtroCarrera, #filtroGenero { font-family: 'Oswald'; font-size: 20px; font-weight: bold; height: 50px; border: 2px solid #F89238; border-radius: 8px; padding: 0 10px; }\n        #selectPublico { width: 100%; max-width: 100%; height: 50px; font-size: 16px; padding: 5px 10px; }\n        \n        .mejor-marca-row td { background: #ffe4b5 !important; font-weight: bold; color: #d35400 !important; border: 2px solid #F89238 !important; }\n        .nombre-ranking { color: #F89238; text-decoration: underline; cursor: pointer; font-weight: bold; }\n        \n        .modal { display: none; position: fixed; z-index: 999999; left: 0; top: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); overflow-y: auto; }\n        .modal-content { background: #fff; margin: 160px auto 100px auto; padding: 20px; border-radius: 8px; width: 95%; max-width: 900px; position: relative; }\n        .close { position: absolute; right: 20px; top: 10px; font-size: 40px; cursor: pointer; }\n        \n        .pagination-container { margin-top: 15px; text-align: center; display: flex; justify-content: center; gap: 10px; align-items: center; }\n        .btn-export { background: #F89238 !important; margin-top: 15px; padding: 12px 25px !important; font-size: 16px; width: 100%; }\n        .btn-share { background: #F89238 !important; margin-top: 10px; }\n        .input-date-active { border: 3px solid #F89238 !important; background-color: #fff5eb !important; }\n\n        @media screen and (max-width: 600px) {\n            .running-container h2 { font-size: 32px; }\n            .running-container h3 { font-size: 20px; }\n            .form-row { flex-direction: column; align-items: stretch; }\n            .form-row input, .form-row select { width: 100% !important; }\n            #filtroFechaPublico { width: 100% !important; min-height: 45px; display: block !important; visibility: visible !important; }\n            .running-table th, .running-table td { padding: 6px; font-size: 12px; }\n        }\n\n        @media print {\n            header, footer, nav, aside, .header, .footer, .sidebar, .menu, #header, #footer, img, .logo, .wp-admin-bar { display: none !important; }\n            #adminPanel, h2, .form-row, #pagination, .seccion > h3, .seccion > p, #btnImprimir, #btnExportarFiltrado, #tablaRankingPrincipal, #seccionFiltroFecha, .btn-share, .close, .modal { display: none !important; }\n            body, html { visibility: hidden; height: auto; margin: 0 !important; background: #fff !important; }\n            .running-container { visibility: visible; position: absolute; left: 0; top: 0; width: 100% !important; }\n            .seccion { border: none !important; background: none !important; padding: 0 !important; }\n            #areaImpresion { display: block !important; visibility: visible !important; width: 100% !important; }\n            #tablaPublica { display: table !important; width: 100% !important; border: 1px solid #333 !important; }\n            #tituloPublico { display: block !important; visibility: visible !important; text-align: center; font-size: 20pt; color: #000 !important; }\n            @page { size: auto; margin: 1.5cm; }\n        }\n    <\/style>\n\n    <div class=\"running-container\">\n        \n        <h2>Marcas Personales<\/h2>\n        <div class=\"form-row\">\n            <select id=\"filtroCarrera\" onchange=\"resetPaginaYRender()\"><\/select>\n            <select id=\"filtroGenero\" onchange=\"resetPaginaYRender()\">\n                <option value=\"all\">Todo (Todos los corredores)<\/option>\n                <option value=\"M\">Masculino (Top 10)<\/option>\n                <option value=\"F\">Femenino (Top 10)<\/option>\n            <\/select>\n        <\/div>\n        <div class=\"table-container\">\n            <table class=\"running-table\" id=\"tablaRankingPrincipal\">\n                <thead>\n                    <tr><th>#<\/th><th>Nombre<\/th><th id=\"colDinamica\">Tiempo<\/th><th>Fecha<\/th><\/tr>\n                <\/thead>\n                <tbody id=\"rankingBody\"><\/tbody>\n            <\/table>\n        <\/div>\n        <div id=\"pagination\" class=\"pagination-container\"><\/div>\n\n        <div class=\"seccion\" style=\"background: #fff; border: 2px solid #F89238;\">\n            <h3>Buscar marcas e Historial<\/h3>\n            <div class=\"form-row\">\n                <select id=\"selectPublico\" onchange=\"verHistorialPublico()\">\n                    <option value=\"\">-- Selecciona el corredor --<\/option>\n                <\/select>\n            <\/div>\n\n            <div id=\"seccionFiltroFecha\" style=\"margin-top:20px; border-top: 1px solid #eee; padding-top: 20px;\">\n                <p style=\"font-weight: bold;\">Ver resultados de una fecha con carreras:<\/p>\n                <div class=\"form-row\">\n                    <input type=\"date\" id=\"filtroFechaPublico\" onchange=\"verResultadosPorFecha()\" value=\"2026-06-13\">\n                    <span id=\"msgFecha\" style=\"font-size: 0.85em; color: #F89238; font-weight: bold;\"><\/span>\n                <\/div>\n            <\/div>\n            \n            <div id=\"areaImpresion\">\n                <h4 id=\"tituloPublico\"><\/h4>\n                <div class=\"table-container\">\n                    <table class=\"running-table\" id=\"tablaPublica\" style=\"display:none;\">\n                        <thead>\n                            <tr><th>Corredor \/ Fecha<\/th><th>Carrera<\/th><th>Marca<\/th><th>Ritmo<\/th><th>Notas<\/th><\/tr>\n                        <\/thead>\n                        <tbody id=\"historialBodyPublico\"><\/tbody>\n                    <\/table>\n                <\/div>\n            <\/div>\n            <div class=\"form-row\">\n                <button id=\"btnImprimir\" class=\"btn-export\" style=\"display:none;\" onclick=\"window.print()\">\ud83d\udda8\ufe0f Imprimir \/ Exportar PDF<\/button>\n                                <button id=\"btnCompartir\" class=\"btn-export btn-share\" style=\"display:none;\" onclick=\"generarEnlaceCompartir()\">\ud83d\udd17 Copiar enlace<\/button>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div id=\"modalGrafico\" class=\"modal\">\n        <div class=\"modal-content\">\n            <span class=\"close\" onclick=\"cerrarModal()\">&times;<\/span>\n            <h3 id=\"tituloGrafico\" style=\"text-align:center;\"><\/h3>\n            <div style=\"height: 300px;\"><canvas id=\"canvasGrafico\"><\/canvas><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    const ajaxurl = \"https:\/\/legroup.es\/zonacorredores\/wp-admin\/admin-ajax.php\";\n    let resultados = [], corredores = [], generos = {}, chartInstance = null, currentPage = 1;\n    const resultsPerPage = 10, carreras = [\"1000m\",\"1500m\",\"2000m\",\"3000m\",\"5k\",\"10k\",\"15k\",\"20k\",\"Media Marat\u00f3n\",\"25k\",\"30k\",\"Marat\u00f3n\",\"50k\",\"100k\",\"101k Ronda\",\"6 horas\",\"12 horas\",\"24 horas\",\"Spartathlon\"], carrerasTiempo = [\"6 horas\", \"12 horas\", \"24 horas\"];\n\n    document.addEventListener(\"DOMContentLoaded\", () => {\n        const fc = document.getElementById('filtroCarrera'), cs = document.getElementById('carreraSelect');\n        carreras.forEach(c => { if(fc) fc.innerHTML += `<option value=\"${c}\">${c}<\/option>`; if(cs) cs.innerHTML += `<option value=\"${c}\">${c}<\/option>`; });\n        fetchData().then(() => {\n            const urlParams = new URLSearchParams(window.location.search);\n            const dateParam = urlParams.get('run_date');\n            if (dateParam) {\n                document.getElementById('filtroFechaPublico').value = dateParam;\n                verResultadosPorFecha();\n            }\n        });\n    });\n\n    async function fetchData() {\n        const response = await fetch(`${ajaxurl}?action=get_running_data`);\n        const data = await response.json();\n        resultados = data.resultados || [];\n        corredores = [...new Set(data.corredores || [])];\n        generos = data.generos || {};\n        actualizarSelects();\n        renderRanking();\n        marcarFechasConDatos();\n    }\n\n    function exportarDatosFiltrados() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        const corredor = document.getElementById('selectPublico').value;\n        let datosAExportar = [];\n\n        if (fecha && !corredor) {\n            datosAExportar = resultados.filter(r => r.fecha === fecha);\n        } else if (corredor) {\n            datosAExportar = resultados.filter(r => r.nombre === corredor);\n        }\n\n        if (datosAExportar.length === 0) return alert(\"No hay datos cargados en esta vista para exportar.\");\n\n        let csvContent = \"data:text\/csv;charset=utf-8,Nombre,Genero,Carrera,Fecha,Tiempo,Notas\\n\";\n        datosAExportar.forEach(r => {\n            csvContent += `\"${r.nombre}\",\"${r.genero}\",\"${r.carrera}\",\"${r.fecha}\",\"${r.tiempo}\",\"${(r.notas || '').replace(\/\"\/g, '\"\"')}\"\\n`;\n        });\n\n        const fileName = fecha ? `resultados_${fecha}.csv` : `historial_${corredor}.csv`;\n        const encodedUri = encodeURI(csvContent);\n        const link = document.createElement(\"a\");\n        link.setAttribute(\"href\", encodedUri);\n        link.setAttribute(\"download\", fileName);\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n    }\n\n    function importarExcel(event) {\n        const file = event.target.files[0];\n        if (!file) return;\n        const reader = new FileReader();\n        reader.onload = async function(e) {\n            const content = e.target.result;\n            const rows = content.split(\/\\r?\\n\/).slice(1);\n            let nuevos = 0;\n            \n            for(let row of rows) {\n                if(!row.trim()) continue;\n                let separator = row.includes(\";\") ? \";\" : \",\";\n                let cols = row.split(separator).map(c => c.replace(\/\"\/g, '').trim());\n                \n                if (cols && cols.length >= 5) {\n                    let r = {\n                        nombre: cols[0],\n                        genero: cols[1],\n                        carrera: cols[2],\n                        fecha: cols[3],\n                        tiempo: cols[4],\n                        notas: cols[5] || ''\n                    };\n                    \n                    if(!r.nombre || r.nombre.toLowerCase() === 'nombre') continue;\n                    \n                    const p = new URLSearchParams();\n                    p.append('action', 'save_running_result');\n                    p.append('nombre', r.nombre); \n                    p.append('genero', r.genero);\n                    p.append('carrera', r.carrera); \n                    p.append('fecha', r.fecha);\n                    p.append('tiempo', r.tiempo); \n                    p.append('notas', r.notas);\n\n                    const res = await fetch(ajaxurl, { method: 'POST', body: p });\n                    const status = await res.json();\n                    if(status.success && status.data.new) nuevos++;\n                }\n            }\n            alert(`Proceso completado. Se han a\u00f1adido ${nuevos} registros nuevos. Los duplicados fueron ignorados.`);\n            fetchData();\n        };\n        reader.readAsText(file);\n    }\n\n    function formatFechaES(f) { if(!f) return \"\"; const p = f.split('-'); return `${p[2]}\/${p[1]}\/${p[0]}`; }\n    function formatSegundosAHis(s) { if(isNaN(s)) return \"00:00:00\"; const h = Math.floor(s\/3600), m = Math.floor((s%3600)\/60), sec = Math.floor(s%60); return `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${sec.toString().padStart(2,'0')}`; }\n    function resetPaginaYRender() { currentPage = 1; renderRanking(); }\n    function tiempoSegundos(t) { if(!t || typeof t !== 'string') return 0; if(t.includes(\":\")) { let p = t.split(\":\").map(Number); return (p[0]*3600)+(p[1]*60)+p[2]; } return parseFloat(t) || 0; }\n\n    function ritmo(c, t) {\n        if(carrerasTiempo.includes(c)) return \"-\";\n        const dists = {\"1000m\":1,\"2000m\":2,\"3000m\":3,\"5k\":5,\"10k\":10,\"15k\":15,\"20k\":20,\"Media Marat\u00f3n\":21.097,\"25k\":25,\"30k\":30,\"Marat\u00f3n\":42.195,\"50k\":50,\"100k\":100,\"101k Ronda\":101,\"Spartathlon\":246};\n        let km = dists[c] || 0; if(km === 0) return \"-\";\n        let segTotales = tiempoSegundos(t) \/ km;\n        let mins = Math.floor(segTotales \/ 60), segs = Math.floor(segTotales % 60);\n        return `${mins}:${segs.toString().padStart(2,\"0\")}`;\n    }\n\n    function esMejorMarca(corredor, carrera, tiempo) {\n        let isKm = carrerasTiempo.includes(carrera);\n        let marcas = resultados.filter(r => r.nombre === corredor && r.carrera === carrera);\n        let val = tiempoSegundos(tiempo);\n        return isKm ? !marcas.some(m => tiempoSegundos(m.tiempo) > val) : !marcas.some(m => tiempoSegundos(m.tiempo) < val);\n    }\n\n    function renderRanking() {\n        const c = document.getElementById('filtroCarrera').value, g = document.getElementById('filtroGenero').value, isKm = carrerasTiempo.includes(c);\n        document.getElementById('colDinamica').innerText = isKm ? \"Kil\u00f3metros\" : \"Tiempo\";\n        let filtered = resultados.filter(r => r.carrera === c);\n        if(g !== 'all') filtered = filtered.filter(r => r.genero === g);\n        let bests = {};\n        filtered.forEach(r => { let v = tiempoSegundos(r.tiempo); if(!bests[r.nombre] || (isKm ? v > tiempoSegundos(bests[r.nombre].tiempo) : v < tiempoSegundos(bests[r.nombre].tiempo))) bests[r.nombre] = r; });\n        let sorted = Object.values(bests).sort((a,b) => isKm ? tiempoSegundos(b.tiempo) - tiempoSegundos(a.tiempo) : tiempoSegundos(a.tiempo) - tiempoSegundos(b.tiempo));\n        let finalDisplay = [];\n        const paginationDiv = document.getElementById('pagination');\n        if (g === 'all') {\n            const totalPages = Math.ceil(sorted.length \/ resultsPerPage);\n            finalDisplay = sorted.slice((currentPage - 1) * resultsPerPage, currentPage * resultsPerPage);\n            paginationDiv.innerHTML = `<button onclick=\"changePage(-1)\" ${currentPage===1?'disabled':''}>Anterior<\/button><span>P\u00e1gina ${currentPage} de ${totalPages || 1}<\/span><button onclick=\"changePage(1)\" ${currentPage===totalPages || totalPages===0?'disabled':''}>Siguiente<\/button>`;\n        } else { finalDisplay = sorted.slice(0, 10); paginationDiv.innerHTML = \"\"; }\n        document.getElementById('rankingBody').innerHTML = finalDisplay.map((r,i) => {\n            const index = g === 'all' ? ((currentPage - 1) * resultsPerPage) + i + 1 : i + 1;\n            return `<tr><td>${index}<\/td><td class=\"nombre-ranking\" onclick=\"abrirGrafico('${r.nombre}')\">${r.nombre}<\/td><td>${isKm ? parseFloat(r.tiempo).toFixed(3)+' km' : r.tiempo}<\/td><td>${formatFechaES(r.fecha)}<\/td><\/tr>`;\n        }).join('');\n    }\n\n    function changePage(step) { currentPage += step; renderRanking(); }\n\n    function verHistorialPublico() {\n        const n = document.getElementById('selectPublico').value, body = document.getElementById('historialBodyPublico');\n        if(!n) return;\n        document.getElementById('filtroFechaPublico').value = \"\";\n        document.getElementById('tablaPublica').style.display = \"table\";\n        document.getElementById('btnImprimir').style.display = \"block\";\n        if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"block\";\n        document.getElementById('btnCompartir').style.display = \"none\";\n        document.getElementById('tituloPublico').innerText = \"Historial: \" + n;\n        let susRes = resultados.filter(r => r.nombre === n).sort((a,b) => new Date(b.fecha) - new Date(a.fecha));\n        body.innerHTML = susRes.map(r => `<tr class=\"${esMejorMarca(r.nombre, r.carrera, r.tiempo) ? 'mejor-marca-row' : ''}\"><td>${formatFechaES(r.fecha)}<\/td><td>${r.carrera}<\/td><td>${r.tiempo}<\/td><td>${ritmo(r.carrera, r.tiempo)}<\/td><td>${r.notas || ''}<\/td><\/tr>`).join('');\n    }\n\n    function verResultadosPorFecha() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        const body = document.getElementById('historialBodyPublico');\n        if(!fecha) return;\n        document.getElementById('selectPublico').value = \"\";\n        document.getElementById('tablaPublica').style.display = \"table\";\n        document.getElementById('btnImprimir').style.display = \"block\";\n        if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"block\";\n        document.getElementById('btnCompartir').style.display = \"block\";\n        document.getElementById('tituloPublico').innerText = \"Resultados del: \" + formatFechaES(fecha);\n        let diaRes = resultados.filter(r => r.fecha === fecha).sort((a,b) => a.nombre.localeCompare(b.nombre));\n        if(diaRes.length === 0) {\n            body.innerHTML = '<tr><td colspan=\"5\">Sin registros.<\/td><\/tr>';\n            document.getElementById('btnCompartir').style.display = \"none\";\n            if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"none\";\n            return;\n        }\n        body.innerHTML = diaRes.map(r => `<tr class=\"${esMejorMarca(r.nombre, r.carrera, r.tiempo) ? 'mejor-marca-row' : ''}\"><td>${r.nombre}<\/td><td>${r.carrera}<\/td><td>${r.tiempo}<\/td><td>${ritmo(r.carrera, r.tiempo)}<\/td><td>${r.notas || ''}<\/td><\/tr>`).join('');\n    }\n\n    function marcarFechasConDatos() {\n        const fechasSet = [...new Set(resultados.map(r => r.fecha))];\n        const inputFecha = document.getElementById('filtroFechaPublico');\n        if(fechasSet.length > 0) {\n            inputFecha.classList.add('input-date-active');\n            document.getElementById('msgFecha').innerText = \"\";\n        }\n    }\n\n    function generarEnlaceCompartir() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        if(!fecha) return;\n        const baseUrl = window.location.href.split('?')[0];\n        const shareUrl = `${baseUrl}?run_date=${fecha}`;\n        navigator.clipboard.writeText(shareUrl).then(() => { alert(\"\u00a1Enlace copiado!\"); });\n    }\n\n    function handleSearch(e, sid, isAdminHist = false) {\n        const filter = e.target.value.toLowerCase(), select = document.getElementById(sid), options = Array.from(select.options);\n        let match = null, count = 0;\n        options.forEach(o => {\n            const isM = o.text.toLowerCase().includes(filter);\n            o.style.display = isM ? \"\" : \"none\";\n            if(isM && o.value !== \"\") { match = o.value; count++; }\n        });\n        if(e.key === \"Enter\" && count === 1) { select.value = match; if(isAdminHist) verHistorialAdmin(); e.target.value = \"\"; }\n    }\n\n    function abrirGrafico(nombre) {\n        document.getElementById('modalGrafico').style.display = \"block\";\n        const cSel = document.getElementById('filtroCarrera').value;\n        const isKmCarrera = carrerasTiempo.includes(cSel);\n        document.getElementById('tituloGrafico').innerText = `Evoluci\u00f3n ${nombre} (${cSel})`;\n        \n        let data = resultados.filter(r => r.nombre === nombre && r.carrera === cSel).sort((a,b) => new Date(a.fecha) - new Date(b.fecha));\n        if(chartInstance) chartInstance.destroy();\n        \n        chartInstance = new Chart(document.getElementById('canvasGrafico'), {\n            type: 'line', \n            data: { datasets: [{ label: cSel, data: data.map(r => ({x: r.fecha, y: tiempoSegundos(r.tiempo), realVal: r.tiempo})), borderColor: '#F89238', tension: 0.1, fill: false, borderWidth: 3, pointRadius: 5 }] },\n            options: { \n                responsive: true, \n                maintainAspectRatio: false, \n                scales: { \n                    y: { \n                        ticks: { \n                            callback: function(v) {\n                                return isKmCarrera ? v + \" km\" : formatSegundosAHis(v);\n                            }\n                        } \n                    } \n                },\n                plugins: {\n                    tooltip: {\n                        callbacks: {\n                            label: function(context) {\n                                let label = context.dataset.label || '';\n                                let val = context.raw.realVal;\n                                return label + ': ' + val + (isKmCarrera ? ' km' : '');\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    function verHistorialAdmin() {\n        const n = document.getElementById('histCorredor').value, body = document.getElementById('historialBodyAdmin');\n        if(!n) return;\n        let susRes = resultados.filter(r => r.nombre === n).sort((a,b) => new Date(b.fecha) - new Date(a.fecha));\n        body.innerHTML = susRes.map(r => `<tr>\n            <td><input value=\"${r.nombre}\" id=\"name-${r.id}\" style=\"width:120px;\"><\/td>\n            <td><input type=\"date\" value=\"${r.fecha}\" id=\"f-${r.id}\"><\/td>\n            <td><select id=\"c-${r.id}\">${carreras.map(c => `<option value=\"${c}\" ${r.carrera === c ? 'selected' : ''}>${c}<\/option>`).join('')}<\/select><\/td>\n            <td><input value=\"${r.tiempo}\" id=\"t-${r.id}\" style=\"width:80px;\"><\/td>\n            <td><input value=\"${r.notas || ''}\" id=\"n-${r.id}\" style=\"width:150px;\"><\/td>\n            <td><button onclick=\"actualizarRegistro(${r.id})\">Modificar<\/button><button onclick=\"borrarRegistro(${r.id})\" style=\"background:red; margin-left:5px;\">\ud83d\uddd1\ufe0f<\/button><\/td><\/tr>`).join('');\n    }\n\n    function actualizarSelects() {\n        ['nombreSelect', 'histCorredor', 'selectPublico'].forEach(id => {\n            const s = document.getElementById(id);\n            if(s) { \n                const v = s.value; \n                s.innerHTML = `<option value=\"\">-- Selecciona el corredor --<\/option>` + corredores.sort().map(c => `<option value=\"${c}\">${c}<\/option>`).join(''); \n                if(v) s.value = v; \n            }\n        });\n    }\n\n    function adaptarInputCarga() { const c = document.getElementById('carreraSelect').value; document.getElementById('tiempo').placeholder = carrerasTiempo.includes(c) ? \"Km\" : \"hhmmss\"; }\n    function procesarEntRef() {\n        const c = document.getElementById('carreraSelect').value, t = document.getElementById('tiempo'); if(!t.value) return;\n        if(carrerasTiempo.includes(c)) { let v = parseFloat(t.value); if(!isNaN(v)) t.value = v.toFixed(3); }\n        else { let v = t.value.replace(\/\\D\/g, \"\").padStart(6, \"0\").slice(-6); t.value = `${v.slice(0,2)}:${v.slice(2,4)}:${v.slice(4,6)}`; }\n    }\n    async function agregarCorredor() {\n        const n = document.getElementById('nuevoCorredor').value.trim(); if(!n) return;\n        const p = new URLSearchParams(); p.append('action', 'add_running_corredor'); p.append('nombre', n); p.append('genero', document.getElementById('genero').value);\n        await fetch(ajaxurl, { method: 'POST', body: p }); document.getElementById('nuevoCorredor').value = \"\"; fetchData();\n    }\n    async function guardarResultado() {\n        const n = document.getElementById('nombreSelect').value; if(!n) return alert(\"Selecciona corredor\");\n        const p = new URLSearchParams(); p.append('action', 'save_running_result');\n        p.append('nombre', n); p.append('carrera', document.getElementById('carreraSelect').value);\n        p.append('fecha', document.getElementById('fecha').value); p.append('tiempo', document.getElementById('tiempo').value);\n        p.append('genero', generos[n] || 'M'); p.append('notas', document.getElementById('notasInput').value);\n        await fetch(ajaxurl, { method: 'POST', body: p });\n        fetchData();\n    }\n    async function actualizarRegistro(id) {\n        const p = new URLSearchParams(); p.append('action', 'update_running_result'); p.append('id', id);\n        p.append('nombre', document.getElementById(`name-${id}`).value);\n        p.append('fecha', document.getElementById(`f-${id}`).value); \n        p.append('carrera', document.getElementById(`c-${id}`).value);\n        p.append('tiempo', document.getElementById(`t-${id}`).value);\n        p.append('notas', document.getElementById(`n-${id}`).value);\n        await fetch(ajaxurl, { method: 'POST', body: p }); \n        fetchData().then(() => verHistorialAdmin());\n    }\n    async function borrarRegistro(id) { if(confirm(\"\u00bfEliminar?\")) { const p = new URLSearchParams(); p.append('action', 'delete_running_result'); p.append('id', id); await fetch(ajaxurl, { method: 'POST', body: p }); fetchData().then(() => verHistorialAdmin()); } }\n    async function borrarCorredorCompleto() {\n        const n = document.getElementById('histCorredor').value; if(!n || !confirm(`\u26a0\ufe0f ELIMINAR TODO DE ${n}`)) return;\n        const p = new URLSearchParams(); p.append('action', 'delete_full_runner'); p.append('nombre', n);\n        await fetch(ajaxurl, { method: 'POST', body: p }); fetchData();\n    }\n    function cerrarModal() { document.getElementById('modalGrafico').style.display = \"none\"; }\n    <\/script>\n    [\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Oswald:wght@400;700&family=Lato:wght@400;700&display=swap\" rel=\"stylesheet\">\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.1\/dist\/chart.umd.min.js\"><\/script>\n\n    <style>\n        .running-container { font-family: 'Lato', sans-serif; margin: 20px 0; color: #333; font-size: 15px; }\n        .running-container h2, .running-container h3 { font-family: 'Oswald', sans-serif; margin-top: 30px; }\n        .running-container h2 { font-size: 42px; font-weight: 700; line-height: 1.1; }\n        .seccion { border: 1px solid #eee; padding: 20px; margin-top: 20px; border-radius: 8px; background: #fafafa; }\n        .form-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 10px; }\n        \n        .table-container { width: 100%; overflow-x: auto; margin-top: 20px; -webkit-overflow-scrolling: touch; }\n        .running-table { width: 100%; border-collapse: collapse; border: 2px solid #F89238; min-width: 500px; }\n        .running-table th { background: #F89238; color: #ffffff !important; font-family: 'Oswald', sans-serif; text-transform: uppercase; padding: 10px; text-align: center; font-size: 14px; }\n        .running-table td { border: 1px solid #F89238; padding: 8px; text-align: center; background: #fff; font-size: 13px; }\n        \n        .running-container input, .running-container select, .running-container button { padding: 10px; border-radius: 4px; border: 1px solid #ccc; }\n        .running-container button { background: #F89238; color: white; border: none; cursor: pointer; font-weight: bold; }\n        \n        #filtroCarrera, #filtroGenero { font-family: 'Oswald'; font-size: 20px; font-weight: bold; height: 50px; border: 2px solid #F89238; border-radius: 8px; padding: 0 10px; }\n        #selectPublico { width: 100%; max-width: 100%; height: 50px; font-size: 16px; padding: 5px 10px; }\n        \n        .mejor-marca-row td { background: #ffe4b5 !important; font-weight: bold; color: #d35400 !important; border: 2px solid #F89238 !important; }\n        .nombre-ranking { color: #F89238; text-decoration: underline; cursor: pointer; font-weight: bold; }\n        \n        .modal { display: none; position: fixed; z-index: 999999; left: 0; top: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); overflow-y: auto; }\n        .modal-content { background: #fff; margin: 160px auto 100px auto; padding: 20px; border-radius: 8px; width: 95%; max-width: 900px; position: relative; }\n        .close { position: absolute; right: 20px; top: 10px; font-size: 40px; cursor: pointer; }\n        \n        .pagination-container { margin-top: 15px; text-align: center; display: flex; justify-content: center; gap: 10px; align-items: center; }\n        .btn-export { background: #F89238 !important; margin-top: 15px; padding: 12px 25px !important; font-size: 16px; width: 100%; }\n        .btn-share { background: #F89238 !important; margin-top: 10px; }\n        .input-date-active { border: 3px solid #F89238 !important; background-color: #fff5eb !important; }\n\n        @media screen and (max-width: 600px) {\n            .running-container h2 { font-size: 32px; }\n            .running-container h3 { font-size: 20px; }\n            .form-row { flex-direction: column; align-items: stretch; }\n            .form-row input, .form-row select { width: 100% !important; }\n            #filtroFechaPublico { width: 100% !important; min-height: 45px; display: block !important; visibility: visible !important; }\n            .running-table th, .running-table td { padding: 6px; font-size: 12px; }\n        }\n\n        @media print {\n            header, footer, nav, aside, .header, .footer, .sidebar, .menu, #header, #footer, img, .logo, .wp-admin-bar { display: none !important; }\n            #adminPanel, h2, .form-row, #pagination, .seccion > h3, .seccion > p, #btnImprimir, #btnExportarFiltrado, #tablaRankingPrincipal, #seccionFiltroFecha, .btn-share, .close, .modal { display: none !important; }\n            body, html { visibility: hidden; height: auto; margin: 0 !important; background: #fff !important; }\n            .running-container { visibility: visible; position: absolute; left: 0; top: 0; width: 100% !important; }\n            .seccion { border: none !important; background: none !important; padding: 0 !important; }\n            #areaImpresion { display: block !important; visibility: visible !important; width: 100% !important; }\n            #tablaPublica { display: table !important; width: 100% !important; border: 1px solid #333 !important; }\n            #tituloPublico { display: block !important; visibility: visible !important; text-align: center; font-size: 20pt; color: #000 !important; }\n            @page { size: auto; margin: 1.5cm; }\n        }\n    <\/style>\n\n    <div class=\"running-container\">\n        \n        <h2>Marcas Personales<\/h2>\n        <div class=\"form-row\">\n            <select id=\"filtroCarrera\" onchange=\"resetPaginaYRender()\"><\/select>\n            <select id=\"filtroGenero\" onchange=\"resetPaginaYRender()\">\n                <option value=\"all\">Todo (Todos los corredores)<\/option>\n                <option value=\"M\">Masculino (Top 10)<\/option>\n                <option value=\"F\">Femenino (Top 10)<\/option>\n            <\/select>\n        <\/div>\n        <div class=\"table-container\">\n            <table class=\"running-table\" id=\"tablaRankingPrincipal\">\n                <thead>\n                    <tr><th>#<\/th><th>Nombre<\/th><th id=\"colDinamica\">Tiempo<\/th><th>Fecha<\/th><\/tr>\n                <\/thead>\n                <tbody id=\"rankingBody\"><\/tbody>\n            <\/table>\n        <\/div>\n        <div id=\"pagination\" class=\"pagination-container\"><\/div>\n\n        <div class=\"seccion\" style=\"background: #fff; border: 2px solid #F89238;\">\n            <h3>Buscar marcas e Historial<\/h3>\n            <div class=\"form-row\">\n                <select id=\"selectPublico\" onchange=\"verHistorialPublico()\">\n                    <option value=\"\">-- Selecciona el corredor --<\/option>\n                <\/select>\n            <\/div>\n\n            <div id=\"seccionFiltroFecha\" style=\"margin-top:20px; border-top: 1px solid #eee; padding-top: 20px;\">\n                <p style=\"font-weight: bold;\">Ver resultados de una fecha con carreras:<\/p>\n                <div class=\"form-row\">\n                    <input type=\"date\" id=\"filtroFechaPublico\" onchange=\"verResultadosPorFecha()\" value=\"2026-06-13\">\n                    <span id=\"msgFecha\" style=\"font-size: 0.85em; color: #F89238; font-weight: bold;\"><\/span>\n                <\/div>\n            <\/div>\n            \n            <div id=\"areaImpresion\">\n                <h4 id=\"tituloPublico\"><\/h4>\n                <div class=\"table-container\">\n                    <table class=\"running-table\" id=\"tablaPublica\" style=\"display:none;\">\n                        <thead>\n                            <tr><th>Corredor \/ Fecha<\/th><th>Carrera<\/th><th>Marca<\/th><th>Ritmo<\/th><th>Notas<\/th><\/tr>\n                        <\/thead>\n                        <tbody id=\"historialBodyPublico\"><\/tbody>\n                    <\/table>\n                <\/div>\n            <\/div>\n            <div class=\"form-row\">\n                <button id=\"btnImprimir\" class=\"btn-export\" style=\"display:none;\" onclick=\"window.print()\">\ud83d\udda8\ufe0f Imprimir \/ Exportar PDF<\/button>\n                                <button id=\"btnCompartir\" class=\"btn-export btn-share\" style=\"display:none;\" onclick=\"generarEnlaceCompartir()\">\ud83d\udd17 Copiar enlace<\/button>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div id=\"modalGrafico\" class=\"modal\">\n        <div class=\"modal-content\">\n            <span class=\"close\" onclick=\"cerrarModal()\">&times;<\/span>\n            <h3 id=\"tituloGrafico\" style=\"text-align:center;\"><\/h3>\n            <div style=\"height: 300px;\"><canvas id=\"canvasGrafico\"><\/canvas><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    const ajaxurl = \"https:\/\/legroup.es\/zonacorredores\/wp-admin\/admin-ajax.php\";\n    let resultados = [], corredores = [], generos = {}, chartInstance = null, currentPage = 1;\n    const resultsPerPage = 10, carreras = [\"1000m\",\"1500m\",\"2000m\",\"3000m\",\"5k\",\"10k\",\"15k\",\"20k\",\"Media Marat\u00f3n\",\"25k\",\"30k\",\"Marat\u00f3n\",\"50k\",\"100k\",\"101k Ronda\",\"6 horas\",\"12 horas\",\"24 horas\",\"Spartathlon\"], carrerasTiempo = [\"6 horas\", \"12 horas\", \"24 horas\"];\n\n    document.addEventListener(\"DOMContentLoaded\", () => {\n        const fc = document.getElementById('filtroCarrera'), cs = document.getElementById('carreraSelect');\n        carreras.forEach(c => { if(fc) fc.innerHTML += `<option value=\"${c}\">${c}<\/option>`; if(cs) cs.innerHTML += `<option value=\"${c}\">${c}<\/option>`; });\n        fetchData().then(() => {\n            const urlParams = new URLSearchParams(window.location.search);\n            const dateParam = urlParams.get('run_date');\n            if (dateParam) {\n                document.getElementById('filtroFechaPublico').value = dateParam;\n                verResultadosPorFecha();\n            }\n        });\n    });\n\n    async function fetchData() {\n        const response = await fetch(`${ajaxurl}?action=get_running_data`);\n        const data = await response.json();\n        resultados = data.resultados || [];\n        corredores = [...new Set(data.corredores || [])];\n        generos = data.generos || {};\n        actualizarSelects();\n        renderRanking();\n        marcarFechasConDatos();\n    }\n\n    function exportarDatosFiltrados() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        const corredor = document.getElementById('selectPublico').value;\n        let datosAExportar = [];\n\n        if (fecha && !corredor) {\n            datosAExportar = resultados.filter(r => r.fecha === fecha);\n        } else if (corredor) {\n            datosAExportar = resultados.filter(r => r.nombre === corredor);\n        }\n\n        if (datosAExportar.length === 0) return alert(\"No hay datos cargados en esta vista para exportar.\");\n\n        let csvContent = \"data:text\/csv;charset=utf-8,Nombre,Genero,Carrera,Fecha,Tiempo,Notas\\n\";\n        datosAExportar.forEach(r => {\n            csvContent += `\"${r.nombre}\",\"${r.genero}\",\"${r.carrera}\",\"${r.fecha}\",\"${r.tiempo}\",\"${(r.notas || '').replace(\/\"\/g, '\"\"')}\"\\n`;\n        });\n\n        const fileName = fecha ? `resultados_${fecha}.csv` : `historial_${corredor}.csv`;\n        const encodedUri = encodeURI(csvContent);\n        const link = document.createElement(\"a\");\n        link.setAttribute(\"href\", encodedUri);\n        link.setAttribute(\"download\", fileName);\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n    }\n\n    function importarExcel(event) {\n        const file = event.target.files[0];\n        if (!file) return;\n        const reader = new FileReader();\n        reader.onload = async function(e) {\n            const content = e.target.result;\n            const rows = content.split(\/\\r?\\n\/).slice(1);\n            let nuevos = 0;\n            \n            for(let row of rows) {\n                if(!row.trim()) continue;\n                let separator = row.includes(\";\") ? \";\" : \",\";\n                let cols = row.split(separator).map(c => c.replace(\/\"\/g, '').trim());\n                \n                if (cols && cols.length >= 5) {\n                    let r = {\n                        nombre: cols[0],\n                        genero: cols[1],\n                        carrera: cols[2],\n                        fecha: cols[3],\n                        tiempo: cols[4],\n                        notas: cols[5] || ''\n                    };\n                    \n                    if(!r.nombre || r.nombre.toLowerCase() === 'nombre') continue;\n                    \n                    const p = new URLSearchParams();\n                    p.append('action', 'save_running_result');\n                    p.append('nombre', r.nombre); \n                    p.append('genero', r.genero);\n                    p.append('carrera', r.carrera); \n                    p.append('fecha', r.fecha);\n                    p.append('tiempo', r.tiempo); \n                    p.append('notas', r.notas);\n\n                    const res = await fetch(ajaxurl, { method: 'POST', body: p });\n                    const status = await res.json();\n                    if(status.success && status.data.new) nuevos++;\n                }\n            }\n            alert(`Proceso completado. Se han a\u00f1adido ${nuevos} registros nuevos. Los duplicados fueron ignorados.`);\n            fetchData();\n        };\n        reader.readAsText(file);\n    }\n\n    function formatFechaES(f) { if(!f) return \"\"; const p = f.split('-'); return `${p[2]}\/${p[1]}\/${p[0]}`; }\n    function formatSegundosAHis(s) { if(isNaN(s)) return \"00:00:00\"; const h = Math.floor(s\/3600), m = Math.floor((s%3600)\/60), sec = Math.floor(s%60); return `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${sec.toString().padStart(2,'0')}`; }\n    function resetPaginaYRender() { currentPage = 1; renderRanking(); }\n    function tiempoSegundos(t) { if(!t || typeof t !== 'string') return 0; if(t.includes(\":\")) { let p = t.split(\":\").map(Number); return (p[0]*3600)+(p[1]*60)+p[2]; } return parseFloat(t) || 0; }\n\n    function ritmo(c, t) {\n        if(carrerasTiempo.includes(c)) return \"-\";\n        const dists = {\"1000m\":1,\"2000m\":2,\"3000m\":3,\"5k\":5,\"10k\":10,\"15k\":15,\"20k\":20,\"Media Marat\u00f3n\":21.097,\"25k\":25,\"30k\":30,\"Marat\u00f3n\":42.195,\"50k\":50,\"100k\":100,\"101k Ronda\":101,\"Spartathlon\":246};\n        let km = dists[c] || 0; if(km === 0) return \"-\";\n        let segTotales = tiempoSegundos(t) \/ km;\n        let mins = Math.floor(segTotales \/ 60), segs = Math.floor(segTotales % 60);\n        return `${mins}:${segs.toString().padStart(2,\"0\")}`;\n    }\n\n    function esMejorMarca(corredor, carrera, tiempo) {\n        let isKm = carrerasTiempo.includes(carrera);\n        let marcas = resultados.filter(r => r.nombre === corredor && r.carrera === carrera);\n        let val = tiempoSegundos(tiempo);\n        return isKm ? !marcas.some(m => tiempoSegundos(m.tiempo) > val) : !marcas.some(m => tiempoSegundos(m.tiempo) < val);\n    }\n\n    function renderRanking() {\n        const c = document.getElementById('filtroCarrera').value, g = document.getElementById('filtroGenero').value, isKm = carrerasTiempo.includes(c);\n        document.getElementById('colDinamica').innerText = isKm ? \"Kil\u00f3metros\" : \"Tiempo\";\n        let filtered = resultados.filter(r => r.carrera === c);\n        if(g !== 'all') filtered = filtered.filter(r => r.genero === g);\n        let bests = {};\n        filtered.forEach(r => { let v = tiempoSegundos(r.tiempo); if(!bests[r.nombre] || (isKm ? v > tiempoSegundos(bests[r.nombre].tiempo) : v < tiempoSegundos(bests[r.nombre].tiempo))) bests[r.nombre] = r; });\n        let sorted = Object.values(bests).sort((a,b) => isKm ? tiempoSegundos(b.tiempo) - tiempoSegundos(a.tiempo) : tiempoSegundos(a.tiempo) - tiempoSegundos(b.tiempo));\n        let finalDisplay = [];\n        const paginationDiv = document.getElementById('pagination');\n        if (g === 'all') {\n            const totalPages = Math.ceil(sorted.length \/ resultsPerPage);\n            finalDisplay = sorted.slice((currentPage - 1) * resultsPerPage, currentPage * resultsPerPage);\n            paginationDiv.innerHTML = `<button onclick=\"changePage(-1)\" ${currentPage===1?'disabled':''}>Anterior<\/button><span>P\u00e1gina ${currentPage} de ${totalPages || 1}<\/span><button onclick=\"changePage(1)\" ${currentPage===totalPages || totalPages===0?'disabled':''}>Siguiente<\/button>`;\n        } else { finalDisplay = sorted.slice(0, 10); paginationDiv.innerHTML = \"\"; }\n        document.getElementById('rankingBody').innerHTML = finalDisplay.map((r,i) => {\n            const index = g === 'all' ? ((currentPage - 1) * resultsPerPage) + i + 1 : i + 1;\n            return `<tr><td>${index}<\/td><td class=\"nombre-ranking\" onclick=\"abrirGrafico('${r.nombre}')\">${r.nombre}<\/td><td>${isKm ? parseFloat(r.tiempo).toFixed(3)+' km' : r.tiempo}<\/td><td>${formatFechaES(r.fecha)}<\/td><\/tr>`;\n        }).join('');\n    }\n\n    function changePage(step) { currentPage += step; renderRanking(); }\n\n    function verHistorialPublico() {\n        const n = document.getElementById('selectPublico').value, body = document.getElementById('historialBodyPublico');\n        if(!n) return;\n        document.getElementById('filtroFechaPublico').value = \"\";\n        document.getElementById('tablaPublica').style.display = \"table\";\n        document.getElementById('btnImprimir').style.display = \"block\";\n        if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"block\";\n        document.getElementById('btnCompartir').style.display = \"none\";\n        document.getElementById('tituloPublico').innerText = \"Historial: \" + n;\n        let susRes = resultados.filter(r => r.nombre === n).sort((a,b) => new Date(b.fecha) - new Date(a.fecha));\n        body.innerHTML = susRes.map(r => `<tr class=\"${esMejorMarca(r.nombre, r.carrera, r.tiempo) ? 'mejor-marca-row' : ''}\"><td>${formatFechaES(r.fecha)}<\/td><td>${r.carrera}<\/td><td>${r.tiempo}<\/td><td>${ritmo(r.carrera, r.tiempo)}<\/td><td>${r.notas || ''}<\/td><\/tr>`).join('');\n    }\n\n    function verResultadosPorFecha() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        const body = document.getElementById('historialBodyPublico');\n        if(!fecha) return;\n        document.getElementById('selectPublico').value = \"\";\n        document.getElementById('tablaPublica').style.display = \"table\";\n        document.getElementById('btnImprimir').style.display = \"block\";\n        if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"block\";\n        document.getElementById('btnCompartir').style.display = \"block\";\n        document.getElementById('tituloPublico').innerText = \"Resultados del: \" + formatFechaES(fecha);\n        let diaRes = resultados.filter(r => r.fecha === fecha).sort((a,b) => a.nombre.localeCompare(b.nombre));\n        if(diaRes.length === 0) {\n            body.innerHTML = '<tr><td colspan=\"5\">Sin registros.<\/td><\/tr>';\n            document.getElementById('btnCompartir').style.display = \"none\";\n            if(document.getElementById('btnExportarFiltrado')) document.getElementById('btnExportarFiltrado').style.display = \"none\";\n            return;\n        }\n        body.innerHTML = diaRes.map(r => `<tr class=\"${esMejorMarca(r.nombre, r.carrera, r.tiempo) ? 'mejor-marca-row' : ''}\"><td>${r.nombre}<\/td><td>${r.carrera}<\/td><td>${r.tiempo}<\/td><td>${ritmo(r.carrera, r.tiempo)}<\/td><td>${r.notas || ''}<\/td><\/tr>`).join('');\n    }\n\n    function marcarFechasConDatos() {\n        const fechasSet = [...new Set(resultados.map(r => r.fecha))];\n        const inputFecha = document.getElementById('filtroFechaPublico');\n        if(fechasSet.length > 0) {\n            inputFecha.classList.add('input-date-active');\n            document.getElementById('msgFecha').innerText = \"\";\n        }\n    }\n\n    function generarEnlaceCompartir() {\n        const fecha = document.getElementById('filtroFechaPublico').value;\n        if(!fecha) return;\n        const baseUrl = window.location.href.split('?')[0];\n        const shareUrl = `${baseUrl}?run_date=${fecha}`;\n        navigator.clipboard.writeText(shareUrl).then(() => { alert(\"\u00a1Enlace copiado!\"); });\n    }\n\n    function handleSearch(e, sid, isAdminHist = false) {\n        const filter = e.target.value.toLowerCase(), select = document.getElementById(sid), options = Array.from(select.options);\n        let match = null, count = 0;\n        options.forEach(o => {\n            const isM = o.text.toLowerCase().includes(filter);\n            o.style.display = isM ? \"\" : \"none\";\n            if(isM && o.value !== \"\") { match = o.value; count++; }\n        });\n        if(e.key === \"Enter\" && count === 1) { select.value = match; if(isAdminHist) verHistorialAdmin(); e.target.value = \"\"; }\n    }\n\n    function abrirGrafico(nombre) {\n        document.getElementById('modalGrafico').style.display = \"block\";\n        const cSel = document.getElementById('filtroCarrera').value;\n        const isKmCarrera = carrerasTiempo.includes(cSel);\n        document.getElementById('tituloGrafico').innerText = `Evoluci\u00f3n ${nombre} (${cSel})`;\n        \n        let data = resultados.filter(r => r.nombre === nombre && r.carrera === cSel).sort((a,b) => new Date(a.fecha) - new Date(b.fecha));\n        if(chartInstance) chartInstance.destroy();\n        \n        chartInstance = new Chart(document.getElementById('canvasGrafico'), {\n            type: 'line', \n            data: { datasets: [{ label: cSel, data: data.map(r => ({x: r.fecha, y: tiempoSegundos(r.tiempo), realVal: r.tiempo})), borderColor: '#F89238', tension: 0.1, fill: false, borderWidth: 3, pointRadius: 5 }] },\n            options: { \n                responsive: true, \n                maintainAspectRatio: false, \n                scales: { \n                    y: { \n                        ticks: { \n                            callback: function(v) {\n                                return isKmCarrera ? v + \" km\" : formatSegundosAHis(v);\n                            }\n                        } \n                    } \n                },\n                plugins: {\n                    tooltip: {\n                        callbacks: {\n                            label: function(context) {\n                                let label = context.dataset.label || '';\n                                let val = context.raw.realVal;\n                                return label + ': ' + val + (isKmCarrera ? ' km' : '');\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    function verHistorialAdmin() {\n        const n = document.getElementById('histCorredor').value, body = document.getElementById('historialBodyAdmin');\n        if(!n) return;\n        let susRes = resultados.filter(r => r.nombre === n).sort((a,b) => new Date(b.fecha) - new Date(a.fecha));\n        body.innerHTML = susRes.map(r => `<tr>\n            <td><input value=\"${r.nombre}\" id=\"name-${r.id}\" style=\"width:120px;\"><\/td>\n            <td><input type=\"date\" value=\"${r.fecha}\" id=\"f-${r.id}\"><\/td>\n            <td><select id=\"c-${r.id}\">${carreras.map(c => `<option value=\"${c}\" ${r.carrera === c ? 'selected' : ''}>${c}<\/option>`).join('')}<\/select><\/td>\n            <td><input value=\"${r.tiempo}\" id=\"t-${r.id}\" style=\"width:80px;\"><\/td>\n            <td><input value=\"${r.notas || ''}\" id=\"n-${r.id}\" style=\"width:150px;\"><\/td>\n            <td><button onclick=\"actualizarRegistro(${r.id})\">Modificar<\/button><button onclick=\"borrarRegistro(${r.id})\" style=\"background:red; margin-left:5px;\">\ud83d\uddd1\ufe0f<\/button><\/td><\/tr>`).join('');\n    }\n\n    function actualizarSelects() {\n        ['nombreSelect', 'histCorredor', 'selectPublico'].forEach(id => {\n            const s = document.getElementById(id);\n            if(s) { \n                const v = s.value; \n                s.innerHTML = `<option value=\"\">-- Selecciona el corredor --<\/option>` + corredores.sort().map(c => `<option value=\"${c}\">${c}<\/option>`).join(''); \n                if(v) s.value = v; \n            }\n        });\n    }\n\n    function adaptarInputCarga() { const c = document.getElementById('carreraSelect').value; document.getElementById('tiempo').placeholder = carrerasTiempo.includes(c) ? \"Km\" : \"hhmmss\"; }\n    function procesarEntRef() {\n        const c = document.getElementById('carreraSelect').value, t = document.getElementById('tiempo'); if(!t.value) return;\n        if(carrerasTiempo.includes(c)) { let v = parseFloat(t.value); if(!isNaN(v)) t.value = v.toFixed(3); }\n        else { let v = t.value.replace(\/\\D\/g, \"\").padStart(6, \"0\").slice(-6); t.value = `${v.slice(0,2)}:${v.slice(2,4)}:${v.slice(4,6)}`; }\n    }\n    async function agregarCorredor() {\n        const n = document.getElementById('nuevoCorredor').value.trim(); if(!n) return;\n        const p = new URLSearchParams(); p.append('action', 'add_running_corredor'); p.append('nombre', n); p.append('genero', document.getElementById('genero').value);\n        await fetch(ajaxurl, { method: 'POST', body: p }); document.getElementById('nuevoCorredor').value = \"\"; fetchData();\n    }\n    async function guardarResultado() {\n        const n = document.getElementById('nombreSelect').value; if(!n) return alert(\"Selecciona corredor\");\n        const p = new URLSearchParams(); p.append('action', 'save_running_result');\n        p.append('nombre', n); p.append('carrera', document.getElementById('carreraSelect').value);\n        p.append('fecha', document.getElementById('fecha').value); p.append('tiempo', document.getElementById('tiempo').value);\n        p.append('genero', generos[n] || 'M'); p.append('notas', document.getElementById('notasInput').value);\n        await fetch(ajaxurl, { method: 'POST', body: p });\n        fetchData();\n    }\n    async function actualizarRegistro(id) {\n        const p = new URLSearchParams(); p.append('action', 'update_running_result'); p.append('id', id);\n        p.append('nombre', document.getElementById(`name-${id}`).value);\n        p.append('fecha', document.getElementById(`f-${id}`).value); \n        p.append('carrera', document.getElementById(`c-${id}`).value);\n        p.append('tiempo', document.getElementById(`t-${id}`).value);\n        p.append('notas', document.getElementById(`n-${id}`).value);\n        await fetch(ajaxurl, { method: 'POST', body: p }); \n        fetchData().then(() => verHistorialAdmin());\n    }\n    async function borrarRegistro(id) { if(confirm(\"\u00bfEliminar?\")) { const p = new URLSearchParams(); p.append('action', 'delete_running_result'); p.append('id', id); await fetch(ajaxurl, { method: 'POST', body: p }); fetchData().then(() => verHistorialAdmin()); } }\n    async function borrarCorredorCompleto() {\n        const n = document.getElementById('histCorredor').value; if(!n || !confirm(`\u26a0\ufe0f ELIMINAR TODO DE ${n}`)) return;\n        const p = new URLSearchParams(); p.append('action', 'delete_full_runner'); p.append('nombre', n);\n        await fetch(ajaxurl, { method: 'POST', body: p }); fetchData();\n    }\n    function cerrarModal() { document.getElementById('modalGrafico').style.display = \"none\"; }\n    <\/script>\n    \n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-342793","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/pages\/342793","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/comments?post=342793"}],"version-history":[{"count":81,"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/pages\/342793\/revisions"}],"predecessor-version":[{"id":342956,"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/pages\/342793\/revisions\/342956"}],"wp:attachment":[{"href":"https:\/\/legroup.es\/zonacorredores\/wp-json\/wp\/v2\/media?parent=342793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}