@konce-pt/angular 0.7.6 → 0.7.7

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.
@@ -322,9 +322,21 @@ const ROLE_CONTRAST_VARS = {
322
322
  info: 'var(--kpt-color-info-contrast)',
323
323
  muted: 'var(--kpt-color-on-muted)',
324
324
  };
325
- /** Rola koloru → zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian. */
325
+ /**
326
+ * Kształt jedynego wejścia spoza znanej roli, jakie kontrakt `KptMapColor` dopuszcza —
327
+ * gotowy token `var(--kpt-*)`. Dane runtime (JSON/CMS) nie są tym kontraktem związane, więc
328
+ * zanim trafią do atrybutu `style="..."` budowanego konkatenacją stringów w `renderMarkerHtml`/
329
+ * `renderClusterHtml`, muszą zostać zweryfikowane — inaczej cudzysłów/`>` wyrywa się z atrybutu
330
+ * (HTML injection), a średnik wstrzykuje dodatkową deklarację CSS.
331
+ */
332
+ const SAFE_VAR_TOKEN = /^var\(--kpt-[\w-]+\)$/;
333
+ /** Rola koloru → zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian; cokolwiek spoza tego
334
+ * kontraktu dostaje bezpieczny fallback zamiast trafić surowo do wyjścia. */
326
335
  function colorVarOf(color) {
327
- return ROLE_VARS[color] ?? color;
336
+ const known = ROLE_VARS[color];
337
+ if (known)
338
+ return known;
339
+ return SAFE_VAR_TOKEN.test(color) ? color : ROLE_VARS.muted;
328
340
  }
329
341
  /** Kolor treści na tle `color` — dla ról znany, dla własnych zmiennych fallback na biel tokenową. */
