@heroelc/fsociety 0.0.12 → 0.0.14

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.
@@ -515,12 +515,50 @@ class FsProfileCardComponent {
515
515
  .join('')
516
516
  .toUpperCase();
517
517
  }
518
+ /**
519
+ * Resuelve el href de un link.
520
+ * Si tiene encodedEmail, lo decodifica con atob() y retorna 'mailto:email'.
521
+ * Si tiene url, la retorna directamente.
522
+ * Si no tiene ninguno, retorna null.
523
+ */
524
+ getLinkHref(link) {
525
+ if (link.encodedEmail) {
526
+ try {
527
+ return 'mailto:' + atob(link.encodedEmail);
528
+ }
529
+ catch {
530
+ return null;
531
+ }
532
+ }
533
+ return link.url ?? null;
534
+ }
535
+ /**
536
+ * Resuelve el label visible de un link.
537
+ * Si tiene encodedEmail, decodifica y reversa el texto —
538
+ * CSS direction:rtl lo muestra al derecho para el usuario
539
+ * pero el DOM tiene el string invertido, dificultando scrapers.
540
+ */
541
+ getLinkLabel(link) {
542
+ if (link.encodedEmail) {
543
+ try {
544
+ return atob(link.encodedEmail).split('').reverse().join('');
545
+ }
546
+ catch {
547
+ return link.label;
548
+ }
549
+ }
550
+ return link.label;
551
+ }
552
+ /** Verdadero si el link muestra un email (para aplicar la clase RTL) */
553
+ isEmailLink(link) {
554
+ return !!link.encodedEmail;
555
+ }
518
556
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FsProfileCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
519
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: FsProfileCardComponent, isStandalone: true, selector: "fs-profile-card", inputs: { name: "name", handle: "handle", role: "role", verified: "verified", avatarUrl: "avatarUrl", bannerUrl: "bannerUrl", links: "links", badges: "badges", stats: "stats", showActions: "showActions", primaryActionLabel: "primaryActionLabel", secondaryActionLabel: "secondaryActionLabel" }, outputs: { primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, ngImport: i0, template: "<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"link.url || '#'\"\n [attr.target]=\"link.url ? '_blank' : null\"\n [attr.rel]=\"link.url ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- \u00EDcono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ link.label }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n", styles: [":root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-50);--fs-primary-subtle: var(--fs-primary-100);--fs-primary-tint: var(--fs-primary-200);--fs-primary-light: var(--fs-primary-300);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-600);--fs-primary-active: var(--fs-primary-700);--fs-primary-emphasis: var(--fs-primary-800);--fs-primary-contrast: var(--fs-primary-900);--fs-secondary-muted: var(--fs-secondary-50);--fs-secondary-subtle: var(--fs-secondary-100);--fs-secondary-tint: var(--fs-secondary-200);--fs-secondary-light: var(--fs-secondary-300);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-600);--fs-secondary-active: var(--fs-secondary-700);--fs-secondary-emphasis: var(--fs-secondary-800);--fs-secondary-contrast: var(--fs-secondary-900);--fs-tertiary-muted: var(--fs-tertiary-50);--fs-tertiary-subtle: var(--fs-tertiary-100);--fs-tertiary-tint: var(--fs-tertiary-200);--fs-tertiary-light: var(--fs-tertiary-300);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-600);--fs-tertiary-active: var(--fs-tertiary-700);--fs-tertiary-emphasis: var(--fs-tertiary-800);--fs-tertiary-contrast: var(--fs-tertiary-900);--fs-neutral-muted: var(--fs-neutral-50);--fs-neutral-subtle: var(--fs-neutral-100);--fs-neutral-tint: var(--fs-neutral-200);--fs-neutral-light: var(--fs-neutral-300);--fs-neutral-soft: var(--fs-neutral-400);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-600);--fs-neutral-active: var(--fs-neutral-700);--fs-neutral-emphasis: var(--fs-neutral-800);--fs-neutral-contrast: var(--fs-neutral-900);--fs-success-muted: var(--fs-success-50);--fs-success-subtle: var(--fs-success-100);--fs-success-tint: var(--fs-success-200);--fs-success-light: var(--fs-success-300);--fs-success-soft: var(--fs-success-400);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-600);--fs-success-active: var(--fs-success-700);--fs-success-emphasis: var(--fs-success-800);--fs-success-contrast: var(--fs-success-900);--fs-warning-muted: var(--fs-warning-50);--fs-warning-subtle: var(--fs-warning-100);--fs-warning-tint: var(--fs-warning-200);--fs-warning-light: var(--fs-warning-300);--fs-warning-soft: var(--fs-warning-400);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-600);--fs-warning-active: var(--fs-warning-700);--fs-warning-emphasis: var(--fs-warning-800);--fs-warning-contrast: var(--fs-warning-900);--fs-danger-muted: var(--fs-danger-50);--fs-danger-subtle: var(--fs-danger-100);--fs-danger-tint: var(--fs-danger-200);--fs-danger-light: var(--fs-danger-300);--fs-danger-soft: var(--fs-danger-400);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-600);--fs-danger-active: var(--fs-danger-700);--fs-danger-emphasis: var(--fs-danger-800);--fs-danger-contrast: var(--fs-danger-900);--fs-font-sans: Inter, Segoe UI, system-ui, sans-serif;--fs-font-mono: JetBrains Mono, Fira Code, Cascadia Code, monospace;--fs-font-serif: Georgia, serif;--fs-radius-sm: 4px;--fs-radius-md: 6px;--fs-radius-lg: 8px;--fs-radius-xl: 12px;--fs-radius-full: 9999px;--fs-duration-fast: .1s;--fs-duration-normal: .2s;--fs-duration-slow: .35s;--fs-shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--fs-shadow-md: 0 4px 6px rgba(0, 0, 0, .07), 0 2px 4px rgba(0, 0, 0, .04);--fs-shadow-lg: 0 10px 15px rgba(0, 0, 0, .08), 0 4px 6px rgba(0, 0, 0, .04);--fs-space-1: .25rem;--fs-space-2: .5rem;--fs-space-3: .75rem;--fs-space-4: 1rem;--fs-space-6: 1.5rem;--fs-space-8: 2rem}@media (prefers-color-scheme: dark){:root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-900);--fs-primary-subtle: var(--fs-primary-800);--fs-primary-tint: var(--fs-primary-700);--fs-primary-light: var(--fs-primary-600);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-400);--fs-primary-active: var(--fs-primary-300);--fs-primary-emphasis: var(--fs-primary-200);--fs-primary-contrast: var(--fs-primary-50);--fs-secondary-muted: var(--fs-secondary-900);--fs-secondary-subtle: var(--fs-secondary-800);--fs-secondary-tint: var(--fs-secondary-700);--fs-secondary-light: var(--fs-secondary-600);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-400);--fs-secondary-active: var(--fs-secondary-300);--fs-secondary-emphasis: var(--fs-secondary-200);--fs-secondary-contrast: var(--fs-secondary-50);--fs-tertiary-muted: var(--fs-tertiary-900);--fs-tertiary-subtle: var(--fs-tertiary-800);--fs-tertiary-tint: var(--fs-tertiary-700);--fs-tertiary-light: var(--fs-tertiary-600);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-400);--fs-tertiary-active: var(--fs-tertiary-300);--fs-tertiary-emphasis: var(--fs-tertiary-200);--fs-tertiary-contrast: var(--fs-tertiary-50);--fs-neutral-muted: var(--fs-neutral-900);--fs-neutral-subtle: var(--fs-neutral-800);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-400);--fs-neutral-active: var(--fs-neutral-300);--fs-neutral-contrast: var(--fs-neutral-50);--fs-danger-muted: var(--fs-danger-900);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-400);--fs-danger-contrast: var(--fs-danger-50);--fs-success-muted: var(--fs-success-900);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-400);--fs-success-contrast: var(--fs-success-50);--fs-warning-muted: var(--fs-warning-900);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-400);--fs-warning-contrast: var(--fs-warning-50)}}.fs-profile{--fs-profile-bg: #0d1117;--fs-profile-border: rgba(255, 255, 255, .08);--fs-profile-banner-from: #1e3a5f;--fs-profile-banner-to: #0f2035;--fs-profile-avatar-bg: #1d3557;--fs-profile-avatar-color: #60a5fa;--fs-profile-avatar-border: #0d1117;--fs-profile-name: #ffffff;--fs-profile-handle: rgba(255, 255, 255, .35);--fs-profile-role: rgba(255, 255, 255, .5);--fs-profile-link: #60a5fa;--fs-profile-stat-value: #ffffff;--fs-profile-stat-label: rgba(255, 255, 255, .3);--fs-profile-stats-border: rgba(255, 255, 255, .06);--fs-profile-divider: rgba(255, 255, 255, .06);--fs-profile-radius: 12px;background:var(--fs-profile-bg);border:.5px solid var(--fs-profile-border);border-radius:var(--fs-profile-radius);overflow:hidden;width:100%}.fs-profile__banner{height:180px;position:relative;overflow:hidden}.fs-profile__banner-img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.fs-profile__banner-gradient{width:100%;height:100%;background:linear-gradient(135deg,var(--fs-profile-banner-from) 0%,var(--fs-profile-banner-to) 100%)}.fs-profile__banner-line{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--fs-primary-base) 0%,var(--fs-tertiary-base) 100%)}.fs-profile__body{padding:.75rem 1.5rem 1.5rem}.fs-profile__avatar-wrap{position:relative;width:fit-content;margin-top:-60px;margin-bottom:1rem}.fs-profile__avatar{width:120px;height:120px;border-radius:9999px;background:var(--fs-profile-avatar-bg);border:3px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center;overflow:hidden}.fs-profile__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.fs-profile__avatar-initials{font-size:34px;font-weight:700;color:var(--fs-profile-avatar-color);font-family:Inter,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.fs-profile__verified{position:absolute;bottom:2px;right:0;width:30px;height:30px;border-radius:9999px;background:var(--fs-primary-base);border:2px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center}.fs-profile__name{font-size:1.25rem;font-weight:600;color:var(--fs-profile-name);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.25rem;line-height:1.2}.fs-profile__handle{font-size:.875rem;color:var(--fs-profile-handle);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.5rem}.fs-profile__role{font-size:.875rem;font-weight:500;color:var(--fs-profile-role);text-transform:uppercase;letter-spacing:.08em;font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:1rem}.fs-profile__actions{display:flex;gap:.5rem;margin-bottom:1rem}.fs-profile__btn{flex:1;padding:.5rem 0;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:background-color .1s cubic-bezier(.4,0,.2,1),border-color .1s cubic-bezier(.4,0,.2,1),color .1s cubic-bezier(.4,0,.2,1);border:none}.fs-profile__btn--primary{background:var(--fs-primary-base);color:#fff}.fs-profile__btn--primary:hover{background:var(--fs-primary-hover)}.fs-profile__btn--primary:active{background:var(--fs-primary-active)}.fs-profile__btn--outline{background:transparent;color:#ffffffb3;border:.5px solid rgba(255,255,255,.15)}.fs-profile__btn--outline:hover{border-color:#ffffff4d}.fs-profile__btn--outline:active{background:#ffffff0d}.fs-profile__btn:focus-visible{outline:none;box-shadow:0 0 0 2px #fff,0 0 0 4px var(--fs-primary-base)}.fs-profile__links{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.fs-profile__link{display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--fs-profile-link);text-decoration:none;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:opacity .1s cubic-bezier(.4,0,.2,1)}.fs-profile__link svg{opacity:.5;flex-shrink:0;stroke:currentColor}.fs-profile__link:hover{opacity:.75}.fs-profile__link-img{width:14px;height:14px;object-fit:contain;display:block;flex-shrink:0;opacity:.6;border-radius:2px}.fs-profile__badges{display:flex;flex-wrap:wrap;gap:.5rem}.fs-profile__stats{border-top:.5px solid var(--fs-profile-stats-border);display:flex}.fs-profile__stat{flex:1;padding:1rem 0;text-align:center;border-right:.5px solid var(--fs-profile-divider);display:flex;flex-direction:column;gap:.25rem}.fs-profile__stat:last-child{border-right:none}.fs-profile__stat-value{font-size:1.25rem;font-weight:600;color:var(--fs-profile-stat-value);font-family:Inter,Segoe UI,system-ui,sans-serif;line-height:1}.fs-profile__stat-label{font-size:.75rem;color:var(--fs-profile-stat-label);font-family:Inter,Segoe UI,system-ui,sans-serif}\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: FsBadgeComponent, selector: "fs-badge", inputs: ["color", "customColor", "variant", "size", "label", "dot", "iconLeft", "iconRight", "imgLeft", "imgRight", "imgLeftAlt", "imgRightAlt", "iconOnly", "removable"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
557
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: FsProfileCardComponent, isStandalone: true, selector: "fs-profile-card", inputs: { name: "name", handle: "handle", role: "role", verified: "verified", avatarUrl: "avatarUrl", bannerUrl: "bannerUrl", links: "links", badges: "badges", stats: "stats", showActions: "showActions", primaryActionLabel: "primaryActionLabel", secondaryActionLabel: "secondaryActionLabel" }, outputs: { primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, ngImport: i0, template: "<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"getLinkHref(link) || '#'\"\n [attr.target]=\"link.url && !link.encodedEmail ? '_blank' : null\"\n [attr.rel]=\"link.url && !link.encodedEmail ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- \u00EDcono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span\n [class.fs-profile__link-email]=\"isEmailLink(link)\"\n >{{ getLinkLabel(link) }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n", styles: [":root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-50);--fs-primary-subtle: var(--fs-primary-100);--fs-primary-tint: var(--fs-primary-200);--fs-primary-light: var(--fs-primary-300);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-600);--fs-primary-active: var(--fs-primary-700);--fs-primary-emphasis: var(--fs-primary-800);--fs-primary-contrast: var(--fs-primary-900);--fs-secondary-muted: var(--fs-secondary-50);--fs-secondary-subtle: var(--fs-secondary-100);--fs-secondary-tint: var(--fs-secondary-200);--fs-secondary-light: var(--fs-secondary-300);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-600);--fs-secondary-active: var(--fs-secondary-700);--fs-secondary-emphasis: var(--fs-secondary-800);--fs-secondary-contrast: var(--fs-secondary-900);--fs-tertiary-muted: var(--fs-tertiary-50);--fs-tertiary-subtle: var(--fs-tertiary-100);--fs-tertiary-tint: var(--fs-tertiary-200);--fs-tertiary-light: var(--fs-tertiary-300);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-600);--fs-tertiary-active: var(--fs-tertiary-700);--fs-tertiary-emphasis: var(--fs-tertiary-800);--fs-tertiary-contrast: var(--fs-tertiary-900);--fs-neutral-muted: var(--fs-neutral-50);--fs-neutral-subtle: var(--fs-neutral-100);--fs-neutral-tint: var(--fs-neutral-200);--fs-neutral-light: var(--fs-neutral-300);--fs-neutral-soft: var(--fs-neutral-400);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-600);--fs-neutral-active: var(--fs-neutral-700);--fs-neutral-emphasis: var(--fs-neutral-800);--fs-neutral-contrast: var(--fs-neutral-900);--fs-success-muted: var(--fs-success-50);--fs-success-subtle: var(--fs-success-100);--fs-success-tint: var(--fs-success-200);--fs-success-light: var(--fs-success-300);--fs-success-soft: var(--fs-success-400);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-600);--fs-success-active: var(--fs-success-700);--fs-success-emphasis: var(--fs-success-800);--fs-success-contrast: var(--fs-success-900);--fs-warning-muted: var(--fs-warning-50);--fs-warning-subtle: var(--fs-warning-100);--fs-warning-tint: var(--fs-warning-200);--fs-warning-light: var(--fs-warning-300);--fs-warning-soft: var(--fs-warning-400);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-600);--fs-warning-active: var(--fs-warning-700);--fs-warning-emphasis: var(--fs-warning-800);--fs-warning-contrast: var(--fs-warning-900);--fs-danger-muted: var(--fs-danger-50);--fs-danger-subtle: var(--fs-danger-100);--fs-danger-tint: var(--fs-danger-200);--fs-danger-light: var(--fs-danger-300);--fs-danger-soft: var(--fs-danger-400);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-600);--fs-danger-active: var(--fs-danger-700);--fs-danger-emphasis: var(--fs-danger-800);--fs-danger-contrast: var(--fs-danger-900);--fs-font-sans: Inter, Segoe UI, system-ui, sans-serif;--fs-font-mono: JetBrains Mono, Fira Code, Cascadia Code, monospace;--fs-font-serif: Georgia, serif;--fs-radius-sm: 4px;--fs-radius-md: 6px;--fs-radius-lg: 8px;--fs-radius-xl: 12px;--fs-radius-full: 9999px;--fs-duration-fast: .1s;--fs-duration-normal: .2s;--fs-duration-slow: .35s;--fs-shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--fs-shadow-md: 0 4px 6px rgba(0, 0, 0, .07), 0 2px 4px rgba(0, 0, 0, .04);--fs-shadow-lg: 0 10px 15px rgba(0, 0, 0, .08), 0 4px 6px rgba(0, 0, 0, .04);--fs-space-1: .25rem;--fs-space-2: .5rem;--fs-space-3: .75rem;--fs-space-4: 1rem;--fs-space-6: 1.5rem;--fs-space-8: 2rem}@media (prefers-color-scheme: dark){:root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-900);--fs-primary-subtle: var(--fs-primary-800);--fs-primary-tint: var(--fs-primary-700);--fs-primary-light: var(--fs-primary-600);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-400);--fs-primary-active: var(--fs-primary-300);--fs-primary-emphasis: var(--fs-primary-200);--fs-primary-contrast: var(--fs-primary-50);--fs-secondary-muted: var(--fs-secondary-900);--fs-secondary-subtle: var(--fs-secondary-800);--fs-secondary-tint: var(--fs-secondary-700);--fs-secondary-light: var(--fs-secondary-600);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-400);--fs-secondary-active: var(--fs-secondary-300);--fs-secondary-emphasis: var(--fs-secondary-200);--fs-secondary-contrast: var(--fs-secondary-50);--fs-tertiary-muted: var(--fs-tertiary-900);--fs-tertiary-subtle: var(--fs-tertiary-800);--fs-tertiary-tint: var(--fs-tertiary-700);--fs-tertiary-light: var(--fs-tertiary-600);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-400);--fs-tertiary-active: var(--fs-tertiary-300);--fs-tertiary-emphasis: var(--fs-tertiary-200);--fs-tertiary-contrast: var(--fs-tertiary-50);--fs-neutral-muted: var(--fs-neutral-900);--fs-neutral-subtle: var(--fs-neutral-800);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-400);--fs-neutral-active: var(--fs-neutral-300);--fs-neutral-contrast: var(--fs-neutral-50);--fs-danger-muted: var(--fs-danger-900);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-400);--fs-danger-contrast: var(--fs-danger-50);--fs-success-muted: var(--fs-success-900);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-400);--fs-success-contrast: var(--fs-success-50);--fs-warning-muted: var(--fs-warning-900);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-400);--fs-warning-contrast: var(--fs-warning-50)}}.fs-profile{--fs-profile-bg: #0d1117;--fs-profile-border: rgba(255, 255, 255, .08);--fs-profile-banner-from: #1e3a5f;--fs-profile-banner-to: #0f2035;--fs-profile-avatar-bg: #1d3557;--fs-profile-avatar-color: #60a5fa;--fs-profile-avatar-border: #0d1117;--fs-profile-name: #ffffff;--fs-profile-handle: rgba(255, 255, 255, .35);--fs-profile-role: rgba(255, 255, 255, .5);--fs-profile-link: #60a5fa;--fs-profile-stat-value: #ffffff;--fs-profile-stat-label: rgba(255, 255, 255, .3);--fs-profile-stats-border: rgba(255, 255, 255, .06);--fs-profile-divider: rgba(255, 255, 255, .06);--fs-profile-radius: 12px;background:var(--fs-profile-bg);border:.5px solid var(--fs-profile-border);border-radius:var(--fs-profile-radius);overflow:hidden;width:100%}.fs-profile__banner{height:180px;position:relative;overflow:hidden}.fs-profile__banner-img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.fs-profile__banner-gradient{width:100%;height:100%;background:linear-gradient(135deg,var(--fs-profile-banner-from) 0%,var(--fs-profile-banner-to) 100%)}.fs-profile__banner-line{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--fs-primary-base) 0%,var(--fs-tertiary-base) 100%)}.fs-profile__body{padding:.75rem 1.5rem 1.5rem}.fs-profile__avatar-wrap{position:relative;width:fit-content;margin-top:-60px;margin-bottom:1rem}.fs-profile__avatar{width:120px;height:120px;border-radius:9999px;background:var(--fs-profile-avatar-bg);border:3px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center;overflow:hidden}.fs-profile__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.fs-profile__avatar-initials{font-size:34px;font-weight:700;color:var(--fs-profile-avatar-color);font-family:Inter,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.fs-profile__verified{position:absolute;bottom:2px;right:0;width:30px;height:30px;border-radius:9999px;background:var(--fs-primary-base);border:2px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center}.fs-profile__name{font-size:1.25rem;font-weight:600;color:var(--fs-profile-name);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.25rem;line-height:1.2}.fs-profile__handle{font-size:.875rem;color:var(--fs-profile-handle);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.5rem}.fs-profile__role{font-size:.875rem;font-weight:500;color:var(--fs-profile-role);text-transform:uppercase;letter-spacing:.08em;font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:1rem}.fs-profile__actions{display:flex;gap:.5rem;margin-bottom:1rem}.fs-profile__btn{flex:1;padding:.5rem 0;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:background-color .1s cubic-bezier(.4,0,.2,1),border-color .1s cubic-bezier(.4,0,.2,1),color .1s cubic-bezier(.4,0,.2,1);border:none}.fs-profile__btn--primary{background:var(--fs-primary-base);color:#fff}.fs-profile__btn--primary:hover{background:var(--fs-primary-hover)}.fs-profile__btn--primary:active{background:var(--fs-primary-active)}.fs-profile__btn--outline{background:transparent;color:#ffffffb3;border:.5px solid rgba(255,255,255,.15)}.fs-profile__btn--outline:hover{border-color:#ffffff4d}.fs-profile__btn--outline:active{background:#ffffff0d}.fs-profile__btn:focus-visible{outline:none;box-shadow:0 0 0 2px #fff,0 0 0 4px var(--fs-primary-base)}.fs-profile__links{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.fs-profile__link{display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--fs-profile-link);text-decoration:none;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:opacity .1s cubic-bezier(.4,0,.2,1)}.fs-profile__link svg{opacity:.5;flex-shrink:0;stroke:currentColor}.fs-profile__link:hover{opacity:.75}.fs-profile__link-email{unicode-bidi:bidi-override;direction:rtl}.fs-profile__link-img{width:14px;height:14px;object-fit:contain;display:block;flex-shrink:0;opacity:.6;border-radius:2px}.fs-profile__badges{display:flex;flex-wrap:wrap;gap:.5rem}.fs-profile__stats{border-top:.5px solid var(--fs-profile-stats-border);display:flex}.fs-profile__stat{flex:1;padding:1rem 0;text-align:center;border-right:.5px solid var(--fs-profile-divider);display:flex;flex-direction:column;gap:.25rem}.fs-profile__stat:last-child{border-right:none}.fs-profile__stat-value{font-size:1.25rem;font-weight:600;color:var(--fs-profile-stat-value);font-family:Inter,Segoe UI,system-ui,sans-serif;line-height:1}.fs-profile__stat-label{font-size:.75rem;color:var(--fs-profile-stat-label);font-family:Inter,Segoe UI,system-ui,sans-serif}\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: FsBadgeComponent, selector: "fs-badge", inputs: ["color", "customColor", "variant", "size", "label", "dot", "iconLeft", "iconRight", "imgLeft", "imgRight", "imgLeftAlt", "imgRightAlt", "iconOnly", "removable"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
520
558
  }
521
559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FsProfileCardComponent, decorators: [{
522
560
  type: Component,
523
- args: [{ selector: 'fs-profile-card', standalone: true, imports: [CommonModule, FsBadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"link.url || '#'\"\n [attr.target]=\"link.url ? '_blank' : null\"\n [attr.rel]=\"link.url ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- \u00EDcono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ link.label }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n", styles: [":root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-50);--fs-primary-subtle: var(--fs-primary-100);--fs-primary-tint: var(--fs-primary-200);--fs-primary-light: var(--fs-primary-300);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-600);--fs-primary-active: var(--fs-primary-700);--fs-primary-emphasis: var(--fs-primary-800);--fs-primary-contrast: var(--fs-primary-900);--fs-secondary-muted: var(--fs-secondary-50);--fs-secondary-subtle: var(--fs-secondary-100);--fs-secondary-tint: var(--fs-secondary-200);--fs-secondary-light: var(--fs-secondary-300);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-600);--fs-secondary-active: var(--fs-secondary-700);--fs-secondary-emphasis: var(--fs-secondary-800);--fs-secondary-contrast: var(--fs-secondary-900);--fs-tertiary-muted: var(--fs-tertiary-50);--fs-tertiary-subtle: var(--fs-tertiary-100);--fs-tertiary-tint: var(--fs-tertiary-200);--fs-tertiary-light: var(--fs-tertiary-300);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-600);--fs-tertiary-active: var(--fs-tertiary-700);--fs-tertiary-emphasis: var(--fs-tertiary-800);--fs-tertiary-contrast: var(--fs-tertiary-900);--fs-neutral-muted: var(--fs-neutral-50);--fs-neutral-subtle: var(--fs-neutral-100);--fs-neutral-tint: var(--fs-neutral-200);--fs-neutral-light: var(--fs-neutral-300);--fs-neutral-soft: var(--fs-neutral-400);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-600);--fs-neutral-active: var(--fs-neutral-700);--fs-neutral-emphasis: var(--fs-neutral-800);--fs-neutral-contrast: var(--fs-neutral-900);--fs-success-muted: var(--fs-success-50);--fs-success-subtle: var(--fs-success-100);--fs-success-tint: var(--fs-success-200);--fs-success-light: var(--fs-success-300);--fs-success-soft: var(--fs-success-400);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-600);--fs-success-active: var(--fs-success-700);--fs-success-emphasis: var(--fs-success-800);--fs-success-contrast: var(--fs-success-900);--fs-warning-muted: var(--fs-warning-50);--fs-warning-subtle: var(--fs-warning-100);--fs-warning-tint: var(--fs-warning-200);--fs-warning-light: var(--fs-warning-300);--fs-warning-soft: var(--fs-warning-400);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-600);--fs-warning-active: var(--fs-warning-700);--fs-warning-emphasis: var(--fs-warning-800);--fs-warning-contrast: var(--fs-warning-900);--fs-danger-muted: var(--fs-danger-50);--fs-danger-subtle: var(--fs-danger-100);--fs-danger-tint: var(--fs-danger-200);--fs-danger-light: var(--fs-danger-300);--fs-danger-soft: var(--fs-danger-400);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-600);--fs-danger-active: var(--fs-danger-700);--fs-danger-emphasis: var(--fs-danger-800);--fs-danger-contrast: var(--fs-danger-900);--fs-font-sans: Inter, Segoe UI, system-ui, sans-serif;--fs-font-mono: JetBrains Mono, Fira Code, Cascadia Code, monospace;--fs-font-serif: Georgia, serif;--fs-radius-sm: 4px;--fs-radius-md: 6px;--fs-radius-lg: 8px;--fs-radius-xl: 12px;--fs-radius-full: 9999px;--fs-duration-fast: .1s;--fs-duration-normal: .2s;--fs-duration-slow: .35s;--fs-shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--fs-shadow-md: 0 4px 6px rgba(0, 0, 0, .07), 0 2px 4px rgba(0, 0, 0, .04);--fs-shadow-lg: 0 10px 15px rgba(0, 0, 0, .08), 0 4px 6px rgba(0, 0, 0, .04);--fs-space-1: .25rem;--fs-space-2: .5rem;--fs-space-3: .75rem;--fs-space-4: 1rem;--fs-space-6: 1.5rem;--fs-space-8: 2rem}@media (prefers-color-scheme: dark){:root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-900);--fs-primary-subtle: var(--fs-primary-800);--fs-primary-tint: var(--fs-primary-700);--fs-primary-light: var(--fs-primary-600);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-400);--fs-primary-active: var(--fs-primary-300);--fs-primary-emphasis: var(--fs-primary-200);--fs-primary-contrast: var(--fs-primary-50);--fs-secondary-muted: var(--fs-secondary-900);--fs-secondary-subtle: var(--fs-secondary-800);--fs-secondary-tint: var(--fs-secondary-700);--fs-secondary-light: var(--fs-secondary-600);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-400);--fs-secondary-active: var(--fs-secondary-300);--fs-secondary-emphasis: var(--fs-secondary-200);--fs-secondary-contrast: var(--fs-secondary-50);--fs-tertiary-muted: var(--fs-tertiary-900);--fs-tertiary-subtle: var(--fs-tertiary-800);--fs-tertiary-tint: var(--fs-tertiary-700);--fs-tertiary-light: var(--fs-tertiary-600);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-400);--fs-tertiary-active: var(--fs-tertiary-300);--fs-tertiary-emphasis: var(--fs-tertiary-200);--fs-tertiary-contrast: var(--fs-tertiary-50);--fs-neutral-muted: var(--fs-neutral-900);--fs-neutral-subtle: var(--fs-neutral-800);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-400);--fs-neutral-active: var(--fs-neutral-300);--fs-neutral-contrast: var(--fs-neutral-50);--fs-danger-muted: var(--fs-danger-900);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-400);--fs-danger-contrast: var(--fs-danger-50);--fs-success-muted: var(--fs-success-900);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-400);--fs-success-contrast: var(--fs-success-50);--fs-warning-muted: var(--fs-warning-900);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-400);--fs-warning-contrast: var(--fs-warning-50)}}.fs-profile{--fs-profile-bg: #0d1117;--fs-profile-border: rgba(255, 255, 255, .08);--fs-profile-banner-from: #1e3a5f;--fs-profile-banner-to: #0f2035;--fs-profile-avatar-bg: #1d3557;--fs-profile-avatar-color: #60a5fa;--fs-profile-avatar-border: #0d1117;--fs-profile-name: #ffffff;--fs-profile-handle: rgba(255, 255, 255, .35);--fs-profile-role: rgba(255, 255, 255, .5);--fs-profile-link: #60a5fa;--fs-profile-stat-value: #ffffff;--fs-profile-stat-label: rgba(255, 255, 255, .3);--fs-profile-stats-border: rgba(255, 255, 255, .06);--fs-profile-divider: rgba(255, 255, 255, .06);--fs-profile-radius: 12px;background:var(--fs-profile-bg);border:.5px solid var(--fs-profile-border);border-radius:var(--fs-profile-radius);overflow:hidden;width:100%}.fs-profile__banner{height:180px;position:relative;overflow:hidden}.fs-profile__banner-img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.fs-profile__banner-gradient{width:100%;height:100%;background:linear-gradient(135deg,var(--fs-profile-banner-from) 0%,var(--fs-profile-banner-to) 100%)}.fs-profile__banner-line{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--fs-primary-base) 0%,var(--fs-tertiary-base) 100%)}.fs-profile__body{padding:.75rem 1.5rem 1.5rem}.fs-profile__avatar-wrap{position:relative;width:fit-content;margin-top:-60px;margin-bottom:1rem}.fs-profile__avatar{width:120px;height:120px;border-radius:9999px;background:var(--fs-profile-avatar-bg);border:3px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center;overflow:hidden}.fs-profile__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.fs-profile__avatar-initials{font-size:34px;font-weight:700;color:var(--fs-profile-avatar-color);font-family:Inter,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.fs-profile__verified{position:absolute;bottom:2px;right:0;width:30px;height:30px;border-radius:9999px;background:var(--fs-primary-base);border:2px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center}.fs-profile__name{font-size:1.25rem;font-weight:600;color:var(--fs-profile-name);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.25rem;line-height:1.2}.fs-profile__handle{font-size:.875rem;color:var(--fs-profile-handle);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.5rem}.fs-profile__role{font-size:.875rem;font-weight:500;color:var(--fs-profile-role);text-transform:uppercase;letter-spacing:.08em;font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:1rem}.fs-profile__actions{display:flex;gap:.5rem;margin-bottom:1rem}.fs-profile__btn{flex:1;padding:.5rem 0;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:background-color .1s cubic-bezier(.4,0,.2,1),border-color .1s cubic-bezier(.4,0,.2,1),color .1s cubic-bezier(.4,0,.2,1);border:none}.fs-profile__btn--primary{background:var(--fs-primary-base);color:#fff}.fs-profile__btn--primary:hover{background:var(--fs-primary-hover)}.fs-profile__btn--primary:active{background:var(--fs-primary-active)}.fs-profile__btn--outline{background:transparent;color:#ffffffb3;border:.5px solid rgba(255,255,255,.15)}.fs-profile__btn--outline:hover{border-color:#ffffff4d}.fs-profile__btn--outline:active{background:#ffffff0d}.fs-profile__btn:focus-visible{outline:none;box-shadow:0 0 0 2px #fff,0 0 0 4px var(--fs-primary-base)}.fs-profile__links{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.fs-profile__link{display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--fs-profile-link);text-decoration:none;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:opacity .1s cubic-bezier(.4,0,.2,1)}.fs-profile__link svg{opacity:.5;flex-shrink:0;stroke:currentColor}.fs-profile__link:hover{opacity:.75}.fs-profile__link-img{width:14px;height:14px;object-fit:contain;display:block;flex-shrink:0;opacity:.6;border-radius:2px}.fs-profile__badges{display:flex;flex-wrap:wrap;gap:.5rem}.fs-profile__stats{border-top:.5px solid var(--fs-profile-stats-border);display:flex}.fs-profile__stat{flex:1;padding:1rem 0;text-align:center;border-right:.5px solid var(--fs-profile-divider);display:flex;flex-direction:column;gap:.25rem}.fs-profile__stat:last-child{border-right:none}.fs-profile__stat-value{font-size:1.25rem;font-weight:600;color:var(--fs-profile-stat-value);font-family:Inter,Segoe UI,system-ui,sans-serif;line-height:1}.fs-profile__stat-label{font-size:.75rem;color:var(--fs-profile-stat-label);font-family:Inter,Segoe UI,system-ui,sans-serif}\n"] }]
561
+ args: [{ selector: 'fs-profile-card', standalone: true, imports: [CommonModule, FsBadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"getLinkHref(link) || '#'\"\n [attr.target]=\"link.url && !link.encodedEmail ? '_blank' : null\"\n [attr.rel]=\"link.url && !link.encodedEmail ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- \u00EDcono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span\n [class.fs-profile__link-email]=\"isEmailLink(link)\"\n >{{ getLinkLabel(link) }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n", styles: [":root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-50);--fs-primary-subtle: var(--fs-primary-100);--fs-primary-tint: var(--fs-primary-200);--fs-primary-light: var(--fs-primary-300);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-600);--fs-primary-active: var(--fs-primary-700);--fs-primary-emphasis: var(--fs-primary-800);--fs-primary-contrast: var(--fs-primary-900);--fs-secondary-muted: var(--fs-secondary-50);--fs-secondary-subtle: var(--fs-secondary-100);--fs-secondary-tint: var(--fs-secondary-200);--fs-secondary-light: var(--fs-secondary-300);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-600);--fs-secondary-active: var(--fs-secondary-700);--fs-secondary-emphasis: var(--fs-secondary-800);--fs-secondary-contrast: var(--fs-secondary-900);--fs-tertiary-muted: var(--fs-tertiary-50);--fs-tertiary-subtle: var(--fs-tertiary-100);--fs-tertiary-tint: var(--fs-tertiary-200);--fs-tertiary-light: var(--fs-tertiary-300);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-600);--fs-tertiary-active: var(--fs-tertiary-700);--fs-tertiary-emphasis: var(--fs-tertiary-800);--fs-tertiary-contrast: var(--fs-tertiary-900);--fs-neutral-muted: var(--fs-neutral-50);--fs-neutral-subtle: var(--fs-neutral-100);--fs-neutral-tint: var(--fs-neutral-200);--fs-neutral-light: var(--fs-neutral-300);--fs-neutral-soft: var(--fs-neutral-400);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-600);--fs-neutral-active: var(--fs-neutral-700);--fs-neutral-emphasis: var(--fs-neutral-800);--fs-neutral-contrast: var(--fs-neutral-900);--fs-success-muted: var(--fs-success-50);--fs-success-subtle: var(--fs-success-100);--fs-success-tint: var(--fs-success-200);--fs-success-light: var(--fs-success-300);--fs-success-soft: var(--fs-success-400);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-600);--fs-success-active: var(--fs-success-700);--fs-success-emphasis: var(--fs-success-800);--fs-success-contrast: var(--fs-success-900);--fs-warning-muted: var(--fs-warning-50);--fs-warning-subtle: var(--fs-warning-100);--fs-warning-tint: var(--fs-warning-200);--fs-warning-light: var(--fs-warning-300);--fs-warning-soft: var(--fs-warning-400);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-600);--fs-warning-active: var(--fs-warning-700);--fs-warning-emphasis: var(--fs-warning-800);--fs-warning-contrast: var(--fs-warning-900);--fs-danger-muted: var(--fs-danger-50);--fs-danger-subtle: var(--fs-danger-100);--fs-danger-tint: var(--fs-danger-200);--fs-danger-light: var(--fs-danger-300);--fs-danger-soft: var(--fs-danger-400);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-600);--fs-danger-active: var(--fs-danger-700);--fs-danger-emphasis: var(--fs-danger-800);--fs-danger-contrast: var(--fs-danger-900);--fs-font-sans: Inter, Segoe UI, system-ui, sans-serif;--fs-font-mono: JetBrains Mono, Fira Code, Cascadia Code, monospace;--fs-font-serif: Georgia, serif;--fs-radius-sm: 4px;--fs-radius-md: 6px;--fs-radius-lg: 8px;--fs-radius-xl: 12px;--fs-radius-full: 9999px;--fs-duration-fast: .1s;--fs-duration-normal: .2s;--fs-duration-slow: .35s;--fs-shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--fs-shadow-md: 0 4px 6px rgba(0, 0, 0, .07), 0 2px 4px rgba(0, 0, 0, .04);--fs-shadow-lg: 0 10px 15px rgba(0, 0, 0, .08), 0 4px 6px rgba(0, 0, 0, .04);--fs-space-1: .25rem;--fs-space-2: .5rem;--fs-space-3: .75rem;--fs-space-4: 1rem;--fs-space-6: 1.5rem;--fs-space-8: 2rem}@media (prefers-color-scheme: dark){:root,[data-theme=dark]{--fs-primary-50: rgb(237.56, 242.52, 253.4);--fs-primary-100: rgb(211.4, 223.8, 251);--fs-primary-200: rgb(176.52, 198.84, 247.8);--fs-primary-300: rgb(132.92, 167.64, 243.8);--fs-primary-400: rgb(84.96, 133.32, 239.4);--fs-primary-500: #2563eb;--fs-primary-600: rgb(33.48, 86.84, 204.12);--fs-primary-700: rgb(29.52, 73.16, 169.38);--fs-primary-800: rgb(25.12, 57.96, 130.78);--fs-primary-900: rgb(21.16, 44.28, 96.04);--fs-secondary-50: rgb(235.72, 247.8, 253.24);--fs-secondary-100: rgb(206.8, 237, 250.6);--fs-secondary-200: rgb(168.24, 222.6, 247.08);--fs-secondary-300: rgb(120.04, 204.6, 242.68);--fs-secondary-400: rgb(67.02, 184.8, 237.84);--fs-secondary-500: #0ea5e9;--fs-secondary-600: rgb(14.16, 142.28, 202.44);--fs-secondary-700: rgb(14.34, 116.72, 168.06);--fs-secondary-800: rgb(14.54, 88.32, 129.86);--fs-secondary-900: rgb(14.72, 62.76, 95.48);--fs-tertiary-50: rgb(237.32, 251.48, 253.64);--fs-tertiary-100: rgb(210.8, 246.2, 251.6);--fs-tertiary-200: rgb(175.44, 239.16, 248.88);--fs-tertiary-300: rgb(131.24, 230.36, 245.48);--fs-tertiary-400: rgb(82.62, 220.68, 241.74);--fs-tertiary-500: #22d3ee;--fs-tertiary-600: rgb(30.96, 180.92, 206.64);--fs-tertiary-700: rgb(27.54, 147.08, 171.36);--fs-tertiary-800: rgb(23.74, 109.48, 132.16);--fs-tertiary-900: rgb(20.32, 75.64, 96.88);--fs-neutral-50: rgb(242.6, 243.88, 245.72);--fs-neutral-100: rgb(224, 227.2, 231.8);--fs-neutral-200: rgb(199.2, 204.96, 213.24);--fs-neutral-300: rgb(168.2, 177.16, 190.04);--fs-neutral-400: rgb(134.1, 146.58, 164.52);--fs-neutral-500: #64748b;--fs-neutral-600: rgb(86.4, 101.12, 123.48);--fs-neutral-700: rgb(71.1, 84.38, 106.02);--fs-neutral-800: rgb(54.1, 65.78, 86.62);--fs-neutral-900: rgb(38.8, 49.04, 69.16);--fs-success-50: rgb(237.32, 250.36, 242.12);--fs-success-100: rgb(210.8, 243.4, 222.8);--fs-success-200: rgb(175.44, 234.12, 197.04);--fs-success-300: rgb(131.24, 222.52, 164.84);--fs-success-400: rgb(82.62, 209.76, 129.42);--fs-success-500: #22c55e;--fs-success-600: rgb(30.96, 169.16, 85.68);--fs-success-700: rgb(27.54, 137.84, 76.32);--fs-success-800: rgb(23.74, 103.04, 65.92);--fs-success-900: rgb(20.32, 71.72, 56.56);--fs-warning-50: rgb(254.2, 247.24, 235.48);--fs-warning-100: rgb(253, 235.6, 206.2);--fs-warning-200: rgb(251.4, 220.08, 167.16);--fs-warning-300: rgb(249.4, 200.68, 118.36);--fs-warning-400: rgb(247.2, 179.34, 64.68);--fs-warning-500: #f59e0b;--fs-warning-600: rgb(208.2, 136.4, 15.96);--fs-warning-700: rgb(166.8, 112.1, 21.54);--fs-warning-800: rgb(120.8, 85.1, 27.74);--fs-warning-900: rgb(79.4, 60.8, 33.32);--fs-danger-50: rgb(254.12, 239.64, 242.12);--fs-danger-100: rgb(252.8, 216.6, 222.8);--fs-danger-200: rgb(251.04, 185.88, 197.04);--fs-danger-300: rgb(248.84, 147.48, 164.84);--fs-danger-400: rgb(246.42, 105.24, 129.42);--fs-danger-500: #f43f5e;--fs-danger-600: rgb(207.36, 56.6, 85.68);--fs-danger-700: rgb(166.14, 49.4, 76.32);--fs-danger-800: rgb(120.34, 41.4, 65.92);--fs-danger-900: rgb(79.12, 34.2, 56.56);--fs-primary-muted: var(--fs-primary-900);--fs-primary-subtle: var(--fs-primary-800);--fs-primary-tint: var(--fs-primary-700);--fs-primary-light: var(--fs-primary-600);--fs-primary-soft: var(--fs-primary-400);--fs-primary-base: var(--fs-primary-500);--fs-primary-hover: var(--fs-primary-400);--fs-primary-active: var(--fs-primary-300);--fs-primary-emphasis: var(--fs-primary-200);--fs-primary-contrast: var(--fs-primary-50);--fs-secondary-muted: var(--fs-secondary-900);--fs-secondary-subtle: var(--fs-secondary-800);--fs-secondary-tint: var(--fs-secondary-700);--fs-secondary-light: var(--fs-secondary-600);--fs-secondary-soft: var(--fs-secondary-400);--fs-secondary-base: var(--fs-secondary-500);--fs-secondary-hover: var(--fs-secondary-400);--fs-secondary-active: var(--fs-secondary-300);--fs-secondary-emphasis: var(--fs-secondary-200);--fs-secondary-contrast: var(--fs-secondary-50);--fs-tertiary-muted: var(--fs-tertiary-900);--fs-tertiary-subtle: var(--fs-tertiary-800);--fs-tertiary-tint: var(--fs-tertiary-700);--fs-tertiary-light: var(--fs-tertiary-600);--fs-tertiary-soft: var(--fs-tertiary-400);--fs-tertiary-base: var(--fs-tertiary-500);--fs-tertiary-hover: var(--fs-tertiary-400);--fs-tertiary-active: var(--fs-tertiary-300);--fs-tertiary-emphasis: var(--fs-tertiary-200);--fs-tertiary-contrast: var(--fs-tertiary-50);--fs-neutral-muted: var(--fs-neutral-900);--fs-neutral-subtle: var(--fs-neutral-800);--fs-neutral-base: var(--fs-neutral-500);--fs-neutral-hover: var(--fs-neutral-400);--fs-neutral-active: var(--fs-neutral-300);--fs-neutral-contrast: var(--fs-neutral-50);--fs-danger-muted: var(--fs-danger-900);--fs-danger-base: var(--fs-danger-500);--fs-danger-hover: var(--fs-danger-400);--fs-danger-contrast: var(--fs-danger-50);--fs-success-muted: var(--fs-success-900);--fs-success-base: var(--fs-success-500);--fs-success-hover: var(--fs-success-400);--fs-success-contrast: var(--fs-success-50);--fs-warning-muted: var(--fs-warning-900);--fs-warning-base: var(--fs-warning-500);--fs-warning-hover: var(--fs-warning-400);--fs-warning-contrast: var(--fs-warning-50)}}.fs-profile{--fs-profile-bg: #0d1117;--fs-profile-border: rgba(255, 255, 255, .08);--fs-profile-banner-from: #1e3a5f;--fs-profile-banner-to: #0f2035;--fs-profile-avatar-bg: #1d3557;--fs-profile-avatar-color: #60a5fa;--fs-profile-avatar-border: #0d1117;--fs-profile-name: #ffffff;--fs-profile-handle: rgba(255, 255, 255, .35);--fs-profile-role: rgba(255, 255, 255, .5);--fs-profile-link: #60a5fa;--fs-profile-stat-value: #ffffff;--fs-profile-stat-label: rgba(255, 255, 255, .3);--fs-profile-stats-border: rgba(255, 255, 255, .06);--fs-profile-divider: rgba(255, 255, 255, .06);--fs-profile-radius: 12px;background:var(--fs-profile-bg);border:.5px solid var(--fs-profile-border);border-radius:var(--fs-profile-radius);overflow:hidden;width:100%}.fs-profile__banner{height:180px;position:relative;overflow:hidden}.fs-profile__banner-img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}.fs-profile__banner-gradient{width:100%;height:100%;background:linear-gradient(135deg,var(--fs-profile-banner-from) 0%,var(--fs-profile-banner-to) 100%)}.fs-profile__banner-line{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--fs-primary-base) 0%,var(--fs-tertiary-base) 100%)}.fs-profile__body{padding:.75rem 1.5rem 1.5rem}.fs-profile__avatar-wrap{position:relative;width:fit-content;margin-top:-60px;margin-bottom:1rem}.fs-profile__avatar{width:120px;height:120px;border-radius:9999px;background:var(--fs-profile-avatar-bg);border:3px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center;overflow:hidden}.fs-profile__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.fs-profile__avatar-initials{font-size:34px;font-weight:700;color:var(--fs-profile-avatar-color);font-family:Inter,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.fs-profile__verified{position:absolute;bottom:2px;right:0;width:30px;height:30px;border-radius:9999px;background:var(--fs-primary-base);border:2px solid var(--fs-profile-avatar-border);display:flex;align-items:center;justify-content:center}.fs-profile__name{font-size:1.25rem;font-weight:600;color:var(--fs-profile-name);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.25rem;line-height:1.2}.fs-profile__handle{font-size:.875rem;color:var(--fs-profile-handle);font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:.5rem}.fs-profile__role{font-size:.875rem;font-weight:500;color:var(--fs-profile-role);text-transform:uppercase;letter-spacing:.08em;font-family:Inter,Segoe UI,system-ui,sans-serif;margin-bottom:1rem}.fs-profile__actions{display:flex;gap:.5rem;margin-bottom:1rem}.fs-profile__btn{flex:1;padding:.5rem 0;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:background-color .1s cubic-bezier(.4,0,.2,1),border-color .1s cubic-bezier(.4,0,.2,1),color .1s cubic-bezier(.4,0,.2,1);border:none}.fs-profile__btn--primary{background:var(--fs-primary-base);color:#fff}.fs-profile__btn--primary:hover{background:var(--fs-primary-hover)}.fs-profile__btn--primary:active{background:var(--fs-primary-active)}.fs-profile__btn--outline{background:transparent;color:#ffffffb3;border:.5px solid rgba(255,255,255,.15)}.fs-profile__btn--outline:hover{border-color:#ffffff4d}.fs-profile__btn--outline:active{background:#ffffff0d}.fs-profile__btn:focus-visible{outline:none;box-shadow:0 0 0 2px #fff,0 0 0 4px var(--fs-primary-base)}.fs-profile__links{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.fs-profile__link{display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--fs-profile-link);text-decoration:none;font-family:Inter,Segoe UI,system-ui,sans-serif;transition:opacity .1s cubic-bezier(.4,0,.2,1)}.fs-profile__link svg{opacity:.5;flex-shrink:0;stroke:currentColor}.fs-profile__link:hover{opacity:.75}.fs-profile__link-email{unicode-bidi:bidi-override;direction:rtl}.fs-profile__link-img{width:14px;height:14px;object-fit:contain;display:block;flex-shrink:0;opacity:.6;border-radius:2px}.fs-profile__badges{display:flex;flex-wrap:wrap;gap:.5rem}.fs-profile__stats{border-top:.5px solid var(--fs-profile-stats-border);display:flex}.fs-profile__stat{flex:1;padding:1rem 0;text-align:center;border-right:.5px solid var(--fs-profile-divider);display:flex;flex-direction:column;gap:.25rem}.fs-profile__stat:last-child{border-right:none}.fs-profile__stat-value{font-size:1.25rem;font-weight:600;color:var(--fs-profile-stat-value);font-family:Inter,Segoe UI,system-ui,sans-serif;line-height:1}.fs-profile__stat-label{font-size:.75rem;color:var(--fs-profile-stat-label);font-family:Inter,Segoe UI,system-ui,sans-serif}\n"] }]
524
562
  }], propDecorators: { name: [{
525
563
  type: Input
526
564
  }], handle: [{
@@ -1 +1 @@
1
- {"version":3,"file":"heroelc-fsociety.mjs","sources":["../../../projects/fsociety/src/lib/fsociety.service.ts","../../../projects/fsociety/src/lib/fsociety.component.ts","../../../projects/fsociety/src/lib/button/button.component.ts","../../../projects/fsociety/src/lib/button/button.component.html","../../../projects/fsociety/src/lib/badge/badge.component.ts","../../../projects/fsociety/src/lib/badge/badge.component.html","../../../projects/fsociety/src/lib/tabs/tabs.component.ts","../../../projects/fsociety/src/lib/tabs/tabs.component.html","../../../projects/fsociety/src/lib/alert/alert.component.ts","../../../projects/fsociety/src/lib/alert/alert.component.html","../../../projects/fsociety/src/lib/experience-card/experience-card.component.ts","../../../projects/fsociety/src/lib/experience-card/experience-card.component.html","../../../projects/fsociety/src/lib/profile-card/profile-card.component.ts","../../../projects/fsociety/src/lib/profile-card/profile-card.component.html","../../../projects/fsociety/src/public-api.ts","../../../projects/fsociety/src/heroelc-fsociety.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class FsocietyService {\r\n\r\n constructor() { }\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'fs-fsociety',\r\n imports: [],\r\n template: `\r\n <p>\r\n fsociety works!\r\n </p>\r\n `,\r\n styles: ``\r\n})\r\nexport class FsocietyComponent {\r\n\r\n}\r\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n HostBinding,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'link';\nexport type FsButtonSize = 'sm' | 'md' | 'lg';\nexport type FsButtonType = 'button' | 'submit' | 'reset';\n\n@Component({\n selector: 'fs-button',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsButtonComponent {\n\n /** Variante visual del botón */\n @Input() variant: FsButtonVariant = 'primary';\n\n /** Tamaño del botón */\n @Input() size: FsButtonSize = 'md';\n\n /** Tipo HTML nativo */\n @Input() type: FsButtonType = 'button';\n\n /** Deshabilita el botón */\n @Input() disabled = false;\n\n /** Muestra spinner y deshabilita el botón */\n @Input() loading = false;\n\n /** Texto del botón (alternativa al content projection) */\n @Input() label?: string;\n\n /** Ícono izquierdo — string SVG path o nombre de ícono */\n @Input() iconLeft?: string;\n\n /** Ícono derecho */\n @Input() iconRight?: string;\n\n /** Ancho completo del contenedor */\n @Input() fullWidth = false;\n\n /** Emite el click — no dispara si disabled o loading */\n @Output() fsClick = new EventEmitter<MouseEvent>();\n\n @HostBinding('style.width')\n get hostWidth(): string {\n return this.fullWidth ? '100%' : 'auto';\n }\n\n get isDisabled(): boolean {\n return this.disabled || this.loading;\n }\n\n get classes(): Record<string, boolean> {\n return {\n [`fs-btn--${this.variant}`]: true,\n [`fs-btn--${this.size}`]: true,\n 'fs-btn--loading': this.loading,\n 'fs-btn--disabled': this.isDisabled,\n 'fs-btn--full-width': this.fullWidth,\n };\n }\n\n onClick(event: MouseEvent): void {\n if (this.isDisabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n this.fsClick.emit(event);\n }\n}\n","<button\n class=\"fs-btn\"\n [ngClass]=\"classes\"\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n (click)=\"onClick($event)\"\n>\n <!-- spinner (solo cuando loading) -->\n <span *ngIf=\"loading\" class=\"fs-btn__spinner\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-dasharray=\"28\" stroke-dashoffset=\"10\" />\n </svg>\n </span>\n\n <!-- ícono izquierdo -->\n <span *ngIf=\"iconLeft && !loading\" class=\"fs-btn__icon fs-btn__icon--left\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path [attr.d]=\"iconLeft\" stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n\n <!-- label vía input o content projection -->\n <span class=\"fs-btn__label\">\n <ng-content>{{ label }}</ng-content>\n </span>\n\n <!-- ícono derecho -->\n <span *ngIf=\"iconRight && !loading\" class=\"fs-btn__icon fs-btn__icon--right\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path [attr.d]=\"iconRight\" stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</button>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n OnChanges,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsBadgeColor = 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'neutral';\nexport type FsBadgeVariant = 'filled' | 'outline';\nexport type FsBadgeSize = 'sm' | 'md';\n\n@Component({\n selector: 'fs-badge',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsBadgeComponent implements OnChanges {\n\n /** Color semántico del badge */\n @Input() color: FsBadgeColor = 'neutral';\n\n /**\n * Color personalizado en formato hex.\n * Ejemplo: '#7c3aed'\n * Cuando se provee, tiene prioridad sobre `color` y genera\n * automáticamente el fondo, borde y texto con la opacidad correcta.\n */\n @Input() customColor?: string;\n\n /** Filled = fondo sutil · outline = solo borde */\n @Input() variant: FsBadgeVariant = 'filled';\n\n /** Tamaño */\n @Input() size: FsBadgeSize = 'md';\n\n /** Texto del badge (alternativa al content projection) */\n @Input() label?: string;\n\n /** Muestra punto de estado a la izquierda */\n @Input() dot = false;\n\n /** SVG path del ícono izquierdo (viewBox 0 0 24 24) */\n @Input() iconLeft?: string;\n\n /** SVG path del ícono derecho (viewBox 0 0 24 24) */\n @Input() iconRight?: string;\n\n /**\n * URL o ruta de imagen izquierda.\n * Ejemplo: 'assets/icons/angular.svg' o 'https://cdn.simpleicons.org/angular/white'\n * Tiene prioridad sobre iconLeft si ambos están definidos.\n */\n @Input() imgLeft?: string;\n\n /**\n * URL o ruta de imagen derecha.\n * Tiene prioridad sobre iconRight si ambos están definidos.\n */\n @Input() imgRight?: string;\n\n /** Alt text para imgLeft — por defecto vacío (decorativo) */\n @Input() imgLeftAlt = '';\n\n /** Alt text para imgRight — por defecto vacío (decorativo) */\n @Input() imgRightAlt = '';\n\n /**\n * Modo solo ícono — oculta el label y hace el badge cuadrado/circular.\n * Requiere iconLeft, iconRight, imgLeft o imgRight.\n */\n @Input() iconOnly = false;\n\n /** Badge removible — muestra botón X */\n @Input() removable = false;\n\n /** Emite cuando se clickea el botón remove */\n @Output() removed = new EventEmitter<void>();\n\n // Estilos calculados para customColor\n customStyles: Record<string, string> = {};\n\n ngOnChanges(): void {\n if (this.customColor) {\n this.customStyles = this.buildCustomStyles(this.customColor);\n } else {\n this.customStyles = {};\n }\n }\n\n get classes(): Record<string, boolean> {\n return {\n [`fs-badge--${this.color}`]: !this.customColor,\n [`fs-badge--${this.variant}`]: true,\n [`fs-badge--${this.size}`]: true,\n 'fs-badge--custom': !!this.customColor,\n 'fs-badge--dot': this.dot,\n 'fs-badge--icon-only': this.iconOnly,\n 'fs-badge--removable': this.removable,\n };\n }\n\n onRemove(event: MouseEvent): void {\n event.stopPropagation();\n this.removed.emit();\n }\n\n private buildCustomStyles(hex: string): Record<string, string> {\n // Convertir hex a rgb para poder usar con opacidad\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n if (this.variant === 'outline') {\n return {\n 'background': 'transparent',\n 'color': hex,\n 'border-color': hex,\n };\n }\n\n return {\n 'background': `rgba(${r}, ${g}, ${b}, 0.15)`,\n 'color': this.lightenHex(r, g, b),\n 'border-color': `rgba(${r}, ${g}, ${b}, 0.30)`,\n };\n }\n\n private lightenHex(r: number, g: number, b: number): string {\n // Mezcla con blanco al 60% para el texto\n const mix = (c: number) => Math.round(c + (255 - c) * 0.6);\n return `rgb(${mix(r)}, ${mix(g)}, ${mix(b)})`;\n }\n}\n","<span class=\"fs-badge\" [ngClass]=\"classes\" [ngStyle]=\"customStyles\">\n\n <!-- dot de estado -->\n <span *ngIf=\"dot\" class=\"fs-badge__dot\" aria-hidden=\"true\"></span>\n\n <!-- imagen izquierda (prioridad sobre iconLeft) -->\n <span *ngIf=\"imgLeft\" class=\"fs-badge__icon fs-badge__icon--left\" aria-hidden=\"true\">\n <img [src]=\"imgLeft\" [alt]=\"imgLeftAlt\" class=\"fs-badge__img\" />\n </span>\n\n <!-- ícono izquierdo SVG (solo si no hay imgLeft) -->\n <span *ngIf=\"iconLeft && !imgLeft\" class=\"fs-badge__icon fs-badge__icon--left\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path [attr.d]=\"iconLeft\"/>\n </svg>\n </span>\n\n <!-- label — oculto en iconOnly -->\n <span *ngIf=\"!iconOnly\" class=\"fs-badge__label\">\n <ng-content>{{ label }}</ng-content>\n </span>\n\n <!-- imagen derecha (prioridad sobre iconRight) -->\n <span *ngIf=\"imgRight\" class=\"fs-badge__icon fs-badge__icon--right\" aria-hidden=\"true\">\n <img [src]=\"imgRight\" [alt]=\"imgRightAlt\" class=\"fs-badge__img\" />\n </span>\n\n <!-- ícono derecho SVG (solo si no hay imgRight) -->\n <span *ngIf=\"iconRight && !imgRight\" class=\"fs-badge__icon fs-badge__icon--right\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path [attr.d]=\"iconRight\"/>\n </svg>\n </span>\n\n <!-- botón remove -->\n <button\n *ngIf=\"removable\"\n class=\"fs-badge__remove\"\n type=\"button\"\n aria-label=\"Remover\"\n (click)=\"onRemove($event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 2l6 6M8 2L2 8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n\n</span>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n AfterViewInit,\n OnChanges,\n SimpleChanges,\n ViewChild,\n ElementRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n NgZone,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport interface FsTab {\n /** Identificador único de la tab */\n id: string;\n /** Texto visible en el encabezado */\n label: string;\n /** Deshabilita la tab */\n disabled?: boolean;\n}\n\n@Component({\n selector: 'fs-tabs',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './tabs.component.html',\n styleUrl: './tabs.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsTabsComponent implements AfterViewInit, OnChanges {\n\n /** Lista de tabs a renderizar */\n @Input() tabs: FsTab[] = [];\n\n /** Id de la tab activa */\n @Input() activeTab = '';\n\n /** Two-way binding: [(activeTab)] */\n @Output() activeTabChange = new EventEmitter<string>();\n\n /** Emite la tab completa al cambiar */\n @Output() tabChange = new EventEmitter<FsTab>();\n\n @ViewChild('tabsRow') tabsRow!: ElementRef<HTMLElement>;\n\n indicatorLeft = 0;\n indicatorWidth = 0;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private zone: NgZone,\n ) {}\n\n ngAfterViewInit(): void {\n this.updateIndicator();\n\n // Recalcular al cambiar el tamaño del contenedor\n this.zone.runOutsideAngular(() => {\n const ro = new ResizeObserver(() => {\n this.zone.run(() => {\n this.updateIndicator();\n this.cdr.markForCheck();\n });\n });\n ro.observe(this.tabsRow.nativeElement);\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['activeTab'] || changes['tabs']) {\n // Defer para que el DOM se actualice primero\n setTimeout(() => this.updateIndicator());\n }\n }\n\n selectTab(tab: FsTab): void {\n if (tab.disabled) return;\n this.activeTab = tab.id;\n this.activeTabChange.emit(tab.id);\n this.tabChange.emit(tab);\n this.updateIndicator();\n }\n\n isActive(tab: FsTab): boolean {\n return this.activeTab === tab.id;\n }\n\n private updateIndicator(): void {\n if (!this.tabsRow) return;\n\n const row = this.tabsRow.nativeElement;\n const items = row.querySelectorAll<HTMLElement>('.fs-tabs__item');\n const idx = this.tabs.findIndex(t => t.id === this.activeTab);\n\n if (idx === -1 || !items[idx]) return;\n\n const item = items[idx];\n this.indicatorLeft = item.offsetLeft;\n this.indicatorWidth = item.offsetWidth;\n this.cdr.markForCheck();\n }\n}\n","<div class=\"fs-tabs\">\n\n <!-- encabezado -->\n <div class=\"fs-tabs__header\" #tabsRow role=\"tablist\">\n\n <button\n *ngFor=\"let tab of tabs\"\n class=\"fs-tabs__item\"\n [class.fs-tabs__item--active]=\"isActive(tab)\"\n [class.fs-tabs__item--disabled]=\"tab.disabled\"\n role=\"tab\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-disabled]=\"tab.disabled\"\n [disabled]=\"tab.disabled\"\n (click)=\"selectTab(tab)\"\n >\n {{ tab.label }}\n </button>\n\n <!-- indicator deslizante -->\n <span\n class=\"fs-tabs__indicator\"\n [style.left.px]=\"indicatorLeft\"\n [style.width.px]=\"indicatorWidth\"\n aria-hidden=\"true\"\n ></span>\n\n </div>\n\n <!-- contenido vía content projection -->\n <div class=\"fs-tabs__content\" role=\"tabpanel\">\n <ng-content></ng-content>\n </div>\n\n</div>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsAlertType = 'info' | 'success' | 'warning' | 'danger' | 'neutral';\nexport type FsAlertVariant = 'filled' | 'accent';\n\n@Component({\n selector: 'fs-alert',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './alert.component.html',\n styleUrl: './alert.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsAlertComponent implements OnInit, OnDestroy {\n\n /** Tipo semántico del alert */\n @Input() type: FsAlertType = 'info';\n\n /** filled = fondo sutil · accent = borde izquierdo */\n @Input() variant: FsAlertVariant = 'filled';\n\n /** Título opcional en negrita */\n @Input() title?: string;\n\n /** Muestra botón X para cerrar */\n @Input() dismissible = false;\n\n /**\n * Auto-cierre en milisegundos.\n * 0 = deshabilitado.\n * Muestra progress bar cuando está activo.\n */\n @Input() autoDismiss = 0;\n\n /** Emite cuando el alert se cierra (botón X o auto-dismiss) */\n @Output() dismissed = new EventEmitter<void>();\n\n // Estado interno de animación\n animState: 'entering' | 'visible' | 'exiting' = 'entering';\n\n private autoTimer?: ReturnType<typeof setTimeout>;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnInit(): void {\n // tras la animación de entrada → visible\n setTimeout(() => {\n this.animState = 'visible';\n this.cdr.markForCheck();\n }, 300);\n\n if (this.autoDismiss > 0) {\n this.autoTimer = setTimeout(() => this.dismiss(), this.autoDismiss);\n }\n }\n\n ngOnDestroy(): void {\n if (this.autoTimer) clearTimeout(this.autoTimer);\n }\n\n dismiss(): void {\n if (this.animState === 'exiting') return;\n this.animState = 'exiting';\n this.cdr.markForCheck();\n\n // esperar la animación de salida antes de emitir\n setTimeout(() => {\n this.dismissed.emit();\n }, 240);\n }\n\n get progressDuration(): string {\n return `${this.autoDismiss}ms`;\n }\n\n get iconPath(): string {\n const icons: Record<FsAlertType, string> = {\n info: 'M8 7v4M8 5.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n success: 'M5 8l2 2 4-4M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n warning: 'M8 2L2 13h12L8 2zM8 7v3M8 11.5v.01',\n danger: 'M8 5v4M8 10.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n neutral: 'M8 7v4M8 5.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n };\n return icons[this.type];\n }\n}\n","<div\n *ngIf=\"animState !== 'exiting' || true\"\n class=\"fs-alert\"\n [class.fs-alert--entering]=\"animState === 'entering'\"\n [class.fs-alert--visible]=\"animState === 'visible'\"\n [class.fs-alert--exiting]=\"animState === 'exiting'\"\n [class]=\"'fs-alert fs-alert--' + type + ' fs-alert--' + variant\"\n [attr.role]=\"type === 'danger' ? 'alert' : 'status'\"\n [attr.aria-live]=\"type === 'danger' ? 'assertive' : 'polite'\"\n>\n\n <!-- ícono semántico -->\n <svg\n class=\"fs-alert__icon\"\n width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n [attr.d]=\"iconPath\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n\n <!-- cuerpo -->\n <div class=\"fs-alert__body\">\n <div *ngIf=\"title\" class=\"fs-alert__title\">{{ title }}</div>\n <div class=\"fs-alert__desc\">\n <ng-content></ng-content>\n </div>\n </div>\n\n <!-- botón cerrar -->\n <button\n *ngIf=\"dismissible\"\n class=\"fs-alert__close\"\n type=\"button\"\n aria-label=\"Cerrar\"\n (click)=\"dismiss()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M3 3l8 8M11 3L3 11\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n\n <!-- progress bar de auto-dismiss -->\n <div\n *ngIf=\"autoDismiss > 0\"\n class=\"fs-alert__progress\"\n [style.animation-duration]=\"progressDuration\"\n ></div>\n\n</div>\n","import {\n Component,\n Input,\n OnInit,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FsBadgeComponent, FsBadgeColor } from '../badge/badge.component';\n\nexport interface FsExperienceBadge {\n label: string;\n color?: FsBadgeColor;\n customColor?: string;\n iconLeft?: string;\n imgLeft?: string;\n imgLeftAlt?: string;\n}\n\nexport interface FsExperienceCard {\n /** Nombre de la empresa */\n company: string;\n\n /** Rol / puesto */\n role: string;\n\n /** Fecha de inicio — formato libre: 'abr 2022' */\n startDate: string;\n\n /** Fecha de fin — omitir si es trabajo actual */\n endDate?: string;\n\n /** Marca el trabajo como actual — muestra dot verde y \"actualidad\" */\n current?: boolean;\n\n /** Logo de la empresa — URL de imagen */\n logoUrl?: string;\n\n /** Texto corto para el logo cuando no hay imagen: 'X CALE' */\n logoText?: string;\n\n /** Lista de responsabilidades / bullets */\n bullets?: string[];\n\n /** Cuántos bullets mostrar antes del \"ver más\" */\n bulletsPreview?: number;\n\n /** Badges de tecnologías */\n badges?: FsExperienceBadge[];\n}\n\n@Component({\n selector: 'fs-experience-card',\n standalone: true,\n imports: [CommonModule, FsBadgeComponent],\n templateUrl: './experience-card.component.html',\n styleUrl: './experience-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsExperienceCardComponent implements OnInit {\n\n /** Datos de la experiencia */\n @Input() experience!: FsExperienceCard;\n\n /** Variante de presentación */\n @Input() variant: 'full' | 'compact' = 'full';\n\n /** Muestra la línea vertical de timeline a la izquierda */\n @Input() timeline = false;\n\n /** Si es el último item del timeline (no dibuja la línea hacia abajo) */\n @Input() timelineLast = false;\n\n expanded = false;\n\n get hasBullets(): boolean {\n return !!(this.experience?.bullets?.length);\n }\n\n get visibleBullets(): string[] {\n if (!this.experience?.bullets) return [];\n const preview = this.experience.bulletsPreview ?? 3;\n return this.expanded\n ? this.experience.bullets\n : this.experience.bullets.slice(0, preview);\n }\n\n get hasMoreBullets(): boolean {\n if (!this.experience?.bullets) return false;\n const preview = this.experience.bulletsPreview ?? 3;\n return this.experience.bullets.length > preview;\n }\n\n get duration(): string {\n return this.calculateDuration();\n }\n\n get isCurrent(): boolean {\n return this.experience?.current ?? false;\n }\n\n ngOnInit(): void {\n this.expanded = false;\n }\n\n toggleExpand(): void {\n this.expanded = !this.expanded;\n }\n\n private calculateDuration(): string {\n if (!this.experience?.startDate) return '';\n\n const start = this.parseDate(this.experience.startDate);\n const end = this.experience.current || !this.experience.endDate\n ? new Date()\n : this.parseDate(this.experience.endDate);\n\n if (!start || !end) return '';\n\n let months = (end.getFullYear() - start.getFullYear()) * 12\n + (end.getMonth() - start.getMonth());\n\n const years = Math.floor(months / 12);\n const remain = months % 12;\n\n const parts: string[] = [];\n if (years > 0) parts.push(`${years} ${years === 1 ? 'año' : 'años'}`);\n if (remain > 0) parts.push(`${remain} ${remain === 1 ? 'mes' : 'meses'}`);\n\n return parts.join(' ');\n }\n\n private parseDate(dateStr: string): Date | null {\n const months: Record<string, number> = {\n ene: 0, feb: 1, mar: 2, abr: 3, may: 4, jun: 5,\n jul: 6, ago: 7, sep: 8, oct: 9, nov: 10, dic: 11,\n };\n\n const parts = dateStr.trim().toLowerCase().split(' ');\n if (parts.length === 2) {\n const month = months[parts[0]];\n const year = parseInt(parts[1], 10);\n if (month !== undefined && !isNaN(year)) {\n return new Date(year, month, 1);\n }\n }\n\n // fallback: intentar parsear como fecha estándar\n const d = new Date(dateStr);\n return isNaN(d.getTime()) ? null : d;\n }\n}\n","<div\n class=\"fs-exp\"\n [class.fs-exp--compact]=\"variant === 'compact'\"\n [class.fs-exp--timeline]=\"timeline\"\n [class.fs-exp--timeline-last]=\"timeline && timelineLast\"\n>\n\n <!-- línea vertical de timeline -->\n <div *ngIf=\"timeline\" class=\"fs-exp__timeline-line\"></div>\n\n <!-- dot del timeline -->\n <div *ngIf=\"timeline\" class=\"fs-exp__timeline-dot\"\n [class.fs-exp__timeline-dot--current]=\"isCurrent\">\n </div>\n\n <!-- card -->\n <div class=\"fs-exp__card\">\n\n <!-- header -->\n <div class=\"fs-exp__header\">\n\n <!-- logo -->\n <div class=\"fs-exp__logo\">\n <img\n *ngIf=\"experience.logoUrl\"\n [src]=\"experience.logoUrl\"\n [alt]=\"experience.company\"\n class=\"fs-exp__logo-img\"\n />\n <span *ngIf=\"!experience.logoUrl\" class=\"fs-exp__logo-text\">\n {{ experience.logoText || experience.company.slice(0, 4).toUpperCase() }}\n </span>\n </div>\n\n <!-- info -->\n <div class=\"fs-exp__info\">\n <div class=\"fs-exp__company\">{{ experience.company }}</div>\n <div class=\"fs-exp__role\">{{ experience.role }}</div>\n <div class=\"fs-exp__date\">\n <span\n class=\"fs-exp__dot\"\n [class.fs-exp__dot--current]=\"isCurrent\"\n ></span>\n <span>\n {{ experience.startDate }} –\n {{ experience.current ? 'actualidad' : experience.endDate }}\n </span>\n <span *ngIf=\"duration\" class=\"fs-exp__duration\">\n · {{ duration }}\n </span>\n </div>\n </div>\n\n </div>\n\n <!-- cuerpo — solo en variante full -->\n <ng-container *ngIf=\"variant === 'full'\">\n\n <div *ngIf=\"hasBullets || experience.badges?.length\" class=\"fs-exp__divider\"></div>\n\n <!-- bullets -->\n <ul *ngIf=\"hasBullets\" class=\"fs-exp__bullets\">\n <li *ngFor=\"let bullet of visibleBullets\" class=\"fs-exp__bullet\">\n <span class=\"fs-exp__bullet-arrow\" aria-hidden=\"true\">▸</span>\n <span>{{ bullet }}</span>\n </li>\n </ul>\n\n <!-- toggle ver más / menos -->\n <button\n *ngIf=\"hasMoreBullets\"\n class=\"fs-exp__toggle\"\n type=\"button\"\n (click)=\"toggleExpand()\"\n >\n <svg\n class=\"fs-exp__toggle-icon\"\n [class.fs-exp__toggle-icon--open]=\"expanded\"\n width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"\n >\n <path d=\"M3 4.5l3 3 3-3\"\n stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n {{ expanded ? 'ver menos' : 'ver más' }}\n </button>\n\n <!-- badges -->\n <div *ngIf=\"experience.badges?.length\" class=\"fs-exp__badges\">\n <fs-badge\n *ngFor=\"let badge of experience.badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </ng-container>\n\n </div>\n</div>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FsBadgeComponent, FsBadgeColor } from '../badge/badge.component';\n\nexport interface FsProfileStat {\n value: string | number;\n label: string;\n}\n\nexport interface FsProfileLink {\n /** Texto visible */\n label: string;\n /** URL destino */\n url?: string;\n /** SVG path del ícono (viewBox 0 0 16 16) — se ignora si hay imgUrl */\n icon?: string;\n /**\n * URL o ruta de imagen para el ícono del link.\n * Ejemplo: 'https://cdn.simpleicons.org/linkedin/white'\n * Tiene prioridad sobre icon si ambos están definidos.\n */\n imgUrl?: string;\n /** Alt text para imgUrl — por defecto vacío (decorativo) */\n imgAlt?: string;\n}\n\nexport interface FsProfileBadge {\n label: string;\n color?: FsBadgeColor;\n customColor?: string;\n iconLeft?: string;\n imgLeft?: string;\n imgLeftAlt?: string;\n}\n\n@Component({\n selector: 'fs-profile-card',\n standalone: true,\n imports: [CommonModule, FsBadgeComponent],\n templateUrl: './profile-card.component.html',\n styleUrl: './profile-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsProfileCardComponent {\n\n @Input() name = '';\n @Input() handle = '';\n @Input() role = '';\n @Input() verified = false;\n @Input() avatarUrl?: string;\n @Input() bannerUrl?: string;\n @Input() links: FsProfileLink[] = [];\n @Input() badges: FsProfileBadge[] = [];\n @Input() stats: FsProfileStat[] = [];\n @Input() showActions = false;\n @Input() primaryActionLabel = 'Seguir';\n @Input() secondaryActionLabel = 'Mensaje';\n\n @Output() primaryAction = new EventEmitter<void>();\n @Output() secondaryAction = new EventEmitter<void>();\n\n get initials(): string {\n return this.name\n .split(' ')\n .slice(0, 2)\n .map(w => w[0])\n .join('')\n .toUpperCase();\n }\n}\n","<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"link.url || '#'\"\n [attr.target]=\"link.url ? '_blank' : null\"\n [attr.rel]=\"link.url ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- ícono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ link.label }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n","/*\r\n * Public API Surface of fsociety\r\n */\r\n\r\nexport * from './lib/fsociety.service';\r\nexport * from './lib/fsociety.component';\r\n\r\nexport * from './lib/button/button.component';\r\nexport type { FsButtonVariant, FsButtonSize, FsButtonType } from './lib/button/button.component';\r\n\r\nexport * from './lib/badge/badge.component';\r\nexport type { FsBadgeColor, FsBadgeVariant, FsBadgeSize } from './lib/badge/badge.component';\r\n\r\nexport * from './lib/tabs/tabs.component';\r\nexport type { FsTab } from './lib/tabs/tabs.component';\r\n\r\nexport * from './lib/alert/alert.component';\r\nexport type { FsAlertType, FsAlertVariant } from './lib/alert/alert.component';\r\n\r\nexport * from './lib/experience-card/experience-card.component';\r\nexport type { FsExperienceCard, FsExperienceBadge } from './lib/experience-card/experience-card.component';\r\n\r\nexport * from './lib/profile-card/profile-card.component';\r\nexport type { FsProfileStat, FsProfileLink, FsProfileBadge } from './lib/profile-card/profile-card.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heroelc-fsociety.mjs","sources":["../../../projects/fsociety/src/lib/fsociety.service.ts","../../../projects/fsociety/src/lib/fsociety.component.ts","../../../projects/fsociety/src/lib/button/button.component.ts","../../../projects/fsociety/src/lib/button/button.component.html","../../../projects/fsociety/src/lib/badge/badge.component.ts","../../../projects/fsociety/src/lib/badge/badge.component.html","../../../projects/fsociety/src/lib/tabs/tabs.component.ts","../../../projects/fsociety/src/lib/tabs/tabs.component.html","../../../projects/fsociety/src/lib/alert/alert.component.ts","../../../projects/fsociety/src/lib/alert/alert.component.html","../../../projects/fsociety/src/lib/experience-card/experience-card.component.ts","../../../projects/fsociety/src/lib/experience-card/experience-card.component.html","../../../projects/fsociety/src/lib/profile-card/profile-card.component.ts","../../../projects/fsociety/src/lib/profile-card/profile-card.component.html","../../../projects/fsociety/src/public-api.ts","../../../projects/fsociety/src/heroelc-fsociety.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class FsocietyService {\r\n\r\n constructor() { }\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'fs-fsociety',\r\n imports: [],\r\n template: `\r\n <p>\r\n fsociety works!\r\n </p>\r\n `,\r\n styles: ``\r\n})\r\nexport class FsocietyComponent {\r\n\r\n}\r\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n HostBinding,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'link';\nexport type FsButtonSize = 'sm' | 'md' | 'lg';\nexport type FsButtonType = 'button' | 'submit' | 'reset';\n\n@Component({\n selector: 'fs-button',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsButtonComponent {\n\n /** Variante visual del botón */\n @Input() variant: FsButtonVariant = 'primary';\n\n /** Tamaño del botón */\n @Input() size: FsButtonSize = 'md';\n\n /** Tipo HTML nativo */\n @Input() type: FsButtonType = 'button';\n\n /** Deshabilita el botón */\n @Input() disabled = false;\n\n /** Muestra spinner y deshabilita el botón */\n @Input() loading = false;\n\n /** Texto del botón (alternativa al content projection) */\n @Input() label?: string;\n\n /** Ícono izquierdo — string SVG path o nombre de ícono */\n @Input() iconLeft?: string;\n\n /** Ícono derecho */\n @Input() iconRight?: string;\n\n /** Ancho completo del contenedor */\n @Input() fullWidth = false;\n\n /** Emite el click — no dispara si disabled o loading */\n @Output() fsClick = new EventEmitter<MouseEvent>();\n\n @HostBinding('style.width')\n get hostWidth(): string {\n return this.fullWidth ? '100%' : 'auto';\n }\n\n get isDisabled(): boolean {\n return this.disabled || this.loading;\n }\n\n get classes(): Record<string, boolean> {\n return {\n [`fs-btn--${this.variant}`]: true,\n [`fs-btn--${this.size}`]: true,\n 'fs-btn--loading': this.loading,\n 'fs-btn--disabled': this.isDisabled,\n 'fs-btn--full-width': this.fullWidth,\n };\n }\n\n onClick(event: MouseEvent): void {\n if (this.isDisabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n this.fsClick.emit(event);\n }\n}\n","<button\n class=\"fs-btn\"\n [ngClass]=\"classes\"\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n (click)=\"onClick($event)\"\n>\n <!-- spinner (solo cuando loading) -->\n <span *ngIf=\"loading\" class=\"fs-btn__spinner\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-dasharray=\"28\" stroke-dashoffset=\"10\" />\n </svg>\n </span>\n\n <!-- ícono izquierdo -->\n <span *ngIf=\"iconLeft && !loading\" class=\"fs-btn__icon fs-btn__icon--left\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path [attr.d]=\"iconLeft\" stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n\n <!-- label vía input o content projection -->\n <span class=\"fs-btn__label\">\n <ng-content>{{ label }}</ng-content>\n </span>\n\n <!-- ícono derecho -->\n <span *ngIf=\"iconRight && !loading\" class=\"fs-btn__icon fs-btn__icon--right\" aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path [attr.d]=\"iconRight\" stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</button>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n OnChanges,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsBadgeColor = 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'neutral';\nexport type FsBadgeVariant = 'filled' | 'outline';\nexport type FsBadgeSize = 'sm' | 'md';\n\n@Component({\n selector: 'fs-badge',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsBadgeComponent implements OnChanges {\n\n /** Color semántico del badge */\n @Input() color: FsBadgeColor = 'neutral';\n\n /**\n * Color personalizado en formato hex.\n * Ejemplo: '#7c3aed'\n * Cuando se provee, tiene prioridad sobre `color` y genera\n * automáticamente el fondo, borde y texto con la opacidad correcta.\n */\n @Input() customColor?: string;\n\n /** Filled = fondo sutil · outline = solo borde */\n @Input() variant: FsBadgeVariant = 'filled';\n\n /** Tamaño */\n @Input() size: FsBadgeSize = 'md';\n\n /** Texto del badge (alternativa al content projection) */\n @Input() label?: string;\n\n /** Muestra punto de estado a la izquierda */\n @Input() dot = false;\n\n /** SVG path del ícono izquierdo (viewBox 0 0 24 24) */\n @Input() iconLeft?: string;\n\n /** SVG path del ícono derecho (viewBox 0 0 24 24) */\n @Input() iconRight?: string;\n\n /**\n * URL o ruta de imagen izquierda.\n * Ejemplo: 'assets/icons/angular.svg' o 'https://cdn.simpleicons.org/angular/white'\n * Tiene prioridad sobre iconLeft si ambos están definidos.\n */\n @Input() imgLeft?: string;\n\n /**\n * URL o ruta de imagen derecha.\n * Tiene prioridad sobre iconRight si ambos están definidos.\n */\n @Input() imgRight?: string;\n\n /** Alt text para imgLeft — por defecto vacío (decorativo) */\n @Input() imgLeftAlt = '';\n\n /** Alt text para imgRight — por defecto vacío (decorativo) */\n @Input() imgRightAlt = '';\n\n /**\n * Modo solo ícono — oculta el label y hace el badge cuadrado/circular.\n * Requiere iconLeft, iconRight, imgLeft o imgRight.\n */\n @Input() iconOnly = false;\n\n /** Badge removible — muestra botón X */\n @Input() removable = false;\n\n /** Emite cuando se clickea el botón remove */\n @Output() removed = new EventEmitter<void>();\n\n // Estilos calculados para customColor\n customStyles: Record<string, string> = {};\n\n ngOnChanges(): void {\n if (this.customColor) {\n this.customStyles = this.buildCustomStyles(this.customColor);\n } else {\n this.customStyles = {};\n }\n }\n\n get classes(): Record<string, boolean> {\n return {\n [`fs-badge--${this.color}`]: !this.customColor,\n [`fs-badge--${this.variant}`]: true,\n [`fs-badge--${this.size}`]: true,\n 'fs-badge--custom': !!this.customColor,\n 'fs-badge--dot': this.dot,\n 'fs-badge--icon-only': this.iconOnly,\n 'fs-badge--removable': this.removable,\n };\n }\n\n onRemove(event: MouseEvent): void {\n event.stopPropagation();\n this.removed.emit();\n }\n\n private buildCustomStyles(hex: string): Record<string, string> {\n // Convertir hex a rgb para poder usar con opacidad\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n if (this.variant === 'outline') {\n return {\n 'background': 'transparent',\n 'color': hex,\n 'border-color': hex,\n };\n }\n\n return {\n 'background': `rgba(${r}, ${g}, ${b}, 0.15)`,\n 'color': this.lightenHex(r, g, b),\n 'border-color': `rgba(${r}, ${g}, ${b}, 0.30)`,\n };\n }\n\n private lightenHex(r: number, g: number, b: number): string {\n // Mezcla con blanco al 60% para el texto\n const mix = (c: number) => Math.round(c + (255 - c) * 0.6);\n return `rgb(${mix(r)}, ${mix(g)}, ${mix(b)})`;\n }\n}\n","<span class=\"fs-badge\" [ngClass]=\"classes\" [ngStyle]=\"customStyles\">\n\n <!-- dot de estado -->\n <span *ngIf=\"dot\" class=\"fs-badge__dot\" aria-hidden=\"true\"></span>\n\n <!-- imagen izquierda (prioridad sobre iconLeft) -->\n <span *ngIf=\"imgLeft\" class=\"fs-badge__icon fs-badge__icon--left\" aria-hidden=\"true\">\n <img [src]=\"imgLeft\" [alt]=\"imgLeftAlt\" class=\"fs-badge__img\" />\n </span>\n\n <!-- ícono izquierdo SVG (solo si no hay imgLeft) -->\n <span *ngIf=\"iconLeft && !imgLeft\" class=\"fs-badge__icon fs-badge__icon--left\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path [attr.d]=\"iconLeft\"/>\n </svg>\n </span>\n\n <!-- label — oculto en iconOnly -->\n <span *ngIf=\"!iconOnly\" class=\"fs-badge__label\">\n <ng-content>{{ label }}</ng-content>\n </span>\n\n <!-- imagen derecha (prioridad sobre iconRight) -->\n <span *ngIf=\"imgRight\" class=\"fs-badge__icon fs-badge__icon--right\" aria-hidden=\"true\">\n <img [src]=\"imgRight\" [alt]=\"imgRightAlt\" class=\"fs-badge__img\" />\n </span>\n\n <!-- ícono derecho SVG (solo si no hay imgRight) -->\n <span *ngIf=\"iconRight && !imgRight\" class=\"fs-badge__icon fs-badge__icon--right\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path [attr.d]=\"iconRight\"/>\n </svg>\n </span>\n\n <!-- botón remove -->\n <button\n *ngIf=\"removable\"\n class=\"fs-badge__remove\"\n type=\"button\"\n aria-label=\"Remover\"\n (click)=\"onRemove($event)\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 2l6 6M8 2L2 8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n\n</span>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n AfterViewInit,\n OnChanges,\n SimpleChanges,\n ViewChild,\n ElementRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n NgZone,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport interface FsTab {\n /** Identificador único de la tab */\n id: string;\n /** Texto visible en el encabezado */\n label: string;\n /** Deshabilita la tab */\n disabled?: boolean;\n}\n\n@Component({\n selector: 'fs-tabs',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './tabs.component.html',\n styleUrl: './tabs.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsTabsComponent implements AfterViewInit, OnChanges {\n\n /** Lista de tabs a renderizar */\n @Input() tabs: FsTab[] = [];\n\n /** Id de la tab activa */\n @Input() activeTab = '';\n\n /** Two-way binding: [(activeTab)] */\n @Output() activeTabChange = new EventEmitter<string>();\n\n /** Emite la tab completa al cambiar */\n @Output() tabChange = new EventEmitter<FsTab>();\n\n @ViewChild('tabsRow') tabsRow!: ElementRef<HTMLElement>;\n\n indicatorLeft = 0;\n indicatorWidth = 0;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private zone: NgZone,\n ) {}\n\n ngAfterViewInit(): void {\n this.updateIndicator();\n\n // Recalcular al cambiar el tamaño del contenedor\n this.zone.runOutsideAngular(() => {\n const ro = new ResizeObserver(() => {\n this.zone.run(() => {\n this.updateIndicator();\n this.cdr.markForCheck();\n });\n });\n ro.observe(this.tabsRow.nativeElement);\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['activeTab'] || changes['tabs']) {\n // Defer para que el DOM se actualice primero\n setTimeout(() => this.updateIndicator());\n }\n }\n\n selectTab(tab: FsTab): void {\n if (tab.disabled) return;\n this.activeTab = tab.id;\n this.activeTabChange.emit(tab.id);\n this.tabChange.emit(tab);\n this.updateIndicator();\n }\n\n isActive(tab: FsTab): boolean {\n return this.activeTab === tab.id;\n }\n\n private updateIndicator(): void {\n if (!this.tabsRow) return;\n\n const row = this.tabsRow.nativeElement;\n const items = row.querySelectorAll<HTMLElement>('.fs-tabs__item');\n const idx = this.tabs.findIndex(t => t.id === this.activeTab);\n\n if (idx === -1 || !items[idx]) return;\n\n const item = items[idx];\n this.indicatorLeft = item.offsetLeft;\n this.indicatorWidth = item.offsetWidth;\n this.cdr.markForCheck();\n }\n}\n","<div class=\"fs-tabs\">\n\n <!-- encabezado -->\n <div class=\"fs-tabs__header\" #tabsRow role=\"tablist\">\n\n <button\n *ngFor=\"let tab of tabs\"\n class=\"fs-tabs__item\"\n [class.fs-tabs__item--active]=\"isActive(tab)\"\n [class.fs-tabs__item--disabled]=\"tab.disabled\"\n role=\"tab\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-disabled]=\"tab.disabled\"\n [disabled]=\"tab.disabled\"\n (click)=\"selectTab(tab)\"\n >\n {{ tab.label }}\n </button>\n\n <!-- indicator deslizante -->\n <span\n class=\"fs-tabs__indicator\"\n [style.left.px]=\"indicatorLeft\"\n [style.width.px]=\"indicatorWidth\"\n aria-hidden=\"true\"\n ></span>\n\n </div>\n\n <!-- contenido vía content projection -->\n <div class=\"fs-tabs__content\" role=\"tabpanel\">\n <ng-content></ng-content>\n </div>\n\n</div>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport type FsAlertType = 'info' | 'success' | 'warning' | 'danger' | 'neutral';\nexport type FsAlertVariant = 'filled' | 'accent';\n\n@Component({\n selector: 'fs-alert',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './alert.component.html',\n styleUrl: './alert.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsAlertComponent implements OnInit, OnDestroy {\n\n /** Tipo semántico del alert */\n @Input() type: FsAlertType = 'info';\n\n /** filled = fondo sutil · accent = borde izquierdo */\n @Input() variant: FsAlertVariant = 'filled';\n\n /** Título opcional en negrita */\n @Input() title?: string;\n\n /** Muestra botón X para cerrar */\n @Input() dismissible = false;\n\n /**\n * Auto-cierre en milisegundos.\n * 0 = deshabilitado.\n * Muestra progress bar cuando está activo.\n */\n @Input() autoDismiss = 0;\n\n /** Emite cuando el alert se cierra (botón X o auto-dismiss) */\n @Output() dismissed = new EventEmitter<void>();\n\n // Estado interno de animación\n animState: 'entering' | 'visible' | 'exiting' = 'entering';\n\n private autoTimer?: ReturnType<typeof setTimeout>;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnInit(): void {\n // tras la animación de entrada → visible\n setTimeout(() => {\n this.animState = 'visible';\n this.cdr.markForCheck();\n }, 300);\n\n if (this.autoDismiss > 0) {\n this.autoTimer = setTimeout(() => this.dismiss(), this.autoDismiss);\n }\n }\n\n ngOnDestroy(): void {\n if (this.autoTimer) clearTimeout(this.autoTimer);\n }\n\n dismiss(): void {\n if (this.animState === 'exiting') return;\n this.animState = 'exiting';\n this.cdr.markForCheck();\n\n // esperar la animación de salida antes de emitir\n setTimeout(() => {\n this.dismissed.emit();\n }, 240);\n }\n\n get progressDuration(): string {\n return `${this.autoDismiss}ms`;\n }\n\n get iconPath(): string {\n const icons: Record<FsAlertType, string> = {\n info: 'M8 7v4M8 5.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n success: 'M5 8l2 2 4-4M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n warning: 'M8 2L2 13h12L8 2zM8 7v3M8 11.5v.01',\n danger: 'M8 5v4M8 10.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n neutral: 'M8 7v4M8 5.5v.01M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z',\n };\n return icons[this.type];\n }\n}\n","<div\n *ngIf=\"animState !== 'exiting' || true\"\n class=\"fs-alert\"\n [class.fs-alert--entering]=\"animState === 'entering'\"\n [class.fs-alert--visible]=\"animState === 'visible'\"\n [class.fs-alert--exiting]=\"animState === 'exiting'\"\n [class]=\"'fs-alert fs-alert--' + type + ' fs-alert--' + variant\"\n [attr.role]=\"type === 'danger' ? 'alert' : 'status'\"\n [attr.aria-live]=\"type === 'danger' ? 'assertive' : 'polite'\"\n>\n\n <!-- ícono semántico -->\n <svg\n class=\"fs-alert__icon\"\n width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n [attr.d]=\"iconPath\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n\n <!-- cuerpo -->\n <div class=\"fs-alert__body\">\n <div *ngIf=\"title\" class=\"fs-alert__title\">{{ title }}</div>\n <div class=\"fs-alert__desc\">\n <ng-content></ng-content>\n </div>\n </div>\n\n <!-- botón cerrar -->\n <button\n *ngIf=\"dismissible\"\n class=\"fs-alert__close\"\n type=\"button\"\n aria-label=\"Cerrar\"\n (click)=\"dismiss()\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M3 3l8 8M11 3L3 11\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n\n <!-- progress bar de auto-dismiss -->\n <div\n *ngIf=\"autoDismiss > 0\"\n class=\"fs-alert__progress\"\n [style.animation-duration]=\"progressDuration\"\n ></div>\n\n</div>\n","import {\n Component,\n Input,\n OnInit,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FsBadgeComponent, FsBadgeColor } from '../badge/badge.component';\n\nexport interface FsExperienceBadge {\n label: string;\n color?: FsBadgeColor;\n customColor?: string;\n iconLeft?: string;\n imgLeft?: string;\n imgLeftAlt?: string;\n}\n\nexport interface FsExperienceCard {\n /** Nombre de la empresa */\n company: string;\n\n /** Rol / puesto */\n role: string;\n\n /** Fecha de inicio — formato libre: 'abr 2022' */\n startDate: string;\n\n /** Fecha de fin — omitir si es trabajo actual */\n endDate?: string;\n\n /** Marca el trabajo como actual — muestra dot verde y \"actualidad\" */\n current?: boolean;\n\n /** Logo de la empresa — URL de imagen */\n logoUrl?: string;\n\n /** Texto corto para el logo cuando no hay imagen: 'X CALE' */\n logoText?: string;\n\n /** Lista de responsabilidades / bullets */\n bullets?: string[];\n\n /** Cuántos bullets mostrar antes del \"ver más\" */\n bulletsPreview?: number;\n\n /** Badges de tecnologías */\n badges?: FsExperienceBadge[];\n}\n\n@Component({\n selector: 'fs-experience-card',\n standalone: true,\n imports: [CommonModule, FsBadgeComponent],\n templateUrl: './experience-card.component.html',\n styleUrl: './experience-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsExperienceCardComponent implements OnInit {\n\n /** Datos de la experiencia */\n @Input() experience!: FsExperienceCard;\n\n /** Variante de presentación */\n @Input() variant: 'full' | 'compact' = 'full';\n\n /** Muestra la línea vertical de timeline a la izquierda */\n @Input() timeline = false;\n\n /** Si es el último item del timeline (no dibuja la línea hacia abajo) */\n @Input() timelineLast = false;\n\n expanded = false;\n\n get hasBullets(): boolean {\n return !!(this.experience?.bullets?.length);\n }\n\n get visibleBullets(): string[] {\n if (!this.experience?.bullets) return [];\n const preview = this.experience.bulletsPreview ?? 3;\n return this.expanded\n ? this.experience.bullets\n : this.experience.bullets.slice(0, preview);\n }\n\n get hasMoreBullets(): boolean {\n if (!this.experience?.bullets) return false;\n const preview = this.experience.bulletsPreview ?? 3;\n return this.experience.bullets.length > preview;\n }\n\n get duration(): string {\n return this.calculateDuration();\n }\n\n get isCurrent(): boolean {\n return this.experience?.current ?? false;\n }\n\n ngOnInit(): void {\n this.expanded = false;\n }\n\n toggleExpand(): void {\n this.expanded = !this.expanded;\n }\n\n private calculateDuration(): string {\n if (!this.experience?.startDate) return '';\n\n const start = this.parseDate(this.experience.startDate);\n const end = this.experience.current || !this.experience.endDate\n ? new Date()\n : this.parseDate(this.experience.endDate);\n\n if (!start || !end) return '';\n\n let months = (end.getFullYear() - start.getFullYear()) * 12\n + (end.getMonth() - start.getMonth());\n\n const years = Math.floor(months / 12);\n const remain = months % 12;\n\n const parts: string[] = [];\n if (years > 0) parts.push(`${years} ${years === 1 ? 'año' : 'años'}`);\n if (remain > 0) parts.push(`${remain} ${remain === 1 ? 'mes' : 'meses'}`);\n\n return parts.join(' ');\n }\n\n private parseDate(dateStr: string): Date | null {\n const months: Record<string, number> = {\n ene: 0, feb: 1, mar: 2, abr: 3, may: 4, jun: 5,\n jul: 6, ago: 7, sep: 8, oct: 9, nov: 10, dic: 11,\n };\n\n const parts = dateStr.trim().toLowerCase().split(' ');\n if (parts.length === 2) {\n const month = months[parts[0]];\n const year = parseInt(parts[1], 10);\n if (month !== undefined && !isNaN(year)) {\n return new Date(year, month, 1);\n }\n }\n\n // fallback: intentar parsear como fecha estándar\n const d = new Date(dateStr);\n return isNaN(d.getTime()) ? null : d;\n }\n}\n","<div\n class=\"fs-exp\"\n [class.fs-exp--compact]=\"variant === 'compact'\"\n [class.fs-exp--timeline]=\"timeline\"\n [class.fs-exp--timeline-last]=\"timeline && timelineLast\"\n>\n\n <!-- línea vertical de timeline -->\n <div *ngIf=\"timeline\" class=\"fs-exp__timeline-line\"></div>\n\n <!-- dot del timeline -->\n <div *ngIf=\"timeline\" class=\"fs-exp__timeline-dot\"\n [class.fs-exp__timeline-dot--current]=\"isCurrent\">\n </div>\n\n <!-- card -->\n <div class=\"fs-exp__card\">\n\n <!-- header -->\n <div class=\"fs-exp__header\">\n\n <!-- logo -->\n <div class=\"fs-exp__logo\">\n <img\n *ngIf=\"experience.logoUrl\"\n [src]=\"experience.logoUrl\"\n [alt]=\"experience.company\"\n class=\"fs-exp__logo-img\"\n />\n <span *ngIf=\"!experience.logoUrl\" class=\"fs-exp__logo-text\">\n {{ experience.logoText || experience.company.slice(0, 4).toUpperCase() }}\n </span>\n </div>\n\n <!-- info -->\n <div class=\"fs-exp__info\">\n <div class=\"fs-exp__company\">{{ experience.company }}</div>\n <div class=\"fs-exp__role\">{{ experience.role }}</div>\n <div class=\"fs-exp__date\">\n <span\n class=\"fs-exp__dot\"\n [class.fs-exp__dot--current]=\"isCurrent\"\n ></span>\n <span>\n {{ experience.startDate }} –\n {{ experience.current ? 'actualidad' : experience.endDate }}\n </span>\n <span *ngIf=\"duration\" class=\"fs-exp__duration\">\n · {{ duration }}\n </span>\n </div>\n </div>\n\n </div>\n\n <!-- cuerpo — solo en variante full -->\n <ng-container *ngIf=\"variant === 'full'\">\n\n <div *ngIf=\"hasBullets || experience.badges?.length\" class=\"fs-exp__divider\"></div>\n\n <!-- bullets -->\n <ul *ngIf=\"hasBullets\" class=\"fs-exp__bullets\">\n <li *ngFor=\"let bullet of visibleBullets\" class=\"fs-exp__bullet\">\n <span class=\"fs-exp__bullet-arrow\" aria-hidden=\"true\">▸</span>\n <span>{{ bullet }}</span>\n </li>\n </ul>\n\n <!-- toggle ver más / menos -->\n <button\n *ngIf=\"hasMoreBullets\"\n class=\"fs-exp__toggle\"\n type=\"button\"\n (click)=\"toggleExpand()\"\n >\n <svg\n class=\"fs-exp__toggle-icon\"\n [class.fs-exp__toggle-icon--open]=\"expanded\"\n width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"\n >\n <path d=\"M3 4.5l3 3 3-3\"\n stroke=\"currentColor\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n {{ expanded ? 'ver menos' : 'ver más' }}\n </button>\n\n <!-- badges -->\n <div *ngIf=\"experience.badges?.length\" class=\"fs-exp__badges\">\n <fs-badge\n *ngFor=\"let badge of experience.badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </ng-container>\n\n </div>\n</div>\n","import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FsBadgeComponent, FsBadgeColor } from '../badge/badge.component';\n\nexport interface FsProfileStat {\n value: string | number;\n label: string;\n}\n\nexport interface FsProfileLink {\n /** Texto visible */\n label: string;\n /** URL destino — se ignora si hay encodedEmail */\n url?: string;\n /**\n * Email codificado en base64 — tiene prioridad sobre url.\n * Generá el valor con btoa('tu@email.com') en la consola del browser.\n * El componente lo decodifica en runtime con atob() — nunca aparece\n * el mailto: en el HTML estático, protegiéndolo de email scrapers.\n * Ejemplo: btoa('johndoe@example.com') → 'am9obmRvZUBleGFtcGxlLmNvbQ=='\n */\n encodedEmail?: string;\n /** SVG path del ícono (viewBox 0 0 16 16) — se ignora si hay imgUrl */\n icon?: string;\n /**\n * URL o ruta de imagen para el ícono del link.\n * Ejemplo: 'https://cdn.simpleicons.org/linkedin/white'\n * Tiene prioridad sobre icon si ambos están definidos.\n */\n imgUrl?: string;\n /** Alt text para imgUrl — por defecto vacío (decorativo) */\n imgAlt?: string;\n}\n\nexport interface FsProfileBadge {\n label: string;\n color?: FsBadgeColor;\n customColor?: string;\n iconLeft?: string;\n imgLeft?: string;\n imgLeftAlt?: string;\n}\n\n@Component({\n selector: 'fs-profile-card',\n standalone: true,\n imports: [CommonModule, FsBadgeComponent],\n templateUrl: './profile-card.component.html',\n styleUrl: './profile-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FsProfileCardComponent {\n\n @Input() name = '';\n @Input() handle = '';\n @Input() role = '';\n @Input() verified = false;\n @Input() avatarUrl?: string;\n @Input() bannerUrl?: string;\n @Input() links: FsProfileLink[] = [];\n @Input() badges: FsProfileBadge[] = [];\n @Input() stats: FsProfileStat[] = [];\n @Input() showActions = false;\n @Input() primaryActionLabel = 'Seguir';\n @Input() secondaryActionLabel = 'Mensaje';\n\n @Output() primaryAction = new EventEmitter<void>();\n @Output() secondaryAction = new EventEmitter<void>();\n\n get initials(): string {\n return this.name\n .split(' ')\n .slice(0, 2)\n .map(w => w[0])\n .join('')\n .toUpperCase();\n }\n\n /**\n * Resuelve el href de un link.\n * Si tiene encodedEmail, lo decodifica con atob() y retorna 'mailto:email'.\n * Si tiene url, la retorna directamente.\n * Si no tiene ninguno, retorna null.\n */\n getLinkHref(link: FsProfileLink): string | null {\n if (link.encodedEmail) {\n try {\n return 'mailto:' + atob(link.encodedEmail);\n } catch {\n return null;\n }\n }\n return link.url ?? null;\n }\n\n /**\n * Resuelve el label visible de un link.\n * Si tiene encodedEmail, decodifica y reversa el texto —\n * CSS direction:rtl lo muestra al derecho para el usuario\n * pero el DOM tiene el string invertido, dificultando scrapers.\n */\n getLinkLabel(link: FsProfileLink): string {\n if (link.encodedEmail) {\n try {\n return atob(link.encodedEmail).split('').reverse().join('');\n } catch {\n return link.label;\n }\n }\n return link.label;\n }\n\n /** Verdadero si el link muestra un email (para aplicar la clase RTL) */\n isEmailLink(link: FsProfileLink): boolean {\n return !!link.encodedEmail;\n }\n}\n","<div class=\"fs-profile\">\n\n <!-- banner -->\n <div class=\"fs-profile__banner\">\n <img\n *ngIf=\"bannerUrl\"\n [src]=\"bannerUrl\"\n [alt]=\"name + ' banner'\"\n class=\"fs-profile__banner-img\"\n />\n <div *ngIf=\"!bannerUrl\" class=\"fs-profile__banner-gradient\"></div>\n <div class=\"fs-profile__banner-line\"></div>\n </div>\n\n <!-- body -->\n <div class=\"fs-profile__body\">\n\n <!-- avatar -->\n <div class=\"fs-profile__avatar-wrap\">\n <div class=\"fs-profile__avatar\">\n <img\n *ngIf=\"avatarUrl\"\n [src]=\"avatarUrl\"\n [alt]=\"name\"\n class=\"fs-profile__avatar-img\"\n />\n <span *ngIf=\"!avatarUrl\" class=\"fs-profile__avatar-initials\">\n {{ initials }}\n </span>\n </div>\n <div *ngIf=\"verified\" class=\"fs-profile__verified\" aria-label=\"Verificado\">\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M2 5l2 2 4-4\"\n stroke=\"white\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n\n <!-- identidad -->\n <div class=\"fs-profile__name\">{{ name }}</div>\n <div *ngIf=\"handle\" class=\"fs-profile__handle\">&#64;{{ handle }}</div>\n <div *ngIf=\"role\" class=\"fs-profile__role\">{{ role }}</div>\n\n <!-- acciones -->\n <div *ngIf=\"showActions\" class=\"fs-profile__actions\">\n <button\n class=\"fs-profile__btn fs-profile__btn--primary\"\n type=\"button\"\n (click)=\"primaryAction.emit()\"\n >\n {{ primaryActionLabel }}\n </button>\n <button\n class=\"fs-profile__btn fs-profile__btn--outline\"\n type=\"button\"\n (click)=\"secondaryAction.emit()\"\n >\n {{ secondaryActionLabel }}\n </button>\n </div>\n\n <!-- links -->\n <div *ngIf=\"links.length\" class=\"fs-profile__links\">\n <a\n *ngFor=\"let link of links\"\n class=\"fs-profile__link\"\n [href]=\"getLinkHref(link) || '#'\"\n [attr.target]=\"link.url && !link.encodedEmail ? '_blank' : null\"\n [attr.rel]=\"link.url && !link.encodedEmail ? 'noopener noreferrer' : null\"\n >\n <!-- imagen del link (prioridad sobre icon SVG) -->\n <img\n *ngIf=\"link.imgUrl\"\n [src]=\"link.imgUrl\"\n [alt]=\"link.imgAlt || ''\"\n class=\"fs-profile__link-img\"\n aria-hidden=\"true\"\n />\n <!-- ícono SVG (solo si no hay imgUrl) -->\n <svg\n *ngIf=\"link.icon && !link.imgUrl\"\n width=\"12\" height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"link.icon\" stroke=\"currentColor\" stroke-width=\"1.3\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span\n [class.fs-profile__link-email]=\"isEmailLink(link)\"\n >{{ getLinkLabel(link) }}</span>\n </a>\n </div>\n\n <!-- badges -->\n <div *ngIf=\"badges.length\" class=\"fs-profile__badges\">\n <fs-badge\n *ngFor=\"let badge of badges\"\n [color]=\"badge.color || 'neutral'\"\n [customColor]=\"badge.customColor\"\n [iconLeft]=\"badge.iconLeft\"\n [imgLeft]=\"badge.imgLeft\"\n [imgLeftAlt]=\"badge.imgLeftAlt || ''\"\n variant=\"filled\"\n size=\"sm\"\n >{{ badge.label }}</fs-badge>\n </div>\n\n </div>\n\n <!-- stats footer -->\n <div *ngIf=\"stats.length\" class=\"fs-profile__stats\">\n <div *ngFor=\"let stat of stats\" class=\"fs-profile__stat\">\n <span class=\"fs-profile__stat-value\">{{ stat.value }}</span>\n <span class=\"fs-profile__stat-label\">{{ stat.label }}</span>\n </div>\n </div>\n\n</div>\n","/*\r\n * Public API Surface of fsociety\r\n */\r\n\r\nexport * from './lib/fsociety.service';\r\nexport * from './lib/fsociety.component';\r\n\r\nexport * from './lib/button/button.component';\r\nexport type { FsButtonVariant, FsButtonSize, FsButtonType } from './lib/button/button.component';\r\n\r\nexport * from './lib/badge/badge.component';\r\nexport type { FsBadgeColor, FsBadgeVariant, FsBadgeSize } from './lib/badge/badge.component';\r\n\r\nexport * from './lib/tabs/tabs.component';\r\nexport type { FsTab } from './lib/tabs/tabs.component';\r\n\r\nexport * from './lib/alert/alert.component';\r\nexport type { FsAlertType, FsAlertVariant } from './lib/alert/alert.component';\r\n\r\nexport * from './lib/experience-card/experience-card.component';\r\nexport type { FsExperienceCard, FsExperienceBadge } from './lib/experience-card/experience-card.component';\r\n\r\nexport * from './lib/profile-card/profile-card.component';\r\nexport type { FsProfileStat, FsProfileLink, FsProfileBadge } from './lib/profile-card/profile-card.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MAKa,eAAe,CAAA;AAE1B,IAAA,WAAA,GAAA,EAAgB;wGAFL,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAf,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,cAFd,MAAM,EAAA,CAAA;;4FAEP,eAAe,EAAA,UAAA,EAAA,CAAA;kBAH3B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCQY,iBAAiB,CAAA;wGAAjB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAPlB,CAAA;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FAGU,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAV7B,SAAS;+BACE,aAAa,EAAA,OAAA,EACd,EAAE,EAAA,QAAA,EACD,CAAA;;;;AAIT,EAAA,CAAA,EAAA;;;MCaU,iBAAiB,CAAA;;IAGnB,OAAO,GAAoB,SAAS;;IAGpC,IAAI,GAAiB,IAAI;;IAGzB,IAAI,GAAiB,QAAQ;;IAG7B,QAAQ,GAAG,KAAK;;IAGhB,OAAO,GAAG,KAAK;;AAGf,IAAA,KAAK;;AAGL,IAAA,QAAQ;;AAGR,IAAA,SAAS;;IAGT,SAAS,GAAG,KAAK;;AAGhB,IAAA,OAAO,GAAG,IAAI,YAAY,EAAc;AAElD,IAAA,IACI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,MAAM;IACzC;AAEA,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO;IACtC;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO;AACL,YAAA,CAAC,WAAW,IAAI,CAAC,OAAO,CAAA,CAAE,GAAG,IAAI;AACjC,YAAA,CAAC,WAAW,IAAI,CAAC,IAAI,CAAA,CAAE,GAAM,IAAI;YACjC,iBAAiB,EAAY,IAAI,CAAC,OAAO;YACzC,kBAAkB,EAAW,IAAI,CAAC,UAAU;YAC5C,oBAAoB,EAAS,IAAI,CAAC,SAAS;SAC5C;IACH;AAEA,IAAA,OAAO,CAAC,KAAiB,EAAA;AACvB,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;YACnB,KAAK,CAAC,cAAc,EAAE;YACtB,KAAK,CAAC,eAAe,EAAE;YACvB;QACF;AACA,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1B;wGA1DW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,aAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECtB9B,g+CAsCA,EAAA,MAAA,EAAA,CAAA,m2dAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDrBY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKX,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAR7B,SAAS;+BACE,WAAW,EAAA,UAAA,EACT,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,g+CAAA,EAAA,MAAA,EAAA,CAAA,m2dAAA,CAAA,EAAA;8BAKtC,OAAO,EAAA,CAAA;sBAAf;gBAGQ,IAAI,EAAA,CAAA;sBAAZ;gBAGQ,IAAI,EAAA,CAAA;sBAAZ;gBAGQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,OAAO,EAAA,CAAA;sBAAf;gBAGQ,KAAK,EAAA,CAAA;sBAAb;gBAGQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,SAAS,EAAA,CAAA;sBAAjB;gBAGQ,SAAS,EAAA,CAAA;sBAAjB;gBAGS,OAAO,EAAA,CAAA;sBAAhB;gBAGG,SAAS,EAAA,CAAA;sBADZ,WAAW;uBAAC,aAAa;;;MEhCf,gBAAgB,CAAA;;IAGlB,KAAK,GAAiB,SAAS;AAExC;;;;;AAKG;AACM,IAAA,WAAW;;IAGX,OAAO,GAAmB,QAAQ;;IAGlC,IAAI,GAAgB,IAAI;;AAGxB,IAAA,KAAK;;IAGL,GAAG,GAAG,KAAK;;AAGX,IAAA,QAAQ;;AAGR,IAAA,SAAS;AAElB;;;;AAIG;AACM,IAAA,OAAO;AAEhB;;;AAGG;AACM,IAAA,QAAQ;;IAGR,UAAU,GAAG,EAAE;;IAGf,WAAW,GAAG,EAAE;AAEzB;;;AAGG;IACM,QAAQ,GAAG,KAAK;;IAGhB,SAAS,GAAG,KAAK;;AAGhB,IAAA,OAAO,GAAG,IAAI,YAAY,EAAQ;;IAG5C,YAAY,GAA2B,EAAE;IAEzC,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAC9D;aAAO;AACL,YAAA,IAAI,CAAC,YAAY,GAAG,EAAE;QACxB;IACF;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO;YACL,CAAC,CAAA,UAAA,EAAa,IAAI,CAAC,KAAK,CAAA,CAAE,GAAK,CAAC,IAAI,CAAC,WAAW;AAChD,YAAA,CAAC,aAAa,IAAI,CAAC,OAAO,CAAA,CAAE,GAAG,IAAI;AACnC,YAAA,CAAC,aAAa,IAAI,CAAC,IAAI,CAAA,CAAE,GAAM,IAAI;AACnC,YAAA,kBAAkB,EAAa,CAAC,CAAC,IAAI,CAAC,WAAW;YACjD,eAAe,EAAgB,IAAI,CAAC,GAAG;YACvC,qBAAqB,EAAU,IAAI,CAAC,QAAQ;YAC5C,qBAAqB,EAAU,IAAI,CAAC,SAAS;SAC9C;IACH;AAEA,IAAA,QAAQ,CAAC,KAAiB,EAAA;QACxB,KAAK,CAAC,eAAe,EAAE;AACvB,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACrB;AAEQ,IAAA,iBAAiB,CAAC,GAAW,EAAA;;AAEnC,QAAA,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AACvC,QAAA,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AACvC,QAAA,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AAEvC,QAAA,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC9B,OAAO;AACL,gBAAA,YAAY,EAAI,aAAa;AAC7B,gBAAA,OAAO,EAAS,GAAG;AACnB,gBAAA,cAAc,EAAE,GAAG;aACpB;QACH;QAEA,OAAO;AACL,YAAA,YAAY,EAAI,CAAA,KAAA,EAAQ,CAAC,KAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,OAAA,CAAS;YAC9C,OAAO,EAAS,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACxC,YAAA,cAAc,EAAE,CAAA,KAAA,EAAQ,CAAC,KAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,OAAA,CAAS;SAC/C;IACH;AAEQ,IAAA,UAAU,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;;QAEhD,MAAM,GAAG,GAAG,CAAC,CAAS,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC;AAC1D,QAAA,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG;IAC/C;wGAnHW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA,OAAA,EAAA,GAAA,EAAA,KAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,UAAA,EAAA,YAAA,EAAA,WAAA,EAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECtB7B,i0DAgDA,EAAA,MAAA,EAAA,CAAA,qjeAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED/BY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKX,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAR5B,SAAS;+BACE,UAAU,EAAA,UAAA,EACR,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,i0DAAA,EAAA,MAAA,EAAA,CAAA,qjeAAA,CAAA,EAAA;8BAKtC,KAAK,EAAA,CAAA;sBAAb;gBAQQ,WAAW,EAAA,CAAA;sBAAnB;gBAGQ,OAAO,EAAA,CAAA;sBAAf;gBAGQ,IAAI,EAAA,CAAA;sBAAZ;gBAGQ,KAAK,EAAA,CAAA;sBAAb;gBAGQ,GAAG,EAAA,CAAA;sBAAX;gBAGQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,SAAS,EAAA,CAAA;sBAAjB;gBAOQ,OAAO,EAAA,CAAA;sBAAf;gBAMQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,UAAU,EAAA,CAAA;sBAAlB;gBAGQ,WAAW,EAAA,CAAA;sBAAnB;gBAMQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,SAAS,EAAA,CAAA;sBAAjB;gBAGS,OAAO,EAAA,CAAA;sBAAhB;;;MEjDU,eAAe,CAAA;AAoBhB,IAAA,GAAA;AACA,IAAA,IAAA;;IAlBD,IAAI,GAAY,EAAE;;IAGlB,SAAS,GAAG,EAAE;;AAGb,IAAA,eAAe,GAAG,IAAI,YAAY,EAAU;;AAG5C,IAAA,SAAS,GAAG,IAAI,YAAY,EAAS;AAEzB,IAAA,OAAO;IAE7B,aAAa,GAAI,CAAC;IAClB,cAAc,GAAG,CAAC;IAElB,WAAA,CACU,GAAsB,EACtB,IAAY,EAAA;QADZ,IAAA,CAAA,GAAG,GAAH,GAAG;QACH,IAAA,CAAA,IAAI,GAAJ,IAAI;IACX;IAEH,eAAe,GAAA;QACb,IAAI,CAAC,eAAe,EAAE;;AAGtB,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAK;AAC/B,YAAA,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,MAAK;AACjC,gBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAK;oBACjB,IAAI,CAAC,eAAe,EAAE;AACtB,oBAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;AACzB,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;YACF,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;AACxC,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;QAChC,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE;;YAE3C,UAAU,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC1C;IACF;AAEA,IAAA,SAAS,CAAC,GAAU,EAAA;QAClB,IAAI,GAAG,CAAC,QAAQ;YAAE;AAClB,QAAA,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE;QACvB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QACxB,IAAI,CAAC,eAAe,EAAE;IACxB;AAEA,IAAA,QAAQ,CAAC,GAAU,EAAA;AACjB,QAAA,OAAO,IAAI,CAAC,SAAS,KAAK,GAAG,CAAC,EAAE;IAClC;IAEQ,eAAe,GAAA;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAEnB,QAAA,MAAM,GAAG,GAAK,IAAI,CAAC,OAAO,CAAC,aAAa;QACxC,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAgB,CAAc,gBAAgB,CAAC;QACjE,MAAM,GAAG,GAAK,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC;QAE/D,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE;AAE/B,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC;AACvB,QAAA,IAAI,CAAC,aAAa,GAAI,IAAI,CAAC,UAAU;AACrC,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW;AACtC,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;IACzB;wGAvEW,eAAe,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAf,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,SAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjC5B,44BAmCA,EAAA,MAAA,EAAA,CAAA,4yaAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDPY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKX,eAAe,EAAA,UAAA,EAAA,CAAA;kBAR3B,SAAS;+BACE,SAAS,EAAA,UAAA,EACP,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,44BAAA,EAAA,MAAA,EAAA,CAAA,4yaAAA,CAAA,EAAA;2GAKtC,IAAI,EAAA,CAAA;sBAAZ;gBAGQ,SAAS,EAAA,CAAA;sBAAjB;gBAGS,eAAe,EAAA,CAAA;sBAAxB;gBAGS,SAAS,EAAA,CAAA;sBAAlB;gBAEqB,OAAO,EAAA,CAAA;sBAA5B,SAAS;uBAAC,SAAS;;;MExBT,gBAAgB,CAAA;AA6BP,IAAA,GAAA;;IA1BX,IAAI,GAAgB,MAAM;;IAG1B,OAAO,GAAmB,QAAQ;;AAGlC,IAAA,KAAK;;IAGL,WAAW,GAAG,KAAK;AAE5B;;;;AAIG;IACM,WAAW,GAAG,CAAC;;AAGd,IAAA,SAAS,GAAG,IAAI,YAAY,EAAQ;;IAG9C,SAAS,GAAuC,UAAU;AAElD,IAAA,SAAS;AAEjB,IAAA,WAAA,CAAoB,GAAsB,EAAA;QAAtB,IAAA,CAAA,GAAG,GAAH,GAAG;IAAsB;IAE7C,QAAQ,GAAA;;QAEN,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,SAAS,GAAG,SAAS;AAC1B,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;QACzB,CAAC,EAAE,GAAG,CAAC;AAEP,QAAA,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE;AACxB,YAAA,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC;QACrE;IACF;IAEA,WAAW,GAAA;QACT,IAAI,IAAI,CAAC,SAAS;AAAE,YAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;IAClD;IAEA,OAAO,GAAA;AACL,QAAA,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE;AAClC,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;AAC1B,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;;QAGvB,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;QACvB,CAAC,EAAE,GAAG,CAAC;IACT;AAEA,IAAA,IAAI,gBAAgB,GAAA;AAClB,QAAA,OAAO,CAAA,EAAG,IAAI,CAAC,WAAW,IAAI;IAChC;AAEA,IAAA,IAAI,QAAQ,GAAA;AACV,QAAA,MAAM,KAAK,GAAgC;AACzC,YAAA,IAAI,EAAK,oDAAoD;AAC7D,YAAA,OAAO,EAAE,gDAAgD;AACzD,YAAA,OAAO,EAAE,oCAAoC;AAC7C,YAAA,MAAM,EAAG,qDAAqD;AAC9D,YAAA,OAAO,EAAE,oDAAoD;SAC9D;AACD,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IACzB;wGAvEW,gBAAgB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvB7B,unDA8DA,EAAA,MAAA,EAAA,CAAA,qreAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED5CY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKX,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAR5B,SAAS;+BACE,UAAU,EAAA,UAAA,EACR,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,unDAAA,EAAA,MAAA,EAAA,CAAA,qreAAA,CAAA,EAAA;sFAKtC,IAAI,EAAA,CAAA;sBAAZ;gBAGQ,OAAO,EAAA,CAAA;sBAAf;gBAGQ,KAAK,EAAA,CAAA;sBAAb;gBAGQ,WAAW,EAAA,CAAA;sBAAnB;gBAOQ,WAAW,EAAA,CAAA;sBAAnB;gBAGS,SAAS,EAAA,CAAA;sBAAlB;;;MEaU,yBAAyB,CAAA;;AAG3B,IAAA,UAAU;;IAGV,OAAO,GAAuB,MAAM;;IAGpC,QAAQ,GAAG,KAAK;;IAGhB,YAAY,GAAG,KAAK;IAE7B,QAAQ,GAAG,KAAK;AAEhB,IAAA,IAAI,UAAU,GAAA;QACZ,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;IAC7C;AAEA,IAAA,IAAI,cAAc,GAAA;AAChB,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO;AAAE,YAAA,OAAO,EAAE;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,IAAI,CAAC;QACnD,OAAO,IAAI,CAAC;AACV,cAAE,IAAI,CAAC,UAAU,CAAC;AAClB,cAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;IAC/C;AAEA,IAAA,IAAI,cAAc,GAAA;AAChB,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO;AAAE,YAAA,OAAO,KAAK;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,IAAI,CAAC;QACnD,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO;IACjD;AAEA,IAAA,IAAI,QAAQ,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,iBAAiB,EAAE;IACjC;AAEA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,KAAK;IAC1C;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;IACvB;IAEA,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ;IAChC;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS;AAAE,YAAA,OAAO,EAAE;AAE1C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;AACvD,QAAA,MAAM,GAAG,GAAK,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;cACtD,IAAI,IAAI;cACR,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;AAE3C,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,EAAE;AAE7B,QAAA,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI;eAC3C,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAEhD,MAAM,KAAK,GAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;AACtC,QAAA,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE;QAE1B,MAAM,KAAK,GAAa,EAAE;QAC1B,IAAI,KAAK,GAAG,CAAC;AAAG,YAAA,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA,CAAA,EAAI,KAAK,KAAK,CAAC,GAAG,KAAK,GAAG,MAAM,CAAA,CAAE,CAAC;QACtE,IAAI,MAAM,GAAG,CAAC;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAA,CAAA,EAAI,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,OAAO,CAAA,CAAE,CAAC;AAEzE,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB;AAEQ,IAAA,SAAS,CAAC,OAAe,EAAA;AAC/B,QAAA,MAAM,MAAM,GAA2B;YACrC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;YAC9C,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;SACjD;AAED,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;AACrD,QAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;YACtB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;gBACvC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACjC;QACF;;AAGA,QAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;AAC3B,QAAA,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC;IACtC;wGA3FW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC1DtC,uzGAyGA,EAAA,MAAA,EAAA,CAAA,4weAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDpDY,YAAY,gQAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,KAAA,EAAA,UAAA,EAAA,WAAA,EAAA,SAAA,EAAA,UAAA,EAAA,YAAA,EAAA,aAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAK7B,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBARrC,SAAS;+BACE,oBAAoB,EAAA,UAAA,EAClB,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,gBAAgB,CAAC,EAAA,eAAA,EAGxB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,uzGAAA,EAAA,MAAA,EAAA,CAAA,4weAAA,CAAA,EAAA;8BAKtC,UAAU,EAAA,CAAA;sBAAlB;gBAGQ,OAAO,EAAA,CAAA;sBAAf;gBAGQ,QAAQ,EAAA,CAAA;sBAAhB;gBAGQ,YAAY,EAAA,CAAA;sBAApB;;;MEbU,sBAAsB,CAAA;IAExB,IAAI,GAAG,EAAE;IACT,MAAM,GAAG,EAAE;IACX,IAAI,GAAG,EAAE;IACT,QAAQ,GAAG,KAAK;AAChB,IAAA,SAAS;AACT,IAAA,SAAS;IACT,KAAK,GAAoB,EAAE;IAC3B,MAAM,GAAqB,EAAE;IAC7B,KAAK,GAAoB,EAAE;IAC3B,WAAW,GAAG,KAAK;IACnB,kBAAkB,GAAG,QAAQ;IAC7B,oBAAoB,GAAG,SAAS;AAE/B,IAAA,aAAa,GAAK,IAAI,YAAY,EAAQ;AAC1C,IAAA,eAAe,GAAG,IAAI,YAAY,EAAQ;AAEpD,IAAA,IAAI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC;aACT,KAAK,CAAC,GAAG;AACT,aAAA,KAAK,CAAC,CAAC,EAAE,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACb,IAAI,CAAC,EAAE;AACP,aAAA,WAAW,EAAE;IAClB;AAEA;;;;;AAKG;AACH,IAAA,WAAW,CAAC,IAAmB,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,IAAI;gBACF,OAAO,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;YAC5C;AAAE,YAAA,MAAM;AACN,gBAAA,OAAO,IAAI;YACb;QACF;AACA,QAAA,OAAO,IAAI,CAAC,GAAG,IAAI,IAAI;IACzB;AAEA;;;;;AAKG;AACH,IAAA,YAAY,CAAC,IAAmB,EAAA;AAC9B,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,IAAI;AACF,gBAAA,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D;AAAE,YAAA,MAAM;gBACN,OAAO,IAAI,CAAC,KAAK;YACnB;QACF;QACA,OAAO,IAAI,CAAC,KAAK;IACnB;;AAGA,IAAA,WAAW,CAAC,IAAmB,EAAA;AAC7B,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY;IAC5B;wGAhEW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,SAAA,EAAA,WAAA,EAAA,KAAA,EAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,EAAA,OAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECzDnC,m2HAyHA,EAAA,MAAA,EAAA,CAAA,4mgBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDrEY,YAAY,gQAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,KAAA,EAAA,UAAA,EAAA,WAAA,EAAA,SAAA,EAAA,UAAA,EAAA,YAAA,EAAA,aAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAK7B,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBARlC,SAAS;+BACE,iBAAiB,EAAA,UAAA,EACf,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,gBAAgB,CAAC,EAAA,eAAA,EAGxB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,m2HAAA,EAAA,MAAA,EAAA,CAAA,4mgBAAA,CAAA,EAAA;8BAItC,IAAI,EAAA,CAAA;sBAAZ;gBACQ,MAAM,EAAA,CAAA;sBAAd;gBACQ,IAAI,EAAA,CAAA;sBAAZ;gBACQ,QAAQ,EAAA,CAAA;sBAAhB;gBACQ,SAAS,EAAA,CAAA;sBAAjB;gBACQ,SAAS,EAAA,CAAA;sBAAjB;gBACQ,KAAK,EAAA,CAAA;sBAAb;gBACQ,MAAM,EAAA,CAAA;sBAAd;gBACQ,KAAK,EAAA,CAAA;sBAAb;gBACQ,WAAW,EAAA,CAAA;sBAAnB;gBACQ,kBAAkB,EAAA,CAAA;sBAA1B;gBACQ,oBAAoB,EAAA,CAAA;sBAA5B;gBAES,aAAa,EAAA,CAAA;sBAAtB;gBACS,eAAe,EAAA,CAAA;sBAAxB;;;AEzEH;;AAEG;;ACFH;;AAEG;;;;"}
@@ -8,8 +8,16 @@ export interface FsProfileStat {
8
8
  export interface FsProfileLink {
9
9
  /** Texto visible */
10
10
  label: string;
11
- /** URL destino */
11
+ /** URL destino — se ignora si hay encodedEmail */
12
12
  url?: string;
13
+ /**
14
+ * Email codificado en base64 — tiene prioridad sobre url.
15
+ * Generá el valor con btoa('tu@email.com') en la consola del browser.
16
+ * El componente lo decodifica en runtime con atob() — nunca aparece
17
+ * el mailto: en el HTML estático, protegiéndolo de email scrapers.
18
+ * Ejemplo: btoa('johndoe@example.com') → 'am9obmRvZUBleGFtcGxlLmNvbQ=='
19
+ */
20
+ encodedEmail?: string;
13
21
  /** SVG path del ícono (viewBox 0 0 16 16) — se ignora si hay imgUrl */
14
22
  icon?: string;
15
23
  /**
@@ -45,6 +53,22 @@ export declare class FsProfileCardComponent {
45
53
  primaryAction: EventEmitter<void>;
46
54
  secondaryAction: EventEmitter<void>;
47
55
  get initials(): string;
56
+ /**
57
+ * Resuelve el href de un link.
58
+ * Si tiene encodedEmail, lo decodifica con atob() y retorna 'mailto:email'.
59
+ * Si tiene url, la retorna directamente.
60
+ * Si no tiene ninguno, retorna null.
61
+ */
62
+ getLinkHref(link: FsProfileLink): string | null;
63
+ /**
64
+ * Resuelve el label visible de un link.
65
+ * Si tiene encodedEmail, decodifica y reversa el texto —
66
+ * CSS direction:rtl lo muestra al derecho para el usuario
67
+ * pero el DOM tiene el string invertido, dificultando scrapers.
68
+ */
69
+ getLinkLabel(link: FsProfileLink): string;
70
+ /** Verdadero si el link muestra un email (para aplicar la clase RTL) */
71
+ isEmailLink(link: FsProfileLink): boolean;
48
72
  static ɵfac: i0.ɵɵFactoryDeclaration<FsProfileCardComponent, never>;
49
73
  static ɵcmp: i0.ɵɵComponentDeclaration<FsProfileCardComponent, "fs-profile-card", never, { "name": { "alias": "name"; "required": false; }; "handle": { "alias": "handle"; "required": false; }; "role": { "alias": "role"; "required": false; }; "verified": { "alias": "verified"; "required": false; }; "avatarUrl": { "alias": "avatarUrl"; "required": false; }; "bannerUrl": { "alias": "bannerUrl"; "required": false; }; "links": { "alias": "links"; "required": false; }; "badges": { "alias": "badges"; "required": false; }; "stats": { "alias": "stats"; "required": false; }; "showActions": { "alias": "showActions"; "required": false; }; "primaryActionLabel": { "alias": "primaryActionLabel"; "required": false; }; "secondaryActionLabel": { "alias": "secondaryActionLabel"; "required": false; }; }, { "primaryAction": "primaryAction"; "secondaryAction": "secondaryAction"; }, never, never, true, never>;
50
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heroelc/fsociety",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "Angular component library with design system tokens, mixins and UI components",
5
5
  "author": "Heroel Carpinetti <heroeljcarpinetti@gmail.com>",
6
6
  "license": "MIT",