TutorLoom
The learning platform for companies, colleges and training institutes. Free and open source, with an Enterprise edition.
Estudia chino y español con contexto. Minado de oraciones y repetición espaciada.
Translation pending
EducationJavaScript · CSSGitHub @ulisesorchani-ossOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗App web (PWA) para practicar chino mandarín y español: lecciones graduadas, exámenes (HSK, TOCFL, DELE), práctica diaria con SRS, lectura de clásicos con pinyin/tonos, evaluación de pronunciación por voz y síntesis de audio (TTS) vía Microsoft Edge neural voices.
Estado actual: app.js (el "cerebro" de la app) se modularizó — pasó de
9.451 líneas en un solo archivo a 4.116 líneas, con 11 módulos separados
por función (audio, diccionario, trazos, mazo de repaso, lectores, etc.). Ver
docs/historial-actualizaciones/ para el
detalle de cada versión.
| Archivo | Qué hace |
|---|---|
index.html | Estructura HTML + carga todos los scripts en el orden correcto |
app.js | Núcleo: estado, eventos, lógica de juego (checkAnswer/markWord), dropdowns de módulos, popup de vocabulario, PWA |
style.css | Estilos |
sw.js | Service worker — cachea todo para que la app funcione offline |
app.js (extraídos, cada uno una responsabilidad)| Archivo | Qué contiene |
|---|---|
audio-tts.js | Velocidad, elección de voz, pedido de TTS al servidor con su fallback, playAudio |
dict.js | Motor de búsqueda del diccionario (toque en una palabra → traducción) |
trazos.js | Escritor de trazos Hanzi Writer (orden de trazos, práctica, respuesta a mano) |
srs.js | Mazo de repaso espaciado (Leitner de 6 cajas) |
reader.js | Lector de texto libre (pegás texto y lo lee, con pinyin interlineal) |
karaoke.js | Resaltado de caracteres al ritmo del audio (lector/clásicos) |
classics-reader.js | Lector de los 9 clásicos chinos |
lessons-graduated.js | Quiz de lecciones graduadas HSK 3.0/TOCFL |
placement-test.js | Test de colocación HSK adaptativo |
minimal-pairs.js | Ejercicio de pares mínimos (discriminación tonal) |
data-embedded.js | Datos: oraciones de práctica y vocabulario embebido (ver Cómo agregar contenido nuevo) |
Todos son scripts clásicos (sin import/export) que se cargan en orden
desde index.html — mismas variables/funciones globales que antes, solo que
repartidas en archivos más chicos.
| Archivo | Qué es |
|---|---|
lessons.js, lessons-tocfl.js, lessons-extra.js, lessons-dele.js | Lecciones graduadas y textos largos |
classics.js | Los 9 clásicos chinos (texto original) |
dict-mini.js | Diccionario offline zh↔es |
data-embedded.js | Oraciones de práctica + vocabulario HSK/TOCFL |
data/ | Datos de exámenes en JSON (respaldo, poco usado — casi todo está embebido) |
| Archivo | Qué hace |
|---|---|
voice-evaluator.js, VoiceRecorder.js, pitch-analyzer.js, config.js | Evaluador de pronunciación (Whisper WASM local + análisis de tono) |
api/ | Endpoint serverless (Vercel, Python) para TTS (/api/tts) |
| Archivo | Qué es |
|---|---|
stats.js, onboarding.js, text-utils.js | Estadísticas, onboarding y utilidades de texto |
manifest.json, icons/ | PWA instalable |
README-Pronunciacion.md | Documentación viva del módulo de pronunciación |
docs/historial-actualizaciones/ | Notas de actualización de versiones anteriores (histórico, ya aplicadas) |
README-Pronunciacion.md.LEEME-* de versiones anteriores,
ya integrados en el código actual): ver
docs/historial-actualizaciones/.Ninguno de estos cambios toca app.js ni los demás módulos de lógica —
son archivos de puro contenido.
Archivo: lessons.js (o lessons-tocfl.js/lessons-extra.js/lessons-dele.js
según el examen). Cada entrada de window.LESSONS_DATA.lessons es un objeto:
{
id: 'mi-leccion-1', // único, requerido
title: 'En el mercado', // nombre completo
label: 'Mercado (corto)', // opcional: nombre corto en la Biblioteca
group: 'Vida diaria', // opcional: agrupa en la Biblioteca
module: 'Mercado', // TODO el módulo de oraciones es la lección
// — o en vez de "module" —
// ids: [101, 102, 103], // oraciones puntuales = una SECCIÓN
text_simp: '你好...(texto completo simplificado)',
text_trad: '你好...(texto completo tradicional, opcional)',
hsk: 2 // opcional: nivel HSK de una lectura graduada
}
Si todavía no tenés el texto listo, agregala con status: 'planned': aparece
en la Biblioteca como "· próximamente" (deshabilitada) hasta que la
completes.
___)Archivo: data-embedded.js → EMBEDDED_SENTENCES (módulo base "todas") o
EMBEDDED_MODULE_DATA['NombreDelMódulo'] (un módulo específico). Cada
entrada:
{
"id": 999,
"level": 1,
"module": "Saludos",
"spanish_full": "Hola, ¿cómo estás?",
"spanish_cloze": "___, ¿cómo estás?",
"spanish_answer": "Hola",
"chinese_simp_full": "你好,你好吗?",
"chinese_simp_cloze": "___,你好吗?",
"chinese_simp_answer": "你好",
"chinese_trad_full": "你好,你好嗎?",
"chinese_trad_cloze": "___,你好嗎?",
"chinese_trad_answer": "你好",
"pinyin": "Nǐ hǎo, nǐ hǎo ma?"
}
___ marca el hueco que hay que completar; *_full es la oración
completa y *_answer la respuesta esperada.
Archivo: data-embedded.js → EMBEDDED_MODULE_DATA['HSK3'] (o el nivel que
sea). Viaja como tupla compacta, no como objeto, para que el archivo pese
menos — se expande sola con expandWordCards() al abrir el módulo:
["爱", "愛", "ài", "Amar", ["Gustar"]]
// [simplificado, tradicional|null, pinyin, español, alternativas|null]
Si el tradicional es igual al simplificado, poné null en su lugar (ej.
["八", null, "bā", "Ocho", null]).
Archivo: classics.js. Cada entrada de window.CLASSIC_TEXTS[claveDelMódulo]:
"Clasicos-MiClasico": {
es: "Nombre en español", emoji: "📜", badge: "completo",
intro: "Una línea de descripción.",
blocks: [
{ n: "Capítulo 1", l: [
["原文en chino.", "Traducción al español."],
["Otra línea del bloque.", "Su traducción."]
] }
]
}
El tradicional se genera aparte (mapas T_LINE/T_TITLE horneados con
opencc) — no hace falta escribirlo a mano si solo estás agregando texto
nuevo con la traducción en es.
VERSION en sw.js (línea const VERSION = 'vNNN')
para que el service worker le avise a todos los dispositivos que hay
contenido nuevo — si no, quien ya tiene la app instalada puede seguir
viendo la versión vieja cacheada un tiempo.id de oración, no lo repitas con uno ya existente en el
mismo archivo.index.html.vercel.json + api/), Microsoft Edge neural
voices vía edge-tts.sw.js) versiona la caché de shell y de audios; al
subir cambios de cualquier .js/index.html/style.css/sw.js conviene
refresco forzado (Ctrl+Shift+R) para evitar ver la versión cacheada.pip install -r requirements.txt
python serve.py