@getparallel/parx 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +21 -3
- package/dist/agente.js +9 -6
- package/dist/api.js +6 -0
- package/dist/bash.js +89 -0
- package/dist/cli.js +200 -15
- package/dist/consejos.js +4 -1
- package/dist/herramientas.js +12 -8
- package/dist/informe.js +6 -0
- package/dist/marca.js +8 -0
- package/dist/textos.js +53 -5
- package/dist/tui.js +687 -138
- package/dist/ui.js +66 -22
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -24,6 +24,33 @@ export function bloqueDeTexto(texto, sangria = '') {
|
|
|
24
24
|
return out;
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
export function bloqueDeTabla(filas, o = {}) {
|
|
28
|
+
return (ancho) => {
|
|
29
|
+
const util = anchoUtil(ancho);
|
|
30
|
+
const sangria = ' '.repeat(o.sangria ?? 0);
|
|
31
|
+
const dentro = util - sangria.length;
|
|
32
|
+
const col = Math.min(Math.max(0, ...filas.map(([k]) => anchoDe(k))) + 3, Math.floor(dentro / 2));
|
|
33
|
+
const out = [];
|
|
34
|
+
if (o.titulo)
|
|
35
|
+
out.push(`${m}${c.negrita(o.titulo)}`);
|
|
36
|
+
for (const [k, d] of filas) {
|
|
37
|
+
const resto = dentro - col;
|
|
38
|
+
if (resto < 12) {
|
|
39
|
+
out.push(`${m}${sangria}${c.marca(recortar(k, dentro))}`);
|
|
40
|
+
for (const l of envolver(d, dentro - 2))
|
|
41
|
+
out.push(`${m}${sangria} ${l}`);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
envolver(d, resto).forEach((l, i) => out.push(`${m}${sangria}${i === 0 ? c.marca(rellenar(recortar(k, col - 1), col)) : ' '.repeat(col)}${l}`));
|
|
45
|
+
}
|
|
46
|
+
if (o.pie) {
|
|
47
|
+
out.push('');
|
|
48
|
+
for (const l of envolver(o.pie, util))
|
|
49
|
+
out.push(`${m}${c.gris(l)}`);
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
27
54
|
export function bloqueDeLinea(linea) {
|
|
28
55
|
return (ancho) => [`${m}${recortar(linea, anchoUtil(ancho))}`];
|
|
29
56
|
}
|
|
@@ -108,6 +135,26 @@ export function bloqueDeCierre(texto, marca) {
|
|
|
108
135
|
return [`${m}${izq}${resto > 0 ? ` ${c.tenue(c.gris((capacidades().unicode ? '─' : '-').repeat(resto)))}` : ''}`];
|
|
109
136
|
};
|
|
110
137
|
}
|
|
138
|
+
export function bloqueDeBash(comando) {
|
|
139
|
+
return (ancho) => {
|
|
140
|
+
const util = anchoUtil(ancho);
|
|
141
|
+
return ['', ...envolver(comando, util - 2).map((l, i) => `${m}${i === 0 ? c.aviso(c.negrita('!')) : ' '} ${l}`)];
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export function bloqueDeSalidaDeBash(lineas) {
|
|
145
|
+
return (ancho) => {
|
|
146
|
+
const util = anchoUtil(ancho);
|
|
147
|
+
const raya = c.tenue(c.aviso(capacidades().unicode ? '│' : '|'));
|
|
148
|
+
return lineas.map((l) => `${m}${raya} ${recortar(l.replace(/\t/g, ' '), util - 2)}`);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export function bloqueDeFinDeBash(bien, texto) {
|
|
152
|
+
return (ancho) => {
|
|
153
|
+
const u = capacidades().unicode;
|
|
154
|
+
const marca = bien ? c.ok(u ? '✓' : 'v') : c.error(u ? '✗' : 'x');
|
|
155
|
+
return [`${m}${c.tenue(c.aviso(u ? '╰' : '`'))} ${marca} ${recortar(c.gris(texto), anchoUtil(ancho) - 4)}`];
|
|
156
|
+
};
|
|
157
|
+
}
|
|
111
158
|
export function trocearTeclas(datos, estado) {
|
|
112
159
|
const out = [];
|
|
113
160
|
let i = 0;
|
|
@@ -125,6 +172,20 @@ export function trocearTeclas(datos, estado) {
|
|
|
125
172
|
}
|
|
126
173
|
const ch = datos[i];
|
|
127
174
|
if (ch === '\x1b') {
|
|
175
|
+
const sgr = /^\x1b\[<(\d+);(\d+);(\d+)([Mm])/.exec(datos.slice(i));
|
|
176
|
+
if (sgr) {
|
|
177
|
+
i += sgr[0].length;
|
|
178
|
+
out.push(teclaDeRaton(Number(sgr[1]), Number(sgr[2]), Number(sgr[3]), sgr[4] === 'm'));
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (datos.startsWith('\x1b[M', i) && datos.length >= i + 6) {
|
|
182
|
+
const b = datos.charCodeAt(i + 3) - 32;
|
|
183
|
+
const x = datos.charCodeAt(i + 4) - 32;
|
|
184
|
+
const y = datos.charCodeAt(i + 5) - 32;
|
|
185
|
+
i += 6;
|
|
186
|
+
out.push(teclaDeRaton(b, x, y, (b & 3) === 3 && (b & 64) === 0 && (b & 32) === 0, b & 64 ? 3 : b & 3));
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
128
189
|
const r = /^\x1b(?:\[([0-9;?]*)([ -/]*[@-~])|O([@-~])|([\s\S]))?/.exec(datos.slice(i));
|
|
129
190
|
const seq = r[0];
|
|
130
191
|
i += Math.max(1, seq.length);
|
|
@@ -147,10 +208,16 @@ export function trocearTeclas(datos, estado) {
|
|
|
147
208
|
out.push({ t: 'abajo' });
|
|
148
209
|
else if (fin === 'H' || (fin === '~' && (params === '1' || params === '7')))
|
|
149
210
|
out.push({ t: 'inicio' });
|
|
211
|
+
else if ((fin === 'F' && /;5$/.test(params)) || (fin === '~' && /^[48];5$/.test(params)))
|
|
212
|
+
out.push({ t: 'fondo' });
|
|
150
213
|
else if (fin === 'F' || (fin === '~' && (params === '4' || params === '8')))
|
|
151
214
|
out.push({ t: 'fin' });
|
|
152
215
|
else if (fin === '~' && params === '3')
|
|
153
216
|
out.push({ t: 'suprimir' });
|
|
217
|
+
else if (fin === '~' && params === '5')
|
|
218
|
+
out.push({ t: 'pagina_arriba' });
|
|
219
|
+
else if (fin === '~' && params === '6')
|
|
220
|
+
out.push({ t: 'pagina_abajo' });
|
|
154
221
|
else if (fin === 'Z')
|
|
155
222
|
out.push({ t: 'cambiar' });
|
|
156
223
|
else if (fin === 'I' && params === '')
|
|
@@ -194,6 +261,8 @@ export function trocearTeclas(datos, estado) {
|
|
|
194
261
|
out.push({ t: 'borrar_palabra' });
|
|
195
262
|
else if (ch === '\x0c')
|
|
196
263
|
out.push({ t: 'limpiar' });
|
|
264
|
+
else if (ch === '\x1a')
|
|
265
|
+
out.push({ t: 'suspender' });
|
|
197
266
|
else if (ch === '\x10')
|
|
198
267
|
out.push({ t: 'arriba' });
|
|
199
268
|
else if (ch === '\x0e')
|
|
@@ -210,8 +279,17 @@ export function trocearTeclas(datos, estado) {
|
|
|
210
279
|
}
|
|
211
280
|
return out;
|
|
212
281
|
}
|
|
213
|
-
|
|
282
|
+
function teclaDeRaton(b, x, y, soltar, botonX10) {
|
|
283
|
+
const rueda = b & 64 ? ((b & 1) === 0 ? -1 : 1) : 0;
|
|
284
|
+
const mover = Boolean(b & 32);
|
|
285
|
+
const boton = botonX10 ?? (rueda ? 3 : b & 3);
|
|
286
|
+
return { t: 'raton', boton, x, y, soltar, mover, rueda: rueda };
|
|
287
|
+
}
|
|
288
|
+
export const RATON_SI = '\x1b[?1000h\x1b[?1002h\x1b[?1003h\x1b[?1006h';
|
|
289
|
+
export const RATON_NO = '\x1b[?1003l\x1b[?1002l\x1b[?1000l\x1b[?1006l';
|
|
290
|
+
const CON_VALOR = new Set(['mode', 'model', 'tips', 'notify', 'teach', 'mouse']);
|
|
214
291
|
const CON_TEXTO = new Set(['folder']);
|
|
292
|
+
const SE_MANDAN_SOLOS = new Set(['teach', 'notify', 'tips', 'folder', 'mouse']);
|
|
215
293
|
const MODOS_DEL_MENU = ['ask', 'auto', 'read', 'bypass'];
|
|
216
294
|
export function opcionesDelMenu(valor) {
|
|
217
295
|
if (!valor.startsWith('/') || valor.includes('\n'))
|
|
@@ -226,7 +304,8 @@ export function opcionesDelMenu(valor) {
|
|
|
226
304
|
if (!casa)
|
|
227
305
|
continue;
|
|
228
306
|
const conAlgo = CON_VALOR.has(cmd) || CON_TEXTO.has(cmd);
|
|
229
|
-
|
|
307
|
+
const entero = q === cmd || ALIAS_COMANDO[q] === cmd;
|
|
308
|
+
out.push({ nombre: `/${cmd}`, descripcion, completar: `/${cmd}${conAlgo ? ' ' : ''}`, enviar: !conAlgo || (entero && SE_MANDAN_SOLOS.has(cmd)) });
|
|
230
309
|
}
|
|
231
310
|
return out;
|
|
232
311
|
}
|
|
@@ -242,31 +321,51 @@ export function opcionesDelMenu(valor) {
|
|
|
242
321
|
: cmd === 'model'
|
|
243
322
|
? ORDEN_DE_MODELOS.map((k) => [k, `${MODELOS[k].nombre} ${MODELOS[k].version}: ${MODELOS[k].descripcion}`])
|
|
244
323
|
: [
|
|
245
|
-
['on', cmd === 'teach' ? 'Explain each step as it codes' : cmd === 'notify' ? 'Notify me when it finishes or needs me' : 'Show them when parx opens'],
|
|
246
|
-
['off', cmd === 'teach' ? 'Back to normal' : cmd === 'notify' ? 'No desktop notifications' : 'Don’t show them again'],
|
|
324
|
+
['on', cmd === 'teach' ? 'Explain each step as it codes' : cmd === 'notify' ? 'Notify me when it finishes or needs me' : cmd === 'mouse' ? 'Click options, scroll with the wheel' : 'Show them when parx opens'],
|
|
325
|
+
['off', cmd === 'teach' ? 'Back to normal' : cmd === 'notify' ? 'No desktop notifications' : cmd === 'mouse' ? 'The terminal selects and scrolls as usual' : 'Don’t show them again'],
|
|
247
326
|
];
|
|
248
327
|
return valores
|
|
249
328
|
.filter(([v]) => v.startsWith(q))
|
|
250
329
|
.map(([v, d]) => ({ nombre: v, descripcion: d, completar: `${base}${v}`, enviar: true, ...(cmd === 'mode' && v === 'bypass' ? { peligro: true } : {}) }));
|
|
251
330
|
}
|
|
252
331
|
export function componerBarra(e, util) {
|
|
332
|
+
return componerBarraConZonas(e, util).texto;
|
|
333
|
+
}
|
|
334
|
+
export function componerBarraConZonas(e, util) {
|
|
335
|
+
const u = capacidades().unicode;
|
|
253
336
|
const punto = c.gris(sep());
|
|
254
|
-
const modo = e.peligro ? c.aviso(c.negrita(`${
|
|
337
|
+
const modo = e.peligro ? c.aviso(c.negrita(`${u ? '▲' : '!'} ${e.modo}`)) : c.gris(e.modo);
|
|
255
338
|
const extra = e.extra ? `${punto}${c.marca(e.extra)}` : '';
|
|
339
|
+
const n = e.esperando ?? 0;
|
|
340
|
+
const espera = n ? c.aviso(`${u ? '●' : '*'} ${tt('bandeja.esperando', { n })}`) : '';
|
|
341
|
+
const esperaCorta = n ? c.aviso(`${u ? '●' : '*'} ${n}`) : '';
|
|
342
|
+
const conEspera = (base, e2) => (e2 ? [...base, { t: punto }, { t: e2, id: 'bandeja' }] : base);
|
|
343
|
+
const m = { t: modo, id: 'modo' };
|
|
256
344
|
const opciones = [
|
|
257
|
-
[`${
|
|
258
|
-
[`${
|
|
259
|
-
[`${
|
|
260
|
-
[
|
|
345
|
+
[conEspera([m, { t: `${punto}${c.gris(e.modelo)}${extra}` }], espera), e.saldo],
|
|
346
|
+
[conEspera([m, { t: `${punto}${c.gris(e.modelo)}${extra}` }], espera), e.saldoCorto ?? e.saldo],
|
|
347
|
+
[conEspera([m, { t: `${punto}${c.gris(e.modelo)}` }], esperaCorta), e.saldoCorto ?? e.saldo],
|
|
348
|
+
[conEspera([m], esperaCorta), e.saldoCorto ?? e.saldo],
|
|
349
|
+
[[m], e.saldoCorto ?? e.saldo],
|
|
261
350
|
];
|
|
262
|
-
for (const [
|
|
351
|
+
for (const [trozos, der] of opciones) {
|
|
352
|
+
const izq = trozos.map((x) => x.t).join('');
|
|
263
353
|
const hueco = util - anchoDe(izq) - anchoDe(der);
|
|
264
|
-
if (hueco
|
|
265
|
-
|
|
354
|
+
if (hueco < 2)
|
|
355
|
+
continue;
|
|
356
|
+
const zonas = [];
|
|
357
|
+
let col = 0;
|
|
358
|
+
for (const x of trozos) {
|
|
359
|
+
const w = anchoDe(x.t);
|
|
360
|
+
if (x.id)
|
|
361
|
+
zonas.push({ desde: col, hasta: col + w, id: x.id });
|
|
362
|
+
col += w;
|
|
363
|
+
}
|
|
364
|
+
return { texto: `${izq}${' '.repeat(hueco)}${c.gris(der)}`, zonas };
|
|
266
365
|
}
|
|
267
366
|
const der = e.saldoCorto ?? '';
|
|
268
367
|
const izq = recortar(modo, Math.max(1, util - anchoDe(der) - 2));
|
|
269
|
-
return rellenar(`${izq}${' '.repeat(Math.max(0, util - anchoDe(izq) - anchoDe(der)))}${c.gris(der)}`, util);
|
|
368
|
+
return { texto: rellenar(`${izq}${' '.repeat(Math.max(0, util - anchoDe(izq) - anchoDe(der)))}${c.gris(der)}`, util), zonas: [{ desde: 0, hasta: anchoDe(izq), id: 'modo' }] };
|
|
270
369
|
}
|
|
271
370
|
export function duracion(ms) {
|
|
272
371
|
const s = Math.max(0, Math.floor(ms / 1000));
|
|
@@ -308,11 +407,16 @@ export function textoDeTrabajo(w, ahora) {
|
|
|
308
407
|
return { texto: w.texto, anim: w.anim };
|
|
309
408
|
return { texto: fraseDeEspera(ahora - w.esperaDesde, w.semilla), anim: 'ruta' };
|
|
310
409
|
}
|
|
311
|
-
export function filaDeTrabajo(w, ahora) {
|
|
410
|
+
export function filaDeTrabajo(w, ahora, ancho = Infinity) {
|
|
312
411
|
const { texto, anim } = textoDeTrabajo(w, ahora);
|
|
313
412
|
const tiempo = duracion(ahora - w.desde);
|
|
314
413
|
const gasto = w.acciones ? `${sep()}${acciones(w.acciones)}` : '';
|
|
315
|
-
|
|
414
|
+
for (const cola of [`${sep()}${tiempo}${gasto}`, `${sep()}${tiempo}${w.acciones ? `${sep()}${w.acciones.toLocaleString('en-US')}` : ''}`, `${sep()}${tiempo}`]) {
|
|
415
|
+
const fila = `${animacion(anim, w.paso)} ${texto}${c.gris(cola)}`;
|
|
416
|
+
if (anchoDe(fila) <= ancho)
|
|
417
|
+
return fila;
|
|
418
|
+
}
|
|
419
|
+
return recortar(`${animacion(anim, w.paso)} ${texto}`, ancho);
|
|
316
420
|
}
|
|
317
421
|
export function filaDeCarril(k, util, ahora) {
|
|
318
422
|
const fin = k.hasta ?? ahora;
|
|
@@ -333,8 +437,11 @@ export function filaDeCarril(k, util, ahora) {
|
|
|
333
437
|
}
|
|
334
438
|
const anchoTarea = Math.max(8, Math.floor(util * 0.32));
|
|
335
439
|
const tarea = recortar(k.tarea.replace(/\s+/g, ' '), anchoTarea);
|
|
336
|
-
const
|
|
337
|
-
|
|
440
|
+
const sitio = util - (anchoDe(derecha) + 2 <= util / 2 ? anchoDe(derecha) + 2 : 0);
|
|
441
|
+
const base = `${numero} ${señal} ${c.negrita(tarea)}`;
|
|
442
|
+
const libre = sitio - anchoDe(base) - anchoDe(sep());
|
|
443
|
+
const izq = libre >= 8 ? `${base}${c.gris(sep())}${c.gris(recortar(texto, libre))}` : base;
|
|
444
|
+
return izquierdaYDerecha(recortar(izq, sitio), derecha, util);
|
|
338
445
|
}
|
|
339
446
|
function izquierdaYDerecha(izq, der, util) {
|
|
340
447
|
if (anchoDe(izq) + anchoDe(der) + 2 <= util)
|
|
@@ -367,77 +474,163 @@ export function ventanaDeEntrada(unidades, cursor, ancho) {
|
|
|
367
474
|
export function cabePar(ancho) {
|
|
368
475
|
return ancho >= 56;
|
|
369
476
|
}
|
|
477
|
+
export function esBash(unidades) {
|
|
478
|
+
return unidades[0] === '!';
|
|
479
|
+
}
|
|
480
|
+
export function boton(etiqueta, numero, o = {}) {
|
|
481
|
+
const u = capacidades().unicode;
|
|
482
|
+
const n = numero === null ? '' : `${numero} `;
|
|
483
|
+
if (o.elegido)
|
|
484
|
+
return c.boton(`[${u ? '▸' : '>'}${n}${etiqueta} ]`, o.peligro);
|
|
485
|
+
const pinta = o.peligro ? c.peligro : (x) => x;
|
|
486
|
+
if (o.sobre)
|
|
487
|
+
return `${c.claro('[')} ${c.marca(`${n}${etiqueta}`)} ${c.claro(']')}`;
|
|
488
|
+
return `${c.gris('[')} ${numero === null ? '' : c.claro(n)}${pinta(etiqueta)} ${c.gris(']')}`;
|
|
489
|
+
}
|
|
490
|
+
function filaDeBotones(etiquetas, p, sobre, ancho) {
|
|
491
|
+
const partes = etiquetas.map((e, i) => boton(e, i + 1, { elegido: i === p.elegida, sobre: sobre === `opcion:${i}`, peligro: p.peligro || p.notas?.[i]?.peligro }));
|
|
492
|
+
const total = partes.reduce((n, x) => n + anchoDe(x), 0) + 2 * (partes.length - 1);
|
|
493
|
+
if (total > ancho)
|
|
494
|
+
return null;
|
|
495
|
+
const zonas = [];
|
|
496
|
+
let col = 0;
|
|
497
|
+
partes.forEach((x, i) => {
|
|
498
|
+
zonas.push({ desde: col, hasta: col + anchoDe(x), id: `opcion:${i}` });
|
|
499
|
+
col += anchoDe(x) + 2;
|
|
500
|
+
});
|
|
501
|
+
return { texto: partes.join(' '), zonas };
|
|
502
|
+
}
|
|
370
503
|
export function componerCarril(d, ancho, alto) {
|
|
371
504
|
const util = anchoUtil(ancho);
|
|
372
505
|
const conPar = cabePar(ancho);
|
|
373
506
|
const huecoPar = conPar ? ANCHO_DE_PAR + 2 : 0;
|
|
374
|
-
const
|
|
507
|
+
const u = capacidades().unicode;
|
|
508
|
+
const bash = !d.pregunta && esBash(d.unidades);
|
|
509
|
+
const signoW = bash ? 2 : 3;
|
|
510
|
+
const holgado = alto >= 14;
|
|
511
|
+
const medio = alto >= 9;
|
|
512
|
+
const vacia = `${m}${' '.repeat(util)}`;
|
|
375
513
|
let filaEscribir;
|
|
376
514
|
let cursor = null;
|
|
377
515
|
const anchoEscribir = util - (conPar ? huecoPar + 1 : 0);
|
|
378
|
-
|
|
379
|
-
const p = d.pregunta;
|
|
380
|
-
const pinta = (etiquetas) => etiquetas
|
|
381
|
-
.map((e, i) => {
|
|
382
|
-
const txt = `${i + 1} ${e}`;
|
|
383
|
-
return i === p.elegida ? `${c.claro(capacidades().unicode ? '▸' : '>')} ${c.negrita(txt)}` : ` ${c.gris(txt)}`;
|
|
384
|
-
})
|
|
385
|
-
.join(' ');
|
|
386
|
-
let opciones = pinta(p.opciones);
|
|
387
|
-
if (anchoDe(opciones) > anchoEscribir - signoW)
|
|
388
|
-
opciones = pinta(p.cortas);
|
|
389
|
-
filaEscribir = rellenar(`${(p.peligro ? c.peligro : c.aviso)(signo())} ${opciones}`, anchoEscribir);
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
516
|
+
{
|
|
392
517
|
const libre = Math.max(4, anchoEscribir - signoW);
|
|
393
|
-
const color = d.trabajo ? c.gris : c.claro;
|
|
394
|
-
|
|
395
|
-
|
|
518
|
+
const color = d.trabajo || d.pregunta ? c.gris : c.claro;
|
|
519
|
+
const marca = bash ? c.aviso(c.negrita('!')) : color(signo());
|
|
520
|
+
const unidades = bash ? d.unidades.slice(1) : d.unidades;
|
|
521
|
+
const enCursor = bash ? Math.max(0, d.cursor - 1) : d.cursor;
|
|
522
|
+
if (!unidades.length) {
|
|
523
|
+
const ejemplo = bash ? tt('bash.ejemplo') : d.pregunta ? '' : d.ejemplo;
|
|
524
|
+
filaEscribir = rellenar(`${marca} ${c.gris(recortar(ejemplo, libre))}`, anchoEscribir);
|
|
396
525
|
cursor = { fila: 0, col: MARGEN + signoW };
|
|
397
526
|
}
|
|
398
527
|
else {
|
|
399
|
-
const v = ventanaDeEntrada(
|
|
400
|
-
filaEscribir = rellenar(`${
|
|
528
|
+
const v = ventanaDeEntrada(unidades, enCursor, libre);
|
|
529
|
+
filaEscribir = rellenar(`${marca} ${d.pregunta ? c.gris(v.texto) : v.texto}`, anchoEscribir);
|
|
401
530
|
cursor = { fila: 0, col: MARGEN + signoW + v.col };
|
|
402
531
|
}
|
|
532
|
+
if (d.pregunta)
|
|
533
|
+
cursor = null;
|
|
403
534
|
}
|
|
404
535
|
if (conPar)
|
|
405
536
|
filaEscribir += ` ${cabezaDePar()} `;
|
|
406
|
-
const tinta = (t) => c.violeta(t);
|
|
537
|
+
const tinta = (t) => (bash ? c.aviso(t) : c.violeta(t));
|
|
407
538
|
const linea = conPar ? `${tinta(carril(util - ANCHO_DE_PAR - 2))}${caraDePar(d.gesto)}${tinta(carril(2))}` : tinta(carril(util));
|
|
408
539
|
let barra;
|
|
540
|
+
let zonasBarra = [];
|
|
409
541
|
const enCarriles = (d.carriles ?? []).filter((k) => k.estado === 'trabaja').length;
|
|
410
542
|
if (d.trabajo && !d.pregunta && d.carriles?.length) {
|
|
411
543
|
const gasto = d.carriles.reduce((n, k) => n + (k.trabajo.acciones ?? 0), 0);
|
|
412
|
-
const
|
|
413
|
-
|
|
544
|
+
const base = `${animacion('tren', d.trabajo.paso)} ${tt('carriles.en_marcha', { n: enCarriles, total: d.carriles.length })}`;
|
|
545
|
+
const tiempo = `${sep()}${duracion(d.ahora - d.trabajo.desde)}`;
|
|
546
|
+
const izq = [`${base}${c.gris(`${tiempo}${gasto ? `${sep()}${acciones(gasto)}` : ''}`)}`, `${base}${c.gris(tiempo)}`, base].find((x) => anchoDe(x) <= util) ?? recortar(base, util);
|
|
547
|
+
barra = izquierdaYDerecha(izq, c.tenue(c.gris(d.aviso ?? tt('tui.parar'))), util);
|
|
414
548
|
}
|
|
415
549
|
else if (d.trabajo && !d.pregunta) {
|
|
416
|
-
barra = izquierdaYDerecha(
|
|
550
|
+
barra = izquierdaYDerecha(filaDeTrabajo(d.trabajo, d.ahora, util), c.tenue(c.gris(d.aviso ?? tt('tui.parar'))), util);
|
|
417
551
|
}
|
|
418
552
|
else if (d.aviso) {
|
|
419
553
|
barra = izquierdaYDerecha(c.aviso(recortar(d.aviso, util)), '', util);
|
|
420
554
|
}
|
|
555
|
+
else if (bash) {
|
|
556
|
+
const etiqueta = c.aviso(c.negrita(tt('bash.etiqueta')));
|
|
557
|
+
const largo = `${etiqueta}${c.gris(`${sep()}${tt('bash.intro')}`)}`;
|
|
558
|
+
barra = izquierdaYDerecha(anchoDe(largo) + anchoDe(d.estado.saldoCorto ?? '') + 2 <= util ? largo : etiqueta, c.gris(d.estado.saldoCorto ?? ''), util);
|
|
559
|
+
}
|
|
421
560
|
else {
|
|
422
|
-
|
|
561
|
+
const b = componerBarraConZonas(d.estado, util);
|
|
562
|
+
barra = b.texto;
|
|
563
|
+
zonasBarra = b.zonas;
|
|
423
564
|
}
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
const
|
|
565
|
+
const filas = [filaEscribir, linea, ...(holgado ? [''] : []), barra].map((f) => (f ? `${m}${f}` : vacia));
|
|
566
|
+
const zonas = [];
|
|
567
|
+
const filaBarra = filas.length - 1;
|
|
568
|
+
for (const z of zonasBarra)
|
|
569
|
+
zonas.push({ fila: filaBarra, desde: MARGEN + z.desde, hasta: MARGEN + z.hasta, id: z.id });
|
|
570
|
+
let abajo = alto >= 3 ? filas : alto === 2 ? [filas[0], filas[filas.length - 1]] : [filas[0]];
|
|
571
|
+
if (abajo !== filas)
|
|
572
|
+
zonas.length = 0;
|
|
573
|
+
const carriles = (d.carriles ?? []).slice(0, Math.max(0, alto - abajo.length - 2));
|
|
427
574
|
const filasDeCarriles = carriles.map((k) => `${m}${rellenar(filaDeCarril(k, util, d.ahora), util)}`);
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const hueco = Math.max(0, alto - filas.length);
|
|
432
|
-
let encima = [];
|
|
433
|
-
if (d.pregunta) {
|
|
575
|
+
let arriba = [...filasDeCarriles];
|
|
576
|
+
const zonasPregunta = [];
|
|
577
|
+
if (d.pregunta && alto >= 3) {
|
|
434
578
|
const p = d.pregunta;
|
|
435
|
-
const marca = p.peligro ? c.peligro(
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
579
|
+
const marca = p.peligro ? c.peligro(u ? '▲' : '!') : c.aviso('?');
|
|
580
|
+
const bloque = [];
|
|
581
|
+
const sitio = Math.max(1, alto - abajo.length - arriba.length - 2);
|
|
582
|
+
const titulo = envolver(p.texto, util - 2);
|
|
583
|
+
bloque.push(...titulo.map((l, i) => `${m}${rellenar(`${i === 0 ? marca : ' '} ${c.negrita(p.peligro ? c.peligro(l) : l)}`, util)}`));
|
|
584
|
+
if (p.detalle)
|
|
585
|
+
bloque.push(...envolver(p.detalle, util - 2).slice(0, 3).map((l) => `${m} ${rellenar(c.gris(l), util - 2)}`));
|
|
586
|
+
if (holgado)
|
|
587
|
+
bloque.push(vacia);
|
|
588
|
+
const enFila = !p.vertical ? (filaDeBotones(p.opciones, p, d.sobre, util - 2) ?? filaDeBotones(p.cortas, p, d.sobre, util - 2)) : null;
|
|
589
|
+
const filasBotones = [];
|
|
590
|
+
const zonasBotones = [];
|
|
591
|
+
if (enFila) {
|
|
592
|
+
filasBotones.push(`${m} ${rellenar(enFila.texto, util - 2)}`);
|
|
593
|
+
for (const z of enFila.zonas)
|
|
594
|
+
zonasBotones.push({ fila: 0, desde: MARGEN + 2 + z.desde, hasta: MARGEN + 2 + z.hasta, id: z.id });
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
const lista = filasDeLista(p, d.sobre, util, Math.max(1, sitio - bloque.length - (holgado ? 1 : 0)));
|
|
598
|
+
filasBotones.push(...lista.filas);
|
|
599
|
+
zonasBotones.push(...lista.zonas);
|
|
600
|
+
}
|
|
601
|
+
if (holgado)
|
|
602
|
+
filasBotones.push(vacia);
|
|
603
|
+
let todo = [...bloque, ...filasBotones];
|
|
604
|
+
let inicioBotones = bloque.length;
|
|
605
|
+
if (todo.length > sitio) {
|
|
606
|
+
const una = `${m}${rellenar(`${marca} ${c.negrita(recortar(p.texto, util - 2))}`, util)}`;
|
|
607
|
+
todo = [una, ...filasBotones.filter((x) => x !== vacia)];
|
|
608
|
+
inicioBotones = 1;
|
|
609
|
+
}
|
|
610
|
+
for (const z of zonasBotones)
|
|
611
|
+
zonasPregunta.push({ ...z, fila: inicioBotones + z.fila });
|
|
612
|
+
arriba = [...todo, ...arriba];
|
|
439
613
|
}
|
|
440
|
-
|
|
614
|
+
let separacion = medio || d.fondo ? vacia : null;
|
|
615
|
+
const zonaFondo = [];
|
|
616
|
+
if (separacion !== null && d.fondo) {
|
|
617
|
+
const texto = `${u ? '↓' : 'v'} ${tt('tui.al_fondo')}${d.fondo.nuevas ? `${sep()}${tt('tui.nuevas', { n: d.fondo.nuevas.toLocaleString('en-US') })}` : ''}`;
|
|
618
|
+
const b = d.sobre === 'fondo' ? c.boton(` ${texto} `) : boton(texto, null);
|
|
619
|
+
separacion = `${m}${rellenar(b, util)}`;
|
|
620
|
+
zonaFondo.push({ fila: 0, desde: MARGEN, hasta: MARGEN + anchoDe(b), id: 'fondo' });
|
|
621
|
+
}
|
|
622
|
+
const cabeza = separacion === null ? [] : [separacion];
|
|
623
|
+
const todas = [...cabeza, ...arriba, ...abajo];
|
|
624
|
+
const desplazar = cabeza.length + arriba.length;
|
|
625
|
+
for (const z of zonas)
|
|
626
|
+
z.fila += desplazar;
|
|
627
|
+
const zonasFinales = [...zonaFondo, ...zonasPregunta.map((z) => ({ ...z, fila: z.fila + cabeza.length })), ...zonas];
|
|
628
|
+
if (cursor)
|
|
629
|
+
cursor = { fila: cursor.fila + desplazar, col: cursor.col };
|
|
630
|
+
const hueco = Math.max(0, alto - todas.length);
|
|
631
|
+
let encima = [];
|
|
632
|
+
const zonasEncima = [];
|
|
633
|
+
if (!d.pregunta && d.menu && d.menu.opciones.length) {
|
|
441
634
|
const ops = d.menu.opciones;
|
|
442
635
|
const visibles = Math.min(6, ops.length, hueco);
|
|
443
636
|
if (visibles > 0) {
|
|
@@ -446,20 +639,58 @@ export function componerCarril(d, ancho, alto) {
|
|
|
446
639
|
encima = ops.slice(ini, ini + visibles).map((o, k) => {
|
|
447
640
|
const i = ini + k;
|
|
448
641
|
const sel = i === d.menu.elegida;
|
|
449
|
-
const
|
|
642
|
+
const sobre = d.sobre === `menu:${i}`;
|
|
643
|
+
zonasEncima.push({ fila: k, desde: MARGEN, hasta: MARGEN + util, id: `menu:${i}` });
|
|
644
|
+
const marca = sel ? (o.peligro ? c.peligro : c.claro)(u ? '▌' : '>') : ' ';
|
|
450
645
|
const resto = Math.max(0, util - 2 - anchoNombre);
|
|
451
646
|
const desc = recortar(o.descripcion, resto);
|
|
452
647
|
if (o.peligro) {
|
|
453
|
-
const nombre = rellenar(recortar(`${
|
|
454
|
-
return `${m}${rellenar(`${marca} ${sel ? c.negrita(c.peligro(nombre)) : c.peligro(nombre)}${sel ? c.peligro(desc) : c.tenue(c.peligro(desc))}`, util)}`;
|
|
648
|
+
const nombre = rellenar(recortar(`${u ? '▲' : '!'} ${o.nombre}`, anchoNombre - 1), anchoNombre);
|
|
649
|
+
return `${m}${rellenar(`${marca} ${sel || sobre ? c.negrita(c.peligro(nombre)) : c.peligro(nombre)}${sel ? c.peligro(desc) : c.tenue(c.peligro(desc))}`, util)}`;
|
|
455
650
|
}
|
|
456
651
|
const nombre = rellenar(recortar(o.nombre, anchoNombre - 1), anchoNombre);
|
|
457
|
-
return `${m}${rellenar(`${marca} ${sel ? c.negrita(c.marca(nombre)) : c.gris(nombre)}${sel ? desc : c.tenue(c.gris(desc))}`, util)}`;
|
|
652
|
+
return `${m}${rellenar(`${marca} ${sel ? c.negrita(c.marca(nombre)) : sobre ? c.marca(nombre) : c.gris(nombre)}${sel || sobre ? desc : c.tenue(c.gris(desc))}`, util)}`;
|
|
458
653
|
});
|
|
459
654
|
}
|
|
460
655
|
}
|
|
461
|
-
|
|
462
|
-
|
|
656
|
+
const fuera = Math.max(0, encima.length - hueco);
|
|
657
|
+
encima = encima.slice(fuera);
|
|
658
|
+
return {
|
|
659
|
+
encima,
|
|
660
|
+
carril: todas,
|
|
661
|
+
cursor: cursor && todas.length ? cursor : null,
|
|
662
|
+
zonas: zonasFinales,
|
|
663
|
+
zonasEncima: zonasEncima.filter((z) => z.fila >= fuera).map((z) => ({ ...z, fila: z.fila - fuera })),
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
function filasDeLista(p, sobre, util, max) {
|
|
667
|
+
const u = capacidades().unicode;
|
|
668
|
+
const n = p.opciones.length;
|
|
669
|
+
const visibles = Math.max(1, Math.min(n, max, 8));
|
|
670
|
+
const ini = Math.max(0, Math.min(p.elegida - visibles + 1, n - visibles));
|
|
671
|
+
const filas = [];
|
|
672
|
+
const zonas = [];
|
|
673
|
+
const recom = anchoDe(tt('bandeja.recomendada')) + 2;
|
|
674
|
+
const anchoEtiqueta = Math.max(...p.opciones.map((o, i) => anchoDe(o) + (p.notas?.[i]?.recomendada ? recom : 0))) + 2;
|
|
675
|
+
const conNotas = anchoEtiqueta <= Math.floor(util * 0.65);
|
|
676
|
+
for (let k = 0; k < visibles; k++) {
|
|
677
|
+
const i = ini + k;
|
|
678
|
+
const sel = i === p.elegida;
|
|
679
|
+
const enc = sobre === `opcion:${i}`;
|
|
680
|
+
const nota = p.notas?.[i];
|
|
681
|
+
const peligro = p.peligro || nota?.peligro;
|
|
682
|
+
const marca = sel ? (peligro ? c.peligro : c.claro)(u ? '▌' : '>') : ' ';
|
|
683
|
+
const num = i < 9 ? `${i + 1}` : ' ';
|
|
684
|
+
const recomendada = nota?.recomendada ? ` ${c.marca(tt('bandeja.recomendada'))}` : '';
|
|
685
|
+
const etiqueta = sel ? c.negrita(peligro ? c.peligro(p.opciones[i]) : p.opciones[i]) : enc ? c.marca(p.opciones[i]) : peligro ? c.peligro(p.opciones[i]) : p.opciones[i];
|
|
686
|
+
const cabeza = `${marca} ${c.claro(num)} `;
|
|
687
|
+
const base = conNotas ? `${cabeza}${rellenar(`${etiqueta}${recomendada}`, anchoEtiqueta)}` : `${cabeza}${recortar(`${etiqueta}${recomendada}`, Math.max(4, util - anchoDe(cabeza)))}`;
|
|
688
|
+
const resto = util - anchoDe(base);
|
|
689
|
+
const extra = conNotas && nota?.nota && resto >= 6 ? c.gris(recortar(nota.nota, resto)) : '';
|
|
690
|
+
filas.push(`${m}${rellenar(`${base}${extra}`, util)}`);
|
|
691
|
+
zonas.push({ fila: k, desde: MARGEN, hasta: MARGEN + util, id: `opcion:${i}` });
|
|
692
|
+
}
|
|
693
|
+
return { filas, zonas };
|
|
463
694
|
}
|
|
464
695
|
export function opcionesDePregunta(tipo) {
|
|
465
696
|
switch (tipo) {
|
|
@@ -495,20 +726,37 @@ export function rutaDeImagenPegada(texto) {
|
|
|
495
726
|
v = decodeURIComponent(v.slice(7));
|
|
496
727
|
return IMAGEN.test(v) && /^(\/|~|[A-Za-z]:\\|\.)/.test(v) ? v : null;
|
|
497
728
|
}
|
|
729
|
+
function sinBlancoDoble(lineas, previaEnBlanco) {
|
|
730
|
+
let i = 0;
|
|
731
|
+
if (previaEnBlanco)
|
|
732
|
+
while (i < lineas.length && lineas[i].trim() === '')
|
|
733
|
+
i++;
|
|
734
|
+
return i ? lineas.slice(i) : lineas;
|
|
735
|
+
}
|
|
498
736
|
export class Superficie {
|
|
499
737
|
o;
|
|
500
738
|
bloques = [];
|
|
501
739
|
lineas = [];
|
|
740
|
+
volcadas = 0;
|
|
741
|
+
subidas = 0;
|
|
742
|
+
vistaSucia = false;
|
|
502
743
|
anchoCompuesto = 0;
|
|
744
|
+
ultimoAlto = 0;
|
|
745
|
+
ultimoTrasBlanco = false;
|
|
503
746
|
encimaPintadas = 0;
|
|
504
747
|
carrilPintadas = 0;
|
|
505
748
|
activa = false;
|
|
506
749
|
oyente = null;
|
|
507
750
|
alRedimensionar = null;
|
|
751
|
+
alReanudar = null;
|
|
508
752
|
relojResize = null;
|
|
509
753
|
relojAnim = null;
|
|
510
754
|
relojAviso = null;
|
|
511
755
|
pegando = { pegando: false };
|
|
756
|
+
raton;
|
|
757
|
+
zonas = [];
|
|
758
|
+
sobre = null;
|
|
759
|
+
pulsado = null;
|
|
512
760
|
unidades = [];
|
|
513
761
|
cursor = 0;
|
|
514
762
|
pegados = [];
|
|
@@ -518,7 +766,7 @@ export class Superficie {
|
|
|
518
766
|
borrador = [];
|
|
519
767
|
menuCerradoPara = null;
|
|
520
768
|
menuElegida = 0;
|
|
521
|
-
cola =
|
|
769
|
+
cola = [];
|
|
522
770
|
ctrlC = 0;
|
|
523
771
|
ejemplo = null;
|
|
524
772
|
resolverLectura = null;
|
|
@@ -535,6 +783,7 @@ export class Superficie {
|
|
|
535
783
|
peligroPintado = false;
|
|
536
784
|
constructor(o) {
|
|
537
785
|
this.o = o;
|
|
786
|
+
this.raton = o.raton !== false;
|
|
538
787
|
}
|
|
539
788
|
get ancho() {
|
|
540
789
|
return Math.max(20, this.o.salida.columns || 80);
|
|
@@ -545,6 +794,9 @@ export class Superficie {
|
|
|
545
794
|
get enfocada() {
|
|
546
795
|
return this.foco;
|
|
547
796
|
}
|
|
797
|
+
get conRaton() {
|
|
798
|
+
return this.raton;
|
|
799
|
+
}
|
|
548
800
|
escribir(s) {
|
|
549
801
|
this.o.salida.write(s);
|
|
550
802
|
}
|
|
@@ -553,6 +805,7 @@ export class Superficie {
|
|
|
553
805
|
const ops = this.menuCerradoPara === valor ? null : opcionesDelMenu(valor);
|
|
554
806
|
if (ops && this.menuElegida >= ops.length)
|
|
555
807
|
this.menuElegida = Math.max(0, ops.length - 1);
|
|
808
|
+
const pendientes = this.lineas.length - this.volcadas;
|
|
556
809
|
return {
|
|
557
810
|
unidades: this.unidades.map((u) => this.vistaDeUnidad(u)),
|
|
558
811
|
cursor: this.cursor,
|
|
@@ -565,6 +818,8 @@ export class Superficie {
|
|
|
565
818
|
carriles: this.carriles,
|
|
566
819
|
gesto: this.pregunta ? 'pregunta' : this.trabajo || this.carriles.some((k) => k.estado === 'trabaja') ? (((this.trabajo?.paso ?? this.carriles[0]?.trabajo.paso ?? 0) >> 1) % 4) : this.gesto,
|
|
567
820
|
ahora: Date.now(),
|
|
821
|
+
sobre: this.raton ? this.sobre : null,
|
|
822
|
+
fondo: this.subidas > 0 || pendientes > 0 ? { nuevas: pendientes } : null,
|
|
568
823
|
};
|
|
569
824
|
}
|
|
570
825
|
vistaDeUnidad(u) {
|
|
@@ -584,14 +839,31 @@ export class Superficie {
|
|
|
584
839
|
return this.alto - n + 1;
|
|
585
840
|
}
|
|
586
841
|
desplazadas(altoCarril) {
|
|
587
|
-
return Math.max(0, this.
|
|
842
|
+
return Math.max(0, this.volcadas - (this.alto - altoCarril));
|
|
588
843
|
}
|
|
589
844
|
filaTrasLaConversacion(altoCarril) {
|
|
590
|
-
return Math.min(this.
|
|
845
|
+
return Math.min(this.volcadas, Math.max(0, this.alto - altoCarril)) + 1;
|
|
591
846
|
}
|
|
592
847
|
lineaDeFila(fila, altoCarril) {
|
|
593
|
-
const indice = this.desplazadas(altoCarril) + (fila - 1);
|
|
594
|
-
return indice >= 0 ? (this.lineas[indice] ?? '') : '';
|
|
848
|
+
const indice = this.desplazadas(altoCarril) - this.subidas + (fila - 1);
|
|
849
|
+
return indice >= 0 && indice < this.volcadas ? (this.lineas[indice] ?? '') : '';
|
|
850
|
+
}
|
|
851
|
+
componerTodo() {
|
|
852
|
+
const out = [];
|
|
853
|
+
for (const b of this.bloques) {
|
|
854
|
+
this.ultimoTrasBlanco = out.length === 0 || out[out.length - 1].trim() === '';
|
|
855
|
+
const l = sinBlancoDoble(b(this.ancho), this.ultimoTrasBlanco);
|
|
856
|
+
this.ultimoAlto = l.length;
|
|
857
|
+
out.push(...l);
|
|
858
|
+
}
|
|
859
|
+
this.lineas = out;
|
|
860
|
+
}
|
|
861
|
+
recortarMemoria() {
|
|
862
|
+
const sobran = this.lineas.length - MAX_LINEAS;
|
|
863
|
+
if (sobran <= 0)
|
|
864
|
+
return;
|
|
865
|
+
this.lineas.splice(0, sobran);
|
|
866
|
+
this.volcadas = Math.max(0, this.volcadas - sobran);
|
|
595
867
|
}
|
|
596
868
|
pintar() {
|
|
597
869
|
if (!this.activa)
|
|
@@ -607,21 +879,34 @@ export class Superficie {
|
|
|
607
879
|
const k = componerCarril(this.datos(), this.ancho, this.alto);
|
|
608
880
|
const n = k.carril.length;
|
|
609
881
|
let s = '\x1b[?2026h\x1b[?25l';
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if (subir)
|
|
615
|
-
s += `\x1b[${this.alto};1H${'\r\n'.repeat(subir)}`;
|
|
882
|
+
const subido = this.subidas > 0 || this.volcadas < this.lineas.length;
|
|
883
|
+
if (this.carrilPintadas && n !== this.carrilPintadas && subido) {
|
|
884
|
+
this.vistaSucia = true;
|
|
885
|
+
this.encimaPintadas = 0;
|
|
616
886
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
887
|
+
else {
|
|
888
|
+
if (this.carrilPintadas && n > this.carrilPintadas) {
|
|
889
|
+
s += this.destapar();
|
|
890
|
+
const ocupadas = Math.min(this.volcadas, Math.max(0, this.alto - this.carrilPintadas));
|
|
891
|
+
const subir = Math.max(0, ocupadas - Math.max(0, this.alto - n));
|
|
892
|
+
if (subir)
|
|
893
|
+
s += `\x1b[${this.alto};1H${'\r\n'.repeat(subir)}`;
|
|
894
|
+
}
|
|
895
|
+
if (this.carrilPintadas && n < this.carrilPintadas) {
|
|
896
|
+
s += this.destapar();
|
|
897
|
+
const topNuevo = this.filaDelCarril(n);
|
|
898
|
+
for (let fila = 1; fila < topNuevo; fila++)
|
|
899
|
+
s += `\x1b[${fila};1H\x1b[2K${this.lineaDeFila(fila, n)}`;
|
|
900
|
+
}
|
|
622
901
|
}
|
|
623
902
|
this.carrilPintadas = n;
|
|
624
903
|
const top = this.filaDelCarril(n);
|
|
904
|
+
if (this.vistaSucia) {
|
|
905
|
+
for (let fila = 1; fila < top; fila++)
|
|
906
|
+
s += `\x1b[${fila};1H\x1b[2K${this.lineaDeFila(fila, n)}`;
|
|
907
|
+
this.vistaSucia = false;
|
|
908
|
+
this.encimaPintadas = 0;
|
|
909
|
+
}
|
|
625
910
|
for (let i = k.encima.length; i < this.encimaPintadas; i++) {
|
|
626
911
|
const fila = top - 1 - i;
|
|
627
912
|
if (fila >= 1)
|
|
@@ -636,6 +921,12 @@ export class Superficie {
|
|
|
636
921
|
k.carril.forEach((l, i) => {
|
|
637
922
|
s += `\x1b[${top + i};1H\x1b[2K${l}`;
|
|
638
923
|
});
|
|
924
|
+
this.zonas = [
|
|
925
|
+
...k.zonasEncima.map((z) => ({ ...z, fila: top - k.encima.length + z.fila })),
|
|
926
|
+
...k.zonas.map((z) => ({ ...z, fila: top + z.fila })),
|
|
927
|
+
];
|
|
928
|
+
if (this.sobre && !this.zonas.some((z) => z.id === this.sobre))
|
|
929
|
+
this.sobre = null;
|
|
639
930
|
if (k.cursor)
|
|
640
931
|
s += `\x1b[${top + k.cursor.fila};${k.cursor.col + 1}H\x1b[?25h`;
|
|
641
932
|
s += '\x1b[?2026l';
|
|
@@ -659,9 +950,13 @@ export class Superficie {
|
|
|
659
950
|
this.consejosVisibles = false;
|
|
660
951
|
if (!this.activa)
|
|
661
952
|
return;
|
|
662
|
-
this.
|
|
663
|
-
|
|
664
|
-
|
|
953
|
+
if (this.subidas > 0 || this.volcadas < this.lineas.length) {
|
|
954
|
+
this.recomponer();
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
this.componerTodo();
|
|
958
|
+
this.volcadas = this.lineas.length;
|
|
959
|
+
this.recortarMemoria();
|
|
665
960
|
const n = componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
666
961
|
const top = this.filaDelCarril(n);
|
|
667
962
|
let s = '\x1b[?2026h\x1b[?25l';
|
|
@@ -672,41 +967,68 @@ export class Superficie {
|
|
|
672
967
|
this.escribir(s);
|
|
673
968
|
this.pintar();
|
|
674
969
|
}
|
|
970
|
+
terminaEnBlanco() {
|
|
971
|
+
const ultima = this.lineas[this.lineas.length - 1];
|
|
972
|
+
return ultima === undefined || ultima.trim() === '';
|
|
973
|
+
}
|
|
675
974
|
anadir(b) {
|
|
676
975
|
this.ocultarConsejos();
|
|
677
|
-
const destapado = this.activa ? this.destapar() : '';
|
|
678
|
-
const n = this.activa ? this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length : 0;
|
|
679
|
-
const desde = this.activa ? this.filaTrasLaConversacion(n) : 0;
|
|
680
976
|
this.bloques.push(b);
|
|
681
977
|
if (this.bloques.length > MAX_BLOQUES)
|
|
682
978
|
this.bloques.splice(0, this.bloques.length - MAX_BLOQUES);
|
|
683
|
-
|
|
979
|
+
this.ultimoTrasBlanco = this.terminaEnBlanco();
|
|
980
|
+
const nuevas = sinBlancoDoble(b(this.ancho), this.ultimoTrasBlanco);
|
|
981
|
+
this.ultimoAlto = nuevas.length;
|
|
982
|
+
if (this.activa && (this.subidas > 0 || this.volcadas < this.lineas.length)) {
|
|
983
|
+
this.lineas.push(...nuevas);
|
|
984
|
+
this.recortarMemoria();
|
|
985
|
+
this.pintar();
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
const destapado = this.activa ? this.destapar() : '';
|
|
684
989
|
this.lineas.push(...nuevas);
|
|
685
|
-
if (this.
|
|
686
|
-
this.
|
|
687
|
-
|
|
990
|
+
if (!this.activa) {
|
|
991
|
+
this.volcadas = this.lineas.length;
|
|
992
|
+
this.recortarMemoria();
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
this.escribir(destapado);
|
|
996
|
+
this.volcar();
|
|
997
|
+
this.pintar();
|
|
998
|
+
}
|
|
999
|
+
volcar() {
|
|
1000
|
+
const nuevas = this.lineas.slice(this.volcadas);
|
|
1001
|
+
if (!nuevas.length)
|
|
688
1002
|
return;
|
|
689
|
-
|
|
690
|
-
|
|
1003
|
+
const n = this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
1004
|
+
const desde = this.filaTrasLaConversacion(n);
|
|
1005
|
+
let s = `\x1b[?2026h\x1b[?25l\x1b[${desde};1H\x1b[J`;
|
|
691
1006
|
s += nuevas.map((l) => `${l}\x1b[K\r\n`).join('');
|
|
692
1007
|
s += '\r\n'.repeat(Math.max(0, n - 1));
|
|
693
1008
|
s += '\x1b[?2026l';
|
|
1009
|
+
this.volcadas = this.lineas.length;
|
|
1010
|
+
this.recortarMemoria();
|
|
1011
|
+
this.encimaPintadas = 0;
|
|
694
1012
|
this.escribir(s);
|
|
695
|
-
this.pintar();
|
|
696
1013
|
}
|
|
697
1014
|
ultimoBloque() {
|
|
698
1015
|
return this.bloques[this.bloques.length - 1];
|
|
699
1016
|
}
|
|
700
1017
|
reemplazarUltimo(b) {
|
|
701
1018
|
const viejo = this.ultimoBloque();
|
|
702
|
-
const k = viejo ?
|
|
703
|
-
const nuevas = b(this.ancho);
|
|
1019
|
+
const k = viejo ? this.ultimoAlto : -1;
|
|
1020
|
+
const nuevas = sinBlancoDoble(b(this.ancho), this.ultimoTrasBlanco);
|
|
704
1021
|
if (!viejo || !this.activa || nuevas.length !== k || this.encimaPintadas > 0 || this.lineas.length < k) {
|
|
705
1022
|
this.anadir(b);
|
|
706
1023
|
return;
|
|
707
1024
|
}
|
|
708
1025
|
this.bloques[this.bloques.length - 1] = b;
|
|
709
1026
|
this.lineas.splice(this.lineas.length - k, k, ...nuevas);
|
|
1027
|
+
if (this.subidas > 0 || this.volcadas < this.lineas.length) {
|
|
1028
|
+
this.vistaSucia = true;
|
|
1029
|
+
this.pintar();
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
710
1032
|
const n = this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
711
1033
|
const primera = this.lineas.length - k - this.desplazadas(n) + 1;
|
|
712
1034
|
let s = '\x1b[?2026h\x1b[?25l';
|
|
@@ -724,9 +1046,10 @@ export class Superficie {
|
|
|
724
1046
|
return;
|
|
725
1047
|
fijarCapacidades({ ancho: this.ancho });
|
|
726
1048
|
this.anchoCompuesto = this.ancho;
|
|
727
|
-
this.
|
|
728
|
-
|
|
729
|
-
|
|
1049
|
+
this.componerTodo();
|
|
1050
|
+
this.volcadas = this.lineas.length;
|
|
1051
|
+
this.subidas = 0;
|
|
1052
|
+
this.recortarMemoria();
|
|
730
1053
|
const n = componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
731
1054
|
let s = alEmpezar ? `\x1b[?2026h\x1b[?25l${'\r\n'.repeat(this.alto)}\x1b[H` : '\x1b[?2026h\x1b[?25l\x1b[H\x1b[2J\x1b[3J\x1b[H';
|
|
732
1055
|
s += this.lineas.map((l) => `${l}\x1b[K\r\n`).join('');
|
|
@@ -737,6 +1060,113 @@ export class Superficie {
|
|
|
737
1060
|
this.escribir(s);
|
|
738
1061
|
this.pintar();
|
|
739
1062
|
}
|
|
1063
|
+
filasDeVista() {
|
|
1064
|
+
return Math.max(1, this.filaDelCarril(this.carrilPintadas || 3) - 1);
|
|
1065
|
+
}
|
|
1066
|
+
desplazar(n) {
|
|
1067
|
+
if (!this.activa)
|
|
1068
|
+
return;
|
|
1069
|
+
const max = this.desplazadas(this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length);
|
|
1070
|
+
const nuevo = Math.max(0, Math.min(max, this.subidas + n));
|
|
1071
|
+
if (nuevo === 0) {
|
|
1072
|
+
if (this.subidas > 0 || this.volcadas < this.lineas.length)
|
|
1073
|
+
this.irAlFondo();
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (nuevo === this.subidas)
|
|
1077
|
+
return;
|
|
1078
|
+
this.subidas = nuevo;
|
|
1079
|
+
this.vistaSucia = true;
|
|
1080
|
+
this.pintar();
|
|
1081
|
+
}
|
|
1082
|
+
irAlFondo() {
|
|
1083
|
+
if (!this.activa || (this.subidas === 0 && this.volcadas === this.lineas.length))
|
|
1084
|
+
return;
|
|
1085
|
+
this.subidas = 0;
|
|
1086
|
+
const n = this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
1087
|
+
const top = this.filaDelCarril(n);
|
|
1088
|
+
let s = '\x1b[?2026h\x1b[?25l';
|
|
1089
|
+
for (let fila = 1; fila < top; fila++)
|
|
1090
|
+
s += `\x1b[${fila};1H\x1b[2K${this.lineaDeFila(fila, n)}`;
|
|
1091
|
+
s += '\x1b[?2026l';
|
|
1092
|
+
this.encimaPintadas = 0;
|
|
1093
|
+
this.escribir(s);
|
|
1094
|
+
this.volcar();
|
|
1095
|
+
this.pintar();
|
|
1096
|
+
}
|
|
1097
|
+
get _vista() {
|
|
1098
|
+
return { subidas: this.subidas, pendientes: this.lineas.length - this.volcadas };
|
|
1099
|
+
}
|
|
1100
|
+
fijarRaton(si) {
|
|
1101
|
+
this.raton = si;
|
|
1102
|
+
this.sobre = null;
|
|
1103
|
+
this.pulsado = null;
|
|
1104
|
+
if (this.activa)
|
|
1105
|
+
this.escribir(si ? RATON_SI : RATON_NO);
|
|
1106
|
+
if (!si)
|
|
1107
|
+
this.irAlFondo();
|
|
1108
|
+
this.pintar();
|
|
1109
|
+
}
|
|
1110
|
+
zonaEn(x, y) {
|
|
1111
|
+
const col = x - 1;
|
|
1112
|
+
for (const z of this.zonas)
|
|
1113
|
+
if (z.fila === y && col >= z.desde && col < z.hasta)
|
|
1114
|
+
return z.id;
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
alRaton(k) {
|
|
1118
|
+
if (!this.raton)
|
|
1119
|
+
return;
|
|
1120
|
+
if (k.rueda) {
|
|
1121
|
+
this.desplazar(-k.rueda * 3);
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
const zona = this.zonaEn(k.x, k.y);
|
|
1125
|
+
if (k.mover && k.boton === 3) {
|
|
1126
|
+
if (zona !== this.sobre) {
|
|
1127
|
+
this.sobre = zona;
|
|
1128
|
+
this.pintar();
|
|
1129
|
+
}
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (k.boton !== 0 && !(k.soltar && k.boton === 3))
|
|
1133
|
+
return;
|
|
1134
|
+
if (!k.soltar) {
|
|
1135
|
+
if (!k.mover)
|
|
1136
|
+
this.pulsado = zona;
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
const pulsado = this.pulsado;
|
|
1140
|
+
this.pulsado = null;
|
|
1141
|
+
if (pulsado && zona === pulsado)
|
|
1142
|
+
this.activar(pulsado);
|
|
1143
|
+
}
|
|
1144
|
+
activar(id) {
|
|
1145
|
+
if (id === 'fondo')
|
|
1146
|
+
return this.irAlFondo();
|
|
1147
|
+
if (id === 'bandeja') {
|
|
1148
|
+
if (this.resolverLectura && !this.trabajo && !this.pregunta)
|
|
1149
|
+
this.o.alBandeja?.();
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
if (id === 'modo') {
|
|
1153
|
+
if (!this.pregunta)
|
|
1154
|
+
this.o.alCambiarModo?.();
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
const opcion = /^opcion:(\d+)$/.exec(id);
|
|
1158
|
+
if (opcion && this.pregunta)
|
|
1159
|
+
return this.responder(Number(opcion[1]));
|
|
1160
|
+
const menu = /^menu:(\d+)$/.exec(id);
|
|
1161
|
+
if (menu && !this.pregunta) {
|
|
1162
|
+
this.menuElegida = Number(menu[1]);
|
|
1163
|
+
this.tecla({ t: 'intro' });
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
modosSi() {
|
|
1167
|
+
return `\x1b[?2004h\x1b[?1004h${this.raton ? RATON_SI : ''}`;
|
|
1168
|
+
}
|
|
1169
|
+
static MODOS_NO = `${RATON_NO}\x1b[?2004l\x1b[?1004l\x1b[?25h`;
|
|
740
1170
|
iniciar(bienvenida, consejos = []) {
|
|
741
1171
|
if (this.activa)
|
|
742
1172
|
return;
|
|
@@ -744,7 +1174,7 @@ export class Superficie {
|
|
|
744
1174
|
if (bienvenida)
|
|
745
1175
|
this.bloques.push(bienvenida);
|
|
746
1176
|
if (consejos.length) {
|
|
747
|
-
const ocupado = (bienvenida ? bienvenida(this.ancho).length : 0) +
|
|
1177
|
+
const ocupado = (bienvenida ? bienvenida(this.ancho).length : 0) + componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
748
1178
|
let n = consejos.length;
|
|
749
1179
|
while (n > 0 && ocupado + bloqueDeConsejos(() => consejos.slice(0, n))(this.ancho).length > this.alto)
|
|
750
1180
|
n--;
|
|
@@ -753,7 +1183,7 @@ export class Superficie {
|
|
|
753
1183
|
if (n > 0)
|
|
754
1184
|
this.bloques.push(bloqueDeConsejos(() => (this.consejosVisibles ? this.consejos : [])));
|
|
755
1185
|
}
|
|
756
|
-
this.escribir(
|
|
1186
|
+
this.escribir(this.modosSi());
|
|
757
1187
|
try {
|
|
758
1188
|
this.o.entrada.setRawMode?.(true);
|
|
759
1189
|
}
|
|
@@ -799,12 +1229,13 @@ export class Superficie {
|
|
|
799
1229
|
terminar(despedida) {
|
|
800
1230
|
if (!this.activa)
|
|
801
1231
|
return;
|
|
1232
|
+
this.irAlFondo();
|
|
802
1233
|
const n = this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
803
1234
|
let s = this.destapar();
|
|
804
1235
|
s += `\x1b[${this.filaTrasLaConversacion(n)};1H\x1b[J`;
|
|
805
1236
|
if (despedida)
|
|
806
|
-
s += `${m}${despedida}\r\n`;
|
|
807
|
-
s +=
|
|
1237
|
+
s += `${this.terminaEnBlanco() ? '' : '\r\n'}${m}${despedida}\r\n`;
|
|
1238
|
+
s += Superficie.MODOS_NO;
|
|
808
1239
|
this.escribir(s);
|
|
809
1240
|
this.activa = false;
|
|
810
1241
|
if (this.relojAnim)
|
|
@@ -817,6 +1248,8 @@ export class Superficie {
|
|
|
817
1248
|
this.o.entrada.removeListener('data', this.oyente);
|
|
818
1249
|
if (this.alRedimensionar)
|
|
819
1250
|
this.o.salida.removeListener('resize', this.alRedimensionar);
|
|
1251
|
+
if (this.alReanudar)
|
|
1252
|
+
process.removeListener('SIGCONT', this.alReanudar);
|
|
820
1253
|
try {
|
|
821
1254
|
this.o.entrada.setRawMode?.(false);
|
|
822
1255
|
}
|
|
@@ -827,21 +1260,65 @@ export class Superficie {
|
|
|
827
1260
|
restaurarDeUrgencia() {
|
|
828
1261
|
if (!this.activa)
|
|
829
1262
|
return;
|
|
830
|
-
this.o.salida.write(
|
|
1263
|
+
this.o.salida.write(`${Superficie.MODOS_NO}\x1b[?2026l`);
|
|
831
1264
|
try {
|
|
832
1265
|
this.o.entrada.setRawMode?.(false);
|
|
833
1266
|
}
|
|
834
1267
|
catch {
|
|
835
1268
|
}
|
|
836
1269
|
}
|
|
1270
|
+
suspender() {
|
|
1271
|
+
if (process.platform === 'win32' && !this.o.suspenderProceso)
|
|
1272
|
+
return;
|
|
1273
|
+
this.irAlFondo();
|
|
1274
|
+
const n = this.carrilPintadas || componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
1275
|
+
let s = this.destapar();
|
|
1276
|
+
s += `\x1b[${this.filaTrasLaConversacion(n)};1H\x1b[J`;
|
|
1277
|
+
s += Superficie.MODOS_NO;
|
|
1278
|
+
this.escribir(s);
|
|
1279
|
+
try {
|
|
1280
|
+
this.o.entrada.setRawMode?.(false);
|
|
1281
|
+
}
|
|
1282
|
+
catch {
|
|
1283
|
+
}
|
|
1284
|
+
if (!this.alReanudar) {
|
|
1285
|
+
this.alReanudar = () => this.reanudar();
|
|
1286
|
+
if (!this.o.suspenderProceso)
|
|
1287
|
+
process.on('SIGCONT', this.alReanudar);
|
|
1288
|
+
}
|
|
1289
|
+
if (this.o.suspenderProceso)
|
|
1290
|
+
this.o.suspenderProceso();
|
|
1291
|
+
else
|
|
1292
|
+
process.kill(process.pid, 'SIGTSTP');
|
|
1293
|
+
}
|
|
1294
|
+
reanudar() {
|
|
1295
|
+
if (!this.activa)
|
|
1296
|
+
return;
|
|
1297
|
+
try {
|
|
1298
|
+
this.o.entrada.setRawMode?.(true);
|
|
1299
|
+
}
|
|
1300
|
+
catch {
|
|
1301
|
+
}
|
|
1302
|
+
this.o.entrada.resume();
|
|
1303
|
+
const n = componerCarril(this.datos(), this.ancho, this.alto).carril.length;
|
|
1304
|
+
let s = `\x1b[?2026h\x1b[?25l${this.modosSi()}${'\r\n'.repeat(this.alto)}`;
|
|
1305
|
+
for (let fila = 1; fila < this.filaDelCarril(n); fila++)
|
|
1306
|
+
s += `\x1b[${fila};1H\x1b[2K${this.lineaDeFila(fila, n)}`;
|
|
1307
|
+
s += '\x1b[?2026l';
|
|
1308
|
+
this.carrilPintadas = n;
|
|
1309
|
+
this.encimaPintadas = 0;
|
|
1310
|
+
this.escribir(s);
|
|
1311
|
+
this.pintar();
|
|
1312
|
+
}
|
|
837
1313
|
leer(ejemplo = null) {
|
|
838
1314
|
this.ejemplo = ejemplo;
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1315
|
+
const enCola = this.cola.shift();
|
|
1316
|
+
if (enCola !== undefined) {
|
|
1317
|
+
const r = enCola;
|
|
842
1318
|
this.ejemplo = null;
|
|
843
|
-
this.mostrarAviso(null);
|
|
844
|
-
|
|
1319
|
+
this.mostrarAviso(this.cola.length ? tt('tui.en_cola_n', { n: this.cola.length }) : null);
|
|
1320
|
+
if (r.trim() && r.trim() !== '!')
|
|
1321
|
+
this.anadir(this.bloqueDeEnvio(r));
|
|
845
1322
|
return Promise.resolve(this.expandir(r));
|
|
846
1323
|
}
|
|
847
1324
|
return new Promise((resolver) => {
|
|
@@ -852,6 +1329,15 @@ export class Superficie {
|
|
|
852
1329
|
this.pintar();
|
|
853
1330
|
});
|
|
854
1331
|
}
|
|
1332
|
+
escribirYMandar(texto) {
|
|
1333
|
+
if (!this.libre)
|
|
1334
|
+
return;
|
|
1335
|
+
this.ponerValor(texto);
|
|
1336
|
+
this.enviar();
|
|
1337
|
+
}
|
|
1338
|
+
get libre() {
|
|
1339
|
+
return Boolean(this.resolverLectura) && !this.trabajo && !this.pregunta;
|
|
1340
|
+
}
|
|
855
1341
|
trabajar(alParar) {
|
|
856
1342
|
if (this.trabajo)
|
|
857
1343
|
this.trabajo.alParar = alParar;
|
|
@@ -885,31 +1371,55 @@ export class Superficie {
|
|
|
885
1371
|
this.pintar();
|
|
886
1372
|
}
|
|
887
1373
|
preguntar(texto, tipo = 'normal') {
|
|
1374
|
+
const o = opcionesDePregunta(tipo);
|
|
1375
|
+
const peligro = tipo === 'bypass';
|
|
888
1376
|
return new Promise((resolver) => {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1377
|
+
this.mostrarPregunta({
|
|
1378
|
+
texto,
|
|
1379
|
+
opciones: o.opciones,
|
|
1380
|
+
cortas: o.cortas,
|
|
1381
|
+
elegida: o.elegida,
|
|
1382
|
+
...(peligro ? { peligro: true } : {}),
|
|
1383
|
+
indiceNo: o.valores.indexOf('no'),
|
|
1384
|
+
siConY: o.valores[o.elegida] !== 'no' || peligro,
|
|
1385
|
+
}, (i) => resolver(i === null ? 'no' : (o.valores[i] ?? 'no')));
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
elegir(texto, opciones, o = {}) {
|
|
1389
|
+
return new Promise((resolver) => {
|
|
1390
|
+
this.mostrarPregunta({
|
|
1391
|
+
texto,
|
|
1392
|
+
...(o.detalle ? { detalle: o.detalle } : {}),
|
|
1393
|
+
opciones: opciones.map((x) => x.etiqueta),
|
|
1394
|
+
cortas: opciones.map((x) => x.corta ?? x.etiqueta),
|
|
1395
|
+
notas: opciones.map((x) => ({ nota: x.nota, recomendada: x.recomendada, peligro: x.peligro })),
|
|
1396
|
+
elegida: Math.max(0, Math.min(opciones.length - 1, o.elegida ?? 0)),
|
|
1397
|
+
...(o.vertical ? { vertical: true } : {}),
|
|
1398
|
+
indiceNo: null,
|
|
1399
|
+
siConY: false,
|
|
1400
|
+
}, resolver);
|
|
899
1401
|
});
|
|
900
1402
|
}
|
|
1403
|
+
mostrarPregunta(p, resolver) {
|
|
1404
|
+
const mostrar = () => {
|
|
1405
|
+
this.pregunta = { ...p, resolver, sordaHasta: Date.now() + this.guardaDePregunta };
|
|
1406
|
+
this.o.alPreguntar?.(p.texto);
|
|
1407
|
+
this.pintar();
|
|
1408
|
+
};
|
|
1409
|
+
if (this.pregunta)
|
|
1410
|
+
this.esperando.push(mostrar);
|
|
1411
|
+
else
|
|
1412
|
+
mostrar();
|
|
1413
|
+
}
|
|
901
1414
|
responder(i) {
|
|
902
1415
|
const p = this.pregunta;
|
|
903
1416
|
if (!p)
|
|
904
1417
|
return;
|
|
905
|
-
const r = p.valores[i] ?? 'no';
|
|
906
1418
|
this.pregunta = null;
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
this.pintar();
|
|
912
|
-
p.resolver(r);
|
|
1419
|
+
this.sobre = null;
|
|
1420
|
+
this.pulsado = null;
|
|
1421
|
+
this.pintar();
|
|
1422
|
+
p.resolver(i);
|
|
913
1423
|
this.esperando.shift()?.();
|
|
914
1424
|
}
|
|
915
1425
|
mostrarAviso(texto, ms = 0) {
|
|
@@ -933,14 +1443,18 @@ export class Superficie {
|
|
|
933
1443
|
}
|
|
934
1444
|
expandir(v) {
|
|
935
1445
|
return v
|
|
936
|
-
.replace(
|
|
937
|
-
.replace(
|
|
1446
|
+
.replace(/(\d+)/g, (_x, i) => this.pegados[Number(i)] ?? '')
|
|
1447
|
+
.replace(/(\d+)/g, (_x, i) => `${this.imagenes[Number(i)] ?? ''}`);
|
|
1448
|
+
}
|
|
1449
|
+
bloqueDeEnvio(crudo) {
|
|
1450
|
+
const v = crudo.trim();
|
|
1451
|
+
return v.startsWith('!') ? bloqueDeBash(this.vistaDeEnvio(v.slice(1).trim())) : bloqueDeLaPersona(this.vistaDeEnvio(v));
|
|
938
1452
|
}
|
|
939
1453
|
vistaDeEnvio(v) {
|
|
940
|
-
return v.replace(/[
|
|
1454
|
+
return v.replace(/[]\d+/g, (x) => sinColorSimple(this.vistaDeUnidad(x)));
|
|
941
1455
|
}
|
|
942
1456
|
ponerValor(v) {
|
|
943
|
-
this.unidades = v.match(/[
|
|
1457
|
+
this.unidades = v.match(/[]\d+|[\s\S]/gu) ?? [];
|
|
944
1458
|
this.cursor = this.unidades.length;
|
|
945
1459
|
}
|
|
946
1460
|
insertar(texto) {
|
|
@@ -959,17 +1473,18 @@ export class Superficie {
|
|
|
959
1473
|
if (v && this.historial[this.historial.length - 1] !== crudo)
|
|
960
1474
|
this.historial.push(crudo);
|
|
961
1475
|
this.posHistorial = this.historial.length;
|
|
1476
|
+
this.irAlFondo();
|
|
962
1477
|
if (this.trabajo || !this.resolverLectura) {
|
|
963
1478
|
if (v) {
|
|
964
|
-
this.cola
|
|
965
|
-
this.mostrarAviso(tt('tui.en_cola'));
|
|
1479
|
+
this.cola.push(crudo);
|
|
1480
|
+
this.mostrarAviso(this.cola.length > 1 ? tt('tui.en_cola_n', { n: this.cola.length }) : tt('tui.en_cola'));
|
|
966
1481
|
}
|
|
967
1482
|
return;
|
|
968
1483
|
}
|
|
969
1484
|
const r = this.resolverLectura;
|
|
970
1485
|
this.resolverLectura = null;
|
|
971
|
-
if (v)
|
|
972
|
-
this.anadir(
|
|
1486
|
+
if (v && v !== '!')
|
|
1487
|
+
this.anadir(this.bloqueDeEnvio(crudo));
|
|
973
1488
|
else
|
|
974
1489
|
this.pintar();
|
|
975
1490
|
r(this.expandir(crudo));
|
|
@@ -986,6 +1501,14 @@ export class Superficie {
|
|
|
986
1501
|
this.foco = k.t === 'foco_si';
|
|
987
1502
|
return;
|
|
988
1503
|
}
|
|
1504
|
+
if (k.t === 'raton')
|
|
1505
|
+
return this.alRaton(k);
|
|
1506
|
+
if (k.t === 'pagina_arriba' || k.t === 'pagina_abajo')
|
|
1507
|
+
return this.desplazar((k.t === 'pagina_arriba' ? 1 : -1) * Math.max(1, this.filasDeVista() - 2));
|
|
1508
|
+
if (k.t === 'fondo')
|
|
1509
|
+
return this.irAlFondo();
|
|
1510
|
+
if (k.t === 'suspender')
|
|
1511
|
+
return this.suspender();
|
|
989
1512
|
if (this.pregunta)
|
|
990
1513
|
return this.teclaDePregunta(k);
|
|
991
1514
|
if (k.t !== 'ctrlc' && this.ctrlC && !this.trabajo) {
|
|
@@ -1007,13 +1530,13 @@ export class Superficie {
|
|
|
1007
1530
|
const imagen = rutaDeImagenPegada(v);
|
|
1008
1531
|
if (imagen) {
|
|
1009
1532
|
this.imagenes.push(imagen);
|
|
1010
|
-
this.unidades.splice(this.cursor, 0,
|
|
1533
|
+
this.unidades.splice(this.cursor, 0, `${this.imagenes.length - 1}`, ' ');
|
|
1011
1534
|
this.cursor += 2;
|
|
1012
1535
|
break;
|
|
1013
1536
|
}
|
|
1014
1537
|
if (v.includes('\n') || v.length > PEGADO_LARGO) {
|
|
1015
1538
|
this.pegados.push(v);
|
|
1016
|
-
this.unidades.splice(this.cursor, 0,
|
|
1539
|
+
this.unidades.splice(this.cursor, 0, `${this.pegados.length - 1}`);
|
|
1017
1540
|
this.cursor++;
|
|
1018
1541
|
}
|
|
1019
1542
|
else
|
|
@@ -1042,6 +1565,8 @@ export class Superficie {
|
|
|
1042
1565
|
this.menuCerradoPara = valor;
|
|
1043
1566
|
else if (this.trabajo)
|
|
1044
1567
|
this.trabajo.alParar();
|
|
1568
|
+
else if (this.subidas > 0 || this.volcadas < this.lineas.length)
|
|
1569
|
+
this.irAlFondo();
|
|
1045
1570
|
break;
|
|
1046
1571
|
case 'borrar':
|
|
1047
1572
|
if (this.cursor > 0) {
|
|
@@ -1083,6 +1608,8 @@ export class Superficie {
|
|
|
1083
1608
|
this.cursor = 0;
|
|
1084
1609
|
break;
|
|
1085
1610
|
case 'fin':
|
|
1611
|
+
if (this.cursor >= this.unidades.length && (this.subidas > 0 || this.volcadas < this.lineas.length))
|
|
1612
|
+
this.irAlFondo();
|
|
1086
1613
|
this.cursor = this.unidades.length;
|
|
1087
1614
|
break;
|
|
1088
1615
|
case 'borrar_linea':
|
|
@@ -1157,17 +1684,38 @@ export class Superficie {
|
|
|
1157
1684
|
break;
|
|
1158
1685
|
}
|
|
1159
1686
|
}
|
|
1687
|
+
get guardaDePregunta() {
|
|
1688
|
+
return this.o.guardaDePreguntaMs ?? (this.o.quieta ? 0 : 600);
|
|
1689
|
+
}
|
|
1160
1690
|
teclaDePregunta(k) {
|
|
1161
1691
|
const p = this.pregunta;
|
|
1162
1692
|
const n = p.opciones.length;
|
|
1693
|
+
const ahora = Date.now();
|
|
1694
|
+
if (k.t === 'esc' || k.t === 'ctrlc')
|
|
1695
|
+
return this.responder(p.indiceNo);
|
|
1696
|
+
const r0 = k.t === 'texto' ? k.v.trim().toLowerCase() : '';
|
|
1697
|
+
const esRespuesta = k.t === 'texto' && (/^[1-9]$/.test(r0) || ((r0 === 'y' || r0 === 'n') && p.indiceNo !== null));
|
|
1698
|
+
if (k.t === 'texto' && !esRespuesta) {
|
|
1699
|
+
this.insertar(k.v);
|
|
1700
|
+
p.escribiendo = true;
|
|
1701
|
+
p.sordaHasta = Math.max(p.sordaHasta, ahora + this.guardaDePregunta);
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
if (ahora < p.sordaHasta) {
|
|
1705
|
+
if (k.t === 'texto' && p.escribiendo) {
|
|
1706
|
+
this.insertar(k.v);
|
|
1707
|
+
p.sordaHasta = ahora + this.guardaDePregunta;
|
|
1708
|
+
}
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1163
1711
|
if (k.t === 'texto') {
|
|
1164
1712
|
const r = k.v.trim().toLowerCase();
|
|
1165
1713
|
const num = Number(r);
|
|
1166
1714
|
if (Number.isInteger(num) && num >= 1 && num <= n)
|
|
1167
1715
|
return this.responder(num - 1);
|
|
1168
|
-
if (r === 'n')
|
|
1169
|
-
return this.responder(p.
|
|
1170
|
-
if (r === 'y' &&
|
|
1716
|
+
if (r === 'n' && p.indiceNo !== null)
|
|
1717
|
+
return this.responder(p.indiceNo);
|
|
1718
|
+
if (r === 'y' && p.siConY)
|
|
1171
1719
|
return this.responder(0);
|
|
1172
1720
|
return;
|
|
1173
1721
|
}
|
|
@@ -1177,8 +1725,6 @@ export class Superficie {
|
|
|
1177
1725
|
p.elegida = (p.elegida + 1) % n;
|
|
1178
1726
|
else if (k.t === 'intro')
|
|
1179
1727
|
this.responder(p.elegida);
|
|
1180
|
-
else if (k.t === 'esc' || k.t === 'ctrlc')
|
|
1181
|
-
this.responder(p.valores.indexOf('no'));
|
|
1182
1728
|
}
|
|
1183
1729
|
get _lineas() {
|
|
1184
1730
|
return this.lineas;
|
|
@@ -1192,6 +1738,9 @@ export class Superficie {
|
|
|
1192
1738
|
get _trabajo() {
|
|
1193
1739
|
return this.trabajo;
|
|
1194
1740
|
}
|
|
1741
|
+
get _zonas() {
|
|
1742
|
+
return this.zonas;
|
|
1743
|
+
}
|
|
1195
1744
|
}
|
|
1196
1745
|
function sinColorSimple(t) {
|
|
1197
1746
|
return t.replace(/\x1b\[[0-9;]*m/g, '');
|