Akira-Kurusu commited on
Commit
e479979
·
verified ·
1 Parent(s): 8e73785

Update web/diagnosis.html

Browse files
Files changed (1) hide show
  1. web/diagnosis.html +49 -37
web/diagnosis.html CHANGED
@@ -9,7 +9,7 @@
9
  <title>Diagnóstico IA</title>
10
  <link rel="stylesheet" href="css/simplebar.css">
11
  <link href="https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,100;0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
12
- <link rel="stylesheet" href="css/feather.css">
13
  <link rel="stylesheet" href="css/select2.css">
14
  <link rel="stylesheet" href="css/dropzone.css">
15
  <link rel="stylesheet" href="css/uppy.min.css">
@@ -195,7 +195,7 @@
195
  <!-- Navegación superior -->
196
  <nav class="topnav navbar navbar-light">
197
  <button type="button" class="navbar-toggler text-muted mt-2 p-0 mr-3 collapseSidebar">
198
- <i class="fe fe-menu navbar-toggler-icon"></i>
199
  </button>
200
 
201
  <ul class="nav">
@@ -213,7 +213,7 @@
213
  </nav>
214
  <aside class="sidebar-left border-right bg-white shadow" id="leftSidebar" data-simplebar>
215
  <a href="#" class="btn collapseSidebar toggle-btn d-lg-none text-muted ml-2 mt-3" data-toggle="toggle">
216
- <i class="fe fe-x"><span class="sr-only"></span></i>
217
  </a>
218
  <nav class="vertnav navbar navbar-light">
219
  <!-- nav bar -->
@@ -226,31 +226,31 @@
226
  <ul class="navbar-nav flex-fill w-100 mb-2">
227
  <li class="nav-item">
228
  <a class="nav-link" href="./index.html">
229
- <i class="fe fe-home fe-16"></i>
230
  <span class="ml-3 item-text">Dashboard</span>
231
  </a>
232
  </li>
233
  <li class="nav-item active">
234
  <a class="nav-link" href="./diagnosis.html">
235
- <i class="fe fe-eye fe-16"></i>
236
  <span class="ml-3 item-text">Diagnóstico</span>
237
  </a>
238
  </li>
239
  <li class="nav-item">
240
  <a class="nav-link" href="./patients.html">
241
- <i class="fe fe-users fe-16"></i>
242
  <span class="ml-3 item-text">Pacientes</span>
243
  </a>
244
  </li>
245
  <li class="nav-item">
246
  <a class="nav-link" href="./historial-consultas.html">
247
- <i class="fe fe-file-text fe-16"></i>
248
  <span class="ml-3 item-text">Consultas</span>
249
  </a>
250
  </li>
251
  <li class="nav-item">
252
  <a class="nav-link" href="./users.html">
253
- <i class="fe fe-user fe-16"></i>
254
  <span class="ml-3 item-text">Usuarios</span>
255
  </a>
256
  </li>
@@ -267,7 +267,7 @@
267
  <div class="row align-items-center mb-4">
268
  <div class="col">
269
  <h2 class="h3 page-title">
270
- <i class="fe fe-eye fe-24 mr-2 text-primary"></i>
271
  Diagnóstico con Inteligencia Artificial
272
  </h2>
273
  <p class="text-muted">Diagnostico de retinopatía diabética mediante análisis de imágenes</p>
@@ -280,7 +280,7 @@
280
  <div class="card shadow mb-4">
281
  <div class="card-header">
282
  <h5 class="card-title mb-0">
283
- <i class="fe fe-upload fe-16 mr-2"></i>Cargar Imágenes para Análisis
284
  </h5>
285
  </div>
286
  <div class="card-body">
@@ -294,7 +294,7 @@
294
 
295
  <!-- Zona de carga 2 -->
296
  <div id="uploadZone2" class="upload-zone" data-zone="2">
297
- <i class="fe fe-camera fe-48 text-muted mb-3"></i>
298
  <h5 class="text-muted">Arrastra una imagen aquí o haz clic para seleccionar</h5>
299
  <p class="text-muted mb-0">Formatos soportados: JPG, PNG, JPEG (Máx. 10MB)</p>
300
  </div>
@@ -304,13 +304,13 @@
304
  <img id="previewImg2" class="image-preview" alt="Vista previa">
305
  <div class="mt-3">
306
  <button class="btn btn-success btn-lg mr-2" id="analyzeBtn2">
307
- <i class="fe fe-zap fe-16 mr-2"></i>Analizar con IA
308
  </button>