330
342
  function contrastVarOf(color) {
@@ -343,16 +355,19 @@ const ROLE_FOREGROUND_VARS = {
343
355
  muted: 'var(--kpt-color-on-surface-muted)',
344
356
  };
345
357
  function foregroundVarOf(color) {
346
- return ROLE_FOREGROUND_VARS[color] ?? color;
358
+ const known = ROLE_FOREGROUND_VARS[color];
359
+ if (known)
360
+ return known;
361
+ return SAFE_VAR_TOKEN.test(color) ? color : ROLE_FOREGROUND_VARS.muted;
347
362
  }
348
363
  /** Ucieka znaki, które rozbiłyby atrybut albo wstrzyknęły znacznik. */
349
364
  function escapeHtml(value) {
350
365
  return value
351
- .replace(/&/g, '&')
352
- .replace(/</g, '&lt;')
353
- .replace(/>/g, '&gt;')
354
- .replace(/"/g, '&quot;')
355
- .replace(/'/g, '&#39;');
366
+ .replaceAll('&', '&amp;')
367
+ .replaceAll('<', '&lt;')
368
+ .replaceAll('>', '&gt;')
369
+ .replaceAll('"', '&quot;')
370
+ .replaceAll("'", '&#39;');
356
371
  }
357
372
  /**
358
373
  * Pinezka o wysokości `--kpt-map-marker-size`, zakotwiczona czubkiem w punkcie.
@@ -360,7 +375,10 @@ function escapeHtml(value) {
360
375
  */
361
376
  const PIN_PATH = 'M12 0C5.8 0 .8 5 .8 11.2c0 8 9.9 19.4 10.3 19.9a1.2 1.2 0 0 0 1.8 0c.4-.5 10.3-11.9 10.3-19.9C23.2 5 18.2 0 12 0z';
362
377
  function renderMarkerHtml(input) {
363
- const shape = input.shape ?? 'pin';
378
+ // `shape` trafia do atrybutu `class="..."` konkatenacją stringów — `KptMapMarkerShape` ogranicza
379
+ // to tylko compile-time, dane runtime (JSON/CMS) nie są tym związane (ten sam powód, dla którego
380
+ // `color`/`contrast` dostały escapowanie/whitelistę wyżej w pliku).
381
+ const shape = escapeHtml(input.shape ?? 'pin');
364
382
  const color = colorVarOf(input.color);
365
383
  const contrast = contrastVarOf(input.color);
366
384
  const label = escapeHtml(input.label);
@@ -1788,7 +1806,7 @@ class KptMapLegend {
1788
1806
  i0.ɵɵrepeaterCreate(0, KptMapLegend_For_1_Template, 6, 12, "button", 0, _forTrack0$3);
1789
1807
  } if (rf & 2) {
1790
1808
  i0.ɵɵrepeater(ctx.entries());
1791
- } }, dependencies: [KptIcon], styles: ["@charset \"UTF-8\";@layer kpt.components{.kpt-map-legend{display:flex;flex-wrap:wrap;gap:var(--%NS%kpt-space-2);align-items:center}.kpt-map-legend[data-orientation=vertical]{flex-direction:column;align-items:stretch}.kpt-map-legend__item{display:inline-flex;gap:var(--%NS%kpt-space-2);align-items:center;padding:var(--%NS%kpt-space-1) var(--%NS%kpt-space-2);font:inherit;font-size:var(--%NS%kpt-font-size-sm);color:var(--%NS%kpt-color-on-surface);cursor:pointer;background:transparent;border:var(--%NS%kpt-border-width-thin) solid transparent;border-radius:var(--%NS%kpt-radius-full);transition:background-color var(--%NS%kpt-motion-duration-fast) var(--%NS%kpt-motion-easing-standard)}.kpt-map-legend__item:hover:not(:disabled){background:var(--%NS%kpt-color-surface-hover)}.kpt-map-legend__item:focus-visible{outline:var(--%NS%kpt-border-width-medium) solid var(--%NS%kpt-color-focus-ring);outline-offset:2px}.kpt-map-legend__item:disabled{cursor:default}.kpt-map-legend__item.kpt-map-legend__item--off{color:var(--%NS%kpt-color-on-surface-muted)}.kpt-map-legend__item.kpt-map-legend__item--off .kpt-map-legend__swatch{background:transparent;border-color:var(--%NS%kpt-color-border-strong)}.kpt-map-legend__swatch{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;font-size:.875rem;color:var(--%NS%_kpt-legend-fg, var(--%NS%kpt-color-text-inverse));background:var(--%NS%_kpt-legend-color, var(--%NS%kpt-color-muted));border:var(--%NS%kpt-border-width-thin) solid transparent;border-radius:var(--%NS%kpt-radius-full)}.kpt-map-legend__count{font-variant-numeric:tabular-nums;color:var(--%NS%kpt-color-on-surface-muted)}@media(prefers-reduced-motion:reduce){.kpt-map-legend__item{transition:none}}}\n"], encapsulation: 2 }); }
1809
+ } }, dependencies: [KptIcon], styles: ["@charset \"UTF-8\";@layer kpt.components{.kpt-map-legend{display:flex;flex-wrap:wrap;gap:var(--%NS%kpt-space-2);align-items:center}.kpt-map-legend[data-orientation=vertical]{flex-direction:column;align-items:stretch}.kpt-map-legend__item{display:inline-flex;gap:var(--%NS%kpt-space-2);align-items:center;padding:var(--%NS%kpt-space-1) var(--%NS%kpt-space-2);font:inherit;font-size:var(--%NS%kpt-font-size-sm);color:var(--%NS%kpt-color-on-surface);cursor:pointer;background:transparent;border:var(--%NS%kpt-border-width-thin) solid transparent;border-radius:var(--%NS%kpt-radius-full);transition:background-color var(--%NS%kpt-motion-duration-fast) var(--%NS%kpt-motion-easing-standard)}.kpt-map-legend__item:hover:not(:disabled){background:var(--%NS%kpt-color-surface-hover)}.kpt-map-legend__item:focus-visible{outline:var(--%NS%kpt-border-width-medium) solid var(--%NS%kpt-color-focus-ring);outline-offset:2px}.kpt-map-legend__item:disabled{cursor:default}.kpt-map-legend__item.kpt-map-legend__item--off{color:var(--%NS%kpt-color-on-surface-muted)}.kpt-map-legend__item.kpt-map-legend__item--off .kpt-map-legend__swatch{background:transparent;border-color:var(--%NS%kpt-color-border-strong)}.kpt-map-legend__swatch{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;font-size:.875rem;color:var(--%NS%_kpt-legend-fg, var(--%NS%kpt-color-text-inverse));background-color:var(--%NS%_kpt-legend-color, var(--%NS%kpt-color-muted));border:var(--%NS%kpt-border-width-thin) solid transparent;border-radius:var(--%NS%kpt-radius-full)}.kpt-map-legend__count{font-variant-numeric:tabular-nums;color:var(--%NS%kpt-color-on-surface-muted)}@media(prefers-reduced-motion:reduce){.kpt-map-legend__item{transition:none}}}\n"], encapsulation: 2 }); }
1792
1810
  }
