@konce-pt/map 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  <p align="center">
2
- <img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI — Angular component library" width="100%" />
2
+ <img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI - Angular component library" width="100%" />
3
3
  </p>
4
4
 
5
5
  # @konce-pt/map
6
6
 
7
7
  Rdzeń mapy [Koncept UI](https://gitlab.com/konce-pt/koncept-ui): odwzorowanie i arytmetyka
8
- prostokątów, klastrowanie znaczników, godziny otwarcia, HTML znaczników, formatowanie — oraz
8
+ prostokątów, klastrowanie znaczników, godziny otwarcia, HTML znaczników, formatowanie - oraz
9
9
  adaptery silników Leaflet i Google. Czysty TypeScript, **zero zależności runtime**
10
10
  (`leaflet` to peer opcjonalny, ładowany dynamicznym `import()`).
11
11
 
@@ -20,7 +20,7 @@ npm i @konce-pt/map
20
20
  ```ts
21
21
  import { clusterLocations, zoomForBounds, isOpenAt, createLeafletEngine } from '@konce-pt/map';
22
22
 
23
- // Klastrowanie na siatce pikseli — wynik zależy od zoomu, nie od samych współrzędnych.
23
+ // Klastrowanie na siatce pikseli - wynik zależy od zoomu, nie od samych współrzędnych.
24
24
  clusterLocations(locations, 12, { gridSize: 60 });
25
25
 
26
26
  // Zoom, przy którym prostokąt mieści się w kontenerze.
@@ -35,16 +35,16 @@ const engine = createLeafletEngine({ maxZoom: 19 });
35
35
 
36
36
  ## API
37
37
 
38
- - **Geometria** — `project`, `unproject`, `boundsOf`, `boundsCenter`, `boundsContain`, `padBounds`,
38
+ - **Geometria** - `project`, `unproject`, `boundsOf`, `boundsCenter`, `boundsContain`, `padBounds`,
39
39
  `isFittableBounds`, `haversine`, `metersPerPixel`, `zoomForBounds`, `clampLat`, `normalizeLng`
40
- - **Klastry** — `clusterLocations`, `dominantCategory`, `countByCategory`, `isSplittable`
41
- - **Znaczniki** — `renderMarkerHtml`, `renderClusterHtml`, `renderUserMarkerHtml`, `colorVarOf`,
40
+ - **Klastry** - `clusterLocations`, `dominantCategory`, `countByCategory`, `isSplittable`
41
+ - **Znaczniki** - `renderMarkerHtml`, `renderClusterHtml`, `renderUserMarkerHtml`, `colorVarOf`,
42
42
  `contrastVarOf`, `foregroundVarOf`, `clusterTier`
43
- - **Godziny** — `parseTime`, `formatTime`, `isOpenAt`, `isAlwaysOpen`, `nextChange`, `groupWeek`
44
- - **Kraje i format** — `KPT_MAP_COUNTRIES`, `countryPreset`, `resolveCountryView`,
43
+ - **Godziny** - `parseTime`, `formatTime`, `isOpenAt`, `isAlwaysOpen`, `nextChange`, `groupWeek`
44
+ - **Kraje i format** - `KPT_MAP_COUNTRIES`, `countryPreset`, `resolveCountryView`,
45
45
  `formatDistance`, `formatLatLng`, `normalizeUrl`, `prettyUrl`
46
- - **Silniki** — `createLeafletEngine`, `createGoogleEngine`, `loadGoogleMapsApi`
47
- - **Typy** — `KptMapEngine`, `KptMapLocation`, `KptMapCategory`, `KptMapPoi` i reszta kontraktu
46
+ - **Silniki** - `createLeafletEngine`, `createGoogleEngine`, `loadGoogleMapsApi`
47
+ - **Typy** - `KptMapEngine`, `KptMapLocation`, `KptMapCategory`, `KptMapPoi` i reszta kontraktu
48
48
 
49
49
  Pełny opis: [`llms.txt`](https://ui.konce.pt/llms/map/llms.txt) (EN)
50
50
  i [`llms-pl.txt`](https://ui.konce.pt/llms/map/llms-pl.txt) (PL).
package/dist/cluster.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { KptMapCluster, KptMapClusterEntry, KptMapLocation } from './types.ts';
2
2
  export interface KptClusterOptions {
3
- /** Aktualny zoom mapy — decyduje o gęstości siatki. */
3
+ /** Aktualny zoom mapy - decyduje o gęstości siatki. */
4
4
  zoom: number;
5
5
  /** Bok komórki siatki w pikselach ekranu. Domyślnie 60. */
6
6
  gridSize?: number;
@@ -9,7 +9,7 @@ export interface KptClusterOptions {
9
9
  /** Ile punktów musi trafić do komórki, żeby powstała grupa. Domyślnie 2. */
10
10
  minPoints?: number;
11
11
  /**
12
- * Kolejność kategorii — rozstrzyga remis przy wyborze kategorii dominującej.
12
+ * Kolejność kategorii - rozstrzyga remis przy wyborze kategorii dominującej.
13
13
  * Bez niej remis rozstrzyga kolejność wystąpienia w danych.
14
14
  */
15
15
  categoryOrder?: readonly string[];
@@ -24,18 +24,18 @@ export declare const KPT_CLUSTER_DEFAULTS: {
24
24
  *
25
25
  * Środek grupy uśredniamy w przestrzeni pikseli, nie w stopniach. Mercator rozciąga
26
26
  * stopnie tym mocniej, im dalej od równika, więc średnia w stopniach wypada obok
27
- * wizualnego środka kropek na ekranie — a to jego ma pilnować znacznik grupy.
27
+ * wizualnego środka kropek na ekranie - a to jego ma pilnować znacznik grupy.
28
28
  */
29
29
  export declare function clusterLocations<T>(locations: readonly KptMapLocation<T>[], options: KptClusterOptions): KptMapClusterEntry<T>[];
30
30
  /**
31
31
  * Najliczniejsza kategoria w grupie. Remis rozstrzyga `categoryOrder`, a bez niej
32
- * kolejność pierwszego wystąpienia — w obu wypadkach wynik jest deterministyczny.
32
+ * kolejność pierwszego wystąpienia - w obu wypadkach wynik jest deterministyczny.
33
33
  */
34
34
  export declare function dominantCategory<T>(items: readonly KptMapLocation<T>[], categoryOrder?: readonly string[]): string;
35
- /** Zlicza lokalizacje w rozbiciu na kategorie — licznik obok pozycji legendy. */
35
+ /** Zlicza lokalizacje w rozbiciu na kategorie - licznik obok pozycji legendy. */
36
36
  export declare function countByCategory<T>(locations: readonly KptMapLocation<T>[]): Record<string, number>;
37
37
  /**
38
38
  * Czy grupa da się rozbić przybliżeniem. Punkty o tej samej współrzędnej zostaną razem
39
- * na każdym zoomie — wtedy kliknięcie ma otworzyć listę zamiast zoomować w nieskończoność.
39
+ * na każdym zoomie - wtedy kliknięcie ma otworzyć listę zamiast zoomować w nieskończoność.
40
40
  */
41
41
  export declare function isSplittable<T>(cluster: KptMapCluster<T>): boolean;
package/dist/cluster.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Grupowanie znaczników — siatka w przestrzeni pikseli, O(n), deterministyczna.
2
+ * Grupowanie znaczników - siatka w przestrzeni pikseli, O(n), deterministyczna.
3
3
  * Pure TS: ten sam kod obsługuje silnik Leaflet i Google Maps, i przenosi się do Reacta.
4
4
  */
5
5
  import { boundsOf, project, unproject } from "./geo.js";
@@ -13,7 +13,7 @@ export const KPT_CLUSTER_DEFAULTS = {
13
13
  *
14
14
  * Środek grupy uśredniamy w przestrzeni pikseli, nie w stopniach. Mercator rozciąga
15
15
  * stopnie tym mocniej, im dalej od równika, więc średnia w stopniach wypada obok
16
- * wizualnego środka kropek na ekranie — a to jego ma pilnować znacznik grupy.
16
+ * wizualnego środka kropek na ekranie - a to jego ma pilnować znacznik grupy.
17
17
  */
18
18
  export function clusterLocations(locations, options) {
19
19
  const gridSize = options.gridSize ?? KPT_CLUSTER_DEFAULTS.gridSize;
@@ -22,7 +22,7 @@ export function clusterLocations(locations, options) {
22
22
  const zoom = options.zoom;
23
23
  if (locations.length === 0)
24
24
  return [];
25
- // Powyżej progu pokazujemy wszystko osobno — użytkownik przybliżył się celowo.
25
+ // Powyżej progu pokazujemy wszystko osobno - użytkownik przybliżył się celowo.
26
26
  if (zoom > maxZoom || gridSize <= 0)
27
27
  return [...locations];
28
28
  const cells = new Map();
@@ -62,7 +62,7 @@ export function clusterLocations(locations, options) {
62
62
  }
63
63
  /**
64
64
  * Najliczniejsza kategoria w grupie. Remis rozstrzyga `categoryOrder`, a bez niej
65
- * kolejność pierwszego wystąpienia — w obu wypadkach wynik jest deterministyczny.
65
+ * kolejność pierwszego wystąpienia - w obu wypadkach wynik jest deterministyczny.
66
66
  */
67
67
  export function dominantCategory(items, categoryOrder) {
68
68
  const counts = new Map();
@@ -82,7 +82,7 @@ export function dominantCategory(items, categoryOrder) {
82
82
  }
83
83
  if (count < bestCount)
84
84
  continue;
85
- // Remis — niższy indeks w `categoryOrder` wygrywa, a poza nią wcześniejsze wystąpienie.
85
+ // Remis - niższy indeks w `categoryOrder` wygrywa, a poza nią wcześniejsze wystąpienie.
86
86
  const rank = (c) => {
87
87
  const i = categoryOrder?.indexOf(c) ?? -1;
88
88
  return i >= 0 ? i : Number.MAX_SAFE_INTEGER;
@@ -93,7 +93,7 @@ export function dominantCategory(items, categoryOrder) {
93
93
  }
94
94
  return best;
95
95
  }
96
- /** Zlicza lokalizacje w rozbiciu na kategorie — licznik obok pozycji legendy. */
96
+ /** Zlicza lokalizacje w rozbiciu na kategorie - licznik obok pozycji legendy. */
97
97
  export function countByCategory(locations) {
98
98
  const out = {};
99
99
  for (const loc of locations)
@@ -102,7 +102,7 @@ export function countByCategory(locations) {
102
102
  }
103
103
  /**
104
104
  * Czy grupa da się rozbić przybliżeniem. Punkty o tej samej współrzędnej zostaną razem
105
- * na każdym zoomie — wtedy kliknięcie ma otworzyć listę zamiast zoomować w nieskończoność.
105
+ * na każdym zoomie - wtedy kliknięcie ma otworzyć listę zamiast zoomować w nieskończoność.
106
106
  */
107
107
  export function isSplittable(cluster) {
108
108
  const { south, west, north, east } = cluster.bounds;
@@ -3,25 +3,25 @@ export interface KptMapCountryPreset {
3
3
  /** Kod ISO 3166-1 alpha-2 (albo `EU` dla całego kontynentu). */
4
4
  code: string;
5
5
  center: KptLatLng;
6
- /** Zoom, przy którym kraj mieści się na typowym kontenerze (~1000×600 px). */
6
+ /** Zoom, przy którym kraj mieści się na typowym kontenerze (~1000x600 px). */
7
7
  zoom: number;
8
8
  bounds: KptMapBounds;
9
9
  }
10
10
  /** Kod kraju użyty, gdy aplikacja nie poda żadnego. */
11
11
  export declare const KPT_MAP_DEFAULT_COUNTRY = "PL";
12
12
  /**
13
- * Zasięgi lądowe (bez terytoriów zamorskich) zaokrąglone do dwóch miejsc —
13
+ * Zasięgi lądowe (bez terytoriów zamorskich) zaokrąglone do dwóch miejsc -
14
14
  * to widok startowy, nie granica administracyjna.
15
15
  */
16
16
  export declare const KPT_MAP_COUNTRIES: Record<string, KptMapCountryPreset>;
17
17
  /** Preset kraju po kodzie (wielkość liter bez znaczenia); `undefined`, gdy nieznany. */
18
18
  export declare function countryPreset(code: string): KptMapCountryPreset | undefined;
19
- /** Kody wszystkich presetów — do listy wyboru w aplikacji. */
19
+ /** Kody wszystkich presetów - do listy wyboru w aplikacji. */
20
20
  export declare function countryCodes(): string[];
21
21
  /**
22
22
  * Widok startowy: preset kraju, a przy nieznanym kodzie preset domyślny.
23
- * Zawsze zwraca coś sensownego — mapa nigdy nie startuje na `[0, 0]`.
23
+ * Zawsze zwraca coś sensownego - mapa nigdy nie startuje na `[0, 0]`.
24
24
  */
25
25
  export declare function resolveCountryView(code: string | null | undefined): KptMapCountryPreset;
26
- /** Środek prostokąta kraju — pomocnicze przy własnych `bounds`. */
26
+ /** Środek prostokąta kraju - pomocnicze przy własnych `bounds`. */
27
27
  export declare function centerOfBounds(bounds: KptMapBounds): KptLatLng;
package/dist/countries.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /*
2
- * Presety widoku bazowego — pure TS. Domyślny kraj to Polska.
2
+ * Presety widoku bazowego - pure TS. Domyślny kraj to Polska.
3
3
  * Kto potrzebuje kraju spoza listy, podaje `[view]` albo `[bounds]` wprost.
4
4
  */
5
5
  import { boundsCenter } from "./geo.js";
6
6
  /** Kod kraju użyty, gdy aplikacja nie poda żadnego. */
7
7
  export const KPT_MAP_DEFAULT_COUNTRY = 'PL';
8
8
  /**
9
- * Zasięgi lądowe (bez terytoriów zamorskich) zaokrąglone do dwóch miejsc —
9
+ * Zasięgi lądowe (bez terytoriów zamorskich) zaokrąglone do dwóch miejsc -
10
10
  * to widok startowy, nie granica administracyjna.
11
11
  */
12
12
  export const KPT_MAP_COUNTRIES = {
@@ -33,18 +33,18 @@ export const KPT_MAP_COUNTRIES = {
33
33
  export function countryPreset(code) {
34
34
  return KPT_MAP_COUNTRIES[code?.toUpperCase()];
35
35
  }
36
- /** Kody wszystkich presetów — do listy wyboru w aplikacji. */
36
+ /** Kody wszystkich presetów - do listy wyboru w aplikacji. */
37
37
  export function countryCodes() {
38
38
  return Object.keys(KPT_MAP_COUNTRIES);
39
39
  }
40
40
  /**
41
41
  * Widok startowy: preset kraju, a przy nieznanym kodzie preset domyślny.
42
- * Zawsze zwraca coś sensownego — mapa nigdy nie startuje na `[0, 0]`.
42
+ * Zawsze zwraca coś sensownego - mapa nigdy nie startuje na `[0, 0]`.
43
43
  */
44
44
  export function resolveCountryView(code) {
45
45
  return (code ? countryPreset(code) : undefined) ?? KPT_MAP_COUNTRIES[KPT_MAP_DEFAULT_COUNTRY];
46
46
  }
47
- /** Środek prostokąta kraju — pomocnicze przy własnych `bounds`. */
47
+ /** Środek prostokąta kraju - pomocnicze przy własnych `bounds`. */
48
48
  export function centerOfBounds(bounds) {
49
49
  return boundsCenter(bounds);
50
50
  }
package/dist/engine.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { KptLatLng, KptMapBounds, KptMapPoint, KptMapUserPosition } from './types.ts';
2
- /** Rodzaj silnika — trafia do `data-engine` na hoście, przydatne w testach i stylach. */
2
+ /** Rodzaj silnika - trafia do `data-engine` na hoście, przydatne w testach i stylach. */
3
3
  export type KptMapEngineKind = 'leaflet' | 'google';
4
4
  export interface KptMapEngineInit {
5
5
  center: KptLatLng;
@@ -10,25 +10,25 @@ export interface KptMapEngineInit {
10
10
  maxBounds?: KptMapBounds | null;
11
11
  /** Szablon URL kafli, np. `https://tile.openstreetmap.org/{z}/{x}/{y}.png`. */
12
12
  tileUrl: string;
13
- /** Tekst atrybucji — wymagany licencyjnie przy OSM. */
13
+ /** Tekst atrybucji - wymagany licencyjnie przy OSM. */
14
14
  attribution: string;
15
- /** Silnik nie rysuje własnych kontrolek zoomu — robi to warstwa Angulara. */
15
+ /** Silnik nie rysuje własnych kontrolek zoomu - robi to warstwa Angulara. */
16
16
  interactive?: boolean;
17
17
  }
