@caribeng/ui 22.4.0 → 22.5.0

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.
Files changed (186) hide show
  1. package/README.md +311 -313
  2. package/fesm2022/caribeng-ui-account-picker.mjs +533 -0
  3. package/fesm2022/caribeng-ui-aging.mjs +488 -0
  4. package/fesm2022/{caribeng-ui-caribe-alert.mjs → caribeng-ui-alert.mjs} +45 -45
  5. package/fesm2022/caribeng-ui-amount.mjs +249 -0
  6. package/fesm2022/caribeng-ui-anchor.mjs +2 -2
  7. package/fesm2022/{caribeng-ui-caribe-animation-lottie.mjs → caribeng-ui-animation-lottie.mjs} +41 -41
  8. package/fesm2022/caribeng-ui-audit-log.mjs +323 -0
  9. package/fesm2022/caribeng-ui-avatar.mjs +2 -2
  10. package/fesm2022/caribeng-ui-breadcrumb.mjs +13 -3
  11. package/fesm2022/{caribeng-ui-caribe-button-group.mjs → caribeng-ui-button-group.mjs} +15 -15
  12. package/fesm2022/caribeng-ui-button.mjs +2 -2
  13. package/fesm2022/{caribeng-ui-caribe-card-content.mjs → caribeng-ui-card-content.mjs} +39 -39
  14. package/fesm2022/{caribeng-ui-caribe-card-move.mjs → caribeng-ui-card-move.mjs} +65 -65
  15. package/fesm2022/{caribeng-ui-caribe-card-primary.mjs → caribeng-ui-card-primary.mjs} +31 -31
  16. package/fesm2022/{caribeng-ui-caribe-card-select.mjs → caribeng-ui-card-select.mjs} +67 -67
  17. package/fesm2022/caribeng-ui-carousel.mjs +2 -2
  18. package/fesm2022/caribeng-ui-cascadeselect.mjs +45 -9
  19. package/fesm2022/caribeng-ui-chat.mjs +2 -2
  20. package/fesm2022/{caribeng-ui-caribe-coachmark.mjs → caribeng-ui-coachmark.mjs} +85 -85
  21. package/fesm2022/caribeng-ui-command-palette.mjs +2 -2
  22. package/fesm2022/caribeng-ui-comments.mjs +864 -0
  23. package/fesm2022/caribeng-ui-datagrid.mjs +1635 -0
  24. package/fesm2022/caribeng-ui-dataview.mjs +2 -2
  25. package/fesm2022/caribeng-ui-datepicker.mjs +2 -2
  26. package/fesm2022/caribeng-ui-document.mjs +495 -0
  27. package/fesm2022/{caribeng-ui-caribe-dots-indicator.mjs → caribeng-ui-dots-indicator.mjs} +41 -41
  28. package/fesm2022/caribeng-ui-dynamic-form.mjs +1581 -0
  29. package/fesm2022/caribeng-ui-editor.mjs +2303 -1311
  30. package/fesm2022/{caribeng-ui-caribe-expansion-panel.mjs → caribeng-ui-expansion-panel.mjs} +39 -39
  31. package/fesm2022/{caribeng-ui-caribe-fab-menu.mjs → caribeng-ui-fab-menu.mjs} +75 -75
  32. package/fesm2022/caribeng-ui-file-card.mjs +2 -2
  33. package/fesm2022/{caribeng-ui-caribe-file-download.mjs → caribeng-ui-file-download.mjs} +63 -63
  34. package/fesm2022/caribeng-ui-financial-report.mjs +380 -0
  35. package/fesm2022/{caribeng-ui-caribe-float-menu.mjs → caribeng-ui-float-menu.mjs} +31 -31
  36. package/fesm2022/caribeng-ui-floatlabel.mjs +2 -2
  37. package/fesm2022/caribeng-ui-flow.mjs +1508 -0
  38. package/fesm2022/{caribeng-ui-caribe-footer.mjs → caribeng-ui-footer.mjs} +19 -19
  39. package/fesm2022/caribeng-ui-gantt.mjs +1094 -0
  40. package/fesm2022/{caribeng-ui-caribe-header.mjs → caribeng-ui-header.mjs} +49 -49
  41. package/fesm2022/{caribeng-ui-caribe-icon-button.mjs → caribeng-ui-icon-button.mjs} +23 -23
  42. package/fesm2022/caribeng-ui-image-cropper.mjs +671 -0
  43. package/fesm2022/caribeng-ui-import-wizard.mjs +746 -0
  44. package/fesm2022/caribeng-ui-infinite-scroll.mjs +226 -0
  45. package/fesm2022/caribeng-ui-input-number.mjs +22 -6
  46. package/fesm2022/{caribeng-ui-caribe-input-search.mjs → caribeng-ui-input-search.mjs} +65 -65
  47. package/fesm2022/{caribeng-ui-caribe-input-token.mjs → caribeng-ui-input-token.mjs} +59 -59
  48. package/fesm2022/caribeng-ui-inputotp.mjs +2 -2
  49. package/fesm2022/caribeng-ui-journal-entry.mjs +340 -0
  50. package/fesm2022/caribeng-ui-kanban.mjs +6 -6
  51. package/fesm2022/caribeng-ui-kpi.mjs +189 -0
  52. package/fesm2022/{caribeng-ui-caribe-link.mjs → caribeng-ui-link.mjs} +37 -37
  53. package/fesm2022/caribeng-ui-masonry.mjs +93 -0
  54. package/fesm2022/caribeng-ui-media-player.mjs +821 -0
  55. package/fesm2022/caribeng-ui-mentions.mjs +2 -2
  56. package/fesm2022/caribeng-ui-notification-center.mjs +636 -0
  57. package/fesm2022/{caribeng-ui-caribe-off-canvas.mjs → caribeng-ui-off-canvas.mjs} +55 -55
  58. package/fesm2022/{caribeng-ui-caribe-onboarding.mjs → caribeng-ui-onboarding.mjs} +105 -105
  59. package/fesm2022/caribeng-ui-orderlist.mjs +2 -2
  60. package/fesm2022/caribeng-ui-pdfviewer.mjs +1755 -25
  61. package/fesm2022/caribeng-ui-period-picker.mjs +637 -0
  62. package/fesm2022/caribeng-ui-phone-input.mjs +2 -2
  63. package/fesm2022/caribeng-ui-picklist.mjs +2 -2
  64. package/fesm2022/caribeng-ui-pivot.mjs +419 -0
  65. package/fesm2022/caribeng-ui-pricing.mjs +2 -2
  66. package/fesm2022/caribeng-ui-rating.mjs +14 -17
  67. package/fesm2022/caribeng-ui-reconciliation.mjs +386 -0
  68. package/fesm2022/caribeng-ui-scheduler.mjs +1027 -0
  69. package/fesm2022/caribeng-ui-select.mjs +2 -2
  70. package/fesm2022/{caribeng-ui-caribe-shortcut.mjs → caribeng-ui-shortcut.mjs} +29 -29
  71. package/fesm2022/caribeng-ui-sidebar.mjs +2 -2
  72. package/fesm2022/caribeng-ui-signature-pad.mjs +654 -0
  73. package/fesm2022/{caribeng-ui-caribe-status.mjs → caribeng-ui-status.mjs} +11 -11
  74. package/fesm2022/{caribeng-ui-caribe-step-indicator.mjs → caribeng-ui-step-indicator.mjs} +53 -53
  75. package/fesm2022/caribeng-ui-stepper.mjs +2 -2
  76. package/fesm2022/caribeng-ui-steps.mjs +2 -2
  77. package/fesm2022/caribeng-ui-table.mjs +323 -15
  78. package/fesm2022/caribeng-ui-tabmenu.mjs +2 -2
  79. package/fesm2022/caribeng-ui-tabs.mjs +2 -2
  80. package/fesm2022/{caribeng-ui-caribe-tag-button.mjs → caribeng-ui-tag-button.mjs} +25 -25
  81. package/fesm2022/caribeng-ui-tag.mjs +2 -2
  82. package/fesm2022/caribeng-ui-tieredmenu.mjs +6 -6
  83. package/fesm2022/{caribeng-ui-caribe-tracker.mjs → caribeng-ui-tracker.mjs} +29 -29
  84. package/fesm2022/{caribeng-ui-caribe-transaction-status.mjs → caribeng-ui-transaction-status.mjs} +11 -11
  85. package/fesm2022/caribeng-ui-treeselect.mjs +44 -9
  86. package/fesm2022/caribeng-ui-treetable.mjs +236 -17
  87. package/fesm2022/{caribeng-ui-caribe-voucher.mjs → caribeng-ui-voucher.mjs} +45 -45
  88. package/fesm2022/caribeng-ui-xlsx.mjs +486 -0
  89. package/fesm2022/caribeng-ui.mjs +1181 -1
  90. package/package.json +217 -177
  91. package/types/caribeng-ui-account-picker.d.ts +142 -0
  92. package/types/caribeng-ui-aging.d.ts +123 -0
  93. package/types/{caribeng-ui-caribe-alert.d.ts → caribeng-ui-alert.d.ts} +2 -2
  94. package/types/caribeng-ui-amount.d.ts +82 -0
  95. package/types/{caribeng-ui-caribe-animation-lottie.d.ts → caribeng-ui-animation-lottie.d.ts} +2 -2
  96. package/types/caribeng-ui-audit-log.d.ts +86 -0
  97. package/types/caribeng-ui-breadcrumb.d.ts +2 -2
  98. package/types/{caribeng-ui-caribe-button-group.d.ts → caribeng-ui-button-group.d.ts} +2 -2
  99. package/types/{caribeng-ui-caribe-card-content.d.ts → caribeng-ui-card-content.d.ts} +2 -2
  100. package/types/{caribeng-ui-caribe-card-move.d.ts → caribeng-ui-card-move.d.ts} +1 -1
  101. package/types/{caribeng-ui-caribe-card-primary.d.ts → caribeng-ui-card-primary.d.ts} +2 -2
  102. package/types/{caribeng-ui-caribe-card-select.d.ts → caribeng-ui-card-select.d.ts} +2 -2
  103. package/types/caribeng-ui-cascadeselect.d.ts +6 -0
  104. package/types/{caribeng-ui-caribe-coachmark.d.ts → caribeng-ui-coachmark.d.ts} +2 -2
  105. package/types/caribeng-ui-comments.d.ts +214 -0
  106. package/types/caribeng-ui-datagrid.d.ts +269 -0
  107. package/types/caribeng-ui-document.d.ts +138 -0
  108. package/types/{caribeng-ui-caribe-dots-indicator.d.ts → caribeng-ui-dots-indicator.d.ts} +2 -2
  109. package/types/caribeng-ui-dynamic-form.d.ts +409 -0
  110. package/types/caribeng-ui-editor.d.ts +110 -12
  111. package/types/{caribeng-ui-caribe-expansion-panel.d.ts → caribeng-ui-expansion-panel.d.ts} +1 -1
  112. package/types/{caribeng-ui-caribe-fab-menu.d.ts → caribeng-ui-fab-menu.d.ts} +2 -2
  113. package/types/{caribeng-ui-caribe-file-download.d.ts → caribeng-ui-file-download.d.ts} +1 -1
  114. package/types/caribeng-ui-financial-report.d.ts +102 -0
  115. package/types/{caribeng-ui-caribe-float-menu.d.ts → caribeng-ui-float-menu.d.ts} +2 -2
  116. package/types/caribeng-ui-flow.d.ts +228 -0
  117. package/types/{caribeng-ui-caribe-footer.d.ts → caribeng-ui-footer.d.ts} +2 -2
  118. package/types/caribeng-ui-gantt.d.ts +244 -0
  119. package/types/{caribeng-ui-caribe-header.d.ts → caribeng-ui-header.d.ts} +2 -2
  120. package/types/{caribeng-ui-caribe-icon-button.d.ts → caribeng-ui-icon-button.d.ts} +2 -2
  121. package/types/{caribeng-ui-caribe-illustration.d.ts → caribeng-ui-illustration.d.ts} +1 -1
  122. package/types/caribeng-ui-image-cropper.d.ts +169 -0
  123. package/types/caribeng-ui-import-wizard.d.ts +149 -0
  124. package/types/caribeng-ui-infinite-scroll.d.ts +75 -0
  125. package/types/caribeng-ui-input-number.d.ts +1 -1
  126. package/types/{caribeng-ui-caribe-input-search.d.ts → caribeng-ui-input-search.d.ts} +2 -2
  127. package/types/{caribeng-ui-caribe-input-token.d.ts → caribeng-ui-input-token.d.ts} +2 -2
  128. package/types/caribeng-ui-journal-entry.d.ts +110 -0
  129. package/types/caribeng-ui-kpi.d.ts +64 -0
  130. package/types/{caribeng-ui-caribe-link.d.ts → caribeng-ui-link.d.ts} +2 -2
  131. package/types/{caribeng-ui-caribe-logo.d.ts → caribeng-ui-logo.d.ts} +1 -1
  132. package/types/caribeng-ui-masonry.d.ts +32 -0
  133. package/types/caribeng-ui-media-player.d.ts +140 -0
  134. package/types/caribeng-ui-notification-center.d.ts +153 -0
  135. package/types/{caribeng-ui-caribe-off-canvas.d.ts → caribeng-ui-off-canvas.d.ts} +2 -2
  136. package/types/{caribeng-ui-caribe-onboarding.d.ts → caribeng-ui-onboarding.d.ts} +2 -2
  137. package/types/caribeng-ui-pdfviewer.d.ts +245 -5
  138. package/types/caribeng-ui-period-picker.d.ts +148 -0
  139. package/types/caribeng-ui-pivot.d.ts +116 -0
  140. package/types/caribeng-ui-reconciliation.d.ts +109 -0
  141. package/types/caribeng-ui-scheduler.d.ts +188 -0
  142. package/types/{caribeng-ui-caribe-shortcut.d.ts → caribeng-ui-shortcut.d.ts} +2 -2
  143. package/types/caribeng-ui-signature-pad.d.ts +151 -0
  144. package/types/{caribeng-ui-caribe-status.d.ts → caribeng-ui-status.d.ts} +2 -2
  145. package/types/{caribeng-ui-caribe-step-indicator.d.ts → caribeng-ui-step-indicator.d.ts} +2 -2
  146. package/types/caribeng-ui-table.d.ts +66 -2
  147. package/types/{caribeng-ui-caribe-tag-button.d.ts → caribeng-ui-tag-button.d.ts} +2 -2
  148. package/types/{caribeng-ui-caribe-tracker.d.ts → caribeng-ui-tracker.d.ts} +2 -2
  149. package/types/{caribeng-ui-caribe-transaction-status.d.ts → caribeng-ui-transaction-status.d.ts} +2 -2
  150. package/types/caribeng-ui-treeselect.d.ts +6 -0
  151. package/types/caribeng-ui-treetable.d.ts +67 -2
  152. package/types/{caribeng-ui-caribe-voucher.d.ts → caribeng-ui-voucher.d.ts} +2 -2
  153. package/types/caribeng-ui-xlsx.d.ts +79 -0
  154. package/types/caribeng-ui.d.ts +711 -2
  155. package/fesm2022/caribeng-ui-caribe-calendar.mjs +0 -92
  156. package/fesm2022/caribeng-ui-caribe-circle-loading.mjs +0 -130
  157. package/fesm2022/caribeng-ui-caribe-data-table.mjs +0 -94
  158. package/fesm2022/caribeng-ui-caribe-file-select.mjs +0 -88
  159. package/fesm2022/caribeng-ui-caribe-inline-alert.mjs +0 -100
  160. package/fesm2022/caribeng-ui-caribe-input-date.mjs +0 -138
  161. package/fesm2022/caribeng-ui-caribe-input-select.mjs +0 -154
  162. package/fesm2022/caribeng-ui-caribe-loader.mjs +0 -48
  163. package/fesm2022/caribeng-ui-caribe-modal.mjs +0 -119
  164. package/fesm2022/caribeng-ui-caribe-pictogram.mjs +0 -52
  165. package/fesm2022/caribeng-ui-caribe-pop-over.mjs +0 -104
  166. package/fesm2022/caribeng-ui-caribe-preloader.mjs +0 -57
  167. package/fesm2022/caribeng-ui-caribe-progress-bar.mjs +0 -84
  168. package/fesm2022/caribeng-ui-caribe-stroke.mjs +0 -69
  169. package/fesm2022/caribeng-ui-caribe-switch.mjs +0 -182
  170. package/types/caribeng-ui-caribe-calendar.d.ts +0 -27
  171. package/types/caribeng-ui-caribe-circle-loading.d.ts +0 -28
  172. package/types/caribeng-ui-caribe-data-table.d.ts +0 -26
  173. package/types/caribeng-ui-caribe-file-select.d.ts +0 -31
  174. package/types/caribeng-ui-caribe-inline-alert.d.ts +0 -28
  175. package/types/caribeng-ui-caribe-input-date.d.ts +0 -40
  176. package/types/caribeng-ui-caribe-input-select.d.ts +0 -47
  177. package/types/caribeng-ui-caribe-loader.d.ts +0 -22
  178. package/types/caribeng-ui-caribe-modal.d.ts +0 -21
  179. package/types/caribeng-ui-caribe-pictogram.d.ts +0 -15
  180. package/types/caribeng-ui-caribe-pop-over.d.ts +0 -17
  181. package/types/caribeng-ui-caribe-preloader.d.ts +0 -24
  182. package/types/caribeng-ui-caribe-progress-bar.d.ts +0 -28
  183. package/types/caribeng-ui-caribe-stroke.d.ts +0 -17
  184. package/types/caribeng-ui-caribe-switch.d.ts +0 -55
  185. /package/fesm2022/{caribeng-ui-caribe-illustration.mjs → caribeng-ui-illustration.mjs} +0 -0
  186. /package/fesm2022/{caribeng-ui-caribe-logo.mjs → caribeng-ui-logo.mjs} +0 -0
