valtech-components 2.0.779 → 2.0.781

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.
@@ -52,7 +52,7 @@ import 'prismjs/components/prism-json';
52
52
  * Current version of valtech-components.
53
53
  * This is automatically updated during the publish process.
54
54
  */
55
- const VERSION = '2.0.779';
55
+ const VERSION = '2.0.781';
56
56
 
57
57
  /**
58
58
  * Servicio para gestionar presets de componentes.
@@ -6268,6 +6268,209 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6268
6268
  type: Input
6269
6269
  }] } });
6270
6270
 
6271
+ addIcons({ personOutline });
6272
+ /**
6273
+ * `val-user-avatar`
6274
+ *
6275
+ * Avatar **smart** con cadena de fallback automática:
6276
+ *
6277
+ * foto (`avatarUrl`) → iniciales (de `name`/`email`) → icono persona.
6278
+ *
6279
+ * Si la imagen falla en cargar (404, CORS, etc.), automáticamente cae a las
6280
+ * iniciales sin que el caller tenga que hacer nada. Color de fondo derivado
6281
+ * deterministicamente del user para que el mismo user tenga siempre el mismo
6282
+ * color (a menos que `background` se sobrescriba).
6283
+ *
6284
+ * @example
6285
+ * ```html
6286
+ * <val-user-avatar [props]="{ user: auth.user() }" (onClick)="goProfile()" />
6287
+ * ```
6288
+ */
6289
+ class UserAvatarComponent {
6290
+ constructor() {
6291
+ this.props_ = signal({});
6292
+ this.imageFailed = signal(false);
6293
+ /** Indica si el `<img>` actual disparó su evento `load`. Conduce el fade-in. */
6294
+ this.imageLoaded = signal(false);
6295
+ this.onClick = new EventEmitter();
6296
+ this.resolvedProps = computed(() => this.props_());
6297
+ /** Resuelve los campos del user (user prop > campos sueltos). */
6298
+ this.resolvedUser = computed(() => {
6299
+ const p = this.resolvedProps();
6300
+ return {
6301
+ name: p.user?.name?.trim() || p.name?.trim() || '',
6302
+ email: p.user?.email?.trim() || p.email?.trim() || '',
6303
+ avatarUrl: p.user?.avatarUrl?.trim() || p.avatarUrl?.trim() || '',
6304
+ };
6305
+ });
6306
+ /**
6307
+ * URL de imagen. Empty si la última carga falló — eso evita re-intentar
6308
+ * con la misma URL cuando el browser ya marcó error. El placeholder
6309
+ * (iniciales/icono) sigue visible debajo.
6310
+ */
6311
+ this.imageUrl = computed(() => {
6312
+ if (this.imageFailed())
6313
+ return '';
6314
+ return this.resolvedUser().avatarUrl;
6315
+ });
6316
+ /** Iniciales — 1-2 chars derivados de name (preferred) o email prefix. */
6317
+ this.initials = computed(() => {
6318
+ const { name, email } = this.resolvedUser();
6319
+ if (name) {
6320
+ const parts = name.split(/\s+/).filter(Boolean);
6321
+ if (parts.length >= 2)
6322
+ return parts[0][0] + parts[1][0];
6323
+ if (parts.length === 1 && parts[0].length >= 2) {
6324
+ return parts[0].slice(0, 2);
6325
+ }
6326
+ return parts[0]?.[0] ?? '';
6327
+ }
6328
+ if (email) {
6329
+ const prefix = email.split('@')[0] ?? '';
6330
+ // Tomar 1-2 chars del prefix
6331
+ if (prefix.length >= 2)
6332
+ return prefix.slice(0, 2);
6333
+ return prefix[0] ?? '';
6334
+ }
6335
+ return '';
6336
+ });
6337
+ this.sizeClass = computed(() => this.resolvedProps().size || 'small');
6338
+ this.shapeClass = computed(() => this.resolvedProps().shape || 'circle');
6339
+ /** Background — explicito o derivado deterministicamente del user. */
6340
+ this.bgColor = computed(() => {
6341
+ const p = this.resolvedProps();
6342
+ if (p.background)
6343
+ return p.background;
6344
+ const { name, email } = this.resolvedUser();
6345
+ const seed = name || email || 'val';
6346
+ return this.colorFromSeed(seed);
6347
+ });
6348
+ this.ariaLabel = computed(() => {
6349
+ const { name, email } = this.resolvedUser();
6350
+ return name || email || 'User avatar';
6351
+ });
6352
+ }
6353
+ set props(value) {
6354
+ const prev = this.props_();
6355
+ const next = value ?? {};
6356
+ this.props_.set(next);
6357
+ // Reset estado de carga si cambia la URL — re-disparar fade-in.
6358
+ const prevUrl = prev?.user?.avatarUrl || prev?.avatarUrl || '';
6359
+ const nextUrl = next.user?.avatarUrl || next.avatarUrl || '';
6360
+ if (prevUrl !== nextUrl) {
6361
+ this.imageFailed.set(false);
6362
+ this.imageLoaded.set(false);
6363
+ }
6364
+ }
6365
+ /** Subscribers — usado para condicionar cursor/aria. */
6366
+ get hasClick() {
6367
+ return this.onClick.observed;
6368
+ }
6369
+ onImageError() {
6370
+ this.imageFailed.set(true);
6371
+ this.imageLoaded.set(false);
6372
+ }
6373
+ onImageLoad() {
6374
+ this.imageFailed.set(false);
6375
+ this.imageLoaded.set(true);
6376
+ }
6377
+ /**
6378
+ * Hash determinista string → HSL color del rango Valtech (purples/blues).
6379
+ * Mismo seed → mismo color (consistencia entre sessions).
6380
+ */
6381
+ colorFromSeed(seed) {
6382
+ let hash = 0;
6383
+ for (let i = 0; i < seed.length; i++) {
6384
+ hash = (hash * 31 + seed.charCodeAt(i)) >>> 0;
6385
+ }
6386
+ // Restringir a rango violet/blue (240-290°) para coherencia con palette
6387
+ const hue = 240 + (hash % 50);
6388
+ const sat = 55 + ((hash >>> 8) % 20); // 55-75%
6389
+ const light = 38 + ((hash >>> 16) % 12); // 38-50% — siempre legible con fg blanco
6390
+ return `hsl(${hue}, ${sat}%, ${light}%)`;
6391
+ }
6392
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6393
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UserAvatarComponent, isStandalone: true, selector: "val-user-avatar", inputs: { props: "props" }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
6394
+ <button
6395
+ type="button"
6396
+ class="val-user-avatar"
6397
+ [class.bordered]="resolvedProps().bordered"
6398
+ [class.grayscale]="resolvedProps().grayscale"
6399
+ [class.has-click]="hasClick"
6400
+ [class]="shapeClass() + ' ' + sizeClass() + ' ' + (resolvedProps().cssClass || '')"
6401
+ [style.background]="bgColor()"
6402
+ [style.color]="resolvedProps().foreground || '#fff'"
6403
+ [attr.aria-label]="ariaLabel()"
6404
+ (click)="onClick.emit()"
6405
+ >
6406
+ <!-- Placeholder layer (siempre presente) — iniciales o icono. La imagen
6407
+ se monta encima y hace fade-in al cargar; si falla queda invisible
6408
+ y el placeholder permanece visible sin parpadeo. -->
6409
+ @if (initials()) {
6410
+ <span class="val-user-avatar__initials">{{ initials() }}</span>
6411
+ } @else {
6412
+ <ion-icon name="person-outline" class="val-user-avatar__icon" aria-hidden="true" />
6413
+ }
6414
+
6415
+ @if (imageUrl()) {
6416
+ <img
6417
+ class="val-user-avatar__img"
6418
+ [class.loaded]="imageLoaded()"
6419
+ [src]="imageUrl()"
6420
+ alt=""
6421
+ loading="lazy"
6422
+ decoding="async"
6423
+ (error)="onImageError()"
6424
+ (load)="onImageLoad()"
6425
+ />
6426
+ }
6427
+ </button>
6428
+ `, isInline: true, styles: [":host{display:inline-flex}.val-user-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;padding:0;margin:0;border:none;background:var(--ion-color-medium, #92949c);color:#fff;font-weight:600;font-family:inherit;line-height:1;-webkit-user-select:none;user-select:none;cursor:default;transition:transform .15s ease,box-shadow .15s ease}.val-user-avatar.has-click{cursor:pointer}.val-user-avatar.has-click:hover{transform:scale(1.04)}.val-user-avatar.has-click:active{transform:scale(.96)}.val-user-avatar.circle{border-radius:50%}.val-user-avatar.square{border-radius:8px}.val-user-avatar.xsmall{width:24px;height:24px;font-size:.625rem}.val-user-avatar.small{width:32px;height:32px;font-size:.75rem}.val-user-avatar.medium{width:48px;height:48px;font-size:1rem}.val-user-avatar.large{width:72px;height:72px;font-size:1.5rem}.val-user-avatar.xlarge{width:96px;height:96px;font-size:2rem}.val-user-avatar.bordered{box-shadow:0 0 0 2px var(--ion-background-color, #fff)}.val-user-avatar.grayscale{filter:grayscale(100%)}.val-user-avatar__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;opacity:0;transition:opacity .35s ease-in-out;pointer-events:none}.val-user-avatar__img.loaded{opacity:1}.val-user-avatar__initials{text-transform:uppercase;letter-spacing:.02em;position:relative;z-index:0}.val-user-avatar__icon{font-size:60%;position:relative;z-index:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
6429
+ }
6430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserAvatarComponent, decorators: [{
6431
+ type: Component,
6432
+ args: [{ selector: 'val-user-avatar', standalone: true, imports: [CommonModule, IonIcon], template: `
6433
+ <button
6434
+ type="button"
6435
+ class="val-user-avatar"
6436
+ [class.bordered]="resolvedProps().bordered"
6437
+ [class.grayscale]="resolvedProps().grayscale"
6438
+ [class.has-click]="hasClick"
6439
+ [class]="shapeClass() + ' ' + sizeClass() + ' ' + (resolvedProps().cssClass || '')"
6440
+ [style.background]="bgColor()"
6441
+ [style.color]="resolvedProps().foreground || '#fff'"
6442
+ [attr.aria-label]="ariaLabel()"
6443
+ (click)="onClick.emit()"
6444
+ >
6445
+ <!-- Placeholder layer (siempre presente) — iniciales o icono. La imagen
6446
+ se monta encima y hace fade-in al cargar; si falla queda invisible
6447
+ y el placeholder permanece visible sin parpadeo. -->
6448
+ @if (initials()) {
6449
+ <span class="val-user-avatar__initials">{{ initials() }}</span>
6450
+ } @else {
6451
+ <ion-icon name="person-outline" class="val-user-avatar__icon" aria-hidden="true" />
6452
+ }
6453
+
6454
+ @if (imageUrl()) {
6455
+ <img
6456
+ class="val-user-avatar__img"
6457
+ [class.loaded]="imageLoaded()"
6458
+ [src]="imageUrl()"
6459
+ alt=""
6460
+ loading="lazy"
6461
+ decoding="async"
6462
+ (error)="onImageError()"
6463
+ (load)="onImageLoad()"
6464
+ />
6465
+ }
6466
+ </button>
6467
+ `, styles: [":host{display:inline-flex}.val-user-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;padding:0;margin:0;border:none;background:var(--ion-color-medium, #92949c);color:#fff;font-weight:600;font-family:inherit;line-height:1;-webkit-user-select:none;user-select:none;cursor:default;transition:transform .15s ease,box-shadow .15s ease}.val-user-avatar.has-click{cursor:pointer}.val-user-avatar.has-click:hover{transform:scale(1.04)}.val-user-avatar.has-click:active{transform:scale(.96)}.val-user-avatar.circle{border-radius:50%}.val-user-avatar.square{border-radius:8px}.val-user-avatar.xsmall{width:24px;height:24px;font-size:.625rem}.val-user-avatar.small{width:32px;height:32px;font-size:.75rem}.val-user-avatar.medium{width:48px;height:48px;font-size:1rem}.val-user-avatar.large{width:72px;height:72px;font-size:1.5rem}.val-user-avatar.xlarge{width:96px;height:96px;font-size:2rem}.val-user-avatar.bordered{box-shadow:0 0 0 2px var(--ion-background-color, #fff)}.val-user-avatar.grayscale{filter:grayscale(100%)}.val-user-avatar__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;opacity:0;transition:opacity .35s ease-in-out;pointer-events:none}.val-user-avatar__img.loaded{opacity:1}.val-user-avatar__initials{text-transform:uppercase;letter-spacing:.02em;position:relative;z-index:0}.val-user-avatar__icon{font-size:60%;position:relative;z-index:0}\n"] }]
6468
+ }], propDecorators: { props: [{
6469
+ type: Input
6470
+ }], onClick: [{
6471
+ type: Output
6472
+ }] } });
6473
+
6271
6474
  /**
6272
6475
  * val-alert-box
6273
6476
  *
@@ -8489,95 +8692,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8489
8692
  }] } });
8490
8693
 
8491
8694
  /**
8492
- * val-notes-box
8695
+ * `val-notes-box` — callout / admonition para resaltar información dentro de un
8696
+ * flujo de texto.
8493
8697
  *
8494
- * Displays a styled notes/info box with optional prefix and configurable color, size, and padding.
8698
+ * Diseño tipo GitHub/Docusaurus: fondo tintado suave, accent en el borde
8699
+ * izquierdo, prefijo en mayúsculas pequeñas. Funciona en light & dark.
8495
8700
  *
8496
- * @example
8497
- * <val-notes-box [props]="{ text: 'Note', prefix: 'Info', color: 'primary', textColor: 'dark', size: 'medium', rounded: true, padding: '8px' }"></val-notes-box>
8701
+ * El color es un Ionic Color (primary, success, warning, danger, tertiary, …).
8702
+ * No usa `ion-card` ni `ion-color="X"` como background sino una mezcla
8703
+ * `rgba(--ion-color-X-rgb, 0.08)` para no asfixiar el contenido.
8704
+ *
8705
+ * Renderiza inline HTML (`<strong>`, links via `processLinks`) cuando los
8706
+ * flags están activos.
8498
8707
  *
8499
- * @input props: NotesBoxMetadata - Configuration for the notes box (text, prefix, color, textColor, size, rounded, padding)
8708
+ * @example
8709
+ * <val-notes-box [props]="{
8710
+ * text: 'Recordá guardar tus cambios antes de salir.',
8711
+ * prefix: 'Tip',
8712
+ * color: 'tertiary',
8713
+ * textColor: 'dark',
8714
+ * size: 'medium',
8715
+ * rounded: true,
8716
+ * allowPartialBold: true,
8717
+ * }"></val-notes-box>
8500
8718
  */
8501
8719
  class NotesBoxComponent {
8502
- constructor() { }
8503
- ngOnInit() { }
8504
8720
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NotesBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8505
8721
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: NotesBoxComponent, isStandalone: true, selector: "val-notes-box", inputs: { props: "props" }, ngImport: i0, template: `
8506
8722
  <div
8507
- [class.notes-box-compact]="props.compact"
8508
- [class.notes-box-align-center]="props.align === 'center'"
8509
- [class.notes-box-align-right]="props.align === 'right'"
8723
+ class="val-notes-box"
8724
+ [class.is-compact]="props.compact"
8725
+ [class.is-rounded]="props.rounded"
8726
+ [class.align-center]="props.align === 'center'"
8727
+ [class.align-right]="props.align === 'right'"
8728
+ [attr.data-color]="props.color || 'primary'"
8729
+ role="note"
8510
8730
  >
8511
- <val-box
8512
- [props]="{
8513
- icon: '',
8514
- bordered: false,
8515
- color: props.color,
8516
- leftBorder: !props.compact,
8517
- rounded: props.rounded,
8518
- padding: props.padding || (props.compact ? '6px 12px' : undefined),
8519
- }"
8520
- >
8521
- <div [ngClass]="['content-container', props.size]" body>
8522
- @if (props.prefix) {
8523
- <val-text
8524
- [props]="{ content: props.prefix, color: props.textColor, bold: true, size: props.size }"
8525
- ></val-text>
8526
- }
8527
- <val-text
8528
- [props]="{
8529
- content: props.text,
8530
- color: props.textColor,
8531
- bold: false,
8532
- size: props.size,
8533
- allowPartialBold: props.allowPartialBold,
8534
- processLinks: props.processLinks,
8535
- }"
8536
- ></val-text>
8537
- </div>
8538
- </val-box>
8731
+ @if (props.prefix) {
8732
+ <div class="val-notes-box__header">{{ props.prefix }}</div>
8733
+ }
8734
+ <div class="val-notes-box__body" [class]="'size-' + (props.size || 'medium')">
8735
+ <val-text
8736
+ [props]="{
8737
+ content: props.text,
8738
+ color: props.textColor,
8739
+ bold: false,
8740
+ size: props.size,
8741
+ allowPartialBold: props.allowPartialBold,
8742
+ processLinks: props.processLinks,
8743
+ }"
8744
+ ></val-text>
8745
+ </div>
8539
8746
  </div>