1793
1811
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(KptMapLegend, [{
1794
1812
  type: Component,
@@ -1797,7 +1815,7 @@ class KptMapLegend {
1797
1815
  '[attr.data-orientation]': 'orientation()',
1798
1816
  role: 'group',
1799
1817
  '[attr.aria-label]': 'i18n.t("map.legend")',
1800
- }, template: "@for (entry of entries(); track entry.category.id) {\n <button\n class=\"kpt-map-legend__item\"\n type=\"button\"\n [style.--_kpt-legend-color]=\"entry.colorVar\"\n [style.--_kpt-legend-fg]=\"entry.contrastVar\"\n [class.kpt-map-legend__item--off]=\"entry.hidden\"\n [attr.aria-pressed]=\"interactive() ? !entry.hidden : null\"\n [attr.aria-label]=\"interactive() ? label(entry) : null\"\n [disabled]=\"!interactive()\"\n (click)=\"toggle(entry)\"\n >\n <span class=\"kpt-map-legend__swatch\" aria-hidden=\"true\">\n @if (entry.category.icon) {\n <kpt-icon [name]=\"entry.category.icon\" />\n }\n </span>\n <span class=\"kpt-map-legend__label\">{{ entry.category.label }}</span>\n @if (entry.count !== null) {\n <span class=\"kpt-map-legend__count\">{{ entry.count }}</span>\n }\n </button>\n}\n", styles: ["@charset \"UTF-8\";@layer kpt.components{.kpt-map-legend{display:flex;flex-wrap:wrap;gap:var(--kpt-space-2);align-items:center}.kpt-map-legend[data-orientation=vertical]{flex-direction:column;align-items:stretch}.kpt-map-legend__item{display:inline-flex;gap:var(--kpt-space-2);align-items:center;padding:var(--kpt-space-1) var(--kpt-space-2);font:inherit;font-size:var(--kpt-font-size-sm);color:var(--kpt-color-on-surface);cursor:pointer;background:transparent;border:var(--kpt-border-width-thin) solid transparent;border-radius:var(--kpt-radius-full);transition:background-color var(--kpt-motion-duration-fast) var(--kpt-motion-easing-standard)}.kpt-map-legend__item:hover:not(:disabled){background:var(--kpt-color-surface-hover)}.kpt-map-legend__item:focus-visible{outline:var(--kpt-border-width-medium) solid var(--kpt-color-focus-ring);outline-offset:2px}.kpt-map-legend__item:disabled{cursor:default}.kpt-map-legend__item.kpt-map-legend__item--off{color:var(--kpt-color-on-surface-muted)}.kpt-map-legend__item.kpt-map-legend__item--off .kpt-map-legend__swatch{background:transparent;border-color:var(--kpt-color-border-strong)}.kpt-map-legend__swatch{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;font-size:.875rem;color:var(--_kpt-legend-fg, var(--kpt-color-text-inverse));background:var(--_kpt-legend-color, var(--kpt-color-muted));border:var(--kpt-border-width-thin) solid transparent;border-radius:var(--kpt-radius-full)}.kpt-map-legend__count{font-variant-numeric:tabular-nums;color:var(--kpt-color-on-surface-muted)}@media(prefers-reduced-motion:reduce){.kpt-map-legend__item{transition:none}}}\n"] }]
1818
+ }, template: "@for (entry of entries(); track entry.category.id) {\n <button\n class=\"kpt-map-legend__item\"\n type=\"button\"\n [style.--_kpt-legend-color]=\"entry.colorVar\"\n [style.--_kpt-legend-fg]=\"entry.contrastVar\"\n [class.kpt-map-legend__item--off]=\"entry.hidden\"\n [attr.aria-pressed]=\"interactive() ? !entry.hidden : null\"\n [attr.aria-label]=\"interactive() ? label(entry) : null\"\n [disabled]=\"!interactive()\"\n (click)=\"toggle(entry)\"\n >\n <span class=\"kpt-map-legend__swatch\" aria-hidden=\"true\">\n @if (entry.category.icon) {\n <kpt-icon [name]=\"entry.category.icon\" />\n }\n </span>\n <span class=\"kpt-map-legend__label\">{{ entry.category.label }}</span>\n @if (entry.count !== null) {\n <span class=\"kpt-map-legend__count\">{{ entry.count }}</span>\n }\n </button>\n}\n", styles: ["@charset \"UTF-8\";@layer kpt.components{.kpt-map-legend{display:flex;flex-wrap:wrap;gap:var(--kpt-space-2);align-items:center}.kpt-map-legend[data-orientation=vertical]{flex-direction:column;align-items:stretch}.kpt-map-legend__item{display:inline-flex;gap:var(--kpt-space-2);align-items:center;padding:var(--kpt-space-1) var(--kpt-space-2);font:inherit;font-size:var(--kpt-font-size-sm);color:var(--kpt-color-on-surface);cursor:pointer;background:transparent;border:var(--kpt-border-width-thin) solid transparent;border-radius:var(--kpt-radius-full);transition:background-color var(--kpt-motion-duration-fast) var(--kpt-motion-easing-standard)}.kpt-map-legend__item:hover:not(:disabled){background:var(--kpt-color-surface-hover)}.kpt-map-legend__item:focus-visible{outline:var(--kpt-border-width-medium) solid var(--kpt-color-focus-ring);outline-offset:2px}.kpt-map-legend__item:disabled{cursor:default}.kpt-map-legend__item.kpt-map-legend__item--off{color:var(--kpt-color-on-surface-muted)}.kpt-map-legend__item.kpt-map-legend__item--off .kpt-map-legend__swatch{background:transparent;border-color:var(--kpt-color-border-strong)}.kpt-map-legend__swatch{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;font-size:.875rem;color:var(--_kpt-legend-fg, var(--kpt-color-text-inverse));background-color:var(--_kpt-legend-color, var(--kpt-color-muted));border:var(--kpt-border-width-thin) solid transparent;border-radius:var(--kpt-radius-full)}.kpt-map-legend__count{font-variant-numeric:tabular-nums;color:var(--kpt-color-on-surface-muted)}@media(prefers-reduced-motion:reduce){.kpt-map-legend__item{transition:none}}}\n"] }]
1801
1819
  }], null, { categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: true }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }, { type: i0.Output, args: ["hiddenChange"] }], counts: [{ type: i0.Input, args: [{ isSignal: true, alias: "counts", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }] }); })();
