@telcomdev/ui 0.1.14 → 0.1.15

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.
@@ -3012,11 +3012,11 @@ class TdFileViewer {
3012
3012
  return bytes;
3013
3013
  }
3014
3014
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: TdFileViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
3015
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: TdFileViewer, isStandalone: true, selector: "td-file-viewer", inputs: { archivos: "archivos", titulo: "titulo", descripcion: "descripcion", oscuro: "oscuro", compacto: "compacto", showList: "showList" }, outputs: { seleccionar: "seleccionar", descargar: "descargar", closed: "closed" }, viewQueries: [{ propertyName: "visorDialog", first: true, predicate: ["visorDialog"], descendants: true }, { propertyName: "pdfCanvas", first: true, predicate: ["pdfCanvas"], descendants: true }], ngImport: i0, template: "@if (showList) {\n <section\n class=\"td-file-viewer\"\n [class.td-file-viewer--dark]=\"oscuro\"\n [class.td-file-viewer--compact]=\"compacto\"\n >\n <header class=\"td-file-viewer__header\">\n <div>\n <span>{{ archivos.length }} archivo{{ archivos.length === 1 ? '' : 's' }}</span>\n <h3>{{ titulo }}</h3>\n @if (descripcion) {\n <p>{{ descripcion }}</p>\n }\n </div>\n </header>\n\n @if (archivos.length) {\n <div class=\"td-file-viewer__grid\">\n @for (archivo of archivos; track archivo.id) {\n <button type=\"button\" class=\"td-file-viewer__item\" (click)=\"abrir(archivo)\">\n <span class=\"td-file-viewer__preview\" [class.td-file-viewer__preview--image]=\"tipoArchivo(archivo) === 'imagen'\">\n @if (tipoArchivo(archivo) === 'imagen') {\n <img [src]=\"archivo.thumbnailUrl || archivo.url\" [alt]=\"archivo.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"1.55rem\" />\n }\n </span>\n\n <span class=\"td-file-viewer__meta\">\n <strong>{{ archivo.nombre }}</strong>\n @if (archivo.descripcion) {\n <small>{{ archivo.descripcion }}</small>\n }\n <em>\n {{ tieneVistaPrevia(archivo) ? 'Vista previa disponible' : 'Descarga / apertura externa' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </em>\n </span>\n\n @if (archivo.descargable !== false) {\n <span\n role=\"button\"\n tabindex=\"-1\"\n class=\"td-file-viewer__download\"\n title=\"Descargar\"\n (click)=\"descargarArchivo(archivo, $event)\"\n >\n <td-icon nombre=\"download\" tamano=\"1rem\" />\n </span>\n }\n </button>\n }\n </div>\n } @else {\n <div class=\"td-file-viewer__empty\">\n <td-icon nombre=\"file\" tamano=\"2rem\" />\n <strong>No hay adjuntos</strong>\n <span>Cuando existan archivos apareceran en esta zona.</span>\n </div>\n }\n </section>\n}\n\n@if (seleccionado; as archivo) {\n <dialog\n #visorDialog\n class=\"td-file-viewer-modal\"\n [class.td-file-viewer-modal--dark]=\"oscuro\"\n [attr.aria-label]=\"archivo.nombre\"\n (click)=\"cerrarSiBackdrop($event)\"\n (cancel)=\"cerrar()\"\n (close)=\"seleccionado = null\"\n >\n <section class=\"td-file-viewer-modal__panel\">\n <header class=\"td-file-viewer-modal__topbar\">\n <div class=\"td-file-viewer-modal__title\">\n <span class=\"td-file-viewer-modal__badge\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\".95rem\" />\n {{ tipoArchivo(archivo) }}\n </span>\n <h3>{{ archivo.nombre }}</h3>\n @if (archivo.descripcion || tamanoLegible(archivo)) {\n <p>\n {{ archivo.descripcion || 'Archivo adjunto' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </p>\n }\n </div>\n\n <nav class=\"td-file-viewer-modal__toolbar\" aria-label=\"Acciones del visor\">\n <button type=\"button\" title=\"Anterior\" [disabled]=\"indiceSeleccionado() <= 0\" (click)=\"seleccionarAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <button type=\"button\" title=\"Siguiente\" [disabled]=\"indiceSeleccionado() >= archivos.length - 1\" (click)=\"seleccionarSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n\n @if (esImagen(archivo) || esPdf(archivo)) {\n <span class=\"td-file-viewer-modal__divider\"></span>\n <button type=\"button\" title=\"Alejar\" (click)=\"cambiarZoom(-0.1)\">\n <span aria-hidden=\"true\">-</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__zoom\" title=\"Restablecer zoom\" (click)=\"restablecerZoom()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button type=\"button\" title=\"Acercar\" (click)=\"cambiarZoom(0.1)\">\n <span aria-hidden=\"true\">+</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Ajustar\" (click)=\"restablecerZoom()\">\n Ajustar\n </button>\n @if (esImagen(archivo)) {\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Rotar\" (click)=\"rotar()\">\n Rotar\n </button>\n }\n }\n\n <span class=\"td-file-viewer-modal__divider\"></span>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\" title=\"Abrir en nueva pestana\">\n <td-icon nombre=\"visibility\" />\n </a>\n @if (archivo.descargable !== false) {\n <a [href]=\"archivo.url\" [download]=\"archivo.nombre\" target=\"_blank\" rel=\"noopener\" title=\"Descargar\">\n <td-icon nombre=\"download\" />\n </a>\n }\n <button type=\"button\" title=\"Cerrar\" aria-label=\"Cerrar\" (click)=\"cerrar()\">\n <td-icon nombre=\"close\" />\n </button>\n </nav>\n </header>\n\n <div class=\"td-file-viewer-modal__workspace\">\n <main class=\"td-file-viewer-modal__canvas\">\n @if (esImagen(archivo)) {\n <img\n class=\"td-file-viewer-modal__image\"\n [src]=\"archivo.url\"\n [alt]=\"archivo.nombre\"\n [style.transform]=\"'scale(' + zoom + ') rotate(' + rotacion + 'deg)'\"\n />\n } @else if (esPdf(archivo)) {\n <section class=\"td-file-viewer-modal__pdf-shell\">\n <div class=\"td-file-viewer-modal__pdf-head\">\n <span>\n <td-icon nombre=\"pdf\" />\n Vista PDF\n </span>\n <div class=\"td-file-viewer-modal__pdf-pages\">\n <button type=\"button\" title=\"Pagina anterior\" [disabled]=\"pdfPaginaActual <= 1 || pdfCargando\" (click)=\"paginaPdfAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <small>\n Pagina {{ pdfPaginaActual }} de {{ pdfTotalPaginas || '-' }}\n </small>\n <button type=\"button\" title=\"Pagina siguiente\" [disabled]=\"!pdfTotalPaginas || pdfPaginaActual >= pdfTotalPaginas || pdfCargando\" (click)=\"paginaPdfSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n </div>\n </div>\n <div class=\"td-file-viewer-modal__pdf-canvas-wrap\">\n <canvas #pdfCanvas class=\"td-file-viewer-modal__pdf-canvas\"></canvas>\n\n @if (pdfCargando) {\n <div class=\"td-file-viewer-modal__pdf-state\">\n <span class=\"td-file-viewer-modal__spinner\"></span>\n <strong>Cargando PDF</strong>\n <small>Preparando pagina {{ pdfPaginaActual }}...</small>\n </div>\n }\n\n @if (pdfError) {\n <div class=\"td-file-viewer-modal__pdf-state td-file-viewer-modal__pdf-state--error\">\n <td-icon nombre=\"alert\" tamano=\"2rem\" />\n <strong>{{ pdfError }}</strong>\n <small>Prueba abrirlo en una nueva pesta\u00F1a o descargarlo.</small>\n </div>\n }\n </div>\n </section>\n } @else {\n <div class=\"td-file-viewer-modal__fallback\">\n <span class=\"td-file-viewer-modal__fallback-icon\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"3rem\" />\n </span>\n <h4>Vista previa no disponible</h4>\n <p>Este tipo de archivo debe abrirse o descargarse con una aplicacion compatible.</p>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\">\n Abrir archivo\n </a>\n </div>\n }\n </main>\n\n @if (archivos.length > 1) {\n <footer class=\"td-file-viewer-modal__strip\">\n @for (item of archivos; track item.id) {\n <button\n type=\"button\"\n [class.td-file-viewer-modal__thumb--active]=\"item.id === archivo.id\"\n [title]=\"item.nombre\"\n (click)=\"abrir(item)\"\n >\n @if (tipoArchivo(item) === 'imagen') {\n <img [src]=\"item.thumbnailUrl || item.url\" [alt]=\"item.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(item)\" />\n }\n @if (!tieneVistaPrevia(item)) {\n <span class=\"td-file-viewer-modal__no-preview\">Sin preview</span>\n }\n </button>\n }\n </footer>\n }\n </div>\n </section>\n </dialog>\n}\n", styles: [":host{display:block}*{box-sizing:border-box}.td-file-viewer{--fondo: var(--td-color-surface, #fff);--fondo-suave: var(--td-color-surface-soft, #f8fafc);--fondo-mudo: var(--td-color-surface-muted, #eef2f7);--borde: var(--td-color-border, #e4e8f0);--texto: var(--td-color-text, #263147);--suave: var(--td-color-text-muted, #748096);--acento: var(--td-color-primary, #5746d8);display:grid;gap:1rem;color:var(--texto);font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer--dark{--fondo: var(--td-color-surface, #15151b);--fondo-suave: var(--td-color-surface-soft, #1b1b22);--fondo-mudo: var(--td-color-surface-muted, #202028);--borde: var(--td-color-border, #2d2d36);--texto: var(--td-color-text, #ededf0);--suave: var(--td-color-text-muted, #9393a0);--acento: var(--td-color-primary, #a89cf7)}.td-file-viewer__header{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}.td-file-viewer__header span,.td-file-viewer-modal__badge,.td-file-viewer-modal__details>span{color:var(--acento);font-size:.66rem;font-weight:850;letter-spacing:.11em;text-transform:uppercase}.td-file-viewer__header h3,.td-file-viewer__header p,.td-file-viewer-modal h3,.td-file-viewer-modal p,.td-file-viewer-modal h4{margin:0}.td-file-viewer__header h3{margin-top:.18rem;font-size:1rem}.td-file-viewer__header p{margin-top:.25rem;color:var(--suave);font-size:.76rem;line-height:1.45}.td-file-viewer__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.75rem}.td-file-viewer--compact .td-file-viewer__grid{grid-template-columns:1fr}.td-file-viewer__item{display:grid;grid-template-columns:3.25rem minmax(0,1fr) auto;align-items:center;gap:.75rem;border:1px solid var(--borde);border-radius:var(--td-radius-lg, 1rem);padding:.72rem;color:inherit;background:linear-gradient(135deg,var(--fondo),var(--fondo-suave));box-shadow:var(--td-shadow-xs, 0 6px 18px rgba(31, 42, 68, .06));text-align:left;cursor:pointer;transition:border-color .14s ease,box-shadow .14s ease,transform .14s ease}.td-file-viewer__item:hover{border-color:var(--acento);box-shadow:var(--td-shadow-sm, 0 12px 28px rgba(31, 42, 68, .1));transform:translateY(-1px)}.td-file-viewer__preview{display:grid;width:3.25rem;height:3.25rem;place-items:center;overflow:hidden;border-radius:var(--td-radius-md, .85rem);color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,var(--fondo-suave))}.td-file-viewer__preview img{width:100%;height:100%;object-fit:cover}.td-file-viewer__meta{display:grid;min-width:0;gap:.15rem}.td-file-viewer__meta strong,.td-file-viewer__meta small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer__meta strong{font-size:.8rem}.td-file-viewer__meta small,.td-file-viewer__meta em{color:var(--suave);font-size:.7rem;font-style:normal}.td-file-viewer__download{display:grid;width:2rem;height:2rem;place-items:center;border-radius:var(--td-radius-sm, .55rem);color:var(--suave)}.td-file-viewer__download:hover{color:var(--acento);background:var(--fondo-suave)}.td-file-viewer__empty{display:grid;min-height:12rem;place-items:center;align-content:center;gap:.35rem;border:1px dashed var(--borde);border-radius:var(--td-radius-lg, 1rem);color:var(--suave);background:var(--fondo-suave);text-align:center}.td-file-viewer__empty strong{color:var(--texto)}.td-file-viewer-modal{width:min(900px,100vw - 2rem);max-width:none;max-height:min(82dvh,720px);border:0;padding:0;overflow:visible;color:var(--td-color-text, #263147);background:transparent;font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer-modal::backdrop{background:#0a101e80;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px)}.td-file-viewer-modal__panel{display:grid;grid-template-rows:auto minmax(0,1fr);width:100%;max-height:min(82dvh,720px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-xl, 1.15rem);background:var(--td-color-surface, #fff);box-shadow:var(--td-shadow-xl, 0 24px 72px rgba(15, 23, 42, .28))}.td-file-viewer-modal--dark .td-file-viewer-modal__panel{border-color:var(--td-color-border, #2d2d36);background:var(--td-color-surface, #15151b)}.td-file-viewer-modal__topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.75rem .9rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__title{display:grid;min-width:0;gap:.12rem}.td-file-viewer-modal__badge{display:inline-flex;width:fit-content;align-items:center;gap:.35rem;color:var(--td-color-primary, #5746d8);font-size:.64rem;font-weight:850;letter-spacing:.1em;text-transform:uppercase}.td-file-viewer-modal h3,.td-file-viewer-modal h4,.td-file-viewer-modal p{margin:0}.td-file-viewer-modal__title h3{overflow:hidden;color:var(--td-color-text, #263147);font-size:.9rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__title p{overflow:hidden;color:var(--td-color-text-muted, #748096);font-size:.7rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__toolbar{display:flex;flex:0 0 auto;align-items:center;gap:.3rem}.td-file-viewer-modal__toolbar button,.td-file-viewer-modal__toolbar a{display:inline-grid;min-width:2rem;height:2rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .55rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);text-decoration:none;cursor:pointer}.td-file-viewer-modal__toolbar button:hover,.td-file-viewer-modal__toolbar a:hover{color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__toolbar button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__zoom{min-width:3rem!important;padding-inline:.45rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__text-action{width:auto!important;min-width:3.2rem!important;padding-inline:.55rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__divider{width:1px;height:1.25rem;margin-inline:.2rem;background:var(--td-color-border, #e4e8f0)}.td-file-viewer-modal__workspace{display:grid;grid-template-rows:minmax(0,1fr) auto;min-height:0;background:var(--td-color-surface-soft, #f8fafc)}.td-file-viewer-modal__canvas{display:grid;min-height:20rem;max-height:calc(82dvh - 8rem);place-items:center;overflow:auto;padding:1rem;background:linear-gradient(180deg,var(--td-color-surface-soft, #f8fafc),var(--td-color-surface, #fff))}.td-file-viewer-modal__image{display:block;width:auto;max-width:100%;max-height:min(58dvh,500px);border-radius:var(--td-radius-lg, 1rem);object-fit:contain;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .16));transition:transform .12s ease}.td-file-viewer-modal__pdf-shell{display:grid;grid-template-rows:auto minmax(0,1fr);width:min(820px,100%);height:min(60dvh,560px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-lg, 1rem);background:var(--td-color-surface, #fff)}.td-file-viewer-modal__pdf-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.55rem .65rem .55rem .75rem}.td-file-viewer-modal__pdf-head span{display:inline-flex;align-items:center;gap:.4rem;font-size:.75rem;font-weight:850}.td-file-viewer-modal__pdf-head small{color:var(--td-color-text-muted, #748096);font-size:.65rem}.td-file-viewer-modal__pdf-pages{display:inline-flex;align-items:center;gap:.35rem}.td-file-viewer-modal__pdf-pages button{display:inline-grid;width:1.8rem;height:1.8rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .5rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__pdf-pages button:hover:not(:disabled){color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__pdf-pages button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__pdf-canvas-wrap{position:relative;display:grid;min-height:0;overflow:auto;place-items:start center;padding:1rem;background:radial-gradient(circle at 1px 1px,rgba(100,116,139,.18) 1px,transparent 0) 0 0/18px 18px,var(--td-color-surface-muted, #eef2f7)}.td-file-viewer-modal__pdf-canvas{display:block;max-width:none;border-radius:var(--td-radius-sm, .45rem);background:#fff;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .2))}.td-file-viewer-modal__pdf-state{position:absolute;inset:0;display:grid;place-items:center;align-content:center;gap:.35rem;color:var(--td-color-text-muted, #748096);background:color-mix(in srgb,var(--td-color-surface, #fff) 78%,transparent);text-align:center}.td-file-viewer-modal__pdf-state strong{color:var(--td-color-text, #263147);font-size:.85rem}.td-file-viewer-modal__pdf-state--error{color:var(--td-color-danger, #dc2626);background:color-mix(in srgb,var(--td-color-surface, #fff) 92%,transparent)}.td-file-viewer-modal__spinner{display:block;width:2rem;height:2rem;border:3px solid color-mix(in srgb,var(--td-color-primary, #5746d8) 18%,transparent);border-top-color:var(--td-color-primary, #5746d8);border-radius:999px;animation:td-file-viewer-spin .8s linear infinite}@keyframes td-file-viewer-spin{to{transform:rotate(360deg)}}.td-file-viewer-modal__strip{display:flex;gap:.45rem;overflow-x:auto;border-top:1px solid var(--td-color-border, #e4e8f0);padding:.65rem .75rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__strip button{position:relative;display:grid;width:2.4rem;height:2.4rem;flex:0 0 auto;place-items:center;overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-sm, .6rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__strip img{width:100%;height:100%;object-fit:cover}.td-file-viewer-modal__thumb--active{border-color:var(--td-color-primary, #5746d8)!important;box-shadow:var(--td-focus-ring, 0 0 0 3px color-mix(in srgb, var(--td-color-primary, #5746d8) 15%, transparent))}.td-file-viewer-modal__no-preview{position:absolute;right:.12rem;bottom:.12rem;border-radius:var(--td-radius-pill, 999px);padding:.05rem .22rem;color:var(--td-color-text-muted, #748096);background:var(--td-color-surface, #fff);font-size:.46rem;font-weight:850;line-height:1.2}.td-file-viewer-modal__fallback{display:grid;place-items:center;align-content:center;gap:.7rem;color:var(--td-color-text-muted, #748096);text-align:center}.td-file-viewer-modal__fallback-icon{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:var(--td-radius-xl, 1.25rem);color:var(--td-color-primary, #5746d8);background:color-mix(in srgb,var(--td-color-primary, #5746d8) 10%,transparent)}.td-file-viewer-modal__fallback h4{color:var(--td-color-text, #263147)}.td-file-viewer-modal__fallback a{display:inline-flex;min-height:2.25rem;align-items:center;border-radius:var(--td-radius-md, .75rem);padding:0 .9rem;color:var(--td-color-on-primary, #fff);background:var(--td-color-primary, #5746d8);font-size:.75rem;font-weight:800;text-decoration:none}@media(max-width:640px){.td-file-viewer-modal{width:calc(100vw - 1.5rem);max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__panel{max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__topbar{align-items:flex-start;flex-direction:column}.td-file-viewer-modal__toolbar{width:100%;overflow-x:auto}.td-file-viewer-modal__canvas{min-height:16rem;max-height:calc(100dvh - 11rem);padding:.75rem}.td-file-viewer-modal__image,.td-file-viewer-modal__pdf-shell{max-height:calc(100dvh - 13rem)}}\n"], dependencies: [{ kind: "component", type: TdIcon, selector: "td-icon", inputs: ["nombre", "titulo", "tamano"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3015
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: TdFileViewer, isStandalone: true, selector: "td-file-viewer", inputs: { archivos: "archivos", titulo: "titulo", descripcion: "descripcion", oscuro: "oscuro", compacto: "compacto", showList: "showList" }, outputs: { seleccionar: "seleccionar", descargar: "descargar", closed: "closed" }, viewQueries: [{ propertyName: "visorDialog", first: true, predicate: ["visorDialog"], descendants: true }, { propertyName: "pdfCanvas", first: true, predicate: ["pdfCanvas"], descendants: true }], ngImport: i0, template: "@if (showList) {\n <section\n class=\"td-file-viewer\"\n [class.td-file-viewer--dark]=\"oscuro\"\n [class.td-file-viewer--compact]=\"compacto\"\n >\n <header class=\"td-file-viewer__header\">\n <div>\n <span>{{ archivos.length }} archivo{{ archivos.length === 1 ? '' : 's' }}</span>\n <h3>{{ titulo }}</h3>\n @if (descripcion) {\n <p>{{ descripcion }}</p>\n }\n </div>\n </header>\n\n @if (archivos.length) {\n <div class=\"td-file-viewer__grid\">\n @for (archivo of archivos; track archivo.id) {\n <button type=\"button\" class=\"td-file-viewer__item\" (click)=\"abrir(archivo)\">\n <span class=\"td-file-viewer__preview\" [class.td-file-viewer__preview--image]=\"tipoArchivo(archivo) === 'imagen'\">\n @if (tipoArchivo(archivo) === 'imagen') {\n <img [src]=\"archivo.thumbnailUrl || archivo.url\" [alt]=\"archivo.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"1.55rem\" />\n }\n </span>\n\n <span class=\"td-file-viewer__meta\">\n <strong>{{ archivo.nombre }}</strong>\n @if (archivo.descripcion) {\n <small>{{ archivo.descripcion }}</small>\n }\n <em>\n {{ tieneVistaPrevia(archivo) ? 'Vista previa disponible' : 'Descarga / apertura externa' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </em>\n </span>\n\n @if (archivo.descargable !== false) {\n <span\n role=\"button\"\n tabindex=\"-1\"\n class=\"td-file-viewer__download\"\n title=\"Descargar\"\n (click)=\"descargarArchivo(archivo, $event)\"\n >\n <td-icon nombre=\"download\" tamano=\"1rem\" />\n </span>\n }\n </button>\n }\n </div>\n } @else {\n <div class=\"td-file-viewer__empty\">\n <td-icon nombre=\"file\" tamano=\"2rem\" />\n <strong>No hay adjuntos</strong>\n <span>Cuando existan archivos apareceran en esta zona.</span>\n </div>\n }\n </section>\n}\n\n@if (seleccionado; as archivo) {\n <dialog\n #visorDialog\n class=\"td-file-viewer-modal\"\n [class.td-file-viewer-modal--dark]=\"oscuro\"\n [attr.aria-label]=\"archivo.nombre\"\n (click)=\"cerrarSiBackdrop($event)\"\n (cancel)=\"cerrar()\"\n (close)=\"seleccionado = null\"\n >\n <section class=\"td-file-viewer-modal__panel\">\n <header class=\"td-file-viewer-modal__topbar\">\n <div class=\"td-file-viewer-modal__title\">\n <span class=\"td-file-viewer-modal__badge\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\".95rem\" />\n {{ tipoArchivo(archivo) }}\n </span>\n <h3>{{ archivo.nombre }}</h3>\n @if (archivo.descripcion || tamanoLegible(archivo)) {\n <p>\n {{ archivo.descripcion || 'Archivo adjunto' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </p>\n }\n </div>\n\n <nav class=\"td-file-viewer-modal__toolbar\" aria-label=\"Acciones del visor\">\n <button type=\"button\" title=\"Anterior\" [disabled]=\"indiceSeleccionado() <= 0\" (click)=\"seleccionarAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <button type=\"button\" title=\"Siguiente\" [disabled]=\"indiceSeleccionado() >= archivos.length - 1\" (click)=\"seleccionarSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n\n @if (esImagen(archivo) || esPdf(archivo)) {\n <span class=\"td-file-viewer-modal__divider\"></span>\n <button type=\"button\" title=\"Alejar\" (click)=\"cambiarZoom(-0.1)\">\n <span aria-hidden=\"true\">-</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__zoom\" title=\"Restablecer zoom\" (click)=\"restablecerZoom()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button type=\"button\" title=\"Acercar\" (click)=\"cambiarZoom(0.1)\">\n <span aria-hidden=\"true\">+</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Ajustar\" (click)=\"restablecerZoom()\">\n Ajustar\n </button>\n @if (esImagen(archivo)) {\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Rotar\" (click)=\"rotar()\">\n Rotar\n </button>\n }\n }\n\n <span class=\"td-file-viewer-modal__divider\"></span>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\" title=\"Abrir en nueva pestana\">\n <td-icon nombre=\"visibility\" />\n </a>\n @if (archivo.descargable !== false) {\n <a [href]=\"archivo.url\" [download]=\"archivo.nombre\" target=\"_blank\" rel=\"noopener\" title=\"Descargar\">\n <td-icon nombre=\"download\" />\n </a>\n }\n <button type=\"button\" title=\"Cerrar\" aria-label=\"Cerrar\" (click)=\"cerrar()\">\n <td-icon nombre=\"close\" />\n </button>\n </nav>\n </header>\n\n <div class=\"td-file-viewer-modal__workspace\">\n <main class=\"td-file-viewer-modal__canvas\">\n @if (esImagen(archivo)) {\n <img\n class=\"td-file-viewer-modal__image\"\n [src]=\"archivo.url\"\n [alt]=\"archivo.nombre\"\n [style.transform]=\"'scale(' + zoom + ') rotate(' + rotacion + 'deg)'\"\n />\n } @else if (esPdf(archivo)) {\n <section class=\"td-file-viewer-modal__pdf-shell\">\n <div class=\"td-file-viewer-modal__pdf-head\">\n <span>\n <td-icon nombre=\"pdf\" />\n Vista PDF\n </span>\n <div class=\"td-file-viewer-modal__pdf-pages\">\n <button type=\"button\" title=\"Pagina anterior\" [disabled]=\"pdfPaginaActual <= 1 || pdfCargando\" (click)=\"paginaPdfAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <small>\n Pagina {{ pdfPaginaActual }} de {{ pdfTotalPaginas || '-' }}\n </small>\n <button type=\"button\" title=\"Pagina siguiente\" [disabled]=\"!pdfTotalPaginas || pdfPaginaActual >= pdfTotalPaginas || pdfCargando\" (click)=\"paginaPdfSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n </div>\n </div>\n <div class=\"td-file-viewer-modal__pdf-canvas-wrap\">\n <canvas #pdfCanvas class=\"td-file-viewer-modal__pdf-canvas\"></canvas>\n\n @if (pdfCargando) {\n <div class=\"td-file-viewer-modal__pdf-state\">\n <span class=\"td-file-viewer-modal__spinner\"></span>\n <strong>Cargando PDF</strong>\n <small>Preparando pagina {{ pdfPaginaActual }}...</small>\n </div>\n }\n\n @if (pdfError) {\n <div class=\"td-file-viewer-modal__pdf-state td-file-viewer-modal__pdf-state--error\">\n <td-icon nombre=\"alert\" tamano=\"2rem\" />\n <strong>{{ pdfError }}</strong>\n <small>Prueba abrirlo en una nueva pesta\u00F1a o descargarlo.</small>\n </div>\n }\n </div>\n </section>\n } @else {\n <div class=\"td-file-viewer-modal__fallback\">\n <span class=\"td-file-viewer-modal__fallback-icon\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"3rem\" />\n </span>\n <h4>Vista previa no disponible</h4>\n <p>Este tipo de archivo debe abrirse o descargarse con una aplicacion compatible.</p>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\">\n Abrir archivo\n </a>\n </div>\n }\n </main>\n\n @if (archivos.length > 1) {\n <footer class=\"td-file-viewer-modal__strip\">\n @for (item of archivos; track item.id) {\n <button\n type=\"button\"\n [class.td-file-viewer-modal__thumb--active]=\"item.id === archivo.id\"\n [title]=\"item.nombre\"\n (click)=\"abrir(item)\"\n >\n @if (tipoArchivo(item) === 'imagen') {\n <img [src]=\"item.thumbnailUrl || item.url\" [alt]=\"item.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(item)\" />\n }\n @if (!tieneVistaPrevia(item)) {\n <span class=\"td-file-viewer-modal__no-preview\">Sin preview</span>\n }\n </button>\n }\n </footer>\n }\n </div>\n </section>\n </dialog>\n}\n", styles: [":host{display:block}*{box-sizing:border-box}.td-file-viewer{--fondo: var(--td-color-surface, #fff);--fondo-suave: var(--td-color-surface-soft, #f8fafc);--fondo-mudo: var(--td-color-surface-muted, #eef2f7);--borde: var(--td-color-border, #e4e8f0);--texto: var(--td-color-text, #263147);--suave: var(--td-color-text-muted, #748096);--acento: var(--td-color-primary, #5746d8);display:grid;gap:1rem;color:var(--texto);font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer--dark{--fondo: var(--td-color-surface, #15151b);--fondo-suave: var(--td-color-surface-soft, #1b1b22);--fondo-mudo: var(--td-color-surface-muted, #202028);--borde: var(--td-color-border, #2d2d36);--texto: var(--td-color-text, #ededf0);--suave: var(--td-color-text-muted, #9393a0);--acento: var(--td-color-primary, #a89cf7)}.td-file-viewer__header{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}.td-file-viewer__header span,.td-file-viewer-modal__badge,.td-file-viewer-modal__details>span{color:var(--acento);font-size:.66rem;font-weight:850;letter-spacing:.11em;text-transform:uppercase}.td-file-viewer__header h3,.td-file-viewer__header p,.td-file-viewer-modal h3,.td-file-viewer-modal p,.td-file-viewer-modal h4{margin:0}.td-file-viewer__header h3{margin-top:.18rem;font-size:1rem}.td-file-viewer__header p{margin-top:.25rem;color:var(--suave);font-size:.76rem;line-height:1.45}.td-file-viewer__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.75rem}.td-file-viewer--compact .td-file-viewer__grid{grid-template-columns:1fr}.td-file-viewer__item{display:grid;grid-template-columns:3.25rem minmax(0,1fr) auto;align-items:center;gap:.75rem;border:1px solid var(--borde);border-radius:var(--td-radius-lg, 1rem);padding:.72rem;color:inherit;background:linear-gradient(135deg,var(--fondo),var(--fondo-suave));box-shadow:var(--td-shadow-xs, 0 6px 18px rgba(31, 42, 68, .06));text-align:left;cursor:pointer;transition:border-color .14s ease,box-shadow .14s ease,transform .14s ease}.td-file-viewer__item:hover{border-color:var(--acento);box-shadow:var(--td-shadow-sm, 0 12px 28px rgba(31, 42, 68, .1));transform:translateY(-1px)}.td-file-viewer__preview{display:grid;width:3.25rem;height:3.25rem;place-items:center;overflow:hidden;border-radius:var(--td-radius-md, .85rem);color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,var(--fondo-suave))}.td-file-viewer__preview img{width:100%;height:100%;object-fit:cover}.td-file-viewer__meta{display:grid;min-width:0;gap:.15rem}.td-file-viewer__meta strong,.td-file-viewer__meta small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer__meta strong{font-size:.8rem}.td-file-viewer__meta small,.td-file-viewer__meta em{color:var(--suave);font-size:.7rem;font-style:normal}.td-file-viewer__download{display:grid;width:2rem;height:2rem;place-items:center;border-radius:var(--td-radius-sm, .55rem);color:var(--suave)}.td-file-viewer__download:hover{color:var(--acento);background:var(--fondo-suave)}.td-file-viewer__empty{display:grid;min-height:12rem;place-items:center;align-content:center;gap:.35rem;border:1px dashed var(--borde);border-radius:var(--td-radius-lg, 1rem);color:var(--suave);background:var(--fondo-suave);text-align:center}.td-file-viewer__empty strong{color:var(--texto)}.td-file-viewer-modal{position:fixed;inset:0;width:min(900px,100vw - 2rem);max-width:none;max-height:min(82dvh,720px);margin:auto;border:0;padding:0;overflow:visible;color:var(--td-color-text, #263147);background:transparent;font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer-modal::backdrop{background:#0a101e80;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px)}.td-file-viewer-modal__panel{display:grid;grid-template-rows:auto minmax(0,1fr);width:100%;max-height:min(82dvh,720px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-xl, 1.15rem);background:var(--td-color-surface, #fff);box-shadow:var(--td-shadow-xl, 0 24px 72px rgba(15, 23, 42, .28))}.td-file-viewer-modal--dark .td-file-viewer-modal__panel{border-color:var(--td-color-border, #2d2d36);background:var(--td-color-surface, #15151b)}.td-file-viewer-modal__topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.75rem .9rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__title{display:grid;min-width:0;gap:.12rem}.td-file-viewer-modal__badge{display:inline-flex;width:fit-content;align-items:center;gap:.35rem;color:var(--td-color-primary, #5746d8);font-size:.64rem;font-weight:850;letter-spacing:.1em;text-transform:uppercase}.td-file-viewer-modal h3,.td-file-viewer-modal h4,.td-file-viewer-modal p{margin:0}.td-file-viewer-modal__title h3{overflow:hidden;color:var(--td-color-text, #263147);font-size:.9rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__title p{overflow:hidden;color:var(--td-color-text-muted, #748096);font-size:.7rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__toolbar{display:flex;flex:0 0 auto;align-items:center;gap:.3rem}.td-file-viewer-modal__toolbar button,.td-file-viewer-modal__toolbar a{display:inline-grid;min-width:2rem;height:2rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .55rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);text-decoration:none;cursor:pointer}.td-file-viewer-modal__toolbar button:hover,.td-file-viewer-modal__toolbar a:hover{color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__toolbar button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__zoom{min-width:3rem!important;padding-inline:.45rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__text-action{width:auto!important;min-width:3.2rem!important;padding-inline:.55rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__divider{width:1px;height:1.25rem;margin-inline:.2rem;background:var(--td-color-border, #e4e8f0)}.td-file-viewer-modal__workspace{display:grid;grid-template-rows:minmax(0,1fr) auto;min-height:0;background:var(--td-color-surface-soft, #f8fafc)}.td-file-viewer-modal__canvas{display:grid;min-height:20rem;max-height:calc(82dvh - 8rem);place-items:center;overflow:auto;padding:1rem;background:linear-gradient(180deg,var(--td-color-surface-soft, #f8fafc),var(--td-color-surface, #fff))}.td-file-viewer-modal__image{display:block;width:auto;max-width:100%;max-height:min(58dvh,500px);border-radius:var(--td-radius-lg, 1rem);object-fit:contain;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .16));transition:transform .12s ease}.td-file-viewer-modal__pdf-shell{display:grid;grid-template-rows:auto minmax(0,1fr);width:min(820px,100%);height:min(60dvh,560px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-lg, 1rem);background:var(--td-color-surface, #fff)}.td-file-viewer-modal__pdf-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.55rem .65rem .55rem .75rem}.td-file-viewer-modal__pdf-head span{display:inline-flex;align-items:center;gap:.4rem;font-size:.75rem;font-weight:850}.td-file-viewer-modal__pdf-head small{color:var(--td-color-text-muted, #748096);font-size:.65rem}.td-file-viewer-modal__pdf-pages{display:inline-flex;align-items:center;gap:.35rem}.td-file-viewer-modal__pdf-pages button{display:inline-grid;width:1.8rem;height:1.8rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .5rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__pdf-pages button:hover:not(:disabled){color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__pdf-pages button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__pdf-canvas-wrap{position:relative;display:grid;min-height:0;overflow:auto;place-items:start center;padding:1rem;background:radial-gradient(circle at 1px 1px,rgba(100,116,139,.18) 1px,transparent 0) 0 0/18px 18px,var(--td-color-surface-muted, #eef2f7)}.td-file-viewer-modal__pdf-canvas{display:block;max-width:none;border-radius:var(--td-radius-sm, .45rem);background:#fff;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .2))}.td-file-viewer-modal__pdf-state{position:absolute;inset:0;display:grid;place-items:center;align-content:center;gap:.35rem;color:var(--td-color-text-muted, #748096);background:color-mix(in srgb,var(--td-color-surface, #fff) 78%,transparent);text-align:center}.td-file-viewer-modal__pdf-state strong{color:var(--td-color-text, #263147);font-size:.85rem}.td-file-viewer-modal__pdf-state--error{color:var(--td-color-danger, #dc2626);background:color-mix(in srgb,var(--td-color-surface, #fff) 92%,transparent)}.td-file-viewer-modal__spinner{display:block;width:2rem;height:2rem;border:3px solid color-mix(in srgb,var(--td-color-primary, #5746d8) 18%,transparent);border-top-color:var(--td-color-primary, #5746d8);border-radius:999px;animation:td-file-viewer-spin .8s linear infinite}@keyframes td-file-viewer-spin{to{transform:rotate(360deg)}}.td-file-viewer-modal__strip{display:flex;gap:.45rem;overflow-x:auto;border-top:1px solid var(--td-color-border, #e4e8f0);padding:.65rem .75rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__strip button{position:relative;display:grid;width:2.4rem;height:2.4rem;flex:0 0 auto;place-items:center;overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-sm, .6rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__strip img{width:100%;height:100%;object-fit:cover}.td-file-viewer-modal__thumb--active{border-color:var(--td-color-primary, #5746d8)!important;box-shadow:var(--td-focus-ring, 0 0 0 3px color-mix(in srgb, var(--td-color-primary, #5746d8) 15%, transparent))}.td-file-viewer-modal__no-preview{position:absolute;right:.12rem;bottom:.12rem;border-radius:var(--td-radius-pill, 999px);padding:.05rem .22rem;color:var(--td-color-text-muted, #748096);background:var(--td-color-surface, #fff);font-size:.46rem;font-weight:850;line-height:1.2}.td-file-viewer-modal__fallback{display:grid;place-items:center;align-content:center;gap:.7rem;color:var(--td-color-text-muted, #748096);text-align:center}.td-file-viewer-modal__fallback-icon{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:var(--td-radius-xl, 1.25rem);color:var(--td-color-primary, #5746d8);background:color-mix(in srgb,var(--td-color-primary, #5746d8) 10%,transparent)}.td-file-viewer-modal__fallback h4{color:var(--td-color-text, #263147)}.td-file-viewer-modal__fallback a{display:inline-flex;min-height:2.25rem;align-items:center;border-radius:var(--td-radius-md, .75rem);padding:0 .9rem;color:var(--td-color-on-primary, #fff);background:var(--td-color-primary, #5746d8);font-size:.75rem;font-weight:800;text-decoration:none}@media(max-width:640px){.td-file-viewer-modal{width:calc(100vw - 1.5rem);max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__panel{max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__topbar{align-items:flex-start;flex-direction:column}.td-file-viewer-modal__toolbar{width:100%;overflow-x:auto}.td-file-viewer-modal__canvas{min-height:16rem;max-height:calc(100dvh - 11rem);padding:.75rem}.td-file-viewer-modal__image,.td-file-viewer-modal__pdf-shell{max-height:calc(100dvh - 13rem)}}\n"], dependencies: [{ kind: "component", type: TdIcon, selector: "td-icon", inputs: ["nombre", "titulo", "tamano"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3016
3016
  }
3017
3017
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: TdFileViewer, decorators: [{
3018
3018
  type: Component,
3019
- args: [{ selector: 'td-file-viewer', imports: [TdIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showList) {\n <section\n class=\"td-file-viewer\"\n [class.td-file-viewer--dark]=\"oscuro\"\n [class.td-file-viewer--compact]=\"compacto\"\n >\n <header class=\"td-file-viewer__header\">\n <div>\n <span>{{ archivos.length }} archivo{{ archivos.length === 1 ? '' : 's' }}</span>\n <h3>{{ titulo }}</h3>\n @if (descripcion) {\n <p>{{ descripcion }}</p>\n }\n </div>\n </header>\n\n @if (archivos.length) {\n <div class=\"td-file-viewer__grid\">\n @for (archivo of archivos; track archivo.id) {\n <button type=\"button\" class=\"td-file-viewer__item\" (click)=\"abrir(archivo)\">\n <span class=\"td-file-viewer__preview\" [class.td-file-viewer__preview--image]=\"tipoArchivo(archivo) === 'imagen'\">\n @if (tipoArchivo(archivo) === 'imagen') {\n <img [src]=\"archivo.thumbnailUrl || archivo.url\" [alt]=\"archivo.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"1.55rem\" />\n }\n </span>\n\n <span class=\"td-file-viewer__meta\">\n <strong>{{ archivo.nombre }}</strong>\n @if (archivo.descripcion) {\n <small>{{ archivo.descripcion }}</small>\n }\n <em>\n {{ tieneVistaPrevia(archivo) ? 'Vista previa disponible' : 'Descarga / apertura externa' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </em>\n </span>\n\n @if (archivo.descargable !== false) {\n <span\n role=\"button\"\n tabindex=\"-1\"\n class=\"td-file-viewer__download\"\n title=\"Descargar\"\n (click)=\"descargarArchivo(archivo, $event)\"\n >\n <td-icon nombre=\"download\" tamano=\"1rem\" />\n </span>\n }\n </button>\n }\n </div>\n } @else {\n <div class=\"td-file-viewer__empty\">\n <td-icon nombre=\"file\" tamano=\"2rem\" />\n <strong>No hay adjuntos</strong>\n <span>Cuando existan archivos apareceran en esta zona.</span>\n </div>\n }\n </section>\n}\n\n@if (seleccionado; as archivo) {\n <dialog\n #visorDialog\n class=\"td-file-viewer-modal\"\n [class.td-file-viewer-modal--dark]=\"oscuro\"\n [attr.aria-label]=\"archivo.nombre\"\n (click)=\"cerrarSiBackdrop($event)\"\n (cancel)=\"cerrar()\"\n (close)=\"seleccionado = null\"\n >\n <section class=\"td-file-viewer-modal__panel\">\n <header class=\"td-file-viewer-modal__topbar\">\n <div class=\"td-file-viewer-modal__title\">\n <span class=\"td-file-viewer-modal__badge\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\".95rem\" />\n {{ tipoArchivo(archivo) }}\n </span>\n <h3>{{ archivo.nombre }}</h3>\n @if (archivo.descripcion || tamanoLegible(archivo)) {\n <p>\n {{ archivo.descripcion || 'Archivo adjunto' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </p>\n }\n </div>\n\n <nav class=\"td-file-viewer-modal__toolbar\" aria-label=\"Acciones del visor\">\n <button type=\"button\" title=\"Anterior\" [disabled]=\"indiceSeleccionado() <= 0\" (click)=\"seleccionarAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <button type=\"button\" title=\"Siguiente\" [disabled]=\"indiceSeleccionado() >= archivos.length - 1\" (click)=\"seleccionarSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n\n @if (esImagen(archivo) || esPdf(archivo)) {\n <span class=\"td-file-viewer-modal__divider\"></span>\n <button type=\"button\" title=\"Alejar\" (click)=\"cambiarZoom(-0.1)\">\n <span aria-hidden=\"true\">-</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__zoom\" title=\"Restablecer zoom\" (click)=\"restablecerZoom()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button type=\"button\" title=\"Acercar\" (click)=\"cambiarZoom(0.1)\">\n <span aria-hidden=\"true\">+</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Ajustar\" (click)=\"restablecerZoom()\">\n Ajustar\n </button>\n @if (esImagen(archivo)) {\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Rotar\" (click)=\"rotar()\">\n Rotar\n </button>\n }\n }\n\n <span class=\"td-file-viewer-modal__divider\"></span>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\" title=\"Abrir en nueva pestana\">\n <td-icon nombre=\"visibility\" />\n </a>\n @if (archivo.descargable !== false) {\n <a [href]=\"archivo.url\" [download]=\"archivo.nombre\" target=\"_blank\" rel=\"noopener\" title=\"Descargar\">\n <td-icon nombre=\"download\" />\n </a>\n }\n <button type=\"button\" title=\"Cerrar\" aria-label=\"Cerrar\" (click)=\"cerrar()\">\n <td-icon nombre=\"close\" />\n </button>\n </nav>\n </header>\n\n <div class=\"td-file-viewer-modal__workspace\">\n <main class=\"td-file-viewer-modal__canvas\">\n @if (esImagen(archivo)) {\n <img\n class=\"td-file-viewer-modal__image\"\n [src]=\"archivo.url\"\n [alt]=\"archivo.nombre\"\n [style.transform]=\"'scale(' + zoom + ') rotate(' + rotacion + 'deg)'\"\n />\n } @else if (esPdf(archivo)) {\n <section class=\"td-file-viewer-modal__pdf-shell\">\n <div class=\"td-file-viewer-modal__pdf-head\">\n <span>\n <td-icon nombre=\"pdf\" />\n Vista PDF\n </span>\n <div class=\"td-file-viewer-modal__pdf-pages\">\n <button type=\"button\" title=\"Pagina anterior\" [disabled]=\"pdfPaginaActual <= 1 || pdfCargando\" (click)=\"paginaPdfAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <small>\n Pagina {{ pdfPaginaActual }} de {{ pdfTotalPaginas || '-' }}\n </small>\n <button type=\"button\" title=\"Pagina siguiente\" [disabled]=\"!pdfTotalPaginas || pdfPaginaActual >= pdfTotalPaginas || pdfCargando\" (click)=\"paginaPdfSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n </div>\n </div>\n <div class=\"td-file-viewer-modal__pdf-canvas-wrap\">\n <canvas #pdfCanvas class=\"td-file-viewer-modal__pdf-canvas\"></canvas>\n\n @if (pdfCargando) {\n <div class=\"td-file-viewer-modal__pdf-state\">\n <span class=\"td-file-viewer-modal__spinner\"></span>\n <strong>Cargando PDF</strong>\n <small>Preparando pagina {{ pdfPaginaActual }}...</small>\n </div>\n }\n\n @if (pdfError) {\n <div class=\"td-file-viewer-modal__pdf-state td-file-viewer-modal__pdf-state--error\">\n <td-icon nombre=\"alert\" tamano=\"2rem\" />\n <strong>{{ pdfError }}</strong>\n <small>Prueba abrirlo en una nueva pesta\u00F1a o descargarlo.</small>\n </div>\n }\n </div>\n </section>\n } @else {\n <div class=\"td-file-viewer-modal__fallback\">\n <span class=\"td-file-viewer-modal__fallback-icon\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"3rem\" />\n </span>\n <h4>Vista previa no disponible</h4>\n <p>Este tipo de archivo debe abrirse o descargarse con una aplicacion compatible.</p>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\">\n Abrir archivo\n </a>\n </div>\n }\n </main>\n\n @if (archivos.length > 1) {\n <footer class=\"td-file-viewer-modal__strip\">\n @for (item of archivos; track item.id) {\n <button\n type=\"button\"\n [class.td-file-viewer-modal__thumb--active]=\"item.id === archivo.id\"\n [title]=\"item.nombre\"\n (click)=\"abrir(item)\"\n >\n @if (tipoArchivo(item) === 'imagen') {\n <img [src]=\"item.thumbnailUrl || item.url\" [alt]=\"item.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(item)\" />\n }\n @if (!tieneVistaPrevia(item)) {\n <span class=\"td-file-viewer-modal__no-preview\">Sin preview</span>\n }\n </button>\n }\n </footer>\n }\n </div>\n </section>\n </dialog>\n}\n", styles: [":host{display:block}*{box-sizing:border-box}.td-file-viewer{--fondo: var(--td-color-surface, #fff);--fondo-suave: var(--td-color-surface-soft, #f8fafc);--fondo-mudo: var(--td-color-surface-muted, #eef2f7);--borde: var(--td-color-border, #e4e8f0);--texto: var(--td-color-text, #263147);--suave: var(--td-color-text-muted, #748096);--acento: var(--td-color-primary, #5746d8);display:grid;gap:1rem;color:var(--texto);font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer--dark{--fondo: var(--td-color-surface, #15151b);--fondo-suave: var(--td-color-surface-soft, #1b1b22);--fondo-mudo: var(--td-color-surface-muted, #202028);--borde: var(--td-color-border, #2d2d36);--texto: var(--td-color-text, #ededf0);--suave: var(--td-color-text-muted, #9393a0);--acento: var(--td-color-primary, #a89cf7)}.td-file-viewer__header{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}.td-file-viewer__header span,.td-file-viewer-modal__badge,.td-file-viewer-modal__details>span{color:var(--acento);font-size:.66rem;font-weight:850;letter-spacing:.11em;text-transform:uppercase}.td-file-viewer__header h3,.td-file-viewer__header p,.td-file-viewer-modal h3,.td-file-viewer-modal p,.td-file-viewer-modal h4{margin:0}.td-file-viewer__header h3{margin-top:.18rem;font-size:1rem}.td-file-viewer__header p{margin-top:.25rem;color:var(--suave);font-size:.76rem;line-height:1.45}.td-file-viewer__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.75rem}.td-file-viewer--compact .td-file-viewer__grid{grid-template-columns:1fr}.td-file-viewer__item{display:grid;grid-template-columns:3.25rem minmax(0,1fr) auto;align-items:center;gap:.75rem;border:1px solid var(--borde);border-radius:var(--td-radius-lg, 1rem);padding:.72rem;color:inherit;background:linear-gradient(135deg,var(--fondo),var(--fondo-suave));box-shadow:var(--td-shadow-xs, 0 6px 18px rgba(31, 42, 68, .06));text-align:left;cursor:pointer;transition:border-color .14s ease,box-shadow .14s ease,transform .14s ease}.td-file-viewer__item:hover{border-color:var(--acento);box-shadow:var(--td-shadow-sm, 0 12px 28px rgba(31, 42, 68, .1));transform:translateY(-1px)}.td-file-viewer__preview{display:grid;width:3.25rem;height:3.25rem;place-items:center;overflow:hidden;border-radius:var(--td-radius-md, .85rem);color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,var(--fondo-suave))}.td-file-viewer__preview img{width:100%;height:100%;object-fit:cover}.td-file-viewer__meta{display:grid;min-width:0;gap:.15rem}.td-file-viewer__meta strong,.td-file-viewer__meta small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer__meta strong{font-size:.8rem}.td-file-viewer__meta small,.td-file-viewer__meta em{color:var(--suave);font-size:.7rem;font-style:normal}.td-file-viewer__download{display:grid;width:2rem;height:2rem;place-items:center;border-radius:var(--td-radius-sm, .55rem);color:var(--suave)}.td-file-viewer__download:hover{color:var(--acento);background:var(--fondo-suave)}.td-file-viewer__empty{display:grid;min-height:12rem;place-items:center;align-content:center;gap:.35rem;border:1px dashed var(--borde);border-radius:var(--td-radius-lg, 1rem);color:var(--suave);background:var(--fondo-suave);text-align:center}.td-file-viewer__empty strong{color:var(--texto)}.td-file-viewer-modal{width:min(900px,100vw - 2rem);max-width:none;max-height:min(82dvh,720px);border:0;padding:0;overflow:visible;color:var(--td-color-text, #263147);background:transparent;font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer-modal::backdrop{background:#0a101e80;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px)}.td-file-viewer-modal__panel{display:grid;grid-template-rows:auto minmax(0,1fr);width:100%;max-height:min(82dvh,720px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-xl, 1.15rem);background:var(--td-color-surface, #fff);box-shadow:var(--td-shadow-xl, 0 24px 72px rgba(15, 23, 42, .28))}.td-file-viewer-modal--dark .td-file-viewer-modal__panel{border-color:var(--td-color-border, #2d2d36);background:var(--td-color-surface, #15151b)}.td-file-viewer-modal__topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.75rem .9rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__title{display:grid;min-width:0;gap:.12rem}.td-file-viewer-modal__badge{display:inline-flex;width:fit-content;align-items:center;gap:.35rem;color:var(--td-color-primary, #5746d8);font-size:.64rem;font-weight:850;letter-spacing:.1em;text-transform:uppercase}.td-file-viewer-modal h3,.td-file-viewer-modal h4,.td-file-viewer-modal p{margin:0}.td-file-viewer-modal__title h3{overflow:hidden;color:var(--td-color-text, #263147);font-size:.9rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__title p{overflow:hidden;color:var(--td-color-text-muted, #748096);font-size:.7rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__toolbar{display:flex;flex:0 0 auto;align-items:center;gap:.3rem}.td-file-viewer-modal__toolbar button,.td-file-viewer-modal__toolbar a{display:inline-grid;min-width:2rem;height:2rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .55rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);text-decoration:none;cursor:pointer}.td-file-viewer-modal__toolbar button:hover,.td-file-viewer-modal__toolbar a:hover{color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__toolbar button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__zoom{min-width:3rem!important;padding-inline:.45rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__text-action{width:auto!important;min-width:3.2rem!important;padding-inline:.55rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__divider{width:1px;height:1.25rem;margin-inline:.2rem;background:var(--td-color-border, #e4e8f0)}.td-file-viewer-modal__workspace{display:grid;grid-template-rows:minmax(0,1fr) auto;min-height:0;background:var(--td-color-surface-soft, #f8fafc)}.td-file-viewer-modal__canvas{display:grid;min-height:20rem;max-height:calc(82dvh - 8rem);place-items:center;overflow:auto;padding:1rem;background:linear-gradient(180deg,var(--td-color-surface-soft, #f8fafc),var(--td-color-surface, #fff))}.td-file-viewer-modal__image{display:block;width:auto;max-width:100%;max-height:min(58dvh,500px);border-radius:var(--td-radius-lg, 1rem);object-fit:contain;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .16));transition:transform .12s ease}.td-file-viewer-modal__pdf-shell{display:grid;grid-template-rows:auto minmax(0,1fr);width:min(820px,100%);height:min(60dvh,560px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-lg, 1rem);background:var(--td-color-surface, #fff)}.td-file-viewer-modal__pdf-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.55rem .65rem .55rem .75rem}.td-file-viewer-modal__pdf-head span{display:inline-flex;align-items:center;gap:.4rem;font-size:.75rem;font-weight:850}.td-file-viewer-modal__pdf-head small{color:var(--td-color-text-muted, #748096);font-size:.65rem}.td-file-viewer-modal__pdf-pages{display:inline-flex;align-items:center;gap:.35rem}.td-file-viewer-modal__pdf-pages button{display:inline-grid;width:1.8rem;height:1.8rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .5rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__pdf-pages button:hover:not(:disabled){color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__pdf-pages button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__pdf-canvas-wrap{position:relative;display:grid;min-height:0;overflow:auto;place-items:start center;padding:1rem;background:radial-gradient(circle at 1px 1px,rgba(100,116,139,.18) 1px,transparent 0) 0 0/18px 18px,var(--td-color-surface-muted, #eef2f7)}.td-file-viewer-modal__pdf-canvas{display:block;max-width:none;border-radius:var(--td-radius-sm, .45rem);background:#fff;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .2))}.td-file-viewer-modal__pdf-state{position:absolute;inset:0;display:grid;place-items:center;align-content:center;gap:.35rem;color:var(--td-color-text-muted, #748096);background:color-mix(in srgb,var(--td-color-surface, #fff) 78%,transparent);text-align:center}.td-file-viewer-modal__pdf-state strong{color:var(--td-color-text, #263147);font-size:.85rem}.td-file-viewer-modal__pdf-state--error{color:var(--td-color-danger, #dc2626);background:color-mix(in srgb,var(--td-color-surface, #fff) 92%,transparent)}.td-file-viewer-modal__spinner{display:block;width:2rem;height:2rem;border:3px solid color-mix(in srgb,var(--td-color-primary, #5746d8) 18%,transparent);border-top-color:var(--td-color-primary, #5746d8);border-radius:999px;animation:td-file-viewer-spin .8s linear infinite}@keyframes td-file-viewer-spin{to{transform:rotate(360deg)}}.td-file-viewer-modal__strip{display:flex;gap:.45rem;overflow-x:auto;border-top:1px solid var(--td-color-border, #e4e8f0);padding:.65rem .75rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__strip button{position:relative;display:grid;width:2.4rem;height:2.4rem;flex:0 0 auto;place-items:center;overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-sm, .6rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__strip img{width:100%;height:100%;object-fit:cover}.td-file-viewer-modal__thumb--active{border-color:var(--td-color-primary, #5746d8)!important;box-shadow:var(--td-focus-ring, 0 0 0 3px color-mix(in srgb, var(--td-color-primary, #5746d8) 15%, transparent))}.td-file-viewer-modal__no-preview{position:absolute;right:.12rem;bottom:.12rem;border-radius:var(--td-radius-pill, 999px);padding:.05rem .22rem;color:var(--td-color-text-muted, #748096);background:var(--td-color-surface, #fff);font-size:.46rem;font-weight:850;line-height:1.2}.td-file-viewer-modal__fallback{display:grid;place-items:center;align-content:center;gap:.7rem;color:var(--td-color-text-muted, #748096);text-align:center}.td-file-viewer-modal__fallback-icon{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:var(--td-radius-xl, 1.25rem);color:var(--td-color-primary, #5746d8);background:color-mix(in srgb,var(--td-color-primary, #5746d8) 10%,transparent)}.td-file-viewer-modal__fallback h4{color:var(--td-color-text, #263147)}.td-file-viewer-modal__fallback a{display:inline-flex;min-height:2.25rem;align-items:center;border-radius:var(--td-radius-md, .75rem);padding:0 .9rem;color:var(--td-color-on-primary, #fff);background:var(--td-color-primary, #5746d8);font-size:.75rem;font-weight:800;text-decoration:none}@media(max-width:640px){.td-file-viewer-modal{width:calc(100vw - 1.5rem);max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__panel{max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__topbar{align-items:flex-start;flex-direction:column}.td-file-viewer-modal__toolbar{width:100%;overflow-x:auto}.td-file-viewer-modal__canvas{min-height:16rem;max-height:calc(100dvh - 11rem);padding:.75rem}.td-file-viewer-modal__image,.td-file-viewer-modal__pdf-shell{max-height:calc(100dvh - 13rem)}}\n"] }]
3019
+ args: [{ selector: 'td-file-viewer', imports: [TdIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showList) {\n <section\n class=\"td-file-viewer\"\n [class.td-file-viewer--dark]=\"oscuro\"\n [class.td-file-viewer--compact]=\"compacto\"\n >\n <header class=\"td-file-viewer__header\">\n <div>\n <span>{{ archivos.length }} archivo{{ archivos.length === 1 ? '' : 's' }}</span>\n <h3>{{ titulo }}</h3>\n @if (descripcion) {\n <p>{{ descripcion }}</p>\n }\n </div>\n </header>\n\n @if (archivos.length) {\n <div class=\"td-file-viewer__grid\">\n @for (archivo of archivos; track archivo.id) {\n <button type=\"button\" class=\"td-file-viewer__item\" (click)=\"abrir(archivo)\">\n <span class=\"td-file-viewer__preview\" [class.td-file-viewer__preview--image]=\"tipoArchivo(archivo) === 'imagen'\">\n @if (tipoArchivo(archivo) === 'imagen') {\n <img [src]=\"archivo.thumbnailUrl || archivo.url\" [alt]=\"archivo.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"1.55rem\" />\n }\n </span>\n\n <span class=\"td-file-viewer__meta\">\n <strong>{{ archivo.nombre }}</strong>\n @if (archivo.descripcion) {\n <small>{{ archivo.descripcion }}</small>\n }\n <em>\n {{ tieneVistaPrevia(archivo) ? 'Vista previa disponible' : 'Descarga / apertura externa' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </em>\n </span>\n\n @if (archivo.descargable !== false) {\n <span\n role=\"button\"\n tabindex=\"-1\"\n class=\"td-file-viewer__download\"\n title=\"Descargar\"\n (click)=\"descargarArchivo(archivo, $event)\"\n >\n <td-icon nombre=\"download\" tamano=\"1rem\" />\n </span>\n }\n </button>\n }\n </div>\n } @else {\n <div class=\"td-file-viewer__empty\">\n <td-icon nombre=\"file\" tamano=\"2rem\" />\n <strong>No hay adjuntos</strong>\n <span>Cuando existan archivos apareceran en esta zona.</span>\n </div>\n }\n </section>\n}\n\n@if (seleccionado; as archivo) {\n <dialog\n #visorDialog\n class=\"td-file-viewer-modal\"\n [class.td-file-viewer-modal--dark]=\"oscuro\"\n [attr.aria-label]=\"archivo.nombre\"\n (click)=\"cerrarSiBackdrop($event)\"\n (cancel)=\"cerrar()\"\n (close)=\"seleccionado = null\"\n >\n <section class=\"td-file-viewer-modal__panel\">\n <header class=\"td-file-viewer-modal__topbar\">\n <div class=\"td-file-viewer-modal__title\">\n <span class=\"td-file-viewer-modal__badge\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\".95rem\" />\n {{ tipoArchivo(archivo) }}\n </span>\n <h3>{{ archivo.nombre }}</h3>\n @if (archivo.descripcion || tamanoLegible(archivo)) {\n <p>\n {{ archivo.descripcion || 'Archivo adjunto' }}\n @if (tamanoLegible(archivo)) {\n - {{ tamanoLegible(archivo) }}\n }\n </p>\n }\n </div>\n\n <nav class=\"td-file-viewer-modal__toolbar\" aria-label=\"Acciones del visor\">\n <button type=\"button\" title=\"Anterior\" [disabled]=\"indiceSeleccionado() <= 0\" (click)=\"seleccionarAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <button type=\"button\" title=\"Siguiente\" [disabled]=\"indiceSeleccionado() >= archivos.length - 1\" (click)=\"seleccionarSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n\n @if (esImagen(archivo) || esPdf(archivo)) {\n <span class=\"td-file-viewer-modal__divider\"></span>\n <button type=\"button\" title=\"Alejar\" (click)=\"cambiarZoom(-0.1)\">\n <span aria-hidden=\"true\">-</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__zoom\" title=\"Restablecer zoom\" (click)=\"restablecerZoom()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button type=\"button\" title=\"Acercar\" (click)=\"cambiarZoom(0.1)\">\n <span aria-hidden=\"true\">+</span>\n </button>\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Ajustar\" (click)=\"restablecerZoom()\">\n Ajustar\n </button>\n @if (esImagen(archivo)) {\n <button type=\"button\" class=\"td-file-viewer-modal__text-action\" title=\"Rotar\" (click)=\"rotar()\">\n Rotar\n </button>\n }\n }\n\n <span class=\"td-file-viewer-modal__divider\"></span>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\" title=\"Abrir en nueva pestana\">\n <td-icon nombre=\"visibility\" />\n </a>\n @if (archivo.descargable !== false) {\n <a [href]=\"archivo.url\" [download]=\"archivo.nombre\" target=\"_blank\" rel=\"noopener\" title=\"Descargar\">\n <td-icon nombre=\"download\" />\n </a>\n }\n <button type=\"button\" title=\"Cerrar\" aria-label=\"Cerrar\" (click)=\"cerrar()\">\n <td-icon nombre=\"close\" />\n </button>\n </nav>\n </header>\n\n <div class=\"td-file-viewer-modal__workspace\">\n <main class=\"td-file-viewer-modal__canvas\">\n @if (esImagen(archivo)) {\n <img\n class=\"td-file-viewer-modal__image\"\n [src]=\"archivo.url\"\n [alt]=\"archivo.nombre\"\n [style.transform]=\"'scale(' + zoom + ') rotate(' + rotacion + 'deg)'\"\n />\n } @else if (esPdf(archivo)) {\n <section class=\"td-file-viewer-modal__pdf-shell\">\n <div class=\"td-file-viewer-modal__pdf-head\">\n <span>\n <td-icon nombre=\"pdf\" />\n Vista PDF\n </span>\n <div class=\"td-file-viewer-modal__pdf-pages\">\n <button type=\"button\" title=\"Pagina anterior\" [disabled]=\"pdfPaginaActual <= 1 || pdfCargando\" (click)=\"paginaPdfAnterior()\">\n <td-icon nombre=\"chevron_left\" />\n </button>\n <small>\n Pagina {{ pdfPaginaActual }} de {{ pdfTotalPaginas || '-' }}\n </small>\n <button type=\"button\" title=\"Pagina siguiente\" [disabled]=\"!pdfTotalPaginas || pdfPaginaActual >= pdfTotalPaginas || pdfCargando\" (click)=\"paginaPdfSiguiente()\">\n <td-icon nombre=\"chevron_right\" />\n </button>\n </div>\n </div>\n <div class=\"td-file-viewer-modal__pdf-canvas-wrap\">\n <canvas #pdfCanvas class=\"td-file-viewer-modal__pdf-canvas\"></canvas>\n\n @if (pdfCargando) {\n <div class=\"td-file-viewer-modal__pdf-state\">\n <span class=\"td-file-viewer-modal__spinner\"></span>\n <strong>Cargando PDF</strong>\n <small>Preparando pagina {{ pdfPaginaActual }}...</small>\n </div>\n }\n\n @if (pdfError) {\n <div class=\"td-file-viewer-modal__pdf-state td-file-viewer-modal__pdf-state--error\">\n <td-icon nombre=\"alert\" tamano=\"2rem\" />\n <strong>{{ pdfError }}</strong>\n <small>Prueba abrirlo en una nueva pesta\u00F1a o descargarlo.</small>\n </div>\n }\n </div>\n </section>\n } @else {\n <div class=\"td-file-viewer-modal__fallback\">\n <span class=\"td-file-viewer-modal__fallback-icon\">\n <td-icon [nombre]=\"iconoArchivo(archivo)\" tamano=\"3rem\" />\n </span>\n <h4>Vista previa no disponible</h4>\n <p>Este tipo de archivo debe abrirse o descargarse con una aplicacion compatible.</p>\n <a [href]=\"archivo.url\" target=\"_blank\" rel=\"noopener\">\n Abrir archivo\n </a>\n </div>\n }\n </main>\n\n @if (archivos.length > 1) {\n <footer class=\"td-file-viewer-modal__strip\">\n @for (item of archivos; track item.id) {\n <button\n type=\"button\"\n [class.td-file-viewer-modal__thumb--active]=\"item.id === archivo.id\"\n [title]=\"item.nombre\"\n (click)=\"abrir(item)\"\n >\n @if (tipoArchivo(item) === 'imagen') {\n <img [src]=\"item.thumbnailUrl || item.url\" [alt]=\"item.nombre\" loading=\"lazy\" />\n } @else {\n <td-icon [nombre]=\"iconoArchivo(item)\" />\n }\n @if (!tieneVistaPrevia(item)) {\n <span class=\"td-file-viewer-modal__no-preview\">Sin preview</span>\n }\n </button>\n }\n </footer>\n }\n </div>\n </section>\n </dialog>\n}\n", styles: [":host{display:block}*{box-sizing:border-box}.td-file-viewer{--fondo: var(--td-color-surface, #fff);--fondo-suave: var(--td-color-surface-soft, #f8fafc);--fondo-mudo: var(--td-color-surface-muted, #eef2f7);--borde: var(--td-color-border, #e4e8f0);--texto: var(--td-color-text, #263147);--suave: var(--td-color-text-muted, #748096);--acento: var(--td-color-primary, #5746d8);display:grid;gap:1rem;color:var(--texto);font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer--dark{--fondo: var(--td-color-surface, #15151b);--fondo-suave: var(--td-color-surface-soft, #1b1b22);--fondo-mudo: var(--td-color-surface-muted, #202028);--borde: var(--td-color-border, #2d2d36);--texto: var(--td-color-text, #ededf0);--suave: var(--td-color-text-muted, #9393a0);--acento: var(--td-color-primary, #a89cf7)}.td-file-viewer__header{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}.td-file-viewer__header span,.td-file-viewer-modal__badge,.td-file-viewer-modal__details>span{color:var(--acento);font-size:.66rem;font-weight:850;letter-spacing:.11em;text-transform:uppercase}.td-file-viewer__header h3,.td-file-viewer__header p,.td-file-viewer-modal h3,.td-file-viewer-modal p,.td-file-viewer-modal h4{margin:0}.td-file-viewer__header h3{margin-top:.18rem;font-size:1rem}.td-file-viewer__header p{margin-top:.25rem;color:var(--suave);font-size:.76rem;line-height:1.45}.td-file-viewer__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.75rem}.td-file-viewer--compact .td-file-viewer__grid{grid-template-columns:1fr}.td-file-viewer__item{display:grid;grid-template-columns:3.25rem minmax(0,1fr) auto;align-items:center;gap:.75rem;border:1px solid var(--borde);border-radius:var(--td-radius-lg, 1rem);padding:.72rem;color:inherit;background:linear-gradient(135deg,var(--fondo),var(--fondo-suave));box-shadow:var(--td-shadow-xs, 0 6px 18px rgba(31, 42, 68, .06));text-align:left;cursor:pointer;transition:border-color .14s ease,box-shadow .14s ease,transform .14s ease}.td-file-viewer__item:hover{border-color:var(--acento);box-shadow:var(--td-shadow-sm, 0 12px 28px rgba(31, 42, 68, .1));transform:translateY(-1px)}.td-file-viewer__preview{display:grid;width:3.25rem;height:3.25rem;place-items:center;overflow:hidden;border-radius:var(--td-radius-md, .85rem);color:var(--acento);background:color-mix(in srgb,var(--acento) 10%,var(--fondo-suave))}.td-file-viewer__preview img{width:100%;height:100%;object-fit:cover}.td-file-viewer__meta{display:grid;min-width:0;gap:.15rem}.td-file-viewer__meta strong,.td-file-viewer__meta small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer__meta strong{font-size:.8rem}.td-file-viewer__meta small,.td-file-viewer__meta em{color:var(--suave);font-size:.7rem;font-style:normal}.td-file-viewer__download{display:grid;width:2rem;height:2rem;place-items:center;border-radius:var(--td-radius-sm, .55rem);color:var(--suave)}.td-file-viewer__download:hover{color:var(--acento);background:var(--fondo-suave)}.td-file-viewer__empty{display:grid;min-height:12rem;place-items:center;align-content:center;gap:.35rem;border:1px dashed var(--borde);border-radius:var(--td-radius-lg, 1rem);color:var(--suave);background:var(--fondo-suave);text-align:center}.td-file-viewer__empty strong{color:var(--texto)}.td-file-viewer-modal{position:fixed;inset:0;width:min(900px,100vw - 2rem);max-width:none;max-height:min(82dvh,720px);margin:auto;border:0;padding:0;overflow:visible;color:var(--td-color-text, #263147);background:transparent;font-family:var(--td-font-family, Inter, ui-sans-serif, system-ui, sans-serif)}.td-file-viewer-modal::backdrop{background:#0a101e80;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px)}.td-file-viewer-modal__panel{display:grid;grid-template-rows:auto minmax(0,1fr);width:100%;max-height:min(82dvh,720px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-xl, 1.15rem);background:var(--td-color-surface, #fff);box-shadow:var(--td-shadow-xl, 0 24px 72px rgba(15, 23, 42, .28))}.td-file-viewer-modal--dark .td-file-viewer-modal__panel{border-color:var(--td-color-border, #2d2d36);background:var(--td-color-surface, #15151b)}.td-file-viewer-modal__topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.75rem .9rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__title{display:grid;min-width:0;gap:.12rem}.td-file-viewer-modal__badge{display:inline-flex;width:fit-content;align-items:center;gap:.35rem;color:var(--td-color-primary, #5746d8);font-size:.64rem;font-weight:850;letter-spacing:.1em;text-transform:uppercase}.td-file-viewer-modal h3,.td-file-viewer-modal h4,.td-file-viewer-modal p{margin:0}.td-file-viewer-modal__title h3{overflow:hidden;color:var(--td-color-text, #263147);font-size:.9rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__title p{overflow:hidden;color:var(--td-color-text-muted, #748096);font-size:.7rem;text-overflow:ellipsis;white-space:nowrap}.td-file-viewer-modal__toolbar{display:flex;flex:0 0 auto;align-items:center;gap:.3rem}.td-file-viewer-modal__toolbar button,.td-file-viewer-modal__toolbar a{display:inline-grid;min-width:2rem;height:2rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .55rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);text-decoration:none;cursor:pointer}.td-file-viewer-modal__toolbar button:hover,.td-file-viewer-modal__toolbar a:hover{color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__toolbar button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__zoom{min-width:3rem!important;padding-inline:.45rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__text-action{width:auto!important;min-width:3.2rem!important;padding-inline:.55rem;color:var(--td-color-text, #263147)!important;font-size:.7rem;font-weight:800}.td-file-viewer-modal__divider{width:1px;height:1.25rem;margin-inline:.2rem;background:var(--td-color-border, #e4e8f0)}.td-file-viewer-modal__workspace{display:grid;grid-template-rows:minmax(0,1fr) auto;min-height:0;background:var(--td-color-surface-soft, #f8fafc)}.td-file-viewer-modal__canvas{display:grid;min-height:20rem;max-height:calc(82dvh - 8rem);place-items:center;overflow:auto;padding:1rem;background:linear-gradient(180deg,var(--td-color-surface-soft, #f8fafc),var(--td-color-surface, #fff))}.td-file-viewer-modal__image{display:block;width:auto;max-width:100%;max-height:min(58dvh,500px);border-radius:var(--td-radius-lg, 1rem);object-fit:contain;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .16));transition:transform .12s ease}.td-file-viewer-modal__pdf-shell{display:grid;grid-template-rows:auto minmax(0,1fr);width:min(820px,100%);height:min(60dvh,560px);overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-lg, 1rem);background:var(--td-color-surface, #fff)}.td-file-viewer-modal__pdf-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-bottom:1px solid var(--td-color-border, #e4e8f0);padding:.55rem .65rem .55rem .75rem}.td-file-viewer-modal__pdf-head span{display:inline-flex;align-items:center;gap:.4rem;font-size:.75rem;font-weight:850}.td-file-viewer-modal__pdf-head small{color:var(--td-color-text-muted, #748096);font-size:.65rem}.td-file-viewer-modal__pdf-pages{display:inline-flex;align-items:center;gap:.35rem}.td-file-viewer-modal__pdf-pages button{display:inline-grid;width:1.8rem;height:1.8rem;place-items:center;border:0;border-radius:var(--td-radius-sm, .5rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__pdf-pages button:hover:not(:disabled){color:var(--td-color-primary, #5746d8)}.td-file-viewer-modal__pdf-pages button:disabled{opacity:.38;cursor:not-allowed}.td-file-viewer-modal__pdf-canvas-wrap{position:relative;display:grid;min-height:0;overflow:auto;place-items:start center;padding:1rem;background:radial-gradient(circle at 1px 1px,rgba(100,116,139,.18) 1px,transparent 0) 0 0/18px 18px,var(--td-color-surface-muted, #eef2f7)}.td-file-viewer-modal__pdf-canvas{display:block;max-width:none;border-radius:var(--td-radius-sm, .45rem);background:#fff;box-shadow:var(--td-shadow-md, 0 16px 42px rgba(15, 23, 42, .2))}.td-file-viewer-modal__pdf-state{position:absolute;inset:0;display:grid;place-items:center;align-content:center;gap:.35rem;color:var(--td-color-text-muted, #748096);background:color-mix(in srgb,var(--td-color-surface, #fff) 78%,transparent);text-align:center}.td-file-viewer-modal__pdf-state strong{color:var(--td-color-text, #263147);font-size:.85rem}.td-file-viewer-modal__pdf-state--error{color:var(--td-color-danger, #dc2626);background:color-mix(in srgb,var(--td-color-surface, #fff) 92%,transparent)}.td-file-viewer-modal__spinner{display:block;width:2rem;height:2rem;border:3px solid color-mix(in srgb,var(--td-color-primary, #5746d8) 18%,transparent);border-top-color:var(--td-color-primary, #5746d8);border-radius:999px;animation:td-file-viewer-spin .8s linear infinite}@keyframes td-file-viewer-spin{to{transform:rotate(360deg)}}.td-file-viewer-modal__strip{display:flex;gap:.45rem;overflow-x:auto;border-top:1px solid var(--td-color-border, #e4e8f0);padding:.65rem .75rem;background:var(--td-color-surface, #fff)}.td-file-viewer-modal__strip button{position:relative;display:grid;width:2.4rem;height:2.4rem;flex:0 0 auto;place-items:center;overflow:hidden;border:1px solid var(--td-color-border, #e4e8f0);border-radius:var(--td-radius-sm, .6rem);color:var(--td-color-text-muted, #748096);background:var(--td-color-surface-soft, #f8fafc);cursor:pointer}.td-file-viewer-modal__strip img{width:100%;height:100%;object-fit:cover}.td-file-viewer-modal__thumb--active{border-color:var(--td-color-primary, #5746d8)!important;box-shadow:var(--td-focus-ring, 0 0 0 3px color-mix(in srgb, var(--td-color-primary, #5746d8) 15%, transparent))}.td-file-viewer-modal__no-preview{position:absolute;right:.12rem;bottom:.12rem;border-radius:var(--td-radius-pill, 999px);padding:.05rem .22rem;color:var(--td-color-text-muted, #748096);background:var(--td-color-surface, #fff);font-size:.46rem;font-weight:850;line-height:1.2}.td-file-viewer-modal__fallback{display:grid;place-items:center;align-content:center;gap:.7rem;color:var(--td-color-text-muted, #748096);text-align:center}.td-file-viewer-modal__fallback-icon{display:grid;width:4.5rem;height:4.5rem;place-items:center;border-radius:var(--td-radius-xl, 1.25rem);color:var(--td-color-primary, #5746d8);background:color-mix(in srgb,var(--td-color-primary, #5746d8) 10%,transparent)}.td-file-viewer-modal__fallback h4{color:var(--td-color-text, #263147)}.td-file-viewer-modal__fallback a{display:inline-flex;min-height:2.25rem;align-items:center;border-radius:var(--td-radius-md, .75rem);padding:0 .9rem;color:var(--td-color-on-primary, #fff);background:var(--td-color-primary, #5746d8);font-size:.75rem;font-weight:800;text-decoration:none}@media(max-width:640px){.td-file-viewer-modal{width:calc(100vw - 1.5rem);max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__panel{max-height:calc(100dvh - 1.5rem)}.td-file-viewer-modal__topbar{align-items:flex-start;flex-direction:column}.td-file-viewer-modal__toolbar{width:100%;overflow-x:auto}.td-file-viewer-modal__canvas{min-height:16rem;max-height:calc(100dvh - 11rem);padding:.75rem}.td-file-viewer-modal__image,.td-file-viewer-modal__pdf-shell{max-height:calc(100dvh - 13rem)}}\n"] }]
3020
3020
  }], propDecorators: { visorDialog: [{
3021
3021
  type: ViewChild,
3022
3022
  args: ['visorDialog']