{"version":3,"file":"terra-draw.cjs","sources":["../src/geometry/limit-decimal-precision.ts","../src/geometry/measure/pixel-distance.ts","../src/adapters/common/adapter-listener.ts","../src/adapters/common/base.adapter.ts","../src/adapters/google-maps.adapter.ts","../src/adapters/leaflet.adapter.ts","../src/adapters/mapbox-gl.adapter.ts","../src/adapters/maplibre-gl.adapter.ts","../node_modules/ol/proj/Units.js","../node_modules/ol/proj/Projection.js","../node_modules/ol/proj/epsg3857.js","../node_modules/ol/proj/epsg4326.js","../node_modules/ol/proj/projections.js","../node_modules/ol/proj/transforms.js","../node_modules/ol/proj.js","../src/adapters/openlayers.adapter.ts","../src/common.ts","../node_modules/ol/math.js","../src/adapters/arcgis-maps-sdk.adapter.ts","../src/modes/base.mode.ts","../src/store/store-feature-validation.ts","../src/geometry/measure/haversine-distance.ts","../src/geometry/helpers.ts","../src/geometry/project/web-mercator.ts","../src/geometry/shape/create-circle.ts","../src/geometry/boolean/self-intersects.ts","../src/geometry/boolean/is-valid-coordinate.ts","../src/validations/polygon.validation.ts","../src/modes/circle/circle.mode.ts","../src/util/styling.ts","../src/geometry/shape/web-mercator-distortion.ts","../src/modes/freehand/freehand.mode.ts","../src/modes/base.behavior.ts","../src/geometry/shape/create-bbox.ts","../src/modes/click-bounding-box.behavior.ts","../src/modes/pixel-distance.behavior.ts","../src/modes/snapping.behavior.ts","../src/geometry/measure/destination.ts","../src/geometry/measure/bearing.ts","../src/geometry/measure/slice-along.ts","../src/geometry/shape/great-circle-coordinates.ts","../src/modes/insert-coordinates.behavior.ts","../src/geometry/coordinates-identical.ts","../src/modes/linestring/linestring.mode.ts","../src/validations/point.validation.ts","../src/modes/point/point.mode.ts","../src/modes/polygon/behaviors/closing-points.behavior.ts","../src/modes/polygon/polygon.mode.ts","../src/util/geoms.ts","../src/modes/rectangle/rectangle.mode.ts","../src/modes/render/render.mode.ts","../src/validations/linestring.validation.ts","../src/geometry/measure/rhumb-bearing.ts","../src/geometry/measure/rhumb-destination.ts","../src/geometry/midpoint-coordinate.ts","../src/geometry/get-midpoints.ts","../src/modes/select/behaviors/midpoint.behavior.ts","../src/modes/select/behaviors/selection-point.behavior.ts","../src/geometry/get-coordinates-as-points.ts","../src/geometry/boolean/point-in-polygon.ts","../src/geometry/measure/pixel-distance-to-line.ts","../src/modes/select/behaviors/feature-at-pointer-event.behavior.ts","../src/modes/select/behaviors/drag-feature.behavior.ts","../src/modes/select/behaviors/drag-coordinate.behavior.ts","../src/geometry/centroid.ts","../src/geometry/measure/rhumb-distance.ts","../src/geometry/web-mercator-centroid.ts","../src/modes/select/behaviors/rotate-feature.behavior.ts","../src/geometry/transform/rotate.ts","../src/modes/select/behaviors/scale-feature.behavior.ts","../src/geometry/transform/scale.ts","../src/modes/select/behaviors/drag-coordinate-resize.behavior.ts","../src/modes/select/select.mode.ts","../src/modes/static/static.mode.ts","../src/store/spatial-index/quickselect.ts","../src/store/spatial-index/rbush.ts","../src/store/spatial-index/spatial-index.ts","../src/store/store.ts","../src/util/id.ts","../src/geometry/measure/area.ts","../src/geometry/calculate-relative-angle.ts","../src/modes/angled-rectangle/angled-rectangle.mode.ts","../src/geometry/determine-halfplane.ts","../src/geometry/clockwise.ts","../src/modes/sector/sector.mode.ts","../src/modes/sensor/sensor.mode.ts","../src/terra-draw.ts","../src/validations/max-size.validation.ts","../src/validations/min-size.validation.ts","../src/validations/not-self-intersecting.validation.ts"],"sourcesContent":["export function limitPrecision(num: number, decimalLimit = 9) {\n\tconst decimals = Math.pow(10, decimalLimit);\n\treturn Math.round(num * decimals) / decimals;\n}\n","export const cartesianDistance = (\n\tpointOne: { x: number; y: number },\n\tpointTwo: { x: number; y: number },\n) => {\n\tconst { x: x1, y: y1 } = pointOne;\n\tconst { x: x2, y: y2 } = pointTwo;\n\tconst y = x2 - x1;\n\tconst x = y2 - y1;\n\treturn Math.sqrt(x * x + y * y);\n};\n","export class AdapterListener<Callback extends (...args: any[]) => any> {\n\tpublic name: string;\n\tpublic callback: (...args: any[]) => any;\n\tpublic registered = false;\n\tpublic register: any;\n\tpublic unregister: any;\n\n\t/**\n\t * Creates a new AdapterListener instance with the provided configuration.\n\t *\n\t * @param {Object} config - The configuration object for the listener.\n\t * @param {string} config.name - The name of the event listener.\n\t * @param {Function} config.callback - The callback function to be called when the event is triggered.\n\t * @param {Function} config.unregister - The function to unregister the event listeners.\n\t * @param {Function} config.register - The function to register the event listeners.\n\t */\n\tconstructor({\n\t\tname,\n\t\tcallback,\n\t\tunregister,\n\t\tregister,\n\t}: {\n\t\tname: string;\n\t\tcallback: Callback;\n\t\tunregister: (callbacks: Callback) => void;\n\t\tregister: (callback: Callback) => void;\n\t}) {\n\t\tthis.name = name;\n\n\t\t// Function to register the event listeners\n\t\tthis.register = () => {\n\t\t\tif (!this.registered) {\n\t\t\t\tthis.registered = true;\n\t\t\t\tregister(callback);\n\t\t\t}\n\t\t};\n\n\t\t// Function to unregister the event listeners\n\t\tthis.unregister = () => {\n\t\t\tif (this.register) {\n\t\t\t\tthis.registered = false;\n\t\t\t\tunregister(callback);\n\t\t\t}\n\t\t};\n\n\t\tthis.callback = callback;\n\t}\n}\n","import {\n\tProject,\n\tUnproject,\n\tTerraDrawCallbacks,\n\tTerraDrawChanges,\n\tTerraDrawMouseEvent,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tGetLngLatFromEvent,\n\tTerraDrawAdapter,\n} from \"../../common\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { AdapterListener } from \"./adapter-listener\";\n\ntype BasePointerListener = (event: PointerEvent) => void;\ntype BaseKeyboardListener = (event: KeyboardEvent) => void;\ntype BaseMouseListener = (event: MouseEvent) => void;\n\nexport type BaseAdapterConfig = {\n\tcoordinatePrecision?: number;\n\tminPixelDragDistanceDrawing?: number;\n\tminPixelDragDistance?: number;\n\tminPixelDragDistanceSelecting?: number;\n};\n\nexport abstract class TerraDrawBaseAdapter implements TerraDrawAdapter {\n\tconstructor(config: BaseAdapterConfig) {\n\t\tthis._minPixelDragDistance =\n\t\t\ttypeof config.minPixelDragDistance === \"number\"\n\t\t\t\t? config.minPixelDragDistance\n\t\t\t\t: 1;\n\n\t\tthis._minPixelDragDistanceSelecting =\n\t\t\ttypeof config.minPixelDragDistanceSelecting === \"number\"\n\t\t\t\t? config.minPixelDragDistanceSelecting\n\t\t\t\t: 1;\n\n\t\tthis._minPixelDragDistanceDrawing =\n\t\t\ttypeof config.minPixelDragDistanceDrawing === \"number\"\n\t\t\t\t? config.minPixelDragDistanceDrawing\n\t\t\t\t: 8;\n\n\t\tthis._coordinatePrecision =\n\t\t\ttypeof config.coordinatePrecision === \"number\"\n\t\t\t\t? config.coordinatePrecision\n\t\t\t\t: 9;\n\t}\n\n\tprotected _minPixelDragDistance: number;\n\tprotected _minPixelDragDistanceDrawing: number;\n\tprotected _minPixelDragDistanceSelecting: number;\n\tprotected _lastDrawEvent: TerraDrawMouseEvent | undefined;\n\tprotected _coordinatePrecision: number;\n\tprotected _heldKeys: Set<string> = new Set();\n\tprotected _listeners: AdapterListener<\n\t\tBasePointerListener | BaseKeyboardListener | BaseMouseListener\n\t>[] = [];\n\tprotected _dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n\t\t\"not-dragging\";\n\tprotected _currentModeCallbacks: TerraDrawCallbacks | undefined;\n\n\tpublic abstract getMapEventElement(): HTMLElement;\n\n\tprotected getButton(event: PointerEvent | MouseEvent) {\n\t\tif (event.button === -1) {\n\t\t\treturn \"neither\";\n\t\t} else if (event.button === 0) {\n\t\t\treturn \"left\";\n\t\t} else if (event.button === 1) {\n\t\t\treturn \"middle\";\n\t\t} else if (event.button === 2) {\n\t\t\treturn \"right\";\n\t\t}\n\n\t\t// This shouldn't happen (?)\n\t\treturn \"neither\";\n\t}\n\n\tprotected getMapElementXYPosition(event: PointerEvent | MouseEvent) {\n\t\tconst mapElement = this.getMapEventElement();\n\t\tconst { left, top } = mapElement.getBoundingClientRect();\n\n\t\treturn {\n\t\t\tcontainerX: event.clientX - left,\n\t\t\tcontainerY: event.clientY - top,\n\t\t};\n\t}\n\n\tprotected getDrawEventFromEvent(\n\t\tevent: PointerEvent | MouseEvent,\n\t): TerraDrawMouseEvent | null {\n\t\tconst latLng = this.getLngLatFromEvent(event);\n\n\t\tif (!latLng) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { lng, lat } = latLng;\n\t\tconst { containerX, containerY } = this.getMapElementXYPosition(event);\n\t\tconst button = this.getButton(event);\n\t\tconst heldKeys = Array.from(this._heldKeys);\n\n\t\treturn {\n\t\t\tlng: limitPrecision(lng, this._coordinatePrecision),\n\t\t\tlat: limitPrecision(lat, this._coordinatePrecision),\n\t\t\tcontainerX,\n\t\t\tcontainerY,\n\t\t\tbutton,\n\t\t\theldKeys,\n\t\t};\n\t}\n\n\t/**\n\t * Registers the provided callbacks for the current drawing mode and attaches\n\t * the necessary event listeners.\n\t * @param {TerraDrawCallbacks} callbacks - An object containing callback functions\n\t * for handling various drawing events in the current mode.\n\t */\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tthis._currentModeCallbacks = callbacks;\n\n\t\tthis._listeners = this.getAdapterListeners();\n\n\t\tthis._listeners.forEach((listener) => {\n\t\t\tlistener.register();\n\t\t});\n\t}\n\n\t/**\n\t * Gets the coordinate precision. The coordinate precision is the number of decimal places in geometry\n\t * coordinates stored in the store.\n\t * @returns {number} The coordinate precision.\n\t */\n\tpublic getCoordinatePrecision() {\n\t\treturn this._coordinatePrecision;\n\t}\n\n\tprivate getAdapterListeners() {\n\t\treturn [\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointerdown\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._dragState = \"pre-dragging\";\n\n\t\t\t\t\t// On pointer devices pointer mouse move events won't be\n\t\t\t\t\t// triggered so this._lastDrawEvent will not get set in\n\t\t\t\t\t// pointermove listener, so we must set it here.\n\t\t\t\t\tthis._lastDrawEvent = drawEvent;\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement().addEventListener(\"pointerdown\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement().removeEventListener(\n\t\t\t\t\t\t\"pointerdown\",\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointermove\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._dragState === \"not-dragging\") {\n\t\t\t\t\t\t// If we're not dragging we can trigger the onMouseMove event\n\t\t\t\t\t\tthis._currentModeCallbacks.onMouseMove(drawEvent);\n\t\t\t\t\t\tthis._lastDrawEvent = drawEvent;\n\t\t\t\t\t} else if (this._dragState === \"pre-dragging\") {\n\t\t\t\t\t\t// This should always be set because of pointerdown event\n\t\t\t\t\t\tif (!this._lastDrawEvent) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst lastEventXY = {\n\t\t\t\t\t\t\tx: this._lastDrawEvent.containerX,\n\t\t\t\t\t\t\ty: this._lastDrawEvent.containerY,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst currentEventXY = {\n\t\t\t\t\t\t\tx: drawEvent.containerX,\n\t\t\t\t\t\t\ty: drawEvent.containerY,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// We only want to prevent micro drags when we are\n\t\t\t\t\t\t// drawing as doing in on selection can cause janky\n\t\t\t\t\t\t// behaviours\n\t\t\t\t\t\tconst modeState = this._currentModeCallbacks.getState();\n\n\t\t\t\t\t\tconst pixelDistanceToCheck = cartesianDistance(\n\t\t\t\t\t\t\tlastEventXY,\n\t\t\t\t\t\t\tcurrentEventXY,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// We start off assuming it is not a microdrag\n\t\t\t\t\t\tlet isMicroDrag = false;\n\n\t\t\t\t\t\tif (modeState === \"drawing\") {\n\t\t\t\t\t\t\t// We want to ignore very small pointer movements when holding\n\t\t\t\t\t\t\t// the map down as these are normally done by accident when\n\t\t\t\t\t\t\t// drawing and is not an intended drag\n\t\t\t\t\t\t\tisMicroDrag =\n\t\t\t\t\t\t\t\tpixelDistanceToCheck < this._minPixelDragDistanceDrawing;\n\t\t\t\t\t\t} else if (modeState === \"selecting\") {\n\t\t\t\t\t\t\t// Simiarly when selecting, we want to ignore very small pointer\n\t\t\t\t\t\t\t// movements when holding the map down as these are normally done\n\t\t\t\t\t\t\t// by accident when drawing and is not an intended drag\n\t\t\t\t\t\t\tisMicroDrag =\n\t\t\t\t\t\t\t\tpixelDistanceToCheck < this._minPixelDragDistanceSelecting;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Same as above, but when not drawing we generally want a much lower tolerance\n\t\t\t\t\t\t\tisMicroDrag = pixelDistanceToCheck < this._minPixelDragDistance;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If it is a microdrag we do not register it by returning early\n\t\t\t\t\t\tif (isMicroDrag) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._dragState = \"dragging\";\n\t\t\t\t\t\tthis._currentModeCallbacks.onDragStart(\n\t\t\t\t\t\t\tdrawEvent,\n\t\t\t\t\t\t\t(enabled: boolean) => {\n\t\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (this._dragState === \"dragging\") {\n\t\t\t\t\t\tthis._currentModeCallbacks.onDrag(drawEvent, (enabled: boolean) => {\n\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.addEventListener(\"pointermove\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.removeEventListener(\"pointermove\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BaseMouseListener>({\n\t\t\t\tname: \"contextmenu\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\t// We do not want the context menu to open\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.addEventListener(\"contextmenu\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.removeEventListener(\"contextmenu\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointerup\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.target !== this.getMapEventElement()) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._dragState === \"dragging\") {\n\t\t\t\t\t\tthis._currentModeCallbacks.onDragEnd(drawEvent, (enabled) => {\n\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tthis._dragState === \"not-dragging\" ||\n\t\t\t\t\t\tthis._dragState === \"pre-dragging\"\n\t\t\t\t\t) {\n\t\t\t\t\t\t// If we're not dragging or about to drag we\n\t\t\t\t\t\t// can trigger the onClick event\n\t\t\t\t\t\tthis._currentModeCallbacks.onClick(drawEvent);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure we go back to the regular behaviour\n\t\t\t\t\t// not dragging and re-enable draggin on the actual map\n\t\t\t\t\tthis._dragState = \"not-dragging\";\n\t\t\t\t\tthis.setDraggability(true);\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.addEventListener(\"pointerup\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.removeEventListener(\"pointerup\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener({\n\t\t\t\tname: \"keyup\",\n\t\t\t\tcallback: (event: KeyboardEvent) => {\n\t\t\t\t\t// map has no keypress event, so we add one to the canvas itself\n\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\tthis._heldKeys.delete(event.key);\n\n\t\t\t\t\tthis._currentModeCallbacks.onKeyUp({\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\theldKeys: Array.from(this._heldKeys),\n\t\t\t\t\t\tpreventDefault: () => event.preventDefault(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.addEventListener(\"keyup\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.removeEventListener(\"keyup\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener({\n\t\t\t\tname: \"keydown\",\n\t\t\t\tcallback: (event: KeyboardEvent) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._heldKeys.add(event.key);\n\n\t\t\t\t\tthis._currentModeCallbacks.onKeyDown({\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\theldKeys: Array.from(this._heldKeys),\n\t\t\t\t\t\tpreventDefault: () => event.preventDefault(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.addEventListener(\"keydown\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\n\t\t\t\t\tmapElement.removeEventListener(\"keydown\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t}\n\n\t/**\n\t * Unregisters the event listeners for the current drawing mode.\n\t * This is typically called when switching between drawing modes or\n\t * stopping the drawing process.\n\t */\n\tpublic unregister() {\n\t\tthis._listeners.forEach((listener) => {\n\t\t\tlistener.unregister();\n\t\t});\n\t\tthis.clear();\n\t}\n\n\tpublic abstract clear(): void;\n\n\tpublic abstract project(...args: Parameters<Project>): ReturnType<Project>;\n\n\tpublic abstract unproject(\n\t\t...args: Parameters<Unproject>\n\t): ReturnType<Unproject>;\n\n\tpublic abstract setCursor(\n\t\t...args: Parameters<SetCursor>\n\t): ReturnType<SetCursor>;\n\n\tpublic abstract getLngLatFromEvent(\n\t\t...event: Parameters<GetLngLatFromEvent>\n\t): ReturnType<GetLngLatFromEvent>;\n\n\tpublic abstract setDraggability(enabled: boolean): void;\n\n\tpublic abstract setDoubleClickToZoom(enabled: boolean): void;\n\n\tpublic abstract render(\n\t\tchanges: TerraDrawChanges,\n\t\tstyling: TerraDrawStylingFunction,\n\t): void;\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { GeoJsonObject } from \"geojson\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\nimport { FeatureId } from \"../store/store\";\n\nexport class TerraDrawGoogleMapsAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tlib: typeof google.maps;\n\t\t\tmap: google.maps.Map;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\t\tthis._lib = config.lib;\n\t\tthis._map = config.map;\n\n\t\t// In order for the internals of the adapter to work we require an ID to\n\t\t// allow query selectors  to work\n\t\tif (!this._map.getDiv().id) {\n\t\t\tthrow new Error(\"Google Map container div requires and id to be set\");\n\t\t}\n\n\t\tthis._coordinatePrecision =\n\t\t\ttypeof config.coordinatePrecision === \"number\"\n\t\t\t\t? config.coordinatePrecision\n\t\t\t\t: 9;\n\t}\n\n\tprivate _cursor: string | undefined;\n\tprivate _cursorStyleSheet: HTMLStyleElement | undefined;\n\tprivate _lib: typeof google.maps;\n\tprivate _map: google.maps.Map;\n\tprivate _overlay: google.maps.OverlayView | undefined;\n\tprivate _clickEventListener: google.maps.MapsEventListener | undefined;\n\tprivate _mouseMoveEventListener: google.maps.MapsEventListener | undefined;\n\n\tprivate get _layers(): boolean {\n\t\treturn Boolean(this.renderedFeatureIds?.size > 0);\n\t}\n\n\t/**\n\t * Generates an SVG path string for a circle with the given center coordinates and radius.\n\t * Based off this StackOverflow answer: https://stackoverflow.com/a/27905268/1363484\n\t * @param cx The x-coordinate of the circle's center.\n\t * @param cy The y-coordinate of the circle's center.\n\t * @param r The radius of the circle.\n\t * @returns The SVG path string representing the circle.\n\t */\n\tprivate circlePath(cx: number, cy: number, r: number) {\n\t\tconst d = r * 2;\n\t\treturn `M ${cx} ${cy} m -${r}, 0 a ${r},${r} 0 1,0 ${d},0 a ${r},${r} 0 1,0 -${d},0`;\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\t// The overlay is responsible for allow us to\n\t\t// get the projection, which in turn allows us to\n\t\t// go through lng/lat to pixel space and vice versa\n\t\tthis._overlay = new this._lib.OverlayView();\n\t\tthis._overlay.draw = function () {};\n\n\t\t// Unforunately it is only ready after the onAdd\n\t\t// method is called, which is why we need to use the 'ready'\n\t\t// listener with the Google Maps adapter\n\t\tthis._overlay.onAdd = () => {\n\t\t\tthis._currentModeCallbacks &&\n\t\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\t\tthis._currentModeCallbacks.onReady();\n\t\t};\n\t\tthis._overlay.setMap(this._map);\n\n\t\t// Clicking on data geometries triggers\n\t\t// swallows the map onclick event,\n\t\t// so we need to forward it to the click callback handler\n\t\tthis._clickEventListener = this._map.data.addListener(\n\t\t\t\"click\",\n\t\t\t(\n\t\t\t\tevent: google.maps.MapMouseEvent & {\n\t\t\t\t\tdomEvent: MouseEvent;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst clickListener = this._listeners.find(\n\t\t\t\t\t({ name }) => name === \"click\",\n\t\t\t\t);\n\t\t\t\tif (clickListener) {\n\t\t\t\t\tclickListener.callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tthis._mouseMoveEventListener = this._map.data.addListener(\n\t\t\t\"mousemove\",\n\t\t\t(\n\t\t\t\tevent: google.maps.MapMouseEvent & {\n\t\t\t\t\tdomEvent: MouseEvent;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst mouseMoveListener = this._listeners.find(\n\t\t\t\t\t({ name }) => name === \"mousemove\",\n\t\t\t\t);\n\t\t\t\tif (mouseMoveListener) {\n\t\t\t\t\tmouseMoveListener.callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic unregister(): void {\n\t\tsuper.unregister();\n\t\tthis._clickEventListener?.remove();\n\t\tthis._mouseMoveEventListener?.remove();\n\t\tthis._overlay?.setMap(null);\n\t\tthis._overlay = undefined;\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tgetLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst bounds = this._map.getBounds();\n\n\t\tif (!bounds) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst ne = bounds.getNorthEast();\n\t\tconst sw = bounds.getSouthWest();\n\t\tconst latLngBounds = new this._lib.LatLngBounds(sw, ne);\n\n\t\tconst mapCanvas = this._map.getDiv();\n\t\tconst offsetX = event.clientX - mapCanvas.getBoundingClientRect().left;\n\t\tconst offsetY = event.clientY - mapCanvas.getBoundingClientRect().top;\n\t\tconst screenCoord = new this._lib.Point(offsetX, offsetY);\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (!projection) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst latLng = projection.fromContainerPixelToLatLng(screenCoord);\n\n\t\tif (latLng && latLngBounds.contains(latLng)) {\n\t\t\treturn { lng: latLng.lng(), lat: latLng.lat() };\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the Google Map element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\t// TODO: This is a bit hacky, maybe there is a better solution here\n\t\tconst selector = 'div[style*=\"z-index: 3;\"]';\n\t\treturn this._map.getDiv().querySelector(selector) as HTMLDivElement;\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tproject(lng: number, lat: number) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst bounds = this._map.getBounds();\n\n\t\tif (bounds === undefined) {\n\t\t\tthrow new Error(\"cannot get bounds\");\n\t\t}\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (projection === undefined) {\n\t\t\tthrow new Error(\"cannot get projection\");\n\t\t}\n\n\t\tconst point = projection.fromLatLngToContainerPixel(\n\t\t\tnew this._lib.LatLng(lat, lng),\n\t\t);\n\n\t\tif (point === null) {\n\t\t\tthrow new Error(\"cannot project coordinates\");\n\t\t}\n\n\t\treturn { x: point.x, y: point.y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tunproject(x: number, y: number) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (projection === undefined) {\n\t\t\tthrow new Error(\"cannot get projection\");\n\t\t}\n\n\t\tconst latLng = projection.fromContainerPixelToLatLng(\n\t\t\tnew this._lib.Point(x, y),\n\t\t);\n\n\t\tif (latLng === null) {\n\t\t\tthrow new Error(\"cannot unproject coordinates\");\n\t\t}\n\n\t\treturn { lng: latLng.lng(), lat: latLng.lat() };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tsetCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === this._cursor) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._cursorStyleSheet) {\n\t\t\tthis._cursorStyleSheet.remove();\n\t\t\tthis._cursorStyleSheet = undefined;\n\t\t}\n\n\t\tif (cursor !== \"unset\") {\n\t\t\t// TODO: We could cache these individually per cursor\n\n\t\t\tconst div = this._map.getDiv();\n\t\t\tconst styleDivSelector = `#${div.id} .gm-style > div`;\n\t\t\tconst styleDiv = document.querySelector(styleDivSelector);\n\n\t\t\tif (styleDiv) {\n\t\t\t\tstyleDiv.classList.add(\"terra-draw-google-maps\");\n\n\t\t\t\tconst style = document.createElement(\"style\");\n\t\t\t\tstyle.innerHTML = `.terra-draw-google-maps { cursor: ${cursor} !important; }`;\n\t\t\t\tdocument.getElementsByTagName(\"head\")[0].appendChild(style);\n\t\t\t\tthis._cursorStyleSheet = style;\n\t\t\t}\n\t\t}\n\n\t\tthis._cursor = cursor;\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tsetDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.setOptions({ disableDoubleClickZoom: false });\n\t\t} else {\n\t\t\tthis._map.setOptions({ disableDoubleClickZoom: true });\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tsetDraggability(enabled: boolean) {\n\t\tthis._map.setOptions({ draggable: enabled });\n\t}\n\n\tprivate renderedFeatureIds: Set<FeatureId> = new Set();\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\trender(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tif (this._layers) {\n\t\t\tchanges.deletedIds.forEach((deletedId) => {\n\t\t\t\tconst featureToDelete = this._map.data.getFeatureById(deletedId);\n\t\t\t\tif (featureToDelete) {\n\t\t\t\t\tthis._map.data.remove(featureToDelete);\n\t\t\t\t\tthis.renderedFeatureIds.delete(deletedId);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchanges.updated.forEach((updatedFeature) => {\n\t\t\t\tif (!updatedFeature || !updatedFeature.id) {\n\t\t\t\t\tthrow new Error(\"Feature is not valid\");\n\t\t\t\t}\n\n\t\t\t\tconst featureToUpdate = this._map.data.getFeatureById(\n\t\t\t\t\tupdatedFeature.id,\n\t\t\t\t);\n\n\t\t\t\tif (!featureToUpdate) {\n\t\t\t\t\tthrow new Error(\"Feature could not be found by Google Maps API\");\n\t\t\t\t}\n\n\t\t\t\t// Remove all keys\n\t\t\t\tfeatureToUpdate.forEachProperty((property, name) => {\n\t\t\t\t\tfeatureToUpdate.setProperty(name, undefined);\n\t\t\t\t});\n\n\t\t\t\t// Update all keys\n\t\t\t\tObject.keys(updatedFeature.properties).forEach((property) => {\n\t\t\t\t\tfeatureToUpdate.setProperty(\n\t\t\t\t\t\tproperty,\n\t\t\t\t\t\tupdatedFeature.properties[property],\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tswitch (updatedFeature.geometry.type) {\n\t\t\t\t\tcase \"Point\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(\n\t\t\t\t\t\t\t\tnew this._lib.Data.Point(\n\t\t\t\t\t\t\t\t\tnew this._lib.LatLng(coordinates[1], coordinates[0]),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"LineString\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tconst path = [];\n\t\t\t\t\t\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\t\t\t\t\t\tconst coordinate = coordinates[i];\n\t\t\t\t\t\t\t\tconst latLng = new this._lib.LatLng(\n\t\t\t\t\t\t\t\t\tcoordinate[1],\n\t\t\t\t\t\t\t\t\tcoordinate[0],\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tpath.push(latLng);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(new this._lib.Data.LineString(path));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Polygon\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tconst paths = [];\n\t\t\t\t\t\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\t\t\t\t\t\tconst path = [];\n\t\t\t\t\t\t\t\tfor (let j = 0; j < coordinates[i].length; j++) {\n\t\t\t\t\t\t\t\t\tconst latLng = new this._lib.LatLng(\n\t\t\t\t\t\t\t\t\t\tcoordinates[i][j][1],\n\t\t\t\t\t\t\t\t\t\tcoordinates[i][j][0],\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tpath.push(latLng);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpaths.push(path);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(new this._lib.Data.Polygon(paths));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Create new features\n\t\t\tchanges.created.forEach((createdFeature) => {\n\t\t\t\tthis.renderedFeatureIds.add(createdFeature.id as string);\n\t\t\t\tthis._map.data.addGeoJson(createdFeature);\n\t\t\t});\n\t\t}\n\n\t\tchanges.created.forEach((feature) => {\n\t\t\tthis.renderedFeatureIds.add(feature.id as string);\n\t\t});\n\n\t\tconst featureCollection = {\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: [...changes.created],\n\t\t} as GeoJsonObject;\n\n\t\tthis._map.data.addGeoJson(featureCollection);\n\n\t\tthis._map.data.setStyle((feature) => {\n\t\t\tconst mode = feature.getProperty(\"mode\");\n\t\t\tconst gmGeometry = feature.getGeometry();\n\t\t\tif (!gmGeometry) {\n\t\t\t\tthrow new Error(\"Google Maps geometry not found\");\n\t\t\t}\n\t\t\tconst type = gmGeometry.getType();\n\t\t\tconst properties: Record<string, any> = {};\n\n\t\t\tfeature.forEachProperty((value, property) => {\n\t\t\t\tproperties[property] = value;\n\t\t\t});\n\n\t\t\tconst calculatedStyles = styling[mode]({\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: type as \"Point\" | \"LineString\" | \"Polygon\",\n\t\t\t\t\tcoordinates: [],\n\t\t\t\t},\n\t\t\t\tproperties,\n\t\t\t});\n\n\t\t\tswitch (type) {\n\t\t\t\tcase \"Point\":\n\t\t\t\t\tconst path = this.circlePath(0, 0, calculatedStyles.pointWidth);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tclickable: false,\n\t\t\t\t\t\ticon: {\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tfillColor: calculatedStyles.pointColor,\n\t\t\t\t\t\t\tfillOpacity: 1,\n\t\t\t\t\t\t\tstrokeColor: calculatedStyles.pointOutlineColor,\n\t\t\t\t\t\t\tstrokeWeight: calculatedStyles.pointOutlineWidth,\n\t\t\t\t\t\t\trotation: 0,\n\t\t\t\t\t\t\tscale: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\tcase \"LineString\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstrokeColor: calculatedStyles.lineStringColor,\n\t\t\t\t\t\tstrokeWeight: calculatedStyles.lineStringWidth,\n\t\t\t\t\t};\n\t\t\t\tcase \"Polygon\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstrokeColor: calculatedStyles.polygonOutlineColor,\n\t\t\t\t\t\tstrokeWeight: calculatedStyles.polygonOutlineWidth,\n\t\t\t\t\t\tfillOpacity: calculatedStyles.polygonFillOpacity,\n\t\t\t\t\t\tfillColor: calculatedStyles.polygonFillColor,\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\tthrow Error(\"Unknown feature type\");\n\t\t});\n\t}\n\n\tprivate clearLayers() {\n\t\tif (this._layers) {\n\t\t\tthis._map.data.forEach((feature) => {\n\t\t\t\tconst id = feature.getId() as string;\n\t\t\t\tconst hasFeature = this.renderedFeatureIds.has(id);\n\t\t\t\tif (hasFeature) {\n\t\t\t\t\tthis._map.data.remove(feature);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.renderedFeatureIds = new Set();\n\t\t}\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clean up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport L from \"leaflet\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawLeafletAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tlib: typeof L;\n\t\t\tmap: L.Map;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._lib = config.lib;\n\t\tthis._map = config.map;\n\t\tthis._container = this._map.getContainer();\n\t}\n\n\tprivate _lib: typeof L;\n\tprivate _map: L.Map;\n\tprivate _panes: Record<string, HTMLStyleElement | undefined> = {};\n\tprivate _container: HTMLElement;\n\tprivate _layers: Record<string, L.GeoJSON<any>> = {};\n\n\t/**\n\t * Creates a pane and its associated style sheet\n\t * @param pane - The pane name\n\t * @param zIndex - The zIndex value for the pane\n\t * @returns The created style element\n\t */\n\tprivate createPaneStyleSheet(pane: string, zIndex: number) {\n\t\tconst baseZIndex = 600;\n\t\tconst style = document.createElement(\"style\");\n\t\tconst paneZIndex = zIndex + baseZIndex;\n\t\tstyle.innerHTML = `.leaflet-${pane}-pane {z-index: ${paneZIndex}`;\n\t\tdocument.getElementsByTagName(\"head\")[0].appendChild(style);\n\t\tthis._map.createPane(pane);\n\t\treturn style;\n\t}\n\n\t/**\n\t * Clears the panes created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearPanes() {\n\t\tObject.values(this._panes).forEach((pane) => {\n\t\t\tif (pane) {\n\t\t\t\tpane.remove();\n\t\t\t}\n\t\t});\n\t\tthis._panes = {};\n\t}\n\n\t/**\n\t * Clears the leaflet layers created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tObject.values(this._layers).forEach((layer) => {\n\t\t\tthis._map.removeLayer(layer);\n\t\t});\n\t\tthis._layers = {};\n\t}\n\n\t/**\n\t * Styles a GeoJSON layer based on the styling function\n\t * @param styling - The styling function\n\t * */\n\tprivate styleGeoJSONLayer(\n\t\tstyling: TerraDrawStylingFunction,\n\t): L.GeoJSONOptions {\n\t\treturn {\n\t\t\t// Style points - convert markers to circle markers\n\t\t\tpointToLayer: (\n\t\t\t\tfeature: GeoJSONStoreFeatures,\n\t\t\t\tlatlng: L.LatLngExpression,\n\t\t\t) => {\n\t\t\t\tif (!feature.properties) {\n\t\t\t\t\tthrow new Error(\"Feature has no properties\");\n\t\t\t\t}\n\t\t\t\tif (typeof feature.properties.mode !== \"string\") {\n\t\t\t\t\tthrow new Error(\"Feature mode is not a string\");\n\t\t\t\t}\n\n\t\t\t\tconst mode = feature.properties.mode;\n\t\t\t\tconst modeStyle = styling[mode];\n\t\t\t\tconst featureStyles = modeStyle(feature);\n\t\t\t\tconst paneId = String(featureStyles.zIndex);\n\t\t\t\tconst pane = this._panes[paneId];\n\n\t\t\t\tif (!pane) {\n\t\t\t\t\tthis._panes[paneId] = this.createPaneStyleSheet(\n\t\t\t\t\t\tpaneId,\n\t\t\t\t\t\tfeatureStyles.zIndex,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst styles = {\n\t\t\t\t\tradius: featureStyles.pointWidth,\n\t\t\t\t\tstroke: featureStyles.pointOutlineWidth || false,\n\t\t\t\t\tcolor: featureStyles.pointOutlineColor,\n\t\t\t\t\tweight: featureStyles.pointOutlineWidth,\n\t\t\t\t\tfillOpacity: 0.8,\n\t\t\t\t\tfillColor: featureStyles.pointColor,\n\t\t\t\t\tpane: paneId,\n\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t} as L.CircleMarkerOptions;\n\n\t\t\t\tconst marker = this._lib.circleMarker(latlng, styles);\n\n\t\t\t\treturn marker;\n\t\t\t},\n\n\t\t\t// Style LineStrings and Polygons\n\t\t\tstyle: (_feature) => {\n\t\t\t\tif (!_feature || !_feature.properties) {\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\n\t\t\t\tconst feature = _feature as GeoJSONStoreFeatures;\n\n\t\t\t\tconst mode = feature.properties.mode as string;\n\t\t\t\tconst modeStyle = styling[mode];\n\t\t\t\tconst featureStyles = modeStyle(feature);\n\t\t\t\tconst paneId = String(featureStyles.zIndex);\n\t\t\t\tconst pane = this._panes[paneId];\n\n\t\t\t\tif (!pane) {\n\t\t\t\t\tthis._panes[paneId] = this.createPaneStyleSheet(\n\t\t\t\t\t\tpaneId,\n\t\t\t\t\t\tfeatureStyles.zIndex,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (feature.geometry.type === \"LineString\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t\t\tcolor: featureStyles.lineStringColor,\n\t\t\t\t\t\tweight: featureStyles.lineStringWidth,\n\t\t\t\t\t\tpane: paneId,\n\t\t\t\t\t};\n\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t\t\tfillOpacity: featureStyles.polygonFillOpacity,\n\t\t\t\t\t\tfillColor: featureStyles.polygonFillColor,\n\t\t\t\t\t\tweight: featureStyles.polygonOutlineWidth,\n\t\t\t\t\t\tstroke: true,\n\t\t\t\t\t\tcolor: featureStyles.polygonFillColor,\n\t\t\t\t\t\tpane: paneId,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn {};\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\n\t\t// x and y are guaranteed to be numeric as they come from getBoundingClientRect\n\t\tconst point = { x, y } as L.Point;\n\n\t\tconst latLng = this._map.containerPointToLatLng(point);\n\t\tif (\n\t\t\tlatLng.lng === null ||\n\t\t\tisNaN(latLng.lng) ||\n\t\t\tlatLng.lat === null ||\n\t\t\tisNaN(latLng.lat)\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn { lng: latLng.lng, lat: latLng.lat };\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the Leaflet element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._container;\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.dragging.enable();\n\t\t} else {\n\t\t\tthis._map.dragging.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst { x, y } = this._map.latLngToContainerPoint({ lng, lat });\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { lng, lat } = this._map.containerPointToLatLng({\n\t\t\tx,\n\t\t\ty,\n\t\t} as L.PointExpression);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.doubleClickZoom.enable();\n\t\t} else {\n\t\t\tthis._map.doubleClickZoom.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tchanges.created.forEach((created) => {\n\t\t\tthis._layers[created.id as string] = this._lib.geoJSON(\n\t\t\t\tcreated,\n\t\t\t\tthis.styleGeoJSONLayer(styling),\n\t\t\t);\n\t\t\tthis._map.addLayer(this._layers[created.id as string]);\n\t\t});\n\n\t\tchanges.deletedIds.forEach((deleted) => {\n\t\t\tthis._map.removeLayer(this._layers[deleted]);\n\t\t});\n\n\t\tchanges.updated.forEach((updated) => {\n\t\t\tthis._map.removeLayer(this._layers[updated.id as string]);\n\t\t\tthis._layers[updated.id as string] = this._lib.geoJSON(\n\t\t\t\tupdated,\n\t\t\t\tthis.styleGeoJSONLayer(styling),\n\t\t\t);\n\t\t\tthis._map.addLayer(this._layers[updated.id as string]);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clear up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t\tthis.clearPanes();\n\t\t}\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { Feature, LineString, Point, Polygon } from \"geojson\";\nimport mapboxgl, {\n\tCircleLayer,\n\tFillLayer,\n\tLineLayer,\n\tPointLike,\n} from \"mapbox-gl\";\nimport { GeoJSONStoreGeometries } from \"../store/store\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawMapboxGLAdapter extends TerraDrawBaseAdapter {\n\tconstructor(config: { map: mapboxgl.Map } & BaseAdapterConfig) {\n\t\tsuper(config);\n\n\t\tthis._map = config.map;\n\t\tthis._container = this._map.getContainer();\n\t}\n\n\tprivate _nextRender: number | undefined;\n\tprivate _map: mapboxgl.Map;\n\tprivate _container: HTMLElement;\n\tprivate _rendered = false;\n\n\t/**\n\t * Clears the map of rendered layers and sources\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tif (this._rendered) {\n\t\t\tconst geometryTypes = [\"point\", \"linestring\", \"polygon\"] as const;\n\t\t\tgeometryTypes.forEach((geometryKey) => {\n\t\t\t\tconst id = `td-${geometryKey.toLowerCase()}`;\n\t\t\t\tthis._map.removeLayer(id);\n\n\t\t\t\t// Special case for polygons as it has another id for the outline\n\t\t\t\t// that we need to make sure we remove\n\t\t\t\tif (geometryKey === \"polygon\") {\n\t\t\t\t\tthis._map.removeLayer(id + \"-outline\");\n\t\t\t\t}\n\t\t\t\tthis._map.removeSource(id);\n\t\t\t});\n\n\t\t\tthis._rendered = false;\n\n\t\t\t// TODO: This is necessary to prevent render artifacts, perhaps there is a nicer solution?\n\t\t\tif (this._nextRender) {\n\t\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t\t\tthis._nextRender = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _addGeoJSONSource(id: string, features: Feature[]) {\n\t\tthis._map.addSource(id, {\n\t\t\ttype: \"geojson\",\n\t\t\tdata: {\n\t\t\t\ttype: \"FeatureCollection\",\n\t\t\t\tfeatures: features,\n\t\t\t},\n\t\t\ttolerance: 0,\n\t\t});\n\t}\n\n\tprivate _addFillLayer(id: string) {\n\t\treturn this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"fill\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"fill-color\": [\"get\", \"polygonFillColor\"],\n\t\t\t\t\"fill-opacity\": [\"get\", \"polygonFillOpacity\"],\n\t\t\t},\n\t\t} as FillLayer);\n\t}\n\n\tprivate _addFillOutlineLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid: id + \"-outline\",\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"polygonOutlineWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"polygonOutlineColor\"],\n\t\t\t},\n\t\t} as LineLayer);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLineLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"lineStringWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"lineStringColor\"],\n\t\t\t},\n\t\t} as LineLayer);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addPointLayer(id: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"circle\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"circle-stroke-color\": [\"get\", \"pointOutlineColor\"],\n\t\t\t\t\"circle-stroke-width\": [\"get\", \"pointOutlineWidth\"],\n\t\t\t\t\"circle-radius\": [\"get\", \"pointWidth\"],\n\t\t\t\t\"circle-color\": [\"get\", \"pointColor\"],\n\t\t\t},\n\t\t} as CircleLayer);\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLayer(\n\t\tid: string,\n\t\tfeatureType: \"Point\" | \"LineString\" | \"Polygon\",\n\t) {\n\t\tif (featureType === \"Point\") {\n\t\t\tthis._addPointLayer(id);\n\t\t}\n\t\tif (featureType === \"LineString\") {\n\t\t\tthis._addLineLayer(id);\n\t\t}\n\t\tif (featureType === \"Polygon\") {\n\t\t\tthis._addFillLayer(id);\n\t\t\tthis._addFillOutlineLayer(id);\n\t\t}\n\t}\n\n\tprivate _addGeoJSONLayer<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `td-${featureType.toLowerCase()}`;\n\t\tthis._addGeoJSONSource(id, features);\n\t\tthis._addLayer(id, featureType);\n\n\t\treturn id;\n\t}\n\n\tprivate _setGeoJSONLayerData<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `td-${featureType.toLowerCase()}`;\n\t\t(this._map.getSource(id) as any).setData({\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: features,\n\t\t});\n\t\treturn id;\n\t}\n\n\tprivate changedIds: {\n\t\tdeletion: boolean;\n\t\tpoints: boolean;\n\t\tlinestrings: boolean;\n\t\tpolygons: boolean;\n\t\tstyling: boolean;\n\t} = {\n\t\tdeletion: false,\n\t\tpoints: false,\n\t\tlinestrings: false,\n\t\tpolygons: false,\n\t\tstyling: false,\n\t};\n\n\tprivate updateChangedIds(changes: TerraDrawChanges) {\n\t\t[...changes.updated, ...changes.created].forEach((feature) => {\n\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\tthis.changedIds.points = true;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tthis.changedIds.linestrings = true;\n\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\tthis.changedIds.polygons = true;\n\t\t\t}\n\t\t});\n\n\t\tif (changes.deletedIds.length > 0) {\n\t\t\tthis.changedIds.deletion = true;\n\t\t}\n\n\t\tif (\n\t\t\tchanges.created.length === 0 &&\n\t\t\tchanges.updated.length === 0 &&\n\t\t\tchanges.deletedIds.length === 0\n\t\t) {\n\t\t\tthis.changedIds.styling = true;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { left, top } = this._container.getBoundingClientRect();\n\t\tconst x = event.clientX - left;\n\t\tconst y = event.clientY - top;\n\n\t\treturn this.unproject(x, y);\n\t}\n\n\t/**\n\t *Retrieves the HTML element of the Mapbox element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._map.getCanvas();\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\t// Mapbox GL has both drag rotation and drag panning interactions\n\t\t\t// hence having to enable/disable both\n\t\t\tthis._map.dragRotate.enable();\n\t\t\tthis._map.dragPan.enable();\n\t\t} else {\n\t\t\tthis._map.dragRotate.disable();\n\t\t\tthis._map.dragPan.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst { x, y } = this._map.project({ lng, lat });\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { lng, lat } = this._map.unproject({ x, y } as PointLike);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tconst canvas = this._map.getCanvas();\n\t\tif (cursor === \"unset\") {\n\t\t\tcanvas.style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tcanvas.style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.doubleClickZoom.enable();\n\t\t} else {\n\t\t\tthis._map.doubleClickZoom.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.updateChangedIds(changes);\n\n\t\tif (this._nextRender) {\n\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t}\n\n\t\t// Because Mapbox GL makes us pass in a full re-render of all the features\n\t\t// we can do debounce rendering to only render the last render in a given\n\t\t// frame bucket (16ms)\n\t\tthis._nextRender = requestAnimationFrame(() => {\n\t\t\t// Get a map of the changed feature IDs by geometry type\n\t\t\t// We use this to determine which MB layers need to be updated\n\n\t\t\tconst features = [\n\t\t\t\t...changes.created,\n\t\t\t\t...changes.updated,\n\t\t\t\t...changes.unchanged,\n\t\t\t];\n\n\t\t\tconst points = [];\n\t\t\tconst linestrings = [];\n\t\t\tconst polygons = [];\n\n\t\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\t\tconst feature = features[i];\n\t\t\t\tconst { properties } = feature;\n\t\t\t\tconst mode = properties.mode as string;\n\t\t\t\tconst styles = styling[mode](feature);\n\n\t\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\t\tproperties.pointColor = styles.pointColor;\n\t\t\t\t\tproperties.pointOutlineColor = styles.pointOutlineColor;\n\t\t\t\t\tproperties.pointOutlineWidth = styles.pointOutlineWidth;\n\t\t\t\t\tproperties.pointWidth = styles.pointWidth;\n\t\t\t\t\tpoints.push(feature);\n\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\tproperties.lineStringColor = styles.lineStringColor;\n\t\t\t\t\tproperties.lineStringWidth = styles.lineStringWidth;\n\t\t\t\t\tlinestrings.push(feature);\n\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\tproperties.polygonFillColor = styles.polygonFillColor;\n\t\t\t\t\tproperties.polygonFillOpacity = styles.polygonFillOpacity;\n\t\t\t\t\tproperties.polygonOutlineColor = styles.polygonOutlineColor;\n\t\t\t\t\tproperties.polygonOutlineWidth = styles.polygonOutlineWidth;\n\t\t\t\t\tpolygons.push(feature);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!this._rendered) {\n\t\t\t\tconst pointId = this._addGeoJSONLayer<Point>(\n\t\t\t\t\t\"Point\",\n\t\t\t\t\tpoints as Feature<Point>[],\n\t\t\t\t);\n\t\t\t\tthis._addGeoJSONLayer<LineString>(\n\t\t\t\t\t\"LineString\",\n\t\t\t\t\tlinestrings as Feature<LineString>[],\n\t\t\t\t);\n\t\t\t\tthis._addGeoJSONLayer<Polygon>(\n\t\t\t\t\t\"Polygon\",\n\t\t\t\t\tpolygons as Feature<Polygon>[],\n\t\t\t\t);\n\t\t\t\tthis._rendered = true;\n\n\t\t\t\t// Ensure selection/mid points are rendered on top\n\t\t\t\tpointId && this._map.moveLayer(pointId);\n\t\t\t} else {\n\t\t\t\t// If deletion occurred we always have to update all layers\n\t\t\t\t// as we don't know the type (TODO: perhaps we could pass that back?)\n\t\t\t\tconst deletionOccurred = this.changedIds.deletion;\n\t\t\t\tconst styleUpdatedOccurred = this.changedIds.styling;\n\t\t\t\tconst forceUpdate = deletionOccurred || styleUpdatedOccurred;\n\n\t\t\t\t// Determine if we need to update each layer by geometry type\n\t\t\t\tconst updatePoints = forceUpdate || this.changedIds.points;\n\t\t\t\tconst updateLineStrings = forceUpdate || this.changedIds.linestrings;\n\t\t\t\tconst updatedPolygon = forceUpdate || this.changedIds.polygons;\n\n\t\t\t\tlet pointId;\n\t\t\t\tif (updatePoints) {\n\t\t\t\t\tpointId = this._setGeoJSONLayerData<Point>(\n\t\t\t\t\t\t\"Point\",\n\t\t\t\t\t\tpoints as Feature<Point>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (updateLineStrings) {\n\t\t\t\t\tthis._setGeoJSONLayerData<LineString>(\n\t\t\t\t\t\t\"LineString\",\n\t\t\t\t\t\tlinestrings as Feature<LineString>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (updatedPolygon) {\n\t\t\t\t\tthis._setGeoJSONLayerData<Polygon>(\n\t\t\t\t\t\t\"Polygon\",\n\t\t\t\t\t\tpolygons as Feature<Polygon>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// TODO: This logic could be better - I think this will render the selection points above user\n\t\t\t\t// defined layers outside of Terra Draw which is perhaps unideal\n\n\t\t\t\t// Ensure selection/mid points are rendered on top\n\t\t\t\tpointId && this._map.moveLayer(pointId);\n\t\t\t}\n\n\t\t\t// Reset changed ids\n\t\t\tthis.changedIds = {\n\t\t\t\tpoints: false,\n\t\t\t\tlinestrings: false,\n\t\t\t\tpolygons: false,\n\t\t\t\tdeletion: false,\n\t\t\t\tstyling: false,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clear up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { Map } from \"maplibre-gl\";\nimport { TerraDrawMapboxGLAdapter } from \"./mapbox-gl.adapter\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawMapLibreGLAdapter extends TerraDrawBaseAdapter {\n\tprivate mapboxglAdapter: TerraDrawMapboxGLAdapter;\n\n\tconstructor(config: { map: Map } & BaseAdapterConfig) {\n\t\tsuper(config);\n\n\t\t// At the moment the APIs of MapboxGL and MapLibre are so compatible that\n\t\t// there is not need to bother completely reimplementing the internals of the adapter.\n\t\t// This may change over time and gives us a shell to allow for rewriting the internals\n\t\t// of the adapter should the MapboxGL and MapbLibre APIs diverge in the instances where\n\t\t// we rely on them.\n\t\tthis.mapboxglAdapter = new TerraDrawMapboxGLAdapter(\n\t\t\tconfig as {\n\t\t\t\tmap: any; //\n\t\t\t\tcoordinatePrecision: number;\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks): void {\n\t\tthis.mapboxglAdapter.register(callbacks);\n\t}\n\n\tpublic unregister(): void {\n\t\tthis.mapboxglAdapter.unregister();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn this.mapboxglAdapter.getCoordinatePrecision();\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\treturn this.mapboxglAdapter.getLngLatFromEvent(event);\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the MapLibre element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this.mapboxglAdapter.getMapEventElement();\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis.mapboxglAdapter.setDraggability(enabled);\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\treturn this.mapboxglAdapter.project(lng, lat);\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\treturn this.mapboxglAdapter.unproject(x, y);\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(style: Parameters<SetCursor>[0]) {\n\t\tthis.mapboxglAdapter.setCursor(style);\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis.mapboxglAdapter.setDoubleClickToZoom(enabled);\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.mapboxglAdapter.render(changes, styling);\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tthis.mapboxglAdapter.clear();\n\t}\n}\n","/**\n * @module ol/proj/Units\n */\n\n/**\n * @typedef {'radians' | 'degrees' | 'ft' | 'm' | 'pixels' | 'tile-pixels' | 'us-ft'} Units\n * Projection units.\n */\n\n/**\n * See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt\n * @type {Object<number, Units>}\n */\nconst unitByCode = {\n  '9001': 'm',\n  '9002': 'ft',\n  '9003': 'us-ft',\n  '9101': 'radians',\n  '9102': 'degrees',\n};\n\n/**\n * @param {number} code Unit code.\n * @return {Units} Units.\n */\nexport function fromCode(code) {\n  return unitByCode[code];\n}\n\n/**\n * @typedef {Object} MetersPerUnitLookup\n * @property {number} radians Radians\n * @property {number} degrees Degrees\n * @property {number} ft  Feet\n * @property {number} m Meters\n * @property {number} us-ft US feet\n */\n\n/**\n * Meters per unit lookup table.\n * @const\n * @type {MetersPerUnitLookup}\n * @api\n */\nexport const METERS_PER_UNIT = {\n  // use the radius of the Normal sphere\n  'radians': 6370997 / (2 * Math.PI),\n  'degrees': (2 * Math.PI * 6370997) / 360,\n  'ft': 0.3048,\n  'm': 1,\n  'us-ft': 1200 / 3937,\n};\n","/**\n * @module ol/proj/Projection\n */\nimport {METERS_PER_UNIT} from './Units.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import(\"./Units.js\").Units} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import(\"../extent.js\").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link METERS_PER_UNIT}\n * lookup table.\n * @property {import(\"../extent.js\").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import(\"../coordinate.js\").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `number` view resolution and a {@link module:ol/coordinate~Coordinate} as arguments, and returns\n * the `number` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj.getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj.get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n *     urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n *     http://www.opengis.net/gml/srs/epsg.xml#4326,\n *     urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n *     urn:ogc:def:crs:EPSG:6.18:3:3857,\n *     http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4.register} function.\n *\n * @api\n */\nclass Projection {\n  /**\n   * @param {Options} options Projection options.\n   */\n  constructor(options) {\n    /**\n     * @private\n     * @type {string}\n     */\n    this.code_ = options.code;\n\n    /**\n     * Units of projected coordinates. When set to `TILE_PIXELS`, a\n     * `this.extent_` and `this.worldExtent_` must be configured properly for each\n     * tile.\n     * @private\n     * @type {import(\"./Units.js\").Units}\n     */\n    this.units_ = /** @type {import(\"./Units.js\").Units} */ (options.units);\n\n    /**\n     * Validity extent of the projection in projected coordinates. For projections\n     * with `TILE_PIXELS` units, this is the extent of the tile in\n     * tile pixel space.\n     * @private\n     * @type {import(\"../extent.js\").Extent}\n     */\n    this.extent_ = options.extent !== undefined ? options.extent : null;\n\n    /**\n     * Extent of the world in EPSG:4326. For projections with\n     * `TILE_PIXELS` units, this is the extent of the tile in\n     * projected coordinate space.\n     * @private\n     * @type {import(\"../extent.js\").Extent}\n     */\n    this.worldExtent_ =\n      options.worldExtent !== undefined ? options.worldExtent : null;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.axisOrientation_ =\n      options.axisOrientation !== undefined ? options.axisOrientation : 'enu';\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.global_ = options.global !== undefined ? options.global : false;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.canWrapX_ = !!(this.global_ && this.extent_);\n\n    /**\n     * @private\n     * @type {function(number, import(\"../coordinate.js\").Coordinate):number|undefined}\n     */\n    this.getPointResolutionFunc_ = options.getPointResolution;\n\n    /**\n     * @private\n     * @type {import(\"../tilegrid/TileGrid.js\").default}\n     */\n    this.defaultTileGrid_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.metersPerUnit_ = options.metersPerUnit;\n  }\n\n  /**\n   * @return {boolean} The projection is suitable for wrapping the x-axis\n   */\n  canWrapX() {\n    return this.canWrapX_;\n  }\n\n  /**\n   * Get the code for this projection, e.g. 'EPSG:4326'.\n   * @return {string} Code.\n   * @api\n   */\n  getCode() {\n    return this.code_;\n  }\n\n  /**\n   * Get the validity extent for this projection.\n   * @return {import(\"../extent.js\").Extent} Extent.\n   * @api\n   */\n  getExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * Get the units of this projection.\n   * @return {import(\"./Units.js\").Units} Units.\n   * @api\n   */\n  getUnits() {\n    return this.units_;\n  }\n\n  /**\n   * Get the amount of meters per unit of this projection.  If the projection is\n   * not configured with `metersPerUnit` or a units identifier, the return is\n   * `undefined`.\n   * @return {number|undefined} Meters.\n   * @api\n   */\n  getMetersPerUnit() {\n    return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n  }\n\n  /**\n   * Get the world extent for this projection.\n   * @return {import(\"../extent.js\").Extent} Extent.\n   * @api\n   */\n  getWorldExtent() {\n    return this.worldExtent_;\n  }\n\n  /**\n   * Get the axis orientation of this projection.\n   * Example values are:\n   * enu - the default easting, northing, elevation.\n   * neu - northing, easting, up - useful for \"lat/long\" geographic coordinates,\n   *     or south orientated transverse mercator.\n   * wnu - westing, northing, up - some planetary coordinate systems have\n   *     \"west positive\" coordinate systems\n   * @return {string} Axis orientation.\n   * @api\n   */\n  getAxisOrientation() {\n    return this.axisOrientation_;\n  }\n\n  /**\n   * Is this projection a global projection which spans the whole world?\n   * @return {boolean} Whether the projection is global.\n   * @api\n   */\n  isGlobal() {\n    return this.global_;\n  }\n\n  /**\n   * Set if the projection is a global projection which spans the whole world\n   * @param {boolean} global Whether the projection is global.\n   * @api\n   */\n  setGlobal(global) {\n    this.global_ = global;\n    this.canWrapX_ = !!(global && this.extent_);\n  }\n\n  /**\n   * @return {import(\"../tilegrid/TileGrid.js\").default} The default tile grid.\n   */\n  getDefaultTileGrid() {\n    return this.defaultTileGrid_;\n  }\n\n  /**\n   * @param {import(\"../tilegrid/TileGrid.js\").default} tileGrid The default tile grid.\n   */\n  setDefaultTileGrid(tileGrid) {\n    this.defaultTileGrid_ = tileGrid;\n  }\n\n  /**\n   * Set the validity extent for this projection.\n   * @param {import(\"../extent.js\").Extent} extent Extent.\n   * @api\n   */\n  setExtent(extent) {\n    this.extent_ = extent;\n    this.canWrapX_ = !!(this.global_ && extent);\n  }\n\n  /**\n   * Set the world extent for this projection.\n   * @param {import(\"../extent.js\").Extent} worldExtent World extent\n   *     [minlon, minlat, maxlon, maxlat].\n   * @api\n   */\n  setWorldExtent(worldExtent) {\n    this.worldExtent_ = worldExtent;\n  }\n\n  /**\n   * Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}\n   * for this projection.\n   * @param {function(number, import(\"../coordinate.js\").Coordinate):number} func Function\n   * @api\n   */\n  setGetPointResolution(func) {\n    this.getPointResolutionFunc_ = func;\n  }\n\n  /**\n   * Get the custom point resolution function for this projection (if set).\n   * @return {function(number, import(\"../coordinate.js\").Coordinate):number|undefined} The custom point\n   * resolution function (if set).\n   */\n  getPointResolutionFunc() {\n    return this.getPointResolutionFunc_;\n  }\n}\n\nexport default Projection;\n","/**\n * @module ol/proj/epsg3857\n */\nimport Projection from './Projection.js';\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * @const\n * @type {number}\n */\nexport const HALF_SIZE = Math.PI * RADIUS;\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const WORLD_EXTENT = [-180, -85, 180, 85];\n\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\nexport const MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\nclass EPSG3857Projection extends Projection {\n  /**\n   * @param {string} code Code.\n   */\n  constructor(code) {\n    super({\n      code: code,\n      units: 'm',\n      extent: EXTENT,\n      global: true,\n      worldExtent: WORLD_EXTENT,\n      getPointResolution: function (resolution, point) {\n        return resolution / Math.cosh(point[1] / RADIUS);\n      },\n    });\n  }\n}\n\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n  new EPSG3857Projection('EPSG:3857'),\n  new EPSG3857Projection('EPSG:102100'),\n  new EPSG3857Projection('EPSG:102113'),\n  new EPSG3857Projection('EPSG:900913'),\n  new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),\n  new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),\n];\n\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function fromEPSG4326(input, output, dimension) {\n  const length = input.length;\n  dimension = dimension > 1 ? dimension : 2;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = (HALF_SIZE * input[i]) / 180;\n    let y = RADIUS * Math.log(Math.tan((Math.PI * (+input[i + 1] + 90)) / 360));\n    if (y > MAX_SAFE_Y) {\n      y = MAX_SAFE_Y;\n    } else if (y < -MAX_SAFE_Y) {\n      y = -MAX_SAFE_Y;\n    }\n    output[i + 1] = y;\n  }\n  return output;\n}\n\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function toEPSG4326(input, output, dimension) {\n  const length = input.length;\n  dimension = dimension > 1 ? dimension : 2;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = (180 * input[i]) / HALF_SIZE;\n    output[i + 1] =\n      (360 * Math.atan(Math.exp(input[i + 1] / RADIUS))) / Math.PI - 90;\n  }\n  return output;\n}\n","/**\n * @module ol/proj/epsg4326\n */\nimport Projection from './Projection.js';\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-180, -90, 180, 90];\n\n/**\n * @const\n * @type {number}\n */\nexport const METERS_PER_UNIT = (Math.PI * RADIUS) / 180;\n\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\nclass EPSG4326Projection extends Projection {\n  /**\n   * @param {string} code Code.\n   * @param {string} [axisOrientation] Axis orientation.\n   */\n  constructor(code, axisOrientation) {\n    super({\n      code: code,\n      units: 'degrees',\n      extent: EXTENT,\n      axisOrientation: axisOrientation,\n      global: true,\n      metersPerUnit: METERS_PER_UNIT,\n      worldExtent: EXTENT,\n    });\n  }\n}\n\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n  new EPSG4326Projection('CRS:84'),\n  new EPSG4326Projection('EPSG:4326', 'neu'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),\n  new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84'),\n  new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),\n  new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),\n];\n","/**\n * @module ol/proj/projections\n */\n\n/**\n * @type {Object<string, import(\"./Projection.js\").default>}\n */\nlet cache = {};\n\n/**\n * Clear the projections cache.\n */\nexport function clear() {\n  cache = {};\n}\n\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import(\"./Projection.js\").default} The projection (if cached).\n */\nexport function get(code) {\n  return (\n    cache[code] ||\n    cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, 'EPSG:$3')] ||\n    null\n  );\n}\n\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import(\"./Projection.js\").default} projection The projection to cache.\n */\nexport function add(code, projection) {\n  cache[code] = projection;\n}\n","/**\n * @module ol/proj/transforms\n */\nimport {isEmpty} from '../obj.js';\n\n/**\n * @private\n * @type {!Object<string, Object<string, import(\"../proj.js\").TransformFunction>>}\n */\nlet transforms = {};\n\n/**\n * Clear the transform cache.\n */\nexport function clear() {\n  transforms = {};\n}\n\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import(\"./Projection.js\").default} source Source.\n * @param {import(\"./Projection.js\").default} destination Destination.\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform.\n */\nexport function add(source, destination, transformFn) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  if (!(sourceCode in transforms)) {\n    transforms[sourceCode] = {};\n  }\n  transforms[sourceCode][destinationCode] = transformFn;\n}\n\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection.  This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import(\"./Projection.js\").default} source Source projection.\n * @param {import(\"./Projection.js\").default} destination Destination projection.\n * @return {import(\"../proj.js\").TransformFunction} transformFn The unregistered transform.\n */\nexport function remove(source, destination) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  const transform = transforms[sourceCode][destinationCode];\n  delete transforms[sourceCode][destinationCode];\n  if (isEmpty(transforms[sourceCode])) {\n    delete transforms[sourceCode];\n  }\n  return transform;\n}\n\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import(\"../proj.js\").TransformFunction|undefined} The transform function (if found).\n */\nexport function get(sourceCode, destinationCode) {\n  let transform;\n  if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n    transform = transforms[sourceCode][destinationCode];\n  }\n  return transform;\n}\n","/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection~Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4's registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get('EPSG:1234').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj.addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection~Projection} object for the new projection and add it with\n * {@link module:ol/proj.addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj.addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection~Projection} with\n * {@link module:ol/proj.addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\nimport Projection from './proj/Projection.js';\nimport {\n  PROJECTIONS as EPSG3857_PROJECTIONS,\n  fromEPSG4326,\n  toEPSG4326,\n} from './proj/epsg3857.js';\nimport {PROJECTIONS as EPSG4326_PROJECTIONS} from './proj/epsg4326.js';\nimport {METERS_PER_UNIT} from './proj/Units.js';\nimport {\n  add as addProj,\n  clear as clearProj,\n  get as getProj,\n} from './proj/projections.js';\nimport {\n  add as addTransformFunc,\n  clear as clearTransformFuncs,\n  get as getTransformFunc,\n} from './proj/transforms.js';\nimport {applyTransform, getWidth} from './extent.js';\nimport {clamp, modulo} from './math.js';\nimport {equals, getWorldsAway} from './coordinate.js';\nimport {getDistance} from './sphere.js';\nimport {warn} from './console.js';\n\n/**\n * A projection as {@link module:ol/proj/Projection~Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2).  The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\n\nexport {METERS_PER_UNIT};\n\nexport {Projection};\n\nlet showCoordinateWarning = true;\n\n/**\n * @param {boolean} [disable = true] Disable console info about `useGeographic()`\n */\nexport function disableCoordinateWarning(disable) {\n  const hide = disable === undefined ? true : disable;\n  showCoordinateWarning = !hide;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n *     values).\n */\nexport function cloneTransform(input, output) {\n  if (output !== undefined) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      output[i] = input[i];\n    }\n    output = output;\n  } else {\n    output = input.slice();\n  }\n  return output;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\nexport function identityTransform(input, output) {\n  if (output !== undefined && input !== output) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      output[i] = input[i];\n    }\n    input = output;\n  }\n  return input;\n}\n\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\nexport function addProjection(projection) {\n  addProj(projection.getCode(), projection);\n  addTransformFunc(projection, projection, cloneTransform);\n}\n\n/**\n * @param {Array<Projection>} projections Projections.\n */\nexport function addProjections(projections) {\n  projections.forEach(addProjection);\n}\n\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n *     a combination of authority and identifier such as \"EPSG:4326\", or an\n *     existing projection object, or undefined.\n * @return {Projection|null} Projection object, or null if not in list.\n * @api\n */\nexport function get(projectionLike) {\n  return typeof projectionLike === 'string'\n    ? getProj(/** @type {string} */ (projectionLike))\n    : /** @type {Projection} */ (projectionLike) || null;\n}\n\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the `point` pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import(\"./coordinate.js\").Coordinate} point Point to find adjusted resolution at.\n * @param {import(\"./proj/Units.js\").Units} [units] Units to get the point resolution in.\n * Default is the projection's units.\n * @return {number} Point resolution.\n * @api\n */\nexport function getPointResolution(projection, resolution, point, units) {\n  projection = get(projection);\n  let pointResolution;\n  const getter = projection.getPointResolutionFunc();\n  if (getter) {\n    pointResolution = getter(resolution, point);\n    if (units && units !== projection.getUnits()) {\n      const metersPerUnit = projection.getMetersPerUnit();\n      if (metersPerUnit) {\n        pointResolution =\n          (pointResolution * metersPerUnit) / METERS_PER_UNIT[units];\n      }\n    }\n  } else {\n    const projUnits = projection.getUnits();\n    if ((projUnits == 'degrees' && !units) || units == 'degrees') {\n      pointResolution = resolution;\n    } else {\n      // Estimate point resolution by transforming the center pixel to EPSG:4326,\n      // measuring its width and height on the normal sphere, and taking the\n      // average of the width and height.\n      const toEPSG4326 = getTransformFromProjections(\n        projection,\n        get('EPSG:4326'),\n      );\n      if (toEPSG4326 === identityTransform && projUnits !== 'degrees') {\n        // no transform is available\n        pointResolution = resolution * projection.getMetersPerUnit();\n      } else {\n        let vertices = [\n          point[0] - resolution / 2,\n          point[1],\n          point[0] + resolution / 2,\n          point[1],\n          point[0],\n          point[1] - resolution / 2,\n          point[0],\n          point[1] + resolution / 2,\n        ];\n        vertices = toEPSG4326(vertices, vertices, 2);\n        const width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n        const height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n        pointResolution = (width + height) / 2;\n      }\n      const metersPerUnit = units\n        ? METERS_PER_UNIT[units]\n        : projection.getMetersPerUnit();\n      if (metersPerUnit !== undefined) {\n        pointResolution /= metersPerUnit;\n      }\n    }\n  }\n  return pointResolution;\n}\n\n/**\n * Registers transformation functions that don't alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\nexport function addEquivalentProjections(projections) {\n  addProjections(projections);\n  projections.forEach(function (source) {\n    projections.forEach(function (destination) {\n      if (source !== destination) {\n        addTransformFunc(source, destination, cloneTransform);\n      }\n    });\n  });\n}\n\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n *     meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n *     meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n *   projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n *   in projection2 to any projection in projection1..\n */\nexport function addEquivalentTransforms(\n  projections1,\n  projections2,\n  forwardTransform,\n  inverseTransform,\n) {\n  projections1.forEach(function (projection1) {\n    projections2.forEach(function (projection2) {\n      addTransformFunc(projection1, projection2, forwardTransform);\n      addTransformFunc(projection2, projection1, inverseTransform);\n    });\n  });\n}\n\n/**\n * Clear all cached projections and transforms.\n */\nexport function clearAllProjections() {\n  clearProj();\n  clearTransformFuncs();\n}\n\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\nexport function createProjection(projection, defaultCode) {\n  if (!projection) {\n    return get(defaultCode);\n  }\n  if (typeof projection === 'string') {\n    return get(projection);\n  }\n  return /** @type {Projection} */ (projection);\n}\n\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} coordTransform Coordinate\n *     transform.\n * @return {TransformFunction} Transform function.\n */\nexport function createTransformFromCoordinateTransform(coordTransform) {\n  return (\n    /**\n     * @param {Array<number>} input Input.\n     * @param {Array<number>} [output] Output.\n     * @param {number} [dimension] Dimension.\n     * @return {Array<number>} Output.\n     */\n    function (input, output, dimension) {\n      const length = input.length;\n      dimension = dimension !== undefined ? dimension : 2;\n      output = output !== undefined ? output : new Array(length);\n      for (let i = 0; i < length; i += dimension) {\n        const point = coordTransform(input.slice(i, i + dimension));\n        const pointLength = point.length;\n        for (let j = 0, jj = dimension; j < jj; ++j) {\n          output[i + j] = j >= pointLength ? input[i + j] : point[j];\n        }\n      }\n      return output;\n    }\n  );\n}\n\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} forward The forward transform\n *     function (that is, from the source projection to the destination\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} inverse The inverse transform\n *     function (that is, from the destination projection to the source\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only\n *     transform less dimensions than the input coordinate, it is supposeed to return a coordinate\n *     with only the length it can transform. The other dimensions will be taken unchanged from the\n *     source.\n * @api\n */\nexport function addCoordinateTransforms(source, destination, forward, inverse) {\n  const sourceProj = get(source);\n  const destProj = get(destination);\n  addTransformFunc(\n    sourceProj,\n    destProj,\n    createTransformFromCoordinateTransform(forward),\n  );\n  addTransformFunc(\n    destProj,\n    sourceProj,\n    createTransformFromCoordinateTransform(inverse),\n  );\n}\n\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n *     an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike} [projection] Target projection. The\n *     default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate projected to the target projection.\n * @api\n */\nexport function fromLonLat(coordinate, projection) {\n  disableCoordinateWarning();\n  return transform(\n    coordinate,\n    'EPSG:4326',\n    projection !== undefined ? projection : 'EPSG:3857',\n  );\n}\n\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike} [projection] Projection of the coordinate.\n *     The default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate as longitude and latitude, i.e. an array\n *     with longitude as 1st and latitude as 2nd element.\n * @api\n */\nexport function toLonLat(coordinate, projection) {\n  const lonLat = transform(\n    coordinate,\n    projection !== undefined ? projection : 'EPSG:3857',\n    'EPSG:4326',\n  );\n  const lon = lonLat[0];\n  if (lon < -180 || lon > 180) {\n    lonLat[0] = modulo(lon + 180, 360) - 180;\n  }\n  return lonLat;\n}\n\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\nexport function equivalent(projection1, projection2) {\n  if (projection1 === projection2) {\n    return true;\n  }\n  const equalUnits = projection1.getUnits() === projection2.getUnits();\n  if (projection1.getCode() === projection2.getCode()) {\n    return equalUnits;\n  }\n  const transformFunc = getTransformFromProjections(projection1, projection2);\n  return transformFunc === cloneTransform && equalUnits;\n}\n\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n *     object.\n * @return {TransformFunction} Transform function.\n */\nexport function getTransformFromProjections(\n  sourceProjection,\n  destinationProjection,\n) {\n  const sourceCode = sourceProjection.getCode();\n  const destinationCode = destinationProjection.getCode();\n  let transformFunc = getTransformFunc(sourceCode, destinationCode);\n  if (!transformFunc) {\n    transformFunc = identityTransform;\n  }\n  return transformFunc;\n}\n\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\nexport function getTransform(source, destination) {\n  const sourceProjection = get(source);\n  const destinationProjection = get(destination);\n  return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj.transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n * @api\n */\nexport function transform(coordinate, source, destination) {\n  const transformFunc = getTransform(source, destination);\n  return transformFunc(coordinate, undefined, coordinate.length);\n}\n\n/**\n * Transforms an extent from source projection to destination projection.  This\n * returns a new extent (and does not modify the original).\n *\n * @param {import(\"./extent.js\").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number} [stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import(\"./extent.js\").Extent} The transformed extent.\n * @api\n */\nexport function transformExtent(extent, source, destination, stops) {\n  const transformFunc = getTransform(source, destination);\n  return applyTransform(extent, transformFunc, undefined, stops);\n}\n\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import(\"./coordinate.js\").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import(\"./coordinate.js\").Coordinate} Point.\n */\nexport function transformWithProjections(\n  point,\n  sourceProjection,\n  destinationProjection,\n) {\n  const transformFunc = getTransformFromProjections(\n    sourceProjection,\n    destinationProjection,\n  );\n  return transformFunc(point);\n}\n\n/**\n * @type {Projection|null}\n */\nlet userProjection = null;\n\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * This includes all API methods except for those interacting with tile grids,\n * plus {@link import(\"./Map.js\").FrameState} and {@link import(\"./View.js\").State}.\n * @param {ProjectionLike} projection The user projection.\n * @api\n */\nexport function setUserProjection(projection) {\n  userProjection = get(projection);\n}\n\n/**\n * Clear the user projection if set.\n * @api\n */\nexport function clearUserProjection() {\n  userProjection = null;\n}\n\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * @return {Projection|null} The user projection (or null if not set).\n * @api\n */\nexport function getUserProjection() {\n  return userProjection;\n}\n\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods.\n * This includes all API methods except for those interacting with tile grids,\n * plus {@link import(\"./Map.js\").FrameState} and {@link import(\"./View.js\").State}.\n * @api\n */\nexport function useGeographic() {\n  setUserProjection('EPSG:4326');\n}\n\n/**\n * Return a coordinate transformed into the user projection.  If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @return {Array<number>} The input coordinate in the user projection.\n */\nexport function toUserCoordinate(coordinate, sourceProjection) {\n  if (!userProjection) {\n    return coordinate;\n  }\n  return transform(coordinate, sourceProjection, userProjection);\n}\n\n/**\n * Return a coordinate transformed from the user projection.  If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {Array<number>} The input coordinate transformed.\n */\nexport function fromUserCoordinate(coordinate, destProjection) {\n  if (!userProjection) {\n    if (\n      showCoordinateWarning &&\n      !equals(coordinate, [0, 0]) &&\n      coordinate[0] >= -180 &&\n      coordinate[0] <= 180 &&\n      coordinate[1] >= -90 &&\n      coordinate[1] <= 90\n    ) {\n      showCoordinateWarning = false;\n      warn(\n        'Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.',\n      );\n    }\n    return coordinate;\n  }\n  return transform(coordinate, userProjection, destProjection);\n}\n\n/**\n * Return an extent transformed into the user projection.  If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @return {import(\"./extent.js\").Extent} The input extent in the user projection.\n */\nexport function toUserExtent(extent, sourceProjection) {\n  if (!userProjection) {\n    return extent;\n  }\n  return transformExtent(extent, sourceProjection, userProjection);\n}\n\n/**\n * Return an extent transformed from the user projection.  If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {import(\"./extent.js\").Extent} The input extent transformed.\n */\nexport function fromUserExtent(extent, destProjection) {\n  if (!userProjection) {\n    return extent;\n  }\n  return transformExtent(extent, userProjection, destProjection);\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in input projection units per pixel.\n * @param {ProjectionLike} sourceProjection The input projection.\n * @return {number} Resolution in user projection units per pixel.\n */\nexport function toUserResolution(resolution, sourceProjection) {\n  if (!userProjection) {\n    return resolution;\n  }\n  const sourceMetersPerUnit = get(sourceProjection).getMetersPerUnit();\n  const userMetersPerUnit = userProjection.getMetersPerUnit();\n  return sourceMetersPerUnit && userMetersPerUnit\n    ? (resolution * sourceMetersPerUnit) / userMetersPerUnit\n    : resolution;\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in user projection units per pixel.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {number} Resolution in destination projection units per pixel.\n */\nexport function fromUserResolution(resolution, destProjection) {\n  if (!userProjection) {\n    return resolution;\n  }\n  const destMetersPerUnit = get(destProjection).getMetersPerUnit();\n  const userMetersPerUnit = userProjection.getMetersPerUnit();\n  return destMetersPerUnit && userMetersPerUnit\n    ? (resolution * userMetersPerUnit) / destMetersPerUnit\n    : resolution;\n}\n\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * \"Safe\" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent's range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} transform Transform function (source to destination).\n * @return {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} Safe transform function (source to destination).\n */\nexport function createSafeCoordinateTransform(sourceProj, destProj, transform) {\n  return function (coord) {\n    let transformed, worldsAway;\n    if (sourceProj.canWrapX()) {\n      const sourceExtent = sourceProj.getExtent();\n      const sourceExtentWidth = getWidth(sourceExtent);\n      coord = coord.slice(0);\n      worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n      if (worldsAway) {\n        // Move x to the real world\n        coord[0] = coord[0] - worldsAway * sourceExtentWidth;\n      }\n      coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);\n      coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);\n      transformed = transform(coord);\n    } else {\n      transformed = transform(coord);\n    }\n    if (worldsAway && destProj.canWrapX()) {\n      // Move transformed coordinate back to the offset world\n      transformed[0] += worldsAway * getWidth(destProj.getExtent());\n    }\n    return transformed;\n  };\n}\n\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857.  This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\nexport function addCommon() {\n  // Add transformations that don't alter coordinates to convert within set of\n  // projections with equal meaning.\n  addEquivalentProjections(EPSG3857_PROJECTIONS);\n  addEquivalentProjections(EPSG4326_PROJECTIONS);\n  // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n  // coordinates and back.\n  addEquivalentTransforms(\n    EPSG4326_PROJECTIONS,\n    EPSG3857_PROJECTIONS,\n    fromEPSG4326,\n    toEPSG4326,\n  );\n}\n\naddCommon();\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../store/store\";\nimport Feature, { FeatureLike } from \"ol/Feature\";\nimport GeoJSON from \"ol/format/GeoJSON\";\nimport Map from \"ol/Map\";\nimport Circle from \"ol/style/Circle\";\nimport Fill from \"ol/style/Fill\";\nimport Stroke from \"ol/style/Stroke\";\nimport Style from \"ol/style/Style\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Geometry } from \"ol/geom\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport { toLonLat, fromLonLat, getUserProjection, Projection } from \"ol/proj\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { Pixel } from \"ol/pixel\";\n\nexport type InjectableOL = {\n\tFill: typeof Fill;\n\tFeature: typeof Feature;\n\tGeoJSON: typeof GeoJSON;\n\tStyle: typeof Style;\n\tCircle: typeof Circle;\n\tVectorLayer: typeof VectorLayer;\n\tVectorSource: typeof VectorSource;\n\tStroke: typeof Stroke;\n\tgetUserProjection: typeof getUserProjection;\n};\n\nexport class TerraDrawOpenLayersAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tmap: Map;\n\t\t\tlib: InjectableOL;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._map = config.map;\n\t\tthis._lib = config.lib;\n\n\t\tthis._geoJSONReader = new this._lib.GeoJSON();\n\t\tthis._projection = () =>\n\t\t\tthis._lib.getUserProjection() ?? new Projection({ code: \"EPSG:3857\" });\n\n\t\tthis._container = this._map.getViewport();\n\n\t\t// TODO: Is this the best way to recieve keyboard events\n\t\tthis._container.setAttribute(\"tabindex\", \"0\");\n\n\t\tconst vectorSource = new this._lib.VectorSource({\n\t\t\tfeatures: [],\n\t\t}) as unknown as VectorSource<Feature<Geometry>>;\n\n\t\tthis._vectorSource = vectorSource as unknown as VectorSource<\n\t\t\tFeature<Geometry>\n\t\t>;\n\n\t\tconst vectorLayer = new this._lib.VectorLayer({\n\t\t\tsource: vectorSource as unknown as VectorSource<never>,\n\t\t\tstyle: (feature) => this.getStyles(feature, this.stylingFunction()),\n\t\t});\n\n\t\tthis._map.addLayer(vectorLayer);\n\t}\n\n\tprivate stylingFunction = () => ({});\n\n\tprivate _lib: InjectableOL;\n\tprivate _map: Map;\n\tprivate _container: HTMLElement;\n\tprivate _projection: () => Projection;\n\tprivate _vectorSource: VectorSource<Feature<Geometry>>;\n\tprivate _geoJSONReader: GeoJSON;\n\n\t/**\n\t * Converts a hexideciaml color to RGB\n\t * @param hex a string of the hexidecimal string\n\t * @returns an object to red green and blue (RGB) color\n\t */\n\tprivate hexToRGB(hex: string): { r: number; g: number; b: number } {\n\t\treturn {\n\t\t\tr: parseInt(hex.slice(1, 3), 16),\n\t\t\tg: parseInt(hex.slice(3, 5), 16),\n\t\t\tb: parseInt(hex.slice(5, 7), 16),\n\t\t};\n\t}\n\n\tprivate getStyles(feature: FeatureLike, styling: TerraDrawStylingFunction) {\n\t\tconst geometry = feature.getGeometry();\n\t\tif (!geometry) {\n\t\t\treturn;\n\t\t}\n\t\tconst key = geometry.getType() as \"Point\" | \"LineString\" | \"Polygon\";\n\n\t\treturn {\n\t\t\tPoint: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"Point\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\treturn new this._lib.Style({\n\t\t\t\t\timage: new this._lib.Circle({\n\t\t\t\t\t\tradius: style.pointWidth,\n\t\t\t\t\t\tfill: new this._lib.Fill({\n\t\t\t\t\t\t\tcolor: style.pointColor,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tstroke: new this._lib.Stroke({\n\t\t\t\t\t\t\tcolor: style.pointOutlineColor,\n\t\t\t\t\t\t\twidth: style.pointOutlineWidth,\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t\tLineString: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"LineString\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\treturn new this._lib.Style({\n\t\t\t\t\tstroke: new this._lib.Stroke({\n\t\t\t\t\t\tcolor: style.lineStringColor,\n\t\t\t\t\t\twidth: style.lineStringWidth,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t\tPolygon: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"Polygon\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\tconst { r, g, b } = this.hexToRGB(style.polygonFillColor);\n\n\t\t\t\treturn new this._lib.Style({\n\t\t\t\t\tstroke: new this._lib.Stroke({\n\t\t\t\t\t\tcolor: style.polygonOutlineColor,\n\t\t\t\t\t\twidth: style.polygonOutlineWidth,\n\t\t\t\t\t}),\n\t\t\t\t\tfill: new this._lib.Fill({\n\t\t\t\t\t\tcolor: `rgba(${r},${g},${b},${style.polygonFillOpacity})`,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t}[key](feature);\n\t}\n\n\t/**\n\t * Clears the layers created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tif (this._vectorSource) {\n\t\t\tthis._vectorSource.clear();\n\t\t}\n\t}\n\n\tprivate addFeature(feature: GeoJSONStoreFeatures) {\n\t\tconst olFeature = this._geoJSONReader.readFeature(feature, {\n\t\t\tdataProjection: \"EPSG:4326\",\n\t\t\tfeatureProjection: this._projection(),\n\t\t}) as Feature<Geometry>;\n\t\tthis._vectorSource.addFeature(olFeature);\n\t}\n\n\tprivate removeFeature(id: FeatureId) {\n\t\tconst deleted = this._vectorSource.getFeatureById(id);\n\t\tif (!deleted) {\n\t\t\treturn;\n\t\t}\n\t\tthis._vectorSource.removeFeature(deleted);\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\t\ttry {\n\t\t\treturn this.unproject(x, y);\n\t\t} catch (_) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the OpenLayers element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\tconst canvases = this._container.querySelectorAll(\".ol-layer canvas\") as NodeListOf<HTMLElement>;\n\n\t\tif (canvases.length > 1) {\n\t\t\tthrow Error(\n\t\t\t\t\"Terra Draw currently only supports 1 canvas with OpenLayers\",\n\t\t\t);\n\t\t}\n\n\t\treturn canvases[0];\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis._map.getInteractions().forEach((interaction) => {\n\t\t\tif (interaction.constructor.name === \"DragPan\") {\n\t\t\t\tinteraction.setActive(enabled);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst [x, y] = this._map.getPixelFromCoordinate(\n\t\t\tfromLonLat([lng, lat], this._projection()) as Coordinate,\n\t\t);\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst [lng, lat] = toLonLat(\n\t\t\tthis._map.getCoordinateFromPixel([x, y]) as Pixel,\n\t\t\tthis._projection(),\n\t\t);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis._map.getInteractions().forEach(function (interaction) {\n\t\t\tif (interaction.constructor.name === \"DoubleClickZoom\") {\n\t\t\t\tinteraction.setActive(enabled);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.stylingFunction = () => styling;\n\n\t\tchanges.deletedIds.forEach((id) => {\n\t\t\tthis.removeFeature(id);\n\t\t});\n\n\t\tchanges.updated.forEach((feature) => {\n\t\t\tthis.removeFeature(feature.id as FeatureId);\n\t\t\tthis.addFeature(feature);\n\t\t});\n\n\t\tchanges.created.forEach((feature) => {\n\t\t\tthis.addFeature(feature);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clean up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n}\n","import {\n\tStoreChangeHandler,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tFeatureId,\n} from \"./store/store\";\n\nexport type HexColor = `#${string}`;\n\nexport type HexColorStyling =\n\t| HexColor\n\t| ((feature: GeoJSONStoreFeatures) => HexColor);\n\nexport type NumericStyling =\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => number);\n\nexport interface TerraDrawAdapterStyling {\n\tpointColor: HexColor;\n\tpointWidth: number;\n\tpointOutlineColor: HexColor;\n\tpointOutlineWidth: number;\n\tpolygonFillColor: HexColor;\n\tpolygonFillOpacity: number;\n\tpolygonOutlineColor: HexColor;\n\tpolygonOutlineWidth: number;\n\tlineStringWidth: number;\n\tlineStringColor: HexColor;\n\tzIndex: number;\n}\n\n// Neither buttons nor touch/pen contact changed since last event\t-1\n// Mouse move with no buttons pressed, Pen moved while hovering with no buttons pressed\t—\n// Left Mouse, Touch Contact, Pen contact\t0\n// Middle Mouse\t1\n// Right Mouse, Pen barrel button\t2\nexport interface TerraDrawMouseEvent {\n\tlng: number;\n\tlat: number;\n\tcontainerX: number;\n\tcontainerY: number;\n\tbutton: \"neither\" | \"left\" | \"middle\" | \"right\";\n\theldKeys: string[];\n}\n\nexport interface TerraDrawKeyboardEvent {\n\tkey: string;\n\theldKeys: string[];\n\tpreventDefault: () => void;\n}\n\nexport type Cursor = Parameters<SetCursor>[0];\n\nexport type SetCursor = (\n\tcursor:\n\t\t| \"unset\"\n\t\t| \"grab\"\n\t\t| \"grabbing\"\n\t\t| \"crosshair\"\n\t\t| \"pointer\"\n\t\t| \"wait\"\n\t\t| \"move\",\n) => void;\n\nexport type Project = (lng: number, lat: number) => { x: number; y: number };\nexport type Unproject = (x: number, y: number) => { lat: number; lng: number };\nexport type GetLngLatFromEvent = (event: PointerEvent | MouseEvent) => {\n\tlng: number;\n\tlat: number;\n} | null;\n\nexport type Projection = \"web-mercator\" | \"globe\";\n\nexport type OnFinishContext = { mode: string; action: string };\n\nexport interface TerraDrawModeRegisterConfig {\n\tmode: string;\n\tstore: GeoJSONStore;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tsetCursor: SetCursor;\n\tonChange: StoreChangeHandler;\n\tonSelect: (selectedId: string) => void;\n\tonDeselect: (deselectedId: string) => void;\n\tonFinish: (finishedId: string, context: OnFinishContext) => void;\n\tproject: Project;\n\tunproject: Unproject;\n\tcoordinatePrecision: number;\n}\n\nexport enum UpdateTypes {\n\tCommit = \"commit\",\n\tProvisional = \"provisional\",\n\tFinish = \"finish\",\n}\n\ntype ValidationContext = Pick<\n\tTerraDrawModeRegisterConfig,\n\t\"project\" | \"unproject\" | \"coordinatePrecision\"\n> & {\n\tupdateType: UpdateTypes;\n};\n\nexport type Validation = (\n\tfeature: GeoJSONStoreFeatures,\n\tcontext: ValidationContext,\n) => boolean;\n\nexport type TerraDrawModeState =\n\t| \"unregistered\"\n\t| \"registered\"\n\t| \"started\"\n\t| \"drawing\"\n\t| \"selecting\"\n\t| \"stopped\";\n\nexport interface TerraDrawCallbacks {\n\tgetState: () => TerraDrawModeState;\n\tonKeyUp: (event: TerraDrawKeyboardEvent) => void;\n\tonKeyDown: (event: TerraDrawKeyboardEvent) => void;\n\tonClick: (event: TerraDrawMouseEvent) => void;\n\tonMouseMove: (event: TerraDrawMouseEvent) => void;\n\tonDragStart: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonDrag: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonDragEnd: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonClear: () => void;\n\tonReady?(): void;\n}\n\nexport interface TerraDrawChanges {\n\tcreated: GeoJSONStoreFeatures[];\n\tupdated: GeoJSONStoreFeatures[];\n\tunchanged: GeoJSONStoreFeatures[];\n\tdeletedIds: FeatureId[];\n}\n\nexport type TerraDrawStylingFunction = {\n\t[mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n};\n\nexport interface TerraDrawAdapter {\n\tproject: Project;\n\tunproject: Unproject;\n\tsetCursor: SetCursor;\n\tgetLngLatFromEvent: GetLngLatFromEvent;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tgetMapEventElement: () => HTMLElement;\n\tregister(callbacks: TerraDrawCallbacks): void;\n\tunregister(): void;\n\trender(changes: TerraDrawChanges, styling: TerraDrawStylingFunction): void;\n\tclear(): void;\n\tgetCoordinatePrecision(): number;\n}\n\nexport const SELECT_PROPERTIES = {\n\tSELECTED: \"selected\",\n\tMID_POINT: \"midPoint\",\n\tSELECTION_POINT: \"selectionPoint\",\n} as const;\n\nexport const POLYGON_PROPERTIES = {\n\tCLOSING_POINT: \"closingPoint\",\n};\n","/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n *     number within the bounds.\n */\nexport function clamp(value, min, max) {\n  return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  if (dx !== 0 || dy !== 0) {\n    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n    if (t > 1) {\n      x1 = x2;\n      y1 = y2;\n    } else if (t > 0) {\n      x1 += dx * t;\n      y1 += dy * t;\n    }\n  }\n  return squaredDistance(x, y, x1, y1);\n}\n\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredDistance(x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  return dx * dx + dy * dy;\n}\n\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n *                                     in row-major order.\n * @return {Array<number>|null} The resulting vector.\n */\nexport function solveLinearSystem(mat) {\n  const n = mat.length;\n\n  for (let i = 0; i < n; i++) {\n    // Find max in the i-th column (ignoring i - 1 first rows)\n    let maxRow = i;\n    let maxEl = Math.abs(mat[i][i]);\n    for (let r = i + 1; r < n; r++) {\n      const absValue = Math.abs(mat[r][i]);\n      if (absValue > maxEl) {\n        maxEl = absValue;\n        maxRow = r;\n      }\n    }\n\n    if (maxEl === 0) {\n      return null; // matrix is singular\n    }\n\n    // Swap max row with i-th (current) row\n    const tmp = mat[maxRow];\n    mat[maxRow] = mat[i];\n    mat[i] = tmp;\n\n    // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n    for (let j = i + 1; j < n; j++) {\n      const coef = -mat[j][i] / mat[i][i];\n      for (let k = i; k < n + 1; k++) {\n        if (i == k) {\n          mat[j][k] = 0;\n        } else {\n          mat[j][k] += coef * mat[i][k];\n        }\n      }\n    }\n  }\n\n  // Solve Ax=b for upper triangular matrix A (mat)\n  const x = new Array(n);\n  for (let l = n - 1; l >= 0; l--) {\n    x[l] = mat[l][n] / mat[l][l];\n    for (let m = l - 1; m >= 0; m--) {\n      mat[m][n] -= mat[m][l] * x[l];\n    }\n  }\n  return x;\n}\n\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\nexport function toDegrees(angleInRadians) {\n  return (angleInRadians * 180) / Math.PI;\n}\n\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\nexport function toRadians(angleInDegrees) {\n  return (angleInDegrees * Math.PI) / 180;\n}\n\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\nexport function modulo(a, b) {\n  const r = a % b;\n  return r * b < 0 ? r + b : r;\n}\n\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\nexport function lerp(a, b, x) {\n  return a + x * (b - a);\n}\n\n/**\n * Returns a number with a limited number of decimal digits.\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The input number with a limited number of decimal digits.\n */\nexport function toFixed(n, decimals) {\n  const factor = Math.pow(10, decimals);\n  return Math.round(n * factor) / factor;\n}\n\n/**\n * Rounds a number to the nearest integer value considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The nearest integer.\n */\nexport function round(n, decimals) {\n  return Math.round(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next smaller integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next smaller integer.\n */\nexport function floor(n, decimals) {\n  return Math.floor(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next bigger integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next bigger integer.\n */\nexport function ceil(n, decimals) {\n  return Math.ceil(toFixed(n, decimals));\n}\n","import {\n\tSetCursor,\n\tTerraDrawCallbacks,\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n} from \"../common\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\nimport MapView from \"@arcgis/core/views/MapView\";\nimport Point from \"@arcgis/core/geometry/Point\";\nimport Polyline from \"@arcgis/core/geometry/Polyline\";\nimport Polygon from \"@arcgis/core/geometry/Polygon\";\nimport GraphicsLayer from \"@arcgis/core/layers/GraphicsLayer\";\nimport Graphic from \"@arcgis/core/Graphic\";\nimport SimpleMarkerSymbol from \"@arcgis/core/symbols/SimpleMarkerSymbol\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\nimport Symbol from \"@arcgis/core/symbols/Symbol\";\nimport SimpleLineSymbol from \"@arcgis/core/symbols/SimpleLineSymbol\";\nimport SimpleFillSymbol from \"@arcgis/core/symbols/SimpleFillSymbol\";\nimport Color from \"@arcgis/core/Color\";\nimport Geometry from \"@arcgis/core/geometry/Geometry\";\n\ntype InjectableArcGISMapsSDK = {\n\tGraphicsLayer: typeof GraphicsLayer;\n\tPoint: typeof Point;\n\tPolyline: typeof Polyline;\n\tPolygon: typeof Polygon;\n\tSimpleLineSymbol: typeof SimpleLineSymbol;\n\tSimpleMarkerSymbol: typeof SimpleMarkerSymbol;\n\tSimpleFillSymbol: typeof SimpleFillSymbol;\n\tGraphic: typeof Graphic;\n\tColor: typeof Color;\n};\n\nexport class TerraDrawArcGISMapsSDKAdapter extends TerraDrawBaseAdapter {\n\tprivate readonly _lib: InjectableArcGISMapsSDK;\n\tprivate readonly _mapView: MapView;\n\tprivate readonly _container: HTMLElement;\n\tprivate readonly _featureIdAttributeName = \"__tdId\";\n\tprivate readonly _featureLayerName = \"__terraDrawFeatures\";\n\tprivate readonly _featureLayer: GraphicsLayer;\n\n\tprivate _dragEnabled = true;\n\tprivate _zoomEnabled = true;\n\tprivate _dragHandler: undefined | IHandle;\n\tprivate _doubleClickHandler: undefined | IHandle;\n\n\tconstructor(\n\t\tconfig: {\n\t\t\tmap: MapView;\n\t\t\tlib: InjectableArcGISMapsSDK;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._mapView = config.map;\n\t\tthis._lib = config.lib;\n\t\tthis._container = this._mapView.container;\n\t\tthis._featureLayer = new this._lib.GraphicsLayer({\n\t\t\tid: this._featureLayerName,\n\t\t});\n\n\t\tthis._mapView.map.add(this._featureLayer);\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\tthis._dragHandler = this._mapView.on(\"drag\", (event) => {\n\t\t\tif (!this._dragEnabled) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t});\n\t\tthis._doubleClickHandler = this._mapView.on(\"double-click\", (event) => {\n\t\t\tif (!this._zoomEnabled) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t});\n\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic unregister() {\n\t\tsuper.unregister();\n\n\t\tif (this._dragHandler) {\n\t\t\tthis._dragHandler.remove();\n\t\t}\n\n\t\tif (this._doubleClickHandler) {\n\t\t\tthis._doubleClickHandler.remove();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\t\treturn this.unproject(x, y);\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the ArcGIS element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._container.querySelector(\".esri-view-surface\") as HTMLElement;\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis._dragEnabled = enabled;\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst point = new this._lib.Point({ longitude: lng, latitude: lat });\n\t\tconst { x, y } = this._mapView.toScreen(point);\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { latitude, longitude } = this._mapView.toMap({ x, y });\n\t\treturn { lng: longitude, lat: latitude };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis._zoomEnabled = enabled;\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tchanges.created.forEach((createdFeature) => {\n\t\t\tthis.addFeature(createdFeature, styling);\n\t\t});\n\n\t\tchanges.updated.forEach((updatedFeature) => {\n\t\t\tthis.removeFeatureById(updatedFeature.id);\n\t\t\tthis.addFeature(updatedFeature, styling);\n\t\t});\n\n\t\tchanges.deletedIds.forEach((deletedId) => {\n\t\t\tthis.removeFeatureById(deletedId);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tthis._featureLayer.graphics.removeAll();\n\t}\n\n\tprivate removeFeatureById(id: string | number | undefined) {\n\t\tconst feature = this._featureLayer.graphics.find(\n\t\t\t(g) => g.attributes[this._featureIdAttributeName] === id,\n\t\t);\n\t\tthis._featureLayer.remove(feature);\n\t}\n\n\tprivate addFeature(\n\t\tfeature: GeoJSONStoreFeatures,\n\t\tstyling: TerraDrawStylingFunction,\n\t) {\n\t\tconst { coordinates, type } = feature.geometry;\n\t\tconst style = styling[feature.properties.mode as string](feature);\n\n\t\tlet symbol: Symbol | undefined = undefined; // eslint-disable-line @typescript-eslint/ban-types\n\t\tlet geometry: Geometry | undefined = undefined;\n\n\t\tswitch (type) {\n\t\t\tcase \"Point\":\n\t\t\t\tgeometry = new this._lib.Point({\n\t\t\t\t\tlatitude: coordinates[1],\n\t\t\t\t\tlongitude: coordinates[0],\n\t\t\t\t});\n\t\t\t\tsymbol = new this._lib.SimpleMarkerSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(style.pointColor),\n\t\t\t\t\tsize: style.pointWidth * 2 + \"px\",\n\t\t\t\t\toutline: {\n\t\t\t\t\t\tcolor: this.getColorFromHex(style.pointOutlineColor),\n\t\t\t\t\t\twidth: style.pointOutlineWidth + \"px\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"LineString\":\n\t\t\t\tgeometry = new this._lib.Polyline({ paths: [coordinates] });\n\t\t\t\tsymbol = new this._lib.SimpleLineSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(style.lineStringColor),\n\t\t\t\t\twidth: style.lineStringWidth + \"px\",\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"Polygon\":\n\t\t\t\tgeometry = new this._lib.Polygon({ rings: coordinates });\n\t\t\t\tsymbol = new this._lib.SimpleFillSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(\n\t\t\t\t\t\tstyle.polygonFillColor,\n\t\t\t\t\t\tstyle.polygonFillOpacity,\n\t\t\t\t\t),\n\t\t\t\t\toutline: {\n\t\t\t\t\t\tcolor: this.getColorFromHex(style.polygonOutlineColor),\n\t\t\t\t\t\twidth: style.polygonOutlineWidth + \"px\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst graphic = new this._lib.Graphic({\n\t\t\tgeometry,\n\t\t\tsymbol,\n\t\t\tattributes: { [this._featureIdAttributeName]: feature.id },\n\t\t});\n\n\t\t// ensure we add points at the topmost position by adding other geometries at index 0\n\t\tif (type === \"Point\") {\n\t\t\tthis._featureLayer.graphics.add(graphic);\n\t\t} else {\n\t\t\tthis._featureLayer.graphics.add(graphic, 0);\n\t\t}\n\t}\n\n\tprivate getColorFromHex(hexColor: string, opacity?: number): Color {\n\t\tconst color = this._lib.Color.fromHex(hexColor);\n\t\tif (opacity) {\n\t\t\tcolor.a = opacity;\n\t\t}\n\t\treturn color;\n\t}\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport {\n\tHexColor,\n\tOnFinishContext,\n\tProjection,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawModeRegisterConfig,\n\tTerraDrawModeState,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n\tValidation,\n} from \"../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tStoreChangeHandler,\n} from \"../store/store\";\nimport { isValidStoreFeature } from \"../store/store-feature-validation\";\n\nexport type CustomStyling = Record<\n\tstring,\n\t| string\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => HexColor)\n\t| ((feature: GeoJSONStoreFeatures) => number)\n>;\n\nexport enum ModeTypes {\n\tDrawing = \"drawing\",\n\tSelect = \"select\",\n\tStatic = \"static\",\n\tRender = \"render\",\n}\n\nexport type BaseModeOptions<T extends CustomStyling> = {\n\tstyles?: Partial<T>;\n\tpointerDistance?: number;\n\tvalidation?: Validation;\n\tprojection?: Projection;\n};\n\nexport abstract class TerraDrawBaseDrawMode<T extends CustomStyling> {\n\tprotected _state: TerraDrawModeState;\n\tget state() {\n\t\treturn this._state;\n\t}\n\tset state(_) {\n\t\tthrow new Error(\"Please use the modes lifecycle methods\");\n\t}\n\n\tprotected _styles: Partial<T>;\n\n\tget styles(): Partial<T> {\n\t\treturn this._styles;\n\t}\n\tset styles(styling: Partial<T>) {\n\t\tif (typeof styling !== \"object\") {\n\t\t\tthrow new Error(\"Styling must be an object\");\n\t\t}\n\t\tthis.onStyleChange([], \"styling\");\n\t\tthis._styles = styling;\n\t}\n\n\tprotected behaviors: TerraDrawModeBehavior[] = [];\n\tprotected validate: Validation | undefined;\n\tprotected pointerDistance: number;\n\tprotected coordinatePrecision!: number;\n\tprotected onStyleChange!: StoreChangeHandler;\n\tprotected store!: GeoJSONStore;\n\tprotected setDoubleClickToZoom!: TerraDrawModeRegisterConfig[\"setDoubleClickToZoom\"];\n\tprotected unproject!: TerraDrawModeRegisterConfig[\"unproject\"];\n\tprotected project!: TerraDrawModeRegisterConfig[\"project\"];\n\tprotected setCursor!: TerraDrawModeRegisterConfig[\"setCursor\"];\n\tprotected registerBehaviors(behaviorConfig: BehaviorConfig): void {}\n\tprotected projection!: Projection;\n\n\tconstructor(options?: BaseModeOptions<T>) {\n\t\tthis._state = \"unregistered\";\n\t\tthis._styles =\n\t\t\toptions && options.styles ? { ...options.styles } : ({} as Partial<T>);\n\t\tthis.pointerDistance = (options && options.pointerDistance) || 40;\n\n\t\tthis.validate = options && options.validation;\n\n\t\tthis.projection = (options && options.projection) || \"web-mercator\";\n\t}\n\n\ttype = ModeTypes.Drawing;\n\tmode = \"base\";\n\n\tprotected setDrawing() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"drawing\";\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStarted() {\n\t\tif (\n\t\t\tthis._state === \"stopped\" ||\n\t\t\tthis._state === \"registered\" ||\n\t\t\tthis._state === \"drawing\" ||\n\t\t\tthis._state === \"selecting\"\n\t\t) {\n\t\t\tthis._state = \"started\";\n\t\t\tthis.setDoubleClickToZoom(false);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStopped() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"stopped\";\n\t\t\tthis.setDoubleClickToZoom(true);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be started to be stopped\");\n\t\t}\n\t}\n\n\tregister(config: TerraDrawModeRegisterConfig) {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthis._state = \"registered\";\n\t\t\tthis.store = config.store;\n\t\t\tthis.store.registerOnChange(config.onChange);\n\t\t\tthis.setDoubleClickToZoom = config.setDoubleClickToZoom;\n\t\t\tthis.project = config.project;\n\t\t\tthis.unproject = config.unproject;\n\t\t\tthis.onSelect = config.onSelect;\n\t\t\tthis.onDeselect = config.onDeselect;\n\t\t\tthis.setCursor = config.setCursor;\n\t\t\tthis.onStyleChange = config.onChange;\n\t\t\tthis.onFinish = config.onFinish;\n\t\t\tthis.coordinatePrecision = config.coordinatePrecision;\n\n\t\t\tthis.registerBehaviors({\n\t\t\t\tmode: config.mode,\n\t\t\t\tstore: this.store,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tpointerDistance: this.pointerDistance,\n\t\t\t\tcoordinatePrecision: config.coordinatePrecision,\n\t\t\t\tprojection: this.projection,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(\"Can not register unless mode is unregistered\");\n\t\t}\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthrow new Error(\"Mode must be registered\");\n\t\t}\n\n\t\tconst validStoreFeature = isValidStoreFeature(\n\t\t\tfeature,\n\t\t\tthis.store.idStrategy.isValidId,\n\t\t);\n\n\t\t// We also want tp validate based on any specific valdiations passed in\n\t\tif (this.validate) {\n\t\t\treturn this.validate(feature as GeoJSONStoreFeatures, {\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t});\n\t\t}\n\n\t\treturn validStoreFeature;\n\t}\n\n\tabstract start(): void;\n\tabstract stop(): void;\n\tabstract cleanUp(): void;\n\tabstract styleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling;\n\n\tonFinish(finishedId: FeatureId, context: OnFinishContext) {}\n\tonDeselect(deselectedId: FeatureId) {}\n\tonSelect(selectedId: FeatureId) {}\n\tonKeyDown(event: TerraDrawKeyboardEvent) {}\n\tonKeyUp(event: TerraDrawKeyboardEvent) {}\n\tonMouseMove(event: TerraDrawMouseEvent) {}\n\tonClick(event: TerraDrawMouseEvent) {}\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\n\tprotected getHexColorStylingValue(\n\t\tvalue: HexColor | ((feature: GeoJSONStoreFeatures) => HexColor) | undefined,\n\t\tdefaultValue: HexColor,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): HexColor {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprotected getNumericStylingValue(\n\t\tvalue: number | ((feature: GeoJSONStoreFeatures) => number) | undefined,\n\t\tdefaultValue: number,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): number {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprivate getStylingValue<T extends string | number>(\n\t\tvalue: T | ((feature: GeoJSONStoreFeatures) => T) | undefined,\n\t\tdefaultValue: T,\n\t\tfeature: GeoJSONStoreFeatures,\n\t) {\n\t\tif (value === undefined) {\n\t\t\treturn defaultValue;\n\t\t} else if (typeof value === \"function\") {\n\t\t\treturn value(feature);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t}\n}\n\nexport abstract class TerraDrawBaseSelectMode<\n\tT extends CustomStyling,\n> extends TerraDrawBaseDrawMode<T> {\n\tpublic type = ModeTypes.Select;\n\n\tpublic abstract selectFeature(featureId: FeatureId): void;\n\tpublic abstract deselectFeature(featureId: FeatureId): void;\n}\n","import { FeatureId, GeoJSONStoreFeatures, IdStrategy } from \"./store\";\n\nexport const StoreValidationErrors = {\n\tFeatureHasNoId: \"Feature has no id\",\n\tFeatureIsNotObject: \"Feature is not object\",\n\tInvalidTrackedProperties: \"updatedAt and createdAt are not valid timestamps\",\n\tFeatureHasNoMode: \"Feature does not have a set mode\",\n\tFeatureIdIsNotValidGeoJSON: `Feature must be string or number as per GeoJSON spec`,\n\tFeatureIdIsNotValid: `Feature must match the id strategy (default is UUID4)`,\n\tFeatureHasNoGeometry: \"Feature has no geometry\",\n\tFeatureHasNoProperties: \"Feature has no properties\",\n\tFeatureGeometryNotSupported: \"Feature is not Point, LineString or Polygon\",\n\tFeatureCoordinatesNotAnArray: \"Feature coordinates is not an array\",\n\tInvalidModeProperty: \"Feature does not have a valid mode property\",\n} as const;\n\nfunction isObject(\n\tfeature: unknown,\n): feature is Record<string | number, unknown> {\n\treturn Boolean(\n\t\tfeature &&\n\t\t\ttypeof feature === \"object\" &&\n\t\t\tfeature !== null &&\n\t\t\t!Array.isArray(feature),\n\t);\n}\n\nfunction dateIsValid(timestamp: unknown): boolean {\n\treturn (\n\t\ttypeof timestamp === \"number\" &&\n\t\t!isNaN(new Date(timestamp as number).valueOf())\n\t);\n}\n\nexport function isValidTimestamp(timestamp: unknown): boolean {\n\tif (!dateIsValid(timestamp)) {\n\t\tthrow new Error(StoreValidationErrors.InvalidTrackedProperties);\n\t}\n\n\treturn true;\n}\n\nexport function isValidStoreFeature(\n\tfeature: unknown,\n\tisValidId: IdStrategy<FeatureId>[\"isValidId\"],\n): feature is GeoJSONStoreFeatures {\n\tlet error;\n\tif (!isObject(feature)) {\n\t\terror = StoreValidationErrors.FeatureIsNotObject;\n\t} else if (feature.id === null || feature.id === undefined) {\n\t\terror = StoreValidationErrors.FeatureHasNoId;\n\t} else if (typeof feature.id !== \"string\" && typeof feature.id !== \"number\") {\n\t\terror = StoreValidationErrors.FeatureIdIsNotValidGeoJSON;\n\t} else if (!isValidId(feature.id)) {\n\t\terror = StoreValidationErrors.FeatureIdIsNotValid;\n\t} else if (!isObject(feature.geometry)) {\n\t\terror = StoreValidationErrors.FeatureHasNoGeometry;\n\t} else if (!isObject(feature.properties)) {\n\t\terror = StoreValidationErrors.FeatureHasNoProperties;\n\t} else if (\n\t\ttypeof feature.geometry.type !== \"string\" ||\n\t\t![\"Polygon\", \"LineString\", \"Point\"].includes(feature.geometry.type)\n\t) {\n\t\terror = StoreValidationErrors.FeatureGeometryNotSupported;\n\t} else if (!Array.isArray(feature.geometry.coordinates)) {\n\t\terror = StoreValidationErrors.FeatureCoordinatesNotAnArray;\n\t} else if (\n\t\t!feature.properties.mode ||\n\t\ttypeof feature.properties.mode !== \"string\"\n\t) {\n\t\tthrow new Error(StoreValidationErrors.InvalidModeProperty);\n\t}\n\n\tif (error) {\n\t\tthrow new Error(error);\n\t}\n\n\treturn true;\n}\n","import { Position } from \"geojson\";\n\nexport function haversineDistanceKilometers(\n\tpointOne: Position,\n\tpointTwo: Position,\n) {\n\tconst toRadians = (latOrLng: number) => (latOrLng * Math.PI) / 180;\n\n\tconst phiOne = toRadians(pointOne[1]);\n\tconst lambdaOne = toRadians(pointOne[0]);\n\tconst phiTwo = toRadians(pointTwo[1]);\n\tconst lambdaTwo = toRadians(pointTwo[0]);\n\tconst deltaPhi = phiTwo - phiOne;\n\tconst deltalambda = lambdaTwo - lambdaOne;\n\n\tconst a =\n\t\tMath.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +\n\t\tMath.cos(phiOne) *\n\t\t\tMath.cos(phiTwo) *\n\t\t\tMath.sin(deltalambda / 2) *\n\t\t\tMath.sin(deltalambda / 2);\n\tconst c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n\tconst radius = 6371e3;\n\tconst distance = radius * c;\n\n\treturn distance / 1000;\n}\n","export const earthRadius = 6371008.8;\n\nexport function degreesToRadians(degrees: number): number {\n\tconst radians = degrees % 360;\n\treturn (radians * Math.PI) / 180;\n}\n\nexport function lengthToRadians(distance: number): number {\n\tconst factor = earthRadius / 1000;\n\treturn distance / factor;\n}\n\nexport function radiansToDegrees(radians: number): number {\n\tconst degrees = radians % (2 * Math.PI);\n\treturn (degrees * 180) / Math.PI;\n}\n","const RADIANS_TO_DEGREES = 57.29577951308232 as const; // 180 / Math.PI\nconst DEGREES_TO_RADIANS = 0.017453292519943295 as const; // Math.PI / 180\nconst R = 6378137 as const;\n\n/**\n * Convert longitude and latitude to web mercator x and y\n * @param lng\n * @param lat\n * @returns - web mercator x and y\n */\nexport const lngLatToWebMercatorXY = (\n\tlng: number,\n\tlat: number,\n): { x: number; y: number } => ({\n\tx: lng === 0 ? 0 : lng * DEGREES_TO_RADIANS * R,\n\ty:\n\t\tlat === 0\n\t\t\t? 0\n\t\t\t: Math.log(Math.tan(Math.PI / 4 + (lat * DEGREES_TO_RADIANS) / 2)) * R,\n});\n\n/**\n * Convert web mercator x and y to longitude and latitude\n * @param x - web mercator x\n * @param y - web mercator y\n * @returns - longitude and latitude\n */\nexport const webMercatorXYToLngLat = (\n\tx: number,\n\ty: number,\n): { lng: number; lat: number } => ({\n\tlng: x === 0 ? 0 : RADIANS_TO_DEGREES * (x / R),\n\tlat:\n\t\ty === 0\n\t\t\t? 0\n\t\t\t: (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) * RADIANS_TO_DEGREES,\n});\n","import { Feature, Polygon, Position } from \"geojson\";\nimport {\n\tdegreesToRadians,\n\tlengthToRadians,\n\tradiansToDegrees,\n} from \"../helpers\";\nimport { limitPrecision } from \"../limit-decimal-precision\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\n\n// Adapted from the @turf/circle module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-circle/index.ts\n\nfunction destination(\n\torigin: Position,\n\tdistance: number,\n\tbearing: number,\n): Position {\n\tconst longitude1 = degreesToRadians(origin[0]);\n\tconst latitude1 = degreesToRadians(origin[1]);\n\tconst bearingRad = degreesToRadians(bearing);\n\tconst radians = lengthToRadians(distance);\n\n\t// Main\n\tconst latitude2 = Math.asin(\n\t\tMath.sin(latitude1) * Math.cos(radians) +\n\t\t\tMath.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad),\n\t);\n\tconst longitude2 =\n\t\tlongitude1 +\n\t\tMath.atan2(\n\t\t\tMath.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n\t\t\tMath.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2),\n\t\t);\n\tconst lng = radiansToDegrees(longitude2);\n\tconst lat = radiansToDegrees(latitude2);\n\n\treturn [lng, lat];\n}\n\nexport function circle(options: {\n\tcenter: Position;\n\tradiusKilometers: number;\n\tcoordinatePrecision: number;\n\tsteps?: number;\n}): Feature<Polygon> {\n\tconst { center, radiusKilometers, coordinatePrecision } = options;\n\tconst steps = options.steps ? options.steps : 64;\n\n\tconst coordinates: Position[] = [];\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst circleCoordinate = destination(\n\t\t\tcenter,\n\t\t\tradiusKilometers,\n\t\t\t(i * -360) / steps,\n\t\t);\n\n\t\tcoordinates.push([\n\t\t\tlimitPrecision(circleCoordinate[0], coordinatePrecision),\n\t\t\tlimitPrecision(circleCoordinate[1], coordinatePrecision),\n\t\t]);\n\t}\n\tcoordinates.push(coordinates[0]);\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: { type: \"Polygon\", coordinates: [coordinates] },\n\t\tproperties: {},\n\t};\n}\n\nexport function circleWebMercator(options: {\n\tcenter: Position;\n\tradiusKilometers: number;\n\tcoordinatePrecision: number;\n\tsteps?: number;\n}): GeoJSON.Feature<GeoJSON.Polygon> {\n\tconst { center, radiusKilometers, coordinatePrecision } = options;\n\tconst steps = options.steps ? options.steps : 64;\n\n\tconst radiusMeters = radiusKilometers * 1000;\n\n\tconst [lng, lat] = center;\n\tconst { x, y } = lngLatToWebMercatorXY(lng, lat);\n\n\tconst coordinates: Position[] = [];\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst angle = (((i * 360) / steps) * Math.PI) / 180;\n\t\tconst dx = radiusMeters * Math.cos(angle);\n\t\tconst dy = radiusMeters * Math.sin(angle);\n\t\tconst [wx, wy] = [x + dx, y + dy];\n\t\tconst { lng, lat } = webMercatorXYToLngLat(wx, wy);\n\t\tcoordinates.push([\n\t\t\tlimitPrecision(lng, coordinatePrecision),\n\t\t\tlimitPrecision(lat, coordinatePrecision),\n\t\t]);\n\t}\n\n\t// Close the circle by adding the first point at the end\n\tcoordinates.push(coordinates[0]);\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: { type: \"Polygon\", coordinates: [coordinates] },\n\t\tproperties: {},\n\t};\n}\n","// Based on - https://github.com/mclaeysb/geojson-polygon-self-intersections\n// MIT License - Copyright (c) 2016 Manuel Claeys Bouuaert\n\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\n// import * as rbush from \"rbush\";\n\ntype SelfIntersectsOptions = {\n\tepsilon: number;\n\t// reportVertexOnVertex: boolean;\n\t// reportVertexOnEdge: boolean;\n};\n\nexport function selfIntersects(\n\tfeature: Feature<Polygon> | Feature<LineString>,\n): boolean {\n\tconst options: SelfIntersectsOptions = {\n\t\tepsilon: 0,\n\t\t// reportVertexOnVertex: false,\n\t\t// reportVertexOnEdge: false,\n\t};\n\n\tlet coord: number[][][];\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\tcoord = feature.geometry.coordinates;\n\t} else if (feature.geometry.type === \"LineString\") {\n\t\tcoord = [feature.geometry.coordinates];\n\t} else {\n\t\tthrow new Error(\"Self intersects only accepts Polygons and LineStrings\");\n\t}\n\n\tconst output: number[][] = [];\n\tconst seen: { [key: string]: boolean } = {};\n\n\tfor (let ring0 = 0; ring0 < coord.length; ring0++) {\n\t\tfor (let edge0 = 0; edge0 < coord[ring0].length - 1; edge0++) {\n\t\t\tfor (let ring1 = 0; ring1 < coord.length; ring1++) {\n\t\t\t\tfor (let edge1 = 0; edge1 < coord[ring1].length - 1; edge1++) {\n\t\t\t\t\t// speedup possible if only interested in unique: start last two loops at ring0 and edge0+1\n\t\t\t\t\tifInteresctionAddToOutput(ring0, edge0, ring1, edge1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn output.length > 0;\n\n\t// true if frac is (almost) 1.0 or 0.0\n\t// function isBoundaryCase(frac: number) {\n\t//   const e2 = options.epsilon * options.epsilon;\n\t//   return e2 >= (frac - 1) * (frac - 1) || e2 >= frac * frac;\n\t// }\n\n\tfunction isOutside(frac: number) {\n\t\treturn frac < 0 - options.epsilon || frac > 1 + options.epsilon;\n\t}\n\t// Function to check if two edges intersect and add the intersection to the output\n\tfunction ifInteresctionAddToOutput(\n\t\tring0: number,\n\t\tedge0: number,\n\t\tring1: number,\n\t\tedge1: number,\n\t) {\n\t\tconst start0 = coord[ring0][edge0];\n\t\tconst end0 = coord[ring0][edge0 + 1];\n\t\tconst start1 = coord[ring1][edge1];\n\t\tconst end1 = coord[ring1][edge1 + 1];\n\n\t\tconst intersection = intersect(start0, end0, start1, end1);\n\n\t\tif (intersection === null) {\n\t\t\treturn; // discard parallels and coincidence\n\t\t}\n\n\t\tlet frac0;\n\t\tlet frac1;\n\n\t\tif (end0[0] !== start0[0]) {\n\t\t\tfrac0 = (intersection[0] - start0[0]) / (end0[0] - start0[0]);\n\t\t} else {\n\t\t\tfrac0 = (intersection[1] - start0[1]) / (end0[1] - start0[1]);\n\t\t}\n\t\tif (end1[0] !== start1[0]) {\n\t\t\tfrac1 = (intersection[0] - start1[0]) / (end1[0] - start1[0]);\n\t\t} else {\n\t\t\tfrac1 = (intersection[1] - start1[1]) / (end1[1] - start1[1]);\n\t\t}\n\n\t\t// There are roughly three cases we need to deal with.\n\t\t// 1. If at least one of the fracs lies outside [0,1], there is no intersection.\n\t\tif (isOutside(frac0) || isOutside(frac1)) {\n\t\t\treturn; // require segment intersection\n\t\t}\n\n\t\t// 2. If both are either exactly 0 or exactly 1, this is not an intersection but just\n\t\t// two edge segments sharing a common vertex.\n\t\t// if (isBoundaryCase(frac0) && isBoundaryCase(frac1)) {\n\t\t//   if (!options.reportVertexOnVertex) {\n\t\t//     return;\n\t\t//   }\n\t\t// }\n\n\t\t// // 3. If only one of the fractions is exactly 0 or 1, this is\n\t\t// // a vertex-on-edge situation.\n\t\t// if (isBoundaryCase(frac0) || isBoundaryCase(frac1)) {\n\t\t//   if (!options.reportVertexOnEdge) {\n\t\t//     return;\n\t\t//   }\n\t\t// }\n\n\t\tconst key = intersection.toString();\n\t\tconst unique = !seen[key];\n\t\tif (unique) {\n\t\t\tseen[key] = true;\n\t\t}\n\n\t\toutput.push(intersection);\n\t}\n}\n\nfunction equalArrays(array1: Position, array2: Position) {\n\treturn array1[0] === array2[0] && array1[1] === array2[1];\n}\n\n// Function to compute where two lines (not segments) intersect. From https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection\nfunction intersect(\n\tstart0: Position,\n\tend0: Position,\n\tstart1: Position,\n\tend1: Position,\n) {\n\tif (\n\t\tequalArrays(start0, start1) ||\n\t\tequalArrays(start0, end1) ||\n\t\tequalArrays(end0, start1) ||\n\t\tequalArrays(end1, start1)\n\t) {\n\t\treturn null;\n\t}\n\n\tconst x0 = start0[0],\n\t\ty0 = start0[1],\n\t\tx1 = end0[0],\n\t\ty1 = end0[1],\n\t\tx2 = start1[0],\n\t\ty2 = start1[1],\n\t\tx3 = end1[0],\n\t\ty3 = end1[1];\n\n\tconst denom = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3);\n\tif (denom === 0) {\n\t\treturn null;\n\t}\n\n\tconst x4 =\n\t\t((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denom;\n\n\tconst y4 =\n\t\t((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denom;\n\n\treturn [x4, y4];\n}\n","export function validLatitude(lat: number) {\n\treturn lat >= -90 && lat <= 90;\n}\n\nexport function validLongitude(lng: number) {\n\treturn lng >= -180 && lng <= 180;\n}\n\nexport function coordinateIsValid(\n\tcoordinate: unknown[],\n\tcoordinatePrecision: number,\n) {\n\treturn (\n\t\tcoordinate.length === 2 &&\n\t\ttypeof coordinate[0] === \"number\" &&\n\t\ttypeof coordinate[1] === \"number\" &&\n\t\tcoordinate[0] !== Infinity &&\n\t\tcoordinate[1] !== Infinity &&\n\t\tvalidLongitude(coordinate[0]) &&\n\t\tvalidLatitude(coordinate[1]) &&\n\t\tgetDecimalPlaces(coordinate[0]) <= coordinatePrecision &&\n\t\tgetDecimalPlaces(coordinate[1]) <= coordinatePrecision\n\t);\n}\n\nexport function getDecimalPlaces(value: number): number {\n\tlet current = 1;\n\tlet precision = 0;\n\twhile (Math.round(value * current) / current !== value) {\n\t\tcurrent *= 10;\n\t\tprecision++;\n\t}\n\n\treturn precision;\n}\n","import { Feature, Polygon, Position } from \"geojson\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { selfIntersects } from \"../geometry/boolean/self-intersects\";\nimport { coordinateIsValid } from \"./../geometry/boolean/is-valid-coordinate\";\n\nfunction coordinatesMatch(coordinateOne: Position, coordinateTwo: Position) {\n\treturn (\n\t\tcoordinateOne[0] === coordinateTwo[0] &&\n\t\tcoordinateOne[1] === coordinateTwo[1]\n\t);\n}\n\nexport function ValidatePolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"Polygon\" &&\n\t\tfeature.geometry.coordinates.length === 1 && // No hole support\n\t\tfeature.geometry.coordinates[0].length >= 4 &&\n\t\tfeature.geometry.coordinates[0].every((coordinate) =>\n\t\t\tcoordinateIsValid(coordinate, coordinatePrecision),\n\t\t) &&\n\t\tcoordinatesMatch(\n\t\t\tfeature.geometry.coordinates[0][0],\n\t\t\tfeature.geometry.coordinates[0][\n\t\t\t\tfeature.geometry.coordinates[0].length - 1\n\t\t\t],\n\t\t)\n\t);\n}\n\nexport function ValidateNonIntersectingPolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tValidatePolygonFeature(feature, coordinatePrecision) &&\n\t\t!selfIntersects(feature as Feature<Polygon>)\n\t);\n}\n","import { Feature, Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tProjection,\n} from \"../../common\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { circle, circleWebMercator } from \"../../geometry/shape/create-circle\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { Polygon } from \"geojson\";\nimport { calculateWebMercatorDistortion } from \"../../geometry/shape/web-mercator-distortion\";\n\ntype TerraDrawCircleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype CirclePolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\ninterface TerraDrawCircleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawCircleModeKeyEvents | null;\n\tcursors?: Cursors;\n\tstartingRadiusKilometers?: number;\n\tprojection?: Projection;\n}\n\nexport class TerraDrawCircleMode extends TerraDrawBaseDrawMode<CirclePolygonStyling> {\n\tmode = \"circle\";\n\tprivate center: Position | undefined;\n\tprivate clickCount = 0;\n\tprivate currentCircleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawCircleModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\tprivate startingRadiusKilometers = 0.00001;\n\n\t/**\n\t * Create a new circle mode instance\n\t * @param options - Options to customize the behavior of the circle mode\n\t * @param options.keyEvents - Key events to cancel or finish the mode\n\t * @param options.cursors - Cursors to use for the mode\n\t * @param options.styles - Custom styling for the circle\n\t * @param options.pointerDistance - Distance in pixels to consider a pointer close to a vertex\n\t */\n\tconstructor(options?: TerraDrawCircleModeOptions<CirclePolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.startingRadiusKilometers =\n\t\t\toptions?.startingRadiusKilometers ?? 0.00001;\n\t\tthis.validate = options?.validation;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentCircleId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentCircleId;\n\n\t\tif (this.validate && finishedId) {\n\t\t\tconst currentGeometry = this.store.getGeometryCopy<Polygon>(finishedId);\n\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tid: finishedId,\n\t\t\t\t\tgeometry: currentGeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.clickCount = 0;\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (this.clickCount === 0) {\n\t\t\tthis.center = [event.lng, event.lat];\n\t\t\tconst startingCircle = circle({\n\t\t\t\tcenter: this.center,\n\t\t\t\tradiusKilometers: this.startingRadiusKilometers,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t});\n\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: startingCircle.geometry,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\tradiusKilometers: this.startingRadiusKilometers,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentCircleId = createdId;\n\t\t\tthis.clickCount++;\n\t\t\tthis.setDrawing();\n\t\t} else {\n\t\t\tif (\n\t\t\t\tthis.clickCount === 1 &&\n\t\t\t\tthis.center &&\n\t\t\t\tthis.currentCircleId !== undefined\n\t\t\t) {\n\t\t\t\tthis.updateCircle(event);\n\t\t\t}\n\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.updateCircle(event);\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentCircleId;\n\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.clickCount = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\ttry {\n\t\t\tif (cleanUpId !== undefined) {\n\t\t\t\tthis.store.delete([cleanUpId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 10;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidateNonIntersectingPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate updateCircle(event: TerraDrawMouseEvent) {\n\t\tif (this.clickCount === 1 && this.center && this.currentCircleId) {\n\t\t\tconst newRadius = haversineDistanceKilometers(this.center, [\n\t\t\t\tevent.lng,\n\t\t\t\tevent.lat,\n\t\t\t]);\n\n\t\t\tlet updatedCircle: Feature<Polygon>;\n\n\t\t\tif (this.projection === \"web-mercator\") {\n\t\t\t\t// We want to track the mouse cursor, but we need to adjust the radius based\n\t\t\t\t// on the distortion of the web mercator projection\n\t\t\t\tconst distortion = calculateWebMercatorDistortion(this.center, [\n\t\t\t\t\tevent.lng,\n\t\t\t\t\tevent.lat,\n\t\t\t\t]);\n\n\t\t\t\tupdatedCircle = circleWebMercator({\n\t\t\t\t\tcenter: this.center,\n\t\t\t\t\tradiusKilometers: newRadius * distortion,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t});\n\t\t\t} else if (this.projection === \"globe\") {\n\t\t\t\tupdatedCircle = circle({\n\t\t\t\t\tcenter: this.center,\n\t\t\t\t\tradiusKilometers: newRadius,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid projection\");\n\t\t\t}\n\n\t\t\tif (this.validate) {\n\t\t\t\tconst valid = this.validate(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tid: this.currentCircleId,\n\t\t\t\t\t\tgeometry: updatedCircle.geometry,\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tradiusKilometers: newRadius,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.project,\n\t\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!valid) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{ id: this.currentCircleId, geometry: updatedCircle.geometry },\n\t\t\t]);\n\t\t\tthis.store.updateProperty([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentCircleId,\n\t\t\t\t\tproperty: \"radiusKilometers\",\n\t\t\t\t\tvalue: newRadius,\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n}\n","import { TerraDrawAdapterStyling } from \"../common\";\n\nexport const getDefaultStyling = (): TerraDrawAdapterStyling => {\n\treturn {\n\t\tpolygonFillColor: \"#3f97e0\",\n\t\tpolygonOutlineColor: \"#3f97e0\",\n\t\tpolygonOutlineWidth: 4,\n\t\tpolygonFillOpacity: 0.3,\n\t\tpointColor: \"#3f97e0\",\n\t\tpointOutlineColor: \"#ffffff\",\n\t\tpointOutlineWidth: 0,\n\t\tpointWidth: 6,\n\t\tlineStringColor: \"#3f97e0\",\n\t\tlineStringWidth: 4,\n\t\tzIndex: 0,\n\t};\n};\n","import { Position } from \"geojson\";\nimport { haversineDistanceKilometers } from \"../measure/haversine-distance\";\nimport { lngLatToWebMercatorXY } from \"../project/web-mercator\";\n\n/*\n * Function to calculate the web mercator vs geodesic distortion between two coordinates\n * Value of 1 means no distortion, higher values mean higher distortion\n * */\nexport function calculateWebMercatorDistortion(\n\tsource: Position,\n\ttarget: Position,\n): number {\n\tconst geodesicDistance = haversineDistanceKilometers(source, target) * 1000;\n\tif (geodesicDistance === 0) {\n\t\treturn 1;\n\t}\n\n\tconst { x: x1, y: y1 } = lngLatToWebMercatorXY(source[0], source[1]);\n\tconst { x: x2, y: y2 } = lngLatToWebMercatorXY(target[0], target[1]);\n\tconst euclideanDistance = Math.sqrt(\n\t\tMath.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2),\n\t);\n\treturn euclideanDistance / geodesicDistance;\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\n\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\n\ntype TerraDrawFreehandModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype FreehandPolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawFreehandModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tminDistance?: number;\n\tpreventPointsNearClose?: boolean;\n\tkeyEvents?: TerraDrawFreehandModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n\tmode = \"freehand\";\n\n\tprivate startingClick = false;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate minDistance: number;\n\tprivate keyEvents: TerraDrawFreehandModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\tprivate preventPointsNearClose: boolean;\n\n\tconstructor(options?: TerraDrawFreehandModeOptions<FreehandPolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.preventPointsNearClose =\n\t\t\t(options && options.preventPointsNearClose) || true;\n\n\t\tthis.minDistance = (options && options.minDistance) || 20;\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.validate = options?.validation;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentId;\n\n\t\tif (this.validate && finishedId) {\n\t\t\tconst currentGeometry = this.store.getGeometryCopy<Polygon>(finishedId);\n\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tid: finishedId,\n\t\t\t\t\tgeometry: currentGeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.closingPointId && this.store.delete([this.closingPointId]);\n\t\tthis.startingClick = false;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = undefined;\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tif (this.currentId === undefined || this.startingClick === false) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\tconst previousIndex = currentLineGeometry.coordinates[0].length - 2;\n\t\tconst [previousLng, previousLat] =\n\t\t\tcurrentLineGeometry.coordinates[0][previousIndex];\n\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tconst [closingLng, closingLat] = currentLineGeometry.coordinates[0][0];\n\t\tconst { x: closingX, y: closingY } = this.project(closingLng, closingLat);\n\t\tconst closingDistance = cartesianDistance(\n\t\t\t{ x: closingX, y: closingY },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tif (closingDistance < this.pointerDistance) {\n\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\t// We want to prohibit drawing new points at or around the closing\n\t\t\t// point as it can be non user friendly\n\t\t\tif (this.preventPointsNearClose) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t}\n\n\t\t// The cusor must have moved a minimum distance\n\t\t// before we add another coordinate\n\t\tif (distance < this.minDistance) {\n\t\t\treturn;\n\t\t}\n\n\t\tcurrentLineGeometry.coordinates[0].pop();\n\n\t\tconst newGeometry = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [\n\t\t\t\t[\n\t\t\t\t\t...currentLineGeometry.coordinates[0],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentLineGeometry.coordinates[0][0],\n\t\t\t\t],\n\t\t\t],\n\t\t} as Polygon;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tid: this.currentId,\n\t\t\t\t\tgeometry: newGeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: newGeometry,\n\t\t\t},\n\t\t]);\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (this.startingClick === false) {\n\t\t\tconst [createdId, closingPointId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tthis.currentId = createdId;\n\t\t\tthis.closingPointId = closingPointId;\n\t\t\tthis.startingClick = true;\n\t\t\tthis.setDrawing();\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.close();\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\t\tconst cleanUpClosingPointId = this.closingPointId;\n\n\t\tthis.closingPointId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.startingClick = false;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\ttry {\n\t\t\tif (cleanUpId !== undefined) {\n\t\t\t\tthis.store.delete([cleanUpId]);\n\t\t\t}\n\t\t\tif (cleanUpClosingPointId !== undefined) {\n\t\t\t\tthis.store.delete([cleanUpClosingPointId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 10;\n\n\t\t\treturn styles;\n\t\t} else if (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\n\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 40;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { Project, Projection, Unproject } from \"../common\";\nimport { GeoJSONStore } from \"../store/store\";\n\nexport type BehaviorConfig = {\n\tstore: GeoJSONStore;\n\tmode: string;\n\tproject: Project;\n\tunproject: Unproject;\n\tpointerDistance: number;\n\tcoordinatePrecision: number;\n\tprojection: Projection;\n};\n\nexport class TerraDrawModeBehavior {\n\tprotected store: GeoJSONStore;\n\tprotected mode: string;\n\tprotected project: Project;\n\tprotected unproject: Unproject;\n\tprotected pointerDistance: number;\n\tprotected coordinatePrecision: number;\n\tprotected projection: Projection;\n\n\tconstructor({\n\t\tstore,\n\t\tmode,\n\t\tproject,\n\t\tunproject,\n\t\tpointerDistance,\n\t\tcoordinatePrecision,\n\t\tprojection,\n\t}: BehaviorConfig) {\n\t\tthis.store = store;\n\t\tthis.mode = mode;\n\t\tthis.project = project;\n\t\tthis.unproject = unproject;\n\t\tthis.pointerDistance = pointerDistance;\n\t\tthis.coordinatePrecision = coordinatePrecision;\n\t\tthis.projection = projection;\n\t}\n}\n","import { Feature, Polygon } from \"geojson\";\nimport { Unproject } from \"../../common\";\n\nexport function createBBoxFromPoint({\n\tunproject,\n\tpoint,\n\tpointerDistance,\n}: {\n\tpoint: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tunproject: Unproject;\n\tpointerDistance: number;\n}) {\n\tconst halfDist = pointerDistance / 2;\n\tconst { x, y } = point;\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tproperties: {},\n\t\tgeometry: {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [\n\t\t\t\t[\n\t\t\t\t\tunproject(x - halfDist, y - halfDist), // TopLeft\n\t\t\t\t\tunproject(x + halfDist, y - halfDist), // TopRight\n\t\t\t\t\tunproject(x + halfDist, y + halfDist), // BottomRight\n\t\t\t\t\tunproject(x - halfDist, y + halfDist), // BottomLeft\n\t\t\t\t\tunproject(x - halfDist, y - halfDist), // TopLeft\n\t\t\t\t].map((c) => [c.lng, c.lat]),\n\t\t\t],\n\t\t},\n\t} as Feature<Polygon>;\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { createBBoxFromPoint } from \"../geometry/shape/create-bbox\";\n\nexport class ClickBoundingBoxBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tpublic create(event: TerraDrawMouseEvent) {\n\t\tconst { containerX: x, containerY: y } = event;\n\t\treturn createBBoxFromPoint({\n\t\t\tunproject: this.unproject,\n\t\t\tpoint: { x, y },\n\t\t\tpointerDistance: this.pointerDistance,\n\t\t});\n\t}\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\n\nimport { Position } from \"geojson\";\nimport { cartesianDistance } from \"../geometry/measure/pixel-distance\";\n\nexport class PixelDistanceBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\tpublic measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n\t\tconst { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: clickEvent.containerX, y: clickEvent.containerY },\n\t\t);\n\n\t\treturn distance;\n\t}\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { Feature, Position } from \"geojson\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { BBoxPolygon, FeatureId } from \"../store/store\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\n\nexport class SnappingBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly clickBoundingBox: ClickBoundingBoxBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\t/** Returns the nearest snappable coordinate - on first click there is no currentId so no need to provide */\n\tpublic getSnappableCoordinateFirstClick = (event: TerraDrawMouseEvent) => {\n\t\treturn this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties && feature.properties.mode === this.mode,\n\t\t\t);\n\t\t});\n\t};\n\n\tpublic getSnappableCoordinate = (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcurrentFeatureId: FeatureId,\n\t) => {\n\t\treturn this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties &&\n\t\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\t\tfeature.id !== currentFeatureId,\n\t\t\t);\n\t\t});\n\t};\n\n\tprivate getSnappable(\n\t\tevent: TerraDrawMouseEvent,\n\t\tfilter: (feature: Feature) => boolean,\n\t) {\n\t\tconst bbox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\n\t\tconst features = this.store.search(bbox, filter);\n\n\t\tconst closest: { coord: undefined | Position; minDist: number } = {\n\t\t\tcoord: undefined,\n\t\t\tminDist: Infinity,\n\t\t};\n\n\t\tfeatures.forEach((feature) => {\n\t\t\tlet coordinates: Position[];\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcoordinates.forEach((coord) => {\n\t\t\t\tconst dist = this.pixelDistance.measure(event, coord);\n\t\t\t\tif (dist < closest.minDist && dist < this.pointerDistance) {\n\t\t\t\t\tclosest.coord = coord;\n\t\t\t\t\tclosest.minDist = dist;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn closest.coord;\n\t}\n}\n","import { Position } from \"geojson\";\nimport {\n\tdegreesToRadians,\n\tlengthToRadians,\n\tradiansToDegrees,\n} from \"../helpers\";\n\n// Adapted from @turf/destination module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-desination/index.ts\n\nexport function destination(\n\torigin: Position,\n\tdistance: number,\n\tbearing: number,\n): Position {\n\tconst longitude1 = degreesToRadians(origin[0]);\n\tconst latitude1 = degreesToRadians(origin[1]);\n\tconst bearingRad = degreesToRadians(bearing);\n\tconst radians = lengthToRadians(distance);\n\n\tconst latitude2 = Math.asin(\n\t\tMath.sin(latitude1) * Math.cos(radians) +\n\t\t\tMath.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad),\n\t);\n\tconst longitude2 =\n\t\tlongitude1 +\n\t\tMath.atan2(\n\t\t\tMath.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n\t\t\tMath.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2),\n\t\t);\n\tconst lng = radiansToDegrees(longitude2);\n\tconst lat = radiansToDegrees(latitude2);\n\n\treturn [lng, lat];\n}\n\n// Function to create a destination point in Web Mercator projection\nexport function webMercatorDestination(\n\t{ x, y }: { x: number; y: number },\n\tdistance: number,\n\tbearing: number,\n): { x: number; y: number } {\n\t// Convert origin to Web Mercator\n\tconst bearingRad = degreesToRadians(bearing);\n\n\t// Calculate the destination coordinates\n\tconst deltaX = distance * Math.cos(bearingRad);\n\tconst deltaY = distance * Math.sin(bearingRad);\n\n\tconst newX = x + deltaX;\n\tconst newY = y + deltaY;\n\n\treturn { x: newX, y: newY };\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\n// Adapted from the @turf/bearing module which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-bearing\n\nexport function bearing(start: Position, end: Position): number {\n\tconst lon1 = degreesToRadians(start[0]);\n\tconst lon2 = degreesToRadians(end[0]);\n\tconst lat1 = degreesToRadians(start[1]);\n\tconst lat2 = degreesToRadians(end[1]);\n\tconst a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n\tconst b =\n\t\tMath.cos(lat1) * Math.sin(lat2) -\n\t\tMath.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n\treturn radiansToDegrees(Math.atan2(a, b));\n}\n\nexport function webMercatorBearing(\n\t{ x: x1, y: y1 }: { x: number; y: number },\n\t{ x: x2, y: y2 }: { x: number; y: number },\n): number {\n\tconst deltaX = x2 - x1;\n\tconst deltaY = y2 - y1;\n\n\t// Calculate the angle in radians\n\tlet angle = Math.atan2(deltaY, deltaX);\n\n\t// Convert the angle to degrees\n\tangle = angle * (180 / Math.PI);\n\n\t// Normalize to -180 to 180\n\tif (angle > 180) {\n\t\tangle -= 360;\n\t} else if (angle < -180) {\n\t\tangle += 360;\n\t}\n\n\treturn angle;\n}\n\nexport function normalizeBearing(bearing: number): number {\n\treturn (bearing + 360) % 360;\n}\n","import { LineString, Position } from \"geojson\";\nimport { destination } from \"./destination\";\nimport { bearing } from \"./bearing\";\nimport { haversineDistanceKilometers } from \"./haversine-distance\";\n\n// Adapted from @turf/line-slice-along module which is MIT licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-line-slice-along/index.ts\n\nexport function lineSliceAlong(\n\tcoords: LineString[\"coordinates\"],\n\tstartDist: number,\n\tstopDist: number,\n): Position[] {\n\tconst slice: Position[] = [];\n\n\tconst origCoordsLength = coords.length;\n\n\tlet travelled = 0;\n\tlet overshot, direction, interpolated;\n\tfor (let i = 0; i < coords.length; i++) {\n\t\tif (startDist >= travelled && i === coords.length - 1) {\n\t\t\tbreak;\n\t\t} else if (travelled > startDist && slice.length === 0) {\n\t\t\tovershot = startDist - travelled;\n\t\t\tif (!overshot) {\n\t\t\t\tslice.push(coords[i]);\n\t\t\t\treturn slice;\n\t\t\t}\n\t\t\tdirection = bearing(coords[i], coords[i - 1]) - 180;\n\t\t\tinterpolated = destination(coords[i], overshot, direction);\n\t\t\tslice.push(interpolated);\n\t\t}\n\n\t\tif (travelled >= stopDist) {\n\t\t\tovershot = stopDist - travelled;\n\t\t\tif (!overshot) {\n\t\t\t\tslice.push(coords[i]);\n\t\t\t\treturn slice;\n\t\t\t}\n\t\t\tdirection = bearing(coords[i], coords[i - 1]) - 180;\n\t\t\tinterpolated = destination(coords[i], overshot, direction);\n\t\t\tslice.push(interpolated);\n\t\t\treturn slice;\n\t\t}\n\n\t\tif (travelled >= startDist) {\n\t\t\tslice.push(coords[i]);\n\t\t}\n\n\t\tif (i === coords.length - 1) {\n\t\t\treturn slice;\n\t\t}\n\n\t\ttravelled += haversineDistanceKilometers(coords[i], coords[i + 1]);\n\t}\n\n\tif (travelled < startDist && coords.length === origCoordsLength) {\n\t\tthrow new Error(\"Start position is beyond line\");\n\t}\n\n\tconst last = coords[coords.length - 1];\n\treturn [last, last];\n}\n","import { Position } from \"geojson\";\n\nfunction toRadians(degrees: number): number {\n\treturn degrees * (Math.PI / 180);\n}\n\nfunction toDegrees(radians: number): number {\n\treturn radians * (180 / Math.PI);\n}\n\nexport function generateGreatCircleCoordinates(\n\tstart: Position,\n\tend: Position,\n\tnumberOfPoints: number,\n): Position[] {\n\tconst points: Position[] = [];\n\n\tconst lat1 = toRadians(start[1]);\n\tconst lon1 = toRadians(start[0]);\n\tconst lat2 = toRadians(end[1]);\n\tconst lon2 = toRadians(end[0]);\n\n\tnumberOfPoints += 1;\n\n\t// Calculate the angular distance between the two points using the Haversine formula\n\tconst d =\n\t\t2 *\n\t\tMath.asin(\n\t\t\tMath.sqrt(\n\t\t\t\tMath.sin((lat2 - lat1) / 2) ** 2 +\n\t\t\t\t\tMath.cos(lat1) * Math.cos(lat2) * Math.sin((lon2 - lon1) / 2) ** 2,\n\t\t\t),\n\t\t);\n\n\tif (d === 0 || isNaN(d)) {\n\t\t// Start and end coordinates are the same, or distance calculation failed, return empty array\n\t\treturn points;\n\t}\n\n\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\tconst f = i / numberOfPoints; // Fraction of the total distance for the current point\n\t\tconst A = Math.sin((1 - f) * d) / Math.sin(d); // Interpolation factor A\n\t\tconst B = Math.sin(f * d) / Math.sin(d); // Interpolation factor B\n\n\t\t// Calculate the x, y, z coordinates of the intermediate point\n\t\tconst x =\n\t\t\tA * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);\n\t\tconst y =\n\t\t\tA * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);\n\t\tconst z = A * Math.sin(lat1) + B * Math.sin(lat2);\n\n\t\t// Calculate the latitude and longitude of the intermediate point from the x, y, z coordinates\n\t\tif (isNaN(x) || isNaN(y) || isNaN(z)) {\n\t\t\t// Skip this point if any coordinate is NaN\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst lat = Math.atan2(z, Math.sqrt(x ** 2 + y ** 2));\n\t\tconst lon = Math.atan2(y, x);\n\n\t\tif (isNaN(lat) || isNaN(lon)) {\n\t\t\t// Skip this point if any coordinate is NaN\n\t\t\tcontinue;\n\t\t}\n\n\t\tpoints.push([toDegrees(lon), toDegrees(lat)]);\n\t}\n\n\treturn points.slice(1, -1);\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { Position } from \"geojson\";\nimport { haversineDistanceKilometers } from \"../geometry/measure/haversine-distance\";\nimport { lineSliceAlong } from \"../geometry/measure/slice-along\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { generateGreatCircleCoordinates } from \"../geometry/shape/great-circle-coordinates\";\n\nexport class InsertCoordinatesBehavior extends TerraDrawModeBehavior {\n\tconstructor(readonly config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tpublic generateInsertionCoordinates(\n\t\tcoordinateOne: Position,\n\t\tcoordinateTwo: Position,\n\t\tsegmentLength: number,\n\t): Position[] {\n\t\tconst line = [coordinateOne, coordinateTwo];\n\n\t\tlet lineLength = 0;\n\t\tfor (let i = 0; i < line.length - 1; i++) {\n\t\t\tlineLength += haversineDistanceKilometers(line[0], line[1]);\n\t\t}\n\n\t\t// If the line is shorter than the segment length then the original line is returned.\n\t\tif (lineLength <= segmentLength) {\n\t\t\treturn line;\n\t\t}\n\n\t\tlet numberOfSegments = lineLength / segmentLength - 1;\n\n\t\t// If numberOfSegments is integer, no need to plus 1\n\t\tif (!Number.isInteger(numberOfSegments)) {\n\t\t\tnumberOfSegments = Math.floor(numberOfSegments) + 1;\n\t\t}\n\n\t\tconst segments: Position[][] = [];\n\t\tfor (let i = 0; i < numberOfSegments; i++) {\n\t\t\tconst outline = lineSliceAlong(\n\t\t\t\tline,\n\t\t\t\tsegmentLength * i,\n\t\t\t\tsegmentLength * (i + 1),\n\t\t\t);\n\t\t\tsegments.push(outline);\n\t\t}\n\n\t\tconst coordinates: Position[] = [];\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst line = segments[i];\n\t\t\tcoordinates.push(line[1]);\n\t\t}\n\n\t\tconst limitedCoordinates = this.limitCoordinates(coordinates);\n\n\t\treturn limitedCoordinates;\n\t}\n\n\tpublic generateInsertionGeodesicCoordinates(\n\t\tcoordinateOne: Position,\n\t\tcoordinateTwo: Position,\n\t\tsegmentLength: number,\n\t): Position[] {\n\t\tconst distance = haversineDistanceKilometers(coordinateOne, coordinateTwo);\n\t\tconst numberOfPoints = Math.floor(distance / segmentLength);\n\t\tconst coordinates = generateGreatCircleCoordinates(\n\t\t\tcoordinateOne,\n\t\t\tcoordinateTwo,\n\t\t\tnumberOfPoints,\n\t\t);\n\t\tconst limitedCoordinates = this.limitCoordinates(coordinates);\n\n\t\treturn limitedCoordinates;\n\t}\n\n\tprivate limitCoordinates(coordinates: Position[]) {\n\t\treturn coordinates.map((coordinate) => [\n\t\t\tlimitPrecision(coordinate[0], this.config.coordinatePrecision),\n\t\t\tlimitPrecision(coordinate[1], this.config.coordinatePrecision),\n\t\t]);\n\t}\n}\n","import { Position } from \"geojson\";\n\nexport function coordinatesIdentical(\n\tcoordinate: Position,\n\tcoordinateTwo: Position,\n) {\n\treturn (\n\t\tcoordinate[0] === coordinateTwo[0] && coordinate[1] === coordinateTwo[1]\n\t);\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { LineString, Point, Position } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tGeoJSONStoreGeometries,\n} from \"../../store/store\";\nimport { InsertCoordinatesBehavior } from \"../insert-coordinates.behavior\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype LineStringStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface InertCoordinates {\n\tstrategy: \"amount\"; // In future this could be extended\n\tvalue: number;\n}\n\ninterface TerraDrawLineStringModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawLineStringModeKeyEvents | null;\n\tcursors?: Cursors;\n\tinsertCoordinates?: InertCoordinates;\n}\n\nexport class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringStyling> {\n\tmode = \"linestring\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawLineStringModeKeyEvents;\n\tprivate snappingEnabled: boolean;\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\tprivate insertCoordinates: InertCoordinates | undefined;\n\tprivate lastCommitedCoordinates: Position[] | undefined;\n\n\t// Behaviors\n\tprivate snapping!: SnappingBehavior;\n\tprivate insertPoint!: InsertCoordinatesBehavior;\n\n\tconstructor(options?: TerraDrawLineStringModeOptions<LineStringStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.snappingEnabled =\n\t\t\toptions && options.snapping !== undefined ? options.snapping : false;\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.validate = options?.validation;\n\n\t\tthis.insertCoordinates = options?.insertCoordinates;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\t// Finish off the drawing\n\t\tcurrentLineGeometry.coordinates.pop();\n\n\t\tthis.updateGeometries(\n\t\t\t[...currentLineGeometry.coordinates],\n\t\t\tundefined,\n\t\t\tUpdateTypes.Commit,\n\t\t);\n\n\t\tconst finishedId = this.currentId;\n\n\t\t// Reset the state back to starting state\n\t\tthis.closingPointId && this.store.delete([this.closingPointId]);\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = undefined;\n\t\tthis.lastCommitedCoordinates = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\t// Ensure that any listeners are triggered with the main created geometry\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\tprivate updateGeometries(\n\t\tcoordinates: LineString[\"coordinates\"],\n\t\tclosingPointCoordinate: Point[\"coordinates\"] | undefined,\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedGeometry = { type: \"LineString\", coordinates } as LineString;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: updateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst geometries = [\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: updatedGeometry,\n\t\t\t},\n\t\t] as {\n\t\t\tid: FeatureId;\n\t\t\tgeometry: GeoJSONStoreGeometries;\n\t\t}[];\n\n\t\tif (this.closingPointId && closingPointCoordinate) {\n\t\t\tgeometries.push({\n\t\t\t\tid: this.closingPointId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: closingPointCoordinate,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (updateType === \"commit\") {\n\t\t\tthis.lastCommitedCoordinates = updatedGeometry.coordinates;\n\t\t}\n\n\t\tthis.store.updateGeometry(geometries);\n\t}\n\n\tprivate generateInsertCoordinates(startCoord: Position, endCoord: Position) {\n\t\tif (!this.insertCoordinates || !this.lastCommitedCoordinates) {\n\t\t\tthrow new Error(\"Not able to insert coordinates\");\n\t\t}\n\n\t\t// Other strategies my be implemented in the future\n\t\tif (this.insertCoordinates.strategy !== \"amount\") {\n\t\t\tthrow new Error(\"Strategy does not exist\");\n\t\t}\n\n\t\tconst distance = haversineDistanceKilometers(startCoord, endCoord);\n\t\tconst segmentDistance = distance / (this.insertCoordinates.value + 1);\n\t\tlet insertedCoordinates: Position[] = [];\n\n\t\tif (this.projection === \"globe\") {\n\t\t\tinsertedCoordinates =\n\t\t\t\tthis.insertPoint.generateInsertionGeodesicCoordinates(\n\t\t\t\t\tstartCoord,\n\t\t\t\t\tendCoord,\n\t\t\t\t\tsegmentDistance,\n\t\t\t\t);\n\t\t} else if (this.projection === \"web-mercator\") {\n\t\t\tinsertedCoordinates = this.insertPoint.generateInsertionCoordinates(\n\t\t\t\tstartCoord,\n\t\t\t\tendCoord,\n\t\t\t\tsegmentDistance,\n\t\t\t);\n\t\t}\n\n\t\treturn insertedCoordinates;\n\t}\n\n\tprivate createLine(startingCoord: Position) {\n\t\tconst [createdId] = this.store.create([\n\t\t\t{\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\tstartingCoord,\n\t\t\t\t\t\tstartingCoord, // This is the 'live' point that changes on mouse move\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tproperties: { mode: this.mode },\n\t\t\t},\n\t\t]);\n\t\tthis.lastCommitedCoordinates = [startingCoord, startingCoord];\n\t\tthis.currentId = createdId;\n\t\tthis.currentCoordinate++;\n\t\tthis.setDrawing();\n\t}\n\n\tprivate firstUpdateToLine(updatedCoord: Position) {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\tconst currentCoordinates = currentLineGeometry.coordinates;\n\n\t\tconst [pointId] = this.store.create([\n\t\t\t{\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: [...updatedCoord],\n\t\t\t\t},\n\t\t\t\tproperties: { mode: this.mode },\n\t\t\t},\n\t\t]);\n\t\tthis.closingPointId = pointId;\n\n\t\t// We are creating the point so we immediately want\n\t\t// to set the point cursor to show it can be closed\n\t\tthis.setCursor(this.cursors.close);\n\n\t\tconst initialLineCoordinates = [...currentCoordinates, updatedCoord];\n\t\tconst closingPointCoordinate = undefined; // We don't need this until second click\n\n\t\tthis.updateGeometries(\n\t\t\tinitialLineCoordinates,\n\t\t\tclosingPointCoordinate,\n\t\t\tUpdateTypes.Commit,\n\t\t);\n\n\t\tthis.currentCoordinate++;\n\t}\n\n\tprivate updateToLine(\n\t\tupdatedCoord: Position,\n\t\tcursorXY: { x: number; y: number },\n\t) {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\tconst currentCoordinates = currentLineGeometry.coordinates;\n\n\t\t// If we are not inserting points we can get the penultimate coordinated\n\t\tconst [previousLng, previousLat] = this.lastCommitedCoordinates\n\t\t\t? this.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1]\n\t\t\t: currentCoordinates[currentCoordinates.length - 2];\n\n\t\t// Determine if the click closes the line and finished drawing\n\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: cursorXY.x, y: cursorXY.y },\n\t\t);\n\t\tconst isClosingClick = distance < this.pointerDistance;\n\n\t\tif (isClosingClick) {\n\t\t\tthis.close();\n\t\t\treturn;\n\t\t}\n\n\t\t// The cursor will immediately change to closing because the\n\t\t// closing point will be underneath the cursor\n\t\tthis.setCursor(this.cursors.close);\n\n\t\tconst updatedLineCoordinates = [...currentCoordinates, updatedCoord];\n\t\tconst updatedClosingPointCoordinate =\n\t\t\tcurrentCoordinates[currentCoordinates.length - 1];\n\n\t\tthis.updateGeometries(\n\t\t\tupdatedLineCoordinates,\n\t\t\tupdatedClosingPointCoordinate,\n\t\t\tUpdateTypes.Commit,\n\t\t);\n\n\t\tthis.currentCoordinate++;\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.snapping = new SnappingBehavior(\n\t\t\tconfig,\n\t\t\tnew PixelDistanceBehavior(config),\n\t\t\tnew ClickBoundingBoxBehavior(config),\n\t\t);\n\n\t\tthis.insertPoint = new InsertCoordinatesBehavior(config);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\tconst currentCoordinates = currentLineGeometry.coordinates;\n\n\t\t// Remove the 'live' point that changes on mouse move\n\t\tcurrentCoordinates.pop();\n\n\t\tconst snappedCoord =\n\t\t\tthis.snappingEnabled &&\n\t\t\tthis.snapping.getSnappableCoordinate(event, this.currentId);\n\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\t// We want to ensure that when we are hovering over\n\t\t// the closing point that the pointer cursor is shown\n\t\tif (this.closingPointId) {\n\t\t\tconst [previousLng, previousLat] =\n\t\t\t\tcurrentCoordinates[currentCoordinates.length - 1];\n\t\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\t\tconst distance = cartesianDistance(\n\t\t\t\t{ x, y },\n\t\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t\t);\n\n\t\t\tconst isClosingClick = distance < this.pointerDistance;\n\n\t\t\tif (isClosingClick) {\n\t\t\t\tthis.setCursor(this.cursors.close);\n\t\t\t}\n\t\t}\n\n\t\tlet line = [...currentCoordinates, updatedCoord];\n\n\t\tif (\n\t\t\tthis.insertCoordinates &&\n\t\t\tthis.currentId &&\n\t\t\tthis.lastCommitedCoordinates\n\t\t) {\n\t\t\tconst startCoord =\n\t\t\t\tthis.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1];\n\t\t\tconst endCoord = updatedCoord;\n\t\t\tif (!coordinatesIdentical(startCoord, endCoord)) {\n\t\t\t\tconst insertedCoordinates = this.generateInsertCoordinates(\n\t\t\t\t\tstartCoord,\n\t\t\t\t\tendCoord,\n\t\t\t\t);\n\t\t\t\tline = [\n\t\t\t\t\t...this.lastCommitedCoordinates.slice(0, -1),\n\t\t\t\t\t...insertedCoordinates,\n\t\t\t\t\tupdatedCoord,\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\n\t\t// Update the 'live' point\n\t\tthis.updateGeometries(line, undefined, UpdateTypes.Provisional);\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tconst snappedCoord =\n\t\t\tthis.currentId &&\n\t\t\tthis.snappingEnabled &&\n\t\t\tthis.snapping.getSnappableCoordinate(event, this.currentId);\n\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tthis.createLine(updatedCoord);\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tthis.firstUpdateToLine(updatedCoord);\n\t\t} else if (this.currentId) {\n\t\t\tthis.updateToLine(updatedCoord, {\n\t\t\t\tx: event.containerX,\n\t\t\t\ty: event.containerY,\n\t\t\t});\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t}\n\n\t\tif (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\t\tconst cleanupClosingPointId = this.closingPointId;\n\n\t\tthis.closingPointId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\ttry {\n\t\t\tif (cleanUpId !== undefined) {\n\t\t\t\tthis.store.delete([cleanUpId]);\n\t\t\t}\n\t\t\tif (cleanupClosingPointId !== undefined) {\n\t\t\t\tthis.store.delete([cleanupClosingPointId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tstyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringWidth,\n\t\t\t\tstyles.lineStringWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 10;\n\n\t\t\treturn styles;\n\t\t} else if (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\n\t\t\t\t\"#ffffff\",\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 40;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tfeature.geometry.coordinates.length >= 2\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { coordinateIsValid } from \"./../geometry/boolean/is-valid-coordinate\";\n\nexport function ValidatePointFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"Point\" &&\n\t\tcoordinateIsValid(feature.geometry.coordinates, coordinatePrecision)\n\t);\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tNumericStyling,\n\tHexColorStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidatePointFeature } from \"../../validations/point.validation\";\nimport { Point } from \"geojson\";\n\ntype PointModeStyling = {\n\tpointWidth: NumericStyling;\n\tpointColor: HexColorStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tcreate?: Cursor;\n}\n\ninterface TerraDrawPointModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawPointMode extends TerraDrawBaseDrawMode<PointModeStyling> {\n\tmode = \"point\";\n\n\tprivate cursors: Required<Cursors>;\n\n\tconstructor(options?: TerraDrawPointModeOptions<PointModeStyling>) {\n\t\tsuper(options);\n\t\tconst defaultCursors = {\n\t\t\tcreate: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.create);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (!this.store) {\n\t\t\tthrow new Error(\"Mode must be registered first\");\n\t\t}\n\n\t\tconst geometry = {\n\t\t\ttype: \"Point\",\n\t\t\tcoordinates: [event.lng, event.lat],\n\t\t} as Point;\n\n\t\tconst properties = { mode: this.mode };\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry,\n\t\t\t\t\tproperties,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst [pointId] = this.store.create([{ geometry, properties }]);\n\n\t\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(pointId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tonMouseMove() {}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp() {}\n\n\t/** @internal */\n\tcleanUp() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointOutlineColor,\n\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 30;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePointFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { Point, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { POLYGON_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\n\nexport class ClosingPointsBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _startEndPoints: string[] = [];\n\n\tget ids() {\n\t\treturn this._startEndPoints.concat();\n\t}\n\n\tset ids(_: string[]) {}\n\n\tpublic create(selectedCoords: Position[], mode: string) {\n\t\tif (this.ids.length) {\n\t\t\tthrow new Error(\"Opening and closing points already created\");\n\t\t}\n\n\t\tif (selectedCoords.length <= 3) {\n\t\t\tthrow new Error(\"Requires at least 4 coordinates\");\n\t\t}\n\n\t\tthis._startEndPoints = this.store.create(\n\t\t\t// Opening coordinate\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: selectedCoords[0],\n\t\t\t\t\t} as Point,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\t[POLYGON_PROPERTIES.CLOSING_POINT]: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t// Final coordinate\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: selectedCoords[selectedCoords.length - 2],\n\t\t\t\t\t} as Point,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\t[POLYGON_PROPERTIES.CLOSING_POINT]: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t);\n\t}\n\n\tpublic delete() {\n\t\tif (this.ids.length) {\n\t\t\tthis.store.delete(this.ids);\n\t\t\tthis._startEndPoints = [];\n\t\t}\n\t}\n\n\tpublic update(updatedCoordinates: Position[]) {\n\t\tif (this.ids.length !== 2) {\n\t\t\tthrow new Error(\"No closing points to update\");\n\t\t}\n\n\t\tthis.store.updateGeometry(\n\t\t\t// Opening coordinate\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tid: this.ids[0],\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: updatedCoordinates[0],\n\t\t\t\t\t} as Point,\n\t\t\t\t},\n\t\t\t\t// Final coordinate\n\t\t\t\t{\n\t\t\t\t\tid: this.ids[1],\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: updatedCoordinates[updatedCoordinates.length - 3],\n\t\t\t\t\t} as Point,\n\t\t\t\t},\n\t\t\t],\n\t\t);\n\t}\n\n\tpublic isClosingPoint(event: TerraDrawMouseEvent) {\n\t\tconst opening = this.store.getGeometryCopy(this.ids[0]);\n\t\tconst closing = this.store.getGeometryCopy(this.ids[1]);\n\n\t\tconst distance = this.pixelDistance.measure(\n\t\t\tevent,\n\t\t\topening.coordinates as Position,\n\t\t);\n\n\t\tconst distancePrevious = this.pixelDistance.measure(\n\t\t\tevent,\n\t\t\tclosing.coordinates as Position,\n\t\t);\n\n\t\tconst isClosing = distance < this.pointerDistance;\n\t\tconst isPreviousClosing = distancePrevious < this.pointerDistance;\n\n\t\treturn { isClosing, isPreviousClosing };\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n} from \"../base.mode\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { createPolygon } from \"../../util/geoms\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { ClosingPointsBehavior } from \"./behaviors/closing-points.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\ntype PolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawPolygonModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawPolygonModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawPolygonMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n\tmode = \"polygon\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawPolygonModeKeyEvents;\n\tprivate snappingEnabled: boolean;\n\n\t// Behaviors\n\tprivate snapping!: SnappingBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\tconstructor(options?: TerraDrawPolygonModeOptions<PolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.snappingEnabled =\n\t\t\toptions && options.snapping !== undefined ? options.snapping : false;\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\n\n\t\t// We don't want to allow closing if there is not enough\n\t\t// coordinates. We have extra because we insert them on mouse\n\t\t// move\n\t\tif (currentPolygonCoordinates.length < 5) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t[...currentPolygonCoordinates.slice(0, -2), currentPolygonCoordinates[0]],\n\t\t\tUpdateTypes.Finish,\n\t\t);\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPoints.delete();\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.snapping = new SnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tnew ClickBoundingBoxBehavior(config),\n\t\t);\n\t\tthis.closingPoints = new ClosingPointsBehavior(config, this.pixelDistance);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst closestCoord = this.snappingEnabled\n\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t: undefined;\n\n\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\n\n\t\tif (closestCoord) {\n\t\t\tevent.lng = closestCoord[0];\n\t\t\tevent.lat = closestCoord[1];\n\t\t}\n\n\t\tlet updatedCoordinates;\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t\t// renders the polygon - There might be a cleaner solution?\n\t\t\tconst epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n\t\t\tconst offset = Math.max(0.000001, epsilon);\n\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat - offset],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\tcurrentPolygonCoordinates[1],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else {\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isClosingPoint(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\t\tupdatedCoordinates = [\n\t\t\t\t\t...currentPolygonCoordinates.slice(0, -2),\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\tupdatedCoordinates = [\n\t\t\t\t\t...currentPolygonCoordinates.slice(0, -2),\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\n\t\tthis.updatePolygonGeometry(updatedCoordinates, UpdateTypes.Provisional);\n\t}\n\n\tprivate updatePolygonGeometry(\n\t\tcoordinates: Polygon[\"coordinates\"][0],\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tif (!this.currentId) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst updatedGeometry = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t} as Polygon;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([\n\t\t\t{ id: this.currentId, geometry: updatedGeometry },\n\t\t]);\n\n\t\treturn true;\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinateFirstClick(event)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = newId;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t\t[\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t],\n\t\t\t\tUpdateTypes.Commit,\n\t\t\t);\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t).coordinates[0];\n\n\t\t\tconst previousCoordinate = currentPolygonCoordinates[1];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t\t[\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\tcurrentPolygonCoordinates[1],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t],\n\t\t\t\tUpdateTypes.Commit,\n\t\t\t);\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.currentCoordinate === 2) {\n\t\t\t\tthis.closingPoints.create(currentPolygonCoordinates, \"polygon\");\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t).coordinates[0];\n\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isClosingPoint(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tthis.close();\n\t\t\t} else {\n\t\t\t\tif (closestCoord) {\n\t\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t\t}\n\n\t\t\t\tconst previousCoordinate =\n\t\t\t\t\tcurrentPolygonCoordinates[this.currentCoordinate - 1];\n\t\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tpreviousCoordinate,\n\t\t\t\t);\n\n\t\t\t\tif (isIdentical) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst updatedPolygon = createPolygon([\n\t\t\t\t\t[\n\t\t\t\t\t\t...currentPolygonCoordinates.slice(0, -1),\n\t\t\t\t\t\t[event.lng, event.lat], // New point that onMouseMove can manipulate\n\t\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\t],\n\t\t\t\t]);\n\n\t\t\t\t// If not close to the final point, keep adding points\n\t\t\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t\t\tupdatedPolygon.geometry.coordinates[0],\n\t\t\t\t\tUpdateTypes.Commit,\n\t\t\t\t);\n\t\t\t\tif (!updated) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Update closing points straight away\n\t\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\t\tthis.closingPoints.update(updatedPolygon.geometry.coordinates[0]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonDragStart() {\n\t\t// We want to allow the default drag\n\t\t// cursor to exist\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {\n\t\t// Set it back to crosshair\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\ttry {\n\t\t\tif (cleanUpId !== undefined) {\n\t\t\t\tthis.store.delete([cleanUpId]);\n\t\t\t}\n\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\tthis.closingPoints.delete();\n\t\t\t}\n\t\t} catch (error) {}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.closingPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.closingPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.closingPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\t\t\t\tstyles.zIndex = 30;\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\nexport function createPolygon(\n\tcoordinates: Position[][] = [\n\t\t[\n\t\t\t[0, 0],\n\t\t\t[0, 1],\n\t\t\t[1, 1],\n\t\t\t[1, 0],\n\t\t\t[0, 0],\n\t\t],\n\t],\n): Feature<Polygon> {\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates,\n\t\t},\n\t\tproperties: {},\n\t};\n}\n\nexport function createLineString(coordinates: Position[]): Feature<LineString> {\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: {\n\t\t\ttype: \"LineString\",\n\t\t\tcoordinates,\n\t\t},\n\t\tproperties: {},\n\t};\n}\n","import { Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\n\ntype TerraDrawRectangleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype RectanglePolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\ninterface TerraDrawRectangleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawRectangleModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawRectangleMode extends TerraDrawBaseDrawMode<RectanglePolygonStyling> {\n\tmode = \"rectangle\";\n\tprivate center: Position | undefined;\n\tprivate clickCount = 0;\n\tprivate currentRectangleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawRectangleModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\n\tconstructor(\n\t\toptions?: TerraDrawRectangleModeOptions<RectanglePolygonStyling>,\n\t) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\t}\n\n\tprivate updateRectangle(event: TerraDrawMouseEvent, updateType: UpdateTypes) {\n\t\tif (this.clickCount === 1 && this.center && this.currentRectangleId) {\n\t\t\tconst geometry = this.store.getGeometryCopy(this.currentRectangleId);\n\n\t\t\tconst firstCoord = (geometry.coordinates as Position[][])[0][0];\n\n\t\t\tconst newGeometry = {\n\t\t\t\ttype: \"Polygon\",\n\t\t\t\tcoordinates: [\n\t\t\t\t\t[\n\t\t\t\t\t\tfirstCoord,\n\t\t\t\t\t\t[event.lng, firstCoord[1]],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[firstCoord[0], event.lat],\n\t\t\t\t\t\tfirstCoord,\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t} as Polygon;\n\n\t\t\tif (this.validate) {\n\t\t\t\tconst valid = this.validate(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: this.currentRectangleId,\n\t\t\t\t\t\tgeometry: newGeometry,\n\t\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.project,\n\t\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\t\tupdateType,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!valid) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentRectangleId,\n\t\t\t\t\tgeometry: newGeometry,\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tconst finishedId = this.currentRectangleId;\n\t\tthis.center = undefined;\n\t\tthis.currentRectangleId = undefined;\n\t\tthis.clickCount = 0;\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tfinishedId &&\n\t\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (this.clickCount === 0) {\n\t\t\tthis.center = [event.lng, event.lat];\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentRectangleId = createdId;\n\t\t\tthis.clickCount++;\n\t\t\tthis.setDrawing();\n\t\t} else {\n\t\t\tthis.updateRectangle(event, UpdateTypes.Finish);\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.updateRectangle(event, UpdateTypes.Provisional);\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentRectangleId;\n\n\t\tthis.center = undefined;\n\t\tthis.currentRectangleId = undefined;\n\t\tthis.clickCount = 0;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (cleanUpId !== undefined) {\n\t\t\tthis.store.delete([cleanUpId]);\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = 10;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidateNonIntersectingPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import {\n\tHexColorStyling,\n\tNumericStyling,\n\tTerraDrawAdapterStyling,\n} from \"../../common\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeTypes,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../terra-draw\";\nimport { ValidatePointFeature } from \"../../validations/point.validation\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { ValidateLineStringFeature } from \"../../validations/linestring.validation\";\n\ntype RenderModeStyling = {\n\tpointColor: HexColorStyling;\n\tpointWidth: NumericStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineWidth: NumericStyling;\n\tpolygonFillColor: HexColorStyling;\n\tpolygonFillOpacity: NumericStyling;\n\tpolygonOutlineColor: HexColorStyling;\n\tpolygonOutlineWidth: NumericStyling;\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tzIndex: NumericStyling;\n};\n\ninterface TerraDrawRenderModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tmodeName: string;\n\t// styles need to be there else we could fall back to BaseModeOptions\n\tstyles: Partial<T>;\n}\n\nexport class TerraDrawRenderMode extends TerraDrawBaseDrawMode<RenderModeStyling> {\n\tpublic type = ModeTypes.Render; // The type of the mode\n\tpublic mode = \"render\"; // This gets changed dynamically\n\n\tconstructor(options: TerraDrawRenderModeOptions<RenderModeStyling>) {\n\t\tsuper({ styles: options.styles });\n\t\tthis.mode = options.modeName;\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(behaviorConfig: BehaviorConfig) {\n\t\t// TODO: this is probably abusing\n\t\t// registerBehaviors but it works quite well conceptually\n\n\t\t// We can set the mode name dynamically\n\t\tthis.mode = behaviorConfig.mode;\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.setStopped();\n\t}\n\n\t/** @internal */\n\tonKeyUp() {}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonClick() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tonMouseMove() {}\n\n\t/** @internal */\n\tcleanUp() {}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst defaultStyles = getDefaultStyling();\n\n\t\treturn {\n\t\t\tpointColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointColor,\n\t\t\t\tdefaultStyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointWidth,\n\t\t\t\tdefaultStyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOutlineColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointOutlineColor,\n\t\t\t\tdefaultStyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOutlineWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOutlineWidth,\n\t\t\t\tdefaultStyles.pointOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonFillColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonFillColor,\n\t\t\t\tdefaultStyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonFillOpacity: this.getNumericStylingValue(\n\t\t\t\tthis.styles.polygonFillOpacity,\n\t\t\t\tdefaultStyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonOutlineColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonOutlineColor,\n\t\t\t\tdefaultStyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonOutlineWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.polygonOutlineWidth,\n\t\t\t\tdefaultStyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tlineStringWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringWidth,\n\t\t\t\tdefaultStyles.lineStringWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tlineStringColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tdefaultStyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tzIndex: this.getNumericStylingValue(\n\t\t\t\tthis.styles.zIndex,\n\t\t\t\tdefaultStyles.zIndex,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t};\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\treturn (\n\t\t\tsuper.validateFeature(feature) &&\n\t\t\t(ValidatePointFeature(feature, this.coordinatePrecision) ||\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision) ||\n\t\t\t\tValidateLineStringFeature(feature, this.coordinatePrecision))\n\t\t);\n\t}\n}\n","import { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { coordinateIsValid } from \"./../geometry/boolean/is-valid-coordinate\";\n\nexport function ValidateLineStringFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"LineString\" &&\n\t\tfeature.geometry.coordinates.length >= 2 &&\n\t\tfeature.geometry.coordinates.every((coordinate) =>\n\t\t\tcoordinateIsValid(coordinate, coordinatePrecision),\n\t\t)\n\t);\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\n// Based on Turf.js Rhumb Bearing module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-bearing/index.ts\n\nexport function rhumbBearing(start: Position, end: Position): number {\n\tconst from = start;\n\tconst to = end;\n\n\t// φ => phi\n\t// Δλ => deltaLambda\n\t// Δψ => deltaPsi\n\t// θ => theta\n\tconst phi1 = degreesToRadians(from[1]);\n\tconst phi2 = degreesToRadians(to[1]);\n\tlet deltaLambda = degreesToRadians(to[0] - from[0]);\n\n\t// if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:\n\tif (deltaLambda > Math.PI) {\n\t\tdeltaLambda -= 2 * Math.PI;\n\t}\n\tif (deltaLambda < -Math.PI) {\n\t\tdeltaLambda += 2 * Math.PI;\n\t}\n\n\tconst deltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\n\tconst theta = Math.atan2(deltaLambda, deltaPsi);\n\n\tconst bear360 = (radiansToDegrees(theta) + 360) % 360;\n\n\tconst bear180 = bear360 > 180 ? -(360 - bear360) : bear360;\n\n\treturn bear180;\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, earthRadius } from \"../helpers\";\n\n// Based on @turf/rhumb-destination module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-destination/index.ts\n\nexport function rhumbDestination(\n\torigin: Position,\n\tdistanceMeters: number,\n\tbearing: number,\n): Position {\n\tconst wasNegativeDistance = distanceMeters < 0;\n\tlet distanceInMeters = distanceMeters;\n\n\tif (wasNegativeDistance) {\n\t\tdistanceInMeters = -Math.abs(distanceInMeters);\n\t}\n\n\tconst delta = distanceInMeters / earthRadius; // angular distance in radians\n\tconst lambda1 = (origin[0] * Math.PI) / 180; // to radians, but without normalize to 𝜋\n\tconst phi1 = degreesToRadians(origin[1]);\n\tconst theta = degreesToRadians(bearing);\n\n\tconst DeltaPhi = delta * Math.cos(theta);\n\tlet phi2 = phi1 + DeltaPhi;\n\n\t// check for going past the pole, normalise latitude if so\n\tif (Math.abs(phi2) > Math.PI / 2) {\n\t\tphi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2;\n\t}\n\n\tconst DeltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\t// E-W course becomes ill-conditioned with 0/0\n\tconst q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n\tconst DeltaLambda = (delta * Math.sin(theta)) / q;\n\tconst lambda2 = lambda1 + DeltaLambda;\n\n\t// normalise to −180..+180°\n\tconst destination = [\n\t\t(((lambda2 * 180) / Math.PI + 540) % 360) - 180,\n\t\t(phi2 * 180) / Math.PI,\n\t];\n\n\t// compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n\t// solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n\tdestination[0] +=\n\t\tdestination[0] - origin[0] > 180\n\t\t\t? -360\n\t\t\t: origin[0] - destination[0] > 180\n\t\t\t? 360\n\t\t\t: 0;\n\treturn destination;\n}\n","import { Position } from \"geojson\";\nimport { limitPrecision } from \"./limit-decimal-precision\";\nimport { Project, Unproject } from \"../common\";\nimport { haversineDistanceKilometers } from \"./measure/haversine-distance\";\nimport { rhumbBearing } from \"./measure/rhumb-bearing\";\nimport { rhumbDestination } from \"./measure/rhumb-destination\";\n\n// midpointCoordinate is adapted from the @turf/midpoint which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-midpoint\n\nexport function midpointCoordinate(\n\tcoordinates1: Position,\n\tcoordinates2: Position,\n\tprecision: number,\n\tproject: Project,\n\tunproject: Unproject,\n) {\n\tconst projectedCoordinateOne = project(coordinates1[0], coordinates1[1]);\n\tconst projectedCoordinateTwo = project(coordinates2[0], coordinates2[1]);\n\n\tconst { lng, lat } = unproject(\n\t\t(projectedCoordinateOne.x + projectedCoordinateTwo.x) / 2,\n\t\t(projectedCoordinateOne.y + projectedCoordinateTwo.y) / 2,\n\t);\n\n\treturn [limitPrecision(lng, precision), limitPrecision(lat, precision)];\n}\n\n/* Get the geodesic midpoint coordinate between two coordinates */\nexport function geodesicMidpointCoordinate(\n\tcoordinates1: Position,\n\tcoordinates2: Position,\n\tprecision: number,\n) {\n\tconst dist = haversineDistanceKilometers(coordinates1, coordinates2) * 1000;\n\tconst heading = rhumbBearing(coordinates1, coordinates2);\n\tconst midpoint = rhumbDestination(coordinates1, dist / 2, heading);\n\treturn [\n\t\tlimitPrecision(midpoint[0], precision),\n\t\tlimitPrecision(midpoint[1], precision),\n\t];\n}\n","import { Point, Position } from \"geojson\";\nimport { Project, Projection, Unproject } from \"../common\";\nimport { JSONObject } from \"../store/store\";\nimport {\n\tmidpointCoordinate,\n\tgeodesicMidpointCoordinate,\n} from \"./midpoint-coordinate\";\n\nexport function getMidPointCoordinates({\n\tfeatureCoords,\n\tprecision,\n\tunproject,\n\tproject,\n\tprojection,\n}: {\n\tfeatureCoords: Position[];\n\tprecision: number;\n\tproject: Project;\n\tunproject: Unproject;\n\tprojection: Projection;\n}) {\n\tconst midPointCoords: Position[] = [];\n\tfor (let i = 0; i < featureCoords.length - 1; i++) {\n\t\tlet mid;\n\t\tif (projection === \"web-mercator\") {\n\t\t\tmid = midpointCoordinate(\n\t\t\t\tfeatureCoords[i],\n\t\t\t\tfeatureCoords[i + 1],\n\t\t\t\tprecision,\n\t\t\t\tproject,\n\t\t\t\tunproject,\n\t\t\t);\n\t\t} else if (projection === \"globe\") {\n\t\t\tmid = geodesicMidpointCoordinate(\n\t\t\t\tfeatureCoords[i],\n\t\t\t\tfeatureCoords[i + 1],\n\t\t\t\tprecision,\n\t\t\t);\n\t\t} else {\n\t\t\tthrow new Error(\"Invalid projection\");\n\t\t}\n\n\t\tmidPointCoords.push(mid);\n\t}\n\treturn midPointCoords;\n}\n\nexport function getMidPoints(\n\tselectedCoords: Position[],\n\tproperties: (index: number) => JSONObject,\n\tprecision: number,\n\tproject: Project,\n\tunproject: Unproject,\n\tprojection: Projection,\n) {\n\treturn getMidPointCoordinates({\n\t\tfeatureCoords: selectedCoords,\n\t\tprecision,\n\t\tproject,\n\t\tunproject,\n\t\tprojection,\n\t}).map((coord, i) => ({\n\t\tgeometry: { type: \"Point\", coordinates: coord } as Point,\n\t\tproperties: properties(i),\n\t}));\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport {\n\tgetMidPointCoordinates,\n\tgetMidPoints,\n} from \"../../../geometry/get-midpoints\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { Projection, SELECT_PROPERTIES } from \"../../../common\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class MidPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPointBehavior: SelectionPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _midPoints: string[] = [];\n\n\tget ids() {\n\t\treturn this._midPoints.concat();\n\t}\n\n\tset ids(_: string[]) {}\n\n\tpublic insert(midPointId: string, coordinatePrecision: number) {\n\t\tconst midPoint = this.store.getGeometryCopy(midPointId);\n\t\tconst { midPointFeatureId, midPointSegment } =\n\t\t\tthis.store.getPropertiesCopy(midPointId);\n\t\tconst geometry = this.store.getGeometryCopy<Polygon | LineString>(\n\t\t\tmidPointFeatureId as string,\n\t\t);\n\n\t\t// Update the coordinates to include inserted midpoint\n\t\tconst updatedCoordinates =\n\t\t\tgeometry.type === \"Polygon\"\n\t\t\t\t? geometry.coordinates[0]\n\t\t\t\t: geometry.coordinates;\n\n\t\tupdatedCoordinates.splice(\n\t\t\t(midPointSegment as number) + 1,\n\t\t\t0,\n\t\t\tmidPoint.coordinates as Position,\n\t\t);\n\n\t\t// Update geometry coordinates depending\n\t\t// on if a polygon or linestring\n\t\tgeometry.coordinates =\n\t\t\tgeometry.type === \"Polygon\" ? [updatedCoordinates] : updatedCoordinates;\n\n\t\t// Update the selected features geometry to insert\n\t\t// the new midpoint\n\t\tthis.store.updateGeometry([{ id: midPointFeatureId as string, geometry }]);\n\n\t\t// TODO: is there a way of just updating the selection points rather\n\t\t// than fully deleting / recreating?\n\t\t// Recreate the selection points\n\n\t\tthis.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]);\n\n\t\t// We don't need to check if flags are correct\n\t\t// because selection points are prerequiste for midpoints\n\t\tthis.create(\n\t\t\tupdatedCoordinates,\n\t\t\tmidPointFeatureId as string,\n\t\t\tcoordinatePrecision,\n\t\t);\n\t\tthis.selectionPointBehavior.create(\n\t\t\tupdatedCoordinates,\n\t\t\tgeometry.type,\n\t\t\tmidPointFeatureId as string,\n\t\t);\n\t}\n\n\tpublic create(\n\t\tselectedCoords: Position[],\n\t\tfeatureId: FeatureId,\n\t\tcoordinatePrecision: number,\n\t) {\n\t\tif (!this.store.has(featureId)) {\n\t\t\tthrow new Error(\"Store does not have feature with this id\");\n\t\t}\n\n\t\tthis._midPoints = this.store.create(\n\t\t\tgetMidPoints(\n\t\t\t\tselectedCoords,\n\t\t\t\t(i) => ({\n\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t[SELECT_PROPERTIES.MID_POINT]: true,\n\t\t\t\t\tmidPointSegment: i,\n\t\t\t\t\tmidPointFeatureId: featureId,\n\t\t\t\t}),\n\t\t\t\tcoordinatePrecision,\n\t\t\t\tthis.config.project,\n\t\t\t\tthis.config.unproject,\n\t\t\t\tthis.projection,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic delete() {\n\t\tif (this._midPoints.length) {\n\t\t\tthis.store.delete(this._midPoints);\n\t\t\tthis._midPoints = [];\n\t\t}\n\t}\n\n\tpublic getUpdated(updatedCoordinates: Position[]) {\n\t\tif (this._midPoints.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn getMidPointCoordinates({\n\t\t\tfeatureCoords: updatedCoordinates,\n\t\t\tprecision: this.coordinatePrecision,\n\t\t\tproject: this.config.project,\n\t\t\tunproject: this.config.unproject,\n\t\t\tprojection: this.config.projection as Projection,\n\t\t}).map((updatedMidPointCoord, i) => ({\n\t\t\tid: this._midPoints[i] as string,\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: updatedMidPointCoord,\n\t\t\t} as Point,\n\t\t}));\n\t}\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { getCoordinatesAsPoints } from \"../../../geometry/get-coordinates-as-points\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class SelectionPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tprivate _selectionPoints: FeatureId[] = [];\n\n\tget ids() {\n\t\treturn this._selectionPoints.concat();\n\t}\n\n\tset ids(_: FeatureId[]) {}\n\n\tpublic create(\n\t\tselectedCoords: Position[],\n\t\ttype: Polygon[\"type\"] | LineString[\"type\"],\n\t\tfeatureId: FeatureId,\n\t) {\n\t\tthis._selectionPoints = this.store.create(\n\t\t\tgetCoordinatesAsPoints(selectedCoords, type, (i) => ({\n\t\t\t\tmode: this.mode,\n\t\t\t\tselectionPoint: true,\n\t\t\t\tselectionPointFeatureId: featureId,\n\t\t\t\tindex: i,\n\t\t\t})),\n\t\t);\n\t}\n\n\tpublic delete() {\n\t\tif (this.ids.length) {\n\t\t\tthis.store.delete(this.ids);\n\t\t\tthis._selectionPoints = [];\n\t\t}\n\t}\n\n\tpublic getUpdated(updatedCoordinates: Position[]) {\n\t\tif (this._selectionPoints.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this._selectionPoints.map((id, i) => {\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: updatedCoordinates[i],\n\t\t\t\t} as Point,\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic getOneUpdated(index: number, updatedCoordinate: Position) {\n\t\tif (this._selectionPoints[index] === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tid: this._selectionPoints[index] as string,\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: updatedCoordinate,\n\t\t\t} as Point,\n\t\t};\n\t}\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\n\nexport function getCoordinatesAsPoints(\n\tselectedCoords: Position[],\n\tgeometryType: \"Polygon\" | \"LineString\",\n\tproperties: (index: number) => JSONObject,\n) {\n\tconst selectionPoints = [];\n\n\t// We can skip the last point for polygons\n\t// as it's a duplicate of the first\n\tconst length =\n\t\tgeometryType === \"Polygon\"\n\t\t\t? selectedCoords.length - 1\n\t\t\t: selectedCoords.length;\n\n\tfor (let i = 0; i < length; i++) {\n\t\tselectionPoints.push({\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: selectedCoords[i],\n\t\t\t} as Point,\n\t\t\tproperties: properties(i),\n\t\t});\n\t}\n\n\treturn selectionPoints;\n}\n","import { Position } from \"geojson\";\n\n// Based on which-polygon (Mapbox)\n// https://github.com/mapbox/which-polygon/blob/2eb5b8a427d018ebd964c05acd3b9166c4558b2c/index.js#L81\n// ISC License - Copyright (c) 2017, Mapbox\n\nexport function pointInPolygon(point: Position, rings: Position[][]) {\n\tlet inside = false;\n\tfor (let i = 0, len = rings.length; i < len; i++) {\n\t\tconst ring = rings[i];\n\t\tfor (let j = 0, len2 = ring.length, k = len2 - 1; j < len2; k = j++) {\n\t\t\tif (rayIntersect(point, ring[j], ring[k])) {\n\t\t\t\tinside = !inside;\n\t\t\t}\n\t\t}\n\t}\n\treturn inside;\n}\n\nfunction rayIntersect(p: Position, p1: Position, p2: Position) {\n\treturn (\n\t\tp1[1] > p[1] !== p2[1] > p[1] &&\n\t\tp[0] < ((p2[0] - p1[0]) * (p[1] - p1[1])) / (p2[1] - p1[1]) + p1[0]\n\t);\n}\n","export const pixelDistanceToLine = (\n\tpoint: { x: number; y: number },\n\tlinePointOne: { x: number; y: number },\n\tlinePointTwo: { x: number; y: number },\n) => {\n\tconst square = (x: number) => {\n\t\treturn x * x;\n\t};\n\tconst dist2 = (v: { x: number; y: number }, w: { x: number; y: number }) => {\n\t\treturn square(v.x - w.x) + square(v.y - w.y);\n\t};\n\tconst distToSegmentSquared = (\n\t\tp: { x: number; y: number },\n\t\tv: { x: number; y: number },\n\t\tw: { x: number; y: number },\n\t) => {\n\t\tconst l2 = dist2(v, w);\n\n\t\tif (l2 === 0) {\n\t\t\treturn dist2(p, v);\n\t\t}\n\n\t\tlet t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;\n\t\tt = Math.max(0, Math.min(1, t));\n\n\t\treturn dist2(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });\n\t};\n\n\treturn Math.sqrt(distToSegmentSquared(point, linePointOne, linePointTwo));\n};\n","import { SELECT_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { BBoxPolygon, GeoJSONStoreFeatures } from \"../../../store/store\";\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../../click-bounding-box.behavior\";\n\nimport { pointInPolygon } from \"../../../geometry/boolean/point-in-polygon\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { pixelDistanceToLine } from \"../../../geometry/measure/pixel-distance-to-line\";\n\nexport class FeatureAtPointerEventBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly createClickBoundingBox: ClickBoundingBoxBehavior,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tpublic find(event: TerraDrawMouseEvent, hasSelection: boolean) {\n\t\tlet clickedPoint: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedPointDistance = Infinity;\n\t\tlet clickedLineString: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedLineStringDistance = Infinity;\n\t\tlet clickedMidPoint: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedMidPointDistance = Infinity;\n\t\tlet clickedPolygon: GeoJSONStoreFeatures | undefined = undefined;\n\n\t\tconst bbox = this.createClickBoundingBox.create(event);\n\t\tconst features = this.store.search(bbox as BBoxPolygon);\n\n\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\tconst feature = features[i];\n\t\t\tconst geometry = feature.geometry;\n\n\t\t\tif (geometry.type === \"Point\") {\n\t\t\t\t// Ignore selection points always, and ignore mid points\n\t\t\t\t// when nothing is selected\n\t\t\t\tconst isSelectionPoint = feature.properties.selectionPoint;\n\t\t\t\tconst isNonSelectedMidPoint =\n\t\t\t\t\t!hasSelection && feature.properties[SELECT_PROPERTIES.MID_POINT];\n\n\t\t\t\tif (isSelectionPoint || isNonSelectedMidPoint) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst distance = this.pixelDistance.measure(\n\t\t\t\t\tevent,\n\t\t\t\t\tgeometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\t// We want to catch both clicked\n\t\t\t\t// features but also any midpoints\n\t\t\t\t// in the clicked area\n\t\t\t\tif (\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.MID_POINT] &&\n\t\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\t\tdistance < clickedMidPointDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedMidPointDistance = distance;\n\t\t\t\t\tclickedMidPoint = feature;\n\t\t\t\t} else if (\n\t\t\t\t\t!feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n\t\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\t\tdistance < clickedPointDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedPointDistance = distance;\n\t\t\t\t\tclickedPoint = feature;\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"LineString\") {\n\t\t\t\tif (clickedPoint) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (let i = 0; i < geometry.coordinates.length - 1; i++) {\n\t\t\t\t\tconst coord = geometry.coordinates[i];\n\t\t\t\t\tconst nextCoord = geometry.coordinates[i + 1];\n\t\t\t\t\tconst distanceToLine = pixelDistanceToLine(\n\t\t\t\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t\t\t\t\tthis.project(coord[0], coord[1]),\n\t\t\t\t\t\tthis.project(nextCoord[0], nextCoord[1]),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tdistanceToLine < this.pointerDistance &&\n\t\t\t\t\t\tdistanceToLine < clickedLineStringDistance\n\t\t\t\t\t) {\n\t\t\t\t\t\tclickedLineStringDistance = distanceToLine;\n\t\t\t\t\t\tclickedLineString = feature;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\t\tif (clickedPoint || clickedLineString) {\n\t\t\t\t\t// We already have a clicked feature\n\t\t\t\t\t// so we can ignore the polygon\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst clickInsidePolygon = pointInPolygon(\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tgeometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\tif (clickInsidePolygon) {\n\t\t\t\t\tclickedPolygon = feature;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tclickedFeature: clickedPoint || clickedLineString || clickedPolygon,\n\t\t\tclickedMidPoint,\n\t\t};\n\t}\n}\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureAtPointerEventBehavior } from \"./feature-at-pointer-event.behavior\";\nimport { Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class DragFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly featuresAtMouseEvent: FeatureAtPointerEventBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate draggedFeatureId: FeatureId | null = null;\n\n\tprivate dragPosition: Position | undefined;\n\n\tstartDragging(event: TerraDrawMouseEvent, id: FeatureId) {\n\t\tthis.draggedFeatureId = id;\n\t\tthis.dragPosition = [event.lng, event.lat];\n\t}\n\n\tstopDragging() {\n\t\tthis.draggedFeatureId = null;\n\t\tthis.dragPosition = undefined;\n\t}\n\n\tisDragging() {\n\t\treturn this.draggedFeatureId !== null;\n\t}\n\n\tcanDrag(event: TerraDrawMouseEvent, selectedId: FeatureId) {\n\t\tconst { clickedFeature } = this.featuresAtMouseEvent.find(event, true);\n\n\t\t// If the cursor is not over the selected\n\t\t// feature then we don't want to drag\n\t\tif (!clickedFeature || clickedFeature.id !== selectedId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tdrag(event: TerraDrawMouseEvent, validateFeature?: Validation) {\n\t\tif (!this.draggedFeatureId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.store.getGeometryCopy(this.draggedFeatureId);\n\t\tconst mouseCoord = [event.lng, event.lat];\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type === \"Polygon\" || geometry.type === \"LineString\") {\n\t\t\tlet updatedCoords: Position[];\n\t\t\tlet upToCoord: number;\n\n\t\t\tif (geometry.type === \"Polygon\") {\n\t\t\t\tupdatedCoords = geometry.coordinates[0];\n\t\t\t\tupToCoord = updatedCoords.length - 1;\n\t\t\t} else {\n\t\t\t\t// Must be LineString here\n\t\t\t\tupdatedCoords = geometry.coordinates;\n\t\t\t\tupToCoord = updatedCoords.length;\n\t\t\t}\n\n\t\t\tif (!this.dragPosition) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < upToCoord; i++) {\n\t\t\t\tconst coordinate = updatedCoords[i];\n\t\t\t\tconst delta = [\n\t\t\t\t\tthis.dragPosition[0] - mouseCoord[0],\n\t\t\t\t\tthis.dragPosition[1] - mouseCoord[1],\n\t\t\t\t];\n\n\t\t\t\t// Keep precision limited when calculating new coordinates\n\t\t\t\tconst updatedLng = limitPrecision(\n\t\t\t\t\tcoordinate[0] - delta[0],\n\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t);\n\n\t\t\t\tconst updatedLat = limitPrecision(\n\t\t\t\t\tcoordinate[1] - delta[1],\n\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t);\n\n\t\t\t\t// Ensure that coordinates do not exceed\n\t\t\t\t// lng lat limits. Long term we may want to figure out\n\t\t\t\t// proper handling of anti meridian crossings\n\t\t\t\tif (\n\t\t\t\t\tupdatedLng > 180 ||\n\t\t\t\t\tupdatedLng < -180 ||\n\t\t\t\t\tupdatedLat > 90 ||\n\t\t\t\t\tupdatedLat < -90\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tupdatedCoords[i] = [updatedLng, updatedLat];\n\t\t\t}\n\n\t\t\t// Set final coordinate identical to first\n\t\t\t// We only want to do this for polygons!\n\t\t\tif (geometry.type === \"Polygon\") {\n\t\t\t\tupdatedCoords[updatedCoords.length - 1] = [\n\t\t\t\t\tupdatedCoords[0][0],\n\t\t\t\t\tupdatedCoords[0][1],\n\t\t\t\t];\n\t\t\t}\n\n\t\t\tconst updatedSelectionPoints =\n\t\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\t\tif (validateFeature) {\n\t\t\t\tconst valid = validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tid: this.draggedFeatureId,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!valid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Issue the update to the selected feature\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{ id: this.draggedFeatureId, geometry },\n\t\t\t\t...updatedSelectionPoints,\n\t\t\t\t...updatedMidPoints,\n\t\t\t]);\n\n\t\t\tthis.dragPosition = [event.lng, event.lat];\n\n\t\t\t// Update mid point positions\n\t\t} else if (geometry.type === \"Point\") {\n\t\t\t// For mouse points we can simply move it\n\t\t\t// to the dragged position\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.draggedFeatureId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: mouseCoord,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tthis.dragPosition = [event.lng, event.lat];\n\t\t}\n\t}\n}\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\n\nimport { LineString, Polygon, Position, Point, Feature } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { selfIntersects } from \"../../../geometry/boolean/self-intersects\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class DragCoordinateBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate draggedCoordinate: { id: null | FeatureId; index: number } = {\n\t\tid: null,\n\t\tindex: -1,\n\t};\n\n\tprivate getClosestCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tgeometry: Polygon | LineString | Point,\n\t) {\n\t\tconst closestCoordinate = {\n\t\t\tdist: Infinity,\n\t\t\tindex: -1,\n\t\t\tisFirstOrLastPolygonCoord: false,\n\t\t};\n\n\t\tlet geomCoordinates: Position[] | undefined;\n\n\t\tif (geometry.type === \"LineString\") {\n\t\t\tgeomCoordinates = geometry.coordinates;\n\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\tgeomCoordinates = geometry.coordinates[0];\n\t\t} else {\n\t\t\t// We don't want to handle dragging\n\t\t\t// points here\n\t\t\treturn closestCoordinate;\n\t\t}\n\n\t\t// Look through the selected features coordinates\n\t\t// and try to find a coordinate that is draggable\n\t\tfor (let i = 0; i < geomCoordinates.length; i++) {\n\t\t\tconst coord = geomCoordinates[i];\n\t\t\tconst distance = this.pixelDistance.measure(event, coord);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < closestCoordinate.dist\n\t\t\t) {\n\t\t\t\t// We don't create a point for the final\n\t\t\t\t// polygon coord, so we must set it to the first\n\t\t\t\t// coordinate instead\n\t\t\t\tconst isFirstOrLastPolygonCoord =\n\t\t\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t\t\t(i === geomCoordinates.length - 1 || i === 0);\n\n\t\t\t\tclosestCoordinate.dist = distance;\n\t\t\t\tclosestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n\t\t\t\tclosestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n\t\t\t}\n\t\t}\n\n\t\treturn closestCoordinate;\n\t}\n\n\tpublic getDraggableIndex(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t): number {\n\t\tconst geometry = this.store.getGeometryCopy(selectedId);\n\t\tconst closestCoordinate = this.getClosestCoordinate(event, geometry);\n\n\t\t// No coordinate was within the pointer distance\n\t\tif (closestCoordinate.index === -1) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn closestCoordinate.index;\n\t}\n\n\tpublic drag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tallowSelfIntersection: boolean,\n\t\tvalidateFeature?: Validation,\n\t): boolean {\n\t\tif (!this.draggedCoordinate.id) {\n\t\t\treturn false;\n\t\t}\n\t\tconst index = this.draggedCoordinate.index;\n\t\tconst geometry = this.store.getGeometryCopy(this.draggedCoordinate.id);\n\n\t\tconst geomCoordinates = (\n\t\t\tgeometry.type === \"LineString\"\n\t\t\t\t? geometry.coordinates\n\t\t\t\t: geometry.coordinates[0]\n\t\t) as Position[];\n\n\t\tconst isFirstOrLastPolygonCoord =\n\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t(index === geomCoordinates.length - 1 || index === 0);\n\n\t\t// Store the updated coord\n\t\tconst updatedCoordinate = [event.lng, event.lat];\n\n\t\t// Ensure that coordinates do not exceed\n\t\t// lng lat limits. Long term we may want to figure out\n\t\t// proper handling of anti meridian crossings\n\t\tif (\n\t\t\tevent.lng > 180 ||\n\t\t\tevent.lng < -180 ||\n\t\t\tevent.lat > 90 ||\n\t\t\tevent.lat < -90\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We want to update the actual Polygon/LineString itself -\n\t\t// for Polygons we want the first and last coordinates to match\n\t\tif (isFirstOrLastPolygonCoord) {\n\t\t\tconst lastCoordIndex = geomCoordinates.length - 1;\n\t\t\tgeomCoordinates[0] = updatedCoordinate;\n\t\t\tgeomCoordinates[lastCoordIndex] = updatedCoordinate;\n\t\t} else {\n\t\t\tgeomCoordinates[index] = updatedCoordinate;\n\t\t}\n\n\t\tconst updatedSelectionPoint = this.selectionPoints.getOneUpdated(\n\t\t\tindex,\n\t\t\tupdatedCoordinate,\n\t\t);\n\n\t\tconst updatedSelectionPoints = updatedSelectionPoint\n\t\t\t? [updatedSelectionPoint]\n\t\t\t: [];\n\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(geomCoordinates) || [];\n\n\t\tif (\n\t\t\tgeometry.type !== \"Point\" &&\n\t\t\t!allowSelfIntersection &&\n\t\t\tselfIntersects({\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry: geometry,\n\t\t\t\tproperties: {},\n\t\t\t} as Feature<Polygon>)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (validateFeature) {\n\t\t\tconst valid = validateFeature(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Apply all the updates\n\t\tthis.store.updateGeometry([\n\t\t\t// Update feature\n\t\t\t{\n\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\tgeometry: geometry,\n\t\t\t},\n\t\t\t// Update selection and mid points\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\treturn true;\n\t}\n\n\tisDragging() {\n\t\treturn this.draggedCoordinate.id !== null;\n\t}\n\n\tstartDragging(id: FeatureId, index: number) {\n\t\tthis.draggedCoordinate = {\n\t\t\tid,\n\t\t\tindex,\n\t\t};\n\t}\n\n\tstopDragging() {\n\t\tthis.draggedCoordinate = {\n\t\t\tid: null,\n\t\t\tindex: -1,\n\t\t};\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\n// Adapter from the @turf/bearing which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-centroid\n\nexport function centroid(geojson: Feature<Polygon | LineString>): Position {\n\tlet xSum = 0;\n\tlet ySum = 0;\n\tlet len = 0;\n\n\tconst coordinates =\n\t\tgeojson.geometry.type === \"Polygon\"\n\t\t\t? geojson.geometry.coordinates[0].slice(0, -1)\n\t\t\t: geojson.geometry.coordinates;\n\n\tcoordinates.forEach((coord: Position) => {\n\t\txSum += coord[0];\n\t\tySum += coord[1];\n\t\tlen++;\n\t}, true);\n\n\treturn [xSum / len, ySum / len];\n}\n","import { Position } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Adapted from @turf/rhumb-distance module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-distance/index.ts\n\nexport function rhumbDistance(destination: Position, origin: Position): number {\n\t// compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n\t// solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n\tdestination[0] +=\n\t\tdestination[0] - origin[0] > 180\n\t\t\t? -360\n\t\t\t: origin[0] - destination[0] > 180\n\t\t\t? 360\n\t\t\t: 0;\n\n\t// see www.edwilliams.org/avform.htm#Rhumb\n\n\tconst R = earthRadius;\n\tconst phi1 = (origin[1] * Math.PI) / 180;\n\tconst phi2 = (destination[1] * Math.PI) / 180;\n\tconst DeltaPhi = phi2 - phi1;\n\tlet DeltaLambda = (Math.abs(destination[0] - origin[0]) * Math.PI) / 180;\n\n\t// if dLon over 180° take shorter rhumb line across the anti-meridian:\n\tif (DeltaLambda > Math.PI) {\n\t\tDeltaLambda -= 2 * Math.PI;\n\t}\n\n\t// on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor'\n\t// q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it\n\tconst DeltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\tconst q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n\t// distance is pythagoras on 'stretched' Mercator projection\n\tconst delta = Math.sqrt(\n\t\tDeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda,\n\t); // angular distance in radians\n\n\tconst distanceMeters = delta * R;\n\n\treturn distanceMeters;\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { lngLatToWebMercatorXY } from \"./project/web-mercator\";\n\n/**\n * Calculates the centroid of a GeoJSON Polygon or LineString in Web Mercator\n\n * @param {Feature<Polygon | LineString>} feature - The GeoJSON Feature containing either a Polygon or LineString\n * @returns {{ x: number, y: number }} The centroid of the polygon or line string in Web Mercator coordinates.\n */\nexport function webMercatorCentroid(feature: Feature<Polygon | LineString>) {\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tconst webMercatorCoordinates = coordinates.map((coord) => {\n\t\tconst { x, y } = lngLatToWebMercatorXY(coord[0], coord[1]);\n\t\treturn [x, y];\n\t});\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\treturn calculatePolygonCentroid(webMercatorCoordinates);\n\t} else {\n\t\treturn calculateLineStringMidpoint(webMercatorCoordinates);\n\t}\n}\n\nfunction calculatePolygonCentroid(webMercatorCoordinates: Position[]): {\n\tx: number;\n\ty: number;\n} {\n\tlet area = 0;\n\tlet centroidX = 0;\n\tlet centroidY = 0;\n\n\tconst n = webMercatorCoordinates.length;\n\n\tfor (let i = 0; i < n - 1; i++) {\n\t\tconst [x1, y1] = webMercatorCoordinates[i];\n\t\tconst [x2, y2] = webMercatorCoordinates[i + 1];\n\n\t\tconst crossProduct = x1 * y2 - x2 * y1;\n\t\tarea += crossProduct;\n\t\tcentroidX += (x1 + x2) * crossProduct;\n\t\tcentroidY += (y1 + y2) * crossProduct;\n\t}\n\n\tarea /= 2;\n\tcentroidX /= 6 * area;\n\tcentroidY /= 6 * area;\n\n\treturn { x: centroidX, y: centroidY };\n}\n\nfunction calculateLineStringMidpoint(lineString: Position[]): {\n\tx: number;\n\ty: number;\n} {\n\tconst n = lineString.length;\n\tlet totalX = 0;\n\tlet totalY = 0;\n\n\tfor (let i = 0; i < n; i++) {\n\t\tconst [x, y] = lineString[i];\n\t\ttotalX += x;\n\t\ttotalY += y;\n\t}\n\n\treturn { x: totalX / n, y: totalY / n };\n}\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport {\n\ttransformRotate,\n\ttransformRotateWebMercator,\n} from \"../../../geometry/transform/rotate\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { rhumbBearing } from \"../../../geometry/measure/rhumb-bearing\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId } from \"../../../store/store\";\nimport { webMercatorCentroid } from \"../../../geometry/web-mercator-centroid\";\nimport { lngLatToWebMercatorXY } from \"../../../geometry/project/web-mercator\";\nimport { webMercatorBearing } from \"../../../geometry/measure/bearing\";\n\nexport class RotateFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate lastBearing: number | undefined;\n\n\treset() {\n\t\tthis.lastBearing = undefined;\n\t}\n\n\trotate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t\tvalidateFeature?: Validation,\n\t) {\n\t\tconst geometry = this.store.getGeometryCopy<LineString | Polygon>(\n\t\t\tselectedId,\n\t\t);\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mouseCoord = [event.lng, event.lat];\n\n\t\tlet bearing: number;\n\t\tconst feature = { type: \"Feature\", geometry, properties: {} } as\n\t\t\t| Feature<Polygon>\n\t\t\t| Feature<LineString>;\n\n\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\tconst centerWebMercator = webMercatorCentroid(feature);\n\t\t\tconst cursorWebMercator = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\t\tbearing = webMercatorBearing(centerWebMercator, cursorWebMercator);\n\n\t\t\tif (!this.lastBearing) {\n\t\t\t\tthis.lastBearing = bearing;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst angle = this.lastBearing - bearing;\n\n\t\t\ttransformRotateWebMercator(feature, -angle);\n\t\t} else if (this.config.projection === \"globe\") {\n\t\t\tbearing = rhumbBearing(\n\t\t\t\tcentroid({ type: \"Feature\", geometry, properties: {} }),\n\t\t\t\tmouseCoord,\n\t\t\t);\n\n\t\t\t// We need an original bearing to compare against\n\t\t\tif (!this.lastBearing) {\n\t\t\t\tthis.lastBearing = bearing + 180;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst angle = this.lastBearing - (bearing + 180);\n\n\t\t\ttransformRotate(feature, -angle);\n\t\t} else {\n\t\t\tthrow new Error(\"Unsupported projection\");\n\t\t}\n\n\t\t// Coordinates are either polygon or linestring at this point\n\t\tconst updatedCoords: Position[] =\n\t\t\tgeometry.type === \"Polygon\"\n\t\t\t\t? geometry.coordinates[0]\n\t\t\t\t: geometry.coordinates;\n\n\t\t// Ensure that coordinate precision is maintained\n\t\tupdatedCoords.forEach((coordinate) => {\n\t\t\tcoordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n\t\t\tcoordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n\t\t});\n\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tif (validateFeature) {\n\t\t\tif (\n\t\t\t\t!validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: selectedId,\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{ id: selectedId, geometry },\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\tif (this.projection === \"web-mercator\") {\n\t\t\tthis.lastBearing = bearing;\n\t\t} else if (this.projection === \"globe\") {\n\t\t\tthis.lastBearing = bearing + 180;\n\t\t}\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\n\n// Adapted on @turf/transform-rotate module which is MIT licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-transform-rotate\n\nexport function transformRotate(\n\tfeature: Feature<Polygon | LineString>,\n\tangle: number,\n) {\n\t// Shortcut no-rotation\n\tif (angle === 0 || angle === 360 || angle === -360) {\n\t\treturn feature;\n\t}\n\n\t// Use centroid of GeoJSON if pivot is not provided\n\tconst pivot = centroid(feature);\n\n\tconst cooordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tcooordinates.forEach((pointCoords: Position) => {\n\t\tconst initialAngle = rhumbBearing(pivot, pointCoords);\n\t\tconst finalAngle = initialAngle + angle;\n\t\tconst distance = rhumbDistance(pivot, pointCoords);\n\t\tconst newCoords = rhumbDestination(pivot, distance, finalAngle);\n\t\tpointCoords[0] = newCoords[0];\n\t\tpointCoords[1] = newCoords[1];\n\t});\n\n\treturn feature;\n}\n\n/**\n * Rotate a GeoJSON Polygon geometry in web mercator\n * @param polygon - GeoJSON Polygon geometry\n * @param angle - rotation angle in degrees\n * @returns - rotated GeoJSON Polygon geometry\n */\nexport const transformRotateWebMercator = (\n\tfeature: Feature<Polygon> | Feature<LineString>,\n\tangle: number,\n) => {\n\tif (angle === 0 || angle === 360 || angle === -360) {\n\t\treturn feature;\n\t}\n\n\tconst DEGREES_TO_RADIANS = 0.017453292519943295 as const; // Math.PI / 180\n\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\tconst angleRad = angle * DEGREES_TO_RADIANS;\n\n\t// Convert polygon coordinates to Web Mercator\n\tconst webMercatorCoords = coordinates.map(([lng, lat]) =>\n\t\tlngLatToWebMercatorXY(lng, lat),\n\t);\n\n\t// Find centroid of the polygon in Web Mercator\n\tconst centroid = webMercatorCoords.reduce(\n\t\t(acc: { x: number; y: number }, coord: { x: number; y: number }) => ({\n\t\t\tx: acc.x + coord.x,\n\t\t\ty: acc.y + coord.y,\n\t\t}),\n\t\t{ x: 0, y: 0 },\n\t);\n\tcentroid.x /= webMercatorCoords.length;\n\tcentroid.y /= webMercatorCoords.length;\n\n\t// Rotate the coordinates around the centroid\n\tconst rotatedWebMercatorCoords = webMercatorCoords.map((coord) => ({\n\t\tx:\n\t\t\tcentroid.x +\n\t\t\t(coord.x - centroid.x) * Math.cos(angleRad) -\n\t\t\t(coord.y - centroid.y) * Math.sin(angleRad),\n\t\ty:\n\t\t\tcentroid.y +\n\t\t\t(coord.x - centroid.x) * Math.sin(angleRad) +\n\t\t\t(coord.y - centroid.y) * Math.cos(angleRad),\n\t}));\n\n\t// Convert rotated Web Mercator coordinates back to geographic\n\tconst rotatedCoordinates = rotatedWebMercatorCoords.map(\n\t\t({ x, y }) =>\n\t\t\t[\n\t\t\t\twebMercatorXYToLngLat(x, y).lng,\n\t\t\t\twebMercatorXYToLngLat(x, y).lat,\n\t\t\t] as Position,\n\t);\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\tfeature.geometry.coordinates[0] = rotatedCoordinates;\n\t} else {\n\t\tfeature.geometry.coordinates = rotatedCoordinates;\n\t}\n\n\treturn feature;\n};\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { haversineDistanceKilometers } from \"../../../geometry/measure/haversine-distance\";\nimport {\n\ttransformScale,\n\ttransformScaleWebMercator,\n} from \"../../../geometry/transform/scale\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId } from \"../../../store/store\";\nimport { webMercatorCentroid } from \"../../../geometry/web-mercator-centroid\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../../geometry/project/web-mercator\";\nimport { cartesianDistance } from \"../../../geometry/measure/pixel-distance\";\n\nexport class ScaleFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate lastDistance: number | undefined;\n\n\treset() {\n\t\tthis.lastDistance = undefined;\n\t}\n\n\tscale(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t\tvalidateFeature?: Validation,\n\t) {\n\t\tconst geometry = this.store.getGeometryCopy<LineString | Polygon>(\n\t\t\tselectedId,\n\t\t);\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mouseCoord = [event.lng, event.lat];\n\n\t\tconst feature = { type: \"Feature\", geometry, properties: {} } as Feature<\n\t\t\tPolygon | LineString\n\t\t>;\n\n\t\tlet distance;\n\n\t\tconst originWebMercator = webMercatorCentroid(feature);\n\n\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\tconst selectedWebMercator = lngLatToWebMercatorXY(event.lng, event.lat);\n\t\t\tdistance = cartesianDistance(originWebMercator, selectedWebMercator);\n\t\t} else if (this.config.projection === \"globe\") {\n\t\t\tdistance = haversineDistanceKilometers(\n\t\t\t\tcentroid({ type: \"Feature\", geometry, properties: {} }),\n\t\t\t\tmouseCoord,\n\t\t\t);\n\t\t} else {\n\t\t\tthrow new Error(\"Invalid projection\");\n\t\t}\n\n\t\t// We need an original bearing to compare against\n\t\tif (!this.lastDistance) {\n\t\t\tthis.lastDistance = distance;\n\t\t\treturn;\n\t\t}\n\n\t\tconst scale = 1 - (this.lastDistance - distance) / distance;\n\n\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(\n\t\t\t\toriginWebMercator.x,\n\t\t\t\toriginWebMercator.y,\n\t\t\t);\n\t\t\ttransformScaleWebMercator(feature, scale, [lng, lat]);\n\t\t} else if (this.config.projection === \"globe\") {\n\t\t\tconst origin = centroid(feature);\n\t\t\ttransformScale(feature, scale, origin);\n\t\t}\n\n\t\t// Coordinates are either polygon or linestring at this point\n\t\tconst updatedCoords: Position[] =\n\t\t\tgeometry.type === \"Polygon\"\n\t\t\t\t? geometry.coordinates[0]\n\t\t\t\t: geometry.coordinates;\n\n\t\t// Ensure that coordinate precision is maintained\n\t\tupdatedCoords.forEach((coordinate) => {\n\t\t\tcoordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n\t\t\tcoordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n\t\t});\n\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tif (validateFeature) {\n\t\t\tif (\n\t\t\t\t!validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: selectedId,\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{ id: selectedId, geometry },\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\tthis.lastDistance = distance;\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n// import { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\n\n// Adapted from the @turf/transform-scale module which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-transform-scale\n\nexport function transformScale(\n\tfeature: Feature<Polygon | LineString>,\n\tfactor: number,\n\torigin: Position,\n\taxis: \"x\" | \"y\" | \"xy\" = \"xy\",\n) {\n\t// Shortcut no-scaling\n\tif (factor === 1) {\n\t\treturn feature;\n\t}\n\n\tconst cooordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tcooordinates.forEach((pointCoords: Position) => {\n\t\tconst originalDistance = rhumbDistance(origin, pointCoords);\n\t\tconst bearing = rhumbBearing(origin, pointCoords);\n\t\tconst newDistance = originalDistance * factor;\n\t\tconst newCoord = rhumbDestination(origin, newDistance, bearing);\n\n\t\tif (axis === \"x\" || axis === \"xy\") {\n\t\t\tpointCoords[0] = newCoord[0];\n\t\t}\n\n\t\tif (axis === \"y\" || axis === \"xy\") {\n\t\t\tpointCoords[1] = newCoord[1];\n\t\t}\n\t});\n\n\treturn feature;\n}\n\n/**\n * Scale a GeoJSON Polygon geometry in web mercator\n * @param polygon - GeoJSON Polygon geometry\n * @param scale - scaling factor\n * @returns - scaled GeoJSON Polygon geometry\n */\nexport function transformScaleWebMercator(\n\tfeature: Feature<Polygon | LineString>,\n\tfactor: number,\n\torigin: Position,\n): Feature<Polygon | LineString> {\n\tif (factor === 1) {\n\t\treturn feature;\n\t}\n\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\t// Convert polygon coordinates to Web Mercator\n\tconst webMercatorCoords = coordinates.map(([lng, lat]) =>\n\t\tlngLatToWebMercatorXY(lng, lat),\n\t);\n\n\tconst originWebMercator = lngLatToWebMercatorXY(origin[0], origin[1]);\n\n\t// Scale the coordinates around the centroid\n\tconst scaledWebMercatorCoords = webMercatorCoords.map((coord) => ({\n\t\tx: originWebMercator.x + (coord.x - originWebMercator.x) * factor,\n\t\ty: originWebMercator.y + (coord.y - originWebMercator.y) * factor,\n\t}));\n\n\t// Convert scaled Web Mercator coordinates back to geographic\n\tconst scaledCoordinates = scaledWebMercatorCoords.map(({ x, y }) => [\n\t\twebMercatorXYToLngLat(x, y).lng,\n\t\twebMercatorXYToLngLat(x, y).lat,\n\t]);\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\tfeature.geometry.coordinates[0] = scaledCoordinates;\n\t} else {\n\t\tfeature.geometry.coordinates = scaledCoordinates;\n\t}\n\n\treturn feature;\n}\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position, Point, Feature } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { FeatureId, GeoJSONStoreGeometries } from \"../../../store/store\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { cartesianDistance } from \"../../../geometry/measure/pixel-distance\";\nimport { coordinateIsValid } from \"../../../geometry/boolean/is-valid-coordinate\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../../geometry/project/web-mercator\";\nimport { webMercatorCentroid } from \"../../../geometry/web-mercator-centroid\";\n\nexport type ResizeOptions =\n\t| \"center\"\n\t| \"opposite\"\n\t| \"center-fixed\"\n\t| \"opposite-fixed\";\n\ntype BoundingBoxIndex = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\ntype BoundingBox = readonly [\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n];\n\nexport class DragCoordinateResizeBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate minimumScale = 0.0001;\n\n\tprivate draggedCoordinate: { id: null | FeatureId; index: number } = {\n\t\tid: null,\n\t\tindex: -1,\n\t};\n\n\t// This map provides the oppsite corner of the bbox\n\t// to the index of the coordinate provided\n\t//   0    1    2\n\t//   *----*----*\n\t// \t |\t\t   |\n\t// 7 *\t\t   *  3\n\t//   |\t\t   |\n\t//   *----*----*\n\t// \t 6    5    4\n\t//\n\tprivate boundingBoxMaps = {\n\t\topposite: {\n\t\t\t0: 4,\n\t\t\t1: 5,\n\t\t\t2: 6,\n\t\t\t3: 7,\n\t\t\t4: 0,\n\t\t\t5: 1,\n\t\t\t6: 2,\n\t\t\t7: 3,\n\t\t},\n\t};\n\n\tprivate getClosestCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tgeometry: Polygon | LineString | Point,\n\t) {\n\t\tconst closestCoordinate = {\n\t\t\tdist: Infinity,\n\t\t\tindex: -1,\n\t\t\tisFirstOrLastPolygonCoord: false,\n\t\t};\n\n\t\tlet geomCoordinates: Position[] | undefined;\n\n\t\tif (geometry.type === \"LineString\") {\n\t\t\tgeomCoordinates = geometry.coordinates;\n\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\tgeomCoordinates = geometry.coordinates[0];\n\t\t} else {\n\t\t\t// We don't want to handle dragging\n\t\t\t// points here\n\t\t\treturn closestCoordinate;\n\t\t}\n\n\t\t// Look through the selected features coordinates\n\t\t// and try to find a coordinate that is draggable\n\t\tfor (let i = 0; i < geomCoordinates.length; i++) {\n\t\t\tconst coord = geomCoordinates[i];\n\t\t\tconst distance = this.pixelDistance.measure(event, coord);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < closestCoordinate.dist\n\t\t\t) {\n\t\t\t\t// We don't create a point for the final\n\t\t\t\t// polygon coord, so we must set it to the first\n\t\t\t\t// coordinate instead\n\t\t\t\tconst isFirstOrLastPolygonCoord =\n\t\t\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t\t\t(i === geomCoordinates.length - 1 || i === 0);\n\n\t\t\t\tclosestCoordinate.dist = distance;\n\t\t\t\tclosestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n\t\t\t\tclosestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n\t\t\t}\n\t\t}\n\n\t\treturn closestCoordinate;\n\t}\n\n\tprivate isValidDragWebMercator(\n\t\tindex: BoundingBoxIndex,\n\t\tdistanceX: number,\n\t\tdistanceY: number,\n\t) {\n\t\tswitch (index) {\n\t\t\tcase 0:\n\t\t\t\tif (distanceX <= 0 || distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tif (distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (distanceX >= 0 || distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tif (distanceX >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif (distanceX >= 0 || distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tif (distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tif (distanceX <= 0 || distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\tif (distanceX <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate getSelectedFeatureDataWebMercator() {\n\t\tif (!this.draggedCoordinate.id || this.draggedCoordinate.index === -1) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst feature = this.getFeature(this.draggedCoordinate.id);\n\t\tif (!feature) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updatedCoords = this.getNormalisedCoordinates(feature.geometry);\n\t\tconst boundingBox = this.getBBoxWebMercator(updatedCoords);\n\n\t\treturn {\n\t\t\tboundingBox,\n\t\t\tfeature,\n\t\t\tupdatedCoords,\n\t\t\tselectedCoordinate: updatedCoords[this.draggedCoordinate.index],\n\t\t};\n\t}\n\n\tprivate centerWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\t\tconst { feature, boundingBox, updatedCoords, selectedCoordinate } =\n\t\t\tfeatureData;\n\n\t\tconst webMercatorOrigin = webMercatorCentroid(feature);\n\n\t\tif (!webMercatorOrigin) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate centerFixedWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\t\tconst { feature, boundingBox, updatedCoords, selectedCoordinate } =\n\t\t\tfeatureData;\n\n\t\tconst webMercatorOrigin = webMercatorCentroid(feature);\n\n\t\tif (!webMercatorOrigin) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleFixedWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate scaleFixedWebMercator({\n\t\tclosestBBoxIndex,\n\t\twebMercatorOrigin,\n\t\twebMercatorSelected,\n\t\twebMercatorCursor,\n\t\tupdatedCoords,\n\t}: {\n\t\tclosestBBoxIndex: BoundingBoxIndex;\n\t\tupdatedCoords: Position[];\n\t\twebMercatorCursor: { x: number; y: number };\n\t\twebMercatorSelected: { x: number; y: number };\n\t\twebMercatorOrigin: { x: number; y: number };\n\t}) {\n\t\tconst cursorDistanceX = webMercatorOrigin.x - webMercatorCursor.x;\n\t\tconst cursorDistanceY = webMercatorOrigin.y - webMercatorCursor.y;\n\n\t\tconst valid = this.isValidDragWebMercator(\n\t\t\tclosestBBoxIndex,\n\t\t\tcursorDistanceX,\n\t\t\tcursorDistanceY,\n\t\t);\n\n\t\tif (!valid) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet scale =\n\t\t\tcartesianDistance(webMercatorOrigin, webMercatorCursor) /\n\t\t\tcartesianDistance(webMercatorOrigin, webMercatorSelected);\n\n\t\tif (scale < 0) {\n\t\t\tscale = this.minimumScale;\n\t\t}\n\n\t\tthis.performWebMercatorScale(\n\t\t\tupdatedCoords,\n\t\t\twebMercatorOrigin.x,\n\t\t\twebMercatorOrigin.y,\n\t\t\tscale,\n\t\t\tscale,\n\t\t);\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate oppositeFixedWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { boundingBox, updatedCoords, selectedCoordinate } = featureData;\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { oppositeBboxIndex, closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorOrigin = {\n\t\t\tx: boundingBox[oppositeBboxIndex][0],\n\t\t\ty: boundingBox[oppositeBboxIndex][1],\n\t\t};\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleFixedWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate oppositeWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { boundingBox, updatedCoords, selectedCoordinate } = featureData;\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { oppositeBboxIndex, closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorOrigin = {\n\t\t\tx: boundingBox[oppositeBboxIndex][0],\n\t\t\ty: boundingBox[oppositeBboxIndex][1],\n\t\t};\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate scaleWebMercator({\n\t\tclosestBBoxIndex,\n\t\twebMercatorOrigin,\n\t\twebMercatorSelected,\n\t\twebMercatorCursor,\n\t\tupdatedCoords,\n\t}: {\n\t\tclosestBBoxIndex: BoundingBoxIndex;\n\t\tupdatedCoords: Position[];\n\t\twebMercatorCursor: { x: number; y: number };\n\t\twebMercatorSelected: { x: number; y: number };\n\t\twebMercatorOrigin: { x: number; y: number };\n\t}) {\n\t\tconst cursorDistanceX = webMercatorOrigin.x - webMercatorCursor.x;\n\t\tconst cursorDistanceY = webMercatorOrigin.y - webMercatorCursor.y;\n\n\t\tconst valid = this.isValidDragWebMercator(\n\t\t\tclosestBBoxIndex,\n\t\t\tcursorDistanceX,\n\t\t\tcursorDistanceY,\n\t\t);\n\n\t\tif (!valid) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet xScale = 1;\n\t\tif (\n\t\t\tcursorDistanceX !== 0 &&\n\t\t\tclosestBBoxIndex !== 1 &&\n\t\t\tclosestBBoxIndex !== 5\n\t\t) {\n\t\t\tconst currentDistanceX = webMercatorOrigin.x - webMercatorSelected.x;\n\t\t\txScale = 1 - (currentDistanceX - cursorDistanceX) / cursorDistanceX;\n\t\t}\n\n\t\tlet yScale = 1;\n\t\tif (\n\t\t\tcursorDistanceY !== 0 &&\n\t\t\tclosestBBoxIndex !== 3 &&\n\t\t\tclosestBBoxIndex !== 7\n\t\t) {\n\t\t\tconst currentDistanceY = webMercatorOrigin.y - webMercatorSelected.y;\n\t\t\tyScale = 1 - (currentDistanceY - cursorDistanceY) / cursorDistanceY;\n\t\t}\n\n\t\tif (!this.validateScale(xScale, yScale)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (xScale < 0) {\n\t\t\txScale = this.minimumScale;\n\t\t}\n\n\t\tif (yScale < 0) {\n\t\t\tyScale = this.minimumScale;\n\t\t}\n\n\t\tthis.performWebMercatorScale(\n\t\t\tupdatedCoords,\n\t\t\twebMercatorOrigin.x,\n\t\t\twebMercatorOrigin.y,\n\t\t\txScale,\n\t\t\tyScale,\n\t\t);\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate getFeature(id: FeatureId) {\n\t\tif (this.draggedCoordinate.id === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst geometry = this.store.getGeometryCopy(id);\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst feature = { type: \"Feature\", geometry, properties: {} } as Feature<\n\t\t\tPolygon | LineString\n\t\t>;\n\n\t\treturn feature;\n\t}\n\n\tprivate getNormalisedCoordinates(geometry: Polygon | LineString) {\n\t\t// Coordinates are either polygon or linestring at this point\n\t\treturn geometry.type === \"Polygon\"\n\t\t\t? geometry.coordinates[0]\n\t\t\t: geometry.coordinates;\n\t}\n\n\tprivate validateScale(xScale: number, yScale: number) {\n\t\tconst validX = !isNaN(xScale) && yScale < Number.MAX_SAFE_INTEGER;\n\t\tconst validY = !isNaN(yScale) && yScale < Number.MAX_SAFE_INTEGER;\n\n\t\treturn validX && validY;\n\t}\n\n\tprivate performWebMercatorScale(\n\t\tcoordinates: Position[],\n\t\toriginX: number,\n\t\toriginY: number,\n\t\txScale: number,\n\t\tyScale: number,\n\t) {\n\t\tcoordinates.forEach((coordinate) => {\n\t\t\tconst { x, y } = lngLatToWebMercatorXY(coordinate[0], coordinate[1]);\n\n\t\t\tconst updatedX = originX + (x - originX) * xScale;\n\t\t\tconst updatedY = originY + (y - originY) * yScale;\n\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(updatedX, updatedY);\n\n\t\t\tcoordinate[0] = lng;\n\t\t\tcoordinate[1] = lat;\n\t\t});\n\t}\n\n\tprivate getBBoxWebMercator(coordinates: Position[]) {\n\t\tconst bbox: [number, number, number, number] = [\n\t\t\tInfinity,\n\t\t\tInfinity,\n\t\t\t-Infinity,\n\t\t\t-Infinity,\n\t\t];\n\n\t\t// Convert from [lng, lat] -> [x, y]\n\t\tcoordinates = coordinates.map((coord) => {\n\t\t\tconst { x, y } = lngLatToWebMercatorXY(coord[0], coord[1]);\n\t\t\treturn [x, y];\n\t\t});\n\n\t\tcoordinates.forEach(([x, y]) => {\n\t\t\tif (x < bbox[0]) {\n\t\t\t\tbbox[0] = x;\n\t\t\t}\n\n\t\t\tif (y < bbox[1]) {\n\t\t\t\tbbox[1] = y;\n\t\t\t}\n\n\t\t\tif (x > bbox[2]) {\n\t\t\t\tbbox[2] = x;\n\t\t\t}\n\n\t\t\tif (y > bbox[3]) {\n\t\t\t\tbbox[3] = y;\n\t\t\t}\n\t\t});\n\n\t\tconst [west, south, east, north] = bbox;\n\n\t\t//   Bounding box is represnted as follows:\n\t\t//\n\t\t//   0    1    2\n\t\t//   *----*----*\n\t\t// \t |\t\t   |\n\t\t// 7 *\t\t   *  3\n\t\t//   |\t\t   |\n\t\t//   *----*----*\n\t\t// \t 6    5    4\n\t\t//\n\t\tconst topLeft = [west, north];\n\t\tconst topRight = [east, north];\n\t\tconst lowRight = [east, south];\n\t\tconst lowLeft = [west, south];\n\n\t\tconst midTop = [(west + east) / 2, north];\n\t\tconst midRight = [east, north + (south - north) / 2];\n\t\tconst midBottom = [(west + east) / 2, south];\n\t\tconst midLeft = [west, north + (south - north) / 2];\n\n\t\treturn [\n\t\t\ttopLeft, // 0\n\t\t\tmidTop, // 1\n\t\t\ttopRight, // 2\n\t\t\tmidRight, // 3\n\t\t\tlowRight, // 4\n\t\t\tmidBottom, // 5\n\t\t\tlowLeft, // 6\n\t\t\tmidLeft, // 7\n\t\t] as const;\n\t}\n\n\tprivate getIndexesWebMercator(\n\t\tboundingBox: BoundingBox,\n\t\tselectedXY: { x: number; y: number },\n\t) {\n\t\tlet closestIndex: BoundingBoxIndex | undefined;\n\t\tlet closestDistance = Infinity;\n\n\t\tfor (let i = 0; i < boundingBox.length; i++) {\n\t\t\tconst distance = cartesianDistance(\n\t\t\t\t{ x: selectedXY.x, y: selectedXY.y },\n\t\t\t\t{ x: boundingBox[i][0], y: boundingBox[i][1] },\n\t\t\t);\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestIndex = i as BoundingBoxIndex;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t}\n\n\t\tif (closestIndex === undefined) {\n\t\t\tthrow new Error(\"No closest coordinate found\");\n\t\t}\n\n\t\t// Depending on where what the origin is set to, we need to find the position to\n\t\t// scale from\n\t\tconst oppositeIndex = this.boundingBoxMaps[\"opposite\"][\n\t\t\tclosestIndex\n\t\t] as BoundingBoxIndex;\n\n\t\treturn {\n\t\t\toppositeBboxIndex: oppositeIndex,\n\t\t\tclosestBBoxIndex: closestIndex,\n\t\t} as const;\n\t}\n\n\t/**\n\t * @returns - true if the feature is being dragged (resized), false otherwise\n\t */\n\tpublic isDragging() {\n\t\treturn this.draggedCoordinate.id !== null;\n\t}\n\n\t/**\n\t * Starts the resizing of the feature\n\t * @param id - feature id of the feature that is being dragged\n\t * @param index - index of the coordinate that is being dragged\n\t * @returns - void\n\t */\n\tpublic startDragging(id: FeatureId, index: number) {\n\t\tthis.draggedCoordinate = {\n\t\t\tid,\n\t\t\tindex,\n\t\t};\n\t}\n\n\t/**\n\t * Stops the resizing of the feature\n\t * @returns - void\t *\n\t */\n\tpublic stopDragging() {\n\t\tthis.draggedCoordinate = {\n\t\t\tid: null,\n\t\t\tindex: -1,\n\t\t};\n\t}\n\n\t/**\n\t * Returns the index of the coordinate that is going to be dragged\n\t * @param event - cursor event\n\t * @param selectedId - feature id of the feature that is selected\n\t * @returns - the index to be dragged\n\t */\n\tpublic getDraggableIndex(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t): number {\n\t\tconst geometry = this.store.getGeometryCopy(selectedId);\n\t\tconst closestCoordinate = this.getClosestCoordinate(event, geometry);\n\n\t\t// No coordinate was within the pointer distance\n\t\tif (closestCoordinate.index === -1) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn closestCoordinate.index;\n\t}\n\n\t/**\n\t * Resizes the feature based on the cursor event\n\t * @param event - cursor event\n\t * @param resizeOption - the resize option, either \"center\" or \"opposite\"\n\t * @returns - true is resize was successful, false otherwise\n\t */\n\tpublic drag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tresizeOption: ResizeOptions,\n\t\tvalidateFeature?: Validation,\n\t): boolean {\n\t\tif (!this.draggedCoordinate.id) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst feature = this.getFeature(this.draggedCoordinate.id);\n\t\tif (!feature) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet updatedCoords: Position[] | null = null;\n\n\t\tif (resizeOption === \"center\") {\n\t\t\tupdatedCoords = this.centerWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite\") {\n\t\t\tupdatedCoords = this.oppositeWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"center-fixed\") {\n\t\t\tupdatedCoords = this.centerFixedWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite-fixed\") {\n\t\t\tupdatedCoords = this.oppositeFixedWebMercatorDrag(event);\n\t\t}\n\n\t\tif (!updatedCoords) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Ensure that coordinate precision is maintained\n\t\tfor (let i = 0; i < updatedCoords.length; i++) {\n\t\t\tconst coordinate = updatedCoords[i];\n\t\t\tcoordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n\t\t\tcoordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n\n\t\t\t// Ensure the coordinate we are about to update with is valid\n\t\t\tif (!coordinateIsValid(coordinate, this.coordinatePrecision)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Perform the update to the midpoints and selection points\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedGeometry = {\n\t\t\ttype: feature.geometry.type as \"Polygon\" | \"LineString\",\n\t\t\tcoordinates:\n\t\t\t\tfeature.geometry.type === \"Polygon\" ? [updatedCoords] : updatedCoords,\n\t\t} as GeoJSONStoreGeometries;\n\n\t\tif (validateFeature) {\n\t\t\tconst valid = validateFeature(\n\t\t\t\t{\n\t\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\tgeometry: updatedGeometry,\n\t\t\t},\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\treturn true;\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawKeyboardEvent,\n\tSELECT_PROPERTIES,\n\tTerraDrawAdapterStyling,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tValidation,\n\tUpdateTypes,\n} from \"../../common\";\nimport { Point, Position } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseSelectMode,\n} from \"../base.mode\";\nimport { MidPointBehavior } from \"./behaviors/midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./behaviors/selection-point.behavior\";\nimport { FeatureAtPointerEventBehavior } from \"./behaviors/feature-at-pointer-event.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { DragFeatureBehavior } from \"./behaviors/drag-feature.behavior\";\nimport { DragCoordinateBehavior } from \"./behaviors/drag-coordinate.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { RotateFeatureBehavior } from \"./behaviors/rotate-feature.behavior\";\nimport { ScaleFeatureBehavior } from \"./behaviors/scale-feature.behavior\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tDragCoordinateResizeBehavior,\n\tResizeOptions,\n} from \"./behaviors/drag-coordinate-resize.behavior\";\n\ntype TerraDrawSelectModeKeyEvents = {\n\tdeselect: KeyboardEvent[\"key\"] | null;\n\tdelete: KeyboardEvent[\"key\"] | null;\n\trotate: KeyboardEvent[\"key\"][] | null;\n\tscale: KeyboardEvent[\"key\"][] | null;\n};\n\ntype ModeFlags = {\n\tfeature?: {\n\t\tvalidation?: Validation;\n\t\tdraggable?: boolean;\n\t\trotateable?: boolean;\n\t\tscaleable?: boolean;\n\t\tselfIntersectable?: boolean;\n\t\tcoordinates?: {\n\t\t\tmidpoints?: boolean;\n\t\t\tdraggable?: boolean;\n\t\t\tresizable?: ResizeOptions;\n\t\t\tdeletable?: boolean;\n\t\t};\n\t};\n};\n\ntype SelectionStyling = {\n\t// Point\n\tselectedPointColor: HexColorStyling;\n\tselectedPointWidth: NumericStyling;\n\tselectedPointOutlineColor: HexColorStyling;\n\tselectedPointOutlineWidth: NumericStyling;\n\n\t// LineString\n\tselectedLineStringColor: HexColorStyling;\n\tselectedLineStringWidth: NumericStyling;\n\n\t// Polygon\n\tselectedPolygonColor: HexColorStyling;\n\tselectedPolygonFillOpacity: NumericStyling;\n\tselectedPolygonOutlineColor: HexColorStyling;\n\tselectedPolygonOutlineWidth: NumericStyling;\n\n\t// Selection Points (points at vertices of a polygon/linestring feature)\n\tselectionPointWidth: NumericStyling;\n\tselectionPointColor: HexColorStyling;\n\tselectionPointOutlineColor: HexColorStyling;\n\tselectionPointOutlineWidth: NumericStyling;\n\n\t// Mid points (points at mid point of a polygon/linestring feature)\n\tmidPointColor: HexColorStyling;\n\tmidPointOutlineColor: HexColorStyling;\n\tmidPointWidth: NumericStyling;\n\tmidPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tpointerOver?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n\tinsertMidpoint?: Cursor;\n}\n\ninterface TerraDrawSelectModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tpointerDistance?: number;\n\tflags?: { [mode: string]: ModeFlags };\n\tkeyEvents?: TerraDrawSelectModeKeyEvents | null;\n\tdragEventThrottle?: number;\n\tcursors?: Cursors;\n\tallowManualDeselection?: boolean;\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseSelectMode<SelectionStyling> {\n\tpublic mode = \"select\";\n\n\tprivate allowManualDeselection = true;\n\tprivate dragEventThrottle = 5;\n\tprivate dragEventCount = 0;\n\tprivate selected: FeatureId[] = [];\n\n\tprivate flags: { [mode: string]: ModeFlags };\n\tprivate keyEvents: TerraDrawSelectModeKeyEvents;\n\n\t// Behaviors\n\tprivate selectionPoints!: SelectionPointBehavior;\n\tprivate midPoints!: MidPointBehavior;\n\tprivate featuresAtMouseEvent!: FeatureAtPointerEventBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate dragFeature!: DragFeatureBehavior;\n\tprivate dragCoordinate!: DragCoordinateBehavior;\n\tprivate rotateFeature!: RotateFeatureBehavior;\n\tprivate scaleFeature!: ScaleFeatureBehavior;\n\tprivate dragCoordinateResizeFeature!: DragCoordinateResizeBehavior;\n\tprivate cursors: Required<Cursors>;\n\tprivate validations: Record<string, Validation> = {};\n\n\tconstructor(options?: TerraDrawSelectModeOptions<SelectionStyling>) {\n\t\tsuper(options);\n\n\t\tthis.flags = options && options.flags ? options.flags : {};\n\n\t\tconst defaultCursors = {\n\t\t\tpointerOver: \"move\",\n\t\t\tdragStart: \"move\",\n\t\t\tdragEnd: \"move\",\n\t\t\tinsertMidpoint: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = {\n\t\t\t\tdeselect: null,\n\t\t\t\tdelete: null,\n\t\t\t\trotate: null,\n\t\t\t\tscale: null,\n\t\t\t};\n\t\t} else {\n\t\t\tconst defaultKeyEvents = {\n\t\t\t\tdeselect: \"Escape\",\n\t\t\t\tdelete: \"Delete\",\n\t\t\t\trotate: [\"Control\", \"r\"],\n\t\t\t\tscale: [\"Control\", \"s\"],\n\t\t\t};\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.dragEventThrottle =\n\t\t\t(options &&\n\t\t\t\toptions.dragEventThrottle !== undefined &&\n\t\t\t\toptions.dragEventThrottle) ||\n\t\t\t5;\n\n\t\tthis.allowManualDeselection = options?.allowManualDeselection ?? true;\n\n\t\t// Validations\n\t\tif (options && options.flags && options.flags) {\n\t\t\tfor (const mode in options.flags) {\n\t\t\t\tconst feature = options.flags[mode].feature;\n\t\t\t\tif (feature && feature.validation) {\n\t\t\t\t\tthis.validations[mode] = feature.validation as (\n\t\t\t\t\t\tfeature: GeoJSONStoreFeatures,\n\t\t\t\t\t) => boolean;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tselectFeature(featureId: FeatureId) {\n\t\tthis.select(featureId, false);\n\t}\n\n\tsetSelecting() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"selecting\";\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be started to move to selecting state\");\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.featuresAtMouseEvent = new FeatureAtPointerEventBehavior(\n\t\t\tconfig,\n\t\t\tthis.clickBoundingBox,\n\t\t\tthis.pixelDistance,\n\t\t);\n\n\t\tthis.selectionPoints = new SelectionPointBehavior(config);\n\t\tthis.midPoints = new MidPointBehavior(config, this.selectionPoints);\n\n\t\tthis.rotateFeature = new RotateFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\n\t\tthis.scaleFeature = new ScaleFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\n\t\tthis.dragFeature = new DragFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.featuresAtMouseEvent,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\t\tthis.dragCoordinate = new DragCoordinateBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\t\tthis.dragCoordinateResizeFeature = new DragCoordinateResizeBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\t}\n\n\tpublic deselectFeature() {\n\t\tthis.deselect();\n\t}\n\n\tprivate deselect() {\n\t\tconst updateSelectedFeatures = this.selected\n\t\t\t.filter((id) => this.store.has(id))\n\t\t\t.map((id) => ({\n\t\t\t\tid,\n\t\t\t\tproperty: SELECT_PROPERTIES.SELECTED,\n\t\t\t\tvalue: false,\n\t\t\t}));\n\n\t\tthis.store.updateProperty(updateSelectedFeatures);\n\n\t\tthis.onDeselect(this.selected[0]);\n\t\tthis.selected = [];\n\t\tthis.selectionPoints.delete();\n\t\tthis.midPoints.delete();\n\t}\n\n\tprivate deleteSelected() {\n\t\t// Delete all selected features\n\t\t// from the store and clear selected\n\t\t// We don't need to set selected false\n\t\t// as we're going to delete the feature\n\n\t\tthis.store.delete(this.selected);\n\t\tthis.selected = [];\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\tif (!this.selectionPoints.ids.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet clickedSelectionPointProps:\n\t\t\t| {\n\t\t\t\t\tselectionPointFeatureId: string;\n\t\t\t\t\tindex: number;\n\t\t\t  }\n\t\t\t| undefined;\n\n\t\tlet clickedFeatureDistance = Infinity;\n\n\t\tthis.selectionPoints.ids.forEach((id) => {\n\t\t\tconst geometry = this.store.getGeometryCopy<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < clickedFeatureDistance\n\t\t\t) {\n\t\t\t\tclickedFeatureDistance = distance;\n\t\t\t\tclickedSelectionPointProps = this.store.getPropertiesCopy(id) as {\n\t\t\t\t\tselectionPointFeatureId: string;\n\t\t\t\t\tindex: number;\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\tif (!clickedSelectionPointProps) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = clickedSelectionPointProps.selectionPointFeatureId;\n\t\tconst coordinateIndex = clickedSelectionPointProps.index;\n\n\t\t// We allow for preventing deleting coordinates via flags\n\t\tconst properties = this.store.getPropertiesCopy(featureId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst validation = this.validations[properties.mode as string];\n\n\t\t// Check if we can actually delete the coordinate\n\t\tconst cannotDelete =\n\t\t\t!modeFlags ||\n\t\t\t!modeFlags.feature ||\n\t\t\t!modeFlags.feature.coordinates ||\n\t\t\t!modeFlags.feature.coordinates.deletable;\n\n\t\tif (cannotDelete) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.store.getGeometryCopy(featureId);\n\n\t\tlet coordinates;\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tcoordinates = geometry.coordinates[0];\n\n\t\t\t// Prevent creating an invalid polygon\n\t\t\tif (coordinates.length <= 4) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tcoordinates = geometry.coordinates;\n\n\t\t\t// Prevent creating an invalid linestring\n\t\t\tif (coordinates.length <= 3) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Geometry is not Polygon or LineString\n\t\tif (!coordinates) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\t(geometry.type === \"Polygon\" && coordinateIndex === 0) ||\n\t\t\tcoordinateIndex === coordinates.length - 1\n\t\t) {\n\t\t\t// Deleting the final coordinate in a polygon breaks it\n\t\t\t// because GeoJSON expects a duplicate, so we need to fix\n\t\t\t// it by adding the new first coordinate to the end\n\t\t\tcoordinates.shift();\n\t\t\tcoordinates.pop();\n\t\t\tcoordinates.push([coordinates[0][0], coordinates[0][1]]);\n\t\t} else {\n\t\t\t// Remove coordinate from array\n\t\t\tcoordinates.splice(coordinateIndex, 1);\n\t\t}\n\n\t\t// Validate the new geometry\n\t\tif (validation) {\n\t\t\tconst valid = validation(\n\t\t\t\t{\n\t\t\t\t\tid: featureId,\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry,\n\t\t\t\t\tproperties,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType: UpdateTypes.Commit,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.delete([...this.midPoints.ids, ...this.selectionPoints.ids]);\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: featureId,\n\t\t\t\tgeometry,\n\t\t\t},\n\t\t]);\n\n\t\tthis.selectionPoints.create(\n\t\t\tcoordinates,\n\t\t\tgeometry.type as \"Polygon\" | \"LineString\",\n\t\t\tfeatureId,\n\t\t);\n\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\tmodeFlags.feature.coordinates.midpoints\n\t\t) {\n\t\t\tthis.midPoints.create(coordinates, featureId, this.coordinatePrecision);\n\t\t}\n\t}\n\n\tprivate select(featureId: FeatureId, fromCursor = true) {\n\t\tif (this.selected[0] === featureId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { mode } = this.store.getPropertiesCopy(featureId);\n\n\t\t// This will be undefined for points\n\t\tconst modeFlags = this.flags[mode as string];\n\n\t\t// If feature is not selectable then return\n\t\tif (!modeFlags || !modeFlags.feature) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst previouslySelectedId = this.selected[0];\n\n\t\t// If we have something currently selected\n\t\tif (previouslySelectedId) {\n\t\t\t// If it matches the current selected feature id, do nothing\n\t\t\tif (previouslySelectedId === featureId) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t// If it's a different feature set selected\n\t\t\t\t// to false on previously selected feature\n\t\t\t\tthis.deselect();\n\t\t\t}\n\t\t}\n\n\t\tif (fromCursor) {\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t}\n\n\t\t// Select feature\n\t\tthis.selected = [featureId];\n\n\t\tthis.store.updateProperty([\n\t\t\t{ id: featureId, property: \"selected\", value: true },\n\t\t]);\n\t\tthis.onSelect(featureId);\n\n\t\t// Get the clicked feature\n\t\tconst { type, coordinates } = this.store.getGeometryCopy(featureId);\n\n\t\tif (type !== \"LineString\" && type !== \"Polygon\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// LineString does not have nesting so we can just take 'coordinates'\n\t\t// directly. Polygon is nested so we need to take [0] item in the array\n\t\tconst selectedCoords: Position[] =\n\t\t\ttype === \"LineString\" ? coordinates : coordinates[0];\n\n\t\tif (selectedCoords && modeFlags && modeFlags.feature.coordinates) {\n\t\t\tthis.selectionPoints.create(selectedCoords, type, featureId);\n\n\t\t\tif (modeFlags.feature.coordinates.midpoints) {\n\t\t\t\tthis.midPoints.create(\n\t\t\t\t\tselectedCoords,\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tthis.coordinatePrecision,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tconst { clickedFeature, clickedMidPoint } = this.featuresAtMouseEvent.find(\n\t\t\tevent,\n\t\t\tthis.selected.length > 0,\n\t\t);\n\n\t\tif (this.selected.length && clickedMidPoint) {\n\t\t\t// TODO: We probably want to make sure the midpoint\n\t\t\t// is visible?\n\n\t\t\tthis.midPoints.insert(\n\t\t\t\tclickedMidPoint.id as string,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (clickedFeature && clickedFeature.id) {\n\t\t\tthis.select(clickedFeature.id, true);\n\t\t} else if (this.selected.length && this.allowManualDeselection) {\n\t\t\tthis.deselect();\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setSelecting();\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStarted();\n\t\tthis.setStopped();\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (event.button === \"right\") {\n\t\t\tthis.onRightClick(event);\n\t\t\treturn;\n\t\t} else if (event.button === \"left\") {\n\t\t\tthis.onLeftClick(event);\n\t\t}\n\t}\n\n\tprivate canScale(event: TerraDrawKeyboardEvent | TerraDrawMouseEvent) {\n\t\treturn (\n\t\t\tthis.keyEvents.scale &&\n\t\t\tthis.keyEvents.scale.every((key) => event.heldKeys.includes(key))\n\t\t);\n\t}\n\n\tprivate canRotate(event: TerraDrawKeyboardEvent | TerraDrawMouseEvent) {\n\t\treturn (\n\t\t\tthis.keyEvents.rotate &&\n\t\t\tthis.keyEvents.rotate.every((key) => event.heldKeys.includes(key))\n\t\t);\n\t}\n\n\tprivate preventDefaultKeyEvent(event: TerraDrawKeyboardEvent) {\n\t\tconst isRotationKeys = this.canRotate(event);\n\t\tconst isScaleKeys = this.canScale(event);\n\n\t\t// If we are deliberately rotating or scaling then prevent default\n\t\tif (isRotationKeys || isScaleKeys) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown(event: TerraDrawKeyboardEvent) {\n\t\tthis.preventDefaultKeyEvent(event);\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tthis.preventDefaultKeyEvent(event);\n\n\t\tif (this.keyEvents.delete && event.key === this.keyEvents.delete) {\n\t\t\tif (!this.selected.length) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// We are technically deselecting\n\t\t\t// because the selected feature is deleted\n\t\t\t// and will no longer exist or be selected\n\t\t\tconst previouslySelected = this.selected[0];\n\t\t\tthis.onDeselect(previouslySelected);\n\n\t\t\t// Delete all selected features\n\t\t\tthis.deleteSelected();\n\n\t\t\t// Remove all selection points\n\t\t\tthis.selectionPoints.delete();\n\t\t\tthis.midPoints.delete();\n\t\t} else if (\n\t\t\tthis.keyEvents.deselect &&\n\t\t\tevent.key === this.keyEvents.deselect\n\t\t) {\n\t\t\tthis.cleanUp();\n\t\t}\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tif (this.selected.length) {\n\t\t\tthis.deselect();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tif (!this.selected.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the selected feature is not draggable\n\t\t// don't do anything\n\t\tconst properties = this.store.getPropertiesCopy(this.selected[0]);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst draggable =\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\t(modeFlags.feature.draggable ||\n\t\t\t\t(modeFlags.feature.coordinates &&\n\t\t\t\t\tmodeFlags.feature.coordinates.draggable) ||\n\t\t\t\t(modeFlags.feature.coordinates &&\n\t\t\t\t\tmodeFlags.feature.coordinates.resizable));\n\n\t\tif (!draggable) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.dragEventCount = 0;\n\n\t\tconst selectedId = this.selected[0];\n\t\tconst draggableCoordinateIndex = this.dragCoordinate.getDraggableIndex(\n\t\t\tevent,\n\t\t\tselectedId,\n\t\t);\n\n\t\t// Drag Coordinate\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\t(modeFlags.feature.coordinates.draggable ||\n\t\t\t\tmodeFlags.feature.coordinates.resizable) &&\n\t\t\tdraggableCoordinateIndex !== -1\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\t\t// With resizeable\n\t\t\tif (modeFlags.feature.coordinates.resizable) {\n\t\t\t\tthis.dragCoordinateResizeFeature.startDragging(\n\t\t\t\t\tselectedId,\n\t\t\t\t\tdraggableCoordinateIndex,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Without with resizable being set\n\t\t\t\tthis.dragCoordinate.startDragging(selectedId, draggableCoordinateIndex);\n\t\t\t}\n\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Drag Feature\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.draggable &&\n\t\t\tthis.dragFeature.canDrag(event, selectedId)\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\t\t\tthis.dragFeature.startDragging(event, selectedId);\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tconst selectedId = this.selected[0];\n\n\t\t// If nothing selected we can return early\n\t\tif (!selectedId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst properties = this.store.getPropertiesCopy(selectedId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst canSelfIntersect: boolean =\n\t\t\t(modeFlags &&\n\t\t\t\tmodeFlags.feature &&\n\t\t\t\tmodeFlags.feature.selfIntersectable) === true;\n\n\t\t// Ensure drag count is incremented\n\t\tthis.dragEventCount++;\n\n\t\t// Return if we haven't hit the drag throttle limit\n\t\t// (i.e. we only want to drag every nth event)\n\t\tif (this.dragEventCount % this.dragEventThrottle === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst validation = this.validations[properties.mode as string];\n\n\t\t// Check if should rotate\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.rotateable &&\n\t\t\tthis.canRotate(event)\n\t\t) {\n\t\t\tsetMapDraggability(false);\n\t\t\tthis.rotateFeature.rotate(event, selectedId, validation);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if should scale\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.scaleable &&\n\t\t\tthis.canScale(event)\n\t\t) {\n\t\t\tsetMapDraggability(false);\n\t\t\tthis.scaleFeature.scale(event, selectedId, validation);\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.dragCoordinateResizeFeature.isDragging() &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\tmodeFlags.feature.coordinates.resizable\n\t\t) {\n\t\t\tif (this.projection === \"globe\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Globe is currently unsupported projection for resizable\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetMapDraggability(false);\n\t\t\tthis.dragCoordinateResizeFeature.drag(\n\t\t\t\tevent,\n\t\t\t\tmodeFlags.feature.coordinates.resizable,\n\t\t\t\tvalidation,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if coordinate is draggable and is dragged\n\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\tthis.dragCoordinate.drag(event, canSelfIntersect, validation);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if feature is draggable and is dragged\n\t\tif (this.dragFeature.isDragging()) {\n\t\t\tthis.dragFeature.drag(event, validation);\n\t\t\treturn;\n\t\t}\n\n\t\tsetMapDraggability(true);\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\t_: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tthis.setCursor(this.cursors.dragEnd);\n\n\t\t// If we have finished dragging a coordinate or a feature\n\t\t// lets fire an onFinish event which can be listened to\n\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: \"dragCoordinate\",\n\t\t\t});\n\t\t} else if (this.dragFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: \"dragFeature\",\n\t\t\t});\n\t\t} else if (this.dragCoordinateResizeFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: \"dragCoordinateResize\",\n\t\t\t});\n\t\t}\n\n\t\tthis.dragCoordinate.stopDragging();\n\t\tthis.dragFeature.stopDragging();\n\t\tthis.dragCoordinateResizeFeature.stopDragging();\n\t\tthis.rotateFeature.reset();\n\t\tthis.scaleFeature.reset();\n\t\tsetMapDraggability(true);\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tif (!this.selected.length) {\n\t\t\tthis.setCursor(\"unset\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.dragFeature.isDragging()) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet nearbyMidPoint = false;\n\t\tthis.midPoints.ids.forEach((id: string) => {\n\t\t\tif (nearbyMidPoint) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst geometry = this.store.getGeometryCopy<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n\t\t\tif (distance < this.pointerDistance) {\n\t\t\t\tnearbyMidPoint = true;\n\t\t\t}\n\t\t});\n\n\t\tlet nearbySelectionPoint = false;\n\t\t// TODO: Is there a cleaner way to handle prioritising\n\t\t// dragging selection points?\n\t\tthis.selectionPoints.ids.forEach((id: FeatureId) => {\n\t\t\tconst geometry = this.store.getGeometryCopy<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\t\t\tif (distance < this.pointerDistance) {\n\t\t\t\tnearbyMidPoint = false;\n\t\t\t\tnearbySelectionPoint = true;\n\t\t\t}\n\t\t});\n\n\t\tif (nearbyMidPoint) {\n\t\t\tthis.setCursor(this.cursors.insertMidpoint);\n\t\t\treturn;\n\t\t}\n\n\t\t// If we have a feature under the pointer then show the pointer over cursor\n\t\tconst { clickedFeature: featureUnderPointer } =\n\t\t\tthis.featuresAtMouseEvent.find(event, true);\n\n\t\tif (\n\t\t\tthis.selected.length > 0 &&\n\t\t\t((featureUnderPointer && featureUnderPointer.id === this.selected[0]) ||\n\t\t\t\tnearbySelectionPoint)\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t} else {\n\t\t\t// Set it back to whatever the default cursor is\n\t\t\tthis.setCursor(\"unset\");\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.properties.mode === this.mode &&\n\t\t\tfeature.geometry.type === \"Point\"\n\t\t) {\n\t\t\tif (feature.properties.selectionPoint) {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectionPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 30;\n\n\t\t\t\treturn styles;\n\t\t\t}\n\n\t\t\tif (feature.properties.midPoint) {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.midPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.midPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointWidth,\n\t\t\t\t\t4,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 40;\n\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t} else if (feature.properties[SELECT_PROPERTIES.SELECTED]) {\n\t\t\t// Select mode shortcuts the styling of a feature if it is selected\n\t\t\t// A selected feature from another mode will end up in this block\n\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonOutlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonOutlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonFillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedLineStringColor,\n\t\t\t\t\tstyles.lineStringColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedLineStringWidth,\n\t\t\t\t\tstyles.lineStringWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOutlineWidth,\n\t\t\t\t\tstyles.pointOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { ModeTypes, TerraDrawBaseDrawMode } from \"../base.mode\";\n\n// TODO: Is there a better way to handle the following line?\n// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-types\ntype StaticModeStylingExt<T extends TerraDrawAdapterStyling> = {};\ntype StaticModeStyling = StaticModeStylingExt<TerraDrawAdapterStyling>;\n\nexport class TerraDrawStaticMode extends TerraDrawBaseDrawMode<StaticModeStyling> {\n\ttype = ModeTypes.Static;\n\tmode = \"static\";\n\tstart() {}\n\tstop() {}\n\tonKeyUp() {}\n\tonKeyDown() {}\n\tonClick() {}\n\tonDragStart() {}\n\tonDrag() {}\n\tonDragEnd() {}\n\tonMouseMove() {}\n\tcleanUp() {}\n\tstyleFeature() {\n\t\treturn { ...getDefaultStyling() };\n\t}\n}\n","// ISC License\n// Copyright (c) 2018, Vladimir Agafonkin\n\nexport type CompareFunction<T> = (a: T, b: T) => number;\n\nexport function quickselect<T>(\n\tarr: T[],\n\tk: number,\n\tleft: number,\n\tright: number,\n\tcompare: CompareFunction<T>,\n) {\n\twhile (right > left) {\n\t\tif (right - left > 600) {\n\t\t\tconst n = right - left + 1;\n\t\t\tconst m = k - left + 1;\n\t\t\tconst z = Math.log(n);\n\t\t\tconst s = 0.5 * Math.exp((2 * z) / 3);\n\t\t\tconst sd =\n\t\t\t\t0.5 * Math.sqrt((z * s * (n - s)) / n) * (m - n / 2 < 0 ? -1 : 1);\n\t\t\tconst newLeft = Math.max(left, Math.floor(k - (m * s) / n + sd));\n\t\t\tconst newRight = Math.min(right, Math.floor(k + ((n - m) * s) / n + sd));\n\t\t\tquickselect(arr, k, newLeft, newRight, compare);\n\t\t}\n\n\t\tconst t = arr[k];\n\t\tlet i = left;\n\t\tlet j = right;\n\n\t\tswap(arr, left, k);\n\t\tif (compare(arr[right], t) > 0) swap(arr, left, right);\n\n\t\twhile (i < j) {\n\t\t\tswap(arr, i, j);\n\t\t\ti++;\n\t\t\tj--;\n\t\t\twhile (compare(arr[i], t) < 0) i++;\n\t\t\twhile (compare(arr[j], t) > 0) j--;\n\t\t}\n\n\t\tif (compare(arr[left], t) === 0) {\n\t\t\tswap(arr, left, j);\n\t\t} else {\n\t\t\tj++;\n\t\t\tswap(arr, j, right);\n\t\t}\n\n\t\tif (j <= k) left = j + 1;\n\t\tif (k <= j) right = j - 1;\n\t}\n}\n\nfunction swap<T>(arr: T[], i: number, j: number) {\n\tconst tmp = arr[i];\n\tarr[i] = arr[j];\n\tarr[j] = tmp;\n}\n","// Base on Rbush - https://github.com/mourner/rbush\n// MIT License\n// Copyright (c) 2016 Vladimir Agafonkin\n\nimport { CompareFunction, quickselect } from \"./quickselect\";\n\nexport type Node = {\n\tchildren: Node[];\n\theight: number;\n\tleaf: boolean;\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n};\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node: Node, toBBox: (node: Node) => any) {\n\tdistBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(\n\tnode: Node,\n\tk: number,\n\tp: number,\n\ttoBBox: (node: Node) => Node,\n\tdestNode?: Node,\n) {\n\tif (!destNode) destNode = createNode([]);\n\tdestNode.minX = Infinity;\n\tdestNode.minY = Infinity;\n\tdestNode.maxX = -Infinity;\n\tdestNode.maxY = -Infinity;\n\n\tfor (let i = k; i < p; i++) {\n\t\tconst child = node.children[i];\n\t\textend(destNode, node.leaf ? toBBox(child) : child);\n\t}\n\n\treturn destNode;\n}\n\nfunction extend(a: Node, b: Node) {\n\ta.minX = Math.min(a.minX, b.minX);\n\ta.minY = Math.min(a.minY, b.minY);\n\ta.maxX = Math.max(a.maxX, b.maxX);\n\ta.maxY = Math.max(a.maxY, b.maxY);\n\treturn a;\n}\n\nfunction compareNodeMinX(a: Node, b: Node) {\n\treturn a.minX - b.minX;\n}\nfunction compareNodeMinY(a: Node, b: Node) {\n\treturn a.minY - b.minY;\n}\n\nfunction bboxArea(a: Node) {\n\treturn (a.maxX - a.minX) * (a.maxY - a.minY);\n}\nfunction bboxMargin(a: {\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n}) {\n\treturn a.maxX - a.minX + (a.maxY - a.minY);\n}\n\nfunction enlargedArea(a: Node, b: Node) {\n\treturn (\n\t\t(Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n\t\t(Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY))\n\t);\n}\n\nfunction intersectionArea(a: Node, b: Node) {\n\tconst minX = Math.max(a.minX, b.minX);\n\tconst minY = Math.max(a.minY, b.minY);\n\tconst maxX = Math.min(a.maxX, b.maxX);\n\tconst maxY = Math.min(a.maxY, b.maxY);\n\n\treturn Math.max(0, maxX - minX) * Math.max(0, maxY - minY);\n}\n\nfunction contains(a: Node, b: Node) {\n\treturn (\n\t\ta.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY\n\t);\n}\n\nfunction intersects(a: Node, b: Node) {\n\treturn (\n\t\tb.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY\n\t);\n}\n\nfunction createNode(children: Node[]) {\n\treturn {\n\t\tchildren,\n\t\theight: 1,\n\t\tleaf: true,\n\t\tminX: Infinity,\n\t\tminY: Infinity,\n\t\tmaxX: -Infinity,\n\t\tmaxY: -Infinity,\n\t};\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect<T>(\n\tarr: T[],\n\tleft: number,\n\tright: number,\n\tn: number,\n\tcompare: CompareFunction<T>,\n) {\n\tconst stack = [left, right];\n\n\twhile (stack.length) {\n\t\tright = stack.pop() as number;\n\t\tleft = stack.pop() as number;\n\n\t\tif (right - left <= n) continue;\n\n\t\tconst mid = left + Math.ceil((right - left) / n / 2) * n;\n\t\tquickselect(arr, mid, left, right, compare);\n\n\t\tstack.push(left, mid, mid, right);\n\t}\n}\n\nexport class RBush {\n\tprivate _maxEntries: number;\n\tprivate _minEntries: number;\n\tprivate data!: Node;\n\n\tconstructor(maxEntries: number) {\n\t\t// max entries in a node is 9 by default; min node fill is 40% for best performance\n\t\tthis._maxEntries = Math.max(4, maxEntries);\n\t\tthis._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\t\tthis.clear();\n\t}\n\n\tsearch(bbox: Node): Node[] {\n\t\tlet node = this.data;\n\t\tconst result: Node[] = [];\n\n\t\tif (!intersects(bbox, node)) {\n\t\t\treturn result;\n\t\t}\n\n\t\tconst toBBox = this.toBBox;\n\t\tconst nodesToSearch = [];\n\n\t\twhile (node) {\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\t\t\t\tconst childBBox = node.leaf ? toBBox(child) : child;\n\n\t\t\t\tif (intersects(bbox, childBBox)) {\n\t\t\t\t\tif (node.leaf) result.push(child);\n\t\t\t\t\telse if (contains(bbox, childBBox)) this._all(child, result);\n\t\t\t\t\telse nodesToSearch.push(child);\n\t\t\t\t}\n\t\t\t}\n\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tcollides(bbox: Node) {\n\t\tlet node = this.data;\n\n\t\tconst intersect = intersects(bbox, node);\n\t\tif (intersect) {\n\t\t\tconst nodesToSearch = [];\n\t\t\twhile (node) {\n\t\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\t\tconst child = node.children[i];\n\t\t\t\t\tconst childBBox = node.leaf ? this.toBBox(child) : child;\n\n\t\t\t\t\tif (intersects(bbox, childBBox)) {\n\t\t\t\t\t\tif (node.leaf || contains(bbox, childBBox)) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnodesToSearch.push(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tload(data: Node[]): void {\n\t\tif (data.length < this._minEntries) {\n\t\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\t\tthis.insert(data[i]);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// recursively build the tree with the given data from scratch using OMT algorithm\n\t\tlet node = this._build(data.slice(), 0, data.length - 1, 0);\n\n\t\tif (!this.data.children.length) {\n\t\t\t// save as is if tree is empty\n\t\t\tthis.data = node;\n\t\t} else if (this.data.height === node.height) {\n\t\t\t// split root if trees have the same height\n\t\t\tthis._splitRoot(this.data, node);\n\t\t} else {\n\t\t\tif (this.data.height < node.height) {\n\t\t\t\t// swap trees if inserted one is bigger\n\t\t\t\tconst tmpNode = this.data;\n\t\t\t\tthis.data = node;\n\t\t\t\tnode = tmpNode;\n\t\t\t}\n\n\t\t\t// insert the small tree into the large tree at appropriate level\n\t\t\tthis._insert(node, this.data.height - node.height - 1, true);\n\t\t}\n\t}\n\n\tinsert(item: Node): void {\n\t\tthis._insert(item, this.data.height - 1);\n\t}\n\n\tclear(): void {\n\t\tthis.data = createNode([]);\n\t}\n\n\tremove(item: Node): void {\n\t\tlet node: Node | null = this.data;\n\t\tconst bbox = this.toBBox(item);\n\t\tconst path = [];\n\t\tconst indexes: number[] = [];\n\t\tlet i: number | undefined;\n\t\tlet parent: Node | undefined;\n\t\tlet goingUp = false;\n\n\t\t// depth-first iterative tree traversal\n\t\twhile (node || path.length) {\n\t\t\tif (!node) {\n\t\t\t\t// go up\n\t\t\t\tnode = path.pop() as Node;\n\t\t\t\tparent = path[path.length - 1];\n\t\t\t\ti = indexes.pop() as number;\n\t\t\t\tgoingUp = true;\n\t\t\t}\n\n\t\t\tif (node.leaf) {\n\t\t\t\t// check current node\n\n\t\t\t\tconst index = node.children.indexOf(item);\n\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\t// item found, remove the item and condense tree upwards\n\t\t\t\t\tnode.children.splice(index, 1);\n\t\t\t\t\tpath.push(node);\n\t\t\t\t\tthis._condense(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!goingUp && !node.leaf && contains(node, bbox)) {\n\t\t\t\t// go down\n\t\t\t\tpath.push(node);\n\t\t\t\tindexes.push(i as number);\n\t\t\t\ti = 0;\n\t\t\t\tparent = node;\n\t\t\t\tnode = node.children[0];\n\t\t\t} else if (parent) {\n\t\t\t\t// go right\n\t\t\t\t(i as number)++;\n\t\t\t\tnode = parent.children[i as number];\n\t\t\t\tgoingUp = false;\n\t\t\t} else {\n\t\t\t\tnode = null; // nothing found\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate toBBox<T>(item: T): T {\n\t\treturn item;\n\t}\n\n\tprivate compareMinX(a: Node, b: Node) {\n\t\treturn a.minX - b.minX;\n\t}\n\tprivate compareMinY(a: Node, b: Node) {\n\t\treturn a.minY - b.minY;\n\t}\n\n\tprivate _all(node: Node, result: Node[]) {\n\t\tconst nodesToSearch = [];\n\t\twhile (node) {\n\t\t\tif (node.leaf) result.push(...node.children);\n\t\t\telse nodesToSearch.push(...node.children);\n\n\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate _build(items: Node[], left: number, right: number, height: number) {\n\t\tconst N = right - left + 1;\n\t\tlet M = this._maxEntries;\n\t\tlet node;\n\n\t\tif (N <= M) {\n\t\t\t// reached leaf level; return leaf\n\t\t\tnode = createNode(items.slice(left, right + 1));\n\t\t\tcalcBBox(node, this.toBBox);\n\t\t\treturn node;\n\t\t}\n\n\t\tif (!height) {\n\t\t\t// target height of the bulk-loaded tree\n\t\t\theight = Math.ceil(Math.log(N) / Math.log(M));\n\n\t\t\t// target number of root entries to maximize storage utilization\n\t\t\tM = Math.ceil(N / Math.pow(M, height - 1));\n\t\t}\n\n\t\tnode = createNode([]);\n\t\tnode.leaf = false;\n\t\tnode.height = height;\n\n\t\t// split the items into M mostly square tiles\n\n\t\tconst N2 = Math.ceil(N / M);\n\t\tconst N1 = N2 * Math.ceil(Math.sqrt(M));\n\n\t\tmultiSelect(items, left, right, N1, this.compareMinX);\n\n\t\tfor (let i = left; i <= right; i += N1) {\n\t\t\tconst right2 = Math.min(i + N1 - 1, right);\n\n\t\t\tmultiSelect(items, i, right2, N2, this.compareMinY);\n\n\t\t\tfor (let j = i; j <= right2; j += N2) {\n\t\t\t\tconst right3 = Math.min(j + N2 - 1, right2);\n\n\t\t\t\t// pack each entry recursively\n\t\t\t\tnode.children.push(this._build(items, j, right3, height - 1));\n\t\t\t}\n\t\t}\n\n\t\tcalcBBox(node, this.toBBox);\n\n\t\treturn node;\n\t}\n\n\tprivate _chooseSubtree(bbox: Node, node: Node, level: number, path: Node[]) {\n\t\twhile (true) {\n\t\t\tpath.push(node);\n\n\t\t\tif (node.leaf || path.length - 1 === level) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet minArea = Infinity;\n\t\t\tlet minEnlargement = Infinity;\n\t\t\tlet targetNode;\n\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\n\t\t\t\tconst area = bboxArea(child);\n\t\t\t\tconst enlargement = enlargedArea(bbox, child) - area;\n\n\t\t\t\t// choose entry with the least area enlargement\n\n\t\t\t\tif (enlargement < minEnlargement) {\n\t\t\t\t\tminEnlargement = enlargement;\n\t\t\t\t\tminArea = area < minArea ? area : minArea;\n\t\t\t\t\ttargetNode = child;\n\t\t\t\t} else if (enlargement === minEnlargement) {\n\t\t\t\t\t// otherwise choose one with the smallest area\n\t\t\t\t\tif (area < minArea) {\n\t\t\t\t\t\tminArea = area;\n\t\t\t\t\t\ttargetNode = child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnode = targetNode || node.children[0];\n\t\t}\n\n\t\treturn node;\n\t}\n\n\tprivate _insert(item: Node, level: number, isNode?: boolean) {\n\t\tconst bbox = isNode ? item : this.toBBox(item);\n\t\tconst insertPath: Node[] = [];\n\n\t\t// find the best node for accommodating the item, saving all nodes along the path too\n\t\tconst node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n\t\t// put the item into the node\n\t\tnode.children.push(item);\n\t\textend(node, bbox);\n\n\t\t// split on node overflow; propagate upwards if necessary\n\t\twhile (level >= 0) {\n\t\t\tif (insertPath[level].children.length > this._maxEntries) {\n\t\t\t\tthis._split(insertPath, level);\n\t\t\t\tlevel--;\n\t\t\t} else break;\n\t\t}\n\n\t\t// adjust bboxes along the insertion path\n\t\tthis._adjustParentBBoxes(bbox, insertPath, level);\n\t}\n\n\t// split overflowed node into two\n\tprivate _split(insertPath: Node[], level: number) {\n\t\tconst node = insertPath[level];\n\t\tconst M = node.children.length;\n\t\tconst m = this._minEntries;\n\n\t\tthis._chooseSplitAxis(node, m, M);\n\n\t\tconst splitIndex = this._chooseSplitIndex(node, m, M);\n\n\t\tconst newNode = createNode(\n\t\t\tnode.children.splice(splitIndex, node.children.length - splitIndex),\n\t\t);\n\t\tnewNode.height = node.height;\n\t\tnewNode.leaf = node.leaf;\n\n\t\tcalcBBox(node, this.toBBox);\n\t\tcalcBBox(newNode, this.toBBox);\n\n\t\tif (level) insertPath[level - 1].children.push(newNode);\n\t\telse this._splitRoot(node, newNode);\n\t}\n\n\tprivate _splitRoot(node: Node, newNode: Node) {\n\t\t// split root node\n\t\tthis.data = createNode([node, newNode]);\n\t\tthis.data.height = node.height + 1;\n\t\tthis.data.leaf = false;\n\t\tcalcBBox(this.data, this.toBBox);\n\t}\n\n\tprivate _chooseSplitIndex(node: Node, m: number, M: number) {\n\t\tlet index;\n\t\tlet minOverlap = Infinity;\n\t\tlet minArea = Infinity;\n\n\t\tfor (let i = m; i <= M - m; i++) {\n\t\t\tconst bbox1 = distBBox(node, 0, i, this.toBBox);\n\t\t\tconst bbox2 = distBBox(node, i, M, this.toBBox);\n\n\t\t\tconst overlap = intersectionArea(bbox1, bbox2);\n\t\t\tconst area = bboxArea(bbox1) + bboxArea(bbox2);\n\n\t\t\t// choose distribution with minimum overlap\n\t\t\tif (overlap < minOverlap) {\n\t\t\t\tminOverlap = overlap;\n\t\t\t\tindex = i;\n\n\t\t\t\tminArea = area < minArea ? area : minArea;\n\t\t\t} else if (overlap === minOverlap) {\n\t\t\t\t// otherwise choose distribution with minimum area\n\t\t\t\tif (area < minArea) {\n\t\t\t\t\tminArea = area;\n\t\t\t\t\tindex = i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn index || M - m;\n\t}\n\n\t// sorts node children by the best axis for split\n\tprivate _chooseSplitAxis(node: Node, m: number, M: number) {\n\t\tconst compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n\t\tconst compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n\t\tconst xMargin = this._allDistMargin(node, m, M, compareMinX);\n\t\tconst yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n\t\t// if total distributions margin value is minimal for x, sort by minX,\n\t\t// otherwise it's already sorted by minY\n\t\tif (xMargin < yMargin) {\n\t\t\tnode.children.sort(compareMinX);\n\t\t}\n\t}\n\n\t// total margin of all possible split distributions where each node is at least m full\n\tprivate _allDistMargin(\n\t\tnode: Node,\n\t\tm: number,\n\t\tM: number,\n\t\tcompare: CompareFunction<Node>,\n\t) {\n\t\tnode.children.sort(compare);\n\n\t\tconst toBBox = this.toBBox;\n\t\tconst leftBBox = distBBox(node, 0, m, toBBox);\n\t\tconst rightBBox = distBBox(node, M - m, M, toBBox);\n\t\tlet margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n\t\tfor (let i = m; i < M - m; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\textend(leftBBox, node.leaf ? toBBox(child) : child);\n\t\t\tmargin += bboxMargin(leftBBox);\n\t\t}\n\n\t\tfor (let i = M - m - 1; i >= m; i--) {\n\t\t\tconst child = node.children[i];\n\t\t\textend(rightBBox, node.leaf ? toBBox(child) : child);\n\t\t\tmargin += bboxMargin(rightBBox);\n\t\t}\n\n\t\treturn margin;\n\t}\n\n\tprivate _adjustParentBBoxes(bbox: Node, path: Node[], level: number) {\n\t\t// adjust bboxes along the given tree path\n\t\tfor (let i = level; i >= 0; i--) {\n\t\t\textend(path[i], bbox);\n\t\t}\n\t}\n\n\tprivate _condense(path: Node[]) {\n\t\t// go through the path, removing empty nodes and updating bboxes\n\t\tfor (let i = path.length - 1, siblings; i >= 0; i--) {\n\t\t\tif (path[i].children.length === 0) {\n\t\t\t\tif (i > 0) {\n\t\t\t\t\tsiblings = path[i - 1].children;\n\t\t\t\t\tsiblings.splice(siblings.indexOf(path[i]), 1);\n\t\t\t\t} else this.clear();\n\t\t\t} else {\n\t\t\t\tcalcBBox(path[i], this.toBBox);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { Position } from \"geojson\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../store\";\nimport { RBush, Node } from \"./rbush\";\n\nexport class SpatialIndex {\n\tprivate tree: RBush;\n\tprivate idToNode: Map<FeatureId, Node>;\n\tprivate nodeToId: Map<Node, FeatureId>;\n\n\tconstructor(options?: { maxEntries: number }) {\n\t\tthis.tree = new RBush(\n\t\t\toptions && options.maxEntries ? options.maxEntries : 9,\n\t\t);\n\t\tthis.idToNode = new Map();\n\t\tthis.nodeToId = new Map();\n\t}\n\n\tprivate setMaps(feature: GeoJSONStoreFeatures, bbox: Node) {\n\t\tthis.idToNode.set(feature.id as FeatureId, bbox);\n\t\tthis.nodeToId.set(bbox, feature.id as FeatureId);\n\t}\n\n\tprivate toBBox(feature: GeoJSONStoreFeatures) {\n\t\tconst longitudes: number[] = [];\n\t\tconst latitudes: number[] = [];\n\n\t\tlet coordinates: Position[];\n\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\tcoordinates = [feature.geometry.coordinates];\n\t\t} else {\n\t\t\tthrow new Error(\"Not a valid feature to turn into a bounding box\");\n\t\t}\n\n\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\tlatitudes.push(coordinates[i][1]);\n\t\t\tlongitudes.push(coordinates[i][0]);\n\t\t}\n\n\t\tconst minLat = Math.min(...latitudes);\n\t\tconst maxLat = Math.max(...latitudes);\n\t\tconst minLng = Math.min(...longitudes);\n\t\tconst maxLng = Math.max(...longitudes);\n\n\t\treturn {\n\t\t\tminX: minLng,\n\t\t\tminY: minLat,\n\t\t\tmaxX: maxLng,\n\t\t\tmaxY: maxLat,\n\t\t} as Node;\n\t}\n\n\tinsert(feature: GeoJSONStoreFeatures): void {\n\t\tif (this.idToNode.get(String(feature.id))) {\n\t\t\tthrow new Error(\"Feature already exists\");\n\t\t}\n\t\tconst bbox = this.toBBox(feature);\n\t\tthis.setMaps(feature, bbox);\n\t\tthis.tree.insert(bbox);\n\t}\n\n\tload(features: GeoJSONStoreFeatures[]): void {\n\t\tconst load: Node[] = [];\n\t\tconst seenIds: Set<string> = new Set();\n\t\tfeatures.forEach((feature) => {\n\t\t\tconst bbox = this.toBBox(feature);\n\t\t\tthis.setMaps(feature, bbox);\n\t\t\tif (seenIds.has(String(feature.id))) {\n\t\t\t\tthrow new Error(`Duplicate feature ID found ${feature.id}`);\n\t\t\t}\n\t\t\tseenIds.add(String(feature.id));\n\t\t\tload.push(bbox);\n\t\t});\n\t\tthis.tree.load(load);\n\t}\n\n\tupdate(feature: GeoJSONStoreFeatures): void {\n\t\tthis.remove(feature.id as FeatureId);\n\t\tconst bbox = this.toBBox(feature);\n\t\tthis.setMaps(feature, bbox);\n\t\tthis.tree.insert(bbox);\n\t}\n\n\tremove(featureId: FeatureId): void {\n\t\tconst node = this.idToNode.get(featureId);\n\t\tif (!node) {\n\t\t\tthrow new Error(`${featureId} not inserted into the spatial index`);\n\t\t}\n\n\t\tthis.tree.remove(node);\n\t}\n\n\tclear(): void {\n\t\tthis.tree.clear();\n\t}\n\n\tsearch(feature: GeoJSONStoreFeatures): FeatureId[] {\n\t\tconst found = this.tree.search(this.toBBox(feature));\n\t\treturn found.map((node) => {\n\t\t\treturn this.nodeToId.get(node) as FeatureId;\n\t\t});\n\t}\n\n\tcollides(feature: GeoJSONStoreFeatures): boolean {\n\t\treturn this.tree.collides(this.toBBox(feature));\n\t}\n}\n","import { Feature, Point, Polygon, LineString } from \"geojson\";\nimport { uuid4 } from \"../util/id\";\nimport { SpatialIndex } from \"./spatial-index/spatial-index\";\nimport { isValidTimestamp } from \"./store-feature-validation\";\n\ntype JSON = string | number | boolean | null | JSONArray | JSONObject;\n\nexport interface JSONObject {\n\t[member: string]: JSON;\n}\ntype JSONArray = Array<JSON>;\n\ntype DefinedProperties = Record<string, JSON>;\n\nexport type GeoJSONStoreGeometries = Polygon | LineString | Point;\n\nexport type BBoxPolygon = Feature<Polygon, DefinedProperties>;\n\nexport type GeoJSONStoreFeatures = Feature<\n\tGeoJSONStoreGeometries,\n\tDefinedProperties\n>;\n\ntype StoreChangeEvents = \"delete\" | \"create\" | \"update\" | \"styling\";\n\nexport type StoreChangeHandler = (\n\tids: FeatureId[],\n\tchange: StoreChangeEvents,\n) => void;\n\nexport type FeatureId = string | number;\n\nexport type IdStrategy<Id extends FeatureId> = {\n\tisValidId: (id: Id) => boolean;\n\tgetId: () => Id;\n};\n\ntype GeoJSONStoreConfig<Id extends FeatureId> = {\n\tidStrategy?: IdStrategy<Id>;\n\ttracked?: boolean;\n};\n\nexport const defaultIdStrategy = {\n\tgetId: <FeatureId>() => uuid4() as FeatureId,\n\tisValidId: (id: FeatureId) => typeof id === \"string\" && id.length === 36,\n};\n\nexport class GeoJSONStore<Id extends FeatureId = FeatureId> {\n\tconstructor(config?: GeoJSONStoreConfig<Id>) {\n\t\tthis.store = {};\n\t\tthis.spatialIndex = new SpatialIndex();\n\n\t\t// Setting tracked has to happen first\n\t\t// because we use it in featureValidation\n\t\tthis.tracked = config && config.tracked === false ? false : true;\n\t\tthis.idStrategy =\n\t\t\tconfig && config.idStrategy ? config.idStrategy : defaultIdStrategy;\n\t}\n\n\tpublic idStrategy: IdStrategy<Id>;\n\n\tprivate tracked: boolean;\n\n\tprivate spatialIndex: SpatialIndex;\n\n\tprivate store: {\n\t\t[key: FeatureId]: GeoJSONStoreFeatures;\n\t};\n\n\t// Default to no-op\n\tprivate _onChange: StoreChangeHandler = () => {};\n\n\tprivate clone<T>(obj: T): T {\n\t\treturn JSON.parse(JSON.stringify(obj));\n\t}\n\n\tgetId(): FeatureId {\n\t\treturn this.idStrategy.getId();\n\t}\n\n\thas(id: FeatureId): boolean {\n\t\treturn Boolean(this.store[id]);\n\t}\n\n\tload(\n\t\tdata: GeoJSONStoreFeatures[],\n\t\tfeatureValidation?: (feature: unknown, tracked?: boolean) => boolean,\n\t) {\n\t\tif (data.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't want to update the original data\n\t\tconst clonedData = this.clone(data);\n\n\t\t// We try to be a bit forgiving here as many users\n\t\t// may not set a feature id as UUID or createdAt/updatedAt\n\t\tclonedData.forEach((feature) => {\n\t\t\tif (feature.id === undefined || feature.id === null) {\n\t\t\t\tfeature.id = this.idStrategy.getId();\n\t\t\t}\n\n\t\t\tif (this.tracked) {\n\t\t\t\tif (!feature.properties.createdAt) {\n\t\t\t\t\tfeature.properties.createdAt = +new Date();\n\t\t\t\t} else {\n\t\t\t\t\tisValidTimestamp(feature.properties.createdAt);\n\t\t\t\t}\n\n\t\t\t\tif (!feature.properties.updatedAt) {\n\t\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t\t} else {\n\t\t\t\t\tisValidTimestamp(feature.properties.updatedAt);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst changes: FeatureId[] = [];\n\t\tclonedData.forEach((feature) => {\n\t\t\tconst id = feature.id as FeatureId;\n\t\t\tif (featureValidation) {\n\t\t\t\tconst isValid = featureValidation(feature);\n\n\t\t\t\t// Generic error handling if the featureValidation function\n\t\t\t\t// does not throw something more specific itself\n\t\t\t\tif (!isValid) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Feature ${id} is not valid: ${JSON.stringify(feature)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We have to be sure that the feature does not already exist with this ID\n\t\t\tif (this.has(id)) {\n\t\t\t\tthrow new Error(`Feature already exists with this id: ${id}`);\n\t\t\t}\n\n\t\t\tthis.store[id] = feature;\n\t\t\tchanges.push(id);\n\t\t});\n\t\tthis.spatialIndex.load(clonedData);\n\t\tthis._onChange(changes, \"create\");\n\t}\n\n\tsearch(\n\t\tbbox: BBoxPolygon,\n\t\tfilter?: (feature: GeoJSONStoreFeatures) => boolean,\n\t) {\n\t\tconst features = this.spatialIndex.search(bbox).map((id) => this.store[id]);\n\t\tif (filter) {\n\t\t\treturn this.clone(features.filter(filter));\n\t\t} else {\n\t\t\treturn this.clone(features);\n\t\t}\n\t}\n\n\tregisterOnChange(onChange: StoreChangeHandler) {\n\t\tthis._onChange = (ids, change) => {\n\t\t\tonChange(ids, change);\n\t\t};\n\t}\n\n\tgetGeometryCopy<T extends GeoJSONStoreGeometries>(id: FeatureId): T {\n\t\tconst feature = this.store[id];\n\t\tif (!feature) {\n\t\t\tthrow new Error(\n\t\t\t\t`No feature with this id (${id}), can not get geometry copy`,\n\t\t\t);\n\t\t}\n\t\treturn this.clone(feature.geometry as T);\n\t}\n\n\tgetPropertiesCopy(id: FeatureId) {\n\t\tconst feature = this.store[id];\n\t\tif (!feature) {\n\t\t\tthrow new Error(\n\t\t\t\t`No feature with this id (${id}), can not get properties copy`,\n\t\t\t);\n\t\t}\n\t\treturn this.clone(feature.properties);\n\t}\n\n\tupdateProperty(\n\t\tpropertiesToUpdate: { id: FeatureId; property: string; value: JSON }[],\n\t): void {\n\t\tconst ids: FeatureId[] = [];\n\t\tpropertiesToUpdate.forEach(({ id, property, value }) => {\n\t\t\tconst feature = this.store[id];\n\n\t\t\tif (!feature) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No feature with this (${id}), can not update geometry`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tids.push(id);\n\n\t\t\tfeature.properties[property] = value;\n\n\t\t\t// Update the time the feature was updated\n\t\t\tif (this.tracked) {\n\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange(ids, \"update\");\n\t\t}\n\t}\n\n\tupdateGeometry(\n\t\tgeometriesToUpdate: { id: FeatureId; geometry: GeoJSONStoreGeometries }[],\n\t): void {\n\t\tconst ids: FeatureId[] = [];\n\t\tgeometriesToUpdate.forEach(({ id, geometry }) => {\n\t\t\tids.push(id);\n\n\t\t\tconst feature = this.store[id];\n\n\t\t\tif (!feature) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No feature with this (${id}), can not update geometry`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfeature.geometry = this.clone(geometry);\n\n\t\t\tthis.spatialIndex.update(feature);\n\n\t\t\t// Update the time the feature was updated\n\t\t\tif (this.tracked) {\n\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange(ids, \"update\");\n\t\t}\n\t}\n\n\tcreate<Id extends FeatureId>(\n\t\tfeatures: {\n\t\t\tgeometry: GeoJSONStoreGeometries;\n\t\t\tproperties?: JSONObject;\n\t\t}[],\n\t): Id[] {\n\t\tconst ids: FeatureId[] = [];\n\t\tfeatures.forEach(({ geometry, properties }) => {\n\t\t\tlet createdAt;\n\t\t\tlet createdProperties = { ...properties };\n\n\t\t\tif (this.tracked) {\n\t\t\t\tcreatedAt = +new Date();\n\n\t\t\t\tif (properties) {\n\t\t\t\t\tcreatedProperties.createdAt =\n\t\t\t\t\t\ttypeof properties.createdAt === \"number\"\n\t\t\t\t\t\t\t? properties.createdAt\n\t\t\t\t\t\t\t: createdAt;\n\t\t\t\t\tcreatedProperties.updatedAt =\n\t\t\t\t\t\ttypeof properties.updatedAt === \"number\"\n\t\t\t\t\t\t\t? properties.updatedAt\n\t\t\t\t\t\t\t: createdAt;\n\t\t\t\t} else {\n\t\t\t\t\tcreatedProperties = { createdAt, updatedAt: createdAt };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst id = this.getId();\n\t\t\tconst feature = {\n\t\t\t\tid,\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry,\n\t\t\t\tproperties: createdProperties,\n\t\t\t} as GeoJSONStoreFeatures;\n\n\t\t\tthis.store[id] = feature;\n\t\t\tthis.spatialIndex.insert(feature);\n\n\t\t\tids.push(id);\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange([...ids], \"create\");\n\t\t}\n\n\t\treturn ids as Id[];\n\t}\n\n\tdelete(ids: FeatureId[]): void {\n\t\tids.forEach((id) => {\n\t\t\tif (this.store[id]) {\n\t\t\t\tdelete this.store[id];\n\t\t\t\tthis.spatialIndex.remove(id as FeatureId);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"No feature with this id, can not delete\");\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange([...ids], \"delete\");\n\t\t}\n\t}\n\n\tcopyAll(): GeoJSONStoreFeatures[] {\n\t\treturn this.clone(Object.keys(this.store).map((id) => this.store[id]));\n\t}\n\n\tclear(): void {\n\t\tthis.store = {};\n\t\tthis.spatialIndex.clear();\n\t}\n\n\tsize(): number {\n\t\treturn Object.keys(this.store).length;\n\t}\n}\n","export const uuid4 = function (): string {\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n\t\tconst r = (Math.random() * 16) | 0,\n\t\t\tv = c == \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n};\n","import { Polygon } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Adapted from @turf/area is MIT Licensed licesned https://github.com/Turfjs/turf/blob/master/packages/turf-area/index.ts\n// In turn adapted from NASA: https://dataverse.jpl.nasa.gov/file.xhtml?fileId=47998&version=2.0\n\nexport function polygonAreaSquareMeters(polygon: Polygon) {\n\tconst coords = polygon.coordinates;\n\tlet total = 0;\n\tif (coords && coords.length > 0) {\n\t\ttotal += Math.abs(ringArea(coords[0]));\n\t\tfor (let i = 1; i < coords.length; i++) {\n\t\t\ttotal -= Math.abs(ringArea(coords[i]));\n\t\t}\n\t}\n\treturn total;\n}\n\nconst FACTOR = (earthRadius * earthRadius) / 2;\nconst PI_OVER_180 = Math.PI / 180;\n\nfunction ringArea(coords: number[][]): number {\n\tconst coordsLength = coords.length;\n\n\tif (coordsLength <= 2) {\n\t\treturn 0;\n\t}\n\n\tlet total = 0;\n\n\tlet i = 0;\n\twhile (i < coordsLength) {\n\t\tconst lower = coords[i];\n\t\tconst middle = coords[i + 1 === coordsLength ? 0 : i + 1];\n\t\tconst upper =\n\t\t\tcoords[i + 2 >= coordsLength ? (i + 2) % coordsLength : i + 2];\n\n\t\tconst lowerX = lower[0] * PI_OVER_180;\n\t\tconst middleY = middle[1] * PI_OVER_180;\n\t\tconst upperX = upper[0] * PI_OVER_180;\n\n\t\ttotal += (upperX - lowerX) * Math.sin(middleY);\n\n\t\ti++;\n\t}\n\n\treturn total * FACTOR;\n}\n","import { webMercatorBearing } from \"./measure/bearing\";\n\n/**\n * Calculate the relative angle between two lines\n * @param A The first point of the first line\n * @param B The second point of the first line and the first point of the second line\n * @param C The second point of the second line\n * @returns The relative angle between the two lines\n */\nexport function calculateRelativeAngle(\n\tA: { x: number; y: number },\n\tB: { x: number; y: number },\n\tC: { x: number; y: number },\n): number {\n\tconst bearingAB = webMercatorBearing(A, B); // Bearing from A to B\n\tconst bearingBC = webMercatorBearing(B, C); // Bearing from B to C\n\n\t// Calculate the relative angle (bearingBC relative to bearingAB)\n\tlet relativeAngle = bearingBC - bearingAB;\n\n\t// Normalize the relative angle to 0-360 range\n\tif (relativeAngle < 0) {\n\t\trelativeAngle += 360;\n\t}\n\n\t// Normalise to 0 - 90\n\tconst angle = relativeAngle - 90;\n\n\treturn 180 - Math.abs(-90 + angle);\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n} from \"../base.mode\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport { webMercatorBearing } from \"../../geometry/measure/bearing\";\nimport { midpointCoordinate } from \"../../geometry/midpoint-coordinate\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { degreesToRadians } from \"../../geometry/helpers\";\nimport { determineHalfPlane } from \"../../geometry/determine-halfplane\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { calculateRelativeAngle } from \"../../geometry/calculate-relative-angle\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\ntype PolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawPolygonModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawPolygonModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawAngledRectangleMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n\tmode = \"angled-rectangle\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawPolygonModeKeyEvents;\n\n\t// Behaviors\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\tconstructor(options?: TerraDrawPolygonModeOptions<PolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\n\n\t\tlet updatedCoordinates;\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t\t// renders the polygon - There might be a cleaner solution?\n\t\t\tconst epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n\t\t\tconst offset = Math.max(0.000001, epsilon);\n\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat - offset],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tconst firstCoordinate = currentPolygonCoordinates[0];\n\t\t\tconst secondCoordinate = currentPolygonCoordinates[1];\n\t\t\tconst midpoint = midpointCoordinate(\n\t\t\t\tfirstCoordinate,\n\t\t\t\tsecondCoordinate,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t\tthis.project,\n\t\t\t\tthis.unproject,\n\t\t\t);\n\n\t\t\tconst A = lngLatToWebMercatorXY(firstCoordinate[0], firstCoordinate[1]);\n\t\t\tconst B = lngLatToWebMercatorXY(midpoint[0], midpoint[1]);\n\t\t\tconst C = lngLatToWebMercatorXY(secondCoordinate[0], secondCoordinate[1]);\n\t\t\tconst D = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\t\t// Determine if the cursor is closer to A or C\n\t\t\tconst distanceToA = cartesianDistance(D, A);\n\t\t\tconst distanceToB = cartesianDistance(D, C);\n\t\t\tconst ACloserThanC = distanceToA < distanceToB ? true : false;\n\n\t\t\t// We need to work out if the cursor is closer to A or C and then calculate the angle\n\t\t\t// between the cursor and the opposing midpoint\n\t\t\tconst relativeAngle = calculateRelativeAngle(A, B, D);\n\t\t\tconst theta = ACloserThanC\n\t\t\t\t? 90 - relativeAngle\n\t\t\t\t: calculateRelativeAngle(A, B, D) - 90;\n\n\t\t\t// We want to calculate the adjacent i.e. the calculated distance\n\t\t\t// between the cursor and the opposing midpoint\n\t\t\tconst hypotenuse = cartesianDistance(B, D);\n\t\t\tconst adjacent = Math.cos(degreesToRadians(theta)) * hypotenuse;\n\n\t\t\t// Calculate the bearing between the first and second point\n\t\t\tconst firstAndSecondPointBearing = webMercatorBearing(A, C);\n\n\t\t\t// Determine which side of the line the cursor is on\n\t\t\tconst side = determineHalfPlane(A, C, D);\n\n\t\t\t// Determine which direction to draw the rectangle\n\t\t\tconst angle = side === \"right\" ? -90 : 90;\n\n\t\t\t// Calculate the third and fourth coordinates based on the cursor position\n\t\t\tconst rectangleAngle = firstAndSecondPointBearing + angle;\n\t\t\tconst thirdCoordinateXY = webMercatorDestination(\n\t\t\t\tA,\n\t\t\t\tadjacent,\n\t\t\t\trectangleAngle,\n\t\t\t);\n\t\t\tconst fourthCoordinateXY = webMercatorDestination(\n\t\t\t\tC,\n\t\t\t\tadjacent,\n\t\t\t\trectangleAngle,\n\t\t\t);\n\n\t\t\t// Convert the third and fourth coordinates back to lng/lat\n\t\t\tconst thirdCoordinate = webMercatorXYToLngLat(\n\t\t\t\tthirdCoordinateXY.x,\n\t\t\t\tthirdCoordinateXY.y,\n\t\t\t);\n\t\t\tconst fourthCoordinate = webMercatorXYToLngLat(\n\t\t\t\tfourthCoordinateXY.x,\n\t\t\t\tfourthCoordinateXY.y,\n\t\t\t);\n\n\t\t\t// The final coordinates\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\tcurrentPolygonCoordinates[1],\n\t\t\t\t[fourthCoordinate.lng, fourthCoordinate.lat],\n\t\t\t\t[thirdCoordinate.lng, thirdCoordinate.lat],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t}\n\n\t\tupdatedCoordinates &&\n\t\t\tthis.updatePolygonGeometry(\n\t\t\t\tthis.currentId,\n\t\t\t\tupdatedCoordinates,\n\t\t\t\tUpdateTypes.Provisional,\n\t\t\t);\n\t}\n\n\tprivate updatePolygonGeometry(\n\t\tid: FeatureId,\n\t\tcoordinates: Polygon[\"coordinates\"][0],\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tconst updatedGeometry = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t} as Polygon;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([{ id, geometry: updatedGeometry }]);\n\n\t\treturn true;\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = newId;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t\tthis.currentId,\n\t\t\t\t[\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t],\n\t\t\t\tUpdateTypes.Commit,\n\t\t\t);\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","// Function to determine the relative position of a point to a line segment\nexport function determineHalfPlane(\n\tpoint: { x: number; y: number },\n\tlineStart: { x: number; y: number },\n\tlineEnd: { x: number; y: number },\n): string {\n\t// Calculate the vectors\n\tconst vectorLine = { x: lineEnd.x - lineStart.x, y: lineEnd.y - lineStart.y };\n\tconst vectorPoint = { x: point.x - lineStart.x, y: point.y - lineStart.y };\n\n\t// Calculate the cross product\n\tconst crossProduct =\n\t\tvectorLine.x * vectorPoint.y - vectorLine.y * vectorPoint.x;\n\n\t// Use a small epsilon value to handle floating-point precision errors\n\tconst epsilon = 1e-10;\n\n\tif (crossProduct > epsilon) {\n\t\treturn \"left\";\n\t} else if (crossProduct < -epsilon) {\n\t\treturn \"right\";\n\t} else {\n\t\t// Technically on the line but we treat it as left\n\t\treturn \"left\";\n\t}\n}\n","export function isClockwiseWebMercator(\n\tcenter: { x: number; y: number },\n\tsecondCoord: { x: number; y: number },\n\tthirdCoord: { x: number; y: number },\n): boolean {\n\t// Calculate the vectors\n\tconst vector1 = { x: secondCoord.x - center.x, y: secondCoord.y - center.y };\n\tconst vector2 = { x: thirdCoord.x - center.x, y: thirdCoord.y - center.y };\n\n\t// Calculate the cross product\n\tconst cross = vector1.x * vector2.y - vector1.y * vector2.x;\n\n\t// If the cross product is negative, the third point is on the right (clockwise)\n\t// If the cross product is positive, the third point is on the left (anticlockwise)\n\treturn cross <= 0;\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n} from \"../base.mode\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport {\n\tnormalizeBearing,\n\twebMercatorBearing,\n} from \"../../geometry/measure/bearing\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { isClockwiseWebMercator } from \"../../geometry/clockwise\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\n\ntype TerraDrawSectorModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\ntype SectorPolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawSectorModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tarcPoints?: number;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawSectorModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawSectorMode extends TerraDrawBaseDrawMode<SectorPolygonStyling> {\n\tmode = \"sector\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawSectorModeKeyEvents;\n\tprivate direction: \"clockwise\" | \"anticlockwise\" | undefined;\n\tprivate arcPoints: number;\n\n\t// Behaviors\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\tconstructor(options?: TerraDrawSectorModeOptions<SectorPolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.arcPoints = options?.arcPoints || 64;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(finishedId, { mode: this.mode, action: \"draw\" });\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\n\n\t\tlet updatedCoordinates;\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t\t// renders the polygon - There might be a cleaner solution?\n\t\t\tconst epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n\t\t\tconst offset = Math.max(0.000001, epsilon);\n\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat - offset],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tconst center = currentPolygonCoordinates[0];\n\t\t\tconst arcCoordOne = currentPolygonCoordinates[1];\n\t\t\tconst arcCoordTwo = [event.lng, event.lat];\n\n\t\t\t// Convert coordinates to Web Mercator\n\t\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\t\t\tconst webMercatorArcCoordOne = lngLatToWebMercatorXY(\n\t\t\t\tarcCoordOne[0],\n\t\t\t\tarcCoordOne[1],\n\t\t\t);\n\t\t\tconst webMercatorArcCoordTwo = lngLatToWebMercatorXY(\n\t\t\t\tarcCoordTwo[0],\n\t\t\t\tarcCoordTwo[1],\n\t\t\t);\n\n\t\t\t// We want to determine the direction of the sector, whether\n\t\t\t// it is clockwise or anticlockwise\n\t\t\tif (this.direction === undefined) {\n\t\t\t\tconst clockwise = isClockwiseWebMercator(\n\t\t\t\t\twebMercatorCenter,\n\t\t\t\t\twebMercatorArcCoordOne,\n\t\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t\t);\n\t\t\t\tthis.direction = clockwise ? \"clockwise\" : \"anticlockwise\";\n\t\t\t}\n\n\t\t\t// Calculate the radius (distance from center to second point in Web Mercator)\n\t\t\tconst radius = cartesianDistance(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t);\n\n\t\t\t// Calculate bearings for the second and third points in Web Mercator\n\t\t\tconst startBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t);\n\t\t\tconst endBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t);\n\n\t\t\t// Generate points along the arc in Web Mercator\n\t\t\tconst numberOfPoints = this.arcPoints; // Number of points to approximate the arc\n\t\t\tconst coordinates: Position[] = [center]; // Start with the center (in WGS84)\n\n\t\t\t// Corrected version to calculate deltaBearing\n\t\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\n\t\t\t// Calculate the delta bearing based on the direction\n\t\t\tlet deltaBearing;\n\t\t\tif (this.direction === \"anticlockwise\") {\n\t\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\t\tif (deltaBearing < 0) {\n\t\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\t\tif (deltaBearing < 0) {\n\t\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst bearingStep =\n\t\t\t\t((this.direction === \"anticlockwise\" ? 1 : -1) * deltaBearing) /\n\t\t\t\tnumberOfPoints;\n\n\t\t\t// Add the first coordinate to the polygon\n\t\t\tcoordinates.push(arcCoordOne);\n\n\t\t\t// Add all the arc points\n\t\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\t\twebMercatorCenter,\n\t\t\t\t\tradius,\n\t\t\t\t\tcurrentBearing,\n\t\t\t\t);\n\t\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\t\tconst nextCoord = [\n\t\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t\t];\n\n\t\t\t\tconst notIdentical =\n\t\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\t\tif (notIdentical) {\n\t\t\t\t\tcoordinates.push(nextCoord);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Close the polygon\n\t\t\tcoordinates.push(center);\n\n\t\t\tupdatedCoordinates = [...coordinates];\n\t\t}\n\n\t\tupdatedCoordinates &&\n\t\t\tthis.updatePolygonGeometry(\n\t\t\t\tthis.currentId,\n\t\t\t\tupdatedCoordinates,\n\t\t\t\tUpdateTypes.Provisional,\n\t\t\t);\n\t}\n\n\tprivate updatePolygonGeometry(\n\t\tid: FeatureId,\n\t\tcoordinates: Polygon[\"coordinates\"][0],\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tconst updatedGeometry = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t} as Polygon;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([{ id, geometry: updatedGeometry }]);\n\n\t\treturn true;\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = newId;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.updatePolygonGeometry(\n\t\t\t\tthis.currentId,\n\t\t\t\t[\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t],\n\t\t\t\tUpdateTypes.Commit,\n\t\t\t);\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n} from \"../../common\";\nimport { LineString, Point, Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport {\n\tnormalizeBearing,\n\twebMercatorBearing,\n} from \"../../geometry/measure/bearing\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { isClockwiseWebMercator } from \"../../geometry/clockwise\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\n\ntype TerraDrawSensorModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\ntype SensorPolygonStyling = {\n\tcenterPointColor: HexColorStyling;\n\tcenterPointWidth: NumericStyling;\n\tcenterPointOutlineColor: HexColorStyling;\n\tcenterPointOutlineWidth: NumericStyling;\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawSensorModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tarcPoints?: number;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawSensorModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawSensorMode extends TerraDrawBaseDrawMode<SensorPolygonStyling> {\n\tmode = \"sensor\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate currentInitialArcId: FeatureId | undefined;\n\tprivate currentStartingPointId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawSensorModeKeyEvents;\n\tprivate direction: \"clockwise\" | \"anticlockwise\" | undefined;\n\tprivate arcPoints: number;\n\n\t// Behaviors\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\tconstructor(options?: TerraDrawSensorModeOptions<SensorPolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.arcPoints = options?.arcPoints || 64;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentStartingPointId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedCurrentStartingPointId = this.currentStartingPointId;\n\t\tconst finishedInitialArcId = this.currentInitialArcId;\n\t\tconst finishedCurrentId = this.currentId;\n\n\t\tif (finishedCurrentStartingPointId) {\n\t\t\tthis.store.delete([finishedCurrentStartingPointId]);\n\t\t}\n\n\t\tif (finishedInitialArcId) {\n\t\t\tthis.store.delete([finishedInitialArcId]);\n\t\t}\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentStartingPointId = undefined;\n\t\tthis.currentInitialArcId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (finishedCurrentId) {\n\t\t\tthis.onFinish(finishedCurrentId, { mode: this.mode, action: \"draw\" });\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (\n\t\t\tthis.currentInitialArcId === undefined ||\n\t\t\tthis.currentStartingPointId === undefined ||\n\t\t\tthis.currentCoordinate === 0\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.currentCoordinate === 2) {\n\t\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<LineString>(\n\t\t\t\tthis.currentInitialArcId,\n\t\t\t).coordinates;\n\t\t\tconst center = this.store.getGeometryCopy<Point>(\n\t\t\t\tthis.currentStartingPointId,\n\t\t\t).coordinates;\n\n\t\t\tconst arcCoordOne = currentPolygonCoordinates[0];\n\t\t\tconst arcCoordTwo = [event.lng, event.lat];\n\n\t\t\tconst webMercatorArcCoordOne = lngLatToWebMercatorXY(\n\t\t\t\tarcCoordOne[0],\n\t\t\t\tarcCoordOne[1],\n\t\t\t);\n\t\t\tconst webMercatorArcCoordTwo = lngLatToWebMercatorXY(\n\t\t\t\tarcCoordTwo[0],\n\t\t\t\tarcCoordTwo[1],\n\t\t\t);\n\t\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\n\t\t\tconst radius = cartesianDistance(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t);\n\n\t\t\t// We want to determine the direction of the sector, whether\n\t\t\t// it is clockwise or anticlockwise\n\t\t\tif (this.direction === undefined) {\n\t\t\t\tconst clockwise = isClockwiseWebMercator(\n\t\t\t\t\twebMercatorCenter,\n\t\t\t\t\twebMercatorArcCoordOne,\n\t\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t\t);\n\t\t\t\tthis.direction = clockwise ? \"clockwise\" : \"anticlockwise\";\n\t\t\t}\n\n\t\t\t// Calculate bearings for the second and third points in Web Mercator\n\t\t\tconst startBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t);\n\t\t\tconst endBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t);\n\n\t\t\t// Generate points along the arc in Web Mercator\n\t\t\tconst numberOfPoints = this.arcPoints; // Number of points to approximate the arc\n\t\t\tconst coordinates: Position[] = [arcCoordOne];\n\n\t\t\t// Corrected version to calculate deltaBearing\n\t\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\n\t\t\t// Calculate the delta bearing based on the direction\n\t\t\tlet deltaBearing;\n\t\t\tif (this.direction === \"anticlockwise\") {\n\t\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\t\tif (deltaBearing < 0) {\n\t\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\t\tif (deltaBearing < 0) {\n\t\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst bearingStep =\n\t\t\t\t((this.direction === \"anticlockwise\" ? 1 : -1) * deltaBearing) /\n\t\t\t\tnumberOfPoints;\n\n\t\t\t// Add all the arc points\n\t\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\t\twebMercatorCenter,\n\t\t\t\t\tradius,\n\t\t\t\t\tcurrentBearing,\n\t\t\t\t);\n\t\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\t\tconst nextCoord = [\n\t\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t\t];\n\n\t\t\t\tconst notIdentical =\n\t\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\t\tif (notIdentical) {\n\t\t\t\t\tcoordinates.push(nextCoord);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.updateLineStringGeometry(\n\t\t\t\tthis.currentInitialArcId,\n\t\t\t\tcoordinates,\n\t\t\t\tUpdateTypes.Provisional,\n\t\t\t);\n\t\t} else if (this.currentCoordinate === 3) {\n\t\t\tconst coordinates = this.store.getGeometryCopy<LineString>(\n\t\t\t\tthis.currentInitialArcId,\n\t\t\t).coordinates;\n\n\t\t\tif (coordinates.length < 2) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// This shouldn't happen but we protect against it incase as we can't calculate if the cursor\n\t\t\t// is in the sector otherwise\n\t\t\tif (!this.direction) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst center = this.store.getGeometryCopy<Point>(\n\t\t\t\tthis.currentStartingPointId,\n\t\t\t).coordinates;\n\n\t\t\tconst firstCoord = coordinates[0];\n\t\t\tconst lastCoord = coordinates[coordinates.length - 1];\n\n\t\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\t\t\tconst webMercatorCoordOne = lngLatToWebMercatorXY(\n\t\t\t\tfirstCoord[0],\n\t\t\t\tfirstCoord[1],\n\t\t\t);\n\t\t\tconst webMercatorCoordTwo = lngLatToWebMercatorXY(\n\t\t\t\tlastCoord[0],\n\t\t\t\tlastCoord[1],\n\t\t\t);\n\n\t\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\n\t\t\tconst innerRadius = cartesianDistance(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorCoordOne,\n\t\t\t);\n\n\t\t\tconst outerRadius = cartesianDistance(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorCursor,\n\t\t\t);\n\n\t\t\tconst hasLessThanZeroSize = outerRadius < innerRadius;\n\n\t\t\t// If the cursor is inside the inner radius, the depth of the sensor is always 0\n\t\t\tconst radiusCalculationPosition = hasLessThanZeroSize\n\t\t\t\t? webMercatorCoordOne\n\t\t\t\t: webMercatorCursor;\n\n\t\t\tconst cursorBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorCursor,\n\t\t\t);\n\n\t\t\tconst startBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorCoordOne,\n\t\t\t);\n\t\t\tconst endBearing = webMercatorBearing(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorCoordTwo,\n\t\t\t);\n\n\t\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\t\t\tconst normalizedCursor = normalizeBearing(cursorBearing);\n\n\t\t\tconst notInSector = this.notInSector({\n\t\t\t\tnormalizedCursor,\n\t\t\t\tnormalizedStart,\n\t\t\t\tnormalizedEnd,\n\t\t\t\tdirection: this.direction,\n\t\t\t});\n\n\t\t\t// If it's not a valid cursor movement then we don't update\n\t\t\tif (notInSector) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Calculate the delta bearing based on the direction\n\t\t\tconst deltaBearing = this.getDeltaBearing(\n\t\t\t\tthis.direction,\n\t\t\t\tnormalizedStart,\n\t\t\t\tnormalizedEnd,\n\t\t\t);\n\n\t\t\t// Number of points to approximate the arc\n\t\t\tconst numberOfPoints = this.arcPoints;\n\n\t\t\t// Calculate bearing step\n\t\t\tconst multiplier = this.direction === \"anticlockwise\" ? 1 : -1;\n\t\t\tconst bearingStep = (multiplier * deltaBearing) / numberOfPoints;\n\n\t\t\tconst radius = cartesianDistance(\n\t\t\t\twebMercatorCenter,\n\t\t\t\tradiusCalculationPosition,\n\t\t\t);\n\n\t\t\t// Add all the arc points\n\t\t\tconst finalArc = [];\n\t\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\t\twebMercatorCenter,\n\t\t\t\t\tradius,\n\t\t\t\t\tcurrentBearing,\n\t\t\t\t);\n\t\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\t\tconst nextCoord = [\n\t\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t\t];\n\n\t\t\t\tconst notIdentical =\n\t\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\t\tif (notIdentical) {\n\t\t\t\t\tfinalArc.unshift(nextCoord);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcoordinates.push(...finalArc);\n\n\t\t\t// Close the polygon\n\t\t\tcoordinates.push(coordinates[0]);\n\n\t\t\t// If the polygon doesn't exist, create it\n\t\t\t// else update the existing geometry\n\t\t\tif (!this.currentId) {\n\t\t\t\t[this.currentId] = this.store.create([\n\t\t\t\t\t{\n\t\t\t\t\t\tgeometry: {\n\t\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\t\tcoordinates: [coordinates],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tthis.updatePolygonGeometry(\n\t\t\t\t\tthis.currentId,\n\t\t\t\t\tcoordinates,\n\t\t\t\t\tUpdateTypes.Provisional,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate updateLineStringGeometry(\n\t\tid: FeatureId,\n\t\tcoordinates: LineString[\"coordinates\"],\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tconst updatedGeometry = {\n\t\t\ttype: \"LineString\",\n\t\t\tcoordinates,\n\t\t} as LineString;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([{ id, geometry: updatedGeometry }]);\n\n\t\treturn true;\n\t}\n\n\tprivate updatePolygonGeometry(\n\t\tid: FeatureId,\n\t\tcoordinates: Polygon[\"coordinates\"][0],\n\t\tupdateType: UpdateTypes,\n\t) {\n\t\tconst updatedGeometry = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t} as Polygon;\n\n\t\tif (this.validate) {\n\t\t\tconst valid = this.validate(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t\t{\n\t\t\t\t\tproject: this.project,\n\t\t\t\t\tunproject: this.unproject,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tupdateType,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([{ id, geometry: updatedGeometry }]);\n\n\t\treturn true;\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: { type: \"Point\", coordinates: [event.lng, event.lat] },\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentStartingPointId = newId;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentStartingPointId) {\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentInitialArcId = newId;\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentStartingPointId) {\n\t\t\tthis.currentCoordinate++;\n\t\t\t// pass\n\t\t} else if (this.currentCoordinate === 3 && this.currentStartingPointId) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentStartingPointId) {\n\t\t\t\tthis.store.delete([this.currentStartingPointId]);\n\t\t\t}\n\t\t\tif (this.currentInitialArcId) {\n\t\t\t\tthis.store.delete([this.currentInitialArcId]);\n\t\t\t}\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t\tthis.currentStartingPointId = undefined;\n\t\tthis.direction = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 10;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.centerPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.centerPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointOutlineWidth,\n\t\t\t\t\tstyles.pointOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = 20;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tValidatePolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate getDeltaBearing(\n\t\tdirection: \"anticlockwise\" | \"clockwise\",\n\t\tnormalizedStart: number,\n\t\tnormalizedEnd: number,\n\t) {\n\t\tlet deltaBearing;\n\t\tif (direction === \"anticlockwise\") {\n\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t} else {\n\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t}\n\t\treturn deltaBearing;\n\t}\n\n\tprivate notInSector({\n\t\tnormalizedCursor,\n\t\tnormalizedStart,\n\t\tnormalizedEnd,\n\t\tdirection,\n\t}: {\n\t\tnormalizedCursor: number;\n\t\tnormalizedStart: number;\n\t\tnormalizedEnd: number;\n\t\tdirection: \"clockwise\" | \"anticlockwise\";\n\t}) {\n\t\tif (direction === \"clockwise\") {\n\t\t\t// Handle clockwise direction\n\t\t\tif (normalizedStart <= normalizedEnd) {\n\t\t\t\t// Standard case (no wrap-around)\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor >= normalizedStart &&\n\t\t\t\t\tnormalizedCursor <= normalizedEnd\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle wrap-around across 360 degrees\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor >= normalizedStart ||\n\t\t\t\t\tnormalizedCursor <= normalizedEnd\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle anticlockwise direction\n\t\t\tif (normalizedStart >= normalizedEnd) {\n\t\t\t\t// Standard case (no wrap-around)\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor <= normalizedStart &&\n\t\t\t\t\tnormalizedCursor >= normalizedEnd\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle wrap-around across 360 degrees\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor <= normalizedStart ||\n\t\t\t\t\tnormalizedCursor >= normalizedEnd\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { TerraDrawGoogleMapsAdapter } from \"./adapters/google-maps.adapter\";\nimport { TerraDrawLeafletAdapter } from \"./adapters/leaflet.adapter\";\nimport { TerraDrawMapboxGLAdapter } from \"./adapters/mapbox-gl.adapter\";\nimport { TerraDrawMapLibreGLAdapter } from \"./adapters/maplibre-gl.adapter\";\nimport { TerraDrawOpenLayersAdapter } from \"./adapters/openlayers.adapter\";\nimport { TerraDrawArcGISMapsSDKAdapter } from \"./adapters/arcgis-maps-sdk.adapter\";\nimport {\n\tTerraDrawAdapter,\n\tTerraDrawAdapterStyling,\n\tGetLngLatFromEvent,\n\tProject,\n\tSetCursor,\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n\tUnproject,\n\tHexColor,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawMouseEvent,\n\tSELECT_PROPERTIES,\n\tOnFinishContext,\n} from \"./common\";\nimport {\n\tModeTypes,\n\tTerraDrawBaseDrawMode,\n\tTerraDrawBaseSelectMode,\n} from \"./modes/base.mode\";\nimport { TerraDrawCircleMode } from \"./modes/circle/circle.mode\";\nimport { TerraDrawFreehandMode } from \"./modes/freehand/freehand.mode\";\nimport { TerraDrawLineStringMode } from \"./modes/linestring/linestring.mode\";\nimport { TerraDrawPointMode } from \"./modes/point/point.mode\";\nimport { TerraDrawPolygonMode } from \"./modes/polygon/polygon.mode\";\nimport { TerraDrawRectangleMode } from \"./modes/rectangle/rectangle.mode\";\nimport { TerraDrawRenderMode } from \"./modes/render/render.mode\";\nimport { TerraDrawSelectMode } from \"./modes/select/select.mode\";\nimport { TerraDrawStaticMode } from \"./modes/static/static.mode\";\nimport {\n\tBBoxPolygon,\n\tFeatureId,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tIdStrategy,\n\tStoreChangeHandler,\n} from \"./store/store\";\nimport { BehaviorConfig } from \"./modes/base.behavior\";\nimport { cartesianDistance } from \"./geometry/measure/pixel-distance\";\nimport { pixelDistanceToLine } from \"./geometry/measure/pixel-distance-to-line\";\nimport { Position } from \"geojson\";\nimport { pointInPolygon } from \"./geometry/boolean/point-in-polygon\";\nimport { createBBoxFromPoint } from \"./geometry/shape/create-bbox\";\nimport { ValidateMinAreaSquareMeters } from \"./validations/min-size.validation\";\nimport { ValidateMaxAreaSquareMeters } from \"./validations/max-size.validation\";\nimport { ValidateNotSelfIntersecting } from \"./validations/not-self-intersecting.validation\";\nimport { TerraDrawAngledRectangleMode } from \"./modes/angled-rectangle/angled-rectangle.mode\";\nimport { TerraDrawSectorMode } from \"./modes/sector/sector.mode\";\nimport { TerraDrawSensorMode } from \"./modes/sensor/sensor.mode\";\nimport * as TerraDrawExtend from \"./extend\";\n\ntype FinishListener = (id: FeatureId, context: OnFinishContext) => void;\ntype ChangeListener = (ids: FeatureId[], type: string) => void;\ntype SelectListener = (id: FeatureId) => void;\ntype DeselectListener = () => void;\n\ninterface TerraDrawEventListeners {\n\tready: () => void;\n\tfinish: FinishListener;\n\tchange: ChangeListener;\n\tselect: SelectListener;\n\tdeselect: DeselectListener;\n}\n\ntype TerraDrawEvents = keyof TerraDrawEventListeners;\n\nclass TerraDraw {\n\tprivate _modes: {\n\t\t[mode: string]: TerraDrawBaseDrawMode<any> | TerraDrawBaseSelectMode<any>;\n\t};\n\tprivate _mode: TerraDrawBaseDrawMode<any> | TerraDrawBaseSelectMode<any>;\n\tprivate _adapter: TerraDrawAdapter;\n\tprivate _enabled = false;\n\tprivate _store: GeoJSONStore;\n\tprivate _eventListeners: {\n\t\tready: (() => void)[];\n\t\tchange: ChangeListener[];\n\t\tfinish: FinishListener[];\n\t\tselect: SelectListener[];\n\t\tdeselect: DeselectListener[];\n\t};\n\t// This is the select mode that is assigned in the instance.\n\t// There can only be 1 select mode active per instance\n\tprivate _instanceSelectMode: undefined | string;\n\n\tconstructor(options: {\n\t\tadapter: TerraDrawAdapter;\n\t\tmodes: TerraDrawBaseDrawMode<any>[];\n\t\tidStrategy?: IdStrategy<FeatureId>;\n\t\ttracked?: boolean;\n\t}) {\n\t\tthis._adapter = options.adapter;\n\n\t\tthis._mode = new TerraDrawStaticMode();\n\n\t\t// Keep track of if there are duplicate modes\n\t\tconst duplicateModeTracker = new Set();\n\n\t\t// Construct a map of the mode name to the mode\n\t\tconst modesMap = options.modes.reduce<{\n\t\t\t[mode: string]: TerraDrawBaseDrawMode<any>;\n\t\t}>((modeMap, currentMode) => {\n\t\t\tif (duplicateModeTracker.has(currentMode.mode)) {\n\t\t\t\tthrow new Error(`There is already a ${currentMode.mode} mode provided`);\n\t\t\t}\n\t\t\tduplicateModeTracker.add(currentMode.mode);\n\t\t\tmodeMap[currentMode.mode] = currentMode;\n\t\t\treturn modeMap;\n\t\t}, {});\n\n\t\t// Construct an array of the mode keys (names)\n\t\tconst modeKeys = Object.keys(modesMap);\n\n\t\t// Ensure at least one draw mode is provided\n\t\tif (modeKeys.length === 0) {\n\t\t\tthrow new Error(\"No modes provided\");\n\t\t}\n\n\t\t// Ensure only one select mode can be present\n\t\tmodeKeys.forEach((mode) => {\n\t\t\tif (modesMap[mode].type !== ModeTypes.Select) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this._instanceSelectMode) {\n\t\t\t\tthrow new Error(\"only one type of select mode can be provided\");\n\t\t\t} else {\n\t\t\t\tthis._instanceSelectMode = mode;\n\t\t\t}\n\t\t});\n\n\t\tthis._modes = { ...modesMap, static: this._mode };\n\t\tthis._eventListeners = {\n\t\t\tchange: [],\n\t\t\tselect: [],\n\t\t\tdeselect: [],\n\t\t\tfinish: [],\n\t\t\tready: [],\n\t\t};\n\t\tthis._store = new GeoJSONStore<FeatureId>({\n\t\t\ttracked: options.tracked ? true : false,\n\t\t\tidStrategy: options.idStrategy ? options.idStrategy : undefined,\n\t\t});\n\n\t\tconst getChanged = (\n\t\t\tids: FeatureId[],\n\t\t): {\n\t\t\tchanged: GeoJSONStoreFeatures[];\n\t\t\tunchanged: GeoJSONStoreFeatures[];\n\t\t} => {\n\t\t\tconst changed: GeoJSONStoreFeatures[] = [];\n\n\t\t\tconst unchanged = this._store.copyAll().filter((f) => {\n\t\t\t\tif (ids.includes(f.id as string)) {\n\t\t\t\t\tchanged.push(f);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t\treturn { changed, unchanged };\n\t\t};\n\n\t\tconst onFinish = (finishedId: FeatureId, context: OnFinishContext) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.finish.forEach((listener) => {\n\t\t\t\tlistener(finishedId, context);\n\t\t\t});\n\t\t};\n\n\t\tconst onChange: StoreChangeHandler = (ids, event) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.change.forEach((listener) => {\n\t\t\t\tlistener(ids, event);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged(ids);\n\n\t\t\tif (event === \"create\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: changed,\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: [],\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"update\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"delete\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: ids, unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"styling\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onSelect = (selectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.select.forEach((listener) => {\n\t\t\t\tlistener(selectedId);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([selectedId]);\n\n\t\t\tthis._adapter.render(\n\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: changed },\n\t\t\t\tthis.getModeStyles(),\n\t\t\t);\n\t\t};\n\n\t\tconst onDeselect = (deselectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.deselect.forEach((listener) => {\n\t\t\t\tlistener();\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([deselectedId]);\n\n\t\t\t// onDeselect can be called after a delete call which means that\n\t\t\t// you are deselecting a feature that has been deleted. We\n\t\t\t// double check here to ensure that the feature still exists.\n\t\t\tif (changed) {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\t// Register stores and callbacks\n\t\tObject.keys(this._modes).forEach((modeId) => {\n\t\t\tthis._modes[modeId].register({\n\t\t\t\tmode: modeId,\n\t\t\t\tstore: this._store,\n\t\t\t\tsetCursor: this._adapter.setCursor.bind(this._adapter),\n\t\t\t\tproject: this._adapter.project.bind(this._adapter),\n\t\t\t\tunproject: this._adapter.unproject.bind(this._adapter),\n\t\t\t\tsetDoubleClickToZoom: this._adapter.setDoubleClickToZoom.bind(\n\t\t\t\t\tthis._adapter,\n\t\t\t\t),\n\t\t\t\tonChange: onChange,\n\t\t\t\tonSelect: onSelect,\n\t\t\t\tonDeselect: onDeselect,\n\t\t\t\tonFinish: onFinish,\n\t\t\t\tcoordinatePrecision: this._adapter.getCoordinatePrecision(),\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate checkEnabled() {\n\t\tif (!this._enabled) {\n\t\t\tthrow new Error(\"Terra Draw is not enabled\");\n\t\t}\n\t}\n\n\tprivate getModeStyles() {\n\t\tconst modeStyles: {\n\t\t\t[key: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n\t\t} = {};\n\n\t\tObject.keys(this._modes).forEach((mode) => {\n\t\t\tmodeStyles[mode] = (feature: GeoJSONStoreFeatures) => {\n\t\t\t\t// If the feature is selected, we want to use the select mode styling\n\t\t\t\tif (\n\t\t\t\t\tthis._instanceSelectMode &&\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTED]\n\t\t\t\t) {\n\t\t\t\t\treturn this._modes[this._instanceSelectMode].styleFeature.bind(\n\t\t\t\t\t\tthis._modes[this._instanceSelectMode],\n\t\t\t\t\t)(feature);\n\t\t\t\t}\n\n\t\t\t\t// Otherwise use regular styling\n\t\t\t\treturn this._modes[mode].styleFeature.bind(this._modes[mode])(feature);\n\t\t\t};\n\t\t});\n\t\treturn modeStyles;\n\t}\n\n\tprivate featuresAtLocation(\n\t\t{\n\t\t\tlng,\n\t\t\tlat,\n\t\t}: {\n\t\t\tlng: number;\n\t\t\tlat: number;\n\t\t},\n\t\toptions?: { pointerDistance: number; ignoreSelectFeatures: boolean },\n\t) {\n\t\tconst pointerDistance =\n\t\t\toptions && options.pointerDistance !== undefined\n\t\t\t\t? options.pointerDistance\n\t\t\t\t: 30; // default is 30px\n\n\t\tconst ignoreSelectFeatures =\n\t\t\toptions && options.ignoreSelectFeatures !== undefined\n\t\t\t\t? options.ignoreSelectFeatures\n\t\t\t\t: true;\n\n\t\tconst unproject = this._adapter.unproject.bind(this._adapter);\n\t\tconst project = this._adapter.project.bind(this._adapter);\n\n\t\tconst inputPoint = project(lng, lat);\n\n\t\tconst bbox = createBBoxFromPoint({\n\t\t\tunproject,\n\t\t\tpoint: inputPoint,\n\t\t\tpointerDistance,\n\t\t});\n\n\t\tconst features = this._store.search(bbox as BBoxPolygon);\n\n\t\t// TODO: This is designed to work in a similar way as FeatureAtPointerEvent\n\t\t// perhaps at some point we could figure out how to unify them\n\t\treturn features.filter((feature) => {\n\t\t\tif (\n\t\t\t\tignoreSelectFeatures &&\n\t\t\t\t(feature.properties[SELECT_PROPERTIES.MID_POINT] ||\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTION_POINT])\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\tconst pointCoordinates = feature.geometry.coordinates;\n\t\t\t\tconst pointXY = project(pointCoordinates[0], pointCoordinates[1]);\n\t\t\t\tconst distance = cartesianDistance(inputPoint, pointXY);\n\t\t\t\treturn distance < pointerDistance;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tconst coordinates: Position[] = feature.geometry.coordinates;\n\n\t\t\t\tfor (let i = 0; i < coordinates.length - 1; i++) {\n\t\t\t\t\tconst coord = coordinates[i];\n\t\t\t\t\tconst nextCoord = coordinates[i + 1];\n\t\t\t\t\tconst distanceToLine = pixelDistanceToLine(\n\t\t\t\t\t\tinputPoint,\n\t\t\t\t\t\tproject(coord[0], coord[1]),\n\t\t\t\t\t\tproject(nextCoord[0], nextCoord[1]),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (distanceToLine < pointerDistance) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tconst lngLatInsidePolygon = pointInPolygon(\n\t\t\t\t\t[lng, lat],\n\t\t\t\t\tfeature.geometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\tif (lngLatInsidePolygon) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate getSelectMode() {\n\t\tthis.checkEnabled();\n\n\t\tif (!this._instanceSelectMode) {\n\t\t\tthrow new Error(\"No select mode defined in instance\");\n\t\t}\n\n\t\tconst currentMode = this.getMode();\n\n\t\t// If we're not already in the select mode, we switch to it\n\t\tif (currentMode !== this._instanceSelectMode) {\n\t\t\tthis.setMode(this._instanceSelectMode);\n\t\t}\n\n\t\tconst selectMode = this._modes[\n\t\t\tthis._instanceSelectMode\n\t\t] as TerraDrawBaseSelectMode<any>;\n\n\t\treturn selectMode;\n\t}\n\n\t/**\n\t * Allows the setting of a style for a given mode\n\t *\n\t * @param mode - The mode you wish to set a style for\n\t * @param styles - The styles you wish to set for the mode - this is\n\t * the same as the initialisation style schema\n\t *\n\t * @beta\n\t */\n\tsetModeStyles<Styling extends Record<string, number | HexColor>>(\n\t\tmode: string,\n\t\tstyles: Styling,\n\t) {\n\t\tthis.checkEnabled();\n\t\tif (!this._modes[mode]) {\n\t\t\tthrow new Error(\"No mode with this name present\");\n\t\t}\n\n\t\t// TODO: Not sure why this fails TypeScript with TerraDrawBaseSelectMode?\n\t\t(this._modes[mode] as TerraDrawBaseDrawMode<any>).styles = styles;\n\t}\n\n\t/**\n\t * Allows the user to get a snapshot (copy) of all given features\n\t *\n\t * @returns An array of all given Feature Geometries in the instances store\n\t *\n\t * @beta\n\t */\n\tgetSnapshot() {\n\t\t// This is a read only method so we do not need to check if enabled\n\t\treturn this._store.copyAll();\n\t}\n\n\t/**\n\t * Removes all data from the current store and removes any rendered layers\n\t * via the registering the adapter.\n\t *\n\t * @beta\n\t */\n\tclear() {\n\t\tthis.checkEnabled();\n\t\tthis._adapter.clear();\n\t}\n\n\t/**\n\t * A property used to determine whether the instance is active or not. You\n\t * can use the start method to set this to true, and stop method to set this to false.\n\t * This is a read only property.\n\t *\n\t * @return true or false depending on if the instance is stopped or started\n\t * @readonly\n\t * @beta\n\t */\n\tget enabled(): boolean {\n\t\treturn this._enabled;\n\t}\n\n\t/**\n\t * enabled is a read only property and will throw and error if you try and set it.\n\t *\n\t * @beta\n\t */\n\tset enabled(_) {\n\t\tthrow new Error(\"Enabled is read only\");\n\t}\n\n\t/**\n\t * A method for getting the current mode name\n\t *\n\t * @return the current mode name\n\t *\n\t * @beta\n\t */\n\tgetMode(): string {\n\t\t// This is a read only method so we do not need to check if enabled\n\t\treturn this._mode.mode;\n\t}\n\n\t/**\n\t * A method for setting the current mode by name. Under the hood this will stop\n\t * the previous mode and start the new one.\n\t * @param mode - The mode name you wish to start\n\t *\n\t * @beta\n\t */\n\tsetMode(mode: string) {\n\t\tthis.checkEnabled();\n\n\t\tif (this._modes[mode]) {\n\t\t\t// Before we swap modes we want to\n\t\t\t// clean up any state that has been left behind,\n\t\t\t// for example current drawing geometries\n\t\t\t// and mode state\n\t\t\tthis._mode.stop();\n\n\t\t\t// Swap the mode to the new mode\n\t\t\tthis._mode = this._modes[mode];\n\n\t\t\t// Start the new mode\n\t\t\tthis._mode.start();\n\t\t} else {\n\t\t\t// If the mode doesn't exist, we throw an error\n\t\t\tthrow new Error(\"No mode with this name present\");\n\t\t}\n\t}\n\n\t/**\n\t * A method for removing features to the store\n\t * @param ids\n\t * @returns\n\t *\n\t * @beta\n\t */\n\tremoveFeatures(ids: FeatureId[]) {\n\t\tthis.checkEnabled();\n\t\tthis._store.delete(ids);\n\t}\n\n\t/**\n\t * Provides the ability to programmatically select a feature using the instances provided select mode.\n\t * If not select mode is provided in the instance, an error will be thrown. If the instance is not currently\n\t * in the select mode, it will switch to it.\n\t * @param id - the id of the feature to select\n\t * @beta\n\t */\n\tselectFeature(id: FeatureId) {\n\t\tconst selectMdode = this.getSelectMode();\n\t\tselectMdode.selectFeature(id);\n\t}\n\n\t/**\n\t * Provides the ability to programmatically deselect a feature using the instances provided select mode.\n\t * If not select mode is provided in the instance, an error will be thrown. If the instance is not currently\n\t * in the select mode, it will switch to it.\n\t * @param id  - the id of the feature to deselect\n\t * @beta\n\t */\n\tdeselectFeature(id: FeatureId) {\n\t\tconst selectMode = this.getSelectMode();\n\t\tselectMode.deselectFeature(id);\n\t}\n\n\t/**\n\t * Returns the next feature id from the store - defaults to UUID4 unless you have\n\t * set a custom idStrategy. This method can be useful if you are needing creating features\n\t * outside of the Terra Draw instance but want to add them in to the store.\n\t * @returns a id, either number of string based on whatever the configured idStrategy is\n\t *\n\t * @beta\n\t */\n\tgetFeatureId(): FeatureId {\n\t\treturn this._store.getId();\n\t}\n\n\t/**\n\t * Returns true or false depending on if the Terra Draw instance has a feature with a given id\n\t * @returns a boolean determining if the instance has a feature with the given id\n\t *\n\t * @beta\n\t */\n\thasFeature(id: FeatureId): boolean {\n\t\treturn this._store.has(id);\n\t}\n\n\t/**\n\t * A method for adding features to the store. This method will validate the features.\n\t * Features must match one of the modes enabled in the instance.\n\t * @param mode\n\t * @param features\n\t * @returns\n\t *\n\t * @beta\n\t */\n\taddFeatures(features: GeoJSONStoreFeatures[]) {\n\t\tthis.checkEnabled();\n\n\t\tif (features.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._store.load(features, (feature) => {\n\t\t\tconst hasModeProperty = Boolean(\n\t\t\t\tfeature &&\n\t\t\t\t\ttypeof feature === \"object\" &&\n\t\t\t\t\t\"properties\" in feature &&\n\t\t\t\t\ttypeof feature.properties === \"object\" &&\n\t\t\t\t\tfeature.properties !== null &&\n\t\t\t\t\t\"mode\" in feature.properties,\n\t\t\t);\n\n\t\t\tif (hasModeProperty) {\n\t\t\t\tconst modeToAddTo =\n\t\t\t\t\tthis._modes[\n\t\t\t\t\t\t(feature as { properties: { mode: string } }).properties.mode\n\t\t\t\t\t];\n\n\t\t\t\t// if the mode does not exist, we return false\n\t\t\t\tif (!modeToAddTo) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// use the inbuilt validation of the mode\n\t\t\t\tconst validation = modeToAddTo.validateFeature.bind(modeToAddTo);\n\t\t\t\treturn validation(feature);\n\t\t\t}\n\n\t\t\t// If the feature does not have a mode property, we return false\n\t\t\treturn false;\n\t\t});\n\t}\n\n\t/**\n\t * A method starting Terra Draw. It put the instance into a started state, and\n\t * in registers the passed adapter giving it all the callbacks required to operate.\n\t *\n\t * @beta\n\t */\n\tstart() {\n\t\tthis._enabled = true;\n\t\tthis._adapter.register({\n\t\t\tonReady: () => {\n\t\t\t\tthis._eventListeners.ready.forEach((listener) => {\n\t\t\t\t\tlistener();\n\t\t\t\t});\n\t\t\t},\n\t\t\tgetState: () => {\n\t\t\t\treturn this._mode.state;\n\t\t\t},\n\t\t\tonClick: (event) => {\n\t\t\t\tthis._mode.onClick(event);\n\t\t\t},\n\t\t\tonMouseMove: (event) => {\n\t\t\t\tthis._mode.onMouseMove(event);\n\t\t\t},\n\t\t\tonKeyDown: (event) => {\n\t\t\t\tthis._mode.onKeyDown(event);\n\t\t\t},\n\t\t\tonKeyUp: (event) => {\n\t\t\t\tthis._mode.onKeyUp(event);\n\t\t\t},\n\t\t\tonDragStart: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragStart(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDrag: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDrag(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDragEnd: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragEnd(event, setMapDraggability);\n\t\t\t},\n\t\t\tonClear: () => {\n\t\t\t\t// Ensure that the mode resets its state\n\t\t\t\t// as it may be storing feature ids internally in it's instance\n\t\t\t\tthis._mode.cleanUp();\n\n\t\t\t\t// Remove all features from the store\n\t\t\t\tthis._store.clear();\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Gets the features at a given longitude and latitude.\n\t * Will return point and linestrings that are a given pixel distance\n\t * away from the lng/lat and any polygons which contain it.\n\t *\n\t * @beta\n\t */\n\tgetFeaturesAtLngLat(\n\t\tlngLat: { lng: number; lat: number },\n\t\toptions?: { pointerDistance: number; ignoreSelectFeatures: boolean },\n\t) {\n\t\tconst { lng, lat } = lngLat;\n\n\t\treturn this.featuresAtLocation(\n\t\t\t{\n\t\t\t\tlng,\n\t\t\t\tlat,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\t/**\n\t * Takes a given pointer event and\n\t * Will return point and linestrings that are a given pixel distance\n\t * away from the lng/lat and any polygons which contain it.\n\t *\n\t * @beta\n\t */\n\tgetFeaturesAtPointerEvent(\n\t\tevent: PointerEvent | MouseEvent,\n\t\toptions?: { pointerDistance: number; ignoreSelectFeatures: boolean },\n\t) {\n\t\tconst getLngLatFromEvent = this._adapter.getLngLatFromEvent.bind(\n\t\t\tthis._adapter,\n\t\t);\n\n\t\tconst lngLat = getLngLatFromEvent(event);\n\n\t\t// If the pointer event is outside the container or the underlying library is\n\t\t// not ready we can get null as a returned value\n\t\tif (lngLat === null) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn this.featuresAtLocation(lngLat, options);\n\t}\n\n\t/**\n\t * A method for stopping Terra Draw. Will clear the store, deregister the adapter and\n\t * remove any rendered layers in the process.\n\t *\n\t * @beta\n\t */\n\tstop() {\n\t\tthis._enabled = false;\n\t\tthis._adapter.unregister();\n\t}\n\n\t/**\n\t * Registers a Terra Draw event\n\t *\n\t * @param event - The name of the event you wish to listen for\n\t * @param callback - The callback with you wish to be called when this event occurs\n\t *\n\t * @beta\n\t */\n\ton<T extends TerraDrawEvents>(\n\t\tevent: T,\n\t\tcallback: TerraDrawEventListeners[T],\n\t) {\n\t\tconst listeners = this._eventListeners[\n\t\t\tevent\n\t\t] as TerraDrawEventListeners[T][];\n\t\tif (!listeners.includes(callback)) {\n\t\t\tlisteners.push(callback);\n\t\t}\n\t}\n\n\t/**\n\t * Unregisters a Terra Draw event\n\t *\n\t * @param event - The name of the event you wish to unregister\n\t * @param callback - The callback you originally provided to the 'on' method\n\t *\n\t * @beta\n\t */\n\toff<T extends TerraDrawEvents>(\n\t\tevent: TerraDrawEvents,\n\t\tcallback: TerraDrawEventListeners[T],\n\t) {\n\t\tconst listeners = this._eventListeners[\n\t\t\tevent\n\t\t] as TerraDrawEventListeners[T][];\n\t\tif (listeners.includes(callback)) {\n\t\t\tlisteners.splice(listeners.indexOf(callback), 1);\n\t\t}\n\t}\n}\n\nexport {\n\tTerraDraw,\n\n\t// Modes\n\tTerraDrawSelectMode,\n\tTerraDrawPointMode,\n\tTerraDrawLineStringMode,\n\tTerraDrawPolygonMode,\n\tTerraDrawCircleMode,\n\tTerraDrawFreehandMode,\n\tTerraDrawRenderMode,\n\tTerraDrawRectangleMode,\n\tTerraDrawAngledRectangleMode,\n\tTerraDrawSectorMode,\n\tTerraDrawSensorMode,\n\n\t// Adapters\n\tTerraDrawGoogleMapsAdapter,\n\tTerraDrawMapboxGLAdapter,\n\tTerraDrawLeafletAdapter,\n\tTerraDrawMapLibreGLAdapter,\n\tTerraDrawOpenLayersAdapter,\n\tTerraDrawArcGISMapsSDKAdapter,\n\n\t// Types that are required for 3rd party developers to extend\n\tTerraDrawExtend,\n\n\t// TerraDrawBaseMode\n\tBehaviorConfig,\n\tGeoJSONStoreFeatures,\n\tHexColor,\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\n\t// TerraDrawBaseAdapter\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n\tProject,\n\tUnproject,\n\tSetCursor,\n\tGetLngLatFromEvent,\n\n\t// Validations\n\tValidateMinAreaSquareMeters,\n\tValidateMaxAreaSquareMeters,\n\tValidateNotSelfIntersecting,\n};\n","import { polygonAreaSquareMeters } from \"../geometry/measure/area\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\n\nexport const ValidateMaxAreaSquareMeters = (\n\tfeature: GeoJSONStoreFeatures,\n\tmaxSize: number,\n): boolean => {\n\tif (feature.geometry.type !== \"Polygon\") {\n\t\treturn false;\n\t}\n\n\tconst size = polygonAreaSquareMeters(feature.geometry);\n\treturn size < maxSize;\n};\n","import { polygonAreaSquareMeters } from \"../geometry/measure/area\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\n\nexport const ValidateMinAreaSquareMeters = (\n\tfeature: GeoJSONStoreFeatures,\n\tminSize: number,\n): boolean => {\n\tif (feature.geometry.type !== \"Polygon\") {\n\t\treturn false;\n\t}\n\n\treturn polygonAreaSquareMeters(feature.geometry) > minSize;\n};\n","import { Feature, LineString, Polygon } from \"geojson\";\nimport { selfIntersects } from \"../geometry/boolean/self-intersects\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\n\nexport const ValidateNotSelfIntersecting = (\n\tfeature: GeoJSONStoreFeatures,\n): boolean => {\n\tif (\n\t\tfeature.geometry.type !== \"Polygon\" &&\n\t\tfeature.geometry.type !== \"LineString\"\n\t) {\n\t\treturn false;\n\t}\n\n\tconst hasSelfIntersections = selfIntersects(\n\t\tfeature as Feature<LineString> | Feature<Polygon>,\n\t);\n\n\treturn !hasSelfIntersections;\n};\n"],"names":["limitPrecision","num","decimalLimit","decimals","Math","pow","round","cartesianDistance","pointOne","pointTwo","y","x","sqrt","AdapterListener","_ref","_this","this","name","callback","unregister","register","registered","TerraDrawBaseAdapter","config","_minPixelDragDistance","_minPixelDragDistanceDrawing","_minPixelDragDistanceSelecting","_lastDrawEvent","_coordinatePrecision","_heldKeys","Set","_listeners","_dragState","_currentModeCallbacks","minPixelDragDistance","minPixelDragDistanceSelecting","minPixelDragDistanceDrawing","coordinatePrecision","_proto","prototype","getButton","event","button","getMapElementXYPosition","_mapElement$getBoundi","getMapEventElement","getBoundingClientRect","containerX","clientX","left","containerY","clientY","top","getDrawEventFromEvent","latLng","getLngLatFromEvent","lng","lat","_this$getMapElementXY","heldKeys","Array","from","callbacks","getAdapterListeners","forEach","listener","getCoordinatePrecision","isPrimary","drawEvent","addEventListener","removeEventListener","preventDefault","onMouseMove","lastEventXY","currentEventXY","modeState","getState","pixelDistanceToCheck","onDragStart","enabled","setDraggability","bind","onDrag","target","onDragEnd","onClick","key","onKeyUp","add","onKeyDown","clear","TerraDrawGoogleMapsAdapter","_TerraDrawBaseAdapter","call","_cursor","_cursorStyleSheet","_lib","_map","_overlay","_clickEventListener","_mouseMoveEventListener","renderedFeatureIds","lib","map","getDiv","id","Error","_inheritsLoose","circlePath","cx","cy","r","d","_this2","OverlayView","draw","onAdd","onReady","setMap","data","addListener","clickListener","find","mouseMoveListener","_ref2","_this$_clickEventList","_this$_mouseMoveEvent","_this$_overlay","remove","undefined","bounds","getBounds","ne","getNorthEast","sw","getSouthWest","latLngBounds","LatLngBounds","mapCanvas","offsetX","offsetY","screenCoord","Point","projection","getProjection","fromContainerPixelToLatLng","contains","querySelector","project","point","fromLatLngToContainerPixel","LatLng","unproject","setCursor","cursor","div","styleDiv","document","classList","style","createElement","innerHTML","getElementsByTagName","appendChild","setDoubleClickToZoom","setOptions","disableDoubleClickZoom","draggable","render","changes","styling","_this3","_layers","deletedIds","deletedId","featureToDelete","getFeatureById","updated","updatedFeature","featureToUpdate","forEachProperty","property","setProperty","Object","keys","properties","geometry","type","coordinates","setGeometry","Data","path","i","length","coordinate","push","LineString","paths","j","Polygon","created","createdFeature","addGeoJson","feature","featureCollection","features","concat","setStyle","mode","getProperty","gmGeometry","getGeometry","getType","value","calculatedStyles","clickable","icon","pointWidth","fillColor","pointColor","fillOpacity","strokeColor","pointOutlineColor","strokeWeight","pointOutlineWidth","rotation","scale","lineStringColor","lineStringWidth","polygonOutlineColor","polygonOutlineWidth","polygonFillOpacity","polygonFillColor","clearLayers","_this4","getId","has","onClear","_createClass","get","_this$renderedFeature","Boolean","size","TerraDrawLeafletAdapter","_panes","_container","getContainer","createPaneStyleSheet","pane","zIndex","paneZIndex","createPane","clearPanes","values","layer","removeLayer","styleGeoJSONLayer","pointToLayer","latlng","featureStyles","modeStyle","paneId","String","circleMarker","radius","stroke","color","weight","interactive","_feature","containerPointToLatLng","isNaN","dragging","enable","disable","_this$_map$latLngToCo","latLngToContainerPoint","_this$_map$containerP","removeProperty","doubleClickZoom","geoJSON","addLayer","deleted","TerraDrawMapboxGLAdapter","_nextRender","_rendered","changedIds","deletion","points","linestrings","polygons","geometryKey","toLowerCase","removeSource","cancelAnimationFrame","_addGeoJSONSource","addSource","tolerance","_addFillLayer","source","paint","_addFillOutlineLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","_setGeoJSONLayerData","getSource","setData","updateChangedIds","_this$_container$getB","getCanvas","dragRotate","dragPan","_this$_map$project","_this$_map$unproject","canvas","requestAnimationFrame","unchanged","styles","pointId","forceUpdate","updateLineStrings","updatedPolygon","moveLayer","TerraDrawMapLibreGLAdapter","mapboxglAdapter","METERS_PER_UNIT","radians","PI","degrees","ft","m","Projection$1","constructor","options","code_","code","units_","extent_","extent","worldExtent_","worldExtent","axisOrientation_","axisOrientation","global_","global","canWrapX_","getPointResolutionFunc_","getPointResolution","defaultTileGrid_","metersPerUnit_","metersPerUnit","canWrapX","getCode","getExtent","getUnits","getMetersPerUnit","getWorldExtent","getAxisOrientation","isGlobal","setGlobal","getDefaultTileGrid","setDefaultTileGrid","tileGrid","setExtent","setWorldExtent","setGetPointResolution","func","getPointResolutionFunc","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","MAX_SAFE_Y","log","tan","EPSG3857Projection","Projection","super","units","resolution","cosh","PROJECTIONS","EPSG4326Projection","cache","transforms","destination","transformFn","sourceCode","destinationCode","cloneTransform","input","output","ii","slice","identityTransform","addProjection","addProj","addTransformFunc","projectionLike","replace","addEquivalentProjections","projections","addProjections","transform","transformFunc","sourceProjection","destinationProjection","getTransformFunc","getTransformFromProjections","getTransform","projections2","forwardTransform","inverseTransform","EPSG3857_PROJECTIONS","EPSG4326_PROJECTIONS","dimension","atan","exp","projection1","projection2","UpdateTypes","TerraDrawOpenLayersAdapter","stylingFunction","_projection","_vectorSource","_geoJSONReader","GeoJSON","_this$_lib$getUserPro","getUserProjection","getViewport","setAttribute","vectorSource","VectorSource","vectorLayer","VectorLayer","getStyles","hexToRGB","hex","parseInt","g","b","getProperties","Style","image","Circle","fill","Fill","Stroke","width","_this2$hexToRGB","addFeature","olFeature","readFeature","dataProjection","featureProjection","removeFeature","_","canvases","querySelectorAll","getInteractions","interaction","setActive","_this$_map$getPixelFr","getPixelFromCoordinate","_toLonLat","lonLat","lon","a","modulo","toLonLat","getCoordinateFromPixel","TerraDrawArcGISMapsSDKAdapter","_mapView","_featureIdAttributeName","_featureLayerName","_featureLayer","_dragEnabled","_zoomEnabled","_dragHandler","_doubleClickHandler","container","GraphicsLayer","on","stopPropagation","longitude","latitude","_this$_mapView$toScre","toScreen","_this$_mapView$toMap","toMap","removeFeatureById","graphics","removeAll","attributes","_attributes","_feature$geometry","symbol","SimpleMarkerSymbol","getColorFromHex","outline","Polyline","SimpleLineSymbol","rings","SimpleFillSymbol","graphic","Graphic","hexColor","opacity","Color","fromHex","ModeTypes","SELECT_PROPERTIES","POLYGON_PROPERTIES","isObject","isArray","isValidTimestamp","timestamp","Date","valueOf","dateIsValid","TerraDrawBaseDrawMode","_state","_styles","behaviors","validate","pointerDistance","onStyleChange","store","Drawing","_extends","validation","registerBehaviors","behaviorConfig","setDrawing","setStarted","setStopped","registerOnChange","onChange","onSelect","onDeselect","onFinish","validateFeature","validStoreFeature","isValidId","error","includes","isValidStoreFeature","idStrategy","updateType","Provisional","finishedId","context","deselectedId","selectedId","setMapDraggability","getHexColorStylingValue","defaultValue","getStylingValue","getNumericStylingValue","set","TerraDrawBaseSelectMode","_TerraDrawBaseDrawMod","_len","arguments","args","_key","apply","Select","haversineDistanceKilometers","toRadians","latOrLng","phiOne","lambdaOne","phiTwo","deltaPhi","deltalambda","sin","cos","atan2","earthRadius","degreesToRadians","lengthToRadians","distance","radiansToDegrees","RADIANS_TO_DEGREES","DEGREES_TO_RADIANS","R","lngLatToWebMercatorXY","webMercatorXYToLngLat","origin","bearing","longitude1","latitude1","bearingRad","latitude2","asin","circle","center","radiusKilometers","steps","circleCoordinate","selfIntersects","coord","epsilon","ring0","edge0","ring1","edge1","ifInteresctionAddToOutput","isOutside","frac","frac1","start0","end0","start1","end1","intersection","equalArrays","x0","y0","x1","y1","x2","y2","x3","y3","denom","intersect","toString","array1","array2","coordinateIsValid","Infinity","getDecimalPlaces","current","precision","ValidatePolygonFeature","every","coordinateOne","coordinateTwo","ValidateNonIntersectingPolygonFeature","TerraDrawCircleMode","_options$startingRadi","clickCount","currentCircleId","keyEvents","cursors","startingRadiusKilometers","defaultCursors","start","cancel","finish","defaultKeyEvents","close","currentGeometry","getGeometryCopy","Finish","state","action","stop","cleanUp","startingCircle","_this$store$create","create","updateCircle","cleanUpId","styleFeature","outlineColor","outlineWidth","updatedCircle","newRadius","distortion","geodesicDistance","_lngLatToWebMercatorX","_lngLatToWebMercatorX2","calculateWebMercatorDistortion","radiusMeters","angle","dx","dy","_webMercatorXYToLngLa","circleWebMercator","updateGeometry","updateProperty","TerraDrawFreehandMode","startingClick","currentId","closingPointId","minDistance","preventPointsNearClose","currentLineGeometry","_currentLineGeometry$","_this$project","previousLat","_currentLineGeometry$2","_this$project2","closingLat","pop","newGeometry","cleanUpClosingPointId","closingPointWidth","closingPointColor","closingPointOutlineColor","closingPointOutlineWidth","TerraDrawModeBehavior","createBBoxFromPoint","halfDist","c","ClickBoundingBoxBehavior","_TerraDrawModeBehavio","PixelDistanceBehavior","measure","clickEvent","secondCoordinate","SnappingBehavior","pixelDistance","clickBoundingBox","getSnappableCoordinateFirstClick","getSnappable","getSnappableCoordinate","currentFeatureId","filter","bbox","search","closest","minDist","dist","webMercatorDestination","end","lon1","lon2","lat1","lat2","webMercatorBearing","normalizeBearing","lineSliceAlong","coords","startDist","stopDist","overshot","direction","interpolated","origCoordsLength","travelled","last","toDegrees","InsertCoordinatesBehavior","generateInsertionCoordinates","segmentLength","line","lineLength","numberOfSegments","Number","isInteger","floor","segments","limitCoordinates","generateInsertionGeodesicCoordinates","numberOfPoints","f","A","B","z","generateGreatCircleCoordinates","coordinatesIdentical","TerraDrawLineStringMode","currentCoordinate","snappingEnabled","mouseMove","insertCoordinates","lastCommitedCoordinates","snapping","insertPoint","updateGeometries","Commit","closingPointCoordinate","updatedGeometry","geometries","generateInsertCoordinates","startCoord","endCoord","strategy","segmentDistance","insertedCoordinates","createLine","startingCoord","createdId","firstUpdateToLine","updatedCoord","currentCoordinates","_this$store$create2","initialLineCoordinates","updateToLine","cursorXY","updatedLineCoordinates","_currentCoordinates","cleanupClosingPointId","getDefaultStyling","ValidatePointFeature","TerraDrawPointMode","ClosingPointsBehavior","_startEndPoints","selectedCoords","_properties","_properties2","ids","update","updatedCoordinates","isClosingPoint","opening","closing","distancePrevious","isClosing","isPreviousClosing","TerraDrawPolygonMode","closingPoints","currentPolygonCoordinates","updatePolygonGeometry","closestCoord","offset","max","_this$closingPoints$i","currentPolygonGeometry","_this$closingPoints$i2","TerraDrawRectangleMode","currentRectangleId","updateRectangle","firstCoord","TerraDrawRenderMode","Render","modeName","ValidateLineStringFeature","rhumbBearing","to","phi1","phi2","deltaLambda","deltaPsi","bear360","rhumbDestination","distanceMeters","distanceInMeters","abs","delta","lambda1","theta","DeltaPhi","DeltaPsi","q","midpointCoordinate","coordinates1","coordinates2","projectedCoordinateOne","projectedCoordinateTwo","_unproject","geodesicMidpointCoordinate","midpoint","getMidPointCoordinates","featureCoords","midPointCoords","mid","MidPointBehavior","selectionPointBehavior","_midPoints","insert","midPointId","midPoint","_this$store$getProper","getPropertiesCopy","midPointFeatureId","midPointSegment","splice","featureId","getMidPoints","getUpdated","updatedMidPointCoord","SelectionPointBehavior","_selectionPoints","geometryType","selectionPoints","getCoordinatesAsPoints","selectionPoint","selectionPointFeatureId","index","getOneUpdated","updatedCoordinate","pointInPolygon","p","p1","p2","inside","len","ring","len2","k","pixelDistanceToLine","linePointOne","linePointTwo","square","dist2","v","w","l2","t","min","distToSegmentSquared","FeatureAtPointerEventBehavior","createClickBoundingBox","hasSelection","clickedPoint","clickedPointDistance","clickedLineString","clickedLineStringDistance","clickedMidPoint","clickedMidPointDistance","clickedPolygon","nextCoord","distanceToLine","clickedFeature","DragFeatureBehavior","featuresAtMouseEvent","midPoints","draggedFeatureId","dragPosition","startDragging","stopDragging","isDragging","canDrag","drag","mouseCoord","updatedCoords","upToCoord","updatedLng","updatedLat","updatedSelectionPoints","updatedMidPoints","DragCoordinateBehavior","draggedCoordinate","getClosestCoordinate","geomCoordinates","closestCoordinate","isFirstOrLastPolygonCoord","getDraggableIndex","allowSelfIntersection","lastCoordIndex","updatedSelectionPoint","centroid","geojson","xSum","ySum","rhumbDistance","DeltaLambda","webMercatorCentroid","webMercatorCoordinates","area","centroidX","centroidY","n","_webMercatorCoordinat","_webMercatorCoordinat2","crossProduct","calculatePolygonCentroid","lineString","totalX","totalY","_lineString$i","calculateLineStringMidpoint","RotateFeatureBehavior","lastBearing","reset","rotate","angleRad","webMercatorCoords","reduce","acc","rotatedCoordinates","transformRotateWebMercator","pivot","pointCoords","finalAngle","newCoords","transformRotate","ScaleFeatureBehavior","lastDistance","originWebMercator","selectedWebMercator","factor","scaledCoordinates","transformScaleWebMercator","axis","originalDistance","newCoord","transformScale","DragCoordinateResizeBehavior","minimumScale","boundingBoxMaps","opposite","isValidDragWebMercator","distanceX","distanceY","getSelectedFeatureDataWebMercator","getFeature","getNormalisedCoordinates","boundingBox","getBBoxWebMercator","selectedCoordinate","centerWebMercatorDrag","featureData","webMercatorOrigin","webMercatorSelected","closestBBoxIndex","getIndexesWebMercator","webMercatorCursor","scaleWebMercator","centerFixedWebMercatorDrag","scaleFixedWebMercator","performWebMercatorScale","oppositeFixedWebMercatorDrag","_this$getIndexesWebMe3","oppositeBboxIndex","oppositeWebMercatorDrag","_this$getIndexesWebMe4","cursorDistanceX","cursorDistanceY","xScale","yScale","validateScale","validX","MAX_SAFE_INTEGER","validY","originX","originY","_ref3","west","south","east","north","selectedXY","closestIndex","closestDistance","resizeOption","TerraDrawSelectMode","_TerraDrawBaseSelectM","_options$allowManualD","allowManualDeselection","dragEventThrottle","dragEventCount","selected","flags","dragFeature","dragCoordinate","rotateFeature","scaleFeature","dragCoordinateResizeFeature","validations","pointerOver","dragStart","dragEnd","insertMidpoint","deselect","delete","selectFeature","select","setSelecting","deselectFeature","updateSelectedFeatures","deleteSelected","onRightClick","clickedSelectionPointProps","clickedFeatureDistance","coordinateIndex","modeFlags","deletable","shift","midpoints","fromCursor","previouslySelectedId","_this$store$getGeomet","onLeftClick","_this$featuresAtMouse","canScale","canRotate","preventDefaultKeyEvent","isRotationKeys","isScaleKeys","resizable","draggableCoordinateIndex","canSelfIntersect","selfIntersectable","rotateable","scaleable","nearbyMidPoint","nearbySelectionPoint","featureUnderPointer","selectionPointColor","selectionPointOutlineColor","selectionPointWidth","selectionPointOutlineWidth","midPointColor","midPointOutlineColor","midPointWidth","midPointOutlineWidth","selectedPolygonColor","selectedPolygonOutlineWidth","selectedPolygonOutlineColor","selectedPolygonFillOpacity","selectedLineStringColor","selectedLineStringWidth","selectedPointWidth","selectedPointColor","selectedPointOutlineColor","selectedPointOutlineWidth","TerraDrawStaticMode","Static","quickselect","arr","right","compare","s","sd","swap","tmp","calcBBox","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","child","extend","leaf","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","intersects","height","multiSelect","stack","ceil","RBush","maxEntries","_maxEntries","_minEntries","result","nodesToSearch","childBBox","_all","collides","load","_build","_splitRoot","tmpNode","_insert","item","parent","indexes","goingUp","indexOf","_condense","compareMinX","compareMinY","items","N","M","N2","N1","right2","right3","_chooseSubtree","level","minArea","minEnlargement","targetNode","enlargement","isNode","insertPath","_split","_adjustParentBBoxes","_chooseSplitAxis","splitIndex","_chooseSplitIndex","newNode","minOverlap","bbox1","bbox2","overlap","_allDistMargin","sort","leftBBox","rightBBox","margin","siblings","SpatialIndex","tree","idToNode","nodeToId","Map","setMaps","longitudes","latitudes","minLat","maxLat","seenIds","defaultIdStrategy","random","GeoJSONStore","tracked","spatialIndex","_onChange","clone","obj","JSON","parse","stringify","featureValidation","clonedData","createdAt","updatedAt","change","propertiesToUpdate","geometriesToUpdate","_this5","createdProperties","_this6","copyAll","_this7","polygonAreaSquareMeters","polygon","total","ringArea","FACTOR","PI_OVER_180","coordsLength","calculateRelativeAngle","C","bearingAB","relativeAngle","TerraDrawAngledRectangleMode","lineStart","lineEnd","firstCoordinate","D","ACloserThanC","hypotenuse","adjacent","rectangleAngle","thirdCoordinateXY","fourthCoordinateXY","thirdCoordinate","fourthCoordinate","isClockwiseWebMercator","secondCoord","thirdCoord","TerraDrawSectorMode","arcPoints","arcCoordOne","arcCoordTwo","webMercatorCenter","webMercatorArcCoordOne","webMercatorArcCoordTwo","clockwise","deltaBearing","startBearing","endBearing","normalizedStart","normalizedEnd","bearingStep","pointOnArc","TerraDrawSensorMode","currentInitialArcId","currentStartingPointId","finishedCurrentStartingPointId","finishedInitialArcId","finishedCurrentId","updateLineStringGeometry","lastCoord","webMercatorCoordOne","webMercatorCoordTwo","innerRadius","radiusCalculationPosition","cursorBearing","normalizedCursor","notInSector","getDeltaBearing","finalArc","_webMercatorXYToLngLa2","unshift","_this$store$create3","centerPointColor","centerPointWidth","centerPointOutlineColor","centerPointOutlineWidth","TerraDraw","_modes","_mode","_adapter","_enabled","_store","_eventListeners","_instanceSelectMode","adapter","duplicateModeTracker","modesMap","modes","modeMap","currentMode","modeKeys","static","ready","getChanged","changed","_getChanged","getModeStyles","_getChanged2","_getChanged3","modeId","checkEnabled","modeStyles","featuresAtLocation","ignoreSelectFeatures","inputPoint","pointCoordinates","pointXY","getSelectMode","getMode","setMode","setModeStyles","getSnapshot","removeFeatures","getFeatureId","hasFeature","addFeatures","modeToAddTo","getFeaturesAtLngLat","lngLat","getFeaturesAtPointerEvent","listeners","off","maxSize","minSize"],"mappings":"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"}