@defra/interactive-map 0.0.4-alpha → 0.0.6-alpha

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 (203) hide show
  1. package/dist/css/index.css +1 -1
  2. package/dist/esm/im-core.js +1 -1
  3. package/dist/esm/index.js +1 -1
  4. package/dist/umd/im-core.js +1 -1
  5. package/dist/umd/index.js +1 -1
  6. package/docs/api.md +8 -0
  7. package/package.json +3 -2
  8. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +2 -1
  9. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js.LICENSE.txt +1 -0
  10. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +2 -1
  11. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js.LICENSE.txt +1 -0
  12. package/plugins/beta/datasets/dist/umd/index.js +1 -1
  13. package/plugins/beta/datasets/src/datasets.js +55 -2
  14. package/plugins/beta/datasets/src/fetch/createDynamicSource.js +206 -0
  15. package/plugins/beta/datasets/src/fetch/fetchGeoJSON.js +38 -0
  16. package/plugins/beta/datasets/src/handleSetMapStyle.js +8 -1
  17. package/plugins/beta/datasets/src/mapLayers.js +41 -3
  18. package/plugins/beta/datasets/src/utils/bbox.js +113 -2
  19. package/plugins/beta/draw-ml/dist/css/index.css +1 -1
  20. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  21. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  22. package/plugins/beta/draw-ml/dist/umd/index.js +1 -1
  23. package/plugins/beta/draw-ml/src/api/addFeature.js +15 -3
  24. package/plugins/beta/draw-ml/src/api/editFeature.js +16 -5
  25. package/plugins/beta/draw-ml/src/api/newLine.js +32 -7
  26. package/plugins/beta/draw-ml/src/api/newPolygon.js +33 -8
  27. package/plugins/beta/draw-ml/src/defaults.js +1 -0
  28. package/plugins/beta/draw-ml/src/draw.scss +23 -0
  29. package/plugins/beta/draw-ml/src/events.js +55 -113
  30. package/plugins/beta/draw-ml/src/manifest.js +64 -38
  31. package/plugins/beta/draw-ml/src/mapboxSnap.js +16 -12
  32. package/plugins/beta/draw-ml/src/modes/createDrawMode.js +4 -3
  33. package/plugins/beta/draw-ml/src/modes/editVertex/geometryHelpers.js +135 -0
  34. package/plugins/beta/draw-ml/src/modes/editVertex/helpers.js +2 -0
  35. package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +134 -0
  36. package/plugins/beta/draw-ml/src/modes/editVertex/undoHandlers.js +133 -0
  37. package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +141 -0
  38. package/plugins/beta/draw-ml/src/modes/editVertex/vertexQueries.js +121 -0
  39. package/plugins/beta/draw-ml/src/modes/editVertexMode.js +51 -406
  40. package/plugins/beta/draw-ml/src/utils/flattenStyleProperties.js +49 -0
  41. package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -1
  42. package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -1
  43. package/plugins/beta/frame/src/Frame.jsx +1 -1
  44. package/plugins/beta/map-styles/dist/css/index.css +1 -1
  45. package/plugins/beta/map-styles/dist/esm/index.js +1 -1
  46. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
  47. package/plugins/beta/map-styles/dist/umd/index.js +1 -1
  48. package/plugins/beta/map-styles/src/mapStyles.scss +4 -1
  49. package/plugins/interact/dist/css/index.css +1 -1
  50. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  51. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  52. package/plugins/interact/dist/umd/index.js +1 -1
  53. package/plugins/interact/src/InteractInit.jsx +1 -1
  54. package/plugins/interact/src/defaults.js +1 -0
  55. package/plugins/interact/src/events.js +37 -52
  56. package/plugins/interact/src/events.test.js +35 -0
  57. package/plugins/interact/src/hooks/useHighlightSync.js +1 -1
  58. package/plugins/interact/src/hooks/useInteractionHandlers.js +80 -48
  59. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +64 -8
  60. package/plugins/interact/src/interact.scss +6 -0
  61. package/plugins/interact/src/reducer.js +25 -27
  62. package/plugins/interact/src/reducer.test.js +19 -6
  63. package/plugins/interact/src/utils/featureQueries.js +2 -2
  64. package/plugins/interact/src/utils/spatial.js +99 -0
  65. package/plugins/interact/src/utils/spatial.test.js +100 -0
  66. package/plugins/search/dist/css/index.css +1 -1
  67. package/plugins/search/dist/esm/im-search-plugin.js +1 -1
  68. package/plugins/search/dist/umd/im-search-plugin.js +1 -1
  69. package/plugins/search/dist/umd/index.js +1 -1
  70. package/plugins/search/src/Search.jsx +2 -2
  71. package/plugins/search/src/components/Form/Form.jsx +1 -1
  72. package/plugins/search/src/components/Suggestions/Suggestions.jsx +5 -5
  73. package/plugins/search/src/datasets.js +1 -1
  74. package/plugins/search/src/defaults.js +3 -0
  75. package/plugins/search/src/events/fetchSuggestions.js +48 -53
  76. package/plugins/search/src/events/formHandlers.js +3 -2
  77. package/plugins/search/src/events/index.js +1 -1
  78. package/plugins/search/src/events/inputHandlers.js +3 -1
  79. package/plugins/search/src/events/suggestionHandlers.js +12 -3
  80. package/plugins/search/src/search.scss +4 -1
  81. package/plugins/search/src/utils/parseOsNamesResults.js +12 -12
  82. package/providers/beta/esri/src/esriProvider.js +1 -1
  83. package/providers/beta/esri/src/index.js +1 -1
  84. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  85. package/providers/maplibre/dist/esm/index.js +1 -1
  86. package/providers/maplibre/dist/umd/im-maplibre-framework.js +1 -1
  87. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  88. package/providers/maplibre/dist/umd/index.js +1 -1
  89. package/providers/maplibre/src/defaults.js +3 -2
  90. package/providers/maplibre/src/index.js +22 -19
  91. package/providers/maplibre/src/maplibreProvider.js +13 -11
  92. package/providers/maplibre/src/utils/detectWebgl.js +1 -2
  93. package/providers/maplibre/src/utils/highlightFeatures.js +78 -67
  94. package/providers/maplibre/src/utils/labels.js +174 -120
  95. package/providers/maplibre/src/utils/maplibreFixes.js +2 -2
  96. package/providers/maplibre/src/utils/queryFeatures.js +146 -0
  97. package/providers/maplibre/src/utils/spatial.js +14 -17
  98. package/sonar-project.properties +39 -2
  99. package/src/App/components/Actions/Actions.jsx +2 -2
  100. package/src/App/components/Actions/Actions.module.scss +2 -2
  101. package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +3 -1
  102. package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +9 -0
  103. package/src/App/components/Logo/Logo.jsx +1 -1
  104. package/src/App/components/MapButton/MapButton.jsx +217 -41
  105. package/src/App/components/MapButton/MapButton.module.scss +32 -21
  106. package/src/App/components/MapButton/MapButton.test.jsx +128 -84
  107. package/src/App/components/Markers/Markers.jsx +1 -1
  108. package/src/App/components/Markers/Markers.module.scss +0 -5
  109. package/src/App/components/Panel/Panel.jsx +75 -45
  110. package/src/App/components/Panel/Panel.module.scss +18 -24
  111. package/src/App/components/Panel/Panel.test.jsx +18 -0
  112. package/src/App/components/PopupMenu/PopupMenu.jsx +246 -0
  113. package/src/App/components/PopupMenu/PopupMenu.module.scss +70 -0
  114. package/src/App/components/PopupMenu/PopupMenu.test.jsx +304 -0
  115. package/src/App/components/Tooltip/Tooltip.jsx +4 -2
  116. package/src/App/components/Tooltip/getTooltipPosition.js +1 -1
  117. package/src/App/components/Viewport/MapController.jsx +1 -1
  118. package/src/App/components/Viewport/MapStatus.jsx +1 -1
  119. package/src/App/components/Viewport/Viewport.jsx +2 -2
  120. package/src/App/components/Viewport/Viewport.module.scss +2 -2
  121. package/src/App/controls/keyboardActions.js +3 -2
  122. package/src/App/controls/keyboardShortcuts.js +4 -2
  123. package/src/App/hooks/useButtonStateEvaluator.js +58 -45
  124. package/src/App/hooks/useButtonStateEvaluator.test.js +36 -3
  125. package/src/App/hooks/useCrossHairAPI.js +49 -47
  126. package/src/App/hooks/useFocusVisible.js +2 -2
  127. package/src/App/hooks/useInterfaceAPI.js +16 -4
  128. package/src/App/hooks/useKeyboardHint.js +1 -1
  129. package/src/App/hooks/useKeyboardShortcuts.js +4 -2
  130. package/src/App/hooks/useMapAnnouncements.js +34 -32
  131. package/src/App/hooks/useMapEvents.js +12 -1
  132. package/src/App/hooks/useMapProviderOverrides.js +3 -3
  133. package/src/App/hooks/useMapStateSync.js +7 -1
  134. package/src/App/hooks/useMapURLSync.js +6 -1
  135. package/src/App/hooks/useMarkersAPI.js +88 -50
  136. package/src/App/hooks/useMediaQueryDispatch.test.js +48 -0
  137. package/src/App/hooks/useModalPanelBehaviour.js +46 -40
  138. package/src/App/hooks/useResizeObserver.js +2 -2
  139. package/src/App/initialiseApp.js +45 -38
  140. package/src/App/layout/Layout.jsx +6 -4
  141. package/src/App/layout/layout.module.scss +13 -17
  142. package/src/App/registry/keyboardShortcutRegistry.js +12 -2
  143. package/src/App/registry/keyboardShortcutRegistry.test.js +28 -0
  144. package/src/App/registry/mergeManifests.js +1 -1
  145. package/src/App/registry/panelRegistry.js +1 -1
  146. package/src/App/registry/panelRegistry.test.js +30 -1
  147. package/src/App/registry/pluginRegistry.js +14 -51
  148. package/src/App/registry/pluginRegistry.test.js +54 -6
  149. package/src/App/renderer/HtmlElementHost.jsx +186 -0
  150. package/src/App/renderer/HtmlElementHost.test.jsx +231 -0
  151. package/src/App/renderer/mapButtons.js +11 -8
  152. package/src/App/renderer/mapButtons.test.js +6 -4
  153. package/src/App/renderer/mapControls.js +6 -0
  154. package/src/App/renderer/mapControls.test.js +10 -2
  155. package/src/App/renderer/mapPanels.js +39 -26
  156. package/src/App/renderer/mapPanels.test.js +29 -0
  157. package/src/App/renderer/pluginWrapper.test.js +28 -0
  158. package/src/App/renderer/slotHelpers.js +60 -0
  159. package/src/App/renderer/slotHelpers.test.js +82 -0
  160. package/src/App/store/AppProvider.jsx +21 -18
  161. package/src/App/store/AppProvider.test.jsx +40 -0
  162. package/src/App/store/PluginProvider.jsx +7 -5
  163. package/src/App/store/appActionsMap.js +28 -1
  164. package/src/App/store/appActionsMap.test.js +26 -0
  165. package/src/App/store/appReducer.js +1 -0
  166. package/src/App/store/mapActionsMap.js +12 -24
  167. package/src/App/store/mapReducer.js +1 -1
  168. package/src/InteractiveMap/InteractiveMap.js +79 -6
  169. package/src/InteractiveMap/InteractiveMap.test.js +164 -2
  170. package/src/InteractiveMap/behaviourController.js +12 -2
  171. package/src/InteractiveMap/behaviourController.test.js +82 -1
  172. package/src/InteractiveMap/deviceChecker.js +1 -1
  173. package/src/InteractiveMap/deviceChecker.test.js +2 -2
  174. package/src/InteractiveMap/historyManager.js +41 -5
  175. package/src/InteractiveMap/historyManager.test.js +37 -6
  176. package/src/InteractiveMap/polyfills.js +39 -0
  177. package/src/InteractiveMap/polyfills.test.js +127 -0
  178. package/src/config/appConfig.js +5 -5
  179. package/src/config/appConfig.test.js +107 -42
  180. package/src/config/defaults.js +1 -0
  181. package/src/index.umd.js +1 -1
  182. package/src/scss/main.scss +1 -0
  183. package/src/scss/settings/_colors.scss +1 -1
  184. package/src/scss/settings/_dimensions.scss +4 -0
  185. package/src/services/eventBus.test.js +24 -1
  186. package/src/test-utils.js +1 -0
  187. package/src/types.js +5 -0
  188. package/src/utils/detectBreakpoint.js +78 -77
  189. package/src/utils/detectBreakpoint.test.js +50 -4
  190. package/src/utils/detectInterfaceType.js +6 -5
  191. package/src/utils/getIsFullscreen.js +3 -1
  192. package/src/utils/getSafeZoneInset.js +23 -7
  193. package/src/utils/getSafeZoneInset.test.js +18 -0
  194. package/src/utils/mapStateSync.js +3 -3
  195. package/src/utils/queryString.js +1 -1
  196. package/src/utils/stringToKebab.js +1 -1
  197. package/src/utils/toggleInertElements.js +37 -12
  198. package/webpack.dev.mjs +3 -4
  199. package/plugins/interact/src/utils/turfHelpers.js +0 -30
  200. package/plugins/interact/src/utils/turfHelpers.test.js +0 -30
  201. package/plugins/search/src/utils/fetchDataset.js +0 -23
  202. package/providers/maplibre/dist/esm/im-maplibre-legacy-framework.js +0 -1
  203. package/providers/maplibre/dist/umd/im-maplibre-legacy-framework.js +0 -1