1802
1820
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KptMapLegend, { className: "KptMapLegend", filePath: "lib/map-legend.component.ts", lineNumber: 47 }); })();
1803
1821
 
@@ -3974,6 +3992,27 @@ function formatLatLng(at, digits = 5) {
3974
3992
  return `${at.lat.toFixed(digits)}, ${at.lng.toFixed(digits)}`;
3975
3993
  }
3976
3994
 
3995
+ /*
3996
+ * Normalizacja adresów dla karty POI — pure TS. Wydzielone z `map-poi-card.component.ts`,
3997
+ * żeby dało się to testować `node --test` bez ciągnięcia Angulara.
3998
+ */
3999
+ const HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
4000
+ const SAFE_SCHEME = /^(https?:|mailto:|tel:)/i;
4001
+ /**
4002
+ * Adres bez schematu dostaje `https://` — inaczej przeglądarka potraktuje go jak ścieżkę względną.
4003
+ * Schemat spoza allowlisty (np. `javascript:`) traktujemy jak brak schematu — bezpieczny
4004
+ * fallback zamiast przepuszczenia surowej wartości do `[href]`/`[src]`/`navigator.share()`.
4005
+ */
4006
+ function normalizeUrl(value) {
4007
+ if (!HAS_SCHEME.test(value))
4008
+ return `https://${value}`;
4009
+ return SAFE_SCHEME.test(value) ? value : `https://${value.replace(HAS_SCHEME, '')}`;
4010
+ }
4011
+ /** Wersja adresu do pokazania: bez schematu i bez końcowego ukośnika. */
4012
+ function prettyUrl(value) {
4013
+ return value.replace(/^[a-z][a-z0-9+.-]*:\/\//i, '').replace(/\/$/, '');
4014
+ }
4015
+
3977
4016
  const _c0 = () => [];
3978
4017
  const _forTrack0 = ($index, $item) => $item.label;
3979
4018
  const _forTrack1 = ($index, $item) => $item.kind;
@@ -4263,14 +4302,6 @@ function KptMapPoiCard_Conditional_19_Template(rf, ctx) { if (rf & 1) {
4263
4302
  } }
4264
4303
  /** Licznik instancji — `aria-controls` musi wskazywać unikatowy identyfikator na stronie. */
4265
4304
  let poiCardSeq = 0;
4266
- /** Adres bez schematu dostaje `https://` — inaczej przeglądarka potraktuje go jak ścieżkę względną. */
4267
- function normalizeUrl(value) {
4268
- return /^[a-z][a-z0-9+.-]*:/i.test(value) ? value : `https://${value}`;
4269
- }
4270
- /** Wersja adresu do pokazania: bez schematu i bez końcowego ukośnika. */
4271
- function prettyUrl(value) {
4272
- return value.replace(/^[a-z][a-z0-9+.-]*:\/\//i, '').replace(/\/$/, '');
4273
- }
4274
4305
  /**
4275
4306
  * Karta miejsca do popupu mapy — dystans od użytkownika, zdjęcie, akcje, kategoria,
4276
4307
  * rozwijane godziny otwarcia i wiersze kontaktowe z kopiowaniem.
@@ -4550,7 +4581,7 @@ class KptMapPoiCard {
4550
4581
  type: Component,
4551
4582
  args: [{ selector: 'kpt-map-poi-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [KptButton, KptIcon, KptIconButton], host: { class: 'kpt-map-poi' }, template: "<header class=\"kpt-map-poi__head\">\n <!--\n Nag\u0142\u00F3wek jako `role=\"heading\"`, nie `<h3>`: style komponent\u00F3w siedz\u0105 w `@layer\n kpt.components`, a CSS aplikacji spoza warstw wygrywa z nimi zawsze. Zwyk\u0142y `<h3>`\n \u0142apa\u0142by wi\u0119c ka\u017Cd\u0105 regu\u0142\u0119 `h3 { \u2026 }` z uk\u0142adu strony \u2014 a nag\u0142\u00F3wek sekcji strony\n i tytu\u0142 miejsca to dwie r\u00F3\u017Cne rzeczy. Dla czytnika ekranu to wci\u0105\u017C nag\u0142\u00F3wek poziomu 3.\n -->\n <p class=\"kpt-map-poi__title\" role=\"heading\" aria-level=\"3\">{{ poi().title }}</p>\n @if (closable()) {\n <kpt-icon-button\n class=\"kpt-map-poi__close\"\n variant=\"text\"\n size=\"sm\"\n [ariaLabel]=\"i18n.t('common.close')\"\n (click)=\"onClose()\"\n >\n <kpt-icon name=\"x\" />\n </kpt-icon-button>\n }\n</header>\n\n<p class=\"kpt-map-poi__meta\">\n @if (distanceLabel(); as distance) {\n <strong class=\"kpt-map-poi__distance\">{{ distance }}</strong>\n }\n @if (poi().address; as address) {\n <span class=\"kpt-map-poi__address\">{{ address }}</span>\n }\n</p>\n\n<!--\n Wszystko poni\u017Cej nag\u0142\u00F3wka przewija si\u0119 osobno. Kontenerem przewijania jest ten div,\n a nie popup mapy \u2014 inaczej tytu\u0142 z krzy\u017Cykiem odje\u017Cd\u017Ca\u0142by razem ze zdj\u0119ciem.\n-->\n<div class=\"kpt-map-poi__scroll\">\n <div class=\"kpt-map-poi__media\">\n @if (poi().photo; as photo) {\n <img\n class=\"kpt-map-poi__photo\"\n [src]=\"photo\"\n [alt]=\"poi().photoAlt ?? poi().title\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n } @else {\n <div class=\"kpt-map-poi__photo-empty\" [attr.aria-label]=\"i18n.t('map.poi.noPhoto')\" role=\"img\">\n <kpt-icon name=\"photo\" size=\"1.75rem\" />\n </div>\n }\n </div>\n\n <div class=\"kpt-map-poi__actions\">\n @if (primaryLabel()) {\n <kpt-button class=\"kpt-map-poi__cta\" size=\"sm\" fullWidth (click)=\"onPrimary()\">\n {{ primaryLabel() }}\n </kpt-button>\n }\n @if (showShare()) {\n <kpt-icon-button\n variant=\"outline\"\n size=\"sm\"\n [ariaLabel]=\"i18n.t('map.poi.share')\"\n (click)=\"share()\"\n >\n <kpt-icon name=\"share\" />\n </kpt-icon-button>\n }\n @if (showFavourite()) {\n <kpt-icon-button\n class=\"kpt-map-poi__fav\"\n variant=\"outline\"\n size=\"sm\"\n [attr.aria-pressed]=\"favourite()\"\n [attr.data-on]=\"favourite() ? '' : null\"\n [ariaLabel]=\"favouriteLabel()\"\n (click)=\"toggleFavourite()\"\n >\n <kpt-icon name=\"star\" />\n </kpt-icon-button>\n }\n </div>\n\n @if (category(); as category) {\n <p class=\"kpt-map-poi__category\" [style.--_kpt-poi-color]=\"categoryColor()\">\n @if (category.icon) {\n <kpt-icon class=\"kpt-map-poi__category-icon\" [name]=\"category.icon\" />\n }\n {{ category.label }}\n </p>\n }\n\n @if (hasHours()) {\n <div class=\"kpt-map-poi__hours\">\n <button\n class=\"kpt-map-poi__hours-toggle\"\n type=\"button\"\n [attr.aria-expanded]=\"hoursExpanded()\"\n [attr.aria-controls]=\"hoursId\"\n (click)=\"toggleHours()\"\n >\n <kpt-icon class=\"kpt-map-poi__row-icon\" name=\"clock\" />\n <span class=\"kpt-map-poi__status\" [attr.data-open]=\"open() || alwaysOpen()\">\n {{ statusLabel() }}\n </span>\n @if (statusHint(); as hint) {\n <span class=\"kpt-map-poi__status-hint\">\u00B7 {{ hint }}</span>\n }\n <kpt-icon class=\"kpt-map-poi__chevron\" name=\"chevron-down\" />\n </button>\n\n @if (hoursExpanded()) {\n <dl class=\"kpt-map-poi__week\" [id]=\"hoursId\">\n @for (group of hoursGroups(); track group.label) {\n <dt class=\"kpt-map-poi__week-day\">{{ group.label }}</dt>\n <dd class=\"kpt-map-poi__week-hours\">\n @if (group.closed) {\n <span class=\"kpt-map-poi__week-closed\">{{ i18n.t('map.poi.closedDay') }}</span>\n } @else {\n @for (range of group.ranges; track range) {\n <span class=\"kpt-map-poi__week-range\">{{ range }}</span>\n }\n }\n </dd>\n }\n </dl>\n }\n </div>\n }\n\n @if (rows().length || poi().facts?.length) {\n <ul class=\"kpt-map-poi__rows\">\n @for (row of rows(); track row.kind) {\n <li class=\"kpt-map-poi__row\">\n <kpt-icon class=\"kpt-map-poi__row-icon\" [name]=\"row.icon\" />\n\n @if (row.href) {\n <a\n class=\"kpt-map-poi__row-value kpt-map-poi__row-link\"\n [href]=\"row.href\"\n [attr.target]=\"row.external ? '_blank' : null\"\n [attr.rel]=\"row.external ? 'noopener' : null\"\n >\n {{ row.text }}\n </a>\n } @else {\n <span class=\"kpt-map-poi__row-value\">{{ row.text }}</span>\n }\n\n <span class=\"kpt-map-poi__row-actions\">\n @if (row.href) {\n <a\n class=\"kpt-map-poi__row-action\"\n [href]=\"row.href\"\n [attr.target]=\"row.external ? '_blank' : null\"\n [attr.rel]=\"row.external ? 'noopener' : null\"\n [attr.aria-label]=\"row.actionLabel\"\n [title]=\"row.actionLabel\"\n >\n <kpt-icon [name]=\"row.actionIcon\" />\n </a>\n }\n @if (canCopy) {\n <button\n class=\"kpt-map-poi__row-action\"\n type=\"button\"\n [attr.aria-label]=\"i18n.t('map.poi.copy')\"\n [title]=\"i18n.t('map.poi.copy')\"\n (click)=\"copy(row)\"\n >\n <kpt-icon [name]=\"justCopied() === row.kind ? 'check' : 'copy'\" />\n </button>\n }\n </span>\n </li>\n }\n\n @for (fact of poi().facts ?? []; track fact.label) {\n <li class=\"kpt-map-poi__row kpt-map-poi__row--fact\">\n @if (fact.icon) {\n <kpt-icon class=\"kpt-map-poi__row-icon\" [name]=\"fact.icon\" />\n } @else {\n <span class=\"kpt-map-poi__row-icon\" aria-hidden=\"true\"></span>\n }\n <span class=\"kpt-map-poi__row-value\">\n <span class=\"kpt-map-poi__fact-label\">{{ fact.label }}</span>\n {{ fact.value }}\n </span>\n </li>\n }\n </ul>\n }\n\n <p class=\"kpt-map-poi__live\" aria-live=\"polite\">\n @if (justCopied()) {\n {{ i18n.t('map.poi.copied') }}\n }\n </p>\n</div>\n", styles: ["@charset \"UTF-8\";@layer kpt.components{.kpt-map-poi{display:flex;flex-direction:column;min-height:0;color:var(--kpt-color-on-surface);font-size:var(--kpt-font-size-sm);text-align:start}.kpt-map-poi__scroll{flex:0 1 auto;min-height:0;padding:0 var(--kpt-space-4) var(--kpt-space-4);overflow-y:auto;overscroll-behavior:contain}.kpt-map-poi__head{flex:none;padding:var(--kpt-space-4) var(--kpt-space-4) 0;display:flex;gap:var(--kpt-space-2);align-items:flex-start;justify-content:space-between}.kpt-map-poi__title{margin:0;font-size:var(--kpt-font-size-lg);font-weight:var(--kpt-font-weight-bold);line-height:1.25;letter-spacing:normal;text-transform:none}.kpt-map-poi__close{flex:none;margin:calc(var(--kpt-space-1) * -1) calc(var(--kpt-space-2) * -1) 0 0}.kpt-map-poi__meta{flex:none;display:flex;flex-wrap:wrap;gap:0 var(--kpt-space-2);margin:var(--kpt-space-1) 0 0;padding:0 var(--kpt-space-4) var(--kpt-space-3);border-bottom:var(--kpt-border-width-thin) solid var(--kpt-color-border)}.kpt-map-poi__distance{font-weight:var(--kpt-font-weight-bold)}.kpt-map-poi__address{color:var(--kpt-color-on-surface-muted)}.kpt-map-poi__media{margin-top:var(--kpt-space-4);overflow:hidden;border-radius:var(--kpt-map-poi-media-radius, var(--kpt-radius-md))}.kpt-map-poi__photo,.kpt-map-poi__photo-empty{display:block;width:100%;aspect-ratio:16/9}.kpt-map-poi__photo{object-fit:cover}.kpt-map-poi__photo-empty{display:grid;place-items:center;color:var(--kpt-color-text-subtle);background:var(--kpt-color-surface-sunken)}.kpt-map-poi__actions{display:flex;gap:var(--kpt-space-2);align-items:center;margin-top:var(--kpt-space-3);margin-bottom:var(--kpt-space-3)}.kpt-map-poi__cta{flex:1 1 auto;min-width:0}.kpt-map-poi__fav[data-on]{color:var(--kpt-color-warning);border-color:var(--kpt-color-warning-border)}.kpt-map-poi__category{display:flex;gap:var(--kpt-space-3);align-items:center;margin:0;padding:var(--kpt-space-3) 0;border-top:var(--kpt-border-width-thin) solid var(--kpt-color-border)}.kpt-map-poi__category-icon{color:var(--_kpt-poi-color, var(--kpt-color-primary))}.kpt-map-poi__hours{border-top:var(--kpt-border-width-thin) solid var(--kpt-color-border)}.kpt-map-poi__hours-toggle{display:flex;gap:var(--kpt-space-3);align-items:center;width:100%;padding:var(--kpt-space-3) 0;font:inherit;color:inherit;text-align:start;background:none;border:0;cursor:pointer}.kpt-map-poi__hours-toggle:focus-visible{outline:var(--kpt-border-width-medium) solid var(--kpt-color-focus-ring);outline-offset:calc(var(--kpt-space-1) * -1)}.kpt-map-poi__status{font-weight:var(--kpt-font-weight-medium);color:var(--kpt-color-danger)}.kpt-map-poi__status[data-open=true]{color:var(--kpt-color-success)}.kpt-map-poi__status-hint{color:var(--kpt-color-on-surface-muted)}.kpt-map-poi__chevron{margin-inline-start:auto;color:var(--kpt-color-on-surface-muted);transition:rotate var(--kpt-motion-duration-fast, .15s) ease}.kpt-map-poi__hours-toggle[aria-expanded=true] .kpt-map-poi__chevron{rotate:180deg}.kpt-map-poi__week{display:grid;grid-template-columns:auto 1fr;gap:var(--kpt-space-1) var(--kpt-space-4);margin:0;padding:0 0 var(--kpt-space-3) calc(1em + var(--kpt-space-3))}.kpt-map-poi__week-day{color:var(--kpt-color-on-surface-muted)}.kpt-map-poi__week-hours{display:flex;flex-direction:column;margin:0}.kpt-map-poi__week-closed{color:var(--kpt-color-on-surface-muted)}.kpt-map-poi__rows{margin:0;padding:0;list-style:none}.kpt-map-poi__row{display:flex;gap:var(--kpt-space-3);align-items:center;padding:var(--kpt-space-2) var(--kpt-space-2) var(--kpt-space-2) 0;margin-inline-start:calc(var(--kpt-space-2) * -1);padding-inline-start:var(--kpt-space-2);border-top:var(--kpt-border-width-thin) solid var(--kpt-color-border);border-radius:var(--kpt-radius-sm)}.kpt-map-poi__row:hover,.kpt-map-poi__row:focus-within{background:var(--kpt-map-poi-row-hover, var(--kpt-color-surface-hover))}.kpt-map-poi__row-icon{flex:none;color:var(--kpt-color-primary)}.kpt-map-poi__row-value{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}.kpt-map-poi__row-link{color:inherit;text-decoration:none}.kpt-map-poi__row-link:hover{text-decoration:underline}.kpt-map-poi__fact-label{color:var(--kpt-color-on-surface-muted)}.kpt-map-poi__fact-label:after{content:\" \\b7 \"}.kpt-map-poi__row-actions{display:flex;flex:none;gap:var(--kpt-space-1)}.kpt-map-poi__row-action{display:inline-grid;place-items:center;width:1.75rem;height:1.75rem;color:var(--kpt-color-on-surface-muted);background:none;border:0;border-radius:var(--kpt-radius-sm);cursor:pointer}.kpt-map-poi__row-action:hover{color:var(--kpt-color-primary);background:var(--kpt-color-surface-selected)}.kpt-map-poi__row-action:focus-visible{outline:var(--kpt-border-width-medium) solid var(--kpt-color-focus-ring);outline-offset:1px}@media(hover:hover)and (pointer:fine){.kpt-map-poi__row-actions{opacity:0;transition:opacity var(--kpt-motion-duration-fast, .15s) ease}.kpt-map-poi__row:hover .kpt-map-poi__row-actions,.kpt-map-poi__row:focus-within .kpt-map-poi__row-actions{opacity:1}}.kpt-map-poi__live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}}\n"] }]
4552
4583
  }], null, { poi: [{ type: i0.Input, args: [{ isSignal: true, alias: "poi", required: true }] }], distance: [{ type: i0.Input, args: [{ isSignal: true, alias: "distance", required: false }] }], category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], showShare: [{ type: i0.Input, args: [{ isSignal: true, alias: "showShare", required: false }] }], showFavourite: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFavourite", required: false }] }], favourite: [{ type: i0.Input, args: [{ isSignal: true, alias: "favourite", required: false }] }, { type: i0.Output, args: ["favouriteChange"] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], hoursExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursExpanded", required: false }] }, { type: i0.Output, args: ["hoursExpandedChange"] }], primaryAction: [{ type: i0.Output, args: ["primaryAction"] }], closed: [{ type: i0.Output, args: ["closed"] }], shared: [{ type: i0.Output, args: ["shared"] }] }); })();
4553
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KptMapPoiCard, { className: "KptMapPoiCard", filePath: "lib/map-poi-card.component.ts", lineNumber: 81 }); })();
4584
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KptMapPoiCard, { className: "KptMapPoiCard", filePath: "lib/map-poi-card.component.ts", lineNumber: 72 }); })();
4554
4585
 
4555
4586
  /*
4556
4587
  * Public API — @konce-pt/angular/map