309
  <button class="btn btn-outline-secondary mr-2" id="clearBtn2">
310
- <i class="fe fe-x fe-16 mr-2"></i>Limpiar
311
  </button>
312
  <button class="btn btn-warning gradcam-btn" id="gradcamBtn2" style="display: none;">
313
- <i class="fe fe-eye fe-16 mr-2"></i>Ver Grad-CAM
314
  </button>
315
  </div>
316
  </div>
@@ -320,7 +320,7 @@
320
  <div class="card shadow mb-4 analysis-card">
321
  <div class="card-body">
322
  <h5 class="mb-4">
323
- <i class="fe fe-activity fe-16 mr-2"></i>Resultados - Ojo Derecho
324
  </h5>
325
  <div id="resultContent2"></div>
326
  </div>
@@ -337,7 +337,7 @@
337
 
338
  <!-- Zona de carga 1 -->
339
  <div id="uploadZone1" class="upload-zone" data-zone="1">
340
- <i class="fe fe-camera fe-48 text-muted mb-3"></i>
341
  <h5 class="text-muted">Arrastra una imagen aquí o haz clic para seleccionar</h5>
342
  <p class="text-muted mb-0">Formatos soportados: JPG, PNG, JPEG (Máx. 10MB)</p>
343
  </div>
@@ -347,13 +347,13 @@
347
  <img id="previewImg1" class="image-preview" alt="Vista previa">
348
  <div class="mt-3">
349
  <button class="btn btn-success btn-lg mr-2" id="analyzeBtn1">
350
- <i class="fe fe-zap fe-16 mr-2"></i>Analizar con IA
351
  </button>
352
  <button class="btn btn-outline-secondary mr-2" id="clearBtn1">
353
- <i class="fe fe-x fe-16 mr-2"></i>Limpiar
354
  </button>
355
  <button class="btn btn-warning gradcam-btn" id="gradcamBtn1" style="display: none;">
356
- <i class="fe fe-eye fe-16 mr-2"></i>Ver Grad-CAM
357
  </button>
358
  </div>
359
  </div>
@@ -363,7 +363,7 @@
363
  <div class="card shadow mb-4 analysis-card">
364
  <div class="card-body">
365
  <h5 class="mb-4">
366
- <i class="fe fe-activity fe-16 mr-2"></i>Resultados - Ojo Izquierdo
367
  </h5>
368
  <div id="resultContent1"></div>
369
  </div>
@@ -380,7 +380,7 @@
380
  <div class="card shadow mb-4">
381
  <div class="card-header">
382
  <h6 class="card-title mb-0">
383
- <i class="fe fe-user fe-16 mr-2"></i>Información del Paciente y Consulta
384
  </h6>
385
  </div>
386
  <div class="card-body">
@@ -436,7 +436,7 @@
436
  </div>
437
 
438
  <button class="btn btn-primary btn-block" id="saveConsultationBtn" type="button">
439
- <i class="fe fe-save fe-16 mr-2"></i>Guardar Consulta
440
  </button>
441
  </div>
442
  </div>
@@ -445,7 +445,7 @@
445
  <div class="card shadow mb-4">
446
  <div class="card-header">
447
  <h6 class="card-title mb-0">
448
- <i class="fe fe-info fe-16 mr-2"></i>Importante
449
  </h6>
450
  </div>
451
  <div class="card-body">
@@ -725,7 +725,7 @@
725
  }
726
 
727
  $(`#analyzeBtn${zoneNumber}`).prop('disabled', false)
728
- .html('<i class="fe fe-zap fe-16 mr-2"></i>Analizar con IA')
729
  .removeClass('pulse-animation');
730
 
731
  showAnalysisResults(mockResult, zoneNumber);
