import fs from 'node:fs' const timed = fs.readFileSync('reader-script-en-live-30min.md', 'utf8').split(/\r?\n/) const live = fs.readFileSync('reader-script-en-live.md', 'utf8').split(/\r?\n/) const slideTimes = new Map() for (const line of timed) { const m = line.match(/^## Slide\s+(\d+)(?:.*)?\[target:\s*(\d+)s\s*\|\s*cumulative:\s*([0-9:]+)\]/) if (m) slideTimes.set(Number(m[1]), { target: Number(m[2]), cumulative: m[3] }) } const slideLines = new Map() let cur = null for (const line of live) { const h = line.match(/^## Slide\s+(\d+)/) if (h) { cur = Number(h[1]); slideLines.set(cur, []); continue } if (!cur) continue if (!line.trim()) continue if (/^(STORY|TENSION|EMPHASIS|DELIVERY):/.test(line)) continue if (/^\(No spoken text/.test(line)) continue slideLines.get(cur).push(line.trim()) } const blocks = [ { id: 'B1', name: 'Hook & Promise', range: [1,3], goal: 'Abrir con credibilidad y dolor real.' }, { id: 'B2', name: 'Escalation', range: [4,7], goal: 'Mostrar que la complejidad crece sin control.' }, { id: 'B3', name: 'Problem Anatomy', range: [8,14], goal: 'Hacer evidente la causa raiz y el costo de fallar tarde.' }, { id: 'B4', name: 'Turning Point', range: [15,18], goal: 'Giro narrativo: no faltan tools, falta paradigma.' }, { id: 'B5', name: 'Resolution by Types', range: [19,23], goal: 'Conectar Rust/tipos con respuestas concretas.' }, { id: 'B6', name: 'Proof in Production', range: [24,31], goal: 'Probar con casos reales e impacto operativo.' }, { id: 'B7', name: 'Close & CTA', range: [32,35], goal: 'Cerrar con mensaje memorable y accion.' }, ] function mmss(sec) { const m = Math.floor(sec / 60) const s = sec % 60 return `${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}` } let out = '# Rustikon 2026 - Frases Criticas por Bloques (30 min)\n\n' out += 'Guia de control narrativo para saber si vas en tiempo o debes acelerar.\n\n' out += '## Resumen de Bloques\n\n' out += '| Bloque | Slides | Objetivo narrativo | Tiempo bloque | Acumulado |\n' out += '|---|---:|---|---:|---:|\n' let cum = 0 for (const b of blocks) { let sec = 0 for (let n=b.range[0]; n<=b.range[1]; n++) sec += (slideTimes.get(n)?.target ?? 0) cum += sec out += `| ${b.id} ${b.name} | ${b.range[0]}-${b.range[1]} | ${b.goal} | ${mmss(sec)} | ${mmss(cum)} |\n` } out += '\n## Señales de Ritmo\n\n' out += '- Si en **10:00** no has llegado a Slide 12-13, acelera (reduce ejemplos y tablas).\n' out += '- Si en **20:00** no has llegado a Slide 24, recorta explicacion tecnica y ve a casos reales.\n' out += '- En **27:00** deberias estar entrando al cierre (Slide 32+).\n\n' for (const b of blocks) { out += `## ${b.id} - ${b.name} (Slides ${b.range[0]}-${b.range[1]})\n\n` let blockSec = 0 for (let n=b.range[0]; n<=b.range[1]; n++) blockSec += (slideTimes.get(n)?.target ?? 0) out += `Tiempo objetivo bloque: **${mmss(blockSec)}**\n\n` out += `Objetivo: ${b.goal}\n\n` out += 'Frases criticas por slide:\n' for (let n=b.range[0]; n<=b.range[1]; n++) { const lines = (slideLines.get(n) || []).filter(l => /[A-Za-z]/.test(l)) const critical = lines.slice(0, 2) if (!critical.length) { out += `- Slide ${n}: (sin texto hablado, avanzar)\n` continue } out += `- Slide ${n}: ${critical.join(' / ')}\n` } out += '\nRegla de enfasis:\n' if (b.id === 'B1') out += '- Habla lento. No vendas tecnologia; vende problema vivido.\n\n' else if (b.id === 'B2') out += '- Sube energia y marca cada "lesson" con pausa corta.\n\n' else if (b.id === 'B3') out += '- Maxima claridad. Una idea por frase.\n\n' else if (b.id === 'B4') out += '- Haz silencio antes y despues del giro.\n\n' else if (b.id === 'B5') out += '- Tecnico, pero aterrizado a impacto operativo.\n\n' else if (b.id === 'B6') out += '- Menos teoria, mas evidencia: MTTR, DR, 3AM.\n\n' else out += '- Baja ritmo y cierra con conviccion.\n\n' } out += '## Checkpoints Rápidos\n\n' out += '- 05:00 -> deberias estar en Slide 6\n' out += '- 10:00 -> deberias estar en Slide 12-13\n' out += '- 15:00 -> deberias estar en Slide 18-19\n' out += '- 20:00 -> deberias estar en Slide 24\n' out += '- 25:00 -> deberias estar en Slide 29-30\n' out += '- 30:00 -> Slide 35 (end)\n' fs.writeFileSync('critical-phrases-blocks-30min.md', out) console.log('Wrote critical-phrases-blocks-30min.md')