8540
- `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.content-container{display:inline-grid}.notes-box-compact{display:inline-block;width:fit-content;max-width:100%}.notes-box-compact ::ng-deep val-box ion-card{margin:0;box-shadow:none}.notes-box-align-center{text-align:center}.notes-box-align-center:not(.notes-box-compact){display:flex;justify-content:center}.notes-box-align-right{text-align:right}.notes-box-align-right:not(.notes-box-compact){display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BoxComponent, selector: "val-box", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
8747
+ `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}:host{display:block}.val-notes-box{--notes-rgb: var(--ion-color-primary-rgb, 112, 38, 223);--notes-bg: rgba(var(--notes-rgb), .07);--notes-border: rgba(var(--notes-rgb), .18);--notes-accent: rgb(var(--notes-rgb));--notes-text: var(--ion-color-dark, #0a0612);--notes-link: rgb(var(--notes-rgb));position:relative;display:block;padding:14px 18px 14px 20px;background:var(--notes-bg);border:1px solid var(--notes-border);border-left:4px solid var(--notes-accent);border-radius:10px;color:var(--notes-text);margin:0;line-height:1.55}.val-notes-box.is-rounded{border-radius:12px}.val-notes-box[data-color=primary]{--notes-rgb: var(--ion-color-primary-rgb)}.val-notes-box[data-color=secondary]{--notes-rgb: var(--ion-color-secondary-rgb)}.val-notes-box[data-color=tertiary]{--notes-rgb: var(--ion-color-tertiary-rgb)}.val-notes-box[data-color=success]{--notes-rgb: var(--ion-color-success-rgb)}.val-notes-box[data-color=warning]{--notes-rgb: var(--ion-color-warning-rgb)}.val-notes-box[data-color=danger]{--notes-rgb: var(--ion-color-danger-rgb)}.val-notes-box[data-color=medium]{--notes-rgb: var(--ion-color-medium-rgb)}.val-notes-box[data-color=dark]{--notes-rgb: var(--ion-color-dark-rgb)}.val-notes-box[data-color=light]{--notes-rgb: var(--ion-color-medium-rgb)}.val-notes-box__header{display:block;margin:0 0 6px;font-weight:700;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--notes-accent);font-family:var(--ion-font-family, inherit)}.val-notes-box__body{display:block;color:var(--notes-text);font-size:14px;line-height:1.6}.val-notes-box__body.size-small{font-size:13px;line-height:1.55}.val-notes-box__body.size-large{font-size:15px;line-height:1.6}.val-notes-box__body.size-xlarge{font-size:16px;line-height:1.55}.val-notes-box__body ::ng-deep val-text{display:block;color:var(--notes-text)}.val-notes-box__body ::ng-deep val-text p{margin:0;color:inherit}.val-notes-box__body ::ng-deep val-text ion-text{color:var(--notes-text)!important}.val-notes-box__body ::ng-deep val-text strong,.val-notes-box__body ::ng-deep val-text b,.val-notes-box__body ::ng-deep .partial-bold{color:var(--notes-text);font-weight:700}.val-notes-box__body ::ng-deep val-text a{color:var(--notes-link);text-decoration:underline;text-underline-offset:2px;font-weight:600}.val-notes-box__body ::ng-deep val-text a:hover{opacity:.85}.val-notes-box.align-center,.val-notes-box.align-center .val-notes-box__header{text-align:center}.val-notes-box.align-right,.val-notes-box.align-right .val-notes-box__header{text-align:right}.val-notes-box.is-compact{display:inline-block;width:fit-content;max-width:100%;padding:5px 12px;border-left-width:1px;border-radius:999px;font-size:12px;line-height:1.3}.val-notes-box.is-compact .val-notes-box__header{display:inline;margin:0 6px 0 0;font-size:11px;letter-spacing:.06em}.val-notes-box.is-compact .val-notes-box__body{display:inline;font-size:12px}.val-notes-box.is-compact ::ng-deep val-text{display:inline}.val-notes-box.is-compact ::ng-deep val-text p{display:inline}@media (prefers-color-scheme: dark){:host-context(body:not(.light)) .val-notes-box{--notes-bg: rgba(var(--notes-rgb), .16);--notes-border: rgba(var(--notes-rgb), .3);--notes-text: var(--ion-color-light, #f4f5f8)}}:host-context(body.dark) .val-notes-box,:host-context(.theme-dark) .val-notes-box,:host-context([data-theme=dark]) .val-notes-box{--notes-bg: rgba(var(--notes-rgb), .16);--notes-border: rgba(var(--notes-rgb), .3);--notes-text: var(--ion-color-light, #f4f5f8)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8541
8748
  }
8542
8749
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NotesBoxComponent, decorators: [{
8543
8750
  type: Component,
8544
- args: [{ selector: 'val-notes-box', standalone: true, imports: [CommonModule, BoxComponent, TextComponent], template: `
8751
+ args: [{ selector: 'val-notes-box', standalone: true, imports: [CommonModule, TextComponent], template: `
8545
8752
  <div
8546
- [class.notes-box-compact]="props.compact"
8547
- [class.notes-box-align-center]="props.align === 'center'"
8548
- [class.notes-box-align-right]="props.align === 'right'"
8753
+ class="val-notes-box"
8754
+ [class.is-compact]="props.compact"
8755
+ [class.is-rounded]="props.rounded"
8756
+ [class.align-center]="props.align === 'center'"
8757
+ [class.align-right]="props.align === 'right'"
8758
+ [attr.data-color]="props.color || 'primary'"
8759
+ role="note"
8549
8760
  >
8550
- <val-box
8551
- [props]="{
8552
- icon: '',
8553
- bordered: false,
8554
- color: props.color,
8555
- leftBorder: !props.compact,
8556
- rounded: props.rounded,
8557
- padding: props.padding || (props.compact ? '6px 12px' : undefined),
8558
- }"
8559
- >
8560
- <div [ngClass]="['content-container', props.size]" body>
8561
- @if (props.prefix) {
8562
- <val-text
8563
- [props]="{ content: props.prefix, color: props.textColor, bold: true, size: props.size }"
8564
- ></val-text>
8565
- }
8566
- <val-text
8567
- [props]="{
8568
- content: props.text,
8569
- color: props.textColor,
8570
- bold: false,
8571
- size: props.size,
8572
- allowPartialBold: props.allowPartialBold,
8573
- processLinks: props.processLinks,
8574
- }"
8575
- ></val-text>
8576
- </div>
8577
- </val-box>
8761
+ @if (props.prefix) {
8762
+ <div class="val-notes-box__header">{{ props.prefix }}</div>
8763
+ }
8764
+ <div class="val-notes-box__body" [class]="'size-' + (props.size || 'medium')">
8765
+ <val-text
8766
+ [props]="{
8767
+ content: props.text,
8768
+ color: props.textColor,
8769
+ bold: false,
8770
+ size: props.size,
8771
+ allowPartialBold: props.allowPartialBold,
8772
+ processLinks: props.processLinks,
8773
+ }"
8774
+ ></val-text>
8775
+ </div>
8578
8776
  </div>
8579
- `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.content-container{display:inline-grid}.notes-box-compact{display:inline-block;width:fit-content;max-width:100%}.notes-box-compact ::ng-deep val-box ion-card{margin:0;box-shadow:none}.notes-box-align-center{text-align:center}.notes-box-align-center:not(.notes-box-compact){display:flex;justify-content:center}.notes-box-align-right{text-align:right}.notes-box-align-right:not(.notes-box-compact){display:flex;justify-content:flex-end}\n"] }]
8580
- }], ctorParameters: () => [], propDecorators: { props: [{
8777
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}:host{display:block}.val-notes-box{--notes-rgb: var(--ion-color-primary-rgb, 112, 38, 223);--notes-bg: rgba(var(--notes-rgb), .07);--notes-border: rgba(var(--notes-rgb), .18);--notes-accent: rgb(var(--notes-rgb));--notes-text: var(--ion-color-dark, #0a0612);--notes-link: rgb(var(--notes-rgb));position:relative;display:block;padding:14px 18px 14px 20px;background:var(--notes-bg);border:1px solid var(--notes-border);border-left:4px solid var(--notes-accent);border-radius:10px;color:var(--notes-text);margin:0;line-height:1.55}.val-notes-box.is-rounded{border-radius:12px}.val-notes-box[data-color=primary]{--notes-rgb: var(--ion-color-primary-rgb)}.val-notes-box[data-color=secondary]{--notes-rgb: var(--ion-color-secondary-rgb)}.val-notes-box[data-color=tertiary]{--notes-rgb: var(--ion-color-tertiary-rgb)}.val-notes-box[data-color=success]{--notes-rgb: var(--ion-color-success-rgb)}.val-notes-box[data-color=warning]{--notes-rgb: var(--ion-color-warning-rgb)}.val-notes-box[data-color=danger]{--notes-rgb: var(--ion-color-danger-rgb)}.val-notes-box[data-color=medium]{--notes-rgb: var(--ion-color-medium-rgb)}.val-notes-box[data-color=dark]{--notes-rgb: var(--ion-color-dark-rgb)}.val-notes-box[data-color=light]{--notes-rgb: var(--ion-color-medium-rgb)}.val-notes-box__header{display:block;margin:0 0 6px;font-weight:700;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--notes-accent);font-family:var(--ion-font-family, inherit)}.val-notes-box__body{display:block;color:var(--notes-text);font-size:14px;line-height:1.6}.val-notes-box__body.size-small{font-size:13px;line-height:1.55}.val-notes-box__body.size-large{font-size:15px;line-height:1.6}.val-notes-box__body.size-xlarge{font-size:16px;line-height:1.55}.val-notes-box__body ::ng-deep val-text{display:block;color:var(--notes-text)}.val-notes-box__body ::ng-deep val-text p{margin:0;color:inherit}.val-notes-box__body ::ng-deep val-text ion-text{color:var(--notes-text)!important}.val-notes-box__body ::ng-deep val-text strong,.val-notes-box__body ::ng-deep val-text b,.val-notes-box__body ::ng-deep .partial-bold{color:var(--notes-text);font-weight:700}.val-notes-box__body ::ng-deep val-text a{color:var(--notes-link);text-decoration:underline;text-underline-offset:2px;font-weight:600}.val-notes-box__body ::ng-deep val-text a:hover{opacity:.85}.val-notes-box.align-center,.val-notes-box.align-center .val-notes-box__header{text-align:center}.val-notes-box.align-right,.val-notes-box.align-right .val-notes-box__header{text-align:right}.val-notes-box.is-compact{display:inline-block;width:fit-content;max-width:100%;padding:5px 12px;border-left-width:1px;border-radius:999px;font-size:12px;line-height:1.3}.val-notes-box.is-compact .val-notes-box__header{display:inline;margin:0 6px 0 0;font-size:11px;letter-spacing:.06em}.val-notes-box.is-compact .val-notes-box__body{display:inline;font-size:12px}.val-notes-box.is-compact ::ng-deep val-text{display:inline}.val-notes-box.is-compact ::ng-deep val-text p{display:inline}@media (prefers-color-scheme: dark){:host-context(body:not(.light)) .val-notes-box{--notes-bg: rgba(var(--notes-rgb), .16);--notes-border: rgba(var(--notes-rgb), .3);--notes-text: var(--ion-color-light, #f4f5f8)}}:host-context(body.dark) .val-notes-box,:host-context(.theme-dark) .val-notes-box,:host-context([data-theme=dark]) .val-notes-box{--notes-bg: rgba(var(--notes-rgb), .16);--notes-border: rgba(var(--notes-rgb), .3);--notes-text: var(--ion-color-light, #f4f5f8)}\n"] }]
8778
+ }], propDecorators: { props: [{
8581
8779
  type: Input
8582
8780
  }] } });
8583
8781
 
@@ -19890,6 +20088,10 @@ class AuthStateService {
19890
20088
  return {
19891
20089
  userId: state.userId,
19892
20090
  email: state.email || '',
20091
+ name: state.name ?? undefined,
20092
+ handle: state.handle ?? undefined,
20093
+ avatarUrl: state.avatarUrl ?? undefined,
20094
+ phone: state.phone ?? undefined,
19893
20095
  roles: state.roles,
19894
20096
  permissions: state.permissions,
19895
20097
  isSuperAdmin: state.isSuperAdmin,
@@ -19903,7 +20105,7 @@ class AuthStateService {
19903
20105
  * Establece el estado de carga.
19904
20106
  */
19905
20107
  setLoading(isLoading) {
19906
- this._state.update((s) => ({ ...s, isLoading }));
20108
+ this._state.update(s => ({ ...s, isLoading }));
19907
20109
  }
19908
20110
  /**
19909
20111
  * Establece el estado de autenticación exitosa.
@@ -19929,7 +20131,7 @@ class AuthStateService {
19929
20131
  */
19930
20132
  updateAccessToken(accessToken, expiresIn) {
19931
20133
  const expiresAt = Date.now() + expiresIn * 1000;
19932
- this._state.update((s) => ({
20134
+ this._state.update(s => ({
19933
20135
  ...s,
19934
20136
  accessToken,
19935
20137
  expiresAt,
@@ -19939,7 +20141,7 @@ class AuthStateService {
19939
20141
  * Actualiza el refresh token (token rotation).
19940
20142
  */
19941
20143
  updateRefreshToken(refreshToken) {
19942
- this._state.update((s) => ({
20144
+ this._state.update(s => ({
19943
20145
  ...s,
19944
20146
  refreshToken,
19945
20147
  }));
@@ -19948,7 +20150,7 @@ class AuthStateService {
19948
20150
  * Actualiza los permisos.
19949
20151
  */
19950
20152
  updatePermissions(roles, permissions, isSuperAdmin) {
19951
- this._state.update((s) => ({
20153
+ this._state.update(s => ({
19952
20154
  ...s,
19953
20155
  roles,
19954
20156
  permissions,
@@ -19959,7 +20161,7 @@ class AuthStateService {
19959
20161
  * Establece un error de autenticación.
19960
20162
  */
19961
20163
  setError(error) {
19962
- this._state.update((s) => ({
20164
+ this._state.update(s => ({
19963
20165
  ...s,
19964
20166
  error,
19965
20167
  isLoading: false,
@@ -19969,7 +20171,7 @@ class AuthStateService {
19969
20171
  * Limpia el error.
19970
20172
  */
19971
20173
  clearError() {
19972
- this._state.update((s) => ({
20174
+ this._state.update(s => ({
19973
20175
  ...s,
19974
20176
  error: null,
19975
20177
  }));
@@ -20018,12 +20220,29 @@ class AuthStateService {
20018
20220
  * Actualiza el userId y email (después de parsear el token).
20019
20221
  */
20020
20222
  updateUserInfo(userId, email) {
20021
- this._state.update((s) => ({
20223
+ this._state.update(s => ({
20022
20224
  ...s,
20023
20225
  userId,
20024
20226
  email,
20025
20227
  }));
20026
20228
  }
20229
+ /**
20230
+ * Hidrata el state con campos del profile (nombre, handle, avatar, phone).
20231
+ * Invocado tras `getProfile()` o `updateProfile()` para que consumers de
20232
+ * `auth.user()` vean los campos enriched automáticamente.
20233
+ *
20234
+ * Cualquier campo `undefined` se ignora (no sobrescribe con null). Campos
20235
+ * `null` explícitos se persisten (signal de "limpiado").
20236
+ */
20237
+ updateProfileFields(fields) {
20238
+ this._state.update(s => ({
20239
+ ...s,
20240
+ ...(fields.name !== undefined && { name: fields.name }),
20241
+ ...(fields.handle !== undefined && { handle: fields.handle }),
20242
+ ...(fields.avatarUrl !== undefined && { avatarUrl: fields.avatarUrl }),
20243
+ ...(fields.phone !== undefined && { phone: fields.phone }),
20244
+ }));
20245
+ }
20027
20246
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
20028
20247
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthStateService, providedIn: 'root' }); }
20029
20248
  }
@@ -24086,29 +24305,32 @@ class AuthService {
24086
24305
  // =============================================
24087
24306
  /**
24088
24307
  * Obtiene el perfil del usuario autenticado.
24089
- * Incluye información de MFA y teléfono.
24308
+ * Incluye información de MFA y teléfono. Hidrata el state automáticamente
24309
+ * con `name/handle/avatarUrl/phone` para que `auth.user()` los retorne.
24090
24310
  */
24091
24311
  getProfile() {
24092
- return this.http
24093
- .get(`${this.baseUrl}/profile`)
24094
- .pipe(catchError(error => this.handleAuthError(error)));
24312
+ return this.http.get(`${this.baseUrl}/profile`).pipe(tap(profile => this.stateService.updateProfileFields({
24313
+ name: profile.name,
24314
+ handle: profile.handle ?? null,
24315
+ avatarUrl: profile.avatarUrl ?? null,
24316
+ phone: profile.phone ?? null,
24317
+ })), catchError(error => this.handleAuthError(error)));
24095
24318
  }
24096
24319
  /**
24097
- * Actualiza el perfil del usuario.
24320
+ * Actualiza el perfil del usuario. Sincroniza state con los nuevos values
24321
+ * (name/phone) — el backend response no los echo'a pero el caller ya tiene
24322
+ * los valores que mandó.
24098
24323
  */
24099
24324
  updateProfile(request) {
24100
- return this.http
24101
- .put(`${this.baseUrl}/profile`, request)
24102
- .pipe(catchError(error => this.handleAuthError(error)));
24325
+ return this.http.put(`${this.baseUrl}/profile`, request).pipe(tap(() => this.stateService.updateProfileFields(request)), catchError(error => this.handleAuthError(error)));
24103
24326
  }
24104
24327
  /**
24105
- * Actualiza el avatar del usuario en el backend.
24106
- * Nota: El estado local del avatar se maneja a través de getProfile().
24328
+ * Actualiza el avatar del usuario en el backend. Sincroniza state con el
24329
+ * `avatarUrl` retornado para que el header / dashboard se refresquen sin
24330
+ * necesidad de un getProfile adicional.
24107
24331
  */
24108
24332
  updateAvatar(request) {
24109
- return this.http
24110
- .put(`${this.baseUrl}/profile/avatar`, request)
24111
- .pipe(catchError(error => this.handleAuthError(error)));
24333
+ return this.http.put(`${this.baseUrl}/profile/avatar`, request).pipe(tap(res => this.stateService.updateProfileFields({ avatarUrl: res.avatarUrl })), catchError(error => this.handleAuthError(error)));
24112
24334
  }
24113
24335
  // =============================================
24114
24336
  // RECUPERACIÓN DE CONTRASEÑA
@@ -24231,9 +24453,7 @@ class AuthService {
24231
24453
  * @param handle - Nuevo handle (sin @, ej: "victorv")
24232
24454
  */
24233
24455
  updateHandle(handle) {
24234
- return this.http
24235
- .put(`${this.baseUrl}/profile/handle`, { handle })
24236
- .pipe(catchError(error => this.handleAuthError(error)));
24456
+ return this.http.put(`${this.baseUrl}/profile/handle`, { handle }).pipe(tap(() => this.stateService.updateProfileFields({ handle })), catchError(error => this.handleAuthError(error)));
24237
24457
  }
24238
24458
  /**
24239
24459
  * Verifica si un handle está disponible.
@@ -26415,11 +26635,15 @@ class ToolbarComponent {
26415
26635
  <ion-button *ngIf="action.type === actionTypes.ICON" (click)="clickHandler(action.token)">
26416
26636
  <ion-icon slot="icon-only" [name]="action.description" [color]="props.textColor"></ion-icon>
26417
26637
  </ion-button>
26418
- <val-avatar
26638
+ <val-user-avatar
26419
26639
  *ngIf="action.type === actionTypes.AVATAR"
26420
- [props]="{ size: 'small', image: action.description, default: '' }"
26640
+ [props]="{
26641
+ user: action.user,
26642
+ avatarUrl: action.description,
26643
+ size: 'small',
26644
+ }"
26421
26645
  (onClick)="clickHandler(action.token)"
26422
- ></val-avatar>
26646
+ ></val-user-avatar>
26423
26647
  <val-image
26424
26648
  *ngIf="action.type === actionTypes.IMAGE"
26425
26649
  [props]="action.image"
@@ -26444,11 +26668,15 @@ class ToolbarComponent {
26444
26668
  <ion-button *ngIf="action.type === actionTypes.ICON" (click)="clickHandler(action.token)">
26445
26669
  <ion-icon slot="icon-only" [name]="action.description" [color]="props.textColor"></ion-icon>
26446
26670
  </ion-button>
26447
- <val-avatar
26671
+ <val-user-avatar
26448
26672
  *ngIf="action.type === actionTypes.AVATAR"
26449
- [props]="{ size: 'small', image: action.description, default: '' }"
26673
+ [props]="{
26674
+ user: action.user,
26675
+ avatarUrl: action.description,
26676
+ size: 'small',
26677
+ }"
26450
26678
  (onClick)="clickHandler(action.token)"
26451
- ></val-avatar>
26679
+ ></val-user-avatar>
26452
26680
  <val-image
26453
26681
  *ngIf="action.type === actionTypes.IMAGE"
26454
26682
  [props]="action.image"
@@ -26464,7 +26692,7 @@ class ToolbarComponent {
26464
26692
  <!-- experimental -->
26465
26693
  <ng-content select="[toolbar-bottom]"></ng-content>
26466
26694
  </ion-toolbar>
26467
- `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-button{font-family:var(--ion-default-font),Arial,sans-serif}.left-buttons{margin-left:-1rem}.background{background:var(--ion-background-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: AvatarComponent, selector: "val-avatar", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }, { kind: "component", type: IonMenuButton, selector: "ion-menu-button", inputs: ["autoHide", "color", "disabled", "menu", "mode", "type"] }, { kind: "component", type: LanguageSelectorComponent, selector: "val-language-selector", inputs: ["props"], outputs: ["languageChange"] }] }); }
26695
+ `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-button{font-family:var(--ion-default-font),Arial,sans-serif}.left-buttons{margin-left:-1rem}.background{background:var(--ion-background-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }, { kind: "component", type: UserAvatarComponent, selector: "val-user-avatar", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: IonMenuButton, selector: "ion-menu-button", inputs: ["autoHide", "color", "disabled", "menu", "mode", "type"] }, { kind: "component", type: LanguageSelectorComponent, selector: "val-language-selector", inputs: ["props"], outputs: ["languageChange"] }] }); }
26468
26696
  }
26469
26697
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ToolbarComponent, decorators: [{
26470
26698
  type: Component,
@@ -26478,6 +26706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
26478
26706
  IonTitle,
26479
26707
  AvatarComponent,
26480
26708
  ImageComponent,
26709
+ UserAvatarComponent,
26481
26710
  IonMenuButton,
26482
26711
  LanguageSelectorComponent,
26483
26712
  ], template: `