@@ -1,33 +1,24 @@
1
1
  import DirectSelect from '../../../../../node_modules/@mapbox/mapbox-gl-draw/src/modes/direct_select.js'
2
- import { spatialNavigate } from '../utils/spatial.js'
3
2
  import {
4
3
  getSnapInstance, isSnapActive, isSnapEnabled, getSnapLngLat,
5
4
  getSnapRadius, triggerSnapAtPoint, clearSnapIndicator, clearSnapState
6
5
  } from '../utils/snapHelpers.js'
7
-
8
- const ARROW_KEYS = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']
6
+ import { getCoords, coordPathToFlatIndex } from './editVertex/geometryHelpers.js'
7
+ import { scalePoint } from './editVertex/helpers.js'
8
+ import { undoHandlers } from './editVertex/undoHandlers.js'
9
+ import { touchHandlers } from './editVertex/touchHandlers.js'
10
+ import { vertexOperations } from './editVertex/vertexOperations.js'
11
+ import { vertexQueries } from './editVertex/vertexQueries.js'
12
+
13
+ const ARROW_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'])
9
14
  const ARROW_OFFSETS = { ArrowUp: [0, -1], ArrowDown: [0, 1], ArrowLeft: [-1, 0], ArrowRight: [1, 0] }
10
- const NUDGE = 1, STEP = 5
11
-
12
- const touchVertexTarget = `
13
- <svg width='48' height='48' viewBox='0 0 48 48' fill-rule='evenodd' style='display:none;position:absolute;top:50%;left:50%;margin:24px 0 0 -24px' class='touch-vertex-target' data-touch-vertex-target>
14
- <circle cx='24' cy='24' r='24' fill='currentColor'/>
15
- <path d="M37.543 25H34a1 1 0 1 1 0-2h3.629l-.836-.837a1 1 0 0 1 1.414-1.414l2.5 2.501A1 1 0 0 1 41 24a1 1 0 0 1-.487.858l-2.306 2.306a1 1 0 0 1-1.414-1.414l.75-.75zM23 10.414l-.793.793a1 1 0 0 1-1.414-1.414l2.5-2.5C23.481 7.105 23.734 7 24 7s.519.105.707.293l2.5 2.5a1 1 0 0 1-1.414 1.414L25 10.414V14a1 1 0 1 1-2 0v-3.586zM7 24a1 1 0 0 1 .293-.75l2.5-2.501a1 1 0 0 1 1.414 1.414l-.836.837H14a1 1 0 1 1 0 2h-3.543l.75.75a1 1 0 0 1-1.414 1.414l-2.306-2.306A1 1 0 0 1 7 24zm16.293 16.707l-2.5-2.5a1 1 0 0 1 1.414-1.414l.793.793V34a1 1 0 1 1 2 0v3.586l.793-.793a1 1 0 0 1 1.414 1.414l-2.5 2.5c-.188.188-.441.293-.707.293s-.519-.105-.707-.293zM24 20c2.208 0 4 1.792 4 4s-1.792 4-4 4-4-1.792-4-4 1.792-4 4-4z" fill="#fff"/>
16
- </svg>
17
- `
18
-
19
- const scalePoint = (point, scale) => ({ x: point.x * scale, y: point.y * scale })
20
- const isOnSVG = (el) => el instanceof window.SVGElement || el.ownerSVGElement
21
-
22
- // Helper to get flat coordinates array from feature (handles both Polygon and LineString)
23
- const getCoords = (feature) => feature?.type === 'LineString' ? feature.coordinates : feature?.coordinates?.flat(1)
24
-
25
- // Helper to get the modifiable coordinates array from geojson (for undo operations)
26
- const getModifiableCoords = (geojson) =>
27
- geojson.geometry.type === 'Polygon' ? geojson.geometry.coordinates[0] : geojson.geometry.coordinates
28
15
 
