@accelint/map-toolkit 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -1
  3. package/catalog-info.yaml +9 -6
  4. package/dist/deckgl/base-map/index.d.ts +2 -2
  5. package/dist/deckgl/base-map/provider.d.ts +2 -2
  6. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.d.ts +144 -0
  7. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js +535 -0
  8. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js.map +1 -0
  9. package/dist/deckgl/extensions/coffin-corner/index.d.ts +17 -0
  10. package/dist/deckgl/extensions/coffin-corner/index.js +19 -0
  11. package/dist/deckgl/extensions/coffin-corner/store.d.ts +96 -0
  12. package/dist/deckgl/extensions/coffin-corner/store.js +173 -0
  13. package/dist/deckgl/extensions/coffin-corner/store.js.map +1 -0
  14. package/dist/deckgl/extensions/coffin-corner/types.d.ts +76 -0
  15. package/dist/deckgl/extensions/coffin-corner/types.js +27 -0
  16. package/dist/deckgl/extensions/coffin-corner/types.js.map +1 -0
  17. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.d.ts +81 -0
  18. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js +75 -0
  19. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js.map +1 -0
  20. package/dist/deckgl/extensions/index.d.ts +15 -0
  21. package/dist/deckgl/extensions/index.js +16 -0
  22. package/dist/deckgl/index.d.ts +6 -1
  23. package/dist/deckgl/index.js +5 -1
  24. package/dist/deckgl/shapes/display-shape-layer/constants.js +6 -15
  25. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  26. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +31 -15
  27. package/dist/deckgl/shapes/display-shape-layer/index.js +97 -78
  28. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  29. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +8 -0
  30. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js +3 -48
  31. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js.map +1 -1
  32. package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js +53 -0
  33. package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js.map +1 -0
  34. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +7 -3
  35. package/dist/deckgl/shapes/draw-shape-layer/index.js +7 -3
  36. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -1
  37. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +4 -2
  38. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
  39. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +3 -2
  40. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -1
  41. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +5 -2
  42. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
  43. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +5 -2
  44. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
  45. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +7 -2
  46. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
  47. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +2 -2
  48. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +7 -4
  49. package/dist/deckgl/shapes/edit-shape-layer/index.js +22 -8
  50. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
  51. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +3 -2
  52. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
  53. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +4 -2
  54. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
  55. package/dist/deckgl/shapes/edit-shape-layer/store.js +15 -4
  56. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
  57. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +4 -2
  58. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +1 -1
  59. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +7 -3
  60. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -1
  61. package/dist/deckgl/shapes/index.d.ts +3 -2
  62. package/dist/deckgl/shapes/index.js +2 -1
  63. package/dist/deckgl/shapes/shared/constants.js +1 -1
  64. package/dist/deckgl/shapes/shared/types.d.ts +11 -4
  65. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  66. package/dist/deckgl/shapes/shared/utils/duplicate-shape.d.ts +56 -0
  67. package/dist/deckgl/shapes/shared/utils/duplicate-shape.js +131 -0
  68. package/dist/deckgl/shapes/shared/utils/duplicate-shape.js.map +1 -0
  69. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
  70. package/dist/deckgl/shapes/shared/utils/layer-config.js +10 -7
  71. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -1
  72. package/dist/deckgl/symbol-layer/fiber.d.ts +3 -1
  73. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  74. package/dist/shared/units.d.ts +15 -56
  75. package/dist/shared/units.js +1 -52
  76. package/dist/shared/units.js.map +1 -1
  77. package/dist/viewport/index.d.ts +2 -3
  78. package/dist/viewport/index.js +1 -2
  79. package/dist/viewport/types.d.ts +8 -4
  80. package/dist/viewport/utils.d.ts +3 -3
  81. package/dist/viewport/utils.js +16 -8
  82. package/dist/viewport/utils.js.map +1 -1
  83. package/dist/viewport/viewport-size.d.ts +4 -3
  84. package/dist/viewport/viewport-size.js +2 -2
  85. package/dist/viewport/viewport-size.js.map +1 -1
  86. package/package.json +13 -6
  87. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js +0 -50
  88. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @accelint/map-toolkit
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - fa05228: Fix viewport size display to use SI/ICAO-compliant unit symbols instead of uppercased abbreviations. For example, `km` instead of `KM`, `m` instead of `M`. Nautical miles changed from `nm` to `NM` per ICAO/IMO convention.
8
+
9
+ ### Breaking changes
10
+
11
+ **New peer dependency:** `@accelint/constants` is now required.
12
+
13
+ **Removed exports** (from `@accelint/map-toolkit/viewport`):
14
+ - `DISTANCE_UNIT_ABBREVIATIONS` → use `DISTANCE_UNIT_SYMBOLS` from `@accelint/constants/units`
15
+ - `DistanceUnitAbbreviation` type → use `DistanceUnitSymbol` from `@accelint/constants/units`
16
+ - `DistanceUnit` type → use `DistanceUnit` from `@accelint/constants/units`
17
+ - `SupportedDistanceUnit` type → use `DistanceUnitSymbol` from `@accelint/constants/units`
18
+ - `getDistanceUnitFromAbbreviation()` → use `DISTANCE_UNIT_BY_SYMBOL[symbol]` from `@accelint/constants/units`
19
+ - `getDistanceUnitAbbreviation()` → use `DISTANCE_UNIT_SYMBOLS[unit]` from `@accelint/constants/units`
20
+
21
+ **Symbol value changes:** Unit symbols are now SI-compliant though nautical miles uses the ICAO/IMO convention of NM. If you were matching on string values, update accordingly:
22
+ - `'nm'` → `'NM'` (nautical miles)
23
+
24
+ ### Minor Changes
25
+
26
+ - b3de1bb: Add radius label on hover for circle shapes in `DisplayShapeLayer`. When hovering a circle, the radius is displayed in the configured `unit` (defaults to nautical miles). The label positions relative to the shape's text label: below it when `showLabels` is `'always'` or `'hover'`, and in its place when `showLabels` is `'never'`. Also adds the `unit` prop to `DisplayShapeLayerProps` for configuring distance display units.
27
+ - 0c3f356: Add `duplicateShape()` utility for cloning shapes with a new ID. Supports optional coordinate offset and custom naming. The resolved name is also set as the clone's map label. Includes new `GeoPosition` type for 2D or 3D coordinate tuples and a `DuplicateShape` Storybook story.
28
+ - 1b39e64: Add CoffinCornerExtension for icon selection/hover bracket indicators
29
+
30
+ New deck.gl LayerExtension that renders bracket corner indicators around
31
+ selected and hovered icons via GPU shaders. Includes useCoffinCorner hook
32
+ for managing selection state, event bus integration, and configurable
33
+ highlight colors. SymbolLayer fiber type now includes CoffinCornerExtension
34
+ props by default.
35
+
36
+ ### Patch Changes
37
+
38
+ - 75fa668: - When using icons for Point shapes, `EditShapeLayer` now displays icon markers during editing instead of plain circles.
39
+ - `DrawShapeLayer` and `EditShapeLayer` now self-register their fiber dependencies and no longer require manual fiber imports.
40
+ - `useEditShape()` now exposes `updateFeature` to allow form-based updates before saving edits
41
+ - 17c4b6c: Extend CoffinCornerExtension to support ScatterplotLayer (circle points without icons) alongside IconLayer, and refine DisplayShapeLayer integration.
42
+ - CoffinCornerExtension now supports ScatterplotLayer with quad expansion and circle-replicating fragment shaders
43
+ - DisplayShapeLayer skips the highlight outline layer for all Point geometries (coffin corner brackets handle hover/select feedback)
44
+ - DisplayShapeLayer forwards `highlightColor` as the bracket fill color via a cached tuple to avoid per-render allocations
45
+ - Stable `DISPLAY_EXTENSIONS` module-level constant prevents unnecessary `getShaders()` re-evaluation
46
+ - Removed icon-atlas-based coffin corner SVG sprites (replaced by shader SDF rendering)
47
+
48
+ - Updated dependencies [9a25205]
49
+ - Updated dependencies [fa05228]
50
+ - @accelint/logger@1.1.0
51
+ - @accelint/constants@0.3.0
52
+
3
53
  ## 2.0.0