@@ -26496,11 +26725,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
26496
26725
  <ion-button *ngIf="action.type === actionTypes.ICON" (click)="clickHandler(action.token)">
26497
26726
  <ion-icon slot="icon-only" [name]="action.description" [color]="props.textColor"></ion-icon>
26498
26727
  </ion-button>
26499
- <val-avatar
26728
+ <val-user-avatar
26500
26729
  *ngIf="action.type === actionTypes.AVATAR"
26501
- [props]="{ size: 'small', image: action.description, default: '' }"
26730
+ [props]="{
26731
+ user: action.user,
26732
+ avatarUrl: action.description,
26733
+ size: 'small',
26734
+ }"
26502
26735
  (onClick)="clickHandler(action.token)"
26503
- ></val-avatar>
26736
+ ></val-user-avatar>
26504
26737
  <val-image
26505
26738
  *ngIf="action.type === actionTypes.IMAGE"
26506
26739
  [props]="action.image"
@@ -26525,11 +26758,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
26525
26758
  <ion-button *ngIf="action.type === actionTypes.ICON" (click)="clickHandler(action.token)">
26526
26759
  <ion-icon slot="icon-only" [name]="action.description" [color]="props.textColor"></ion-icon>
26527
26760
  </ion-button>
26528
- <val-avatar
26761
+ <val-user-avatar
26529
26762
  *ngIf="action.type === actionTypes.AVATAR"
