Añadido Borel-Maisonny a lectura etapa 1-7, Decroly a etapa 8-9, Montessori a numeros etapa 1-8. Ahora 65/65 archivos con método europeo.
294 lines
10 KiB
TypeScript
294 lines
10 KiB
TypeScript
import type { Stage, Exercise } from '../types'
|
|
|
|
type Info = {
|
|
letra: string
|
|
palabra: string
|
|
emoji: string
|
|
gesto: string
|
|
silaba: string
|
|
palabraLower: string
|
|
}
|
|
|
|
const moduleA: Info[] = [
|
|
{ letra: 'A', palabra: 'ÁRBOL', emoji: '🌳', gesto: 'Abrí la mano como una boca grande', silaba: 'a', palabraLower: 'árbol' },
|
|
{ letra: 'E', palabra: 'ELEFANTE', emoji: '🐘', gesto: 'Estirá la mano como una trompa', silaba: 'e', palabraLower: 'elefante' },
|
|
{ letra: 'I', palabra: 'INDIO', emoji: '🪶', gesto: 'Señalá el cielo con el dedo', silaba: 'i', palabraLower: 'indio' },
|
|
{ letra: 'O', palabra: 'OJO', emoji: '👁️', gesto: 'Redondeá la mano como una O', silaba: 'o', palabraLower: 'ojo' },
|
|
{ letra: 'U', palabra: 'UNO', emoji: '1️⃣', gesto: 'Señalá el suelo con la mano', silaba: 'u', palabraLower: 'uno' },
|
|
]
|
|
|
|
const moduleB: Info[] = [
|
|
{ letra: 'M', palabra: 'MAMÁ', emoji: '👩', gesto: 'Manos en la boca como mmm', silaba: 'ma', palabraLower: 'mamá' },
|
|
{ letra: 'P', palabra: 'PAPÁ', emoji: '👨', gesto: 'Manos que abren y cierran como pompa', silaba: 'pa', palabraLower: 'papá' },
|
|
{ letra: 'L', palabra: 'LUNA', emoji: '🌙', gesto: 'Lengua arriba como lámpara', silaba: 'la', palabraLower: 'luna' },
|
|
{ letra: 'S', palabra: 'SOL', emoji: '☀️', gesto: 'Dedos como serpiente sss', silaba: 'sa', palabraLower: 'sol' },
|
|
]
|
|
|
|
const moduleC: Info[] = [
|
|
{ letra: 'T', palabra: 'TASA', emoji: '☕', gesto: 'Golpecito con la mano', silaba: 'ta', palabraLower: 'tasa' },
|
|
{ letra: 'N', palabra: 'NIDO', emoji: '🪺', gesto: 'Nariz como nido', silaba: 'na', palabraLower: 'nido' },
|
|
{ letra: 'D', palabra: 'DEDO', emoji: '👉', gesto: 'Dedo señalando', silaba: 'da', palabraLower: 'dedo' },
|
|
{ letra: 'R', palabra: 'RATÓN', emoji: '🐭', gesto: 'Lengua que vibra como rrr', silaba: 'ra', palabraLower: 'ratón' },
|
|
]
|
|
|
|
const allModules = [moduleA, moduleB, moduleC]
|
|
|
|
function getDistractors(pool: Info[], current: Info, count: number): Info[] {
|
|
return pool.filter((x) => x.letra !== current.letra).slice(0, count)
|
|
}
|
|
|
|
function getPoolIndex(info: Info): number {
|
|
for (let i = 0; i < allModules.length; i++) {
|
|
if (allModules[i].find((x) => x.letra === info.letra)) return i
|
|
}
|
|
return 0
|
|
}
|
|
|
|
function buildExercises(): Exercise[] {
|
|
const all: Exercise[] = []
|
|
let prevId: string | null = 'lec4-r-completa'
|
|
|
|
for (const pool of allModules) {
|
|
for (const info of pool) {
|
|
const MIN = info.letra.toLowerCase()
|
|
const dist = getDistractors(pool, info, 3)
|
|
|
|
// 1. Descubrimiento del par
|
|
all.push({
|
|
id: `lec5-${MIN}-descubre`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'sensibilizacion',
|
|
prerequisites: prevId ? [prevId] : [],
|
|
content: {
|
|
instruction: `${info.letra} y ${MIN} suenan igual`,
|
|
audioText: `${info.letra} grande y ${MIN} chica suenan igual: ${gestoKey(info.gesto)}`,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Descubrir que ${info.letra} y ${MIN} son la misma letra.. Método Borel-Maisonny.`,
|
|
})
|
|
prevId = `lec5-${MIN}-descubre`
|
|
|
|
// 2. Práctica emparejada: Tocá Mm
|
|
const pairOptions = [
|
|
{ label: `${info.letra}${MIN}`, correct: true, id: MIN },
|
|
...dist.map((d) => ({
|
|
label: `${d.letra}${d.letra.toLowerCase()}`,
|
|
correct: false,
|
|
id: d.letra.toLowerCase(),
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-pareja`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `Tocá la ${info.letra}${MIN}`,
|
|
audioText: `¿Dónde está ${info.letra}${MIN}?`,
|
|
options: pairOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Asociar el par ${info.letra}${MIN}.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-pareja`
|
|
|
|
// 3. Buscar mayúscula entre minúsculas: Tocá la M
|
|
const mayusOptions = [
|
|
{ label: info.letra, correct: true, id: MIN },
|
|
...dist.map((d) => ({
|
|
label: d.letra.toLowerCase(),
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-may`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-busca-mayus`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `Tocá la ${info.letra} grande`,
|
|
audioText: `¿Dónde está la ${info.letra} grande?`,
|
|
options: mayusOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Reconocer ${info.letra} mayúscula entre minúsculas.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-busca-mayus`
|
|
|
|
// 4. Buscar minúscula entre mayúsculas: Tocá la m (CLAVE)
|
|
const minusOptions = [
|
|
{ label: MIN, correct: true, id: MIN },
|
|
...dist.map((d) => ({
|
|
label: d.letra,
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-min`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-busca-minus`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `Tocá la ${MIN} chica`,
|
|
audioText: `¿Dónde está la ${MIN} chica?`,
|
|
options: minusOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Reconocer ${MIN} minúscula entre mayúsculas — discriminación clave para dislexia.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-busca-minus`
|
|
|
|
// 5. Pareja inversa: ¿Cuál es la pareja de M? → m
|
|
const parejaMayusOptions = [
|
|
{ label: MIN, correct: true, id: `${MIN}-pm` },
|
|
...dist.map((d) => ({
|
|
label: d.letra.toLowerCase(),
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-pm`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-pareja-mayus`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `¿Cuál es la pareja de ${info.letra}?`,
|
|
audioText: `Buscá la ${MIN} chica, pareja de la ${info.letra} grande`,
|
|
options: parejaMayusOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Asociar la mayúscula ${info.letra} con su minúscula ${MIN}.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-pareja-mayus`
|
|
|
|
// 6. Pareja inversa 2: ¿Cuál es la pareja de m? → M
|
|
const parejaMinusOptions = [
|
|
{ label: info.letra, correct: true, id: `${MIN}-pm2` },
|
|
...dist.map((d) => ({
|
|
label: d.letra,
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-pm2`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-pareja-minus`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `¿Cuál es la pareja de ${MIN}?`,
|
|
audioText: `Buscá la ${info.letra} grande, pareja de la ${MIN} chica`,
|
|
options: parejaMinusOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Asociar la minúscula ${MIN} con su mayúscula ${info.letra}.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-pareja-minus`
|
|
|
|
// 7. Sílabas en minúscula: Tocá ma
|
|
const silabaOptions = [
|
|
{ label: info.silaba, correct: true, id: `${MIN}-sil` },
|
|
...dist.map((d) => ({
|
|
label: d.silaba,
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-sil`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-silaba`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `Tocá ${info.silaba}`,
|
|
audioText: `¿Dónde está ${info.silaba}?`,
|
|
options: silabaOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Leer la sílaba ${info.silaba} en minúscula.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-silaba`
|
|
|
|
// 8. Palabra en minúscula: Tocá mamá
|
|
const palabraOptions = [
|
|
{ label: info.palabraLower, correct: true, id: `${MIN}-pal` },
|
|
...dist.map((d) => ({
|
|
label: d.palabraLower,
|
|
correct: false,
|
|
id: `${d.letra.toLowerCase()}-pal`,
|
|
})),
|
|
].sort(() => Math.random() - 0.5)
|
|
|
|
all.push({
|
|
id: `lec5-${MIN}-palabra`,
|
|
stage: 5,
|
|
skillCode: `puente-${MIN}`,
|
|
type: 'eleccion',
|
|
prerequisites: [prevId],
|
|
content: {
|
|
instruction: `Tocá ${info.palabraLower}`,
|
|
audioText: `¿Dónde dice ${info.palabraLower}?`,
|
|
options: palabraOptions,
|
|
emoji: info.emoji,
|
|
},
|
|
functionalContext: `Leer la palabra ${info.palabraLower} en minúscula.. Método Borel-Maisonny.`,
|
|
errorType: 'confusion-letra',
|
|
})
|
|
prevId = `lec5-${MIN}-palabra`
|
|
}
|
|
}
|
|
|
|
return all
|
|
}
|
|
|
|
function gestoKey(gesto: string): string {
|
|
const map: Record<string, string> = {
|
|
'Abrí': 'a-a-a',
|
|
'Estirá': 'e-e-e',
|
|
'Señalá el cielo': 'i-i-i',
|
|
'Redondeá': 'o-o-o',
|
|
'Señalá el suelo': 'u-u-u',
|
|
'Manos en la boca': 'mmm',
|
|
'Manos que abren': 'p-p-p',
|
|
'Dedos como serpiente': 'sss',
|
|
'Lengua arriba': 'l-l-l',
|
|
'Golpecito': 't-t-t',
|
|
'Nariz como nido': 'n-n-n',
|
|
'Dedo señalando': 'd-d-d',
|
|
'Lengua que vibra': 'rrr',
|
|
}
|
|
const key = Object.keys(map).find((k) => gesto.startsWith(k))
|
|
return key ? map[key] : gesto
|
|
}
|
|
|
|
const stage: Stage = {
|
|
id: 5,
|
|
name: 'Puente Mayúscula-Minúscula',
|
|
description: 'Asociar letras mayúsculas con sus correspondientes minúsculas. 8 ejercicios por letra — 104 en total.',
|
|
exercises: buildExercises(),
|
|
}
|
|
|
|
export default stage
|