4
54
 
5
55
  ### Major Changes
package/README.md CHANGED
@@ -9,6 +9,8 @@ Map Toolkit is a comprehensive library that provides:
9
9
  - **Deck.gl Components**: Pre-configured layers and components for rendering geospatial data, including symbol layers for military symbology (MIL-STD-2525)
10
10
  - **MapLibre Integration**: Components and utilities for working with MapLibre GL JS
11
11
  - **React Support**: React-friendly components with hooks and utilities via `@deckgl-fiber-renderer`
12
+ - **Shapes System**: Draw, display, and edit geometric shapes (circles, ellipses, polygons, rectangles, lines, points) on the map with built-in styling, selection, and duplication
13
+ - **Layer Extensions**: GPU-based visual effects like coffin corner selection/hover indicators, drawn via SDF shaders with no sprite sheet dependencies
12
14
  - **Geospatial Utilities**: Helper functions and decorators for common mapping tasks
13
15
 
14
16
  The package is organized by technology (e.g., `deckgl/`, `maplibre/`) with feature-specific exports, allowing you to import only what you need.
@@ -16,7 +18,7 @@ The package is organized by technology (e.g., `deckgl/`, `maplibre/`) with featu
16
18
  ## Installation
17
19
 
18
20
  ```sh
19
- npm install @accelint/map-toolkit
21
+ pnpm add @accelint/map-toolkit
20
22
  ```