18
- /** Znacznik gotowy do narysowania — HTML pochodzi z `marker-html.ts`. */
18
+ /** Znacznik gotowy do narysowania - HTML pochodzi z `marker-html.ts`. */
19
19
  export interface KptMapRenderedMarker {
20
20
  /** Stabilne id: `id` lokalizacji albo `id` grupy. */
21
21
  id: string;
22
22
  at: KptLatLng;
23
23
  html: string;
24
- /** Rozmiar ikony w pikselach — silnik potrzebuje go do zakotwiczenia. */
24
+ /** Rozmiar ikony w pikselach - silnik potrzebuje go do zakotwiczenia. */
25
25
  size: {
26
26
  width: number;
27
27
  height: number;
28
28
  };
29
29
  /** Punkt zakotwiczenia względem lewego górnego rogu ikony. */
30
30
  anchor: KptMapPoint;
31
- /** Kolejność rysowania — grupy nad pojedynczymi punktami. */
31
+ /** Kolejność rysowania - grupy nad pojedynczymi punktami. */
32
32
  zIndex?: number;
33
33
  }
34
34
  export interface KptMapPointerEvent {
@@ -39,9 +39,9 @@ export interface KptMapPointerEvent {
39
39
  originalEvent?: Event;
40
40
  }
41
41
  export interface KptMapEngineEvents {
42
- /** Pan i zoom w toku — używane do przeliczania pozycji popupu. */
42
+ /** Pan i zoom w toku - używane do przeliczania pozycji popupu. */
43
43
  move: () => void;
44
- /** Koniec ruchu — dopiero tu warto emitować `viewChange`. */
44
+ /** Koniec ruchu - dopiero tu warto emitować `viewChange`. */
45
45
  moveend: () => void;
46
46
  zoomend: () => void;
47
47
  click: (event: KptMapPointerEvent) => void;
@@ -64,7 +64,7 @@ export interface KptMapEngine {
64
64
  width: number;
65
65
  height: number;
66
66
  };
67
- /** Współrzędne → piksele WZGLĘDEM kontenera (pozycjonowanie popupu). */
67
+ /** Współrzędne -> piksele WZGLĘDEM kontenera (pozycjonowanie popupu). */
68
68
  project(at: KptLatLng): KptMapPoint;
69
69
  unproject(point: KptMapPoint): KptLatLng;
70
70
  /** Pełna wymiana zestawu znaczników; diff po `id` robi implementacja. */
@@ -73,12 +73,12 @@ export interface KptMapEngine {
73
73
  setUserPosition(position: KptMapUserPosition | null, html: string): void;
74
74
  setTileSource(tileUrl: string, attribution: string): void;
75
75
  setMaxBounds(bounds: KptMapBounds | null): void;
76
- /** Kontener zmienił rozmiar — bez tego Leaflet zostawia szare pola. */
76
+ /** Kontener zmienił rozmiar - bez tego Leaflet zostawia szare pola. */
77
77
  invalidateSize(): void;
78
78
  on<K extends keyof KptMapEngineEvents>(event: K, handler: KptMapEngineEvents[K]): void;
79
79
  }
80
- /** Fabryka silnika — to ją dostarcza DI, żeby każda mapa miała własną instancję. */
80
+ /** Fabryka silnika - to ją dostarcza DI, żeby każda mapa miała własną instancję. */
81
81
  export type KptMapEngineFactory = () => KptMapEngine;
82
- /** Domyślne źródło kafli. Do produkcji podstaw własny serwer — patrz llms.txt. */
82
+ /** Domyślne źródło kafli. Do produkcji podstaw własny serwer - patrz llms.txt. */
83
83
  export declare const KPT_MAP_DEFAULT_TILE_URL = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
84
84
  export declare const KPT_MAP_DEFAULT_ATTRIBUTION = "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors";
package/dist/engine.js CHANGED
@@ -1,3 +1,3 @@
1
- /** Domyślne źródło kafli. Do produkcji podstaw własny serwer — patrz llms.txt. */
1
+ /** Domyślne źródło kafli. Do produkcji podstaw własny serwer - patrz llms.txt. */
2
2
  export const KPT_MAP_DEFAULT_TILE_URL = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
3
3
  export const KPT_MAP_DEFAULT_ATTRIBUTION = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
@@ -1,6 +1,6 @@
1
1
  import type { KptMapEngine } from '../engine.ts';
2
2
  /**
3
- * Namespace `google.maps`. Świadomie `any` — pełne typy przychodzą z opcjonalnego
3
+ * Namespace `google.maps`. Świadomie `any` - pełne typy przychodzą z opcjonalnego
4
4
  * `@types/google.maps`, a biblioteka nie może od nich zależeć przy kompilacji.
5
5
  */
6
6
  export type KptGoogleMapsApi = any;
@@ -8,10 +8,10 @@ export interface KptGoogleOptions {
8
8
  /** Klucz API z Google Cloud. Wymagany. */
9
9
  apiKey: string;
10
10
  /**
11
- * Identyfikator stylu mapy z konsoli Google (*Map management → Create Map ID*).
11
+ * Identyfikator stylu mapy z konsoli Google (*Map management -> Create Map ID*).
12
12
  *
13
13
  * **Wymagany.** Bez niego nie działa `AdvancedMarkerElement`, a znaczniki tej biblioteki
14
- * to gotowy HTML z `marker-html.ts` — starsze `Marker` nie umie go przyjąć.
14
+ * to gotowy HTML z `marker-html.ts` - starsze `Marker` nie umie go przyjąć.
15
15
  */
16
16
  mapId: string;
17
17
  /** Wersja API. Domyślnie `weekly`. */
@@ -20,7 +20,7 @@ export interface KptGoogleOptions {
20
20
  language?: string;
21
21
  /** Region wpływający na nazewnictwo i granice sporne (ISO 3166-1 alpha-2). */
22
22
  region?: string;
23
- /** Dolny limit zoomu. Domyślnie 2 — niżej świat powtarza się w poziomie. */
23
+ /** Dolny limit zoomu. Domyślnie 2 - niżej świat powtarza się w poziomie. */
24
24
  minZoom?: number;
25
25
  /** Górny limit zoomu. Domyślnie 21. */
26
26
  maxZoom?: number;
@@ -28,24 +28,24 @@ export interface KptGoogleOptions {
28
28
  scrollWheelZoom?: boolean;
29
29
  }
30
30
  /**
31
- * Tyle z `KptGoogleOptions`, ile trzeba do wczytania samego API. Bez `mapId` — ten dotyczy
31
+ * Tyle z `KptGoogleOptions`, ile trzeba do wczytania samego API. Bez `mapId` - ten dotyczy
32
32
  * wyglądu mapy, a API potrzebują też usługi, które żadnej mapy nie rysują.
33
33
  */
34
34
  export type KptGoogleLoadOptions = Pick<KptGoogleOptions, 'apiKey' | 'version' | 'language' | 'region'>;
35
35
  /**
36
- * Ładuje Google Maps JavaScript API raz na aplikację. Gdy `google.maps` już istnieje — bo
37
- * aplikacja wstawiła skrypt sama albo stoi tu druga mapa — korzystamy z tego, co jest: drugie
36
+ * Ładuje Google Maps JavaScript API raz na aplikację. Gdy `google.maps` już istnieje - bo
37
+ * aplikacja wstawiła skrypt sama albo stoi tu druga mapa - korzystamy z tego, co jest: drugie
38
38
  * wczytanie Google i tak odrzuca, wypisując ostrzeżenie do konsoli.
39
39
  *
40
40
  * Publiczne, bo silnik nie jest jedynym, kto tego API potrzebuje. Geokoder Google **musi**
41
41
  * iść przez SDK, a nie przez REST: web service `/maps/api/geocode/json` odrzuca klucze
42
- * z restrykcją `Referer` („API keys with referer restrictions cannot be used with this API"),
42
+ * z restrykcją `Referer` ("API keys with referer restrictions cannot be used with this API"),
43
43
  * a to jedyna restrykcja, jaką da się sensownie nałożyć na klucz leżący w bundlu przeglądarki.
44
44
  * Wywołania z załadowanego SDK autoryzują się tak samo jak sama mapa.
45
45
  *
46
- * Adaptera geokodera biblioteka nadal nie dostarcza — tylko drogę do API, którą i tak
46
+ * Adaptera geokodera biblioteka nadal nie dostarcza - tylko drogę do API, którą i tak
47
47
  * otwiera silnikowi. Powody stoją przy `provideKptGoogleMap` i w `llms.txt`.
48
48
  */
49
49
  export declare function loadGoogleMapsApi(options: KptGoogleLoadOptions): Promise<KptGoogleMapsApi>;
50
- /** Fabryka silnika — każda mapa dostaje własną instancję. */
50
+ /** Fabryka silnika - każda mapa dostaje własną instancję. */
51
51
  export declare function createGoogleEngine(options: KptGoogleOptions): KptMapEngine;
@@ -6,17 +6,17 @@ const LOAD_ERROR = 'kpt-map: nie udało się załadować Google Maps JavaScript
6
6
  const CALLBACK = '__kptGoogleMapsReady';
7
7
  let modulePromise = null;
8
8
  /**
9
- * Ładuje Google Maps JavaScript API raz na aplikację. Gdy `google.maps` już istnieje — bo
10
- * aplikacja wstawiła skrypt sama albo stoi tu druga mapa — korzystamy z tego, co jest: drugie
9
+ * Ładuje Google Maps JavaScript API raz na aplikację. Gdy `google.maps` już istnieje - bo
10
+ * aplikacja wstawiła skrypt sama albo stoi tu druga mapa - korzystamy z tego, co jest: drugie
11
11
  * wczytanie Google i tak odrzuca, wypisując ostrzeżenie do konsoli.
12
12
  *
13
13
  * Publiczne, bo silnik nie jest jedynym, kto tego API potrzebuje. Geokoder Google **musi**
14
14
  * iść przez SDK, a nie przez REST: web service `/maps/api/geocode/json` odrzuca klucze
15
- * z restrykcją `Referer` („API keys with referer restrictions cannot be used with this API"),
15
+ * z restrykcją `Referer` ("API keys with referer restrictions cannot be used with this API"),
16
16
  * a to jedyna restrykcja, jaką da się sensownie nałożyć na klucz leżący w bundlu przeglądarki.
17
17
  * Wywołania z załadowanego SDK autoryzują się tak samo jak sama mapa.
18
18
  *
19
- * Adaptera geokodera biblioteka nadal nie dostarcza — tylko drogę do API, którą i tak
19
+ * Adaptera geokodera biblioteka nadal nie dostarcza - tylko drogę do API, którą i tak
20
20
  * otwiera silnikowi. Powody stoją przy `provideKptGoogleMap` i w `llms.txt`.
21
21
  */
22
22
  export async function loadGoogleMapsApi(options) {
@@ -52,7 +52,7 @@ export async function loadGoogleMapsApi(options) {
52
52
  });
53
53
  return modulePromise;
54
54
  }
55
- /** Fabryka silnika — każda mapa dostaje własną instancję. */
55
+ /** Fabryka silnika - każda mapa dostaje własną instancję. */
56
56
  export function createGoogleEngine(options) {
57
57
  return new GoogleEngine(options);
58
58
  }
@@ -65,18 +65,18 @@ class GoogleEngine {
65
65
  this.map = null;
66
66
  this.host = null;
67
67
  this.userMarker = null;
68
- /** Krąg dokładności jest własnym `<div>`, nie `google.maps.Circle` — patrz `setUserPosition`. */
68
+ /** Krąg dokładności jest własnym `<div>`, nie `google.maps.Circle` - patrz `setUserPosition`. */
69
69
  this.accuracyEl = null;
70
70
  this.accuracyMeters = 0;
71
71
  this.accuracyAt = null;
72
- /** Znaczniki po `id` wraz z ich sprzątaniem — bez tego każdy przelicz przerysowywałby mapę. */
72
+ /** Znaczniki po `id` wraz z ich sprzątaniem - bez tego każdy przelicz przerysowywałby mapę. */
73
73
  this.markers = new Map();
74
74
  this.listeners = [];
75
75
  this.handlers = {};
76
76
  }
77
77
  async init(host, opts) {
78
78
  const maps = (this.maps = await loadGoogleMapsApi(this.options));
79
- // Pod nazwą `Map` kryje się konstruktor Google, nie wbudowana kolekcja — stąd alias.
79
+ // Pod nazwą `Map` kryje się konstruktor Google, nie wbudowana kolekcja - stąd alias.
80
80
  const [{ Map: GoogleMap }, markerLib] = await Promise.all([
81
81
  maps.importLibrary('maps'),
82
82
  maps.importLibrary('marker'),
@@ -89,9 +89,9 @@ class GoogleEngine {
89
89
  minZoom: opts.minZoom ?? this.options.minZoom ?? 2,
90
90
  maxZoom: opts.maxZoom ?? this.options.maxZoom ?? 21,
91
91
  mapId: this.options.mapId,
92
- // Kontrolki rysuje warstwa Angulara — te same przyciski w obu silnikach.
92
+ // Kontrolki rysuje warstwa Angulara - te same przyciski w obu silnikach.
93
93
  disableDefaultUI: true,
94
- // POI Google przechwytywałyby kliknięcia przeznaczone dla mapy (menu „dodaj lokalizację").
94
+ // POI Google przechwytywałyby kliknięcia przeznaczone dla mapy (menu "dodaj lokalizację").
95
95
  clickableIcons: false,
96
96
  scrollwheel: this.options.scrollWheelZoom ?? true,
97
97
  restriction: opts.maxBounds
@@ -109,7 +109,7 @@ class GoogleEngine {
109
109
  });
110
110
  this.on_(this.map, 'click', (e) => this.emit('click', this.toPointerEvent(e)));
111
111
  this.on_(this.map, 'contextmenu', (e) => {
112
- // Menu przeglądarki zasłoniłoby własne „Dodaj lokalizację".
112
+ // Menu przeglądarki zasłoniłoby własne "Dodaj lokalizację".
113
113
  e.domEvent?.preventDefault();
114
114
  this.emit('contextmenu', this.toPointerEvent(e));
115
115
  });
@@ -132,7 +132,7 @@ class GoogleEngine {
132
132
  for (const listener of this.listeners)
133
133
  listener.remove?.();
134
134
  this.listeners.length = 0;
135
- // Google nie ma odpowiednika `map.remove()` — kontener czyścimy sami.
135
+ // Google nie ma odpowiednika `map.remove()` - kontener czyścimy sami.
136
136
  if (this.map)
137
137
  this.maps?.event.clearInstanceListeners(this.map);
138
138
  this.host?.replaceChildren();
@@ -165,7 +165,7 @@ class GoogleEngine {
165
165
  return this.map.getZoom();
166
166
  }
167
167
  /**
168
- * Zasięg widoku. `getBounds()` bywa `undefined`, zanim mapa policzy pierwszy układ —
168
+ * Zasięg widoku. `getBounds()` bywa `undefined`, zanim mapa policzy pierwszy układ -
169
169
  * liczymy go wtedy z rdzenia, zamiast oddawać `null` przez kontrakt, który go nie przewiduje.
170
170
  */
171
171
  getBounds() {
@@ -185,12 +185,12 @@ class GoogleEngine {
185
185
  return { width: rect?.width ?? 0, height: rect?.height ?? 0 };
186
186
  }
187
187
  /**
188
- * Współrzędne → piksele kontenera.
188
+ * Współrzędne -> piksele kontenera.
189
189
  *
190
190
  * Świadomie **nie** przez `map.getProjection()`: ten zwraca `null` do pierwszego
191
191
  * `projection_changed` i tak czy owak wymaga ręcznego przeliczenia na piksele kontenera.
192
- * Rdzeń (`core/geo.ts`) ma dokładnie tę matematykę — tę samą, na której stoi grupowanie
193
- * i adapter Leafleta — więc popup ląduje piksel w piksel tak samo w obu silnikach.
192
+ * Rdzeń (`core/geo.ts`) ma dokładnie tę matematykę - tę samą, na której stoi grupowanie
193
+ * i adapter Leafleta - więc popup ląduje piksel w piksel tak samo w obu silnikach.
194
194
  * Działa też dla zoomu ułamkowego, którego Google używa przy gestach.
195
195
  */
196
196
  project(at) {
@@ -210,7 +210,7 @@ class GoogleEngine {
210
210
  return unproject({ x: origin.x + point.x - size.width / 2, y: origin.y + point.y - size.height / 2 }, zoom);
211
211
  }
212
212
  /**
213
- * Wymienia zestaw znaczników różnicowo — znaczniki o niezmienionym `id` zostają na miejscu,
213
+ * Wymienia zestaw znaczników różnicowo - znaczniki o niezmienionym `id` zostają na miejscu,
214
214
  * inaczej każdy przelicz gasiłby animacje i migotał.
215
215
  */
216
216
  setMarkers(next) {
@@ -241,7 +241,7 @@ class GoogleEngine {
241
241
  * `L.DomEvent.stopPropagation`: bez zatrzymania propagacji to samo kliknięcie doszłoby
242
242
  * do mapy i `onMapClick()` zamknąłby popup w tej samej klatce, w której go otwieramy.
243
243
  * Przy okazji odpada zależność od tego, jak `gmp-click` zachowuje się w danej wersji API.
244
- * Dostępność bez zmian — etykietę niesie `aria-label` w HTML-u ikony.
244
+ * Dostępność bez zmian - etykietę niesie `aria-label` w HTML-u ikony.
245
245
  */
246
246
  const onClick = (event) => {
247
247
  event.stopPropagation();
@@ -286,13 +286,13 @@ class GoogleEngine {
286
286
  map: this.map,
287
287
  position: at,
288
288
  content: this.buildUserContent(html),
289
- // Nad znacznikami lokalizacji — własne położenie ma być zawsze widoczne.
289
+ // Nad znacznikami lokalizacji - własne położenie ma być zawsze widoczne.
290
290
  zIndex: 1000,
291
291
  });
292
292
  }
293
293
  this.resizeAccuracy();
294
294
  }
295
- /** Google dostarcza własne kafle i własną atrybucję — nie ma czego podmieniać. */
295
+ /** Google dostarcza własne kafle i własną atrybucję - nie ma czego podmieniać. */
296
296
  setTileSource() {
297
297
  // celowo puste
298
298
  }
@@ -301,14 +301,14 @@ class GoogleEngine {
301
301
  restriction: bounds ? { latLngBounds: this.toLatLngBounds(bounds), strictBounds: true } : null,
302
302
  });
303
303
  }
304
- /** Google sam reaguje na zmianę rozmiaru kontenera — nie ma odpowiednika `invalidateSize`. */
304
+ /** Google sam reaguje na zmianę rozmiaru kontenera - nie ma odpowiednika `invalidateSize`. */
305
305
  invalidateSize() {
306
306
  // celowo puste
307
307
  }
308
308
  on(event, handler) {
309
309
  (this.handlers[event] ??= []).push(handler);
310
310
  }
311
- // ── prywatne ────────────────────────────────────────────────────────────────
311
+ // -- prywatne ----------------------------------------------------------------
312
312
  emit(event, ...args) {
313
313
  for (const handler of this.handlers[event] ?? []) {
314
314
  handler(...args);
@@ -321,7 +321,7 @@ class GoogleEngine {
321
321
  /**
322
322
  * Opakowanie znacznika. `AdvancedMarkerElement` kotwiczy treść **środkiem dolnej krawędzi**,
323
323
  * a kontrakt daje kotwicę w pikselach od lewego górnego rogu ikony. Element zewnętrzny ma
324
- * więc zerowe wymiary — jego „środek dolnej krawędzi" wypada dokładnie we współrzędnych —
324
+ * więc zerowe wymiary - jego "środek dolnej krawędzi" wypada dokładnie we współrzędnych -
325
325
  * a wewnętrzny przesuwa ikonę o żądaną kotwicę.
326
326
  */
327
327
  buildMarkerContent(m) {
@@ -339,7 +339,7 @@ class GoogleEngine {
339
339
  inner.style.top = `${-m.anchor.y}px`;
340
340
  inner.style.width = `${m.size.width}px`;
341
341
  inner.style.height = `${m.size.height}px`;
342
- // HTML pochodzi z `marker-html.ts` — z rdzenia biblioteki, nie od użytkownika.
342
+ // HTML pochodzi z `marker-html.ts` - z rdzenia biblioteki, nie od użytkownika.
343
343
  inner.innerHTML = m.html;
344
344
  }
345
345
  /**
@@ -383,7 +383,7 @@ class GoogleEngine {
383
383
  fromDomEvent(event, at) {
384
384
  return { at, point: this.toContainerPoint(event), originalEvent: event };
385
385
  }
386
- /** Google podaje zdarzenie DOM bez pozycji w kontenerze — liczymy ją z prostokąta hosta. */
386
+ /** Google podaje zdarzenie DOM bez pozycji w kontenerze - liczymy ją z prostokąta hosta. */
387
387
  toContainerPoint(event) {
388
388
  const rect = this.host?.getBoundingClientRect();
389
389
  if (!event || !rect)
@@ -1,6 +1,6 @@
1
1
  import type { KptMapEngine } from '../engine.ts';
2
2
  export interface KptLeafletOptions {
3
- /** Dolny limit zoomu. Domyślnie 2 — niżej świat powtarza się w poziomie. */
3
+ /** Dolny limit zoomu. Domyślnie 2 - niżej świat powtarza się w poziomie. */
4
4
  minZoom?: number;
5
5
  /** Górny limit zoomu. Domyślnie 19 (tyle daje OSM). */
6
6
  maxZoom?: number;
@@ -9,5 +9,5 @@ export interface KptLeafletOptions {
9
9
  /** Zoom kółkiem myszy. Domyślnie włączony. */
10
10
  scrollWheelZoom?: boolean;
11
11
  }
12
- /** Fabryka silnika — każda mapa dostaje własną instancję. */
12
+ /** Fabryka silnika - każda mapa dostaje własną instancję. */
13
13
  export declare function createLeafletEngine(options?: KptLeafletOptions): KptMapEngine;
@@ -1,10 +1,10 @@
1
1
  const MODULE_LOAD_ERROR = 'kpt-map: nie udało się załadować biblioteki `leaflet`. ' +
2
- 'To zależność opcjonalna — zainstaluj ją w aplikacji: `pnpm add leaflet` ' +
2
+ 'To zależność opcjonalna - zainstaluj ją w aplikacji: `pnpm add leaflet` ' +
3
3
  '(oraz dołącz `leaflet/dist/leaflet.css`).';
4
4
  let modulePromise = null;
5
5
  /**
6
6
  * Ładuje Leaflet raz na aplikację. Leaflet 1.9 jest paczką UMD/CJS bez pola `exports`,
7
- * więc pod bundlerem trafia raz jako `default`, a raz jako sam namespace — stąd interop.
7
+ * więc pod bundlerem trafia raz jako `default`, a raz jako sam namespace - stąd interop.
8
8
  */
9
9
  async function loadLeaflet() {
10
10
  modulePromise ??= import('leaflet')
@@ -15,7 +15,7 @@ async function loadLeaflet() {
15
15
  });
16
16
  return modulePromise;
17
17
  }
18
- /** Fabryka silnika — każda mapa dostaje własną instancję. */
18
+ /** Fabryka silnika - każda mapa dostaje własną instancję. */
19
19
  export function createLeafletEngine(options = {}) {
20
20
  return new LeafletEngine(options);
21
21
  }
@@ -28,7 +28,7 @@ class LeafletEngine {
28
28
  this.tiles = null;
29
29
  this.userMarker = null;
30
30
  this.userCircle = null;
31
- /** Znaczniki po `id` — bez tego każdy przelicz przerysowywałby całą mapę. */
31
+ /** Znaczniki po `id` - bez tego każdy przelicz przerysowywałby całą mapę. */
32
32
  this.markers = new Map();
33
33
  this.handlers = {};
34
34
  }
@@ -39,7 +39,7 @@ class LeafletEngine {
39
39
  zoom: opts.zoom,
40
40
  minZoom: opts.minZoom ?? this.options.minZoom ?? 2,
41
41
  maxZoom: opts.maxZoom ?? this.options.maxZoom ?? 19,
42
- // Kontrolki rysuje warstwa Angulara — domyślnych nie da się otokenizować
42
+ // Kontrolki rysuje warstwa Angulara - domyślnych nie da się otokenizować
43
43
  // bez walki z niewarstwowanym `leaflet.css`.
44
44
  zoomControl: false,
45
45
  attributionControl: true,
@@ -58,7 +58,7 @@ class LeafletEngine {
58
58
  this.map.on('zoomend', () => this.emit('zoomend'));
59
59
  this.map.on('click', (e) => this.emit('click', this.toPointerEvent(e)));
60
60
  this.map.on('contextmenu', (e) => {
61
- // Menu przeglądarki zasłoniłoby własne „Dodaj lokalizację".
61
+ // Menu przeglądarki zasłoniłoby własne "Dodaj lokalizację".
62
62
  L.DomEvent.preventDefault(e.originalEvent);
63
63
  this.emit('contextmenu', this.toPointerEvent(e));
64
64
  });
@@ -108,7 +108,7 @@ class LeafletEngine {
108
108
  }
109
109
  /**
110
110
  * Wymienia zestaw znaczników różnicowo. Znaczniki, których `id` się nie zmieniło,
111
- * zostają na miejscu — inaczej każdy przelicz gasiłby animacje i migotał.
111
+ * zostają na miejscu - inaczej każdy przelicz gasiłby animacje i migotał.
112
112
  */
113
113
  setMarkers(next) {
114
114
  if (!this.map || !this.L)
@@ -171,7 +171,7 @@ class LeafletEngine {
171
171
  this.userMarker.setIcon(icon);
172
172
  }
173
173
  else {
174
- // Nad znacznikami lokalizacji — własne położenie ma być zawsze widoczne.
174
+ // Nad znacznikami lokalizacji - własne położenie ma być zawsze widoczne.
175
175
  this.userMarker = new L.Marker(at, { icon, alt: '', keyboard: false, zIndexOffset: 1000 }).addTo(this.map);
176
176
  }
177
177
  // Promień w metrach; L.Circle sam przelicza go na piksele przy każdym zoomie.
@@ -198,7 +198,7 @@ class LeafletEngine {
198
198
  attribution,
199
199
  maxZoom: this.options.maxZoom ?? 19,
200
200
  }).addTo(this.map);
201
- // Kafle wchodzą pod znaczniki — bez tego nowa warstwa przykryłaby je.
201
+ // Kafle wchodzą pod znaczniki - bez tego nowa warstwa przykryłaby je.
202
202
  this.tiles.bringToBack();
203
203
  }
204
204
  setMaxBounds(bounds) {
@@ -208,7 +208,7 @@ class LeafletEngine {
208
208
  this.map.options.maxBoundsViscosity = bounds ? 1 : 0;
209
209
  }
210
210
  invalidateSize() {
211
- // `animate: false` — to reakcja na zmianę layoutu, nie gest użytkownika.
211
+ // `animate: false` - to reakcja na zmianę layoutu, nie gest użytkownika.
212
212
  this.map?.invalidateSize({ animate: false });
213
213
  }
214
214
  on(event, handler) {
package/dist/format.d.ts CHANGED
@@ -2,11 +2,11 @@
2
2
  * Dystans po ludzku: poniżej kilometra w metrach zaokrąglonych do dziesiątek,
3
3
  * wyżej w kilometrach z jednym miejscem po przecinku (`6,2 km` w `pl-PL`).
4
4
  *
5
- * Wartość ujemna albo nieskończona daje `null` — wołający chowa wtedy wiersz,
6
- * zamiast malować „NaN km".
5
+ * Wartość ujemna albo nieskończona daje `null` - wołający chowa wtedy wiersz,
6
+ * zamiast malować "NaN km".
7
7
  */
8
8
  export declare function formatDistance(metres: number | null | undefined, locale: string): string | null;
9
- /** Współrzędne do wiersza karty — pięć miejsc po przecinku to ok. metr. */
9
+ /** Współrzędne do wiersza karty - pięć miejsc po przecinku to ok. metr. */
10
10
  export declare function formatLatLng(at: {
11
11
  lat: number;
12
12
  lng: number;
package/dist/format.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Formatowanie liczb dla warstwy prezentacji mapy — pure TS.
2
+ * Formatowanie liczb dla warstwy prezentacji mapy - pure TS.
3
3
  * Wszystko przez `Intl`, więc separator dziesiętny idzie z locale,
4
4
  * a nie z zaszytej na sztywno kropki.
5
5
  */
@@ -7,8 +7,8 @@
7
7
  * Dystans po ludzku: poniżej kilometra w metrach zaokrąglonych do dziesiątek,
8
8
  * wyżej w kilometrach z jednym miejscem po przecinku (`6,2 km` w `pl-PL`).
9
9
  *
10
- * Wartość ujemna albo nieskończona daje `null` — wołający chowa wtedy wiersz,
11
- * zamiast malować „NaN km".
10
+ * Wartość ujemna albo nieskończona daje `null` - wołający chowa wtedy wiersz,
11
+ * zamiast malować "NaN km".
12
12
  */
13
13
  export function formatDistance(metres, locale) {
14
14
  if (metres == null || !Number.isFinite(metres) || metres < 0)
@@ -26,7 +26,7 @@ export function formatDistance(metres, locale) {
26
26
  }).format(km);
27
27
  return `${value} km`;
28
28
  }
29
- /** Współrzędne do wiersza karty — pięć miejsc po przecinku to ok. metr. */
29
+ /** Współrzędne do wiersza karty - pięć miejsc po przecinku to ok. metr. */
30
30
  export function formatLatLng(at, digits = 5) {
31
31
  return `${at.lat.toFixed(digits)}, ${at.lng.toFixed(digits)}`;
32
32
  }
package/dist/geo.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { KptLatLng, KptMapBounds, KptMapPoint } from './types.ts';
2
- /** Bok kafla w pikselach — stała obu silników. */
2
+ /** Bok kafla w pikselach - stała obu silników. */
3
3
  export declare const KPT_TILE_SIZE = 256;
4
4
  /**
5
5
  * Granica szerokości w Mercatorze. Powyżej niej projekcja ucieka do nieskończoności,
@@ -13,31 +13,31 @@ export declare function clampLat(lat: number): number;
13
13
  /**
14
14
  * Zawija długość geograficzną do zakresu [-180, 180].
15
15
  *
16
- * Wartości już w zakresie wracają nietknięte — także -180, bo w projekcji jest to
16
+ * Wartości już w zakresie wracają nietknięte - także -180, bo w projekcji jest to
17
17
  * lewa krawędź świata (x = 0), a nie ta sama kolumna pikseli co +180. Zawijanie
18
18
  * dotyczy wyłącznie tego, co wychodzi poza zakres: 540° to ten sam południk co 180°.
19
19
  */
20
20
  export declare function normalizeLng(lng: number): number;
21
21
  /** Liczba pikseli świata na danym zoomie. */
22
22
  export declare function worldSize(zoom: number): number;
23
- /** Współrzędne → piksele świata na danym zoomie (origin w lewym górnym rogu). */
23
+ /** Współrzędne -> piksele świata na danym zoomie (origin w lewym górnym rogu). */
24
24
  export declare function project(at: KptLatLng, zoom: number): KptMapPoint;
25
- /** Piksele świata → współrzędne. Odwrotność `project`. */
25
+ /** Piksele świata -> współrzędne. Odwrotność `project`. */
26
26
  export declare function unproject(point: KptMapPoint, zoom: number): KptLatLng;
27
- /** Najmniejszy prostokąt obejmujący wszystkie punkty. Pusta lista → `null`. */
27
+ /** Najmniejszy prostokąt obejmujący wszystkie punkty. Pusta lista -> `null`. */
28
28
  export declare function boundsOf(points: readonly KptLatLng[]): KptMapBounds | null;
29
29
  /**
30
30
  * Najmniejszy zasięg w stopniach, przy którym `fitBounds` ma jeszcze sens (~100 m).
31
31
  *
32
32
  * Geokodery obrysowują pojedynczy adres prostokątem rzędu 0,0001°. Wpasowanie takiego
33
33
  * w kadr wjeżdża na górny limit zoomu, a wynik zależy od tego, jak dostawca obrysował
34
- * budynek — dwa sąsiednie adresy lądują w różnych przybliżeniach.
34
+ * budynek - dwa sąsiednie adresy lądują w różnych przybliżeniach.
35
35
  */
36
36
  export declare const KPT_MIN_FIT_SPAN = 0.001;
37
37
  /**
38
38
  * Czy prostokąt warto wpasowywać w kadr, zamiast potraktować go jak punkt.
39
39
  *
40
- * `false` dla zasięgu zdegenerowanego albo ciaśniejszego niż `minSpan` w OBU osiach —
40
+ * `false` dla zasięgu zdegenerowanego albo ciaśniejszego niż `minSpan` w OBU osiach -
41
41
  * długa, wąska ulica ma jeden wymiar mikroskopijny i dalej zasługuje na `fitBounds`.
42
42
  */
43
43
  export declare function isFittableBounds(bounds: KptMapBounds, minSpan?: number): boolean;
@@ -56,7 +56,7 @@ export declare function haversine(a: KptLatLng, b: KptLatLng): number;
56
56
  export declare function metersPerPixel(lat: number, zoom: number): number;
57
57
  /**
58
58
  * Największy zoom, przy którym `bounds` mieści się w kontenerze o zadanym rozmiarze.
59
- * Zwraca liczbę zmiennoprzecinkową — zaokrąglenie w dół zostawiamy wołającemu.
59
+ * Zwraca liczbę zmiennoprzecinkową - zaokrąglenie w dół zostawiamy wołającemu.
60
60
  */
61
61
  export declare function zoomForBounds(bounds: KptMapBounds, size: {
62
62
  width: number;
package/dist/geo.js CHANGED
@@ -1,4 +1,4 @@
1
- /** Bok kafla w pikselach — stała obu silników. */
1
+ /** Bok kafla w pikselach - stała obu silników. */
2
2
  export const KPT_TILE_SIZE = 256;
3
3
  /**
4
4
  * Granica szerokości w Mercatorze. Powyżej niej projekcja ucieka do nieskończoności,
@@ -14,7 +14,7 @@ export function clampLat(lat) {
14
14
  /**
15
15
  * Zawija długość geograficzną do zakresu [-180, 180].
16
16
  *
17
- * Wartości już w zakresie wracają nietknięte — także -180, bo w projekcji jest to
17
+ * Wartości już w zakresie wracają nietknięte - także -180, bo w projekcji jest to
18
18
  * lewa krawędź świata (x = 0), a nie ta sama kolumna pikseli co +180. Zawijanie
19
19
  * dotyczy wyłącznie tego, co wychodzi poza zakres: 540° to ten sam południk co 180°.
20
20
  */
@@ -28,7 +28,7 @@ export function normalizeLng(lng) {
28
28
  export function worldSize(zoom) {
29
29
  return KPT_TILE_SIZE * Math.pow(2, zoom);
30
30
  }
31
- /** Współrzędne → piksele świata na danym zoomie (origin w lewym górnym rogu). */
31
+ /** Współrzędne -> piksele świata na danym zoomie (origin w lewym górnym rogu). */
32
32
  export function project(at, zoom) {
33
33
  const size = worldSize(zoom);
34
34
  const lat = clampLat(at.lat);
@@ -38,7 +38,7 @@ export function project(at, zoom) {
38
38
  y: size * (0.5 - Math.log((1 + sin) / (1 - sin)) / (4 * Math.PI)),
39
39
  };
40
40
  }
41
- /** Piksele świata → współrzędne. Odwrotność `project`. */
41
+ /** Piksele świata -> współrzędne. Odwrotność `project`. */
42
42
  export function unproject(point, zoom) {
43
43
  const size = worldSize(zoom);
44
44
  const lng = (point.x / size - 0.5) * 360;
@@ -46,7 +46,7 @@ export function unproject(point, zoom) {
46
46
  const lat = (180 / Math.PI) * Math.atan(Math.sinh(n));
47
47
  return { lat, lng };
48
48
  }
49
- /** Najmniejszy prostokąt obejmujący wszystkie punkty. Pusta lista → `null`. */
49
+ /** Najmniejszy prostokąt obejmujący wszystkie punkty. Pusta lista -> `null`. */
50
50
  export function boundsOf(points) {
51
51
  if (points.length === 0)
52
52
  return null;
@@ -71,13 +71,13 @@ export function boundsOf(points) {
71
71
  *
72
72
  * Geokodery obrysowują pojedynczy adres prostokątem rzędu 0,0001°. Wpasowanie takiego
73
73
  * w kadr wjeżdża na górny limit zoomu, a wynik zależy od tego, jak dostawca obrysował
74
- * budynek — dwa sąsiednie adresy lądują w różnych przybliżeniach.
74
+ * budynek - dwa sąsiednie adresy lądują w różnych przybliżeniach.
75
75
  */
76
76
  export const KPT_MIN_FIT_SPAN = 0.001;
77
77
  /**
78
78
  * Czy prostokąt warto wpasowywać w kadr, zamiast potraktować go jak punkt.
79
79
  *
80
- * `false` dla zasięgu zdegenerowanego albo ciaśniejszego niż `minSpan` w OBU osiach —
80
+ * `false` dla zasięgu zdegenerowanego albo ciaśniejszego niż `minSpan` w OBU osiach -
81
81
  * długa, wąska ulica ma jeden wymiar mikroskopijny i dalej zasługuje na `fitBounds`.
82
82
  */
83
83
  export function isFittableBounds(bounds, minSpan = KPT_MIN_FIT_SPAN) {
@@ -122,7 +122,7 @@ export function metersPerPixel(lat, zoom) {
122
122
  }
123
123
  /**
124
124
  * Największy zoom, przy którym `bounds` mieści się w kontenerze o zadanym rozmiarze.
125
- * Zwraca liczbę zmiennoprzecinkową — zaokrąglenie w dół zostawiamy wołającemu.
125
+ * Zwraca liczbę zmiennoprzecinkową - zaokrąglenie w dół zostawiamy wołającemu.
126
126
  */
127
127
  export function zoomForBounds(bounds, size, paddingPx = 0) {
128
128
  const w = Math.max(1, size.width - paddingPx * 2);
package/dist/hours.d.ts CHANGED
@@ -9,33 +9,33 @@ export declare function isoWeekday(date: Date): KptMapWeekday;
9
9
  * Czy miejsce jest otwarte w danym momencie.
10
10
  *
11
11
  * Sprawdza dwa dni: bieżący oraz poprzedni, bo przedział przez północ
12
- * (`22:00 – 01:00`) obejmuje wczesne godziny dnia następnego.
12
+ * (`22:00 - 01:00`) obejmuje wczesne godziny dnia następnego.
13
13
  */
14
14
  export declare function isOpenAt(hours: KptMapOpeningHours | undefined, date: Date): boolean;
15
- /** Czy rozkład to pełna doba przez siedem dni — wtedy karta pisze po prostu „24/7". */
15
+ /** Czy rozkład to pełna doba przez siedem dni - wtedy karta pisze po prostu "24/7". */
16
16
  export declare function isAlwaysOpen(hours: KptMapOpeningHours | undefined): boolean;
17
17
  /** Najbliższa zmiana stanu otwarte/zamknięte albo `null`, gdy w ciągu tygodnia jej nie ma. */
18
18
  export declare function nextChange(hours: KptMapOpeningHours | undefined, date: Date): {
19
19
  open: boolean;
20
20
  at: Date;
21
21
  } | null;
22
- /** Skrócona nazwa dnia z `Intl` — bez słownika, więc działa dla dowolnego locale. */
22
+ /** Skrócona nazwa dnia z `Intl` - bez słownika, więc działa dla dowolnego locale. */
23
23
  export declare function weekdayName(day: KptMapWeekday, locale: string): string;
24
24
  /** Wiersz rozkładu: jeden dzień albo sklejony zakres dni o identycznych godzinach. */
25
25
  export interface KptMapHoursGroup {
26
- /** `pon.` albo `wt.–sob.`, wg locale. */
26
+ /** `pon.` albo `wt.-sob.`, wg locale. */
27
27
  label: string;
28
28
  days: KptMapWeekday[];
29
29
  closed: boolean;
30
- /** Sformatowane przedziały, np. `['11:00 – 24:00']`. Puste, gdy zamknięte. */
30
+ /** Sformatowane przedziały, np. `['11:00 - 24:00']`. Puste, gdy zamknięte. */
31
31
  ranges: string[];
32
32
  }
33
33
  /**
34
34
  * Rozkład tygodnia z sąsiadującymi dniami sklejonymi w jeden wiersz.
35
35
  *
36
- * Niedziela i poniedziałek się nie sklejają, choć w tablicy sąsiadują — tydzień
36
+ * Niedziela i poniedziałek się nie sklejają, choć w tablicy sąsiadują - tydzień
37
37
  * czyta się liniowo od poniedziałku i zawijanie byłoby mylące.
38
38
  */
39
39
  export declare function groupWeek(hours: KptMapOpeningHours | undefined, locale: string, separator?: string): KptMapHoursGroup[];
40
- /** Siedem dni oznaczonych jako zamknięte — wartość startowa pola `hours` w formularzu. */
40
+ /** Siedem dni oznaczonych jako zamknięte - wartość startowa pola `hours` w formularzu. */
41
41
  export declare function emptyWeek(): KptMapOpeningHours;
package/dist/hours.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /*
2
- * Godziny otwarcia — pure TS, bez Angulara i bez silnika mapowego.
2
+ * Godziny otwarcia - pure TS, bez Angulara i bez silnika mapowego.
3
3
  * Ten plik przenosi się do portu React bez zmian.
4
4
  *
5
5
  * Umowa o czasie: `HH:MM` w czasie lokalnym miejsca, a porównania robimy
6
6
  * na lokalnym czasie przeglądarki. Miejsce w innej strefie niż użytkownik
7
- * pokaże więc status wg zegara użytkownika — to świadome uproszczenie,
7
+ * pokaże więc status wg zegara użytkownika - to świadome uproszczenie,
8
8
  * bo model nie niesie strefy. Kto potrzebuje inaczej, liczy status u siebie.
9
9
  */
10
10
  /** Minuta doby dla `HH:MM`; `24:00` to 1440. `null`, gdy zapis jest nieprawidłowy. */
@@ -50,7 +50,7 @@ function usableRanges(entry) {
50
50
  * Czy miejsce jest otwarte w danym momencie.
51
51
  *
52
52
  * Sprawdza dwa dni: bieżący oraz poprzedni, bo przedział przez północ
53
- * (`22:00 – 01:00`) obejmuje wczesne godziny dnia następnego.
53
+ * (`22:00 - 01:00`) obejmuje wczesne godziny dnia następnego.
54
54
  */
55
55
  export function isOpenAt(hours, date) {
56
56
  if (!hours || hours.length === 0)
@@ -71,7 +71,7 @@ export function isOpenAt(hours, date) {
71
71
  }
72
72
  return false;
73
73
  }
74
- /** Czy rozkład to pełna doba przez siedem dni — wtedy karta pisze po prostu „24/7". */
74
+ /** Czy rozkład to pełna doba przez siedem dni - wtedy karta pisze po prostu "24/7". */
75
75
  export function isAlwaysOpen(hours) {
76
76
  if (!hours)
77
77
  return false;
@@ -117,7 +117,7 @@ export function nextChange(hours, date) {
117
117
  }
118
118
  return null;
119
119
  }
120
- /** Skrócona nazwa dnia z `Intl` — bez słownika, więc działa dla dowolnego locale. */
120
+ /** Skrócona nazwa dnia z `Intl` - bez słownika, więc działa dla dowolnego locale. */
121
121
  export function weekdayName(day, locale) {
122
122
  // 2024-01-01 był poniedziałkiem, więc dzień ISO wypada na tę samą liczbę w miesiącu.
123
123
  const date = new Date(Date.UTC(2024, 0, day));
@@ -132,10 +132,10 @@ function signatureOf(entry) {
132
132
  /**
133
133
  * Rozkład tygodnia z sąsiadującymi dniami sklejonymi w jeden wiersz.
134
134
  *
135
- * Niedziela i poniedziałek się nie sklejają, choć w tablicy sąsiadują — tydzień
135
+ * Niedziela i poniedziałek się nie sklejają, choć w tablicy sąsiadują - tydzień
136
136
  * czyta się liniowo od poniedziałku i zawijanie byłoby mylące.
137
137
  */
138
- export function groupWeek(hours, locale, separator = ' – ') {
138
+ export function groupWeek(hours, locale, separator = ' - ') {
139
139
  if (!hours || hours.length === 0)
140
140
  return [];
141
141
  const groups = [];
@@ -160,11 +160,11 @@ export function groupWeek(hours, locale, separator = ' – ') {
160
160
  for (const group of groups) {
161
161
  const first = weekdayName(group.days[0], locale);
162
162
  const last = weekdayName(group.days[group.days.length - 1], locale);
163
- group.label = group.days.length === 1 ? first : `${first}–${last}`;
163
+ group.label = group.days.length === 1 ? first : `${first}-${last}`;
164
164
  }
165
165
  return groups;
166
166
  }
167
- /** Siedem dni oznaczonych jako zamknięte — wartość startowa pola `hours` w formularzu. */
167
+ /** Siedem dni oznaczonych jako zamknięte - wartość startowa pola `hours` w formularzu. */
168
168
  export function emptyWeek() {
169
169
  return Array.from({ length: 7 }, (_, i) => ({
170
170
  day: (i + 1),
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Rdzeń mapy — pure TS, bez frameworka. Obok obliczeń (geometria, klastrowanie, godziny)
2
+ * Rdzeń mapy - pure TS, bez frameworka. Obok obliczeń (geometria, klastrowanie, godziny)
3
3
  * mieszkają tu adaptery silników: Leaflet i Google. Oba rozmawiają z resztą kodu wyłącznie
4
4
  * przez interfejs `KptMapEngine`, więc port Angulara i Reacta dzielą całą tę warstwę.
5
5
  */
@@ -1,8 +1,8 @@
1
1
  import type { KptMapColor, KptMapMarkerShape } from './types.ts';
2
- /** Rola koloru → zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian; cokolwiek spoza tego
2
+ /** Rola koloru -> zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian; cokolwiek spoza tego
3
3
  * kontraktu dostaje bezpieczny fallback zamiast trafić surowo do wyjścia. */
4
4
  export declare function colorVarOf(color: KptMapColor): string;
5
- /** Kolor treści na tle `color` — dla ról znany, dla własnych zmiennych fallback na biel tokenową. */
5
+ /** Kolor treści na tle `color` - dla ról znany, dla własnych zmiennych fallback na biel tokenową. */
6
6
  export declare function contrastVarOf(color: KptMapColor): string;
7
7
  export declare function foregroundVarOf(color: KptMapColor): string;
8
8
  /** Ucieka znaki, które rozbiłyby atrybut albo wstrzyknęły znacznik. */
@@ -12,9 +12,9 @@ export interface KptMarkerHtmlInput {
12
12
  color: KptMapColor;
13
13
  /** Inner-SVG ikony (bez wrappera `<svg>`); bez niego znacznik nie ma glifu. */
14
14
  iconSvgInner?: string;
15
- /** Tekst dla czytnika ekranu — zwykle tytuł lokalizacji. */
15
+ /** Tekst dla czytnika ekranu - zwykle tytuł lokalizacji. */
16
16
  label: string;
17
- /** Znacznik wybrany (otwarty popup) — dostaje klasę modyfikującą. */
17
+ /** Znacznik wybrany (otwarty popup) - dostaje klasę modyfikującą. */
18
18
  selected?: boolean;
19
19
  }
20
20
  export declare function renderMarkerHtml(input: KptMarkerHtmlInput): string;
@@ -26,11 +26,11 @@ export interface KptClusterHtmlInput {
26
26
  }
27
27
  /** Koło z licznikiem; rozmiar rośnie schodkowo z liczebnością grupy. */
28
28
  export declare function renderClusterHtml(input: KptClusterHtmlInput): string;
29
- /** Próg wielkości grupy — trzy stopnie wystarczą, żeby zobaczyć różnicę bez skalowania ciągłego. */
29
+ /** Próg wielkości grupy - trzy stopnie wystarczą, żeby zobaczyć różnicę bez skalowania ciągłego. */
30
30
  export declare function clusterTier(count: number): 'sm' | 'md' | 'lg';
31
- /** Powyżej 999 licznik przestaje się mieścić — skracamy. */
31
+ /** Powyżej 999 licznik przestaje się mieścić - skracamy. */
32
32
  export declare function formatCount(count: number): string;
33
- /** Znacznik pozycji użytkownika — ikona podawana z zewnątrz, jak przy zwykłym znaczniku. */
33
+ /** Znacznik pozycji użytkownika - ikona podawana z zewnątrz, jak przy zwykłym znaczniku. */
34
34
  export declare function renderUserMarkerHtml(input: {
35
35
  label: string;
36
36
  iconSvgInner?: string;
@@ -15,14 +15,14 @@ const ROLE_CONTRAST_VARS = {
15
15
  muted: 'var(--kpt-color-on-muted)',
16
16
  };
17
17
  /**
18
- * Kształt jedynego wejścia spoza znanej roli, jakie kontrakt `KptMapColor` dopuszcza —
18
+ * Kształt jedynego wejścia spoza znanej roli, jakie kontrakt `KptMapColor` dopuszcza -
19
19
  * gotowy token `var(--kpt-*)`. Dane runtime (JSON/CMS) nie są tym kontraktem związane, więc
20
20
  * zanim trafią do atrybutu `style="..."` budowanego konkatenacją stringów w `renderMarkerHtml`/
21
- * `renderClusterHtml`, muszą zostać zweryfikowane — inaczej cudzysłów/`>` wyrywa się z atrybutu
21
+ * `renderClusterHtml`, muszą zostać zweryfikowane - inaczej cudzysłów/`>` wyrywa się z atrybutu
22
22
  * (HTML injection), a średnik wstrzykuje dodatkową deklarację CSS.
23
23
  */
24
24
  const SAFE_VAR_TOKEN = /^var\(--kpt-[\w-]+\)$/;
25
- /** Rola koloru → zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian; cokolwiek spoza tego
25
+ /** Rola koloru -> zmienna CSS. Gotowe `var(--kpt-*)` przechodzi bez zmian; cokolwiek spoza tego
26
26
  * kontraktu dostaje bezpieczny fallback zamiast trafić surowo do wyjścia. */
27
27
  export function colorVarOf(color) {
28
28
  const known = ROLE_VARS[color];
@@ -30,7 +30,7 @@ export function colorVarOf(color) {
30
30
  return known;
31
31
  return SAFE_VAR_TOKEN.test(color) ? color : ROLE_VARS.muted;
32
32
  }
33
- /** Kolor treści na tle `color` — dla ról znany, dla własnych zmiennych fallback na biel tokenową. */
33
+ /** Kolor treści na tle `color` - dla ról znany, dla własnych zmiennych fallback na biel tokenową. */
34
34
  export function contrastVarOf(color) {
35
35
  return ROLE_CONTRAST_VARS[color] ?? 'var(--kpt-color-text-inverse)';
36
36
  }
@@ -38,7 +38,7 @@ export function contrastVarOf(color) {
38
38
  * Kolor **glifu stojącego wprost na powierzchni**, bez własnego tła.
39
39
  *
40
40
  * Różni się od `colorVarOf()` tylko dla roli `muted`: `--kpt-color-muted` to neutral-100,
41
- * czyli token tła, a nie treści — goły znak w tym kolorze na jasnej powierzchni jest
41
+ * czyli token tła, a nie treści - goły znak w tym kolorze na jasnej powierzchni jest
42
42
  * niewidoczny. Bierzemy więc czytelny szary tekstowy. Pozostałe role są nasycone
43
43
  * i jako treść czytają się bez zmian.
44
44
  */
@@ -63,11 +63,11 @@ export function escapeHtml(value) {
63
63
  }
64
64
  /**
65
65
  * Pinezka o wysokości `--kpt-map-marker-size`, zakotwiczona czubkiem w punkcie.
66
- * `viewBox` 24×32: 24 szerokości koła + ogon do 32.
66
+ * `viewBox` 24x32: 24 szerokości koła + ogon do 32.
67
67
  */
68
68
  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';
69
69
  export function renderMarkerHtml(input) {
70
- // `shape` trafia do atrybutu `class="..."` konkatenacją stringów — `KptMapMarkerShape` ogranicza
70
+ // `shape` trafia do atrybutu `class="..."` konkatenacją stringów - `KptMapMarkerShape` ogranicza
71
71
  // to tylko compile-time, dane runtime (JSON/CMS) nie są tym związane (ten sam powód, dla którego
72
72
  // `color`/`contrast` dostały escapowanie/whitelistę wyżej w pliku).
73
73
  const shape = escapeHtml(input.shape ?? 'pin');
@@ -96,7 +96,7 @@ export function renderClusterHtml(input) {
96
96
  ` style="--_kpt-map-cluster-bg:${color};--_kpt-map-cluster-fg:${contrast}">` +
97
97
  `<span class="kpt-map__cluster-count">${formatCount(input.count)}</span></div>`);
98
98
  }
99
- /** Próg wielkości grupy — trzy stopnie wystarczą, żeby zobaczyć różnicę bez skalowania ciągłego. */
99
+ /** Próg wielkości grupy - trzy stopnie wystarczą, żeby zobaczyć różnicę bez skalowania ciągłego. */
100
100
  export function clusterTier(count) {
101
101
  if (count < 10)
102
102
  return 'sm';
@@ -104,11 +104,11 @@ export function clusterTier(count) {
104
104
  return 'md';
105
105
  return 'lg';
106
106
  }
107
- /** Powyżej 999 licznik przestaje się mieścić — skracamy. */
107
+ /** Powyżej 999 licznik przestaje się mieścić - skracamy. */
108
108
  export function formatCount(count) {
109
109
  return count > 999 ? '999+' : String(count);
110
110
  }
111
- /** Znacznik pozycji użytkownika — ikona podawana z zewnątrz, jak przy zwykłym znaczniku. */
111
+ /** Znacznik pozycji użytkownika - ikona podawana z zewnątrz, jak przy zwykłym znaczniku. */
112
112
  export function renderUserMarkerHtml(input) {
113
113
  const label = escapeHtml(input.label);
114
114
  const glyph = input.iconSvgInner
package/dist/types.d.ts CHANGED
@@ -10,20 +10,20 @@ export interface KptMapBounds {
10
10
  north: number;
11
11
  east: number;
12
12
  }
13
- /** Punkt w pikselach — kontenera mapy albo świata, zależnie od kontekstu. */
13
+ /** Punkt w pikselach - kontenera mapy albo świata, zależnie od kontekstu. */
14
14
  export interface KptMapPoint {
15
15
  x: number;
16
16
  y: number;
17
17
  }
18
18
  /**
19
19
  * Kolor znacznika: rola z warstwy semantycznej tokenów albo gotowe `var(--kpt-*)`.
20
- * Literały (`#c00`, `rgb(...)`) są celowo niedozwolone — kontrakt repo wymaga tokenów.
20
+ * Literały (`#c00`, `rgb(...)`) są celowo niedozwolone - kontrakt repo wymaga tokenów.
21
21
  */
22
22
  export type KptMapColorRole = 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'muted';
23
23
  export type KptMapColor = KptMapColorRole | `var(--kpt-${string})`;
24
24
  /** Kształt znacznika. */
25
25
  export type KptMapMarkerShape = 'pin' | 'dot' | 'square';
26
- /** Typ pola w schemie formularza „dodaj lokalizację". */
26
+ /** Typ pola w schemie formularza "dodaj lokalizację". */
27
27
  export type KptMapFieldType = 'text' | 'textarea' | 'number' | 'date' | 'select' | 'multiselect' | 'checkbox' | 'tel' | 'email' | 'url'
28
28
  /** Zdjęcie: wybór pliku (wartość jako `data:`) albo wklejony adres. */
29
29
  | 'image'
@@ -59,12 +59,12 @@ export interface KptMapFieldDef {
59
59
  */
60
60
  autofill?: KptMapAddressPart;
61
61
  }
62
- /** Rozbiór adresu zwracany przez geokoder. Wszystko opcjonalne — źródła bywają dziurawe. */
62
+ /** Rozbiór adresu zwracany przez geokoder. Wszystko opcjonalne - źródła bywają dziurawe. */
63
63
  export interface KptMapAddress {
64
64
  /** Nazwa ulicy bez numeru. */
65
65
  street?: string;
66
66
  houseNumber?: string;
67
- /** Ulica z numerem, gotowa do jednego pola „Adres". */
67
+ /** Ulica z numerem, gotowa do jednego pola "Adres". */
68
68
  address?: string;
69
69
  city?: string;
70
70
  postcode?: string;
@@ -81,23 +81,23 @@ export interface KptMapAddress {
81
81
  /** Pole `KptMapAddress`, którym można wypełnić kontrolkę formularza. */
82
82
  export type KptMapAddressPart = keyof KptMapAddress;
83
83
  /**
84
- * Podpowiedź z listy wyszukiwarki adresów (geokodowanie wprost: tekst → miejsce).
84
+ * Podpowiedź z listy wyszukiwarki adresów (geokodowanie wprost: tekst -> miejsce).
85
85
  *
86
86
  * Pochodzi z portu `KPT_MAP_GEOCODER`, więc kształt jest wspólny dla dowolnego
87
- * dostawcy — Nominatim, instancji własnej i komercyjnej.
87
+ * dostawcy - Nominatim, instancji własnej i komercyjnej.
88
88
  */
89
89
  export interface KptMapSuggestion {
90
- /** Stabilny w obrębie jednej odpowiedzi — służy za klucz `track` listy podpowiedzi. */
90
+ /** Stabilny w obrębie jednej odpowiedzi - służy za klucz `track` listy podpowiedzi. */
91
91
  id: string;
92
92
  /** Pełna nazwa jednym ciągiem; to widzi użytkownik na liście. */
93
93
  label: string;
94
94
  /**
95
- * Współrzędne, **gdy dostawca podaje je już na liście** — tak robi każdy geokoder
95
+ * Współrzędne, **gdy dostawca podaje je już na liście** - tak robi każdy geokoder
96
96
  * pytany wprost (Nominatim, Photon, Google Geocoding API).
97
97
  *
98
98
  * Brak wartości znaczy, że podpowiedź trzeba jeszcze uzupełnić metodą `resolve()`
99
99
  * portu. Tak działa Google Places Autocomplete: zwraca `placeId` i tekst, a `lat`/`lng`
100
- * dociąga się osobnym Place Details — jedno wywołanie na *wybór* użytkownika, a nie
100
+ * dociąga się osobnym Place Details - jedno wywołanie na *wybór* użytkownika, a nie
101
101
  * na każdy naciśnięty klawisz. Na tym stoi jego rozliczanie sesyjne, więc to nie jest
102
102
  * dziwactwo jednego dostawcy, tylko wzorzec, który port musi umieć wyrazić.
103
103
  */
@@ -107,11 +107,11 @@ export interface KptMapSuggestion {
107
107
  * zamiast dostać punktowy zoom w środek rynku.
108
108
  */
109
109
  bounds?: KptMapBounds;
110
- /** Rozbiór adresu, gdy dostawca go podaje — ten sam typ, co przy geokodowaniu wstecznym. */
110
+ /** Rozbiór adresu, gdy dostawca go podaje - ten sam typ, co przy geokodowaniu wstecznym. */
111
111
  address?: KptMapAddress;
112
112
  }
113
113
  /**
114
- * Wybrane miejsce — podpowiedź z **pewnymi** współrzędnymi.
114
+ * Wybrane miejsce - podpowiedź z **pewnymi** współrzędnymi.
115
115
  *
116
116
  * To ten typ wychodzi z `selected` pola wyszukiwania i z `searchSelect` mapy: zanim
117
117
  * zdarzenie poleci, brakujące `at` zostaje dociągnięte przez `resolve()`. Aplikacja
@@ -120,7 +120,7 @@ export interface KptMapSuggestion {
120
120
  export interface KptMapSearchResult extends KptMapSuggestion {
121
121
  at: KptLatLng;
122
122
  }
123
- /** Kategoria obiektu — kolor, ikona i schema formularza. */
123
+ /** Kategoria obiektu - kolor, ikona i schema formularza. */
124
124
  export interface KptMapCategory {
125
125
  id: string;
126
126
  /** Etykieta w legendzie i domyślnym popupie. */
@@ -130,7 +130,7 @@ export interface KptMapCategory {
130
130
  icon?: string;
131
131
  /** Domyślnie `'pin'`. */
132
132
  shape?: KptMapMarkerShape;
133
- /** Schema formularza „dodaj lokalizację" dla tej kategorii. */
133
+ /** Schema formularza "dodaj lokalizację" dla tej kategorii. */
134
134
  fields?: KptMapFieldDef[];
135
135
  /** Pokazać w legendzie. Domyślnie `true`. */
136
136
  legend?: boolean;
@@ -140,7 +140,7 @@ export interface KptMapLocation<T = unknown> {
140
140
  id: string;
141
141
  at: KptLatLng;
142
142
  categoryId: string;
143
- /** Tytuł w popupie oraz `aria-label` znacznika — bez niego znacznik jest niedostępny. */
143
+ /** Tytuł w popupie oraz `aria-label` znacznika - bez niego znacznik jest niedostępny. */
144
144
  title: string;
145
145
  /** Dowolne dane aplikacji; trafiają do szablonu popupu jako `data`. */
146
146
  data?: T;
@@ -152,10 +152,10 @@ export interface KptMapCluster<T = unknown> {
152
152
  /** Środek ciężkości grupy. */
153
153
  at: KptLatLng;
154
154
  count: number;
155
- /** Najliczniejsza kategoria w grupie — źródło koloru przy `clusterColorBy: 'dominant'`. */
155
+ /** Najliczniejsza kategoria w grupie - źródło koloru przy `clusterColorBy: 'dominant'`. */
156
156
  dominantCategoryId: string;
157
157
  items: KptMapLocation<T>[];
158
- /** Zasięg grupy — do `fitBounds` po kliknięciu. */
158
+ /** Zasięg grupy - do `fitBounds` po kliknięciu. */
159
159
  bounds: KptMapBounds;
160
160
  }
161
161
  /** Element wyniku grupowania: albo grupa, albo pojedyncza lokalizacja. */
@@ -183,17 +183,17 @@ export interface KptMapCreateEvent {
183
183
  /** Wartości pól wg schemy kategorii (albo z własnego szablonu formularza). */
184
184
  value: Record<string, unknown>;
185
185
  }
186
- /** Widok mapy — środek i zoom. */
186
+ /** Widok mapy - środek i zoom. */
187
187
  export interface KptMapView {
188
188
  center: KptLatLng;
189
189
  zoom: number;
190
190
  }
191
- /** Dzień tygodnia wg ISO-8601: 1 = poniedziałek … 7 = niedziela. */
191
+ /** Dzień tygodnia wg ISO-8601: 1 = poniedziałek ... 7 = niedziela. */
192
192
  export type KptMapWeekday = 1 | 2 | 3 | 4 | 5 | 6 | 7;
193
193
  /**
194
194
  * Przedział otwarcia w dobie, `HH:MM` w czasie lokalnym miejsca.
195
195
  *
196
- * `to` mniejsze albo równe `from` znaczy „przez północ" — przedział kończy się
196
+ * `to` mniejsze albo równe `from` znaczy "przez północ" - przedział kończy się
197
197
  * następnego dnia. `24:00` to prawidłowy koniec doby i nie jest przejściem przez północ.
198
198
  */
199
199
  export interface KptMapHoursRange {
@@ -203,13 +203,13 @@ export interface KptMapHoursRange {
203
203
  /** Godziny jednego dnia tygodnia. */
204
204
  export interface KptMapDayHours {
205
205
  day: KptMapWeekday;
206
- /** Zamknięte przez całą dobę — `ranges` jest wtedy ignorowane. */
206
+ /** Zamknięte przez całą dobę - `ranges` jest wtedy ignorowane. */
207
207
  closed?: boolean;
208
208
  ranges: KptMapHoursRange[];
209
209
  }
210
- /** Tygodniowy rozkład godzin. Brakujący dzień znaczy „zamknięte". */
210
+ /** Tygodniowy rozkład godzin. Brakujący dzień znaczy "zamknięte". */
211
211
  export type KptMapOpeningHours = KptMapDayHours[];
212
- /** Wiersz „ikona + etykieta + wartość" w karcie miejsca. */
212
+ /** Wiersz "ikona + etykieta + wartość" w karcie miejsca. */
213
213
  export interface KptMapPoiFact {
214
214
  /** Nazwa ikony z `KptIconRegistry`; bez niej wiersz jest bez glifu. */
215
215
  icon?: string;
@@ -218,7 +218,7 @@ export interface KptMapPoiFact {
218
218
  }
219
219
  /**
220
220
  * Dane karty miejsca (`kpt-map-poi-card`). Aplikacja mapuje na to swój
221
- * `KptMapLocation.data` — biblioteka nie narzuca kształtu danych domenowych.
221
+ * `KptMapLocation.data` - biblioteka nie narzuca kształtu danych domenowych.
222
222
  */
223
223
  export interface KptMapPoi {
224
224
  title: string;
package/dist/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Typy rdzenia mapy — pure TS, zero Angulara i zero silnika mapowego.
2
+ * Typy rdzenia mapy - pure TS, zero Angulara i zero silnika mapowego.
3
3
  * Ten plik przenosi się do portu React bez zmian.
4
4
  */
5
5
  /** Zawęża wynik `clusterLocations` do grupy. */
package/dist/url.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Adres bez schematu dostaje `https://` — inaczej przeglądarka potraktuje go jak ścieżkę względną.
3
- * Schemat spoza allowlisty (np. `javascript:`) traktujemy jak brak schematu — bezpieczny
2
+ * Adres bez schematu dostaje `https://` - inaczej przeglądarka potraktuje go jak ścieżkę względną.
3
+ * Schemat spoza allowlisty (np. `javascript:`) traktujemy jak brak schematu - bezpieczny
4
4
  * fallback zamiast przepuszczenia surowej wartości do `[href]`/`[src]`/`navigator.share()`.
5
5
  */
6
6
  export declare function normalizeUrl(value: string): string;
package/dist/url.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /*
2
- * Normalizacja adresów dla karty POI — pure TS. Wydzielone z `map-poi-card.component.ts`,
2
+ * Normalizacja adresów dla karty POI - pure TS. Wydzielone z `map-poi-card.component.ts`,
3
3
  * żeby dało się to testować `node --test` bez ciągnięcia Angulara.
4
4
  */
5
5
  const HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
6
6
  const SAFE_SCHEME = /^(https?:|mailto:|tel:)/i;
7
7
  /**
8
- * Adres bez schematu dostaje `https://` — inaczej przeglądarka potraktuje go jak ścieżkę względną.
9
- * Schemat spoza allowlisty (np. `javascript:`) traktujemy jak brak schematu — bezpieczny
8
+ * Adres bez schematu dostaje `https://` - inaczej przeglądarka potraktuje go jak ścieżkę względną.
9
+ * Schemat spoza allowlisty (np. `javascript:`) traktujemy jak brak schematu - bezpieczny
10
10
  * fallback zamiast przepuszczenia surowej wartości do `[href]`/`[src]`/`navigator.share()`.
11
11
  */
12
12
  export function normalizeUrl(value) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@konce-pt/map",
3
- "version": "0.12.0",
4
- "description": "Map core for Koncept UI — projection and bounds maths, marker clustering, opening hours, marker markup, plus the Leaflet and Google engine adapters. Framework-free TypeScript, zero runtime dependencies.",
3
+ "version": "0.14.0",
4
+ "description": "Map core for Koncept UI - projection and bounds maths, marker clustering, opening hours, marker markup, plus the Leaflet and Google engine adapters. Framework-free TypeScript, zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "author": "konce.pt",
7
7
  "homepage": "https://ui.konce.pt/",