29
16
  export const EditVertexMode = {
30
17
  ...DirectSelect,
18
+ ...undoHandlers,
19
+ ...touchHandlers,
20
+ ...vertexOperations,
21
+ ...vertexQueries,
31
22
 
32
23
  onSetup(options) {
33
24
  const state = DirectSelect.onSetup.call(this, options)
@@ -41,6 +32,7 @@ export const EditVertexMode = {
41
32
  featureId: state.featureId || options.featureId,
42
33
  selectedVertexIndex: options.selectedVertexIndex ?? -1,
43
34
  selectedVertexType: options.selectedVertexType,
35
+ coordPath: options.coordPath,
44
36
  scale: options.scale ?? 1
45
37
  })
46
38
 
@@ -53,7 +45,23 @@ export const EditVertexMode = {
53
45
  this.setupEventListeners(state)
54
46
 
55
47
  if (options.selectedVertexType === 'midpoint') {
48
+ // Clear any vertex selection when switching to midpoint
49
+ state.selectedCoordPaths = []
50
+ this.clearSelectedCoordinates()
51
+ // Force feature re-render to clear vertex highlights
52
+ if (state.feature) {
53
+ state.feature.changed()
54
+ }
55
+ this._ctx.store.render()
56
56
  this.updateMidpoint(state.midpoints[options.selectedVertexIndex - state.vertecies.length])
57
+ } else if (options.selectedVertexIndex === -1) {
58
+ // Explicitly clear selection when re-entering with no vertex selected
59
+ state.selectedCoordPaths = []
60
+ this.clearSelectedCoordinates()
61
+ if (state.feature) {
62
+ state.feature.changed()
63
+ }
64
+ this._ctx.store.render()
57
65
  }
58
66
  this.addTouchVertexTarget(state)
59
67
 
@@ -108,14 +116,17 @@ export const EditVertexMode = {
108
116
 
109
117
  onSelectionChange(state, e) {
110
118
  const vertexCoord = e.points[e.points.length - 1]?.geometry.coordinates
111
- const geom = e.features[0].geometry
112
- const coords = getCoords(geom)
113
- const idx = coords.findIndex(c => vertexCoord && c[0] === vertexCoord[0] && c[1] === vertexCoord[1])
114
119
 
115
120
  // Only update selectedVertexIndex from event if not keyboard mode AND event has valid vertex
116
- if (state.interfaceType !== 'keyboard' && idx >= 0) {
117
- state.selectedVertexIndex = idx
121
+ // For keyboard mode or when we have coordPath, trust the existing selectedVertexIndex
122
+ if (state.interfaceType !== 'keyboard' && vertexCoord && !state.coordPath) {
123
+ // No coordPath available - need to search for vertex by coordinates
124
+ const geom = e.features[0]?.geometry
125
+ const coords = getCoords(geom)
126
+ state.selectedVertexIndex = this.findVertexIndex(coords, vertexCoord, state.selectedVertexIndex)
118
127
  }
128
+ // If we have coordPath, selectedVertexIndex is already correct from onTap/changeMode
129
+
119
130
  state.selectedVertexType ??= state.selectedVertexIndex >= 0 ? 'vertex' : null
120
131
 
121
132
  this.map.fire('draw.vertexselection', {
@@ -164,7 +175,7 @@ export const EditVertexMode = {
164
175
  return this.updateVertex(state)
165
176
  }
166
177
 
167
- if (!e.altKey && ARROW_KEYS.includes(e.key) && state.selectedVertexIndex >= 0) {
178
+ if (!e.altKey && ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
168
179
  e.preventDefault()
169
180
  e.stopPropagation()
170
181
  if (state.selectedVertexType === 'midpoint') {
@@ -210,7 +221,7 @@ export const EditVertexMode = {
210
221
  return this.moveVertex(state, newCoord)
211
222
  }
212
223
 
213
- if (e.altKey && ARROW_KEYS.includes(e.key) && state.selectedVertexIndex >= 0) {
224
+ if (e.altKey && ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
214
225
  e.preventDefault()
215
226
  e.stopPropagation()
216
227
  return this.updateVertex(state, e.key)
@@ -234,7 +245,7 @@ export const EditVertexMode = {
234
245
 
235
246
  onKeyup(state, e) {
236
247
  state.interfaceType = 'keyboard'
237
- if (ARROW_KEYS.includes(e.key) && state.selectedVertexIndex >= 0) {
248
+ if (ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
238
249
  e.stopPropagation()
239
250
 
240
251
  // Push undo for keyboard move sequence
@@ -264,11 +275,13 @@ export const EditVertexMode = {
264
275
  state.dragMoving = false
265
276
  DirectSelect.onMouseDown.call(this, state, e)
266
277
 
267
- // Save starting position for undo (only for vertices, not midpoints)
278
+ // Update selection state for vertex clicks (so onSelectionChange has correct context)
268
279
  if (meta === 'vertex' && coordPath) {
269
- // Extract vertex index from coord_path (e.g., "0.2" -> 2 for Polygon, "2" -> 2 for LineString)
270
- const parts = coordPath.split('.')
271
- const vertexIndex = Number.parseInt(parts[parts.length - 1], 10)
280
+ const feature = this.getFeature(state.featureId)
281
+ const vertexIndex = coordPathToFlatIndex(feature, coordPath)
282
+ state.selectedVertexIndex = vertexIndex
283
+ state.selectedVertexType = 'vertex'
284
+ state.coordPath = coordPath
272
285
  const vertex = state.vertecies?.[vertexIndex]
273
286
  if (vertex) {
274
287
  state._moveStartPosition = [...vertex]
@@ -278,9 +291,8 @@ export const EditVertexMode = {
278
291
  }
279
292
  if (meta === 'midpoint') {
280
293
  // DirectSelect converts midpoint to vertex - track this as an insert
281
- // Get the new vertex index (midpoint at position N becomes vertex at N+1)
282
- const parts = coordPath.split('.')
283
- const insertedIndex = Number.parseInt(parts[parts.length - 1], 10)
294
+ const feature = this.getFeature(state.featureId)
295
+ const insertedIndex = coordPathToFlatIndex(feature, coordPath)
284
296
 
285
297
  // Track this insertion for undo (will be pushed on mouseUp if drag occurred)
286
298
  state._insertedVertexIndex = insertedIndex
@@ -288,6 +300,7 @@ export const EditVertexMode = {
288
300
 
289
301
  state.selectedVertexIndex = this.getVertexIndexFromMidpoint(state, coordPath)
290
302
  state.selectedVertexType = 'vertex'
303
+ state.coordPath = null // Clear coordPath for midpoints
291
304
  this.map.fire('draw.vertexselection', { index: state.selectedVertexIndex, numVertecies: state.vertecies.length })
292
305
  }
293
306
  },
@@ -344,108 +357,6 @@ export const EditVertexMode = {
344
357
  DirectSelect.onMouseUp.call(this, state, e)
345
358
  },
346
359
 
347
- onPointerevent(state, e) {
348
- state.interfaceType = e.pointerType === 'touch' ? 'touch' : 'pointer'
349
- state.isPanEnabled = true
350
- if (e.pointerType === 'touch' && e.type === 'pointermove' && !isOnSVG(e.target.parentNode) && !state._ignorePointermoveDeselect) {
351
- this.changeMode(state, { selectedVertexIndex: -1, selectedVertexType: null, coordPath: null })
352
- }
353
- },
354
-
355
- // Empty stubs required by DirectSelect
356
- onTouchStart() {},
357
- onTouchMove() {},
358
- onTouchEnd() {},
359
-
360
- onTouchend(state) {
361
- clearSnapState(getSnapInstance(this.map))
362
- if (state?.featureId) {
363
- this.syncVertices(state)
364
-
365
- // Push undo for the move if touch actually moved
366
- if (state._touchMoved && state._moveStartPosition && state._moveStartIndex !== undefined) {
367
- this.pushUndo({
368
- type: 'move_vertex',
369
- featureId: state.featureId,
370
- vertexIndex: state._moveStartIndex,
371
- previousPosition: state._moveStartPosition
372
- })
373
- }
374
- state._moveStartPosition = null
375
- state._moveStartIndex = undefined
376
- state._touchMoved = false
377
- }
378
- },
379
-
380
- clickNoTarget(state) {
381
- this.changeMode(state, { selectedVertexIndex: -1, selectedVertexType: null, isPanEnabled: true })
382
- },
383
-
384
- onTap(state, e) {
385
- // Hide snap indicator on any tap
386
- const snap = getSnapInstance(this.map)
387
- if (snap) {
388
- clearSnapIndicator(snap, this.map)
389
- }
390
-
391
- const meta = e.featureTarget?.properties.meta
392
- const coordPath = e.featureTarget?.properties.coord_path
393
-
394
- if (meta === 'vertex') {
395
- // Extract vertex index - handle both "0.1" (Polygon) and "1" (LineString) formats
396
- const parts = coordPath.split('.')
397
- const idx = Number.parseInt(parts[parts.length - 1], 10)
398
- this.changeMode(state, {
399
- selectedVertexIndex: idx,
400
- selectedVertexType: 'vertex', coordPath
401
- })
402
- } else if (meta === 'midpoint') {
403
- this.insertVertex({ ...state, selectedVertexIndex: this.getVertexIndexFromMidpoint(state, coordPath), selectedVertexType: 'midpoint' })
404
- } else {
405
- this.clickNoTarget(state)
406
- }
407
- },
408
-
409
- onTouchstart(state, e) {
410
- clearSnapState(getSnapInstance(this.map))
411
- const vertex = state.vertecies?.[state.selectedVertexIndex]
412
- if (!vertex || !isOnSVG(e.target.parentNode)) {
413
- return
414
- }
415
-
416
- // Save starting position for undo
417
- state._moveStartPosition = [...vertex]
418
- state._moveStartIndex = state.selectedVertexIndex
419
- state._touchMoved = false
420
-
421
- const touch = { x: e.touches[0].clientX, y: e.touches[0].clientY }
422
- const style = window.getComputedStyle(state.touchVertexTarget)
423
- state.deltaTarget = { x: touch.x - Number.parseFloat(style.left), y: touch.y - Number.parseFloat(style.top) }
424
- const vertexPt = this.map.project(vertex)
425
- state.deltaVertex = { x: (touch.x / state.scale) - vertexPt.x, y: (touch.y / state.scale) - vertexPt.y }
426
- },
427
-
428
- onTouchmove(state, e) {
429
- if (state.selectedVertexIndex < 0 || !isOnSVG(e.target.parentNode)) {
430
- return
431
- }
432
-
433
- state._touchMoved = true
434
-
435
- const touch = { x: e.touches[0].clientX, y: e.touches[0].clientY }
436
- const screenPt = { x: (touch.x / state.scale) - state.deltaVertex.x, y: (touch.y / state.scale) - state.deltaVertex.y }
437
-
438
- let finalCoord = this.map.unproject(screenPt)
439
- if (isSnapEnabled(state)) {
440
- const snap = getSnapInstance(this.map)
441
- triggerSnapAtPoint(snap, this.map, screenPt)
442
- finalCoord = getSnapLngLat(snap) || finalCoord
443
- }
444
-
445
- this.moveVertex(state, finalCoord)
446
- this.updateTouchVertexTarget(state, { x: touch.x - state.deltaTarget.x, y: touch.y - state.deltaTarget.y })
447
- },
448
-
449
360
  onDrag(state, e) {
450
361
  if (state.interfaceType === 'touch') {
451
362
  return
@@ -493,194 +404,8 @@ export const EditVertexMode = {
493
404
  }
494
405
  },
495
406
 
496
- handleUndo(state) {
497
- const undoStack = this.map._undoStack
498
- if (!undoStack || undoStack.length === 0) {
499
- return
500
- }
501
-
502
- const op = undoStack.pop()
503
-
504
- if (op.type === 'move_vertex') {
505
- this.undoMoveVertex(state, op)
506
- } else if (op.type === 'insert_vertex') {
507
- this.undoInsertVertex(state, op)
508
- } else if (op.type === 'delete_vertex') {
509
- this.undoDeleteVertex(state, op)
510
- } else {
511
- // No action
512
- }
513
- },
514
-
515
- // Utility methods
516
- getCoordPath(state, idx) {
517
- // Use cached featureType or look it up
518
- const type = state.featureType || this.getFeature(state.featureId)?.type
519
- return type === 'LineString' ? `${idx}` : `0.${idx}`
520
- },
521
-
522
- syncVertices(state) {
523
- state.vertecies = this.getVerticies(state.featureId)
524
- state.midpoints = this.getMidpoints(state.featureId)
525
- },
526
-
527
- getVerticies(featureId) {
528
- return getCoords(this.getFeature(featureId)) || []
529
- },
530
-
531
- getMidpoints(featureId) {
532
- const feature = this.getFeature(featureId)
533
- const coords = getCoords(feature)
534
- if (!coords) {
535
- return []
536
- }
537
-
538
- // For lines, don't create midpoint between last and first vertex
539
- const count = feature.type === 'LineString' ? coords.length - 1 : coords.length
540
- const midpoints = []
541
- for (let i = 0; i < count; i++) {
542
- const next = coords[(i + 1) % coords.length]
543
- midpoints.push([(coords[i][0] + next[0]) / 2, (coords[i][1] + next[1]) / 2])
544
- }
545
- return midpoints
546
- },
547
-
548
- getVertexOrMidpoint(state, direction) {
549
- // Ensure vertices and midpoints are populated
550
- if (!state.vertecies?.length) {
551
- state.vertecies = this.getVerticies(state.featureId)
552
- state.midpoints = this.getMidpoints(state.featureId)
553
- }
554
- if (!state.vertecies?.length) {
555
- return [-1, null]
556
- }
557
- const project = (p) => p ? Object.values(this.map.project(p)) : null
558
- const pixels = [...state.vertecies.map(project), ...state.midpoints.map(project)].filter(Boolean)
559
- if (!pixels.length) {
560
- return [-1, null]
561
- }
562
- const start = pixels[state.selectedVertexIndex] || Object.values(this.map.project(this.map.getCenter()))
563
- const idx = spatialNavigate(start, pixels, direction)
564
- return [idx, idx < state.vertecies.length ? 'vertex' : 'midpoint']
565
- },
566
-
567
- getVertexIndexFromMidpoint(state, coordPath) {
568
- // Handle both "0.1" (Polygon) and "1" (LineString) formats
569
- const parts = coordPath.split('.')
570
- const afterIdx = Number.parseInt(parts[parts.length - 1], 10)
571
-
572
- // Get feature type from cache or look it up
573
- const featureType = state.featureType || this.getFeature(state.featureId)?.type
574
-
575
- // For LineString, coord_path is insertion position (1-indexed), so subtract 1 for midpoint array index
576
- // For Polygon, adjust for ring wrapping
577
- if (featureType === 'LineString') {
578
- return state.vertecies.length + (afterIdx - 1)
579
- }
580
- return state.vertecies.length + ((afterIdx - 1 + state.vertecies.length) % state.vertecies.length)
581
- },
582
-
583
- addTouchVertexTarget(state) {
584
- let el = state.container.querySelector('[data-touch-vertex-target]')
585
- if (!el) {
586
- state.container.insertAdjacentHTML('beforeend', touchVertexTarget)
587
- el = state.container.querySelector('[data-touch-vertex-target]')
588
- }
589
- state.touchVertexTarget = el
590
- },
591
-
592
- updateTouchVertexTarget(state, point) {
593
- if (point && state.interfaceType === 'touch' && state.selectedVertexIndex >= 0) {
594
- Object.assign(state.touchVertexTarget.style, { display: 'block', top: `${point.y}px`, left: `${point.x}px` })
595
- } else {
596
- state.touchVertexTarget.style.display = 'none'
597
- }
598
- },
599
-
600
- hideTouchVertexIndicator(state) {
601
- state.touchVertexTarget.style.display = 'none'
602
- },
603
-
604
- updateMidpoint(coordinates) {
605
- setTimeout(() => {
606
- this.map.getSource('mapbox-gl-draw-hot').setData({
607
- type: 'Feature',
608
- properties: { meta: 'midpoint', active: 'true', id: 'active-midpoint' },
609
- geometry: { type: 'Point', coordinates }
610
- })
611
- }, 0)
612
- },
613
-
614
- updateVertex(state, direction) {
615
- const [idx, type] = this.getVertexOrMidpoint(state, direction)
616
- if (idx < 0 || !type) {
617
- return
618
- }
619
- this.changeMode(state, { selectedVertexIndex: idx, selectedVertexType: type, ...(type === 'vertex' && { coordPath: this.getCoordPath(state, idx) }) })
620
- },
621
-
622
- getOffset(coord, e) {
623
- const pt = this.map.project(coord)
624
- const offset = e?.shiftKey ? NUDGE : STEP
625
- const [dx, dy] = e ? ARROW_OFFSETS[e.key].map(v => v * offset) : [0, 0]
626
- return this.map.unproject({ x: pt.x + dx, y: pt.y + dy })
627
- },
628
-
629
- getNewCoord(state, e) {
630
- return this.getOffset(getCoords(this.getFeature(state.featureId))[state.selectedVertexIndex], e)
631
- },
632
-
633
- insertVertex(state, e) {
634
- const midIdx = state.selectedVertexIndex - state.vertecies.length
635
- const newCoord = this.getOffset(state.midpoints[midIdx], e)
636
- const geojson = this.getFeature(state.featureId).toGeoJSON()
637
- const newIdx = midIdx + 1
638
- getModifiableCoords(geojson).splice(newIdx, 0, [newCoord.lng, newCoord.lat])
639
- this._ctx.api.add(geojson)
640
-
641
- this.pushUndo({ type: 'insert_vertex', featureId: state.featureId, vertexIndex: newIdx })
642
- this.changeMode(state, { selectedVertexIndex: newIdx, selectedVertexType: 'vertex', coordPath: this.getCoordPath(state, newIdx) })
643
- },
644
-
645
- moveVertex(state, coord, options = {}) {
646
- if (options.checkSnap && state.enableSnap !== false) {
647
- const snap = this.map._snapInstance
648
- if (snap?.snapStatus && snap.snapCoords?.length >= 2) {
649
- coord = { lng: snap.snapCoords[0], lat: snap.snapCoords[1] }
650
- }
651
- }
652
- const geojson = this.getFeature(state.featureId).toGeoJSON()
653
- getModifiableCoords(geojson)[state.selectedVertexIndex] = [coord.lng, coord.lat]
654
- this._ctx.api.add(geojson)
655
- state.vertecies = this.getVerticies(state.featureId)
656
-
657
- this.map.fire('draw.geometrychange', state.feature)
658
- },
659
-
660
- deleteVertex(state) {
661
- const featureType = state.featureType || this.getFeature(state.featureId)?.type
662
- // Minimum vertices: 3 for Polygon, 2 for LineString
663
- const minVertices = featureType === 'Polygon' ? 3 : 2
664
- if (state.vertecies.length <= minVertices) {
665
- return
666
- }
667
-
668
- // Save position for undo before deletion
669
- const deletedPosition = [...state.vertecies[state.selectedVertexIndex]]
670
- const deletedIndex = state.selectedVertexIndex
671
-
672
- const nextIdx = state.selectedVertexIndex >= state.vertecies.length - 1 ? state.selectedVertexIndex - 1 : state.selectedVertexIndex
673
- this._ctx.api.trash()
674
-
675
- // Push undo operation
676
- this.pushUndo({
677
- type: 'delete_vertex',
678
- featureId: state.featureId,
679
- vertexIndex: deletedIndex,
680
- position: deletedPosition
681
- })
682
-
683
- this.changeMode(state, { selectedVertexIndex: nextIdx, selectedVertexType: 'vertex', coordPath: this.getCoordPath(state, nextIdx) })
407
+ clickNoTarget(state) {
408
+ this.changeMode(state, { selectedVertexIndex: -1, selectedVertexType: null, isPanEnabled: true })
684
409
  },
685
410
 
686
411
  // Prevent selecting other features
@@ -691,86 +416,6 @@ export const EditVertexMode = {
691
416
  this._ctx.api.changeMode('edit_vertex', { ...state, ...updates })
692
417
  },
693
418
 
694
- // Fire geometry change event (for external listeners)
695
- fireGeometryChange(state) {
696
- const feature = this.getFeature(state.featureId)
697
- if (feature) {
698
- this.map.fire('draw.update', {
699
- features: [feature.toGeoJSON()],
700
- action: 'change_coordinates'
701
- })
702
- }
703
- },
704
-
705
- // Undo support
706
- pushUndo(operation) {
707
- const undoStack = this.map._undoStack
708
- if (!undoStack) {
709
- return
710
- }
711
- undoStack.push(operation)
712
- },
713
-
714
- undoMoveVertex(state, op) {
715
- const { vertexIndex, previousPosition, featureId } = op
716
- const feature = this.getFeature(featureId)
717
- if (!feature) {
718
- return
719
- }
720
-
721
- const geojson = feature.toGeoJSON()
722
- getModifiableCoords(geojson)[vertexIndex] = previousPosition
723
- this._applyUndoAndSync(state, geojson, featureId)
724
-
725
- // Update touch vertex target position
726
- const vertex = state.vertecies[state.selectedVertexIndex]
727
- if (vertex) {
728
- this.updateTouchVertexTarget(state, scalePoint(this.map.project(vertex), state.scale))
729
- }
730
- },
731
-
732
- undoInsertVertex(state, op) {
733
- const { vertexIndex, featureId } = op
734
- const feature = this.getFeature(featureId)
735
- if (!feature) {
736
- return
737
- }
738
-
739
- const geojson = feature.toGeoJSON()
740
- getModifiableCoords(geojson).splice(vertexIndex, 1)
741
- this._applyUndoAndSync(state, geojson, featureId)
742
-
743
- this.hideTouchVertexIndicator(state)
744
- this.changeMode(state, { selectedVertexIndex: -1, selectedVertexType: null })
745
- },
746
-
747
- undoDeleteVertex(state, op) {
748
- const { vertexIndex, position, featureId } = op
749
- const feature = this.getFeature(featureId)
750
- if (!feature) {
751
- return
752
- }
753
-
754
- const geojson = feature.toGeoJSON()
755
- getModifiableCoords(geojson).splice(vertexIndex, 0, position)
756
- this._applyUndoAndSync(state, geojson, featureId)
757
-
758
- // Update touch vertex target to restored vertex position
759
- const vertex = state.vertecies[vertexIndex]
760
- if (vertex) {
761
- this.updateTouchVertexTarget(state, scalePoint(this.map.project(vertex), state.scale))
762
- }
763
- this.changeMode(state, { selectedVertexIndex: vertexIndex, selectedVertexType: 'vertex', coordPath: this.getCoordPath(state, vertexIndex) })
764
- },
765
-
766
- _applyUndoAndSync(state, geojson, featureId) {
767
- this._ctx.api.add(geojson)
768
- state.vertecies = this.getVerticies(featureId)
769
- state.midpoints = this.getMidpoints(featureId)
770
- this._ctx.store.render()
771
- this.fireGeometryChange(state)
772
- },
773
-
774
419
  onStop(state) {
775
420
  const h = this.handlers
776
421
  state.container.removeEventListener('pointerdown', h.pointerdown)
@@ -0,0 +1,49 @@
1
+ const STYLE_PROPS = ['stroke', 'fill', 'strokeWidth']
2
+
3
+ /**
4
+ * Flatten style properties that may be strings or variant objects
5
+ * keyed by style ID into flat GeoJSON-compatible properties.
6
+ *
7
+ * @param {object} props - Object containing style properties
8
+ * @returns {object} Flattened properties
9
+ *
10
+ * @example
11
+ * flattenStyleProperties({
12
+ * stroke: { outdoor: '#e6c700', dark: '#ffd700' },
13
+ * fill: 'rgba(255, 221, 0, 0.1)',
14
+ * strokeWidth: 3
15
+ * })
16
+ * // Returns:
17
+ * // {
18
+ * // stroke: '#e6c700',
19
+ * // strokeOutdoor: '#e6c700',
20
+ * // strokeDark: '#ffd700',
21
+ * // fill: 'rgba(255, 221, 0, 0.1)',
22
+ * // strokeWidth: 3
23
+ * // }
24
+ */
25
+ export const flattenStyleProperties = (props) => {
26
+ if (!props) {
27
+ return {}
28
+ }
29
+
30
+ const result = {}
31
+
32
+ for (const [key, value] of Object.entries(props)) {
33
+ if (STYLE_PROPS.includes(key) && typeof value === 'object' && value !== null) {
34
+ const entries = Object.entries(value)
35
+ // First value as base fallback
36
+ if (entries.length > 0) {
37
+ result[key] = entries[0][1]
38
+ }
39
+ // Variant properties: e.g. strokeDark, fillOutdoor
40
+ for (const [styleId, styleValue] of entries) {
41
+ result[`${key}${styleId.charAt(0).toUpperCase() + styleId.slice(1)}`] = styleValue
42
+ }
43
+ } else {
44
+ result[key] = value
45
+ }
46
+ }
47
+
48
+ return result
49
+ }
@@ -1 +1 @@
1
- export const __webpack_esm_id__="im-frame-plugin";export const __webpack_esm_ids__=["im-frame-plugin"];export const __webpack_esm_modules__={"./plugins/beta/frame/src/manifest.js"(e,t,r){function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach(function(t){u(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function u(e,t,r){return(t=function(e){var t=function(e){if("object"!=n(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=n(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==n(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}r.d(t,{manifest:()=>k}),r.r(t);var a={SET_FRAME:function(e,t){return i(i({},e),{},{frame:t})},SET_FRAME_REFS:function(e,t){return i(i({},e),{},{frameRefs:t})}},c=r("react");function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,u,a=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(a.push(n.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return f(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?f(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function p(e){var t;if(null==e||null===(t=e.geometry)||void 0===t||null===(t=t.coordinates)||void 0===t||!t[0])return null;var r=e.geometry.coordinates[0],n=1/0,o=1/0,i=-1/0,u=-1/0;return r.forEach(function(e){var t=l(e,2),r=t[0],a=t[1];r<n&&(n=r),r>i&&(i=r),a<o&&(o=a),a>u&&(u=a)}),[n,o,i,u]}var s=r("react/jsx-runtime");function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}function b(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function m(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?b(Object(r),!0).forEach(function(t){d(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):b(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function d(e,t,r){return(t=function(e){var t=function(e){if("object"!=y(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=y(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==y(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function v(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,u,a=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(a.push(n.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return g(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?g(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var O={aspectRatio:1,mobileWidth:"300px",tabletWidth:"360px",desktopWidth:"400px"};function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function j(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function S(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?j(Object(r),!0).forEach(function(t){w(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):j(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function w(e,t,r){return(t=function(e){var t=function(e){if("object"!=h(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=h(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==h(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function P(e){return P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},P(e)}function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function R(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?E(Object(r),!0).forEach(function(t){x(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):E(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function x(e,t,r){return(t=function(e){var t=function(e){if("object"!=P(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=P(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==P(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _(e){return _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_(e)}function T(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function D(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?T(Object(r),!0).forEach(function(t){M(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):T(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function M(e,t,r){return(t=function(e){var t=function(e){if("object"!=_(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=_(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==_(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var A={mobile:{slot:"actions",showLabel:!0},tablet:{slot:"actions",showLabel:!0},desktop:{slot:"actions",showLabel:!0}},k={reducer:{initialState:{frame:null,frameRefs:null},actions:a},InitComponent:function(e){var t,r,n,o,i=e.appState,u=e.mapState,a=e.mapProvider,l=e.pluginConfig,f=e.pluginState,p=e.services,s=e.buttonConfig,y=i.mode,b=i.breakpoint,m=i.layoutRefs,d=p.eventBus,v=s.frameDone,g=s.frameCancel,O=f.dispatch,h=f.frameRefs,j=f.frame,S=null===(t=null===(r=l.includeModes)||void 0===r?void 0:r.includes(y))||void 0===t||t,w=null!==(n=null===(o=l.excludeModes)||void 0===o?void 0:o.includes(y))&&void 0!==n&&n,P=u.isMapReady&&S&&!w;(0,c.useEffect)(function(){if(P)return v.onClick=function(){var e=function(e){var t=e.viewportEl,r=e.mapProvider,n=e.featureId,o=e.scale,i=e.frameEl.getBoundingClientRect(),u=t.getBoundingClientRect(),a={x:(i.left-u.left)/o,y:(i.top-u.top)/o},c={x:(i.right-u.left)/o,y:(i.top-u.top)/o},l={x:(i.right-u.left)/o,y:(i.bottom-u.top)/o},f={x:(i.left-u.left)/o,y:(i.bottom-u.top)/o},p={type:"Feature",geometry:{type:"Polygon",coordinates:[[r.screenToMap(a),r.screenToMap(c),r.screenToMap(l),r.screenToMap(f),r.screenToMap(a)]]},properties:{}};return n&&(p.id=n),p}({frameEl:h.displayRef.current,viewportEl:m.viewportRef.current,featureId:null==j?void 0:j.featureId,scale:{small:1,medium:1.5,large:2}[u.mapSize],mapProvider:a});O({type:"SET_FRAME",payload:null}),d.emit("frame:done",e)},g.onClick=function(){O({type:"SET_FRAME",payload:null}),d.emit("frame:cancel")},function(){v.onClick=null,g.onClick=null}},[u.isMapReady,y,b,j,h,m,a,O,d,v,g])},controls:[{id:"frame",label:"Frame",mobile:{slot:"middle"},tablet:{slot:"middle"},desktop:{slot:"middle"},render:function(e){var t,r=e.appState,n=e.mapState,o=e.pluginState,i=e.mapProvider,u=r.layoutRefs,a=u.actionsRef,l=u.mainRef,f=u.footerRef,p=u.viewportRef,y=o.dispatch,b=(0,c.useRef)(null),d=(0,c.useRef)(null),g=(0,c.useRef)(null),O=v((0,c.useState)("65px"),2),h=O[0],j=O[1],S=v((0,c.useState)(null),2),w=S[0],P=S[1];return(0,c.useEffect)(function(){y({type:"SET_FRAME_REFS",payload:{displayRef:d}})},[]),(0,c.useEffect)(function(){if(o.frame&&b.current){var e=b.current,t=function(){if(a.current&&l.current&&f.current){var t=l.current.offsetHeight,n=f.current.offsetTop,i=a.current.offsetTop,u=t-Math.min(i,n)+10;j("65px 65px ".concat(u,"px 65px"));var c=e.offsetWidth,p=e.offsetHeight;if(t-u-e.offsetTop===e.offsetHeight){var s=function(e,t,r,n){var o=Number.parseInt(r["".concat(n,"Width")]||e,10),i=Math.min(o,e),u=i/r.aspectRatio;return u>t&&(i=(u=t)*r.aspectRatio),{top:(t-u)/2,left:(e-i)/2,width:i,height:u}}(c,p,o.frame,r.breakpoint),y=s.top,b=s.left,m=s.width,d=s.height,v=y+e.offsetTop,g=b+e.offsetLeft;P({top:"".concat(v,"px"),left:"".concat(g,"px"),width:"".concat(m,"px"),height:"".concat(d,"px")})}}},n=new ResizeObserver(t);return n.observe(e),t(),function(){return n.disconnect()}}g.current=null},[o.frame,r.breakpoint,a,l,f]),(0,c.useEffect)(function(){var e;if(null!==(e=o.frame)&&void 0!==e&&e.bounds&&d.current&&p.current&&w){var t=d.current,r=p.current,u=t.getBoundingClientRect(),a=r.getBoundingClientRect(),c={small:1,medium:1.5,large:2}[n.mapSize],l={top:(u.top-a.top)/c,right:(a.right-u.right)/c,bottom:(a.bottom-u.bottom)/c,left:(u.left-a.left)/c};i.setPadding(l),i.fitToBounds(o.frame.bounds,!0)}},[null===(t=o.frame)||void 0===t?void 0:t.bounds,w,i,d,p]),o.frame?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"im-c-frame-spacer",style:{inset:h},ref:b}),w&&(0,s.jsx)("div",{ref:d,className:"im-c-frame-display",style:m({},w)})]}):null}}],buttons:[D({id:"frameDone",label:"Done",variant:"primary",hiddenWhen:function(e){return!e.pluginState.frame}},A),D({id:"frameCancel",label:"Cancel",variant:"tertiary",hiddenWhen:function(e){return!e.pluginState.frame}},A)],api:{addFrame:function(e,t){var r=e.pluginConfig,n=e.pluginState,o=e.services,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},u=n.dispatch,a=o.eventBus;u({type:"SET_FRAME",payload:S(S(S(S({},O),r),i),{},{featureId:t})}),a.emit("frame:add")},editFeature:function(e,t){var r=e.pluginConfig,n=e.pluginState,o=e.mapProvider,i=e.services,u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=n.dispatch,c=i.eventBus,f=p(t),s=function(e,t){var r=p(e);if(!r)return null;var n=l(r,4),o=n[0],i=n[1],u=n[2],a=n[3],c=t.mapToScreen([o,a]),f=t.mapToScreen([u,i]),s=Math.abs(f.x-c.x),y=Math.abs(f.y-c.y);return 0===y?null:Math.round(s/y*1e6)/1e6}(t,o),y=R(R(R(R({},O),r),u),{},{aspectRatio:s,featureId:(null==t?void 0:t.id)||t.properties.id});a({type:"SET_FRAME",payload:R(R({},y),{},{bounds:f})}),c.emit("frame:edit")}}}}};
1
+ export const __webpack_esm_id__="im-frame-plugin";export const __webpack_esm_ids__=["im-frame-plugin"];export const __webpack_esm_modules__={"./plugins/beta/frame/src/manifest.js"(e,t,r){function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach(function(t){u(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function u(e,t,r){return(t=function(e){var t=function(e){if("object"!=n(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=n(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==n(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}r.d(t,{manifest:()=>k}),r.r(t);var a={SET_FRAME:function(e,t){return i(i({},e),{},{frame:t})},SET_FRAME_REFS:function(e,t){return i(i({},e),{},{frameRefs:t})}},c=r("react");function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,u,a=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(a.push(n.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return f(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?f(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function p(e){var t;if(null==e||null===(t=e.geometry)||void 0===t||null===(t=t.coordinates)||void 0===t||!t[0])return null;var r=e.geometry.coordinates[0],n=1/0,o=1/0,i=-1/0,u=-1/0;return r.forEach(function(e){var t=l(e,2),r=t[0],a=t[1];r<n&&(n=r),r>i&&(i=r),a<o&&(o=a),a>u&&(u=a)}),[n,o,i,u]}var s=r("react/jsx-runtime");function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}function b(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function m(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?b(Object(r),!0).forEach(function(t){d(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):b(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function d(e,t,r){return(t=function(e){var t=function(e){if("object"!=y(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=y(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==y(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function v(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,u,a=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(a.push(n.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return g(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?g(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var O={aspectRatio:1,mobileWidth:"300px",tabletWidth:"360px",desktopWidth:"400px"};function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function j(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function S(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?j(Object(r),!0).forEach(function(t){w(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):j(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function w(e,t,r){return(t=function(e){var t=function(e){if("object"!=h(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=h(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==h(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function P(e){return P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},P(e)}function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function R(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?E(Object(r),!0).forEach(function(t){x(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):E(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function x(e,t,r){return(t=function(e){var t=function(e){if("object"!=P(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=P(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==P(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _(e){return _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_(e)}function T(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function D(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?T(Object(r),!0).forEach(function(t){M(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):T(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function M(e,t,r){return(t=function(e){var t=function(e){if("object"!=_(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=_(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==_(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var A={mobile:{slot:"actions",showLabel:!0},tablet:{slot:"actions",showLabel:!0},desktop:{slot:"actions",showLabel:!0}},k={reducer:{initialState:{frame:null,frameRefs:null},actions:a},InitComponent:function(e){var t,r,n,o,i=e.appState,u=e.mapState,a=e.mapProvider,l=e.pluginConfig,f=e.pluginState,p=e.services,s=e.buttonConfig,y=i.mode,b=i.breakpoint,m=i.layoutRefs,d=p.eventBus,v=s.frameDone,g=s.frameCancel,O=f.dispatch,h=f.frameRefs,j=f.frame,S=null===(t=null===(r=l.includeModes)||void 0===r?void 0:r.includes(y))||void 0===t||t,w=null!==(n=null===(o=l.excludeModes)||void 0===o?void 0:o.includes(y))&&void 0!==n&&n,P=u.isMapReady&&S&&!w;(0,c.useEffect)(function(){if(P)return v.onClick=function(){var e=function(e){var t=e.viewportEl,r=e.mapProvider,n=e.featureId,o=e.scale,i=e.frameEl.getBoundingClientRect(),u=t.getBoundingClientRect(),a={x:(i.left-u.left)/o,y:(i.top-u.top)/o},c={x:(i.right-u.left)/o,y:(i.top-u.top)/o},l={x:(i.right-u.left)/o,y:(i.bottom-u.top)/o},f={x:(i.left-u.left)/o,y:(i.bottom-u.top)/o},p={type:"Feature",geometry:{type:"Polygon",coordinates:[[r.screenToMap(a),r.screenToMap(c),r.screenToMap(l),r.screenToMap(f),r.screenToMap(a)]]},properties:{}};return n&&(p.id=n),p}({frameEl:h.displayRef.current,viewportEl:m.viewportRef.current,featureId:null==j?void 0:j.featureId,scale:{small:1,medium:1.5,large:2}[u.mapSize],mapProvider:a});O({type:"SET_FRAME",payload:null}),d.emit("frame:done",e)},g.onClick=function(){O({type:"SET_FRAME",payload:null}),d.emit("frame:cancel")},function(){v.onClick=null,g.onClick=null}},[u.isMapReady,y,b,j,h,m,a,O,d,v,g])},controls:[{id:"frame",label:"Frame",mobile:{slot:"middle"},tablet:{slot:"middle"},desktop:{slot:"middle"},render:function(e){var t,r=e.appState,n=e.mapState,o=e.pluginState,i=e.mapProvider,u=r.layoutRefs,a=u.actionsRef,l=u.mainRef,f=u.footerRef,p=u.viewportRef,y=o.dispatch,b=(0,c.useRef)(null),d=(0,c.useRef)(null),g=(0,c.useRef)(null),O=v((0,c.useState)("65px"),2),h=O[0],j=O[1],S=v((0,c.useState)(null),2),w=S[0],P=S[1];return(0,c.useEffect)(function(){y({type:"SET_FRAME_REFS",payload:{displayRef:d}})},[]),(0,c.useEffect)(function(){if(o.frame&&b.current){var e=b.current,t=function(){if(a.current&&l.current&&f.current){var t=l.current.offsetHeight,n=f.current.offsetTop,i=a.current.offsetTop,u=t-Math.min(i,n)+10;j("65px 65px ".concat(u,"px 65px"));var c=e.offsetWidth,p=e.offsetHeight;if(t-u-e.offsetTop===e.offsetHeight){var s=function(e,t,r,n){var o=Number.parseInt(r["".concat(n,"Width")]||e,10),i=Math.min(o,e),u=i/r.aspectRatio;return u>t&&(i=(u=t)*r.aspectRatio),{top:(t-u)/2,left:(e-i)/2,width:i,height:u}}(c,p,o.frame,r.breakpoint),y=s.top,b=s.left,m=s.width,d=s.height,v=y+e.offsetTop,g=b+e.offsetLeft;P({top:"".concat(v,"px"),left:"".concat(g,"px"),width:"".concat(m,"px"),height:"".concat(d,"px")})}}},n=new window.ResizeObserver(t);return n.observe(e),t(),function(){return n.disconnect()}}g.current=null},[o.frame,r.breakpoint,a,l,f]),(0,c.useEffect)(function(){var e;if(null!==(e=o.frame)&&void 0!==e&&e.bounds&&d.current&&p.current&&w){var t=d.current,r=p.current,u=t.getBoundingClientRect(),a=r.getBoundingClientRect(),c={small:1,medium:1.5,large:2}[n.mapSize],l={top:(u.top-a.top)/c,right:(a.right-u.right)/c,bottom:(a.bottom-u.bottom)/c,left:(u.left-a.left)/c};i.setPadding(l),i.fitToBounds(o.frame.bounds,!0)}},[null===(t=o.frame)||void 0===t?void 0:t.bounds,w,i,d,p]),o.frame?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"im-c-frame-spacer",style:{inset:h},ref:b}),w&&(0,s.jsx)("div",{ref:d,className:"im-c-frame-display",style:m({},w)})]}):null}}],buttons:[D({id:"frameDone",label:"Done",variant:"primary",hiddenWhen:function(e){return!e.pluginState.frame}},A),D({id:"frameCancel",label:"Cancel",variant:"tertiary",hiddenWhen:function(e){return!e.pluginState.frame}},A)],api:{addFrame:function(e,t){var r=e.pluginConfig,n=e.pluginState,o=e.services,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},u=n.dispatch,a=o.eventBus;u({type:"SET_FRAME",payload:S(S(S(S({},O),r),i),{},{featureId:t})}),a.emit("frame:add")},editFeature:function(e,t){var r=e.pluginConfig,n=e.pluginState,o=e.mapProvider,i=e.services,u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=n.dispatch,c=i.eventBus,f=p(t),s=function(e,t){var r=p(e);if(!r)return null;var n=l(r,4),o=n[0],i=n[1],u=n[2],a=n[3],c=t.mapToScreen([o,a]),f=t.mapToScreen([u,i]),s=Math.abs(f.x-c.x),y=Math.abs(f.y-c.y);return 0===y?null:Math.round(s/y*1e6)/1e6}(t,o),y=R(R(R(R({},O),r),u),{},{aspectRatio:s,featureId:(null==t?void 0:t.id)||t.properties.id});a({type:"SET_FRAME",payload:R(R({},y),{},{bounds:f})}),c.emit("frame:edit")}}}}};