21
23
 
22
24
  ### Optional Dependencies
@@ -48,6 +50,9 @@ import { SymbolLayer } from '@accelint/map-toolkit/deckgl';
48
50
  // MapLibre components
49
51
  import { /* components */ } from '@accelint/map-toolkit/maplibre';
50
52
 
53
+ // Layer extensions
54
+ import { CoffinCornerExtension, useCoffinCorner } from '@accelint/map-toolkit/deckgl';
55
+
51
56
  // React/Fiber components
52
57
  import { /* components */ } from '@accelint/map-toolkit/deckgl/fiber';
53
58
 
@@ -100,6 +105,8 @@ pnpm --filter=@accelint/map-toolkit bench
100
105
  packages/map-toolkit/
101
106
  src/
102
107
  deckgl/ # Deck.gl layers and components
108
+ extensions/ # Layer extensions (coffin corners, etc.)
109
+ shapes/ # Shape drawing, display, editing, and utilities
103
110
  maplibre/ # MapLibre utilities and components
104
111
  decorators/ # Shared decorators and utilities
105
112
  ```
package/catalog-info.yaml CHANGED
@@ -11,15 +11,16 @@ metadata:
11
11
 
12
12
  Dependencies:
13
13
 
14
- accelint_biome-config@1.1.0, accelint_bus@4.0.0, accelint_core@0.6.0,
15
- accelint_design-foundation@3.0.1, accelint_design-toolkit@9.8.0,
16
- accelint_geo@0.6.0, accelint_logger@1.0.1,
17
- accelint_postcss-tailwind-css-modules@1.0.1, accelint_smeegl@0.3.5,
18
- accelint_typescript-config@0.1.4, accelint_vitest-config@0.1.6
14
+ accelint_biome-config@1.1.0, accelint_bus@4.0.0, accelint_constants@0.3.0,
15
+ accelint_core@0.6.0, accelint_design-foundation@3.0.2,
16
+ accelint_design-toolkit@9.9.0, accelint_geo@0.6.0, accelint_logger@1.1.0,
17
+ accelint_postcss-tailwind-css-modules@1.0.1, accelint_predicates@0.5.2,
18
+ accelint_smeegl@0.3.5, accelint_typescript-config@0.1.4,
19
+ accelint_vitest-config@0.1.6
19
20
  annotations:
20
21
  backstage.io/edit-url: https://github.com/gohypergiant/standard-toolkit/blob/main/packages/map-toolkit/catalog-info.yaml
21
22
  backstage.io/techdocs-ref: dir:.
22
- package/version: 2.0.0
23
+ package/version: 3.0.0
23
24
  github.com/project-slug: gohypergiant/standard-toolkit
24
25
  links:
25
26
  - url: https://github.com/gohypergiant/standard-toolkit/tree/main/packages/map-toolkit
@@ -38,12 +39,14 @@ spec:
38
39
  dependsOn:
39
40
  - component:accelint_biome-config
40
41
  - component:accelint_bus
42
+ - component:accelint_constants
41
43
  - component:accelint_core
42
44
  - component:accelint_design-foundation
43
45
  - component:accelint_design-toolkit
44
46
  - component:accelint_geo
45
47
  - component:accelint_logger
46
48
  - component:accelint_postcss-tailwind-css-modules
49
+ - component:accelint_predicates
47
50
  - component:accelint_smeegl
48
51
  - component:accelint_typescript-config
49
52
  - component:accelint_vitest-config
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import { BaseMapProps } from "./types.js";
14
- import * as react_jsx_runtime0 from "react/jsx-runtime";
14
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
15
15
 
16
16
  //#region src/deckgl/base-map/index.d.ts
17
17
 
@@ -106,7 +106,7 @@ declare function BaseMap({
106
106
  onViewStateChange,
107
107
  pickingRadius,
108
108
  ...rest
109
- }: BaseMapProps): react_jsx_runtime0.JSX.Element;
109
+ }: BaseMapProps): react_jsx_runtime1.JSX.Element;
110
110
  //#endregion
111
111
  export { BaseMap };
112
112
  //# sourceMappingURL=index.d.ts.map
@@ -12,7 +12,7 @@
12
12
 
13
13
  import { ReactNode } from "react";
14
14
  import { UniqueId } from "@accelint/core";
15
- import * as react_jsx_runtime1 from "react/jsx-runtime";
15
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
16
16
 
17
17
  //#region src/deckgl/base-map/provider.d.ts
18
18
  /**
@@ -139,7 +139,7 @@ type MapProviderProps = {
139
139
  declare function MapProvider({
140
140
  children,
141
141
  id
142
- }: MapProviderProps): react_jsx_runtime1.JSX.Element;
142
+ }: MapProviderProps): react_jsx_runtime0.JSX.Element;
143
143
  //#endregion
144
144
  export { MapContext, MapProvider, MapProviderProps };
145
145
  //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1,144 @@
1
+ /*
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { CoffinCornerExtensionProps, EntityId } from "./types.js";
14
+ import { Layer, LayerExtension, UpdateParameters } from "@deck.gl/core";
15
+ import { Rgba255Tuple } from "@accelint/predicates";
16
+
17
+ //#region src/deckgl/extensions/coffin-corner/coffin-corner-extension.d.ts
18
+ /** Layer shape with coffin-corner selection and hover state maps. */
19
+ type CoffinCornerLayer = Layer & {
20
+ state: {
21
+ selectedEntities: Map<EntityId, number>;
22
+ hoveredEntities: Map<EntityId, number>;
23
+ };
24
+ };
25
+ /**
26
+ * deck.gl layer extension that renders bracket-like "coffin corner" indicators
27
+ * around hovered and selected map entities.
28
+ *
29
+ * Driven by explicit `hoveredEntityId` and `selectedEntityId` props rather than
30
+ * deck.gl's built-in autoHighlight. Data objects are identified via the
31
+ * `getEntityId` accessor (defaults to `item => item.id`).
32
+ *
33
+ * **Supported layer types:**
34
+ * - **IconLayer** (and subclasses like SymbolLayer) — samples `iconsTexture`
35
+ * to re-composite the icon beneath the brackets.
36
+ * - **ScatterplotLayer** — replicates the circle fill/stroke logic to composite
37
+ * the circle beneath the brackets.
38
+ *
39
+ * Using this extension on unsupported layer types will produce shader compilation
40
+ * errors due to missing layer-specific uniforms/varyings.
41
+ *
42
+ * The host layer must set `pickable` to enable picking events.
43
+ *
44
+ * @see CoffinCornerExtensionProps for the full list of extension props.
45
+ *
46
+ * @example Fiber renderer JSX (IconLayer / SymbolLayer)
47
+ * ```tsx
48
+ * <symbolLayer
49
+ * {...props}
50
+ * pickable
51
+ * extensions={[new CoffinCornerExtension()]}
52
+ * selectedEntityId={selectedId}
53
+ * hoveredEntityId={hoveredId}
54
+ * />
55
+ * ```
56
+ *
57
+ * @example ScatterplotLayer
58
+ * ```typescript
59
+ * new ScatterplotLayer({
60
+ * extensions: [new CoffinCornerExtension()],
61
+ * getEntityId: (d) => d.id,
62
+ * selectedEntityId: selectedId,
63
+ * hoveredEntityId: hoveredId,
64
+ * })
65
+ * ```
66
+ *
67
+ * @example Custom entity ID accessor (e.g. GeoJSON features)
68
+ * ```typescript
69
+ * new IconLayer({
70
+ * extensions: [new CoffinCornerExtension()],
71
+ * getEntityId: (d) => d.properties?.shapeId,
72
+ * selectedEntityId: selectedShapeId,
73
+ * hoveredEntityId: hoveredShapeId,
74
+ * selectedCoffinCornerColor: [255, 0, 0, 255],
75
+ * })
76
+ * ```
77
+ */
78
+ declare class CoffinCornerExtension extends LayerExtension {
79
+ static componentName: string;
80
+ static defaultProps: {
81
+ selectedEntityId: {
82
+ type: string;
83
+ value: undefined;
84
+ };
85
+ hoveredEntityId: {
86
+ type: string;
87
+ value: undefined;
88
+ };
89
+ selectedCoffinCornerColor: {
90
+ type: string;
91
+ value: Rgba255Tuple;
92
+ };
93
+ getEntityId: {
94
+ type: string;
95
+ value: (item: {
96
+ id: EntityId;
97
+ }) => EntityId;
98
+ };
99
+ };
100
+ /** Returns true if the host layer is a supported type. */
101
+ private static isSupportedLayer;
102
+ /**
103
+ * Initializes selection and hover entity state maps and registers
104
+ * `instanceSelectedEntity` / `instanceHoveredEntity` GPU attributes.
105
+ * No-op on unsupported layer types (e.g. PathLayer, SolidPolygonLayer).
106
+ */
107
+ initializeState(this: CoffinCornerLayer): void;
108
+ /**
109
+ * Syncs `selectedEntityId` and `hoveredEntityId` prop changes into the
110
+ * entity state maps and invalidates the corresponding GPU attributes.
111
+ * No-op on unsupported layer types.
112
+ *
113
+ * @param params - The deck.gl update parameters containing current and previous props.
114
+ */
115
+ updateState(this: CoffinCornerLayer, params: UpdateParameters<Layer<CoffinCornerExtensionProps>>): void;
116
+ /**
117
+ * Pushes the normalized `selectedCoffinCornerColor` to the shader's `highlightColor` uniform
118
+ * each frame. No-op on unsupported layer types.
119
+ */
120
+ draw(this: CoffinCornerLayer): void;
121
+ /**
122
+ * Returns the appropriate shader injection config based on the host layer type.
123
+ * IconLayer gets texture-sampling shaders; ScatterplotLayer gets circle-replicating shaders.
124
+ * Returns null for unsupported layer types to skip shader injection.
125
+ *
126
+ * @returns The vertex/fragment shader injection config and uniform module, or null.
127
+ */
128
+ getShaders(this: CoffinCornerLayer, _extensions: this): {
129
+ modules: {
130
+ name: string;
131
+ fs: string;
132
+ uniformTypes: Record<string, string>;
133
+ }[];
134
+ inject: {
135
+ 'vs:#decl': string;
136
+ 'vs:#main-end': string;
137
+ 'fs:#decl': string;
138
+ 'fs:#main-start': string;
139
+ };
140
+ } | null;
141
+ }
142
+ //#endregion
143
+ export { CoffinCornerExtension };
144
+ //# sourceMappingURL=coffin-corner-extension.d.ts.map