26530
- [props]="{ size: 'small', image: action.description, default: '' }"
26763
+ [props]="{
26764
+ user: action.user,
26765
+ avatarUrl: action.description,
26766
+ size: 'small',
26767
+ }"
26531
26768
  (onClick)="clickHandler(action.token)"
26532
- ></val-avatar>
26769
+ ></val-user-avatar>
26533
26770
  <val-image
26534
26771
  *ngIf="action.type === actionTypes.IMAGE"
26535
26772
  [props]="action.image"
@@ -35825,6 +36062,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
35825
36062
  }]
35826
36063
  }] });
35827
36064
 
36065
+ /** Built-in label sets for the three platform locales. */
36066
+ const CALLOUT_LABELS = {
36067
+ es: {
36068
+ NOTE: 'Nota',
36069
+ TIP: 'Tip',
36070
+ INFO: 'Info',
36071
+ IMPORTANT: 'Importante',
36072
+ WARNING: 'Atención',
36073
+ CAUTION: 'Precaución',
36074
+ },
36075
+ en: {
36076
+ NOTE: 'Note',
36077
+ TIP: 'Tip',
36078
+ INFO: 'Info',
36079
+ IMPORTANT: 'Important',
36080
+ WARNING: 'Warning',
36081
+ CAUTION: 'Caution',
36082
+ },
36083
+ pt: {
36084
+ NOTE: 'Nota',
36085
+ TIP: 'Dica',
36086
+ INFO: 'Info',
36087
+ IMPORTANT: 'Importante',
36088
+ WARNING: 'Atenção',
36089
+ CAUTION: 'Cuidado',
36090
+ },
36091
+ };
36092
+ /**
36093
+ * Per-callout-kind color (Ionic semantic color). Fixed across locales since
36094
+ * red = danger no matter what language you speak.
36095
+ */
36096
+ const CALLOUT_COLORS = {
36097
+ NOTE: 'primary',
36098
+ TIP: 'success',
36099
+ INFO: 'tertiary',
36100
+ IMPORTANT: 'warning',
36101
+ WARNING: 'warning',
36102
+ CAUTION: 'danger',
36103
+ };
35828
36104
  const BOX_DRAWING = /[┌┐└┘├┤┬┴┼─│╔╗╚╝═║]/;
