		<div data-elementor-type="wp-page" data-elementor-id="300" class="elementor elementor-300" data-elementor-post-type="page">
				{"id":300,"date":"2026-05-31T17:24:52","date_gmt":"2026-05-31T21:24:52","guid":{"rendered":"https:\/\/www.jose.tumarcaagencia.com\/?page_id=300"},"modified":"2026-05-31T17:26:11","modified_gmt":"2026-05-31T21:26:11","slug":"traduccion-y-pronunciacion","status":"publish","type":"page","link":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/traduccion-y-pronunciacion\/","title":{"rendered":"Traducci\u00f3n y Pronunciaci\u00f3n"},"content":{"rendered":"<div class=\"elementor-element elementor-element-42ff1c2 e-flex e-con-boxed e-con e-parent\" data-id=\"42ff1c2\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b24fdff elementor-widget elementor-widget-shortcode\" data-id=\"b24fdff\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t    <style>\n        .app-container {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            background: linear-gradient(135deg, #e0f2fe 0%, #f3e8ff 100%);\n            border-radius: 20px;\n            padding: 30px;\n            max-width: 550px;\n            margin: 20px auto;\n            box-shadow: 0 10px 25px rgba(0,0,0,0.05);\n            text-align: center;\n            border: 1px solid rgba(255,255,255,0.6);\n        }\n        .app-title {\n            color: #4338ca;\n            font-size: 24px;\n            margin-bottom: 20px;\n            font-weight: 700;\n        }\n        .input-group {\n            margin-bottom: 20px;\n        }\n        .app-input {\n            width: 100%;\n            padding: 12px 15px;\n            border: 2px solid #cbd5e1;\n            border-radius: 12px;\n            font-size: 16px;\n            outline: none;\n            transition: all 0.3s ease;\n            box-sizing: border-box;\n        }\n        .app-input:focus {\n            border-color: #a78bfa;\n            box-shadow: 0 0 10px rgba(167, 139, 250, 0.2);\n        }\n        .btn-primary {\n            background-color: #86efac;\n            color: #1e3a1e;\n            border: none;\n            padding: 12px 25px;\n            border-radius: 12px;\n            font-size: 16px;\n            font-weight: bold;\n            cursor: pointer;\n            transition: transform 0.2s, background-color 0.3s;\n            box-shadow: 0 4px 6px rgba(0,0,0,0.05);\n        }\n        .btn-primary:hover {\n            background-color: #4ade80;\n            transform: translateY(-2px);\n        }\n        .result-card {\n            background: white;\n            border-radius: 16px;\n            padding: 20px;\n            margin-top: 25px;\n            display: none;\n            box-shadow: 0 4px 15px rgba(0,0,0,0.02);\n            animation: fadeIn 0.5s ease-out;\n        }\n        .translation-text {\n            font-size: 20px;\n            color: #1e1b4b;\n            font-weight: 600;\n            margin-bottom: 15px;\n        }\n        .action-buttons {\n            display: flex;\n            justify-content: center;\n            gap: 20px;\n            margin-top: 15px;\n        }\n        .btn-circle {\n            width: 55px;\n            height: 55px;\n            border-radius: 50%;\n            border: none;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 22px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            box-shadow: 0 4px 10px rgba(0,0,0,0.08);\n        }\n        .btn-listen {\n            background-color: #bae6fd;\n            color: #0369a1;\n        }\n        .btn-listen:hover { background-color: #7dd3fc; transform: scale(1.08); }\n        .btn-mic {\n            background-color: #fbcfe8;\n            color: #be185d;\n        }\n        .btn-mic:hover { background-color: #f9a8d4; transform: scale(1.08); }\n        .btn-mic.recording {\n            background-color: #ef4444;\n            color: white;\n            animation: pulse 1.2s infinite;\n        }\n        .status-text {\n            font-size: 14px;\n            color: #64748b;\n            margin-top: 10px;\n            font-style: italic;\n        }\n        .score-box {\n            margin-top: 20px;\n            padding: 15px;\n            border-radius: 12px;\n            font-size: 18px;\n            font-weight: bold;\n            display: none;\n            animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n        }\n        .score-good { background-color: #dcfce7; color: #166534; }\n        .score-regular { background-color: #fef9c3; color: #854d0e; }\n        .score-bad { background-color: #fee2e2; color: #991b1b; }\n\n        \/* Animaciones *\/\n        @keyframes fadeIn {\n            from { opacity: 0; transform: translateY(10px); }\n            to { opacity: 1; transform: translateY(0); }\n        }\n        @keyframes popIn {\n            0% { transform: scale(0.8); opacity: 0; }\n            100% { transform: scale(1); opacity: 1; }\n        }\n        @keyframes pulse {\n            0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5); }\n            70% { transform: scale(1.05); box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }\n            100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }\n        }\n    <\/style>\n\n    <div class=\"app-container\">\n        <div class=\"app-title\">\ud83d\udde3\ufe0f Traductor & Evaluador de Pronunciaci\u00f3n<\/div>\n        \n        <div class=\"input-group\">\n            <input type=\"text\" id=\"txtInput\" class=\"app-input\" placeholder=\"Escribe una palabra o frase en espa\u00f1ol...\">\n        <\/div>\n        <button id=\"btnTraducir\" class=\"btn-primary\">Traducir \u2728<\/button>\n\n        <div id=\"resultCard\" class=\"result-card\">\n            <div class=\"status-text\" style=\"margin-bottom:5px; font-weight:bold;\">Traducci\u00f3n al Ingl\u00e9s:<\/div>\n            <div id=\"txtTraducido\" class=\"translation-text\">...<\/div>\n            \n            <div class=\"action-buttons\">\n                <button id=\"btnEscuchar\" class=\"btn-circle btn-listen\" title=\"Escuchar pronunciaci\u00f3n nativa\">\ud83d\udd0a<\/button>\n                <button id=\"btnGrabar\" class=\"btn-circle btn-mic\" title=\"Presiona para pronunciar\">\ud83c\udf99\ufe0f<\/button>\n            <\/div>\n            \n            <div id=\"statusSpeech\" class=\"status-text\"><\/div>\n            <div id=\"txtEscuchado\" class=\"status-text\" style=\"color:#475569; font-weight: 500;\"><\/div>\n            \n            <div id=\"scoreBox\" class=\"score-box\"><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    document.addEventListener('DOMContentLoaded', function() {\n        const btnTraducir = document.getElementById('btnTraducir');\n        const txtInput = document.getElementById('txtInput');\n        const resultCard = document.getElementById('resultCard');\n        const txtTraducido = document.getElementById('txtTraducido');\n        const btnEscuchar = document.getElementById('btnEscuchar');\n        const btnGrabar = document.getElementById('btnGrabar');\n        const statusSpeech = document.getElementById('statusSpeech');\n        const txtEscuchado = document.getElementById('txtEscuchado');\n        const scoreBox = document.getElementById('scoreBox');\n\n        let traduccionCorrecta = \"\";\n\n        \/\/ 1. FUNCI\u00d3N TRADUCIR\n        btnTraducir.addEventListener('click', async function() {\n            const texto = txtInput.value.trim();\n            if(!texto) {\n                alert(\"Por favor, ingresa un texto para traducir.\");\n                return;\n            }\n\n            btnTraducir.innerText = \"Traduciendo... \u23f3\";\n            scoreBox.style.display = \"none\";\n            txtEscuchado.innerText = \"\";\n            statusSpeech.innerText = \"\";\n\n            try {\n                \/\/ Usamos la API p\u00fablica y gratuita MyMemory\n                const url = `https:\/\/api.mymemory.translated.net\/get?q=${encodeURIComponent(texto)}&langpair=es|en`;\n                const response = await fetch(url);\n                const data = await response.json();\n                \n                if(data.responseData) {\n                    traduccionCorrecta = data.responseData.translatedText;\n                    txtTraducido.innerText = traduccionCorrecta;\n                    resultCard.style.display = \"block\";\n                } else {\n                    alert(\"No se pudo obtener la traducci\u00f3n. Intenta de nuevo.\");\n                }\n            } catch (error) {\n                console.error(error);\n                alert(\"Ocurri\u00f3 un error en la conexi\u00f3n.\");\n            } finally {\n                btnTraducir.innerText = \"Traducir \u2728\";\n            }\n        });\n\n        \/\/ 2. FUNCI\u00d3N AUDIO (Texto a Voz Nativa)\n        btnEscuchar.addEventListener('click', function() {\n            if(!traduccionCorrecta) return;\n            \n            \/\/ Cancelar cualquier audio en curso\n            window.speechSynthesis.cancel();\n            \n            const utterance = new SpeechSynthesisUtterance(traduccionCorrecta);\n            utterance.lang = 'en-US'; \/\/ Idioma ingl\u00e9s nativo\n            utterance.rate = 0.9;     \/\/ Velocidad ligeramente pausada para aprender mejor\n            \n            window.speechSynthesis.speak(utterance);\n        });\n\n        \/\/ 3. FUNCI\u00d3N MICR\u00d3FONO (Reconocimiento de Voz)\n        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;\n        \n        if (!SpeechRecognition) {\n            statusSpeech.innerText = \"Tu navegador no soporta el reconocimiento de voz. Usa Google Chrome.\";\n            btnGrabar.style.display = \"none\";\n        } else {\n            const recognition = new SpeechRecognition();\n            recognition.lang = 'en-US'; \/\/ Esperamos que el usuario hable en ingl\u00e9s\n            recognition.interimResults = false;\n            recognition.maxAlternatives = 1;\n\n            btnGrabar.addEventListener('click', function() {\n                scoreBox.style.display = \"none\";\n                txtEscuchado.innerText = \"\";\n                recognition.start();\n            });\n\n            recognition.onstart = function() {\n                btnGrabar.classList.add('recording');\n                statusSpeech.innerText = \"\ud83c\udf99\ufe0f Escuchando... \u00a1Habla ahora!\";\n            };\n\n            recognition.onspeechend = function() {\n                btnGrabar.classList.remove('recording');\n                statusSpeech.innerText = \"Procesando audio... \ud83d\udd04\";\n                recognition.stop();\n            };\n\n            recognition.onerror = function(event) {\n                btnGrabar.classList.remove('recording');\n                statusSpeech.innerText = \"Error al reconocer la voz: \" + event.error;\n            };\n\n            recognition.onresult = function(event) {\n                const textoClaro = event.results[0][0].transcript;\n                txtEscuchado.innerText = `Dijiste: \"${textoClaro}\"`;\n                \n                \/\/ Evaluar la pronunciaci\u00f3n\n                calificarPronunciacion(textoClaro, traduccionCorrecta);\n            };\n        }\n\n        \/\/ 4. ALGORITMO DE CALIFICACI\u00d3N (1 al 10)\n        function calificarPronunciacion(dicho, correcto) {\n            \/\/ Limpiar textos (quitar puntos, comas y pasar a min\u00fasculas)\n            const limpiar = t => t.toLowerCase().replace(\/[.,\\\/#!$%\\^&\\*;:{}=\\-_`~()?]\/g,\"\").trim();\n            \n            const tDicho = limpiar(dicho);\n            const tCorrecto = limpiar(correcto);\n\n            \/\/ Calcular distancia Levenshtein (similitud de cadenas)\n            const distancia = levenshtein(tDicho, tCorrecto);\n            const maxLen = Math.max(tDicho.length, tCorrecto.length);\n            \n            let porcentajeSimilitud = 0;\n            if (maxLen > 0) {\n                porcentajeSimilitud = ((maxLen - distancia) \/ maxLen);\n            }\n\n            \/\/ Convertir a escala de 1 a 10\n            let nota = Math.round(porcentajeSimilitud * 10);\n            if(nota < 1) nota = 1; \/\/ Nota m\u00ednima de 1\n\n            \/\/ Mostrar el resultado visualmente\n            scoreBox.style.display = \"block\";\n            scoreBox.className = \"score-box\"; \/\/ reset clases\n\n            if(nota >= 8) {\n                scoreBox.classList.add('score-good');\n                scoreBox.innerHTML = `\ud83c\udf1f \u00a1Excelente! Nota: <strong>${nota}\/10<\/strong>`;\n            } else if(nota >= 5) {\n                scoreBox.classList.add('score-regular');\n                scoreBox.innerHTML = `\ud83d\udc4d Bien, puedes mejorar. Nota: <strong>${nota}\/10<\/strong>`;\n            } else {\n                scoreBox.classList.add('score-bad');\n                scoreBox.innerHTML = `\u274c Int\u00e9ntalo de nuevo. Nota: <strong>${nota}\/10<\/strong>`;\n            }\n        }\n\n        \/\/ Funci\u00f3n matem\u00e1tica auxiliar para comparar texto\n        function levenshtein(a, b) {\n            const matrix = [];\n            for (let i = 0; i <= b.length; i++) matrix[i] = [i];\n            for (let j = 0; j <= a.length; j++) matrix[0][j] = j;\n            for (let i = 1; i <= b.length; i++) {\n                for (let j = 1; j <= a.length; j++) {\n                    if (b.charAt(i - 1) == a.charAt(j - 1)) {\n                        matrix[i][j] = matrix[i - 1][j - 1];\n                    } else {\n                        matrix[i][j] = Math.min(\n                            matrix[i - 1][j - 1] + 1,\n                            Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1)\n                        );\n                    }\n                }\n            }\n            return matrix[b.length][a.length];\n        }\n    });\n    <\/script>\n    \t\t<div class=\"elementor-shortcode\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-300","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/pages\/300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/comments?post=300"}],"version-history":[{"count":4,"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/pages\/300\/revisions"}],"predecessor-version":[{"id":304,"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/pages\/300\/revisions\/304"}],"wp:attachment":[{"href":"https:\/\/www.jose.tumarcaagencia.com\/index.php\/wp-json\/wp\/v2\/media?parent=300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}