luna-clasificador 1.2.2 → 1.2.4
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/BD/luna_db.json +2 -2
- package/EtiquetadorVariado.js +119 -0
- package/LUNA_clasificador.js +18 -1
- package/assets/1.png +0 -0
- package/assets/2.png +0 -0
- package/assets/3.png +0 -0
- package/assets/4.png +0 -0
- package/assets/5.png +0 -0
- package/assets/banner.png +0 -0
- package/package.json +8 -1
- package/readme.md +67 -0
- package/tests/luna_dashboard.html +4 -1
- package/tests/luna_dashboard_server.js +10 -0
- package/tests/probe_LUNA.js +8 -0
package/BD/luna_db.json
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// EtiquetadorVariado.js
|
|
2
|
+
// v1.3.0 — Determina la etiqueta específica para los archivos esVARIADO.
|
|
3
|
+
// Es un sistema de expansión modular.
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const Clasificador = require('./Clasificacion.js'); // Para reutilizar limpiadores si hace falta
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Determina la Etiqueta_V para un archivo variado.
|
|
11
|
+
* @param {Object} archivo - El objeto archivo del pipeline (con ruta, nombreOriginal, duracion, etc.)
|
|
12
|
+
* @param {Object} info - El objeto info actual (con nombreLimpio, etc.)
|
|
13
|
+
* @returns {string} - La etiqueta determinada.
|
|
14
|
+
*/
|
|
15
|
+
function determinarEtiquetaVariado(archivo, info) {
|
|
16
|
+
const nombreOrig = archivo.nombreOriginal || '';
|
|
17
|
+
const ruta = archivo.ruta || '';
|
|
18
|
+
const duracion = archivo.duracion || 0;
|
|
19
|
+
|
|
20
|
+
// ------------------------------------------------------------------------
|
|
21
|
+
// 1. Grabación de WhatsApp (se detecta por nombre y por ruta típica)
|
|
22
|
+
// ------------------------------------------------------------------------
|
|
23
|
+
// Patrones: PTT-20240719-WA0002.opus, VID-20231012-WA0001.mp4, AUD-...
|
|
24
|
+
if (/\b(?:PTT|VID|AUD|IMG)-\d{8}-WA\d{4}\b/i.test(nombreOrig)) {
|
|
25
|
+
return 'Grabación de WhatsApp';
|
|
26
|
+
}
|
|
27
|
+
// Ruta típica de WhatsApp en Android: .../WhatsApp/Media/WhatsApp Audio/ ...
|
|
28
|
+
if (/WhatsApp[\\\/]Media/i.test(ruta)) {
|
|
29
|
+
return 'Grabación de WhatsApp';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ------------------------------------------------------------------------
|
|
33
|
+
// 2. Grabación de pantalla (Screen Record)
|
|
34
|
+
// ------------------------------------------------------------------------
|
|
35
|
+
// Patrones: ScreenRecord_20261101_143022.mp4, ScreenCapture_..., OBS (2026-11-01-14-30-22)
|
|
36
|
+
if (/Screen(Record|Capture)_\d{8}_\d{6}/i.test(nombreOrig)) {
|
|
37
|
+
return 'Grabación de Pantalla';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (/(?:Screen Recording|Grabaci[oó]n de pantalla)\s+\d{8}\s+\d{6}/i.test(nombreOrig)) {
|
|
41
|
+
return 'Grabación de Pantalla';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (/^\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.(mp4|mkv|avi)$/i.test(nombreOrig)) {
|
|
45
|
+
return 'Grabación de Pantalla'; // Formato OBS
|
|
46
|
+
}
|
|
47
|
+
// Ruta típica de Android para Screen Record: .../DCIM/ScreenRecorder/ ...
|
|
48
|
+
if (/(ScreenRecorder|ScreenRecord|Grabaciones de pantalla)/i.test(ruta)) {
|
|
49
|
+
return 'Grabación de Pantalla';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ------------------------------------------------------------------------
|
|
53
|
+
// 3. Grabación de Cámara / DCIM (Teléfono o Cámara profesional)
|
|
54
|
+
// ------------------------------------------------------------------------
|
|
55
|
+
// Patrones: VID_20250115_143022.mp4, IMG_4821.MP4, _MG_4821.MOV
|
|
56
|
+
if (/\b(?:VID|IMG|_MG|DSC)_\d{4,8}/i.test(nombreOrig)) {
|
|
57
|
+
return 'Grabación de Cámara / DCIM';
|
|
58
|
+
}
|
|
59
|
+
// Ruta típica: .../DCIM/Camera/... o .../DCIM/100APPLE/...
|
|
60
|
+
if (/DCIM/i.test(ruta)) {
|
|
61
|
+
return 'Grabación de Cámara / DCIM';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ------------------------------------------------------------------------
|
|
65
|
+
// 4. Animados o Videos Cortos (Usa la DB de categoría 'variado')
|
|
66
|
+
// ------------------------------------------------------------------------
|
|
67
|
+
try {
|
|
68
|
+
// Para no ensuciar este archivo, importamos la DB de LUNA (simulada aquí, o pasada como parámetro)
|
|
69
|
+
// La mejor forma es que LUNA le pase la DB ya cargada, pero para mantenerlo desacoplado,
|
|
70
|
+
// haremos que la función reciba la DB o la cargue.
|
|
71
|
+
// (Esto lo ajustaremos en LUNA_clasificador.js)
|
|
72
|
+
const DB_PATH = path.join(__dirname, 'BD', 'luna_db.json');
|
|
73
|
+
if (fs.existsSync(DB_PATH)) {
|
|
74
|
+
const db = JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
|
|
75
|
+
// Usamos la misma lógica de normalización que usa LUNA para la DB
|
|
76
|
+
const normalizarClaveDB = (nombre) => {
|
|
77
|
+
if (!nombre) return '';
|
|
78
|
+
return String(nombre).normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().replace(/[\(\)\[\]\{\}]+/g, ' ').replace(/[_\.\-=\+]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
79
|
+
};
|
|
80
|
+
const clave = normalizarClaveDB(info.nombreLimpio || '');
|
|
81
|
+
const bucket = db.categorias && db.categorias['variado'] && db.categorias['variado'].nombres;
|
|
82
|
+
if (bucket) {
|
|
83
|
+
for (const key of Object.keys(bucket)) {
|
|
84
|
+
if (normalizarClaveDB(key) === clave) {
|
|
85
|
+
return 'Animado / Video Corto';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch (e) {
|
|
91
|
+
// Si falla la DB, no rompemos, seguimos
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ------------------------------------------------------------------------
|
|
95
|
+
// 5. VideoClick (Duración 1-6 min y patrón de corchetes [470k], (720P_HD))
|
|
96
|
+
// ------------------------------------------------------------------------
|
|
97
|
+
if (duracion >= 60 && duracion <= 360) { // 1 min a 6 min
|
|
98
|
+
// Busca corchetes con contenido que parezca métrica o calidad
|
|
99
|
+
if (/\[[^\]]+\]|\([^\)]+\)/.test(nombreOrig)) {
|
|
100
|
+
// Nos aseguramos de que no sea un tag técnico típico de peli (1080p, etc.)
|
|
101
|
+
if (!/\[\s*(1080p|2160p|720p|4k|bd|bluray)\s*\]/i.test(nombreOrig)) {
|
|
102
|
+
return 'VideoClick';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Patrón de música: "Artista - Título [Official Video]"
|
|
106
|
+
if (/\s[-–—]\s.*\[.*(?:Official|Video|Lyric|Audio).*\]/i.test(nombreOrig)) {
|
|
107
|
+
return 'VideoClick';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ------------------------------------------------------------------------
|
|
112
|
+
// 6. Variado (Fallback o desconocido)
|
|
113
|
+
// ------------------------------------------------------------------------
|
|
114
|
+
return 'Variado Desconocido';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
determinarEtiquetaVariado
|
|
119
|
+
};
|
package/LUNA_clasificador.js
CHANGED
|
@@ -14,7 +14,7 @@ const path = require('path');
|
|
|
14
14
|
const { setBinariosFromFolder, procesarDuracionMediainfo } = require('./Servicios/ProcesosCore.js');
|
|
15
15
|
const Clasificador = require('./Clasificacion.js');
|
|
16
16
|
const { guardarLogDebug } = require('./Debug/LUNA_Logger.js');
|
|
17
|
-
const VERSION_LUNA = '1.2.
|
|
17
|
+
const VERSION_LUNA = '1.2.4';
|
|
18
18
|
var seEjecuto = false;
|
|
19
19
|
var seEjecutoIPC = false;
|
|
20
20
|
|
|
@@ -916,6 +916,22 @@ function tomarDecision(paquete) {
|
|
|
916
916
|
}
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
+
// === NUEVO: Etiquetado específico para VARIADO ===
|
|
920
|
+
if (elegido === 'esVARIADO') {
|
|
921
|
+
try {
|
|
922
|
+
const Etiquetador = require('./EtiquetadorVariado.js');
|
|
923
|
+
const etiqueta = Etiquetador.determinarEtiquetaVariado(archivo, archivo.info);
|
|
924
|
+
archivo.info.Etiqueta_V = etiqueta;
|
|
925
|
+
} catch (e) {
|
|
926
|
+
paquete.errores.push({
|
|
927
|
+
etapa: 'tomarDecision.EtiquetaVariado',
|
|
928
|
+
ruta: archivo.ruta,
|
|
929
|
+
mensaje: e.message
|
|
930
|
+
});
|
|
931
|
+
archivo.info.Etiqueta_V = 'Variado Desconocido'; // Fallback seguro
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
919
935
|
// NUEVO: Si la DB lo marcó como película, forzamos.
|
|
920
936
|
if (esPeliDB) {
|
|
921
937
|
elegido = 'esPELI';
|
|
@@ -1206,6 +1222,7 @@ function transformarSalida(paquete) {
|
|
|
1206
1222
|
nombreLimpio: archivo.nombreLimpio,
|
|
1207
1223
|
tituloLimpio: archivo.info.tituloLimpio || null,
|
|
1208
1224
|
fechaExtra: archivo.info.fechaExtra || null,
|
|
1225
|
+
Etiqueta_V: archivo.info.Etiqueta_V || null,
|
|
1209
1226
|
ruta: archivo.ruta,
|
|
1210
1227
|
info: archivo.info,
|
|
1211
1228
|
extension: archivo.extension || archivo.info?.extension || archivo.ext || path.extname(archivo.nombreOriginal).replace('.', '').toLowerCase(),
|
package/assets/1.png
ADDED
|
Binary file
|
package/assets/2.png
ADDED
|
Binary file
|
package/assets/3.png
ADDED
|
Binary file
|
package/assets/4.png
ADDED
|
Binary file
|
package/assets/5.png
ADDED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luna-clasificador",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"icon": "assets/icons.png",
|
|
5
5
|
"description": "Clasificador local de archivos multimedia (película, serie, variado, programa, novela)",
|
|
6
6
|
"main": "LUNA.js",
|
|
7
7
|
"files": [
|
|
8
8
|
"LUNA_clasificador.js",
|
|
9
9
|
"Clasificacion.js",
|
|
10
|
+
"EtiquetadorVariado.js",
|
|
10
11
|
"Debug/LUNA_Logger.js",
|
|
11
12
|
"tests/probe_LUNA.js",
|
|
12
13
|
"tests/luna_dashboard_server.js",
|
|
13
14
|
"tests/luna_dashboard.html",
|
|
14
15
|
"assets/icons.png",
|
|
16
|
+
"assets/banner.png",
|
|
17
|
+
"assets/1.png",
|
|
18
|
+
"assets/2.png",
|
|
19
|
+
"assets/3.png",
|
|
20
|
+
"assets/4.png",
|
|
21
|
+
"assets/5.png",
|
|
15
22
|
"LUNA.js",
|
|
16
23
|
"Servicios/ProcesosCore.js",
|
|
17
24
|
"Servicios/ResolverPathffmpeg.js",
|
package/readme.md
CHANGED
|
@@ -60,6 +60,73 @@ Fue diseñado para ordenar discos duros llenos de series, películas, novelas y
|
|
|
60
60
|
> Versión actual del proyecto: **1.2.1**
|
|
61
61
|
> Base de datos actual: **1.0.0**
|
|
62
62
|
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
***
|
|
66
|
+
|
|
67
|
+
## 🆕 Novedades en v1.2.4: Etiquetado Inteligente de Variados
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="./assets/4.png" width="100%">
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
En esta versión, LUNA no solo clasifica los archivos como `esVARIADO`, sino que ahora es capaz de **sub-clasificarlos** con una etiqueta semántica (`Etiqueta_V`).
|
|
74
|
+
|
|
75
|
+
Sabemos que en la categoría "Variado" cae de todo: desde un clip de YouTube, hasta una nota de voz de WhatsApp o un video de la cámara del celular. Para que no tengas que adivinar qué es cada archivo, agregamos un sistema modular de etiquetas.
|
|
76
|
+
|
|
77
|
+
### 🏷️ ¿Qué etiquetas existen?
|
|
78
|
+
Si el archivo es `esVARIADO`, LUNA intentará asignar una de las siguientes etiquetas:
|
|
79
|
+
|
|
80
|
+
1. **VideoClick**: Videos de 1 a 6 minutos que tienen pinta de ser clips musicales o de redes (detecta patrones como `[Official Video]`, `[470k]`, etc.).
|
|
81
|
+
2. **Grabación de WhatsApp**: Detecta el famoso formato `PTT-202311...-WA0001` o videos en rutas de WhatsApp.
|
|
82
|
+
3. **Grabación de Pantalla**: Reconoce desde el formato de Android (`ScreenRecord_2023...`), el de OBS (`2026-11-01-...`), hasta el de Windows 11 (`Screen Recording 20250713 012858`).
|
|
83
|
+
4. **Grabación de Cámara / DCIM**: Identifica videos crudos del teléfono (`VID_202...`, `IMG_...`) o archivos en la carpeta `/DCIM/`.
|
|
84
|
+
5. **Animado / Video Corto**: Si el nombre limpio del archivo coincide con la base de datos de animados (`Pocoyo`, `Peppa Pig`, etc.).
|
|
85
|
+
6. **Variado Desconocido**: El cajón de sastre. Si no coincide con ninguno, se le asigna esta etiqueta para que el usuario decida.
|
|
86
|
+
|
|
87
|
+
### 📍 ¿Cómo se ve en la salida?
|
|
88
|
+
La etiqueta se agrega directamente en el `info` y en la raíz de la salida.
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"esCC": "esVARIADO",
|
|
93
|
+
"nombreLimpio": "Screen Recording 20250713 012858 Chrome",
|
|
94
|
+
"Etiqueta_V": "Grabación de Pantalla",
|
|
95
|
+
"info": {
|
|
96
|
+
"tipoArchivo": "video",
|
|
97
|
+
"extension": "mp4",
|
|
98
|
+
"Etiqueta_V": "Grabación de Pantalla"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 🛠️ ¿Cómo se usa? (Para desarrolladores)
|
|
104
|
+
No tenés que hacer nada especial. El sistema se ejecuta automáticamente justo después de que LUNA decide que un archivo es `esVARIADO`.
|
|
105
|
+
|
|
106
|
+
Simplemente, cuando leas la salida, podés filtrar por la etiqueta:
|
|
107
|
+
```javascript
|
|
108
|
+
const resultado = await LUNA('C:\\DCIM\\VID_20231101_143022.mp4');
|
|
109
|
+
if (resultado.salida.esCC === 'esVARIADO') {
|
|
110
|
+
console.log(resultado.salida.Etiqueta_V); // "Grabación de Cámara / DCIM"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### ⚙️ ¿Cómo funciona por dentro? (Arquitectura)
|
|
115
|
+
La lógica vive en el nuevo archivo **`EtiquetadorVariado.js`**. Fue diseñado bajo el principio de **"solo agregar, nunca modificar"**. Es un sistema de reglas en cascada:
|
|
116
|
+
1. Se prueba el nombre del archivo (Regex).
|
|
117
|
+
2. Se prueba la ruta del archivo (por si viene de `/WhatsApp/` o `/DCIM/`).
|
|
118
|
+
3. Se prueba la duración (para los VideoClicks).
|
|
119
|
+
4. Se consulta la base de datos (para los Animados).
|
|
120
|
+
Si alguna regla hace "match", devuelve la etiqueta y se detiene. Si querés agregar una nueva etiqueta en el futuro (ej: "Grabación de Discord"), solo tenés que agregar un `if` nuevo en ese archivo.
|
|
121
|
+
|
|
122
|
+
***
|
|
123
|
+
|
|
124
|
+
**LOG de README:**
|
|
125
|
+
<p align="center">
|
|
126
|
+
<img src="./assets/5.png" width="100%">
|
|
127
|
+
</p>
|
|
128
|
+
|
|
129
|
+
|
|
63
130
|
---
|
|
64
131
|
|
|
65
132
|
## 🆕 Novedades en v1.2.1
|
|
@@ -89,6 +89,9 @@
|
|
|
89
89
|
const badge = item.estado === 'ok' ? 'ok' : item.estado === 'warning' ? 'warn' : 'err';
|
|
90
90
|
const badgeText = item.estado === 'ok' ? 'OK' : item.estado === 'warning' ? 'Aviso' : 'Error';
|
|
91
91
|
|
|
92
|
+
const etiquetaVariado = item.etiquetaVariado || null;
|
|
93
|
+
const subtituloFinal = item.subtitulo || (item.categoriaHumana === 'Variado' && etiquetaVariado ? etiquetaVariado : '');
|
|
94
|
+
|
|
92
95
|
// Construir HTML de detalles (solo si hay datos)
|
|
93
96
|
let detallesHtml = '';
|
|
94
97
|
if (item.detalles && item.detalles.length > 0) {
|
|
@@ -101,7 +104,7 @@
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
// Subtítulo opcional
|
|
104
|
-
const subtituloHtml =
|
|
107
|
+
const subtituloHtml = subtituloFinal ? `<div class="card-subtitle">${subtituloFinal}</div>` : '';
|
|
105
108
|
|
|
106
109
|
// Título (si es null, usamos el nombre del archivo)
|
|
107
110
|
const titulo = item.titulo || 'Archivo sin nombre claro';
|
|
@@ -56,6 +56,7 @@ function serializeResult(item, data) {
|
|
|
56
56
|
titulo: null,
|
|
57
57
|
subtitulo: null,
|
|
58
58
|
categoriaHumana: null,
|
|
59
|
+
etiquetaVariado: null,
|
|
59
60
|
detalles: [], // Solo datos reales
|
|
60
61
|
error: null
|
|
61
62
|
};
|
|
@@ -93,6 +94,15 @@ function serializeResult(item, data) {
|
|
|
93
94
|
base.subtitulo = subParts.join(' · ');
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
const etiquetaVariado = info.Etiqueta_V || s.Etiqueta_V || null;
|
|
98
|
+
if (etiquetaVariado) {
|
|
99
|
+
base.etiquetaVariado = etiquetaVariado;
|
|
100
|
+
if (s.esCC === 'esVARIADO') {
|
|
101
|
+
base.subtitulo = etiquetaVariado;
|
|
102
|
+
}
|
|
103
|
+
base.detalles.push({ etiqueta: 'Etiqueta', valor: etiquetaVariado });
|
|
104
|
+
}
|
|
105
|
+
|
|
96
106
|
// Detalles: Solo lo que existe y es útil
|
|
97
107
|
if (info.serie) base.detalles.push({ etiqueta: 'Serie', valor: info.serie });
|
|
98
108
|
if (info.anio) base.detalles.push({ etiqueta: 'Año', valor: info.anio });
|
package/tests/probe_LUNA.js
CHANGED
|
@@ -29,6 +29,13 @@ const RUTAS_PRUEBA = [
|
|
|
29
29
|
'D:\\ANIME\\Peliculas\\Harry Potter La Piedra Filosofal.mkv',
|
|
30
30
|
'D:\\ANIME\\Peliculas\\John Wick 4.mkv',
|
|
31
31
|
'D:\\ANIME\\Thunder 3 [Temp 1] [2026] [Caps 12]\\#Zombie Sagashitemasu 3 Sub Español Online gratis — JkAnime.mp4',
|
|
32
|
+
'D:\\MÚSICA\\NEW\\Bebe_Rexha_-_Im_A_Mess_[Official_Music_Video](360p).mp4',
|
|
33
|
+
'D:\\MÚSICA\\NEW\\Evanescence - Bring Me To Life (Official Music Video)(720P_HD).mp4',
|
|
34
|
+
'D:\\MÚSICA\\NEW\\VID_20261101_143022.mp4',
|
|
35
|
+
'D:\\MÚSICA\\NEW\\Screen_Recording_20250713-012858_Chrome.mp4',
|
|
36
|
+
'D:\\MÚSICA\\NEW\\ScreenCapture_20261101-143022.mp4',
|
|
37
|
+
'D:\\MÚSICA\\NEW\\ScreenRecord_20261101-143022.mp4',
|
|
38
|
+
'D:\\MÚSICA\\NEW\\Yomil y el Dany - SANTA 2 (video oficial) _drill(480P)_1.mp4'
|
|
32
39
|
];
|
|
33
40
|
|
|
34
41
|
// ============================================================================
|
|
@@ -266,6 +273,7 @@ async function ejecutarProbeLUNA2() {
|
|
|
266
273
|
console.log(' salida.tituloLimpio:', JSON.stringify(resultado && resultado.salida && resultado.salida.tituloLimpio));
|
|
267
274
|
console.log(' salida.extension:', JSON.stringify(resultado && resultado.salida && resultado.salida.extension));
|
|
268
275
|
console.log(' salida.tipoArchivo:', JSON.stringify(resultado && resultado.salida && resultado.salida.tipoArchivo));
|
|
276
|
+
console.log(' salida.Etiqueta_V:', JSON.stringify(resultado && resultado.salida && resultado.salida.Etiqueta_V));
|
|
269
277
|
if (resultado && resultado.salida && resultado.salida.info) {
|
|
270
278
|
console.log(' salida.info.serie:', JSON.stringify(resultado.salida.info.serie));
|
|
271
279
|
console.log(' salida.info.temporada:', resultado.salida.info.temporada);
|