35829
36105
  const CALLOUT_RE = /^>\s*\[!(NOTE|TIP|INFO|WARNING|CAUTION|IMPORTANT)\]\s*(.*)$/i;
35830
36106
  const FENCE_RE = /^```([\w-]*)\s*$/;
@@ -35849,9 +36125,11 @@ const TABLE_ROW_RE = /^\s*\|(.+)\|\s*$/;
35849
36125
  * - Tables → flattened into paragraphs with bold keys
35850
36126
  * - Horizontal rules (---, ***, ___) → separator
35851
36127
  */
35852
- function parseMarkdownArticle(markdown, config) {
36128
+ function parseMarkdownArticle(markdown, options) {
35853
36129
  const lines = normalize(markdown).split('\n');
35854
36130
  const elements = [];
36131
+ const labels = options?.calloutLabels ??
36132
+ (options?.locale ? CALLOUT_LABELS[options.locale] : CALLOUT_LABELS.es);
35855
36133
  let i = 0;
35856
36134
  while (i < lines.length) {
35857
36135
  const line = lines[i];
@@ -35906,7 +36184,7 @@ function parseMarkdownArticle(markdown, config) {
35906
36184
  block.push(lines[i]);
35907
36185
  i++;
35908
36186
  }
35909
- elements.push(makeQuoteOrCallout(block));
36187
+ elements.push(makeQuoteOrCallout(block, labels));
35910
36188
  continue;
35911
36189
  }
35912
36190
  if (TABLE_ROW_RE.test(line)) {
@@ -35963,12 +36241,14 @@ function parseMarkdownArticle(markdown, config) {
35963
36241
  });
35964
36242
  }
35965
36243
  }
36244
+ // Strip parser-only options before merging into ArticleMetadata
36245
+ const { locale: _l, calloutLabels: _c, ...metadataOverrides } = options ?? {};
35966
36246
  return {
35967
36247
  elements,
35968
36248
  maxWidth: '900px',
35969
36249
  centered: true,
35970
36250
  theme: 'auto',
35971
- ...config,
36251
+ ...metadataOverrides,
35972
36252
  };
35973
36253
  }
35974
36254
  function normalize(md) {
@@ -35998,7 +36278,7 @@ function makeHeading(level, content) {
35998
36278
  props: { content, size, color: 'dark', bold: true },
35999
36279
  };
36000
36280
  }
36001
- function makeQuoteOrCallout(block) {
36281
+ function makeQuoteOrCallout(block, labels) {
36002
36282
  const first = block[0];
36003
36283
  const callout = first.match(CALLOUT_RE);
36004
36284
  const lines = block.map(l => l.replace(/^>\s?/, ''));
@@ -36007,7 +36287,7 @@ function makeQuoteOrCallout(block) {
36007
36287
  const firstLineRest = callout[2] || '';
36008
36288
  const rest = lines.slice(1).join(' ').trim();
36009
36289
  const text = [firstLineRest, rest].filter(Boolean).join(' ').trim();
36010
- return makeNote(type, text);
36290
+ return makeNote(type, text, labels);
36011
36291
  }
36012
36292
  const text = lines.join(' ').trim();
36013
36293
  return {
@@ -36022,22 +36302,13 @@ function makeQuoteOrCallout(block) {
36022
36302
  },
36023
36303
  };
36024
36304
  }
36025
- function makeNote(kind, text) {
36026
- const map = {
36027
- NOTE: { color: 'primary', prefix: 'Nota' },
36028
- TIP: { color: 'success', prefix: 'Tip' },
36029
- INFO: { color: 'tertiary', prefix: 'Info' },
36030
- IMPORTANT: { color: 'warning', prefix: 'Importante' },
36031
- WARNING: { color: 'warning', prefix: 'Atención' },
36032
- CAUTION: { color: 'danger', prefix: 'Precaución' },
36033
- };
36034
- const cfg = map[kind];
36305
+ function makeNote(kind, text, labels) {
36035
36306
  return {
36036
36307
  type: 'note',
36037
36308
  props: {
36038
36309
  text,
36039
- prefix: `${cfg.prefix}:`,
36040
- color: cfg.color,
36310
+ prefix: `${labels[kind]}:`,
36311
+ color: CALLOUT_COLORS[kind],
36041
36312
  textColor: 'dark',
36042
36313
  size: 'medium',
36043
36314
  rounded: true,
@@ -43619,5 +43890,5 @@ function buildFooterLinks(links, t, resolver) {
43619
43890
  * Generated bundle index. Do not edit.
43620
43891
  */
43621
43892
 
43622
- export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CHEV_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CookieBannerComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FabComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MenuComponent, MessagingService, MetaService, ModalService, MultiSelectSearchComponent, NavigationService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RightsFooterComponent, RotatingTextComponent, SHAPE_KEYS, SKELETON_PRESETS, SOLID_KEYS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_DEFAULT_CONTENT, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
43893
+ export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CookieBannerComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FabComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MenuComponent, MessagingService, MetaService, ModalService, MultiSelectSearchComponent, NavigationService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RightsFooterComponent, RotatingTextComponent, SHAPE_KEYS, SKELETON_PRESETS, SOLID_KEYS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_DEFAULT_CONTENT, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
43623
43894
  //# sourceMappingURL=valtech-components.mjs.map