@@ -0,0 +1,821 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, inject, ElementRef, input, numberAttribute, booleanAttribute, output, contentChild, viewChild, signal, computed, DestroyRef, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { DOCUMENT } from '@angular/common';
4
+ import { injectCbTranslation, cbFormat } from '@caribeng/ui';
5
+ import { CbIconRegistry, CbIcon } from '@caribeng/ui/icon';
6
+ import { pictureInPicture2, captions, volumeX, volume2, pause } from '@caribeng/ui/icons';
7
+
8
+ /** Velocidades por defecto. */
9
+ const CB_MEDIA_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2];
10
+ /** "1:05" o "1:02:05" (con `total` de una hora o más, siempre con horas). */
11
+ function formatTime(seconds, total = seconds) {
12
+ if (!Number.isFinite(seconds) || seconds < 0)
13
+ seconds = 0;
14
+ const s = Math.floor(seconds % 60);
15
+ const m = Math.floor((seconds / 60) % 60);
16
+ const h = Math.floor(seconds / 3600);
17
+ const pad = (n) => String(n).padStart(2, '0');
18
+ return h > 0 || total >= 3600 ? `${h}:${pad(m)}:${pad(s)}` : `${m}:${pad(s)}`;
19
+ }
20
+ /** Tiempo para lectores de pantalla: "1 minuto 5 segundos". */
21
+ function spokenTime(seconds, units) {
22
+ if (!Number.isFinite(seconds) || seconds < 0)
23
+ seconds = 0;
24
+ const h = Math.floor(seconds / 3600);
25
+ const m = Math.floor((seconds / 60) % 60);
26
+ const s = Math.floor(seconds % 60);
27
+ const parts = [];
28
+ if (h)
29
+ parts.push(`${h} ${units.hours}`);
30
+ if (m)
31
+ parts.push(`${m} ${units.minutes}`);
32
+ if (s || !parts.length)
33
+ parts.push(`${s} ${units.seconds}`);
34
+ return parts.join(' ');
35
+ }
36
+ /**
37
+ * Atajo para una tecla (como en YouTube): Espacio / K reproduce o pausa, ← → 5 s, J / L 10 s,
38
+ * ↑ ↓ volumen, M silencio, F pantalla completa, C subtítulos, Inicio / Fin y 0–9 saltan al
39
+ * 0–90 %. Devuelve null si la tecla no es un atajo o viene con Ctrl, Alt o ⌘.
40
+ */
41
+ function shortcutFor(event) {
42
+ if (event.ctrlKey || event.altKey || event.metaKey)
43
+ return null;
44
+ const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;
45
+ switch (key) {
46
+ case ' ':
47
+ case 'k':
48
+ return { action: 'toggle' };
49
+ case 'ArrowLeft':
50
+ return { action: 'seekBy', seconds: -5 };
51
+ case 'ArrowRight':
52
+ return { action: 'seekBy', seconds: 5 };
53
+ case 'j':
54
+ return { action: 'seekBy', seconds: -10 };
55
+ case 'l':
56
+ return { action: 'seekBy', seconds: 10 };
57
+ case 'ArrowUp':
58
+ return { action: 'volumeBy', delta: 0.1 };
59
+ case 'ArrowDown':
60
+ return { action: 'volumeBy', delta: -0.1 };
61
+ case 'm':
62
+ return { action: 'mute' };
63
+ case 'f':
64
+ return { action: 'fullscreen' };
65
+ case 'c':
66
+ return { action: 'captions' };
67
+ case 'Home':
68
+ return { action: 'seekTo', fraction: 0 };
69
+ case 'End':
70
+ return { action: 'seekTo', fraction: 1 };
71
+ default:
72
+ return /^[0-9]$/.test(key) ? { action: 'seekTo', fraction: Number(key) / 10 } : null;
73
+ }
74
+ }
75
+
76
+ /** Transcripción del medio (`<div cbMediaTranscript>…</div>`), en un desplegable bajo los controles. */
77
+ class CbMediaTranscript {
78
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbMediaTranscript, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
79
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: CbMediaTranscript, isStandalone: true, selector: "[cbMediaTranscript]", ngImport: i0 }); }
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbMediaTranscript, decorators: [{
82
+ type: Directive,
83
+ args: [{ selector: '[cbMediaTranscript]' }]
84
+ }] });
85
+ let nextUid = 0;
86
+ /**
87
+ * Reproductor de audio y vídeo de CaribeNG con controles propios y accesibles: reproducir,
88
+ * avanzar y retroceder, barra de progreso y volumen (sliders con su valor hablado), silencio,
89
+ * velocidad, subtítulos (WebVTT), imagen en imagen, pantalla completa, atajos de teclado como
90
+ * los de YouTube y transcripción desplegable. Los controles no se ocultan solos.
91
+ *
92
+ * @example
93
+ * ```html
94
+ * <cb-media-player src="/video/bienvenida.mp4" poster="/video/poster.jpg" [tracks]="subtitulos" heading="Bienvenida" />
95
+ * <cb-media-player kind="audio" src="/audio/podcast.mp3" heading="Episodio 12">
96
+ * <div cbMediaTranscript>…</div>
97
+ * </cb-media-player>
98
+ * ```
99
+ */
100
+ class CbMediaPlayer {
101
+ constructor() {
102
+ this.t = injectCbTranslation();
103
+ this.fmt = cbFormat;
104
+ this.host = inject(ElementRef);
105
+ this.document = inject(DOCUMENT);
106
+ this.hintId = `cb-media-${++nextUid}-hint`;
107
+ /** Archivo a reproducir (o `sources` con varios formatos). */
108
+ this.src = input('', /* @ts-ignore */
109
+ ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
110
+ this.sources = input([], /* @ts-ignore */
111
+ ...(ngDevMode ? [{ debugName: "sources" }] : /* istanbul ignore next */ []));
112
+ this.kind = input('video', /* @ts-ignore */
113
+ ...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
114
+ this.poster = input('', /* @ts-ignore */
115
+ ...(ngDevMode ? [{ debugName: "poster" }] : /* istanbul ignore next */ []));
116
+ /** Título: nombre del reproductor y, en audio, se muestra encima de los controles (no `title`, que daría un tooltip). */
117
+ this.heading = input('', /* @ts-ignore */
118
+ ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
119
+ /** Texto secundario en audio (autor, programa…). */
120
+ this.subtitle = input('', /* @ts-ignore */
121
+ ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
122
+ /** Subtítulos y descripciones (WebVTT). */
123
+ this.tracks = input([], /* @ts-ignore */
124
+ ...(ngDevMode ? [{ debugName: "tracks" }] : /* istanbul ignore next */ []));
125
+ this.rates = input(CB_MEDIA_RATES, /* @ts-ignore */
126
+ ...(ngDevMode ? [{ debugName: "rates" }] : /* istanbul ignore next */ []));
127
+ /** Segundos de los botones de retroceder y avanzar (0 los oculta). */
128
+ this.skipSeconds = input(10, { ...(ngDevMode ? { debugName: "skipSeconds" } : /* istanbul ignore next */ {}), transform: numberAttribute });
129
+ this.loop = input(false, { ...(ngDevMode ? { debugName: "loop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
130
+ /** Empieza silenciado. */
131
+ this.startMuted = input(false, { ...(ngDevMode ? { debugName: "startMuted" } : /* istanbul ignore next */ {}), alias: 'muted', transform: booleanAttribute });
132
+ this.preload = input('metadata', /* @ts-ignore */
133
+ ...(ngDevMode ? [{ debugName: "preload" }] : /* istanbul ignore next */ []));
134
+ /** `anonymous` para subtítulos o medios de otro dominio con CORS. */
135
+ this.crossorigin = input('', /* @ts-ignore */
136
+ ...(ngDevMode ? [{ debugName: "crossorigin" }] : /* istanbul ignore next */ []));
137
+ this.errorMessage = input(undefined, /* @ts-ignore */
138
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
139
+ this.ariaLabel = input('', /* @ts-ignore */
140
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
141
+ this.played = output();
142
+ this.paused = output();
143
+ this.ended = output();
144
+ /** Segundo actual, mientras se reproduce. */
145
+ this.timeUpdate = output();
146
+ this.mediaError = output();
147
+ this.transcript = contentChild(CbMediaTranscript, /* @ts-ignore */
148
+ ...(ngDevMode ? [{ debugName: "transcript" }] : /* istanbul ignore next */ []));
149
+ this.mediaRef = viewChild('media', /* @ts-ignore */
150
+ ...(ngDevMode ? [{ debugName: "mediaRef" }] : /* istanbul ignore next */ []));
151
+ this.playing = signal(false, /* @ts-ignore */
152
+ ...(ngDevMode ? [{ debugName: "playing" }] : /* istanbul ignore next */ []));
153
+ this.started = signal(false, /* @ts-ignore */
154
+ ...(ngDevMode ? [{ debugName: "started" }] : /* istanbul ignore next */ []));
155
+ this.waiting = signal(false, /* @ts-ignore */
156
+ ...(ngDevMode ? [{ debugName: "waiting" }] : /* istanbul ignore next */ []));
157
+ this.current = signal(0, /* @ts-ignore */
158
+ ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
159
+ this.duration = signal(0, /* @ts-ignore */
160
+ ...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
161
+ this.volume = signal(1, /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "volume" }] : /* istanbul ignore next */ []));
163
+ this.muted = signal(false, /* @ts-ignore */
164
+ ...(ngDevMode ? [{ debugName: "muted" }] : /* istanbul ignore next */ []));
165
+ this.rate = signal(1, /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "rate" }] : /* istanbul ignore next */ []));
167
+ this.activeTrack = signal(-1, /* @ts-ignore */
168
+ ...(ngDevMode ? [{ debugName: "activeTrack" }] : /* istanbul ignore next */ []));
169
+ this.fullscreen = signal(false, /* @ts-ignore */
170
+ ...(ngDevMode ? [{ debugName: "fullscreen" }] : /* istanbul ignore next */ []));
171
+ this.pip = signal(false, /* @ts-ignore */
172
+ ...(ngDevMode ? [{ debugName: "pip" }] : /* istanbul ignore next */ []));
173
+ this.error = signal(false, /* @ts-ignore */
174
+ ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
175
+ this.announcement = signal('', /* @ts-ignore */
176
+ ...(ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []));
177
+ this.pipSupported = typeof document !== 'undefined' && 'pictureInPictureEnabled' in document && !!document.pictureInPictureEnabled;
178
+ this.sourceList = computed(() => (this.sources().length ? this.sources() : this.src() ? [{ src: this.src() }] : []), /* @ts-ignore */
179
+ ...(ngDevMode ? [{ debugName: "sourceList" }] : /* istanbul ignore next */ []));
180
+ this.label = computed(() => {
181
+ const kind = this.kind() === 'audio' ? this.t().mediaAudio : this.t().mediaVideo;
182
+ return this.ariaLabel() || (this.heading() ? `${kind}: ${this.heading()}` : kind);
183
+ }, /* @ts-ignore */
184
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
185
+ this.progress = computed(() => (this.duration() ? (this.current() / this.duration()) * 100 : 0), /* @ts-ignore */
186
+ ...(ngDevMode ? [{ debugName: "progress" }] : /* istanbul ignore next */ []));
187
+ this.seekText = computed(() => cbFormat(this.t().mediaTimeOf, this.spoken(this.current()), this.spoken(this.duration())), /* @ts-ignore */
188
+ ...(ngDevMode ? [{ debugName: "seekText" }] : /* istanbul ignore next */ []));
189
+ this.announceFlip = false;
190
+ const registry = inject(CbIconRegistry);
191
+ for (const [name, body] of Object.entries({ pause, 'volume-2': volume2, 'volume-x': volumeX, captions, 'picture-in-picture-2': pictureInPicture2 })) {
192
+ if (!registry.has(name))
193
+ registry.register({ [name]: body });
194
+ }
195
+ // Los eventos del medio se enlazan en la plantilla: así están desde que se crea el elemento
196
+ // (con el medio en caché, loadedmetadata puede llegar antes que un afterNextRender).
197
+ const destroyRef = inject(DestroyRef);
198
+ afterNextRender(() => {
199
+ const media = this.mediaRef()?.nativeElement;
200
+ if (media)
201
+ this.syncFromMedia(media);
202
+ const onFullscreen = () => this.fullscreen.set(this.document.fullscreenElement === this.host.nativeElement);
203
+ this.document.addEventListener('fullscreenchange', onFullscreen);
204
+ destroyRef.onDestroy(() => this.document.removeEventListener('fullscreenchange', onFullscreen));
205
+ });
206
+ }
207
+ // --- API pública ---
208
+ play() {
209
+ const media = this.media();
210
+ if (!media)
211
+ return Promise.resolve();
212
+ return media.play().catch(() => undefined);
213
+ }
214
+ pause() {
215
+ this.media()?.pause();
216
+ }
217
+ toggle() {
218
+ if (this.media()?.paused ?? true)
219
+ void this.play();
220
+ else
221
+ this.pause();
222
+ }
223
+ /** Salta al segundo indicado. */
224
+ seekTo(seconds) {
225
+ const media = this.media();
226
+ if (!media)
227
+ return;
228
+ const max = Number.isFinite(media.duration) ? media.duration : this.duration();
229
+ media.currentTime = Math.min(Math.max(0, seconds), max || 0);
230
+ this.current.set(media.currentTime);
231
+ }
232
+ seekBy(seconds) {
233
+ this.seekTo((this.media()?.currentTime ?? this.current()) + seconds);
234
+ }
235
+ // --- Plantilla ---
236
+ percent(v) {
237
+ return Math.round(v * 100);
238
+ }
239
+ timeText(seconds) {
240
+ return formatTime(seconds, this.duration());
241
+ }
242
+ rateText(r) {
243
+ return `${new Intl.NumberFormat(this.t().intlLocale).format(r)}×`;
244
+ }
245
+ spoken(seconds) {
246
+ const t = this.t();
247
+ return spokenTime(seconds, { hours: t.mediaHours, minutes: t.mediaMinutes, seconds: t.mediaSeconds });
248
+ }
249
+ // --- Eventos ---
250
+ onSeekInput(event) {
251
+ this.seekTo(+event.target.value);
252
+ }
253
+ /** En la barra de progreso, las flechas saltan 5 s y Re Pág / Av Pág 10 s (el paso nativo sería casi nulo). */
254
+ onSeekKeydown(event) {
255
+ const steps = { ArrowLeft: -5, ArrowDown: -5, ArrowRight: 5, ArrowUp: 5, PageDown: -10, PageUp: 10 };
256
+ if (event.key in steps) {
257
+ event.preventDefault();
258
+ event.stopPropagation();
259
+ this.seekBy(steps[event.key]);
260
+ }
261
+ else if (event.key === 'Home' || event.key === 'End') {
262
+ event.preventDefault();
263
+ event.stopPropagation();
264
+ this.seekTo(event.key === 'Home' ? 0 : this.duration());
265
+ }
266
+ }
267
+ onVolumeInput(event) {
268
+ const media = this.media();
269
+ if (!media)
270
+ return;
271
+ media.volume = +event.target.value;
272
+ media.muted = media.volume === 0;
273
+ }
274
+ toggleMute() {
275
+ const media = this.media();
276
+ if (!media)
277
+ return;
278
+ media.muted = !media.muted;
279
+ // Quitar el silencio con el volumen a cero no se oiría: se devuelve a un nivel audible.
280
+ if (!media.muted && media.volume === 0)
281
+ media.volume = 0.5;
282
+ }
283
+ setRate(rate) {
284
+ const media = this.media();
285
+ if (media)
286
+ media.playbackRate = rate;
287
+ this.rate.set(rate);
288
+ this.announce(cbFormat(this.t().mediaSpeedSet, this.rateText(rate)));
289
+ }
290
+ toggleCaptions() {
291
+ if (this.activeTrack() >= 0) {
292
+ this.setTrack(-1);
293
+ }
294
+ else {
295
+ const preferred = this.tracks().findIndex((tr) => tr.default);
296
+ this.setTrack(preferred >= 0 ? preferred : 0);
297
+ }
298
+ }
299
+ setTrack(index) {
300
+ const media = this.media();
301
+ if (media) {
302
+ Array.from(media.textTracks ?? []).forEach((track, i) => (track.mode = i === index ? 'showing' : 'disabled'));
303
+ }
304
+ this.activeTrack.set(index);
305
+ this.announce(index >= 0 ? cbFormat(this.t().mediaCaptionsOn, this.tracks()[index]?.label ?? '') : this.t().mediaCaptionsOff);
306
+ }
307
+ async toggleFullscreen() {
308
+ if (this.kind() !== 'video')
309
+ return;
310
+ try {
311
+ if (this.document.fullscreenElement)
312
+ await this.document.exitFullscreen();
313
+ else
314
+ await this.host.nativeElement.requestFullscreen?.();
315
+ }
316
+ catch {
317
+ // El navegador lo rechazó (p. ej. sin gesto del usuario): no hay nada que hacer.
318
+ }
319
+ }
320
+ async togglePip() {
321
+ const media = this.media();
322
+ if (!media)
323
+ return;
324
+ try {
325
+ if (this.document.pictureInPictureElement)
326
+ await this.document.exitPictureInPicture();
327
+ else
328
+ await media.requestPictureInPicture();
329
+ }
330
+ catch {
331
+ // Sin soporte o rechazado.
332
+ }
333
+ }
334
+ /** Atajos con el foco en el reproductor, salvo las teclas que ya usa el control enfocado. */
335
+ onKeydown(event) {
336
+ const target = event.target;
337
+ if (target.tagName === 'SELECT' || target.closest('summary, .cb-mp__transcript-body'))
338
+ return;
339
+ const shortcut = shortcutFor(event);
340
+ if (!shortcut)
341
+ return;
342
+ const isRange = target instanceof HTMLInputElement && target.type === 'range';
343
+ const isButton = target.tagName === 'BUTTON';
344
+ // Un slider usa sus flechas e Inicio / Fin; un botón, Espacio.
345
+ if (isRange && (shortcut.action === 'seekBy' || shortcut.action === 'volumeBy' || shortcut.action === 'seekTo') && !/^[0-9]$/.test(event.key))
346
+ return;
347
+ if (isButton && event.key === ' ')
348
+ return;
349
+ event.preventDefault();
350
+ this.run(shortcut);
351
+ }
352
+ // --- Eventos del medio ---
353
+ onPlay() {
354
+ this.playing.set(true);
355
+ this.started.set(true);
356
+ this.played.emit();
357
+ }
358
+ onPause() {
359
+ this.playing.set(false);
360
+ this.paused.emit();
361
+ }
362
+ onEnded(event) {
363
+ this.playing.set(false);
364
+ this.sync(event);
365
+ this.ended.emit();
366
+ }
367
+ onTime(event) {
368
+ const media = event.target;
369
+ this.current.set(media.currentTime);
370
+ this.timeUpdate.emit(media.currentTime);
371
+ }
372
+ sync(event) {
373
+ this.syncFromMedia(event.target);
374
+ }
375
+ onError(event) {
376
+ const media = event.target;
377
+ this.error.set(true);
378
+ this.waiting.set(false);
379
+ this.mediaError.emit(media.error);
380
+ }
381
+ // --- Internos ---
382
+ run(shortcut) {
383
+ switch (shortcut.action) {
384
+ case 'toggle':
385
+ return this.toggle();
386
+ case 'mute':
387
+ return this.toggleMute();
388
+ case 'fullscreen':
389
+ void this.toggleFullscreen();
390
+ return;
391
+ case 'captions':
392
+ if (this.tracks().length)
393
+ this.toggleCaptions();
394
+ return;
395
+ case 'seekBy':
396
+ return this.seekBy(shortcut.seconds);
397
+ case 'seekTo':
398
+ return this.seekTo(shortcut.fraction * this.duration());
399
+ case 'volumeBy': {
400
+ const media = this.media();
401
+ if (!media)
402
+ return;
403
+ media.muted = false;
404
+ media.volume = Math.min(1, Math.max(0, Math.round((media.volume + shortcut.delta) * 100) / 100));
405
+ this.announce(cbFormat(this.t().mediaVolumeSet, this.percent(media.volume)));
406
+ }
407
+ }
408
+ }
409
+ media() {
410
+ return this.mediaRef()?.nativeElement;
411
+ }
412
+ syncFromMedia(media) {
413
+ this.duration.set(Number.isFinite(media.duration) ? media.duration : 0);
414
+ this.current.set(media.currentTime);
415
+ this.volume.set(media.volume);
416
+ this.muted.set(media.muted);
417
+ this.rate.set(media.playbackRate || 1);
418
+ const showing = Array.from(media.textTracks ?? []).findIndex((tr) => tr.mode === 'showing');
419
+ if (showing >= 0)
420
+ this.activeTrack.set(showing);
421
+ }
422
+ /** Un espacio duro alterno hace que el mismo texto cuente como cambio y se vuelva a anunciar. */
423
+ announce(text) {
424
+ this.announceFlip = !this.announceFlip;
425
+ this.announcement.set(this.announceFlip ? text : `${text} `);
426
+ }
427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbMediaPlayer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbMediaPlayer, isStandalone: true, selector: "cb-media-player", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, sources: { classPropertyName: "sources", publicName: "sources", isSignal: true, isRequired: false, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: false, transformFunction: null }, poster: { classPropertyName: "poster", publicName: "poster", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, tracks: { classPropertyName: "tracks", publicName: "tracks", isSignal: true, isRequired: false, transformFunction: null }, rates: { classPropertyName: "rates", publicName: "rates", isSignal: true, isRequired: false, transformFunction: null }, skipSeconds: { classPropertyName: "skipSeconds", publicName: "skipSeconds", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, startMuted: { classPropertyName: "startMuted", publicName: "muted", isSignal: true, isRequired: false, transformFunction: null }, preload: { classPropertyName: "preload", publicName: "preload", isSignal: true, isRequired: false, transformFunction: null }, crossorigin: { classPropertyName: "crossorigin", publicName: "crossorigin", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { played: "played", paused: "paused", ended: "ended", timeUpdate: "timeUpdate", mediaError: "mediaError" }, host: { properties: { "class.cb-media-player--audio": "kind() === \"audio\"", "class.cb-media-player--fullscreen": "fullscreen()" }, classAttribute: "cb-media-player" }, queries: [{ propertyName: "transcript", first: true, predicate: CbMediaTranscript, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mediaRef", first: true, predicate: ["media"], descendants: true, isSignal: true }], ngImport: i0, template: `
429
+ <div class="cb-mp" role="group" [attr.aria-label]="label()" [attr.aria-describedby]="hintId" (keydown)="onKeydown($event)">
430
+ @if (kind() === 'video') {
431
+ <div class="cb-mp__screen" (click)="toggle()" (dblclick)="toggleFullscreen()">
432
+ <video
433
+ #media
434
+ class="cb-mp__media"
435
+ [attr.poster]="poster() || null"
436
+ [attr.crossorigin]="crossorigin() || null"
437
+ [preload]="preload()"
438
+ [loop]="loop()"
439
+ [muted]="startMuted()"
440
+ playsinline
441
+ (play)="onPlay()"
442
+ (pause)="onPause()"
443
+ (ended)="onEnded($event)"
444
+ (timeupdate)="onTime($event)"
445
+ (loadedmetadata)="sync($event)"
446
+ (durationchange)="sync($event)"
447
+ (volumechange)="sync($event)"
448
+ (ratechange)="sync($event)"
449
+ (waiting)="waiting.set(true)"
450
+ (playing)="waiting.set(false)"
451
+ (canplay)="waiting.set(false)"
452
+ (error)="onError($event)"
453
+ (enterpictureinpicture)="pip.set(true)"
454
+ (leavepictureinpicture)="pip.set(false)"
455
+ >
456
+ @for (s of sourceList(); track s.src) {
457
+ <source [src]="s.src" [attr.type]="s.type || null" />
458
+ }
459
+ @for (tr of tracks(); track tr.src) {
460
+ <track [src]="tr.src" [attr.kind]="tr.kind || 'subtitles'" [attr.srclang]="tr.srclang" [attr.label]="tr.label" [default]="!!tr.default" />
461
+ }
462
+ </video>
463
+ @if (!playing() && !started()) {
464
+ <span class="cb-mp__big-play" aria-hidden="true"><cb-icon name="play" [size]="34" /></span>
465
+ }
466
+ @if (waiting()) {
467
+ <span class="cb-mp__busy" aria-hidden="true"><cb-icon name="loader-circle" [size]="36" /></span>
468
+ }
469
+ </div>
470
+ } @else {
471
+ <audio
472
+ #media
473
+ [attr.crossorigin]="crossorigin() || null"
474
+ [preload]="preload()"
475
+ [loop]="loop()"
476
+ [muted]="startMuted()"
477
+ (play)="onPlay()"
478
+ (pause)="onPause()"
479
+ (ended)="onEnded($event)"
480
+ (timeupdate)="onTime($event)"
481
+ (loadedmetadata)="sync($event)"
482
+ (durationchange)="sync($event)"
483
+ (volumechange)="sync($event)"
484
+ (ratechange)="sync($event)"
485
+ (waiting)="waiting.set(true)"
486
+ (playing)="waiting.set(false)"
487
+ (canplay)="waiting.set(false)"
488
+ (error)="onError($event)"
489
+ >
490
+ @for (s of sourceList(); track s.src) {
491
+ <source [src]="s.src" [attr.type]="s.type || null" />
492
+ }
493
+ @for (tr of tracks(); track tr.src) {
494
+ <track [src]="tr.src" [attr.kind]="tr.kind || 'subtitles'" [attr.srclang]="tr.srclang" [attr.label]="tr.label" [default]="!!tr.default" />
495
+ }
496
+ </audio>
497
+ @if (heading() || subtitle()) {
498
+ <div class="cb-mp__info">
499
+ @if (heading()) {
500
+ <span class="cb-mp__title">{{ heading() }}</span>
501
+ }
502
+ @if (subtitle()) {
503
+ <span class="cb-mp__subtitle">{{ subtitle() }}</span>
504
+ }
505
+ </div>
506
+ }
507
+ }
508
+
509
+ @if (error()) {
510
+ <p class="cb-mp__error" role="alert">{{ errorMessage() ?? t().mediaError }}</p>
511
+ }
512
+
513
+ <div class="cb-mp__controls" role="group" [attr.aria-label]="t().mediaControls">
514
+ <div class="cb-mp__seek-row">
515
+ <span class="cb-mp__time" aria-hidden="true">{{ timeText(current()) }}</span>
516
+ <input
517
+ type="range"
518
+ class="cb-mp__range cb-mp__seek"
519
+ min="0"
520
+ [max]="duration() || 0"
521
+ step="any"
522
+ [value]="current()"
523
+ [style.--cb-mp-fill]="progress() + '%'"
524
+ [attr.aria-label]="t().mediaSeek"
525
+ [attr.aria-valuetext]="seekText()"
526
+ [disabled]="!duration()"
527
+ (input)="onSeekInput($event)"
528
+ (keydown)="onSeekKeydown($event)"
529
+ />
530
+ <span class="cb-mp__time" aria-hidden="true">{{ timeText(duration()) }}</span>
531
+ </div>
532
+
533
+ <div class="cb-mp__buttons">
534
+ <button type="button" class="cb-mp__btn cb-mp__btn--main" [attr.aria-label]="playing() ? t().mediaPause : t().mediaPlay" [attr.title]="playing() ? t().mediaPause : t().mediaPlay" (click)="toggle()">
535
+ <cb-icon [name]="playing() ? 'pause' : 'play'" [size]="20" aria-hidden="true" />
536
+ </button>
537
+ @if (skipSeconds() > 0) {
538
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="fmt(t().mediaBack, skipSeconds())" [attr.title]="fmt(t().mediaBack, skipSeconds())" (click)="seekBy(-skipSeconds())">
539
+ <cb-icon name="rotate-ccw" [size]="18" aria-hidden="true" />
540
+ </button>
541
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="fmt(t().mediaForward, skipSeconds())" [attr.title]="fmt(t().mediaForward, skipSeconds())" (click)="seekBy(skipSeconds())">
542
+ <cb-icon name="rotate-cw" [size]="18" aria-hidden="true" />
543
+ </button>
544
+ }
545
+
546
+ <span class="cb-mp__volume">
547
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaMute" [attr.title]="t().mediaMute" [attr.aria-pressed]="muted()" (click)="toggleMute()">
548
+ <cb-icon [name]="muted() || volume() === 0 ? 'volume-x' : 'volume-2'" [size]="18" aria-hidden="true" />
549
+ </button>
550
+ <input
551
+ type="range"
552
+ class="cb-mp__range cb-mp__vol"
553
+ min="0"
554
+ max="1"
555
+ step="0.05"
556
+ [value]="muted() ? 0 : volume()"
557
+ [style.--cb-mp-fill]="(muted() ? 0 : volume() * 100) + '%'"
558
+ [attr.aria-label]="t().mediaVolume"
559
+ [attr.aria-valuetext]="(muted() ? 0 : percent(volume())) + ' %'"
560
+ (input)="onVolumeInput($event)"
561
+ />
562
+ </span>
563
+
564
+ <span class="cb-mp__spacer"></span>
565
+
566
+ <select class="cb-mp__select" [attr.aria-label]="t().mediaSpeed" [attr.title]="t().mediaSpeed" [value]="rate()" (change)="setRate(+$any($event.target).value)">
567
+ @for (r of rates(); track r) {
568
+ <option [value]="r" [selected]="r === rate()">{{ rateText(r) }}</option>
569
+ }
570
+ </select>
571
+
572
+ @if (tracks().length) {
573
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaCaptions" [attr.title]="t().mediaCaptions" [attr.aria-pressed]="activeTrack() >= 0" (click)="toggleCaptions()">
574
+ <cb-icon name="captions" [size]="18" aria-hidden="true" />
575
+ </button>
576
+ @if (tracks().length > 1) {
577
+ <select class="cb-mp__select" [attr.aria-label]="t().mediaCaptionsLanguage" (change)="setTrack(+$any($event.target).value)">
578
+ <option value="-1" [selected]="activeTrack() < 0">{{ t().mediaCaptionsNone }}</option>
579
+ @for (tr of tracks(); track tr.src; let i = $index) {
580
+ <option [value]="i" [selected]="activeTrack() === i">{{ tr.label }}</option>
581
+ }
582
+ </select>
583
+ }
584
+ }
585
+
586
+ @if (kind() === 'video') {
587
+ @if (pipSupported) {
588
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaPip" [attr.title]="t().mediaPip" [attr.aria-pressed]="pip()" (click)="togglePip()">
589
+ <cb-icon name="picture-in-picture-2" [size]="18" aria-hidden="true" />
590
+ </button>
591
+ }
592
+ <button
593
+ type="button"
594
+ class="cb-mp__btn"
595
+ [attr.aria-label]="fullscreen() ? t().mediaExitFullscreen : t().mediaFullscreen"
596
+ [attr.title]="fullscreen() ? t().mediaExitFullscreen : t().mediaFullscreen"
597
+ (click)="toggleFullscreen()"
598
+ >
599
+ <cb-icon [name]="fullscreen() ? 'minimize-2' : 'maximize-2'" [size]="18" aria-hidden="true" />
600
+ </button>
601
+ }
602
+ </div>
603
+ </div>
604
+
605
+ @if (transcript()) {
606
+ <details class="cb-mp__transcript">
607
+ <summary>{{ t().mediaTranscript }}</summary>
608
+ <div class="cb-mp__transcript-body"><ng-content select="[cbMediaTranscript]" /></div>
609
+ </details>
610
+ }
611
+
612
+ <span class="cb-mp__sr" [id]="hintId">{{ t().mediaShortcuts }}</span>
613
+ <span class="cb-mp__sr" aria-live="polite">{{ announcement() }}</span>
614
+ </div>
615
+ `, isInline: true, styles: [":host{display:block;color:var(--cb-color-text);font-family:var(--cb-font-sans);font-size:var(--cb-text-sm, .875rem)}.cb-mp{display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--cb-color-border);border-radius:var(--cb-radius-lg, 8px);background:var(--cb-color-surface-raised, var(--cb-color-surface))}:host(.cb-media-player--fullscreen) .cb-mp{height:100%;border:0;border-radius:0;background:#000}.cb-mp__screen{position:relative;display:flex;align-items:center;justify-content:center;background:#000;cursor:pointer}:host(.cb-media-player--fullscreen) .cb-mp__screen{flex:1;min-height:0}.cb-mp__media{display:block;width:100%;max-height:100%}.cb-mp__big-play{position:absolute;display:inline-flex;align-items:center;justify-content:center;width:4.5rem;height:4.5rem;border-radius:50%;background:#0000008c;color:#fff;pointer-events:none}.cb-mp__busy{position:absolute;color:#fff;animation:cb-mp-spin 1s linear infinite;pointer-events:none}@keyframes cb-mp-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.cb-mp__busy{animation-duration:3s}}.cb-mp__info{display:flex;flex-direction:column;gap:.125rem;padding:.875rem 1rem 0}.cb-mp__title{font-size:var(--cb-text-base, 1rem);font-weight:var(--cb-font-weight-semibold, 600)}.cb-mp__subtitle{color:var(--cb-color-text-muted)}.cb-mp__error{margin:0;padding:.5rem 1rem;color:var(--cb-color-danger)}.cb-mp__controls{display:flex;flex-direction:column;gap:.25rem;padding:.5rem .75rem .625rem}:host(.cb-media-player--fullscreen) .cb-mp__controls{background:#111827;color:#fff}.cb-mp__seek-row{display:flex;align-items:center;gap:.625rem}.cb-mp__time{min-width:2.75rem;color:var(--cb-color-text-muted);font-size:var(--cb-text-xs, .75rem);font-variant-numeric:tabular-nums;text-align:center}:host(.cb-media-player--fullscreen) .cb-mp__time{color:#d1d5db}.cb-mp__buttons{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem}.cb-mp__spacer{flex:1}.cb-mp__volume{display:inline-flex;align-items:center;gap:.25rem}.cb-mp__btn{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border:0;border-radius:var(--cb-radius-full, 999px);background:transparent;color:inherit;cursor:pointer}.cb-mp__btn:hover{background:var(--cb-color-surface-hover)}:host(.cb-media-player--fullscreen) .cb-mp__btn:hover{background:#ffffff1f}.cb-mp__btn--main{background:var(--cb-color-primary);color:var(--cb-color-primary-contrast, #fff)}.cb-mp__btn--main:hover{background:var(--cb-color-primary-700, var(--cb-color-primary))}.cb-mp__btn[aria-pressed=true]{color:var(--cb-color-primary)}.cb-mp__select{height:2rem;padding:0 .375rem;border:1px solid var(--cb-color-border);border-radius:var(--cb-radius-md, 6px);background:var(--cb-color-surface-raised, transparent);color:inherit;font:inherit;font-size:var(--cb-text-xs, .75rem)}.cb-mp__range{--cb-mp-fill: 0%;height:1.5rem;margin:0;background:transparent;cursor:pointer;appearance:none}.cb-mp__seek{flex:1;min-width:0}.cb-mp__vol{width:5.5rem}.cb-mp__range::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(to right,var(--cb-color-primary) var(--cb-mp-fill),var(--cb-color-border-strong, #cbd5e1) var(--cb-mp-fill))}.cb-mp__range::-moz-range-track{height:4px;border-radius:2px;background:linear-gradient(to right,var(--cb-color-primary) var(--cb-mp-fill),var(--cb-color-border-strong, #cbd5e1) var(--cb-mp-fill))}.cb-mp__range::-webkit-slider-thumb{width:14px;height:14px;margin-top:-5px;border:0;border-radius:50%;background:var(--cb-color-primary);appearance:none}.cb-mp__range::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:var(--cb-color-primary)}.cb-mp__range:disabled{cursor:default;opacity:.5}.cb-mp__btn:focus-visible,.cb-mp__select:focus-visible,.cb-mp__range:focus-visible,.cb-mp__transcript summary:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-mp__transcript{border-top:1px solid var(--cb-color-border)}.cb-mp__transcript summary{padding:.625rem 1rem;font-weight:var(--cb-font-weight-medium, 500);cursor:pointer}.cb-mp__transcript-body{max-height:16rem;overflow-y:auto;padding:0 1rem .875rem;color:var(--cb-color-text-muted);line-height:1.6}.cb-mp__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
616
+ }
617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbMediaPlayer, decorators: [{
618
+ type: Component,
619
+ args: [{ selector: 'cb-media-player', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, imports: [CbIcon], host: {
620
+ class: 'cb-media-player',
621
+ '[class.cb-media-player--audio]': 'kind() === "audio"',
622
+ '[class.cb-media-player--fullscreen]': 'fullscreen()',
623
+ }, template: `
624
+ <div class="cb-mp" role="group" [attr.aria-label]="label()" [attr.aria-describedby]="hintId" (keydown)="onKeydown($event)">
625
+ @if (kind() === 'video') {
626
+ <div class="cb-mp__screen" (click)="toggle()" (dblclick)="toggleFullscreen()">
627
+ <video
628
+ #media
629
+ class="cb-mp__media"
630
+ [attr.poster]="poster() || null"
631
+ [attr.crossorigin]="crossorigin() || null"
632
+ [preload]="preload()"
633
+ [loop]="loop()"
634
+ [muted]="startMuted()"
635
+ playsinline
636
+ (play)="onPlay()"
637
+ (pause)="onPause()"
638
+ (ended)="onEnded($event)"
639
+ (timeupdate)="onTime($event)"
640
+ (loadedmetadata)="sync($event)"
641
+ (durationchange)="sync($event)"
642
+ (volumechange)="sync($event)"
643
+ (ratechange)="sync($event)"
644
+ (waiting)="waiting.set(true)"
645
+ (playing)="waiting.set(false)"
646
+ (canplay)="waiting.set(false)"
647
+ (error)="onError($event)"
648
+ (enterpictureinpicture)="pip.set(true)"
649
+ (leavepictureinpicture)="pip.set(false)"
650
+ >
651
+ @for (s of sourceList(); track s.src) {
652
+ <source [src]="s.src" [attr.type]="s.type || null" />
653
+ }
654
+ @for (tr of tracks(); track tr.src) {
655
+ <track [src]="tr.src" [attr.kind]="tr.kind || 'subtitles'" [attr.srclang]="tr.srclang" [attr.label]="tr.label" [default]="!!tr.default" />
656
+ }
657
+ </video>
658
+ @if (!playing() && !started()) {
659
+ <span class="cb-mp__big-play" aria-hidden="true"><cb-icon name="play" [size]="34" /></span>
660
+ }
661
+ @if (waiting()) {
662
+ <span class="cb-mp__busy" aria-hidden="true"><cb-icon name="loader-circle" [size]="36" /></span>
663
+ }
664
+ </div>
665
+ } @else {
666
+ <audio
667
+ #media
668
+ [attr.crossorigin]="crossorigin() || null"
669
+ [preload]="preload()"
670
+ [loop]="loop()"
671
+ [muted]="startMuted()"
672
+ (play)="onPlay()"
673
+ (pause)="onPause()"
674
+ (ended)="onEnded($event)"
675
+ (timeupdate)="onTime($event)"
676
+ (loadedmetadata)="sync($event)"
677
+ (durationchange)="sync($event)"
678
+ (volumechange)="sync($event)"
679
+ (ratechange)="sync($event)"
680
+ (waiting)="waiting.set(true)"
681
+ (playing)="waiting.set(false)"
682
+ (canplay)="waiting.set(false)"
683
+ (error)="onError($event)"
684
+ >
685
+ @for (s of sourceList(); track s.src) {
686
+ <source [src]="s.src" [attr.type]="s.type || null" />
687
+ }
688
+ @for (tr of tracks(); track tr.src) {
689
+ <track [src]="tr.src" [attr.kind]="tr.kind || 'subtitles'" [attr.srclang]="tr.srclang" [attr.label]="tr.label" [default]="!!tr.default" />
690
+ }
691
+ </audio>
692
+ @if (heading() || subtitle()) {
693
+ <div class="cb-mp__info">
694
+ @if (heading()) {
695
+ <span class="cb-mp__title">{{ heading() }}</span>
696
+ }
697
+ @if (subtitle()) {
698
+ <span class="cb-mp__subtitle">{{ subtitle() }}</span>
699
+ }
700
+ </div>
701
+ }
702
+ }
703
+
704
+ @if (error()) {
705
+ <p class="cb-mp__error" role="alert">{{ errorMessage() ?? t().mediaError }}</p>
706
+ }
707
+
708
+ <div class="cb-mp__controls" role="group" [attr.aria-label]="t().mediaControls">
709
+ <div class="cb-mp__seek-row">
710
+ <span class="cb-mp__time" aria-hidden="true">{{ timeText(current()) }}</span>
711
+ <input
712
+ type="range"
713
+ class="cb-mp__range cb-mp__seek"
714
+ min="0"
715
+ [max]="duration() || 0"
716
+ step="any"
717
+ [value]="current()"
718
+ [style.--cb-mp-fill]="progress() + '%'"
719
+ [attr.aria-label]="t().mediaSeek"
720
+ [attr.aria-valuetext]="seekText()"
721
+ [disabled]="!duration()"
722
+ (input)="onSeekInput($event)"
723
+ (keydown)="onSeekKeydown($event)"
724
+ />
725
+ <span class="cb-mp__time" aria-hidden="true">{{ timeText(duration()) }}</span>
726
+ </div>
727
+
728
+ <div class="cb-mp__buttons">
729
+ <button type="button" class="cb-mp__btn cb-mp__btn--main" [attr.aria-label]="playing() ? t().mediaPause : t().mediaPlay" [attr.title]="playing() ? t().mediaPause : t().mediaPlay" (click)="toggle()">
730
+ <cb-icon [name]="playing() ? 'pause' : 'play'" [size]="20" aria-hidden="true" />
731
+ </button>
732
+ @if (skipSeconds() > 0) {
733
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="fmt(t().mediaBack, skipSeconds())" [attr.title]="fmt(t().mediaBack, skipSeconds())" (click)="seekBy(-skipSeconds())">
734
+ <cb-icon name="rotate-ccw" [size]="18" aria-hidden="true" />
735
+ </button>
736
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="fmt(t().mediaForward, skipSeconds())" [attr.title]="fmt(t().mediaForward, skipSeconds())" (click)="seekBy(skipSeconds())">
737
+ <cb-icon name="rotate-cw" [size]="18" aria-hidden="true" />
738
+ </button>
739
+ }
740
+
741
+ <span class="cb-mp__volume">
742
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaMute" [attr.title]="t().mediaMute" [attr.aria-pressed]="muted()" (click)="toggleMute()">
743
+ <cb-icon [name]="muted() || volume() === 0 ? 'volume-x' : 'volume-2'" [size]="18" aria-hidden="true" />
744
+ </button>
745
+ <input
746
+ type="range"
747
+ class="cb-mp__range cb-mp__vol"
748
+ min="0"
749
+ max="1"
750
+ step="0.05"
751
+ [value]="muted() ? 0 : volume()"
752
+ [style.--cb-mp-fill]="(muted() ? 0 : volume() * 100) + '%'"
753
+ [attr.aria-label]="t().mediaVolume"
754
+ [attr.aria-valuetext]="(muted() ? 0 : percent(volume())) + ' %'"
755
+ (input)="onVolumeInput($event)"
756
+ />
757
+ </span>
758
+
759
+ <span class="cb-mp__spacer"></span>
760
+
761
+ <select class="cb-mp__select" [attr.aria-label]="t().mediaSpeed" [attr.title]="t().mediaSpeed" [value]="rate()" (change)="setRate(+$any($event.target).value)">
762
+ @for (r of rates(); track r) {
763
+ <option [value]="r" [selected]="r === rate()">{{ rateText(r) }}</option>
764
+ }
765
+ </select>
766
+
767
+ @if (tracks().length) {
768
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaCaptions" [attr.title]="t().mediaCaptions" [attr.aria-pressed]="activeTrack() >= 0" (click)="toggleCaptions()">
769
+ <cb-icon name="captions" [size]="18" aria-hidden="true" />
770
+ </button>
771
+ @if (tracks().length > 1) {
772
+ <select class="cb-mp__select" [attr.aria-label]="t().mediaCaptionsLanguage" (change)="setTrack(+$any($event.target).value)">
773
+ <option value="-1" [selected]="activeTrack() < 0">{{ t().mediaCaptionsNone }}</option>
774
+ @for (tr of tracks(); track tr.src; let i = $index) {
775
+ <option [value]="i" [selected]="activeTrack() === i">{{ tr.label }}</option>
776
+ }
777
+ </select>
778
+ }
779
+ }
780
+
781
+ @if (kind() === 'video') {
782
+ @if (pipSupported) {
783
+ <button type="button" class="cb-mp__btn" [attr.aria-label]="t().mediaPip" [attr.title]="t().mediaPip" [attr.aria-pressed]="pip()" (click)="togglePip()">
784
+ <cb-icon name="picture-in-picture-2" [size]="18" aria-hidden="true" />
785
+ </button>
786
+ }
787
+ <button
788
+ type="button"
789
+ class="cb-mp__btn"
790
+ [attr.aria-label]="fullscreen() ? t().mediaExitFullscreen : t().mediaFullscreen"
791
+ [attr.title]="fullscreen() ? t().mediaExitFullscreen : t().mediaFullscreen"
792
+ (click)="toggleFullscreen()"
793
+ >
794
+ <cb-icon [name]="fullscreen() ? 'minimize-2' : 'maximize-2'" [size]="18" aria-hidden="true" />
795
+ </button>
796
+ }
797
+ </div>
798
+ </div>
799
+
800
+ @if (transcript()) {
801
+ <details class="cb-mp__transcript">
802
+ <summary>{{ t().mediaTranscript }}</summary>
803
+ <div class="cb-mp__transcript-body"><ng-content select="[cbMediaTranscript]" /></div>
804
+ </details>
805
+ }
806
+
807
+ <span class="cb-mp__sr" [id]="hintId">{{ t().mediaShortcuts }}</span>
808
+ <span class="cb-mp__sr" aria-live="polite">{{ announcement() }}</span>
809
+ </div>
810
+ `, styles: [":host{display:block;color:var(--cb-color-text);font-family:var(--cb-font-sans);font-size:var(--cb-text-sm, .875rem)}.cb-mp{display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--cb-color-border);border-radius:var(--cb-radius-lg, 8px);background:var(--cb-color-surface-raised, var(--cb-color-surface))}:host(.cb-media-player--fullscreen) .cb-mp{height:100%;border:0;border-radius:0;background:#000}.cb-mp__screen{position:relative;display:flex;align-items:center;justify-content:center;background:#000;cursor:pointer}:host(.cb-media-player--fullscreen) .cb-mp__screen{flex:1;min-height:0}.cb-mp__media{display:block;width:100%;max-height:100%}.cb-mp__big-play{position:absolute;display:inline-flex;align-items:center;justify-content:center;width:4.5rem;height:4.5rem;border-radius:50%;background:#0000008c;color:#fff;pointer-events:none}.cb-mp__busy{position:absolute;color:#fff;animation:cb-mp-spin 1s linear infinite;pointer-events:none}@keyframes cb-mp-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.cb-mp__busy{animation-duration:3s}}.cb-mp__info{display:flex;flex-direction:column;gap:.125rem;padding:.875rem 1rem 0}.cb-mp__title{font-size:var(--cb-text-base, 1rem);font-weight:var(--cb-font-weight-semibold, 600)}.cb-mp__subtitle{color:var(--cb-color-text-muted)}.cb-mp__error{margin:0;padding:.5rem 1rem;color:var(--cb-color-danger)}.cb-mp__controls{display:flex;flex-direction:column;gap:.25rem;padding:.5rem .75rem .625rem}:host(.cb-media-player--fullscreen) .cb-mp__controls{background:#111827;color:#fff}.cb-mp__seek-row{display:flex;align-items:center;gap:.625rem}.cb-mp__time{min-width:2.75rem;color:var(--cb-color-text-muted);font-size:var(--cb-text-xs, .75rem);font-variant-numeric:tabular-nums;text-align:center}:host(.cb-media-player--fullscreen) .cb-mp__time{color:#d1d5db}.cb-mp__buttons{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem}.cb-mp__spacer{flex:1}.cb-mp__volume{display:inline-flex;align-items:center;gap:.25rem}.cb-mp__btn{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border:0;border-radius:var(--cb-radius-full, 999px);background:transparent;color:inherit;cursor:pointer}.cb-mp__btn:hover{background:var(--cb-color-surface-hover)}:host(.cb-media-player--fullscreen) .cb-mp__btn:hover{background:#ffffff1f}.cb-mp__btn--main{background:var(--cb-color-primary);color:var(--cb-color-primary-contrast, #fff)}.cb-mp__btn--main:hover{background:var(--cb-color-primary-700, var(--cb-color-primary))}.cb-mp__btn[aria-pressed=true]{color:var(--cb-color-primary)}.cb-mp__select{height:2rem;padding:0 .375rem;border:1px solid var(--cb-color-border);border-radius:var(--cb-radius-md, 6px);background:var(--cb-color-surface-raised, transparent);color:inherit;font:inherit;font-size:var(--cb-text-xs, .75rem)}.cb-mp__range{--cb-mp-fill: 0%;height:1.5rem;margin:0;background:transparent;cursor:pointer;appearance:none}.cb-mp__seek{flex:1;min-width:0}.cb-mp__vol{width:5.5rem}.cb-mp__range::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(to right,var(--cb-color-primary) var(--cb-mp-fill),var(--cb-color-border-strong, #cbd5e1) var(--cb-mp-fill))}.cb-mp__range::-moz-range-track{height:4px;border-radius:2px;background:linear-gradient(to right,var(--cb-color-primary) var(--cb-mp-fill),var(--cb-color-border-strong, #cbd5e1) var(--cb-mp-fill))}.cb-mp__range::-webkit-slider-thumb{width:14px;height:14px;margin-top:-5px;border:0;border-radius:50%;background:var(--cb-color-primary);appearance:none}.cb-mp__range::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:var(--cb-color-primary)}.cb-mp__range:disabled{cursor:default;opacity:.5}.cb-mp__btn:focus-visible,.cb-mp__select:focus-visible,.cb-mp__range:focus-visible,.cb-mp__transcript summary:focus-visible{outline:2px solid var(--cb-color-focus-ring);outline-offset:2px}.cb-mp__transcript{border-top:1px solid var(--cb-color-border)}.cb-mp__transcript summary{padding:.625rem 1rem;font-weight:var(--cb-font-weight-medium, 500);cursor:pointer}.cb-mp__transcript-body{max-height:16rem;overflow-y:auto;padding:0 1rem .875rem;color:var(--cb-color-text-muted);line-height:1.6}.cb-mp__sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n"] }]
811
+ }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], sources: [{ type: i0.Input, args: [{ isSignal: true, alias: "sources", required: false }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: false }] }], poster: [{ type: i0.Input, args: [{ isSignal: true, alias: "poster", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], tracks: [{ type: i0.Input, args: [{ isSignal: true, alias: "tracks", required: false }] }], rates: [{ type: i0.Input, args: [{ isSignal: true, alias: "rates", required: false }] }], skipSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "skipSeconds", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], startMuted: [{ type: i0.Input, args: [{ isSignal: true, alias: "muted", required: false }] }], preload: [{ type: i0.Input, args: [{ isSignal: true, alias: "preload", required: false }] }], crossorigin: [{ type: i0.Input, args: [{ isSignal: true, alias: "crossorigin", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], played: [{ type: i0.Output, args: ["played"] }], paused: [{ type: i0.Output, args: ["paused"] }], ended: [{ type: i0.Output, args: ["ended"] }], timeUpdate: [{ type: i0.Output, args: ["timeUpdate"] }], mediaError: [{ type: i0.Output, args: ["mediaError"] }], transcript: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CbMediaTranscript), { isSignal: true }] }], mediaRef: [{ type: i0.ViewChild, args: ['media', { isSignal: true }] }] } });
812
+
813
+ /*
814
+ * Public API Surface de @caribeng/ui/media-player
815
+ */
816
+
817
+ /**
818
+ * Generated bundle index. Do not edit.
819
+ */
820
+
821
+ export { CB_MEDIA_RATES, CbMediaPlayer, CbMediaTranscript, formatTime as cbFormatMediaTime };