@@ -738,7 +738,7 @@
738
  api.predict(imageData, fileName).then(function(result) {
739
  // Restaurar boton
740
  $(`#analyzeBtn${zoneNumber}`).prop('disabled', false)
741
- .html('<i class="fe fe-zap fe-16 mr-2"></i>Analizar con IA')
742
  .removeClass('pulse-animation');
743
 
744
  if (result && result.success) {
@@ -820,7 +820,7 @@
820
  <div class="card shadow-sm mt-3">
821
  <div class="card-header d-flex justify-content-between align-items-center">
822
  <h6 class="mb-0">
823
- <i class="fe fe-bar-chart-2 fe-16 mr-2"></i>Detalles del Análisis
824
  </h6>
825
  <span class="badge badge-pill ${isPositive ? 'badge-warning' : 'badge-success'}">${confidence}%</span>
826
  </div>
@@ -848,7 +848,7 @@
848
  <div class="border-right">
849
  <h6 class="text-muted mb-0">Análisis realizado</h6>
850
  <small class="text-muted">
851
- <i class="fe fe-clock fe-12 mr-1"></i>
852
  ${moment ? moment(result.timestamp).format('DD/MM/YYYY HH:mm') : new Date(result.timestamp).toLocaleString()}
853
  </small>
854
  </div>
@@ -856,7 +856,7 @@
856
  <div class="col-6">
857
  <h6 class="text-muted mb-0">Modelo utilizado</h6>
858
  <small class="text-muted">
859
- <i class="fe fe-cpu fe-12 mr-1"></i>
860
  EfficientNetB0
861
  </small>
862
  </div>
@@ -1011,7 +1011,7 @@
1011
  console.log('Eel no disponible - simulando guardado');
1012
  setTimeout(() => {
1013
  $('#saveConsultationBtn').prop('disabled', false)
1014
- .html('<i class="fe fe-save fe-16 mr-2"></i>Guardar Consulta');
1015
  showAlert('success', 'Consulta guardada correctamente (simulación)');
1016
  }, 1500);
1017
  return;
@@ -1023,7 +1023,7 @@
1023
 
1024
  // Restaurar boton
1025
  $('#saveConsultationBtn').prop('disabled', false)
1026
- .html('<i class="fe fe-save fe-16 mr-2"></i>Guardar Consulta');
1027
 
1028
  if (response && response.success) {
1029
  showAlert('success', 'Consulta guardada correctamente');
@@ -1067,7 +1067,7 @@ if (false) { /* removed */ }
1067
  api.gradcam(imageData, fileName, lastResult).then(function(response) {
1068
  // Restaurar boton
1069
  $(`#gradcamBtn${zoneNumber}`).prop('disabled', false)
1070
- .html('<i class="fe fe-eye fe-16 mr-2"></i>Ver Grad-CAM');
1071
 
1072
  if (response && response.success) {
1073
  console.log('Grad-CAM generado exitosamente');
@@ -1097,7 +1097,7 @@ if (false) { /* removed */ }
1097
  <div class="modal-content">
1098
  <div class="modal-header bg-danger text-white">
1099
  <h5 class="modal-title">
1100
- <i class="fe fe-eye mr-2"></i>Zoom HD - ${eyeName}
1101
  <span class="badge badge-light text-danger ml-2">Retinopatía Detectada</span>
1102
  </h5>
1103
  <button type="button" class="close text-white" data-dismiss="modal">
@@ -1112,7 +1112,7 @@ if (false) { /* removed */ }
1112
  alt="Zoom HD - Región Crítica">
1113
  <div class="mt-3">
1114
  <h6 class="text-danger mb-2">
1115
- <i class="fe fe-zoom-in mr-2"></i>Zona Crítica en Alta Resolución
1116
  </h6>
1117
  <p class="text-muted mb-0">
1118
  <strong>Activación máxima:</strong> ${maxAct} |
@@ -1129,7 +1129,7 @@ if (false) { /* removed */ }
1129
  </div>
1130
  <div class="alert alert-${alertType}">
1131
  <small>
1132
- <i class="fe fe-info mr-1"></i>
1133
  ${clinical}
1134
  </small>
1135
  </div>
@@ -1137,10 +1137,10 @@ if (false) { /* removed */ }
1137
  </div>
1138
  <div class="modal-footer">
1139
  <button type="button" class="btn btn-outline-primary" onclick="downloadGradCAMImage(${zoneNumber})">
1140
- <i class="fe fe-download mr-2"></i>Descargar Imagen
1141
  </button>
1142
  <button type="button" class="btn btn-secondary" data-dismiss="modal">
1143
- <i class="fe fe-x mr-2"></i>Cerrar
1144
  </button>
1145
  </div>
1146
  </div>
@@ -1232,7 +1232,7 @@ if (false) { /* removed */ }
1232
 
1233
  const alertHtml = `
1234
  <div class="alert ${alertClass} alert-dismissible fade show" role="alert">
1235
- <i class="fe fe-${type === 'error' ? 'x-circle' : type === 'success' ? 'check-circle' : type === 'warning' ? 'alert-triangle' : 'info'} mr-2"></i>
1236
  ${message}
1237
  <button type="button" class="close" data-dismiss="alert">
1238
  <span aria-hidden="true">&times;</span>
@@ -1408,5 +1408,17 @@ if (false) { /* removed */ }
1408
  <script src="js/gauge.min.js"></script>
1409
  <script src="js/jquery.sparkline.min.js"></script>
1410
  <script src="js/apps.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
1411
  </body>
1412
  </html>
 
9
  <title>Diagnóstico IA</title>
10
  <link rel="stylesheet" href="css/simplebar.css">
11
  <link href="https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,100;0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
12
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
13
  <link rel="stylesheet" href="css/select2.css">
14
  <link rel="stylesheet" href="css/dropzone.css">
15
  <link rel="stylesheet" href="css/uppy.min.css">
 
195
  <!-- Navegación superior -->
196
  <nav class="topnav navbar navbar-light">
197
  <button type="button" class="navbar-toggler text-muted mt-2 p-0 mr-3 collapseSidebar">
198
+ <i data-feather="menu" class="navbar-toggler-icon"></i>
199
  </button>
200
 
201
  <ul class="nav">
 
213
  </nav>
214
  <aside class="sidebar-left border-right bg-white shadow" id="leftSidebar" data-simplebar>
215
  <a href="#" class="btn collapseSidebar toggle-btn d-lg-none text-muted ml-2 mt-3" data-toggle="toggle">
216
+ <i data-feather="x"><span class="sr-only"></span></i>
217
  </a>
218
  <nav class="vertnav navbar navbar-light">
219
  <!-- nav bar -->
 
226
  <ul class="navbar-nav flex-fill w-100 mb-2">
227
  <li class="nav-item">
228
  <a class="nav-link" href="./index.html">
229
+ <i data-feather="home" class="fe-16"></i>
230
  <span class="ml-3 item-text">Dashboard</span>
231
  </a>
232
  </li>
233
  <li class="nav-item active">
234
  <a class="nav-link" href="./diagnosis.html">
235
+ <i data-feather="eye" class="fe-16"></i>
236
  <span class="ml-3 item-text">Diagnóstico</span>
237
  </a>
238
  </li>
239
  <li class="nav-item">
240
  <a class="nav-link" href="./patients.html">
241
+ <i data-feather="users" class="fe-16"></i>
242
  <span class="ml-3 item-text">Pacientes</span>
243
  </a>
244
  </li>
245
  <li class="nav-item">
246
  <a class="nav-link" href="./historial-consultas.html">
247
+ <i data-feather="file-text" class="fe-16"></i>
248
  <span class="ml-3 item-text">Consultas</span>
249
  </a>
250
  </li>
251
  <li class="nav-item">
252
  <a class="nav-link" href="./users.html">
253
+ <i data-feather="user" class="fe-16"></i>
254
  <span class="ml-3 item-text">Usuarios</span>
255
  </a>
256
  </li>
 
267
  <div class="row align-items-center mb-4">
268
  <div class="col">
269
  <h2 class="h3 page-title">
270
+ <i data-feather="eye" class="fe-24 mr-2 text-primary"></i>
271
  Diagnóstico con Inteligencia Artificial
272
  </h2>
273
  <p class="text-muted">Diagnostico de retinopatía diabética mediante análisis de imágenes</p>
 
280
  <div class="card shadow mb-4">
281
  <div class="card-header">
282
  <h5 class="card-title mb-0">
283
+ <i data-feather="upload" class="fe-16 mr-2"></i>Cargar Imágenes para Análisis
284
  </h5>
285
  </div>
286
  <div class="card-body">
 
294
 
295
  <!-- Zona de carga 2 -->
296
  <div id="uploadZone2" class="upload-zone" data-zone="2">
297
+ <i data-feather="camera" class="fe-48 text-muted mb-3"></i>
298
  <h5 class="text-muted">Arrastra una imagen aquí o haz clic para seleccionar</h5>
299
  <p class="text-muted mb-0">Formatos soportados: JPG, PNG, JPEG (Máx. 10MB)</p>
300
  </div>
 
304
  <img id="previewImg2" class="image-preview" alt="Vista previa">
305
  <div class="mt-3">
306
  <button class="btn btn-success btn-lg mr-2" id="analyzeBtn2">
307
+ <i data-feather="zap" class="fe-16 mr-2"></i>Analizar con IA
308
  </button>
309
  <button class="btn btn-outline-secondary mr-2" id="clearBtn2">
310
+ <i data-feather="x" class="fe-16 mr-2"></i>Limpiar
311
  </button>
312
  <button class="btn btn-warning gradcam-btn" id="gradcamBtn2" style="display: none;">
313
+ <i data-feather="eye" class="fe-16 mr-2"></i>Ver Grad-CAM
314
  </button>
315
  </div>
316
  </div>
 
320
  <div class="card shadow mb-4 analysis-card">
321
  <div class="card-body">
322
  <h5 class="mb-4">
323
+ <i data-feather="activity" class="fe-16 mr-2"></i>Resultados - Ojo Derecho
324
  </h5>
325
  <div id="resultContent2"></div>
326
  </div>
 
337
 
338
  <!-- Zona de carga 1 -->
339
  <div id="uploadZone1" class="upload-zone" data-zone="1">
340
+ <i data-feather="camera" class="fe-48 text-muted mb-3"></i>
341
  <h5 class="text-muted">Arrastra una imagen aquí o haz clic para seleccionar</h5>
342
  <p class="text-muted mb-0">Formatos soportados: JPG, PNG, JPEG (Máx. 10MB)</p>
343
  </div>
 
347
  <img id="previewImg1" class="image-preview" alt="Vista previa">
348
  <div class="mt-3">
349
  <button class="btn btn-success btn-lg mr-2" id="analyzeBtn1">
350
+ <i data-feather="zap" class="fe-16 mr-2"></i>Analizar con IA
351
  </button>
352
  <button class="btn btn-outline-secondary mr-2" id="clearBtn1">
353
+ <i data-feather="x" class="fe-16 mr-2"></i>Limpiar
354
  </button>
355
  <button class="btn btn-warning gradcam-btn" id="gradcamBtn1" style="display: none;">
356
+ <i data-feather="eye" class="fe-16 mr-2"></i>Ver Grad-CAM
357
  </button>
358
  </div>
359
  </div>
 
363
  <div class="card shadow mb-4 analysis-card">
364
  <div class="card-body">
365
  <h5 class="mb-4">
366
+ <i data-feather="activity" class="fe-16 mr-2"></i>Resultados - Ojo Izquierdo
367
  </h5>
368
  <div id="resultContent1"></div>
369
  </div>
 
380
  <div class="card shadow mb-4">
381
  <div class="card-header">
382
  <h6 class="card-title mb-0">
383
+ <i data-feather="user" class="fe-16 mr-2"></i>Información del Paciente y Consulta
384
  </h6>
385
  </div>
386
  <div class="card-body">
 
436
  </div>
437
 
438
  <button class="btn btn-primary btn-block" id="saveConsultationBtn" type="button">
439
+ <i data-feather="save" class="fe-16 mr-2"></i>Guardar Consulta
440
  </button>
441
  </div>
442
  </div>
 
445
  <div class="card shadow mb-4">
446
  <div class="card-header">
447
  <h6 class="card-title mb-0">
448
+ <i data-feather="info" class="fe-16 mr-2"></i>Importante
449
  </h6>
450
  </div>
451
  <div class="card-body">
 
725
  }
726
 
727
  $(`#analyzeBtn${zoneNumber}`).prop('disabled', false)
728
+ .html('<i data-feather="zap" class="fe-16 mr-2"></i>Analizar con IA')
729
  .removeClass('pulse-animation');
730
 
731
  showAnalysisResults(mockResult, zoneNumber);
 
738
  api.predict(imageData, fileName).then(function(result) {
739
  // Restaurar boton
740
  $(`#analyzeBtn${zoneNumber}`).prop('disabled', false)
741
+ .html('<i data-feather="zap" class="fe-16 mr-2"></i>Analizar con IA')
742
  .removeClass('pulse-animation');
743
 
744
  if (result && result.success) {
 
820
  <div class="card shadow-sm mt-3">
821
  <div class="card-header d-flex justify-content-between align-items-center">
822
  <h6 class="mb-0">
823
+ <i data-feather="bar-chart-2" class="fe-16 mr-2"></i>Detalles del Análisis
824
  </h6>
825
  <span class="badge badge-pill ${isPositive ? 'badge-warning' : 'badge-success'}">${confidence}%</span>
826
  </div>
 
848
  <div class="border-right">
849
  <h6 class="text-muted mb-0">Análisis realizado</h6>
850
  <small class="text-muted">
851
+ <i data-feather="clock" class="fe-12 mr-1"></i>
852
  ${moment ? moment(result.timestamp).format('DD/MM/YYYY HH:mm') : new Date(result.timestamp).toLocaleString()}
853
  </small>
854
  </div>
 
856
  <div class="col-6">
857
  <h6 class="text-muted mb-0">Modelo utilizado</h6>
858
  <small class="text-muted">
859
+ <i data-feather="cpu" class="fe-12 mr-1"></i>
860
  EfficientNetB0
861
  </small>
862
  </div>
 
1011
  console.log('Eel no disponible - simulando guardado');
1012
  setTimeout(() => {
1013
  $('#saveConsultationBtn').prop('disabled', false)
1014
+ .html('<i data-feather="save" class="fe-16 mr-2"></i>Guardar Consulta');
1015
  showAlert('success', 'Consulta guardada correctamente (simulación)');
1016
  }, 1500);
1017
  return;
 
1023
 
1024
  // Restaurar boton
1025
  $('#saveConsultationBtn').prop('disabled', false)
1026
+ .html('<i data-feather="save" class="fe-16 mr-2"></i>Guardar Consulta');
1027
 
1028
  if (response && response.success) {
1029
  showAlert('success', 'Consulta guardada correctamente');
 
1067
  api.gradcam(imageData, fileName, lastResult).then(function(response) {
1068
  // Restaurar boton
1069
  $(`#gradcamBtn${zoneNumber}`).prop('disabled', false)
1070
+ .html('<i data-feather="eye" class="fe-16 mr-2"></i>Ver Grad-CAM');
1071
 
1072
  if (response && response.success) {
1073
  console.log('Grad-CAM generado exitosamente');
 
1097
  <div class="modal-content">
1098
  <div class="modal-header bg-danger text-white">
1099
  <h5 class="modal-title">
1100
+ <i data-feather="eye" class="mr-2"></i>Zoom HD - ${eyeName}
1101
  <span class="badge badge-light text-danger ml-2">Retinopatía Detectada</span>
1102
  </h5>
1103
  <button type="button" class="close text-white" data-dismiss="modal">
 
1112
  alt="Zoom HD - Región Crítica">
1113
  <div class="mt-3">
1114
  <h6 class="text-danger mb-2">
1115
+ <i data-feather="zoom-in" class="mr-2"></i>Zona Crítica en Alta Resolución
1116
  </h6>
1117
  <p class="text-muted mb-0">
1118
  <strong>Activación máxima:</strong> ${maxAct} |
 
1129
  </div>
1130
  <div class="alert alert-${alertType}">
1131
  <small>
1132
+ <i data-feather="info" class="mr-1"></i>
1133
  ${clinical}
1134
  </small>
1135
  </div>
 
1137
  </div>
1138
  <div class="modal-footer">
1139
  <button type="button" class="btn btn-outline-primary" onclick="downloadGradCAMImage(${zoneNumber})">
1140
+ <i data-feather="download" class="mr-2"></i>Descargar Imagen
1141
  </button>
1142
  <button type="button" class="btn btn-secondary" data-dismiss="modal">
1143
+ <i data-feather="x" class="mr-2"></i>Cerrar
1144
  </button>
1145
  </div>
1146
  </div>
 
1232
 
1233
  const alertHtml = `
1234
  <div class="alert ${alertClass} alert-dismissible fade show" role="alert">
1235
+ ${(function(){var n=type==='error'?'x-circle':type==='success'?'check-circle':type==='warning'?'alert-triangle':'info';return typeof feather!=='undefined'?feather.icons[n].toSvg({'width':16,'height':16,'stroke-width':1.8,'style':'margin-right:6px;vertical-align:middle;'}):'';})()}
1236
  ${message}
1237
  <button type="button" class="close" data-dismiss="alert">
1238
  <span aria-hidden="true">&times;</span>
 
1408
  <script src="js/gauge.min.js"></script>
1409
  <script src="js/jquery.sparkline.min.js"></script>
1410
  <script src="js/apps.js"></script>
1411
+ <script>
1412
+ function _initFeather() {
1413
+ if (typeof feather !== 'undefined') feather.replace({ 'stroke-width': 1.8 });
1414
+ }
1415
+ document.addEventListener('DOMContentLoaded', _initFeather);
1416
+ var _fObserver = new MutationObserver(function(mutations) {
1417
+ if (mutations.some(function(m){ return m.addedNodes.length > 0; })) _initFeather();
1418
+ });
1419
+ document.addEventListener('DOMContentLoaded', function() {
1420
+ _fObserver.observe(document.body, { childList: true, subtree: true });
1421
+ });
1422
+ </script>
1423
  </body>
1424
  </html>