terra-draw 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"terra-draw.module.js","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/util.js","../node_modules/ol/size.js","../node_modules/ol/style/Image.js","../node_modules/color-space/rgb.js","../node_modules/color-space/xyz.js","../node_modules/color-space/luv.js","../node_modules/color-space/lchuv.js","../node_modules/color-parse/node_modules/color-name/index.js","../node_modules/color-parse/index.js","../node_modules/color-space/hsl.js","../node_modules/ol/math.js","../node_modules/ol/color.js","../node_modules/color-rgba/index.js","../node_modules/ol/has.js","../node_modules/ol/dom.js","../node_modules/ol/Disposable.js","../node_modules/ol/events/Event.js","../node_modules/ol/functions.js","../node_modules/ol/obj.js","../node_modules/ol/events/Target.js","../node_modules/ol/events/EventType.js","../node_modules/ol/events.js","../node_modules/ol/style/IconImageCache.js","../node_modules/ol/ImageState.js","../node_modules/ol/style/IconImage.js","../node_modules/ol/Image.js","../node_modules/ol/colorlike.js","../node_modules/ol/ObjectEventType.js","../node_modules/ol/Observable.js","../node_modules/ol/Object.js","../node_modules/ol/render/canvas.js","../node_modules/ol/style/RegularShape.js","../node_modules/ol/style/Circle.js","../node_modules/ol/style/Fill.js","../node_modules/ol/style/Stroke.js","../node_modules/ol/style/Style.js","../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","../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/validations/min-size.validation.ts","../src/validations/max-size.validation.ts","../src/validations/not-self-intersecting.validation.ts","../src/geometry/calculate-relative-angle.ts","../src/modes/angled-rectangle/angled-rectangle.mode.ts","../src/geometry/determine-halfplane.ts","../src/terra-draw.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.\n\t * @returns {number} The coordinate precision.\n\t * @description The coordinate precision is the number of decimal places. Note that the precision will be overriden by the precision of the TerraDraw Adapter.\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\tstyle.innerHTML = `.leaflet-${pane}-pane {z-index: ${\n\t\t\tzIndex + baseZIndex\n\t\t};}`;\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\tconst point = { x, y } as L.Point;\n\n\t\t// If is not valid point we don't want to convert\n\t\tif (\n\t\t\tpoint.x === null ||\n\t\t\tisNaN(point.x) ||\n\t\t\tpoint.y === null ||\n\t\t\tisNaN(point.y)\n\t\t) {\n\t\t\treturn null;\n\t\t}\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 { GeoJSONStoreFeatures, 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: any;\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, beneath?: 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\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLineLayer(id: string, beneath?: 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\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\n\t\treturn layer;\n\t}\n\n\tprivate _addPointLayer(id: string, beneath?: 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\t\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\t\treturn layer;\n\t}\n\n\tprivate _addLayer(\n\t\tid: string,\n\t\tfeatureType: \"Point\" | \"LineString\" | \"Polygon\",\n\t\tbeneath?: string,\n\t) {\n\t\tif (featureType === \"Point\") {\n\t\t\tthis._addPointLayer(id, beneath);\n\t\t}\n\t\tif (featureType === \"LineString\") {\n\t\t\tthis._addLineLayer(id, beneath);\n\t\t}\n\t\tif (featureType === \"Polygon\") {\n\t\t\tthis._addFillLayer(id);\n\t\t\tthis._addFillOutlineLayer(id, beneath);\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 getEmptyGeometries(): {\n\t\tpoints: GeoJSONStoreFeatures[];\n\t\tlinestrings: GeoJSONStoreFeatures[];\n\t\tpolygons: GeoJSONStoreFeatures[];\n\t} {\n\t\treturn {\n\t\t\tpoints: [],\n\t\t\tlinestrings: [],\n\t\t\tpolygons: [],\n\t\t};\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 alll 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\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 geometryFeatures = this.getEmptyGeometries();\n\n\t\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\t\tconst feature = features[i];\n\n\t\t\t\tObject.keys(styling).forEach((mode) => {\n\t\t\t\t\tconst { properties } = feature;\n\n\t\t\t\t\tif (properties.mode !== mode) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst styles = styling[mode](feature);\n\n\t\t\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\t\t\tproperties.pointColor = styles.pointColor;\n\t\t\t\t\t\tproperties.pointOutlineColor = styles.pointOutlineColor;\n\t\t\t\t\t\tproperties.pointOutlineWidth = styles.pointOutlineWidth;\n\t\t\t\t\t\tproperties.pointWidth = styles.pointWidth;\n\t\t\t\t\t\tgeometryFeatures.points.push(feature);\n\t\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\t\tproperties.lineStringColor = styles.lineStringColor;\n\t\t\t\t\t\tproperties.lineStringWidth = styles.lineStringWidth;\n\t\t\t\t\t\tgeometryFeatures.linestrings.push(feature);\n\t\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\t\tproperties.polygonFillColor = styles.polygonFillColor;\n\t\t\t\t\t\tproperties.polygonFillOpacity = styles.polygonFillOpacity;\n\t\t\t\t\t\tproperties.polygonOutlineColor = styles.polygonOutlineColor;\n\t\t\t\t\t\tproperties.polygonOutlineWidth = styles.polygonOutlineWidth;\n\t\t\t\t\t\tgeometryFeatures.polygons.push(feature);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst { points, linestrings, polygons } = geometryFeatures;\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 occured 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 deletionOccured = this.changedIds.deletion;\n\t\t\t\tconst styleUpdatedOccured = this.changedIds.styling;\n\t\t\t\tconst forceUpdate = deletionOccured || styleUpdatedOccured;\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 TerraDraw 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/util\n */\n\n/**\n * @return {never} Any return.\n */\nexport function abstract() {\n throw new Error('Unimplemented abstract method.');\n}\n\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\nlet uidCounter_ = 0;\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {string} The unique ID for the object.\n * @api\n */\nexport function getUid(obj) {\n return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));\n}\n\n/**\n * OpenLayers version.\n * @type {string}\n */\nexport const VERSION = '10.0.0';\n","/**\n * @module ol/size\n */\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The buffered size.\n */\nexport function buffer(size, num, dest) {\n if (dest === undefined) {\n dest = [0, 0];\n }\n dest[0] = size[0] + 2 * num;\n dest[1] = size[1] + 2 * num;\n return dest;\n}\n\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\nexport function hasArea(size) {\n return size[0] > 0 && size[1] > 0;\n}\n\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The scaled size.\n */\nexport function scale(size, ratio, dest) {\n if (dest === undefined) {\n dest = [0, 0];\n }\n dest[0] = (size[0] * ratio + 0.5) | 0;\n dest[1] = (size[1] * ratio + 0.5) | 0;\n return dest;\n}\n\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\nexport function toSize(size, dest) {\n if (Array.isArray(size)) {\n return size;\n }\n if (dest === undefined) {\n dest = [size, size];\n } else {\n dest[0] = size;\n dest[1] = size;\n }\n return dest;\n}\n","/**\n * @module ol/style/Image\n */\nimport {abstract} from '../util.js';\nimport {toSize} from '../size.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} opacity Opacity.\n * @property {boolean} rotateWithView If the image should get rotated with the view.\n * @property {number} rotation Rotation.\n * @property {number|import(\"../size.js\").Size} scale Scale.\n * @property {Array<number>} displacement Displacement.\n * @property {import('../style/Style.js').DeclutterMode} declutterMode Declutter mode: `declutter`, `obstacle`, `none`.\n */\n\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @abstract\n * @api\n */\nclass ImageStyle {\n /**\n * @param {Options} options Options.\n */\n constructor(options) {\n /**\n * @private\n * @type {number}\n */\n this.opacity_ = options.opacity;\n\n /**\n * @private\n * @type {boolean}\n */\n this.rotateWithView_ = options.rotateWithView;\n\n /**\n * @private\n * @type {number}\n */\n this.rotation_ = options.rotation;\n\n /**\n * @private\n * @type {number|import(\"../size.js\").Size}\n */\n this.scale_ = options.scale;\n\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.scaleArray_ = toSize(options.scale);\n\n /**\n * @private\n * @type {Array<number>}\n */\n this.displacement_ = options.displacement;\n\n /**\n * @private\n * @type {import('../style/Style.js').DeclutterMode}\n */\n this.declutterMode_ = options.declutterMode;\n }\n\n /**\n * Clones the style.\n * @return {ImageStyle} The cloned style.\n * @api\n */\n clone() {\n const scale = this.getScale();\n return new ImageStyle({\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n }\n\n /**\n * Get the symbolizer opacity.\n * @return {number} Opacity.\n * @api\n */\n getOpacity() {\n return this.opacity_;\n }\n\n /**\n * Determine whether the symbolizer rotates with the map.\n * @return {boolean} Rotate with map.\n * @api\n */\n getRotateWithView() {\n return this.rotateWithView_;\n }\n\n /**\n * Get the symoblizer rotation.\n * @return {number} Rotation.\n * @api\n */\n getRotation() {\n return this.rotation_;\n }\n\n /**\n * Get the symbolizer scale.\n * @return {number|import(\"../size.js\").Size} Scale.\n * @api\n */\n getScale() {\n return this.scale_;\n }\n\n /**\n * Get the symbolizer scale array.\n * @return {import(\"../size.js\").Size} Scale array.\n */\n getScaleArray() {\n return this.scaleArray_;\n }\n\n /**\n * Get the displacement of the shape\n * @return {Array<number>} Shape's center displacement\n * @api\n */\n getDisplacement() {\n return this.displacement_;\n }\n\n /**\n * Get the declutter mode of the shape\n * @return {import(\"./Style.js\").DeclutterMode} Shape's declutter mode\n * @api\n */\n getDeclutterMode() {\n return this.declutterMode_;\n }\n\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @abstract\n * @return {Array<number>} Anchor.\n */\n getAnchor() {\n return abstract();\n }\n\n /**\n * Get the image element for the symbolizer.\n * @abstract\n * @param {number} pixelRatio Pixel ratio.\n * @return {import('../DataTile.js').ImageLike} Image element.\n */\n getImage(pixelRatio) {\n return abstract();\n }\n\n /**\n * @abstract\n * @return {import('../DataTile.js').ImageLike} Image element.\n */\n getHitDetectionImage() {\n return abstract();\n }\n\n /**\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel ratio.\n */\n getPixelRatio(pixelRatio) {\n return 1;\n }\n\n /**\n * @abstract\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n getImageState() {\n return abstract();\n }\n\n /**\n * @abstract\n * @return {import(\"../size.js\").Size} Image size.\n */\n getImageSize() {\n return abstract();\n }\n\n /**\n * Get the origin of the symbolizer.\n * @abstract\n * @return {Array<number>} Origin.\n */\n getOrigin() {\n return abstract();\n }\n\n /**\n * Get the size of the symbolizer (in pixels).\n * @abstract\n * @return {import(\"../size.js\").Size} Size.\n */\n getSize() {\n return abstract();\n }\n\n /**\n * Set the displacement.\n *\n * @param {Array<number>} displacement Displacement.\n * @api\n */\n setDisplacement(displacement) {\n this.displacement_ = displacement;\n }\n\n /**\n * Set the opacity.\n *\n * @param {number} opacity Opacity.\n * @api\n */\n setOpacity(opacity) {\n this.opacity_ = opacity;\n }\n\n /**\n * Set whether to rotate the style with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n setRotateWithView(rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n }\n\n /**\n * Set the rotation.\n *\n * @param {number} rotation Rotation.\n * @api\n */\n setRotation(rotation) {\n this.rotation_ = rotation;\n }\n\n /**\n * Set the scale.\n *\n * @param {number|import(\"../size.js\").Size} scale Scale.\n * @api\n */\n setScale(scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale);\n }\n\n /**\n * @abstract\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n listenImageChange(listener) {\n abstract();\n }\n\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n load() {\n abstract();\n }\n\n /**\n * @abstract\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n unlistenImageChange(listener) {\n abstract();\n }\n\n /**\n * @return {Promise<void>} `false` or Promise that resolves when the style is ready to use.\n */\n ready() {\n return Promise.resolve();\n }\n}\n\nexport default ImageStyle;\n","/**\n * RGB space.\n *\n * @module color-space/rgb\n */\n\nexport default {\n\tname: 'rgb',\n\tmin: [0,0,0],\n\tmax: [255,255,255],\n\tchannel: ['red', 'green', 'blue'],\n\talias: ['RGB']\n};\n","/**\n * CIE XYZ\n *\n * @module color-space/xyz\n */\nimport rgb from './rgb.js';\n\nvar xyz = {\n\tname: 'xyz',\n\tmin: [0,0,0],\n\tchannel: ['X','Y','Z'],\n\talias: ['XYZ', 'ciexyz', 'cie1931']\n};\n\n\n/**\n * Whitepoint reference values with observer/illuminant\n *\n * http://en.wikipedia.org/wiki/Standard_illuminant\n */\nxyz.whitepoint = {\n\t//1931 2°\n\t2: {\n\t\t//incadescent\n\t\tA:[109.85, 100, 35.585],\n\t\t// B:[],\n\t\tC: [98.074, 100, 118.232],\n\t\tD50: [96.422, 100, 82.521],\n\t\tD55: [95.682, 100, 92.149],\n\t\t//daylight\n\t\tD65: [95.045592705167, 100, 108.9057750759878],\n\t\tD75: [94.972, 100, 122.638],\n\t\t//flourescent\n\t\t// F1: [],\n\t\tF2: [99.187, 100, 67.395],\n\t\t// F3: [],\n\t\t// F4: [],\n\t\t// F5: [],\n\t\t// F6:[],\n\t\tF7: [95.044, 100, 108.755],\n\t\t// F8: [],\n\t\t// F9: [],\n\t\t// F10: [],\n\t\tF11: [100.966, 100, 64.370],\n\t\t// F12: [],\n\t\tE: [100,100,100]\n\t},\n\n\t//1964 10°\n\t10: {\n\t\t//incadescent\n\t\tA:[111.144, 100, 35.200],\n\t\tC: [97.285, 100, 116.145],\n\t\tD50: [96.720, 100, 81.427],\n\t\tD55: [95.799, 100, 90.926],\n\t\t//daylight\n\t\tD65: [94.811, 100, 107.304],\n\t\tD75: [94.416, 100, 120.641],\n\t\t//flourescent\n\t\tF2: [103.280, 100, 69.026],\n\t\tF7: [95.792, 100, 107.687],\n\t\tF11: [103.866, 100, 65.627],\n\t\tE: [100,100,100]\n\t}\n};\n\n\n/**\n * Top values are the whitepoint’s top values, default are D65\n */\nxyz.max = xyz.whitepoint[2].D65;\n\n\n/**\n * Transform xyz to rgb\n *\n * @param {Array} xyz Array of xyz values\n *\n * @return {Array} RGB values\n */\nxyz.rgb = function (_xyz, white) {\n\t//FIXME: make sure we have to divide like this. Probably we have to replace matrix as well then\n\twhite = white || xyz.whitepoint[2].E;\n\n\tvar x = _xyz[0] / white[0],\n\t\ty = _xyz[1] / white[1],\n\t\tz = _xyz[2] / white[2],\n\t\tr, g, b;\n\n\t// assume sRGB\n\t// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html\n\tr = (x * 3.240969941904521) + (y * -1.537383177570093) + (z * -0.498610760293);\n\tg = (x * -0.96924363628087) + (y * 1.87596750150772) + (z * 0.041555057407175);\n\tb = (x * 0.055630079696993) + (y * -0.20397695888897) + (z * 1.056971514242878);\n\n\tr = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n\t\t: r = (r * 12.92);\n\n\tg = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n\t\t: g = (g * 12.92);\n\n\tb = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n\t\t: b = (b * 12.92);\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n}\n\n\n\n/**\n * RGB to XYZ\n *\n * @param {Array} rgb RGB channels\n *\n * @return {Array} XYZ channels\n */\nrgb.xyz = function(rgb, white) {\n\tvar r = rgb[0] / 255,\n\t\t\tg = rgb[1] / 255,\n\t\t\tb = rgb[2] / 255;\n\n\t// assume sRGB\n\tr = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n\tvar x = (r * 0.41239079926595) + (g * 0.35758433938387) + (b * 0.18048078840183);\n\tvar y = (r * 0.21263900587151) + (g * 0.71516867876775) + (b * 0.072192315360733);\n\tvar z = (r * 0.019330818715591) + (g * 0.11919477979462) + (b * 0.95053215224966);\n\n\twhite = white || xyz.whitepoint[2].E;\n\n\treturn [x * white[0], y * white[1], z * white[2]];\n};\n\n\n\nexport default xyz;\n","/**\n * CIE LUV (C'est la vie)\n *\n * @module color-space/luv\n */\n import xyz from './xyz.js';\n\nexport default {\n\tname: 'luv',\n\t//NOTE: luv has no rigidly defined limits\n\t//easyrgb fails to get proper coords\n\t//boronine states no rigid limits\n\t//colorMine refers this ones:\n\tmin: [0,-134,-140],\n\tmax: [100,224,122],\n\tchannel: ['lightness', 'u', 'v'],\n\talias: ['LUV', 'cieluv', 'cie1976'],\n\n\txyz: function(arg, i, o){\n\t\tvar _u, _v, l, u, v, x, y, z, xn, yn, zn, un, vn;\n\t\tl = arg[0], u = arg[1], v = arg[2];\n\n\t\tif (l === 0) return [0,0,0];\n\n\t\t//get constants\n\t\t//var e = 0.008856451679035631; //(6/29)^3\n\t\tvar k = 0.0011070564598794539; //(3/29)^3\n\n\t\t//get illuminant/observer\n\t\ti = i || 'D65';\n\t\to = o || 2;\n\n\t\txn = xyz.whitepoint[o][i][0];\n\t\tyn = xyz.whitepoint[o][i][1];\n\t\tzn = xyz.whitepoint[o][i][2];\n\n\t\tun = (4 * xn) / (xn + (15 * yn) + (3 * zn));\n\t\tvn = (9 * yn) / (xn + (15 * yn) + (3 * zn));\n\t\t// un = 0.19783000664283;\n\t\t// vn = 0.46831999493879;\n\n\n\t\t_u = u / (13 * l) + un || 0;\n\t\t_v = v / (13 * l) + vn || 0;\n\n\t\ty = l > 8 ? yn * Math.pow( (l + 16) / 116 , 3) : yn * l * k;\n\n\t\t//wikipedia method\n\t\tx = y * 9 * _u / (4 * _v) || 0;\n\t\tz = y * (12 - 3 * _u - 20 * _v) / (4 * _v) || 0;\n\n\t\t//boronine method\n\t\t//https://github.com/boronine/husl/blob/master/husl.coffee#L201\n\t\t// x = 0 - (9 * y * _u) / ((_u - 4) * _v - _u * _v);\n\t\t// z = (9 * y - (15 * _v * y) - (_v * x)) / (3 * _v);\n\n\t\treturn [x, y, z];\n\t}\n};\n\n// http://www.brucelindbloom.com/index.html?Equations.html\n// https://github.com/boronine/husl/blob/master/husl.coffee\n//i - illuminant\n//o - observer\nxyz.luv = function(arg, i, o) {\n\tvar _u, _v, l, u, v, x, y, z, xn, yn, zn, un, vn;\n\n\t//get constants\n\tvar e = 0.008856451679035631; //(6/29)^3\n\tvar k = 903.2962962962961; //(29/3)^3\n\n\t//get illuminant/observer coords\n\ti = i || 'D65';\n\to = o || 2;\n\n\txn = xyz.whitepoint[o][i][0];\n\tyn = xyz.whitepoint[o][i][1];\n\tzn = xyz.whitepoint[o][i][2];\n\n\tun = (4 * xn) / (xn + (15 * yn) + (3 * zn));\n\tvn = (9 * yn) / (xn + (15 * yn) + (3 * zn));\n\n\n\tx = arg[0], y = arg[1], z = arg[2];\n\n\n\t_u = (4 * x) / (x + (15 * y) + (3 * z)) || 0;\n\t_v = (9 * y) / (x + (15 * y) + (3 * z)) || 0;\n\n\tvar yr = y/yn;\n\n\tl = yr <= e ? k * yr : 116 * Math.pow(yr, 1/3) - 16;\n\n\tu = 13 * l * (_u - un);\n\tv = 13 * l * (_v - vn);\n\n\treturn [l, u, v];\n};\n","/**\n * Cylindrical CIE LUV\n *\n * @module color-space/lchuv\n */\nimport luv from './luv.js';\nimport xyz from './xyz.js';\n\n//cylindrical luv\nvar lchuv = {\n\tname: 'lchuv',\n\tchannel: ['lightness', 'chroma', 'hue'],\n\talias: ['LCHuv', 'cielchuv'],\n\tmin: [0,0,0],\n\tmax: [100,100,360],\n\n\tluv: function(luv){\n\t\tvar l = luv[0],\n\t\tc = luv[1],\n\t\th = luv[2],\n\t\tu, v, hr;\n\n\t\thr = h / 360 * 2 * Math.PI;\n\t\tu = c * Math.cos(hr);\n\t\tv = c * Math.sin(hr);\n\t\treturn [l, u, v];\n\t},\n\n\txyz: function(arg) {\n\t\treturn luv.xyz(lchuv.luv(arg));\n\t}\n};\n\nexport default lchuv;\n\nluv.lchuv = function(luv){\n\tvar l = luv[0], u = luv[1], v = luv[2];\n\n\tvar c = Math.sqrt(u*u + v*v);\n\tvar hr = Math.atan2(v,u);\n\tvar h = hr * 360 / 2 / Math.PI;\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\treturn [l,c,h]\n};\n\nxyz.lchuv = function(arg){\n return luv.lchuv(xyz.luv(arg));\n};\n","export default {\n\taliceblue: [240, 248, 255],\n\tantiquewhite: [250, 235, 215],\n\taqua: [0, 255, 255],\n\taquamarine: [127, 255, 212],\n\tazure: [240, 255, 255],\n\tbeige: [245, 245, 220],\n\tbisque: [255, 228, 196],\n\tblack: [0, 0, 0],\n\tblanchedalmond: [255, 235, 205],\n\tblue: [0, 0, 255],\n\tblueviolet: [138, 43, 226],\n\tbrown: [165, 42, 42],\n\tburlywood: [222, 184, 135],\n\tcadetblue: [95, 158, 160],\n\tchartreuse: [127, 255, 0],\n\tchocolate: [210, 105, 30],\n\tcoral: [255, 127, 80],\n\tcornflowerblue: [100, 149, 237],\n\tcornsilk: [255, 248, 220],\n\tcrimson: [220, 20, 60],\n\tcyan: [0, 255, 255],\n\tdarkblue: [0, 0, 139],\n\tdarkcyan: [0, 139, 139],\n\tdarkgoldenrod: [184, 134, 11],\n\tdarkgray: [169, 169, 169],\n\tdarkgreen: [0, 100, 0],\n\tdarkgrey: [169, 169, 169],\n\tdarkkhaki: [189, 183, 107],\n\tdarkmagenta: [139, 0, 139],\n\tdarkolivegreen: [85, 107, 47],\n\tdarkorange: [255, 140, 0],\n\tdarkorchid: [153, 50, 204],\n\tdarkred: [139, 0, 0],\n\tdarksalmon: [233, 150, 122],\n\tdarkseagreen: [143, 188, 143],\n\tdarkslateblue: [72, 61, 139],\n\tdarkslategray: [47, 79, 79],\n\tdarkslategrey: [47, 79, 79],\n\tdarkturquoise: [0, 206, 209],\n\tdarkviolet: [148, 0, 211],\n\tdeeppink: [255, 20, 147],\n\tdeepskyblue: [0, 191, 255],\n\tdimgray: [105, 105, 105],\n\tdimgrey: [105, 105, 105],\n\tdodgerblue: [30, 144, 255],\n\tfirebrick: [178, 34, 34],\n\tfloralwhite: [255, 250, 240],\n\tforestgreen: [34, 139, 34],\n\tfuchsia: [255, 0, 255],\n\tgainsboro: [220, 220, 220],\n\tghostwhite: [248, 248, 255],\n\tgold: [255, 215, 0],\n\tgoldenrod: [218, 165, 32],\n\tgray: [128, 128, 128],\n\tgreen: [0, 128, 0],\n\tgreenyellow: [173, 255, 47],\n\tgrey: [128, 128, 128],\n\thoneydew: [240, 255, 240],\n\thotpink: [255, 105, 180],\n\tindianred: [205, 92, 92],\n\tindigo: [75, 0, 130],\n\tivory: [255, 255, 240],\n\tkhaki: [240, 230, 140],\n\tlavender: [230, 230, 250],\n\tlavenderblush: [255, 240, 245],\n\tlawngreen: [124, 252, 0],\n\tlemonchiffon: [255, 250, 205],\n\tlightblue: [173, 216, 230],\n\tlightcoral: [240, 128, 128],\n\tlightcyan: [224, 255, 255],\n\tlightgoldenrodyellow: [250, 250, 210],\n\tlightgray: [211, 211, 211],\n\tlightgreen: [144, 238, 144],\n\tlightgrey: [211, 211, 211],\n\tlightpink: [255, 182, 193],\n\tlightsalmon: [255, 160, 122],\n\tlightseagreen: [32, 178, 170],\n\tlightskyblue: [135, 206, 250],\n\tlightslategray: [119, 136, 153],\n\tlightslategrey: [119, 136, 153],\n\tlightsteelblue: [176, 196, 222],\n\tlightyellow: [255, 255, 224],\n\tlime: [0, 255, 0],\n\tlimegreen: [50, 205, 50],\n\tlinen: [250, 240, 230],\n\tmagenta: [255, 0, 255],\n\tmaroon: [128, 0, 0],\n\tmediumaquamarine: [102, 205, 170],\n\tmediumblue: [0, 0, 205],\n\tmediumorchid: [186, 85, 211],\n\tmediumpurple: [147, 112, 219],\n\tmediumseagreen: [60, 179, 113],\n\tmediumslateblue: [123, 104, 238],\n\tmediumspringgreen: [0, 250, 154],\n\tmediumturquoise: [72, 209, 204],\n\tmediumvioletred: [199, 21, 133],\n\tmidnightblue: [25, 25, 112],\n\tmintcream: [245, 255, 250],\n\tmistyrose: [255, 228, 225],\n\tmoccasin: [255, 228, 181],\n\tnavajowhite: [255, 222, 173],\n\tnavy: [0, 0, 128],\n\toldlace: [253, 245, 230],\n\tolive: [128, 128, 0],\n\tolivedrab: [107, 142, 35],\n\torange: [255, 165, 0],\n\torangered: [255, 69, 0],\n\torchid: [218, 112, 214],\n\tpalegoldenrod: [238, 232, 170],\n\tpalegreen: [152, 251, 152],\n\tpaleturquoise: [175, 238, 238],\n\tpalevioletred: [219, 112, 147],\n\tpapayawhip: [255, 239, 213],\n\tpeachpuff: [255, 218, 185],\n\tperu: [205, 133, 63],\n\tpink: [255, 192, 203],\n\tplum: [221, 160, 221],\n\tpowderblue: [176, 224, 230],\n\tpurple: [128, 0, 128],\n\trebeccapurple: [102, 51, 153],\n\tred: [255, 0, 0],\n\trosybrown: [188, 143, 143],\n\troyalblue: [65, 105, 225],\n\tsaddlebrown: [139, 69, 19],\n\tsalmon: [250, 128, 114],\n\tsandybrown: [244, 164, 96],\n\tseagreen: [46, 139, 87],\n\tseashell: [255, 245, 238],\n\tsienna: [160, 82, 45],\n\tsilver: [192, 192, 192],\n\tskyblue: [135, 206, 235],\n\tslateblue: [106, 90, 205],\n\tslategray: [112, 128, 144],\n\tslategrey: [112, 128, 144],\n\tsnow: [255, 250, 250],\n\tspringgreen: [0, 255, 127],\n\tsteelblue: [70, 130, 180],\n\ttan: [210, 180, 140],\n\tteal: [0, 128, 128],\n\tthistle: [216, 191, 216],\n\ttomato: [255, 99, 71],\n\tturquoise: [64, 224, 208],\n\tviolet: [238, 130, 238],\n\twheat: [245, 222, 179],\n\twhite: [255, 255, 255],\n\twhitesmoke: [245, 245, 245],\n\tyellow: [255, 255, 0],\n\tyellowgreen: [154, 205, 50]\n}\n","/**\n * @module color-parse\n */\nimport names from 'color-name'\n\nexport default parse\n\n/**\n * Base hues\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\n */\n//FIXME: use external hue detector\nvar baseHues = {\n\tred: 0,\n\torange: 60,\n\tyellow: 120,\n\tgreen: 180,\n\tblue: 240,\n\tpurple: 300\n}\n\n/**\n * Parse color from the string passed\n *\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\n */\nfunction parse(cstr) {\n\tvar m, parts = [], alpha = 1, space\n\n\t//numeric case\n\tif (typeof cstr === 'number') {\n\t\treturn { space: 'rgb', values: [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff], alpha: 1 }\n\t}\n\tif (typeof cstr === 'number') return { space: 'rgb', values: [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff], alpha: 1 }\n\n\tcstr = String(cstr).toLowerCase();\n\n\t//keyword\n\tif (names[cstr]) {\n\t\tparts = names[cstr].slice()\n\t\tspace = 'rgb'\n\t}\n\n\t//reserved words\n\telse if (cstr === 'transparent') {\n\t\talpha = 0\n\t\tspace = 'rgb'\n\t\tparts = [0, 0, 0]\n\t}\n\n\t//hex\n\telse if (cstr[0] === '#') {\n\t\tvar base = cstr.slice(1)\n\t\tvar size = base.length\n\t\tvar isShort = size <= 4\n\t\talpha = 1\n\n\t\tif (isShort) {\n\t\t\tparts = [\n\t\t\t\tparseInt(base[0] + base[0], 16),\n\t\t\t\tparseInt(base[1] + base[1], 16),\n\t\t\t\tparseInt(base[2] + base[2], 16)\n\t\t\t]\n\t\t\tif (size === 4) {\n\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tparts = [\n\t\t\t\tparseInt(base[0] + base[1], 16),\n\t\t\t\tparseInt(base[2] + base[3], 16),\n\t\t\t\tparseInt(base[4] + base[5], 16)\n\t\t\t]\n\t\t\tif (size === 8) {\n\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\n\t\t\t}\n\t\t}\n\n\t\tif (!parts[0]) parts[0] = 0\n\t\tif (!parts[1]) parts[1] = 0\n\t\tif (!parts[2]) parts[2] = 0\n\n\t\tspace = 'rgb'\n\t}\n\n\t// color space\n\telse if (m = /^((?:rgba?|hs[lvb]a?|hwba?|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms|oklch|oklab|color))\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\n\t\tvar name = m[1]\n\t\tspace = name.replace(/a$/, '')\n\t\tvar dims = space === 'cmyk' ? 4 : space === 'gray' ? 1 : 3\n\t\tparts = m[2].trim().split(/\\s*[,\\/]\\s*|\\s+/)\n\n\t\t// color(srgb-linear x x x) -> srgb-linear(x x x)\n\t\tif (space === 'color') space = parts.shift()\n\n\t\tparts = parts.map(function (x, i) {\n\t\t\t//<percentage>\n\t\t\tif (x[x.length - 1] === '%') {\n\t\t\t\tx = parseFloat(x) / 100\n\t\t\t\t// alpha -> 0..1\n\t\t\t\tif (i === 3) return x\n\t\t\t\t// rgb -> 0..255\n\t\t\t\tif (space === 'rgb') return x * 255\n\t\t\t\t// hsl, hwb H -> 0..100\n\t\t\t\tif (space[0] === 'h') return x * 100\n\t\t\t\t// lch, lab L -> 0..100\n\t\t\t\tif (space[0] === 'l' && !i) return x * 100\n\t\t\t\t// lab A B -> -125..125\n\t\t\t\tif (space === 'lab') return x * 125\n\t\t\t\t// lch C -> 0..150, H -> 0..360\n\t\t\t\tif (space === 'lch') return i < 2 ? x * 150 : x * 360\n\t\t\t\t// oklch/oklab L -> 0..1\n\t\t\t\tif (space[0] === 'o' && !i) return x\n\t\t\t\t// oklab A B -> -0.4..0.4\n\t\t\t\tif (space === 'oklab') return x * 0.4\n\t\t\t\t// oklch C -> 0..0.4, H -> 0..360\n\t\t\t\tif (space === 'oklch') return i < 2 ? x * 0.4 : x * 360\n\t\t\t\t// color(xxx) -> 0..1\n\t\t\t\treturn x\n\t\t\t}\n\n\t\t\t//hue\n\t\t\tif (space[i] === 'h' || (i === 2 && space[space.length - 1] === 'h')) {\n\t\t\t\t//<base-hue>\n\t\t\t\tif (baseHues[x] !== undefined) return baseHues[x]\n\t\t\t\t//<deg>\n\t\t\t\tif (x.endsWith('deg')) return parseFloat(x)\n\t\t\t\t//<turn>\n\t\t\t\tif (x.endsWith('turn')) return parseFloat(x) * 360\n\t\t\t\tif (x.endsWith('grad')) return parseFloat(x) * 360 / 400\n\t\t\t\tif (x.endsWith('rad')) return parseFloat(x) * 180 / Math.PI\n\t\t\t}\n\t\t\tif (x === 'none') return 0\n\t\t\treturn parseFloat(x)\n\t\t});\n\n\t\talpha = parts.length > dims ? parts.pop() : 1\n\t}\n\n\t//named channels case\n\telse if (/[0-9](?:\\s|\\/|,)/.test(cstr)) {\n\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\n\t\t\treturn parseFloat(value)\n\t\t})\n\n\t\tspace = cstr.match(/([a-z])/ig)?.join('')?.toLowerCase() || 'rgb'\n\t}\n\n\treturn {\n\t\tspace,\n\t\tvalues: parts,\n\t\talpha\n\t}\n}\n","/**\n * @module color-space/hsl\n */\nimport rgb from './rgb.js';\n\nexport default {\n\tname: 'hsl',\n\tmin: [0,0,0],\n\tmax: [360,100,100],\n\tchannel: ['hue', 'saturation', 'lightness'],\n\talias: ['HSL'],\n\n\trgb: function(hsl) {\n\t\tvar h = hsl[0]/360, s = hsl[1]/100, l = hsl[2]/100, t1, t2, t3, rgb, val, i=0;\n\n\t\tif (s === 0) return val = l * 255, [val, val, val];\n\n\t\tt2 = l < 0.5 ? l * (1 + s) : l + s - l * s;\n\t\tt1 = 2 * l - t2;\n\n\t\trgb = [0, 0, 0];\n\t\tfor (;i<3;) {\n\t\t\tt3 = h + 1 / 3 * - (i - 1);\n\t\t\tt3 < 0 ? t3++ : t3 > 1 && t3--;\n\t\t\tval = 6 * t3 < 1 ? t1 + (t2 - t1) * 6 * t3 :\n\t\t\t2 * t3 < 1 ? t2 :\n\t\t\t3 * t3 < 2 ? t1 + (t2 - t1) * (2 / 3 - t3) * 6 :\n\t\t\tt1;\n\t\t\trgb[i++] = val * 255;\n\t\t}\n\n\t\treturn rgb;\n\t}\n};\n\n\n//extend rgb\nrgb.hsl = function(rgb) {\n\tvar r = rgb[0]/255,\n\t\t\tg = rgb[1]/255,\n\t\t\tb = rgb[2]/255,\n\t\t\tmin = Math.min(r, g, b),\n\t\t\tmax = Math.max(r, g, b),\n\t\t\tdelta = max - min,\n\t\t\th, s, l;\n\n\tif (max === min) {\n\t\th = 0;\n\t}\n\telse if (r === max) {\n\t\th = (g - b) / delta;\n\t}\n\telse if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t}\n\telse if (b === max) {\n\t\th = 4 + (r - g)/ delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tl = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t}\n\telse if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t}\n\telse {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\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","/**\n * @module ol/color\n */\nimport lchuv from 'color-space/lchuv.js';\nimport parseRgba from 'color-rgba';\nimport rgb from 'color-space/rgb.js';\nimport xyz from 'color-space/xyz.js';\nimport {clamp} from './math.js';\n\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array<number>} Color\n * @api\n */\n\n/**\n * Return the color as an rgba string.\n * @param {Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\nexport function asString(color) {\n if (typeof color === 'string') {\n return color;\n }\n return toString(color);\n}\n\n/**\n * @type {number}\n */\nconst MAX_CACHE_SIZE = 1024;\n\n/**\n * We maintain a small cache of parsed strings. Whenever the cache grows too large,\n * we delete an arbitrary set of the entries.\n *\n * @type {Object<string, Color>}\n */\nconst cache = {};\n\n/**\n * @type {number}\n */\nlet cacheSize = 0;\n\n/**\n * @param {Color} color A color that may or may not have an alpha channel.\n * @return {Color} The input color with an alpha channel. If the input color has\n * an alpha channel, the input color will be returned unchanged. Otherwise, a new\n * array will be returned with the input color and an alpha channel of 1.\n */\nexport function withAlpha(color) {\n if (color.length === 4) {\n return color;\n }\n const output = color.slice();\n output[3] = 1;\n return output;\n}\n\n/**\n * @param {Color} color RGBA color.\n * @return {Color} LCHuv color with alpha.\n */\nexport function rgbaToLcha(color) {\n const output = xyz.lchuv(rgb.xyz(color));\n output[3] = color[3];\n return output;\n}\n\n/**\n * @param {Color} color LCHuv color with alpha.\n * @return {Color} RGBA color.\n */\nexport function lchaToRgba(color) {\n const output = xyz.rgb(lchuv.xyz(color));\n output[3] = color[3];\n return output;\n}\n\n/**\n * @param {string} s String.\n * @return {Color} Color.\n */\nexport function fromString(s) {\n if (cache.hasOwnProperty(s)) {\n return cache[s];\n }\n if (cacheSize >= MAX_CACHE_SIZE) {\n let i = 0;\n for (const key in cache) {\n if ((i++ & 3) === 0) {\n delete cache[key];\n --cacheSize;\n }\n }\n }\n\n const color = parseRgba(s);\n if (color.length !== 4) {\n throw new Error('failed to parse \"' + s + '\" as color');\n }\n for (const c of color) {\n if (isNaN(c)) {\n throw new Error('failed to parse \"' + s + '\" as color');\n }\n }\n normalize(color);\n cache[s] = color;\n ++cacheSize;\n return color;\n}\n\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {Color|string} color Color.\n * @return {Color} Color.\n * @api\n */\nexport function asArray(color) {\n if (Array.isArray(color)) {\n return color;\n }\n return fromString(color);\n}\n\n/**\n * Exported for the tests.\n * @param {Color} color Color.\n * @return {Color} Clamped color.\n */\nexport function normalize(color) {\n color[0] = clamp((color[0] + 0.5) | 0, 0, 255);\n color[1] = clamp((color[1] + 0.5) | 0, 0, 255);\n color[2] = clamp((color[2] + 0.5) | 0, 0, 255);\n color[3] = clamp(color[3], 0, 1);\n return color;\n}\n\n/**\n * @param {Color} color Color.\n * @return {string} String.\n */\nexport function toString(color) {\n let r = color[0];\n if (r != (r | 0)) {\n r = (r + 0.5) | 0;\n }\n let g = color[1];\n if (g != (g | 0)) {\n g = (g + 0.5) | 0;\n }\n let b = color[2];\n if (b != (b | 0)) {\n b = (b + 0.5) | 0;\n }\n const a = color[3] === undefined ? 1 : Math.round(color[3] * 1000) / 1000;\n return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n}\n\n/**\n * @param {string} s String.\n * @return {boolean} Whether the string is actually a valid color\n */\nexport function isStringColor(s) {\n try {\n fromString(s);\n return true;\n } catch (_) {\n return false;\n }\n}\n","/** @module color-rgba */\nimport parse from 'color-parse'\nimport rgb from 'color-space/rgb.js'\nimport hsl from 'color-space/hsl.js'\n\nexport default function rgba(color) {\n\t// template literals\n\tif (Array.isArray(color) && color.raw) color = String.raw(...arguments)\n\tif (color instanceof Number) color = +color\n\n\tvar values, i, l\n\n\t//attempt to parse non-array arguments\n\tvar parsed = parse(color)\n\n\tif (!parsed.space) return []\n\n\tconst min = parsed.space[0] === 'h' ? hsl.min : rgb.min\n\tconst max = parsed.space[0] === 'h' ? hsl.max : rgb.max\n\n\tvalues = Array(3)\n\tvalues[0] = Math.min(Math.max(parsed.values[0], min[0]), max[0])\n\tvalues[1] = Math.min(Math.max(parsed.values[1], min[1]), max[1])\n\tvalues[2] = Math.min(Math.max(parsed.values[2], min[2]), max[2])\n\n\tif (parsed.space[0] === 'h') {\n\t\tvalues = hsl.rgb(values)\n\t}\n\n\tvalues.push(Math.min(Math.max(parsed.alpha, 0), 1))\n\n\treturn values\n}\n","/**\n * @module ol/has\n */\n\nconst ua =\n typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined'\n ? navigator.userAgent.toLowerCase()\n : '';\n\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\nexport const FIREFOX = ua.includes('firefox');\n\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\nexport const SAFARI = ua.includes('safari') && !ua.includes('chrom');\n\n/**\n * https://bugs.webkit.org/show_bug.cgi?id=237906\n * @type {boolean}\n */\nexport const SAFARI_BUG_237906 =\n SAFARI &&\n (ua.includes('version/15.4') ||\n /cpu (os|iphone os) 15_4 like mac os x/.test(ua));\n\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\nexport const WEBKIT = ua.includes('webkit') && !ua.includes('edge');\n\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\nexport const MAC = ua.includes('macintosh');\n\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\nexport const DEVICE_PIXEL_RATIO =\n typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n\n/**\n * The execution context is a worker with OffscreenCanvas available.\n * @const\n * @type {boolean}\n */\nexport const WORKER_OFFSCREEN_CANVAS =\n typeof WorkerGlobalScope !== 'undefined' &&\n typeof OffscreenCanvas !== 'undefined' &&\n self instanceof WorkerGlobalScope; //eslint-disable-line\n\n/**\n * Image.prototype.decode() is supported.\n * @type {boolean}\n */\nexport const IMAGE_DECODE =\n typeof Image !== 'undefined' && Image.prototype.decode;\n\n/**\n * createImageBitmap() is supported.\n * @type {boolean}\n */\nexport const CREATE_IMAGE_BITMAP = typeof createImageBitmap === 'function';\n\n/**\n * @type {boolean}\n */\nexport const PASSIVE_EVENT_LISTENERS = (function () {\n let passive = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get: function () {\n passive = true;\n },\n });\n\n // @ts-ignore Ignore invalid event type '_'\n window.addEventListener('_', null, options);\n // @ts-ignore Ignore invalid event type '_'\n window.removeEventListener('_', null, options);\n } catch (error) {\n // passive not supported\n }\n return passive;\n})();\n","import {WORKER_OFFSCREEN_CANVAS} from './has.js';\n\n/**\n * @module ol/dom\n */\n\n//FIXME Move this function to the canvas module\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number} [width] Canvas width.\n * @param {number} [height] Canvas height.\n * @param {Array<HTMLCanvasElement>} [canvasPool] Canvas pool to take existing canvas from.\n * @param {CanvasRenderingContext2DSettings} [settings] CanvasRenderingContext2DSettings\n * @return {CanvasRenderingContext2D} The context.\n */\nexport function createCanvasContext2D(width, height, canvasPool, settings) {\n /** @type {HTMLCanvasElement|OffscreenCanvas} */\n let canvas;\n if (canvasPool && canvasPool.length) {\n canvas = /** @type {HTMLCanvasElement} */ (canvasPool.shift());\n } else if (WORKER_OFFSCREEN_CANVAS) {\n canvas = new OffscreenCanvas(width || 300, height || 300);\n } else {\n canvas = document.createElement('canvas');\n }\n if (width) {\n canvas.width = width;\n }\n if (height) {\n canvas.height = height;\n }\n //FIXME Allow OffscreenCanvasRenderingContext2D as return type\n return /** @type {CanvasRenderingContext2D} */ (\n canvas.getContext('2d', settings)\n );\n}\n\n/** @type {CanvasRenderingContext2D} */\nlet sharedCanvasContext;\n\n/**\n * @return {CanvasRenderingContext2D} Shared canvas context.\n */\nexport function getSharedCanvasContext2D() {\n if (!sharedCanvasContext) {\n sharedCanvasContext = createCanvasContext2D(1, 1);\n }\n return sharedCanvasContext;\n}\n\n/**\n * Releases canvas memory to avoid exceeding memory limits in Safari.\n * See https://pqina.nl/blog/total-canvas-memory-use-exceeds-the-maximum-limit/\n * @param {CanvasRenderingContext2D} context Context.\n */\nexport function releaseCanvas(context) {\n const canvas = context.canvas;\n canvas.width = 1;\n canvas.height = 1;\n context.clearRect(0, 0, 1, 1);\n}\n\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\nexport function outerWidth(element) {\n let width = element.offsetWidth;\n const style = getComputedStyle(element);\n width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n\n return width;\n}\n\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\nexport function outerHeight(element) {\n let height = element.offsetHeight;\n const style = getComputedStyle(element);\n height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n\n return height;\n}\n\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\nexport function replaceNode(newNode, oldNode) {\n const parent = oldNode.parentNode;\n if (parent) {\n parent.replaceChild(newNode, oldNode);\n }\n}\n\n/**\n * @param {Node} node The node to remove the children from.\n */\nexport function removeChildren(node) {\n while (node.lastChild) {\n node.lastChild.remove();\n }\n}\n\n/**\n * Transform the children of a parent node so they match the\n * provided list of children. This function aims to efficiently\n * remove, add, and reorder child nodes while maintaining a simple\n * implementation (it is not guaranteed to minimize DOM operations).\n * @param {Node} node The parent node whose children need reworking.\n * @param {Array<Node>} children The desired children.\n */\nexport function replaceChildren(node, children) {\n const oldChildren = node.childNodes;\n\n for (let i = 0; true; ++i) {\n const oldChild = oldChildren[i];\n const newChild = children[i];\n\n // check if our work is done\n if (!oldChild && !newChild) {\n break;\n }\n\n // check if children match\n if (oldChild === newChild) {\n continue;\n }\n\n // check if a new child needs to be added\n if (!oldChild) {\n node.appendChild(newChild);\n continue;\n }\n\n // check if an old child needs to be removed\n if (!newChild) {\n node.removeChild(oldChild);\n --i;\n continue;\n }\n\n // reorder\n node.insertBefore(newChild, oldChild);\n }\n}\n","/**\n * @module ol/Disposable\n */\n\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nclass Disposable {\n constructor() {\n /**\n * The object has already been disposed.\n * @type {boolean}\n * @protected\n */\n this.disposed = false;\n }\n\n /**\n * Clean up.\n */\n dispose() {\n if (!this.disposed) {\n this.disposed = true;\n this.disposeInternal();\n }\n }\n\n /**\n * Extension point for disposable objects.\n * @protected\n */\n disposeInternal() {}\n}\n\nexport default Disposable;\n","/**\n * @module ol/events/Event\n */\n\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/Target~Target}.\n */\nclass BaseEvent {\n /**\n * @param {string} type Type.\n */\n constructor(type) {\n /**\n * @type {boolean}\n */\n this.propagationStopped;\n\n /**\n * @type {boolean}\n */\n this.defaultPrevented;\n\n /**\n * The event type.\n * @type {string}\n * @api\n */\n this.type = type;\n\n /**\n * The event target.\n * @type {Object}\n * @api\n */\n this.target = null;\n }\n\n /**\n * Prevent default. This means that no emulated `click`, `singleclick` or `doubleclick` events\n * will be fired.\n * @api\n */\n preventDefault() {\n this.defaultPrevented = true;\n }\n\n /**\n * Stop event propagation.\n * @api\n */\n stopPropagation() {\n this.propagationStopped = true;\n }\n}\n\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function stopPropagation(evt) {\n evt.stopPropagation();\n}\n\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function preventDefault(evt) {\n evt.preventDefault();\n}\n\nexport default BaseEvent;\n","/**\n * @module ol/functions\n */\n\nimport {equals as arrayEquals} from './array.js';\n\n/**\n * Always returns true.\n * @return {boolean} true.\n */\nexport function TRUE() {\n return true;\n}\n\n/**\n * Always returns false.\n * @return {boolean} false.\n */\nexport function FALSE() {\n return false;\n}\n\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {void} Nothing.\n */\nexport function VOID() {}\n\n/**\n * Wrap a function in another function that remembers the last return. If the\n * returned function is called twice in a row with the same arguments and the same\n * this object, it will return the value from the first call in the second call.\n *\n * @param {function(...any): ReturnType} fn The function to memoize.\n * @return {function(...any): ReturnType} The memoized function.\n * @template ReturnType\n */\nexport function memoizeOne(fn) {\n /** @type {ReturnType} */\n let lastResult;\n\n /** @type {Array<any>|undefined} */\n let lastArgs;\n\n let lastThis;\n\n /**\n * @this {*} Only need to know if `this` changed, don't care what type\n * @return {ReturnType} Memoized value\n */\n return function () {\n const nextArgs = Array.prototype.slice.call(arguments);\n if (!lastArgs || this !== lastThis || !arrayEquals(nextArgs, lastArgs)) {\n lastThis = this;\n lastArgs = nextArgs;\n lastResult = fn.apply(this, arguments);\n }\n return lastResult;\n };\n}\n\n/**\n * @template T\n * @param {function(): (T | Promise<T>)} getter A function that returns a value or a promise for a value.\n * @return {Promise<T>} A promise for the value.\n */\nexport function toPromise(getter) {\n function promiseGetter() {\n let value;\n try {\n value = getter();\n } catch (err) {\n return Promise.reject(err);\n }\n if (value instanceof Promise) {\n return value;\n }\n return Promise.resolve(value);\n }\n return promiseGetter();\n}\n","/**\n * @module ol/obj\n */\n\n/**\n * Removes all properties from an object.\n * @param {Object<string, unknown>} object The object to clear.\n */\nexport function clear(object) {\n for (const property in object) {\n delete object[property];\n }\n}\n\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\nexport function isEmpty(object) {\n let property;\n for (property in object) {\n return false;\n }\n return !property;\n}\n","/**\n * @module ol/events/Target\n */\nimport Disposable from '../Disposable.js';\nimport Event from './Event.js';\nimport {VOID} from '../functions.js';\nimport {clear} from '../obj.js';\n\n/**\n * @typedef {EventTarget|Target} EventTargetLike\n */\n\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n * `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n * There is no event target hierarchy. When a listener calls\n * `stopPropagation` or `preventDefault` on an event object, it means that no\n * more listeners after this one will be called. Same as when the listener\n * returns false.\n */\nclass Target extends Disposable {\n /**\n * @param {*} [target] Default event target for dispatched events.\n */\n constructor(target) {\n super();\n\n /**\n * @private\n * @type {*}\n */\n this.eventTarget_ = target;\n\n /**\n * @private\n * @type {Object<string, number>|null}\n */\n this.pendingRemovals_ = null;\n\n /**\n * @private\n * @type {Object<string, number>|null}\n */\n this.dispatching_ = null;\n\n /**\n * @private\n * @type {Object<string, Array<import(\"../events.js\").Listener>>|null}\n */\n this.listeners_ = null;\n }\n\n /**\n * @param {string} type Type.\n * @param {import(\"../events.js\").Listener} listener Listener.\n */\n addEventListener(type, listener) {\n if (!type || !listener) {\n return;\n }\n const listeners = this.listeners_ || (this.listeners_ = {});\n const listenersForType = listeners[type] || (listeners[type] = []);\n if (!listenersForType.includes(listener)) {\n listenersForType.push(listener);\n }\n }\n\n /**\n * Dispatches an event and calls all listeners listening for events\n * of this type. The event parameter can either be a string or an\n * Object with a `type` property.\n *\n * @param {import(\"./Event.js\").default|string} event Event object.\n * @return {boolean|undefined} `false` if anyone called preventDefault on the\n * event object or if any of the listeners returned false.\n * @api\n */\n dispatchEvent(event) {\n const isString = typeof event === 'string';\n const type = isString ? event : event.type;\n const listeners = this.listeners_ && this.listeners_[type];\n if (!listeners) {\n return;\n }\n\n const evt = isString ? new Event(event) : /** @type {Event} */ (event);\n if (!evt.target) {\n evt.target = this.eventTarget_ || this;\n }\n const dispatching = this.dispatching_ || (this.dispatching_ = {});\n const pendingRemovals =\n this.pendingRemovals_ || (this.pendingRemovals_ = {});\n if (!(type in dispatching)) {\n dispatching[type] = 0;\n pendingRemovals[type] = 0;\n }\n ++dispatching[type];\n let propagate;\n for (let i = 0, ii = listeners.length; i < ii; ++i) {\n if ('handleEvent' in listeners[i]) {\n propagate = /** @type {import(\"../events.js\").ListenerObject} */ (\n listeners[i]\n ).handleEvent(evt);\n } else {\n propagate = /** @type {import(\"../events.js\").ListenerFunction} */ (\n listeners[i]\n ).call(this, evt);\n }\n if (propagate === false || evt.propagationStopped) {\n propagate = false;\n break;\n }\n }\n if (--dispatching[type] === 0) {\n let pr = pendingRemovals[type];\n delete pendingRemovals[type];\n while (pr--) {\n this.removeEventListener(type, VOID);\n }\n delete dispatching[type];\n }\n return propagate;\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.listeners_ && clear(this.listeners_);\n }\n\n /**\n * Get the listeners for a specified event type. Listeners are returned in the\n * order that they will be called in.\n *\n * @param {string} type Type.\n * @return {Array<import(\"../events.js\").Listener>|undefined} Listeners.\n */\n getListeners(type) {\n return (this.listeners_ && this.listeners_[type]) || undefined;\n }\n\n /**\n * @param {string} [type] Type. If not provided,\n * `true` will be returned if this event target has any listeners.\n * @return {boolean} Has listeners.\n */\n hasListener(type) {\n if (!this.listeners_) {\n return false;\n }\n return type\n ? type in this.listeners_\n : Object.keys(this.listeners_).length > 0;\n }\n\n /**\n * @param {string} type Type.\n * @param {import(\"../events.js\").Listener} listener Listener.\n */\n removeEventListener(type, listener) {\n if (!this.listeners_) {\n return;\n }\n const listeners = this.listeners_[type];\n if (!listeners) {\n return;\n }\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n if (this.pendingRemovals_ && type in this.pendingRemovals_) {\n // make listener a no-op, and remove later in #dispatchEvent()\n listeners[index] = VOID;\n ++this.pendingRemovals_[type];\n } else {\n listeners.splice(index, 1);\n if (listeners.length === 0) {\n delete this.listeners_[type];\n }\n }\n }\n }\n}\n\nexport default Target;\n","/**\n * @module ol/events/EventType\n */\n\n/**\n * @enum {string}\n * @const\n */\nexport default {\n /**\n * Generic change event. Triggered when the revision counter is increased.\n * @event module:ol/events/Event~BaseEvent#change\n * @api\n */\n CHANGE: 'change',\n\n /**\n * Generic error event. Triggered when an error occurs.\n * @event module:ol/events/Event~BaseEvent#error\n * @api\n */\n ERROR: 'error',\n\n BLUR: 'blur',\n CLEAR: 'clear',\n CONTEXTMENU: 'contextmenu',\n CLICK: 'click',\n DBLCLICK: 'dblclick',\n DRAGENTER: 'dragenter',\n DRAGOVER: 'dragover',\n DROP: 'drop',\n FOCUS: 'focus',\n KEYDOWN: 'keydown',\n KEYPRESS: 'keypress',\n LOAD: 'load',\n RESIZE: 'resize',\n TOUCHMOVE: 'touchmove',\n WHEEL: 'wheel',\n};\n","/**\n * @module ol/events\n */\nimport {clear} from './obj.js';\n\n/**\n * Key to use with {@link module:ol/Observable.unByKey}.\n * @typedef {Object} EventsKey\n * @property {ListenerFunction} listener Listener.\n * @property {import(\"./events/Target.js\").EventTargetLike} target Target.\n * @property {string} type Type.\n * @api\n */\n\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function((Event|import(\"./events/Event.js\").default)): (void|boolean)} ListenerFunction\n * @api\n */\n\n/**\n * @typedef {Object} ListenerObject\n * @property {ListenerFunction} handleEvent HandleEvent listener function.\n */\n\n/**\n * @typedef {ListenerFunction|ListenerObject} Listener\n */\n\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events.unlistenByKey}.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [thisArg] Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @param {boolean} [once] If true, add the listener as one-off listener.\n * @return {EventsKey} Unique key for the listener.\n */\nexport function listen(target, type, listener, thisArg, once) {\n if (once) {\n const originalListener = listener;\n /**\n * @this {typeof target}\n */\n listener = function () {\n target.removeEventListener(type, listener);\n originalListener.apply(thisArg ?? this, arguments);\n };\n } else if (thisArg && thisArg !== target) {\n listener = listener.bind(thisArg);\n }\n const eventsKey = {\n target: target,\n type: type,\n listener: listener,\n };\n target.addEventListener(type, listener);\n return eventsKey;\n}\n\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events.unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events.listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [thisArg] Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @return {EventsKey} Key for unlistenByKey.\n */\nexport function listenOnce(target, type, listener, thisArg) {\n return listen(target, type, listener, thisArg, true);\n}\n\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events.listen} or {@link module:ol/events.listenOnce}.\n *\n * @param {EventsKey} key The key.\n */\nexport function unlistenByKey(key) {\n if (key && key.target) {\n key.target.removeEventListener(key.type, key.listener);\n clear(key);\n }\n}\n","/**\n * @module ol/style/IconImageCache\n */\nimport ImageState from '../ImageState.js';\nimport {asArray} from '../color.js';\nimport {getSharedCanvasContext2D} from '../dom.js';\n\n/**\n * @classdesc\n * Singleton class. Available through {@link module:ol/style/IconImageCache.shared}.\n */\nclass IconImageCache {\n constructor() {\n /**\n * @type {!Object<string, import(\"./IconImage.js\").default>}\n * @private\n */\n this.cache_ = {};\n\n /**\n * @type {!Object<string, CanvasPattern>}\n * @private\n */\n this.patternCache_ = {};\n\n /**\n * @type {number}\n * @private\n */\n this.cacheSize_ = 0;\n\n /**\n * @type {number}\n * @private\n */\n this.maxCacheSize_ = 32;\n }\n\n /**\n * FIXME empty description for jsdoc\n */\n clear() {\n this.cache_ = {};\n this.patternCache_ = {};\n this.cacheSize_ = 0;\n }\n\n /**\n * @return {boolean} Can expire cache.\n */\n canExpireCache() {\n return this.cacheSize_ > this.maxCacheSize_;\n }\n\n /**\n * FIXME empty description for jsdoc\n */\n expire() {\n if (this.canExpireCache()) {\n let i = 0;\n for (const key in this.cache_) {\n const iconImage = this.cache_[key];\n if ((i++ & 3) === 0 && !iconImage.hasListener()) {\n delete this.cache_[key];\n delete this.patternCache_[key];\n --this.cacheSize_;\n }\n }\n }\n }\n\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n * @return {import(\"./IconImage.js\").default} Icon image.\n */\n get(src, crossOrigin, color) {\n const key = getCacheKey(src, crossOrigin, color);\n return key in this.cache_ ? this.cache_[key] : null;\n }\n\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n * @return {CanvasPattern} Icon image.\n */\n getPattern(src, crossOrigin, color) {\n const key = getCacheKey(src, crossOrigin, color);\n return key in this.patternCache_ ? this.patternCache_[key] : null;\n }\n\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n * @param {import(\"./IconImage.js\").default|null} iconImage Icon image.\n * @param {boolean} [pattern] Also cache a `'repeat'` pattern with this `iconImage`.\n */\n set(src, crossOrigin, color, iconImage, pattern) {\n const key = getCacheKey(src, crossOrigin, color);\n const update = key in this.cache_;\n this.cache_[key] = iconImage;\n if (pattern) {\n if (iconImage.getImageState() === ImageState.IDLE) {\n iconImage.load();\n }\n if (iconImage.getImageState() === ImageState.LOADING) {\n iconImage.ready().then(() => {\n this.patternCache_[key] = getSharedCanvasContext2D().createPattern(\n iconImage.getImage(1),\n 'repeat',\n );\n });\n } else {\n this.patternCache_[key] = getSharedCanvasContext2D().createPattern(\n iconImage.getImage(1),\n 'repeat',\n );\n }\n }\n if (!update) {\n ++this.cacheSize_;\n }\n }\n\n /**\n * Set the cache size of the icon cache. Default is `32`. Change this value when\n * your map uses more than 32 different icon images and you are not caching icon\n * styles on the application level.\n * @param {number} maxCacheSize Cache max size.\n * @api\n */\n setSize(maxCacheSize) {\n this.maxCacheSize_ = maxCacheSize;\n this.expire();\n }\n}\n\n/**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n * @return {string} Cache key.\n */\nexport function getCacheKey(src, crossOrigin, color) {\n const colorString = color ? asArray(color) : 'null';\n return crossOrigin + ':' + src + ':' + colorString;\n}\n\nexport default IconImageCache;\n\n/**\n * The {@link module:ol/style/IconImageCache~IconImageCache} for\n * {@link module:ol/style/Icon~Icon} images.\n * @api\n */\nexport const shared = new IconImageCache();\n","/**\n * @module ol/ImageState\n */\n\n/**\n * @enum {number}\n */\nexport default {\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n ERROR: 3,\n EMPTY: 4,\n};\n","/**\n * @module ol/style/IconImage\n */\n\nimport EventTarget from '../events/Target.js';\nimport EventType from '../events/EventType.js';\nimport ImageState from '../ImageState.js';\nimport {asString} from '../color.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {decodeFallback} from '../Image.js';\nimport {shared as iconImageCache} from './IconImageCache.js';\n\n/**\n * @type {CanvasRenderingContext2D}\n */\nlet taintedTestContext = null;\n\nclass IconImage extends EventTarget {\n /**\n * @param {HTMLImageElement|HTMLCanvasElement|ImageBitmap|null} image Image.\n * @param {string|undefined} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../ImageState.js\").default|undefined} imageState Image state.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n */\n constructor(image, src, crossOrigin, imageState, color) {\n super();\n\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement|ImageBitmap}\n */\n this.hitDetectionImage_ = null;\n\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement|ImageBitmap|null}\n */\n this.image_ = image;\n\n /**\n * @private\n * @type {string|null}\n */\n this.crossOrigin_ = crossOrigin;\n\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n this.canvas_ = {};\n\n /**\n * @private\n * @type {import(\"../color.js\").Color|string|null}\n */\n this.color_ = color;\n\n /**\n * @private\n * @type {import(\"../ImageState.js\").default}\n */\n this.imageState_ = imageState === undefined ? ImageState.IDLE : imageState;\n\n /**\n * @private\n * @type {import(\"../size.js\").Size|null}\n */\n this.size_ =\n image && image.width && image.height ? [image.width, image.height] : null;\n\n /**\n * @private\n * @type {string|undefined}\n */\n this.src_ = src;\n\n /**\n * @private\n */\n this.tainted_;\n\n /**\n * @private\n * @type {Promise<void>|null}\n */\n this.ready_ = null;\n }\n\n /**\n * @private\n */\n initializeImage_() {\n this.image_ = new Image();\n if (this.crossOrigin_ !== null) {\n this.image_.crossOrigin = this.crossOrigin_;\n }\n }\n\n /**\n * @private\n * @return {boolean} The image canvas is tainted.\n */\n isTainted_() {\n if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) {\n if (!taintedTestContext) {\n taintedTestContext = createCanvasContext2D(1, 1, undefined, {\n willReadFrequently: true,\n });\n }\n taintedTestContext.drawImage(this.image_, 0, 0);\n try {\n taintedTestContext.getImageData(0, 0, 1, 1);\n this.tainted_ = false;\n } catch (e) {\n taintedTestContext = null;\n this.tainted_ = true;\n }\n }\n return this.tainted_ === true;\n }\n\n /**\n * @private\n */\n dispatchChangeEvent_() {\n this.dispatchEvent(EventType.CHANGE);\n }\n\n /**\n * @private\n */\n handleImageError_() {\n this.imageState_ = ImageState.ERROR;\n this.dispatchChangeEvent_();\n }\n\n /**\n * @private\n */\n handleImageLoad_() {\n this.imageState_ = ImageState.LOADED;\n this.size_ = [this.image_.width, this.image_.height];\n this.dispatchChangeEvent_();\n }\n\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement|ImageBitmap} Image or Canvas element or image bitmap.\n */\n getImage(pixelRatio) {\n if (!this.image_) {\n this.initializeImage_();\n }\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;\n }\n\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Image or Canvas element.\n */\n getPixelRatio(pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? pixelRatio : 1;\n }\n\n /**\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n getImageState() {\n return this.imageState_;\n }\n\n /**\n * @return {HTMLImageElement|HTMLCanvasElement|ImageBitmap} Image element.\n */\n getHitDetectionImage() {\n if (!this.image_) {\n this.initializeImage_();\n }\n if (!this.hitDetectionImage_) {\n if (this.isTainted_()) {\n const width = this.size_[0];\n const height = this.size_[1];\n const context = createCanvasContext2D(width, height);\n context.fillRect(0, 0, width, height);\n this.hitDetectionImage_ = context.canvas;\n } else {\n this.hitDetectionImage_ = this.image_;\n }\n }\n return this.hitDetectionImage_;\n }\n\n /**\n * Get the size of the icon (in pixels).\n * @return {import(\"../size.js\").Size} Image size.\n */\n getSize() {\n return this.size_;\n }\n\n /**\n * @return {string|undefined} Image src.\n */\n getSrc() {\n return this.src_;\n }\n\n /**\n * Load not yet loaded URI.\n */\n load() {\n if (this.imageState_ !== ImageState.IDLE) {\n return;\n }\n if (!this.image_) {\n this.initializeImage_();\n }\n\n this.imageState_ = ImageState.LOADING;\n try {\n if (this.src_ !== undefined) {\n /** @type {HTMLImageElement} */ (this.image_).src = this.src_;\n }\n } catch (e) {\n this.handleImageError_();\n }\n if (this.image_ instanceof HTMLImageElement) {\n decodeFallback(this.image_, this.src_)\n .then((image) => {\n this.image_ = image;\n this.handleImageLoad_();\n })\n .catch(this.handleImageError_.bind(this));\n }\n }\n\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @private\n */\n replaceColor_(pixelRatio) {\n if (\n !this.color_ ||\n this.canvas_[pixelRatio] ||\n this.imageState_ !== ImageState.LOADED\n ) {\n return;\n }\n\n const image = this.image_;\n const canvas = document.createElement('canvas');\n canvas.width = Math.ceil(image.width * pixelRatio);\n canvas.height = Math.ceil(image.height * pixelRatio);\n\n const ctx = canvas.getContext('2d');\n ctx.scale(pixelRatio, pixelRatio);\n ctx.drawImage(image, 0, 0);\n\n ctx.globalCompositeOperation = 'multiply';\n ctx.fillStyle = asString(this.color_);\n ctx.fillRect(0, 0, canvas.width / pixelRatio, canvas.height / pixelRatio);\n\n ctx.globalCompositeOperation = 'destination-in';\n ctx.drawImage(image, 0, 0);\n\n this.canvas_[pixelRatio] = canvas;\n }\n\n /**\n * @return {Promise<void>} Promise that resolves when the image is loaded.\n */\n ready() {\n if (!this.ready_) {\n this.ready_ = new Promise((resolve) => {\n if (\n this.imageState_ === ImageState.LOADED ||\n this.imageState_ === ImageState.ERROR\n ) {\n resolve();\n } else {\n const onChange = () => {\n if (\n this.imageState_ === ImageState.LOADED ||\n this.imageState_ === ImageState.ERROR\n ) {\n this.removeEventListener(EventType.CHANGE, onChange);\n resolve();\n }\n };\n this.addEventListener(EventType.CHANGE, onChange);\n }\n });\n }\n return this.ready_;\n }\n}\n\n/**\n * @param {HTMLImageElement|HTMLCanvasElement|ImageBitmap|null} image Image.\n * @param {string|undefined} cacheKey Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../ImageState.js\").default|undefined} imageState Image state.\n * @param {import(\"../color.js\").Color|string|null} color Color.\n * @param {boolean} [pattern] Also cache a `repeat` pattern with the icon image.\n * @return {IconImage} Icon image.\n */\nexport function get(image, cacheKey, crossOrigin, imageState, color, pattern) {\n let iconImage =\n cacheKey === undefined\n ? undefined\n : iconImageCache.get(cacheKey, crossOrigin, color);\n if (!iconImage) {\n iconImage = new IconImage(\n image,\n image && 'src' in image ? image.src || undefined : cacheKey,\n crossOrigin,\n imageState,\n color,\n );\n iconImageCache.set(cacheKey, crossOrigin, color, iconImage, pattern);\n }\n if (\n pattern &&\n iconImage &&\n !iconImageCache.getPattern(cacheKey, crossOrigin, color)\n ) {\n iconImageCache.set(cacheKey, crossOrigin, color, iconImage, pattern);\n }\n return iconImage;\n}\n\nexport default IconImage;\n","/**\n * @module ol/Image\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport ImageState from './ImageState.js';\nimport {CREATE_IMAGE_BITMAP, IMAGE_DECODE} from './has.js';\nimport {listenOnce, unlistenByKey} from './events.js';\nimport {toPromise} from './functions.js';\n\n/**\n * A function that takes an {@link module:ol/Image~ImageWrapper} for the image and a\n * `{string}` for the src as arguments. It is supposed to make it so the\n * underlying image {@link module:ol/Image~ImageWrapper#getImage} is assigned the\n * content specified by the src. If not specified, the default is\n *\n * function(image, src) {\n * image.getImage().src = src;\n * }\n *\n * Providing a custom `imageLoadFunction` can be useful to load images with\n * post requests or - in general - through XHR requests, where the src of the\n * image element would be set to a data URI when the content is loaded.\n *\n * @typedef {function(import(\"./Image.js\").default, string): void} LoadFunction\n * @api\n */\n\n/**\n * @typedef {Object} ImageObject\n * @property {import(\"./extent.js\").Extent} [extent] Extent, if different from the requested one.\n * @property {import(\"./resolution.js\").ResolutionLike} [resolution] Resolution, if different from the requested one.\n * When x and y resolution are different, use the array type (`[xResolution, yResolution]`).\n * @property {number} [pixelRatio] Pixel ratio, if different from the requested one.\n * @property {import('./DataTile.js').ImageLike} image Image.\n */\n\n/**\n * Loader function used for image sources. Receives extent, resolution and pixel ratio as arguments.\n * For images that cover any extent and resolution (static images), the loader function should not accept\n * any arguments. The function returns an {@link import(\"./DataTile.js\").ImageLike image}, an\n * {@link import(\"./Image.js\").ImageObject image object}, or a promise for the same.\n * For loaders that generate images, the promise should not resolve until the image is loaded.\n * If the returned image does not match the extent, resolution or pixel ratio passed to the loader,\n * it has to return an {@link import(\"./Image.js\").ImageObject image object} with the `image` and the\n * correct `extent`, `resolution` and `pixelRatio`.\n *\n * @typedef {function(import(\"./extent.js\").Extent, number, number, (function(HTMLImageElement, string): void)=): import(\"./DataTile.js\").ImageLike|ImageObject|Promise<import(\"./DataTile.js\").ImageLike|ImageObject>} Loader\n * @api\n */\n\n/**\n * Loader function used for image sources. Receives extent, resolution and pixel ratio as arguments.\n * The function returns a promise for an {@link import(\"./Image.js\").ImageObject image object}.\n *\n * @typedef {function(import(\"./extent.js\").Extent, number, number, (function(HTMLImageElement, string): void)=): import(\"./DataTile.js\").ImageLike|ImageObject|Promise<import(\"./DataTile.js\").ImageLike|ImageObject>} ImageObjectPromiseLoader\n */\n\nclass ImageWrapper extends EventTarget {\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number|Array<number>|undefined} resolution Resolution. If provided as array, x and y\n * resolution will be assumed.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"./ImageState.js\").default|import(\"./Image.js\").Loader} stateOrLoader State.\n */\n constructor(extent, resolution, pixelRatio, stateOrLoader) {\n super();\n\n /**\n * @protected\n * @type {import(\"./extent.js\").Extent}\n */\n this.extent = extent;\n\n /**\n * @private\n * @type {number}\n */\n this.pixelRatio_ = pixelRatio;\n\n /**\n * @protected\n * @type {number|Array<number>|undefined}\n */\n this.resolution = resolution;\n\n /**\n * @protected\n * @type {import(\"./ImageState.js\").default}\n */\n this.state =\n typeof stateOrLoader === 'function' ? ImageState.IDLE : stateOrLoader;\n\n /**\n * @private\n * @type {import('./DataTile.js').ImageLike|null}\n */\n this.image_ = null;\n\n /**\n * @protected\n * @type {import(\"./Image.js\").Loader}\n */\n this.loader = typeof stateOrLoader === 'function' ? stateOrLoader : null;\n }\n\n /**\n * @protected\n */\n changed() {\n this.dispatchEvent(EventType.CHANGE);\n }\n\n /**\n * @return {import(\"./extent.js\").Extent} Extent.\n */\n getExtent() {\n return this.extent;\n }\n\n /**\n * @return {import('./DataTile.js').ImageLike} Image.\n */\n getImage() {\n return this.image_;\n }\n\n /**\n * @return {number} PixelRatio.\n */\n getPixelRatio() {\n return this.pixelRatio_;\n }\n\n /**\n * @return {number|Array<number>} Resolution.\n */\n getResolution() {\n return /** @type {number} */ (this.resolution);\n }\n\n /**\n * @return {import(\"./ImageState.js\").default} State.\n */\n getState() {\n return this.state;\n }\n\n /**\n * Load not yet loaded URI.\n */\n load() {\n if (this.state == ImageState.IDLE) {\n if (this.loader) {\n this.state = ImageState.LOADING;\n this.changed();\n const resolution = this.getResolution();\n const requestResolution = Array.isArray(resolution)\n ? resolution[0]\n : resolution;\n toPromise(() =>\n this.loader(\n this.getExtent(),\n requestResolution,\n this.getPixelRatio(),\n ),\n )\n .then((image) => {\n if ('image' in image) {\n this.image_ = image.image;\n }\n if ('extent' in image) {\n this.extent = image.extent;\n }\n if ('resolution' in image) {\n this.resolution = image.resolution;\n }\n if ('pixelRatio' in image) {\n this.pixelRatio_ = image.pixelRatio;\n }\n if (\n image instanceof HTMLImageElement ||\n image instanceof ImageBitmap ||\n image instanceof HTMLCanvasElement ||\n image instanceof HTMLVideoElement\n ) {\n this.image_ = image;\n }\n this.state = ImageState.LOADED;\n })\n .catch((error) => {\n this.state = ImageState.ERROR;\n console.error(error); // eslint-disable-line no-console\n })\n .finally(() => this.changed());\n }\n }\n }\n\n /**\n * @param {import('./DataTile.js').ImageLike} image The image.\n */\n setImage(image) {\n this.image_ = image;\n }\n\n /**\n * @param {number|Array<number>} resolution Resolution.\n */\n setResolution(resolution) {\n this.resolution = resolution;\n }\n}\n\n/**\n * @param {import('./DataTile.js').ImageLike} image Image element.\n * @param {function():any} loadHandler Load callback function.\n * @param {function():any} errorHandler Error callback function.\n * @return {function():void} Callback to stop listening.\n */\nexport function listenImage(image, loadHandler, errorHandler) {\n const img = /** @type {HTMLImageElement} */ (image);\n let listening = true;\n let decoding = false;\n let loaded = false;\n\n const listenerKeys = [\n listenOnce(img, EventType.LOAD, function () {\n loaded = true;\n if (!decoding) {\n loadHandler();\n }\n }),\n ];\n\n if (img.src && IMAGE_DECODE) {\n decoding = true;\n img\n .decode()\n .then(function () {\n if (listening) {\n loadHandler();\n }\n })\n .catch(function (error) {\n if (listening) {\n if (loaded) {\n loadHandler();\n } else {\n errorHandler();\n }\n }\n });\n } else {\n listenerKeys.push(listenOnce(img, EventType.ERROR, errorHandler));\n }\n\n return function unlisten() {\n listening = false;\n listenerKeys.forEach(unlistenByKey);\n };\n}\n\n/**\n * Loads an image.\n * @param {HTMLImageElement} image Image, not yet loaded.\n * @param {string} [src] `src` attribute of the image. Optional, not required if already present.\n * @return {Promise<HTMLImageElement>} Promise resolving to an `HTMLImageElement`.\n * @api\n */\nexport function load(image, src) {\n return new Promise((resolve, reject) => {\n function handleLoad() {\n unlisten();\n resolve(image);\n }\n function handleError() {\n unlisten();\n reject(new Error('Image load error'));\n }\n function unlisten() {\n image.removeEventListener('load', handleLoad);\n image.removeEventListener('error', handleError);\n }\n image.addEventListener('load', handleLoad);\n image.addEventListener('error', handleError);\n if (src) {\n image.src = src;\n }\n });\n}\n\n/**\n * @param {HTMLImageElement} image Image, not yet loaded.\n * @param {string} [src] `src` attribute of the image. Optional, not required if already present.\n * @return {Promise<HTMLImageElement>} Promise resolving to an `HTMLImageElement`.\n */\nexport function decodeFallback(image, src) {\n if (src) {\n image.src = src;\n }\n return image.src && IMAGE_DECODE\n ? new Promise((resolve, reject) =>\n image\n .decode()\n .then(() => resolve(image))\n .catch((e) =>\n image.complete && image.width ? resolve(image) : reject(e),\n ),\n )\n : load(image);\n}\n\n/**\n * Loads an image and decodes it to an `ImageBitmap` if `createImageBitmap()` is supported. Returns\n * the loaded image otherwise.\n * @param {HTMLImageElement} image Image, not yet loaded.\n * @param {string} [src] `src` attribute of the image. Optional, not required if already present.\n * @return {Promise<ImageBitmap|HTMLImageElement>} Promise resolving to an `ImageBitmap` or an\n * `HTMLImageElement` if `createImageBitmap()` is not supported.\n * @api\n */\nexport function decode(image, src) {\n if (src) {\n image.src = src;\n }\n return image.src && IMAGE_DECODE && CREATE_IMAGE_BITMAP\n ? image\n .decode()\n .then(() => createImageBitmap(image))\n .catch((e) => {\n if (image.complete && image.width) {\n return image;\n }\n throw e;\n })\n : decodeFallback(image);\n}\n\nexport default ImageWrapper;\n","/**\n * @module ol/colorlike\n */\nimport ImageState from './ImageState.js';\nimport {createCanvasContext2D} from './dom.js';\nimport {get as getIconImage} from './style/IconImage.js';\nimport {shared as iconCache} from './style/IconImageCache.js';\nimport {toString} from './color.js';\n\n/**\n * @typedef {Object} PatternDescriptor\n * @property {string} src Pattern image URL\n * @property {import(\"./color.js\").Color|string} [color] Color to tint the pattern with.\n * @property {import(\"./size.js\").Size} [size] Size of the desired slice from the pattern image.\n * Use this together with `offset` when the pattern image is a sprite sheet.\n * @property {import(\"./size.js\").Size} [offset] Offset of the desired slice from the pattern image.\n * Use this together with `size` when the pattern image is a sprite sheet.\n */\n\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern),\n * or [CanvasGradient](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient). The origin for\n * patterns and gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n\n/**\n * @param {import(\"./color.js\").Color|ColorLike|PatternDescriptor|null} color Color.\n * @return {ColorLike|null} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\nexport function asColorLike(color) {\n if (!color) {\n return null;\n }\n if (Array.isArray(color)) {\n return toString(color);\n }\n if (typeof color === 'object' && 'src' in color) {\n return asCanvasPattern(color);\n }\n return color;\n}\n\n/**\n * @param {PatternDescriptor} pattern Pattern descriptor.\n * @return {CanvasPattern|null} Canvas pattern or null if the pattern referenced in the\n * PatternDescriptor was not found in the icon image cache.\n */\nfunction asCanvasPattern(pattern) {\n if (!pattern.offset || !pattern.size) {\n return iconCache.getPattern(pattern.src, 'anonymous', pattern.color);\n }\n\n const cacheKey = pattern.src + ':' + pattern.offset;\n\n const canvasPattern = iconCache.getPattern(\n cacheKey,\n undefined,\n pattern.color,\n );\n if (canvasPattern) {\n return canvasPattern;\n }\n\n const iconImage = iconCache.get(pattern.src, 'anonymous', null);\n if (iconImage.getImageState() !== ImageState.LOADED) {\n return null;\n }\n const patternCanvasContext = createCanvasContext2D(\n pattern.size[0],\n pattern.size[1],\n );\n patternCanvasContext.drawImage(\n iconImage.getImage(1),\n pattern.offset[0],\n pattern.offset[1],\n pattern.size[0],\n pattern.size[1],\n 0,\n 0,\n pattern.size[0],\n pattern.size[1],\n );\n getIconImage(\n patternCanvasContext.canvas,\n cacheKey,\n undefined,\n ImageState.LOADED,\n pattern.color,\n true,\n );\n return iconCache.getPattern(cacheKey, undefined, pattern.color);\n}\n","/**\n * @module ol/ObjectEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered when a property is changed.\n * @event module:ol/Object.ObjectEvent#propertychange\n * @api\n */\n PROPERTYCHANGE: 'propertychange',\n};\n\n/**\n * @typedef {'propertychange'} Types\n */\n","/**\n * @module ol/Observable\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport {listen, listenOnce, unlistenByKey} from './events.js';\n\n/***\n * @template {string} Type\n * @template {Event|import(\"./events/Event.js\").default} EventClass\n * @template Return\n * @typedef {(type: Type, listener: (event: EventClass) => ?) => Return} OnSignature\n */\n\n/***\n * @template {string} Type\n * @template Return\n * @typedef {(type: Type[], listener: (event: Event|import(\"./events/Event\").default) => ?) => Return extends void ? void : Return[]} CombinedOnSignature\n */\n\n/**\n * @typedef {'change'|'error'} EventTypes\n */\n\n/***\n * @template Return\n * @typedef {OnSignature<EventTypes, import(\"./events/Event.js\").default, Return> & CombinedOnSignature<EventTypes, Return>} ObservableOnSignature\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires import(\"./events/Event.js\").default\n * @api\n */\nclass Observable extends EventTarget {\n constructor() {\n super();\n\n this.on =\n /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (\n this.onInternal\n );\n\n this.once =\n /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (\n this.onceInternal\n );\n\n this.un = /** @type {ObservableOnSignature<void>} */ (this.unInternal);\n\n /**\n * @private\n * @type {number}\n */\n this.revision_ = 0;\n }\n\n /**\n * Increases the revision counter and dispatches a 'change' event.\n * @api\n */\n changed() {\n ++this.revision_;\n this.dispatchEvent(EventType.CHANGE);\n }\n\n /**\n * Get the version number for this object. Each time the object is modified,\n * its version number will be incremented.\n * @return {number} Revision.\n * @api\n */\n getRevision() {\n return this.revision_;\n }\n\n /**\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n * @protected\n */\n onInternal(type, listener) {\n if (Array.isArray(type)) {\n const len = type.length;\n const keys = new Array(len);\n for (let i = 0; i < len; ++i) {\n keys[i] = listen(this, type[i], listener);\n }\n return keys;\n }\n return listen(this, /** @type {string} */ (type), listener);\n }\n\n /**\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n * @protected\n */\n onceInternal(type, listener) {\n let key;\n if (Array.isArray(type)) {\n const len = type.length;\n key = new Array(len);\n for (let i = 0; i < len; ++i) {\n key[i] = listenOnce(this, type[i], listener);\n }\n } else {\n key = listenOnce(this, /** @type {string} */ (type), listener);\n }\n /** @type {Object} */ (listener).ol_key = key;\n return key;\n }\n\n /**\n * Unlisten for a certain type of event.\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @protected\n */\n unInternal(type, listener) {\n const key = /** @type {Object} */ (listener).ol_key;\n if (key) {\n unByKey(key);\n } else if (Array.isArray(type)) {\n for (let i = 0, ii = type.length; i < ii; ++i) {\n this.removeEventListener(type[i], listener);\n }\n } else {\n this.removeEventListener(type, listener);\n }\n }\n}\n\n/**\n * Listen for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\nObservable.prototype.on;\n\n/**\n * Listen once for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\nObservable.prototype.once;\n\n/**\n * Unlisten for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @api\n */\nObservable.prototype.un;\n\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} key The key returned by `on()`\n * or `once()` (or an array of keys).\n * @api\n */\nexport function unByKey(key) {\n if (Array.isArray(key)) {\n for (let i = 0, ii = key.length; i < ii; ++i) {\n unlistenByKey(key[i]);\n }\n } else {\n unlistenByKey(/** @type {import(\"./events.js\").EventsKey} */ (key));\n }\n}\n\nexport default Observable;\n","/**\n * @module ol/Object\n */\nimport Event from './events/Event.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport Observable from './Observable.js';\nimport {getUid} from './util.js';\nimport {isEmpty} from './obj.js';\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n */\nexport class ObjectEvent extends Event {\n /**\n * @param {string} type The event type.\n * @param {string} key The property name.\n * @param {*} oldValue The old value for `key`.\n */\n constructor(type, key, oldValue) {\n super(type);\n\n /**\n * The name of the property whose value is changing.\n * @type {string}\n * @api\n */\n this.key = key;\n\n /**\n * The old value. To get the new value use `e.target.get(e.key)` where\n * `e` is the event object.\n * @type {*}\n * @api\n */\n this.oldValue = oldValue;\n }\n}\n\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./ObjectEventType\").Types, ObjectEvent, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|import(\"./ObjectEventType\").Types, Return>} ObjectOnSignature\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable~Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * 'Observable Properties', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get('target')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on('change:center', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.\n * You can listen for changes on that property value with\n * `object.on('change:prop', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title='New title'` and with `map.set('title', 'Another title')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset('foo').\n *\n * @fires ObjectEvent\n * @api\n */\nclass BaseObject extends Observable {\n /**\n * @param {Object<string, *>} [values] An object with key-value pairs.\n */\n constructor(values) {\n super();\n\n /***\n * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n */\n this.on;\n\n /***\n * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n */\n this.once;\n\n /***\n * @type {ObjectOnSignature<void>}\n */\n this.un;\n\n // Call {@link module:ol/util.getUid} to ensure that the order of objects' ids is\n // the same as the order in which they were created. This also helps to\n // ensure that object properties are always added in the same order, which\n // helps many JavaScript engines generate faster code.\n getUid(this);\n\n /**\n * @private\n * @type {Object<string, *>|null}\n */\n this.values_ = null;\n\n if (values !== undefined) {\n this.setProperties(values);\n }\n }\n\n /**\n * Gets a value.\n * @param {string} key Key name.\n * @return {*} Value.\n * @api\n */\n get(key) {\n let value;\n if (this.values_ && this.values_.hasOwnProperty(key)) {\n value = this.values_[key];\n }\n return value;\n }\n\n /**\n * Get a list of object property names.\n * @return {Array<string>} List of property names.\n * @api\n */\n getKeys() {\n return (this.values_ && Object.keys(this.values_)) || [];\n }\n\n /**\n * Get an object of all property names and values.\n * @return {Object<string, *>} Object.\n * @api\n */\n getProperties() {\n return (this.values_ && Object.assign({}, this.values_)) || {};\n }\n\n /**\n * Get an object of all property names and values.\n * @return {Object<string, *>?} Object.\n */\n getPropertiesInternal() {\n return this.values_;\n }\n\n /**\n * @return {boolean} The object has properties.\n */\n hasProperties() {\n return !!this.values_;\n }\n\n /**\n * @param {string} key Key name.\n * @param {*} oldValue Old value.\n */\n notify(key, oldValue) {\n let eventType;\n eventType = `change:${key}`;\n if (this.hasListener(eventType)) {\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n }\n eventType = ObjectEventType.PROPERTYCHANGE;\n if (this.hasListener(eventType)) {\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n }\n }\n\n /**\n * @param {string} key Key name.\n * @param {import(\"./events.js\").Listener} listener Listener.\n */\n addChangeListener(key, listener) {\n this.addEventListener(`change:${key}`, listener);\n }\n\n /**\n * @param {string} key Key name.\n * @param {import(\"./events.js\").Listener} listener Listener.\n */\n removeChangeListener(key, listener) {\n this.removeEventListener(`change:${key}`, listener);\n }\n\n /**\n * Sets a value.\n * @param {string} key Key name.\n * @param {*} value Value.\n * @param {boolean} [silent] Update without triggering an event.\n * @api\n */\n set(key, value, silent) {\n const values = this.values_ || (this.values_ = {});\n if (silent) {\n values[key] = value;\n } else {\n const oldValue = values[key];\n values[key] = value;\n if (oldValue !== value) {\n this.notify(key, oldValue);\n }\n }\n }\n\n /**\n * Sets a collection of key-value pairs. Note that this changes any existing\n * properties and adds new ones (it does not remove any existing properties).\n * @param {Object<string, *>} values Values.\n * @param {boolean} [silent] Update without triggering an event.\n * @api\n */\n setProperties(values, silent) {\n for (const key in values) {\n this.set(key, values[key], silent);\n }\n }\n\n /**\n * Apply any properties from another object without triggering events.\n * @param {BaseObject} source The source object.\n * @protected\n */\n applyProperties(source) {\n if (!source.values_) {\n return;\n }\n Object.assign(this.values_ || (this.values_ = {}), source.values_);\n }\n\n /**\n * Unsets a property.\n * @param {string} key Key name.\n * @param {boolean} [silent] Unset without triggering an event.\n * @api\n */\n unset(key, silent) {\n if (this.values_ && key in this.values_) {\n const oldValue = this.values_[key];\n delete this.values_[key];\n if (isEmpty(this.values_)) {\n this.values_ = null;\n }\n if (!silent) {\n this.notify(key, oldValue);\n }\n }\n }\n}\n\nexport default BaseObject;\n","/**\n * @module ol/render/canvas\n */\nimport BaseObject from '../Object.js';\nimport {WORKER_OFFSCREEN_CANVAS} from '../has.js';\nimport {clear} from '../obj.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {getFontParameters} from '../css.js';\n\n/**\n * @typedef {'Circle' | 'Image' | 'LineString' | 'Polygon' | 'Text' | 'Default'} BuilderType\n */\n\n/**\n * @typedef {Object} FillState\n * @property {import(\"../colorlike.js\").ColorLike} fillStyle FillStyle.\n */\n\n/**\n * @typedef Label\n * @property {number} width Width.\n * @property {number} height Height.\n * @property {Array<string|number>} contextInstructions ContextInstructions.\n */\n\n/**\n * @typedef {Object} FillStrokeState\n * @property {import(\"../colorlike.js\").ColorLike} [currentFillStyle] Current FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [currentStrokeStyle] Current StrokeStyle.\n * @property {CanvasLineCap} [currentLineCap] Current LineCap.\n * @property {Array<number>} currentLineDash Current LineDash.\n * @property {number} [currentLineDashOffset] Current LineDashOffset.\n * @property {CanvasLineJoin} [currentLineJoin] Current LineJoin.\n * @property {number} [currentLineWidth] Current LineWidth.\n * @property {number} [currentMiterLimit] Current MiterLimit.\n * @property {number} [lastStroke] Last stroke.\n * @property {import(\"../colorlike.js\").ColorLike} [fillStyle] FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [strokeStyle] StrokeStyle.\n * @property {CanvasLineCap} [lineCap] LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} [lineDashOffset] LineDashOffset.\n * @property {CanvasLineJoin} [lineJoin] LineJoin.\n * @property {number} [lineWidth] LineWidth.\n * @property {number} [miterLimit] MiterLimit.\n * @property {number} [fillPatternScale] Fill pattern scale.\n */\n\n/**\n * @typedef {Object} StrokeState\n * @property {CanvasLineCap} lineCap LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} lineWidth LineWidth.\n * @property {number} miterLimit MiterLimit.\n * @property {import(\"../colorlike.js\").ColorLike} strokeStyle StrokeStyle.\n */\n\n/**\n * @typedef {Object} TextState\n * @property {string} font Font.\n * @property {CanvasTextAlign} [textAlign] TextAlign.\n * @property {number} [repeat] Repeat.\n * @property {import(\"../style/Text.js\").TextJustify} [justify] Justify.\n * @property {CanvasTextBaseline} textBaseline TextBaseline.\n * @property {import(\"../style/Text.js\").TextPlacement} [placement] Placement.\n * @property {number} [maxAngle] MaxAngle.\n * @property {boolean} [overflow] Overflow.\n * @property {import(\"../style/Fill.js\").default} [backgroundFill] BackgroundFill.\n * @property {import(\"../style/Stroke.js\").default} [backgroundStroke] BackgroundStroke.\n * @property {import(\"../size.js\").Size} [scale] Scale.\n * @property {Array<number>} [padding] Padding.\n */\n\n/**\n * @typedef {Object} SerializableInstructions\n * @property {Array<*>} instructions The rendering instructions.\n * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.\n * @property {Array<number>} coordinates The array of all coordinates.\n * @property {!Object<string, TextState>} [textStates] The text states (decluttering).\n * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).\n * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).\n */\n\n/**\n * @typedef {Object<number, import(\"./canvas/Executor.js\").ReplayImageOrLabelArgs>} DeclutterImageWithText\n */\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultFont = '10px sans-serif';\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultFillStyle = '#000';\n\n/**\n * @const\n * @type {CanvasLineCap}\n */\nexport const defaultLineCap = 'round';\n\n/**\n * @const\n * @type {Array<number>}\n */\nexport const defaultLineDash = [];\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineDashOffset = 0;\n\n/**\n * @const\n * @type {CanvasLineJoin}\n */\nexport const defaultLineJoin = 'round';\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultMiterLimit = 10;\n\n/**\n * @const\n * @type {import(\"../colorlike.js\").ColorLike}\n */\nexport const defaultStrokeStyle = '#000';\n\n/**\n * @const\n * @type {CanvasTextAlign}\n */\nexport const defaultTextAlign = 'center';\n\n/**\n * @const\n * @type {CanvasTextBaseline}\n */\nexport const defaultTextBaseline = 'middle';\n\n/**\n * @const\n * @type {Array<number>}\n */\nexport const defaultPadding = [0, 0, 0, 0];\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineWidth = 1;\n\n/**\n * @type {BaseObject}\n */\nexport const checkedFonts = new BaseObject();\n\n/**\n * @type {CanvasRenderingContext2D}\n */\nlet measureContext = null;\n\n/**\n * @type {string}\n */\nlet measureFont;\n\n/**\n * @type {!Object<string, number>}\n */\nexport const textHeights = {};\n\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\nexport const registerFont = (function () {\n const retries = 100;\n const size = '32px ';\n const referenceFonts = ['monospace', 'serif'];\n const len = referenceFonts.length;\n const text = 'wmytzilWMYTZIL@#/&?$%10\\uF013';\n let interval, referenceWidth;\n\n /**\n * @param {string} fontStyle Css font-style\n * @param {string} fontWeight Css font-weight\n * @param {*} fontFamily Css font-family\n * @return {boolean} Font with style and weight is available\n */\n function isAvailable(fontStyle, fontWeight, fontFamily) {\n let available = true;\n for (let i = 0; i < len; ++i) {\n const referenceFont = referenceFonts[i];\n referenceWidth = measureTextWidth(\n fontStyle + ' ' + fontWeight + ' ' + size + referenceFont,\n text,\n );\n if (fontFamily != referenceFont) {\n const width = measureTextWidth(\n fontStyle +\n ' ' +\n fontWeight +\n ' ' +\n size +\n fontFamily +\n ',' +\n referenceFont,\n text,\n );\n // If width and referenceWidth are the same, then the fallback was used\n // instead of the font we wanted, so the font is not available.\n available = available && width != referenceWidth;\n }\n }\n if (available) {\n return true;\n }\n return false;\n }\n\n function check() {\n let done = true;\n const fonts = checkedFonts.getKeys();\n for (let i = 0, ii = fonts.length; i < ii; ++i) {\n const font = fonts[i];\n if (checkedFonts.get(font) < retries) {\n const [style, weight, family] = font.split('\\n');\n if (isAvailable(style, weight, family)) {\n clear(textHeights);\n // Make sure that loaded fonts are picked up by Safari\n measureContext = null;\n measureFont = undefined;\n checkedFonts.set(font, retries);\n } else {\n checkedFonts.set(font, checkedFonts.get(font) + 1, true);\n done = false;\n }\n }\n }\n if (done) {\n clearInterval(interval);\n interval = undefined;\n }\n }\n\n return function (fontSpec) {\n const font = getFontParameters(fontSpec);\n if (!font) {\n return;\n }\n const families = font.families;\n for (let i = 0, ii = families.length; i < ii; ++i) {\n const family = families[i];\n const key = font.style + '\\n' + font.weight + '\\n' + family;\n if (checkedFonts.get(key) === undefined) {\n checkedFonts.set(key, retries, true);\n if (!isAvailable(font.style, font.weight, family)) {\n checkedFonts.set(key, 0, true);\n if (interval === undefined) {\n interval = setInterval(check, 32);\n }\n }\n }\n }\n };\n})();\n\n/**\n * @param {string} font Font to use for measuring.\n * @return {import(\"../size.js\").Size} Measurement.\n */\nexport const measureTextHeight = (function () {\n /**\n * @type {HTMLDivElement}\n */\n let measureElement;\n return function (fontSpec) {\n let height = textHeights[fontSpec];\n if (height == undefined) {\n if (WORKER_OFFSCREEN_CANVAS) {\n const font = getFontParameters(fontSpec);\n const metrics = measureText(fontSpec, 'Žg');\n const lineHeight = isNaN(Number(font.lineHeight))\n ? 1.2\n : Number(font.lineHeight);\n height =\n lineHeight *\n (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);\n } else {\n if (!measureElement) {\n measureElement = document.createElement('div');\n measureElement.innerHTML = 'M';\n measureElement.style.minHeight = '0';\n measureElement.style.maxHeight = 'none';\n measureElement.style.height = 'auto';\n measureElement.style.padding = '0';\n measureElement.style.border = 'none';\n measureElement.style.position = 'absolute';\n measureElement.style.display = 'block';\n measureElement.style.left = '-99999px';\n }\n measureElement.style.font = fontSpec;\n document.body.appendChild(measureElement);\n height = measureElement.offsetHeight;\n document.body.removeChild(measureElement);\n }\n textHeights[fontSpec] = height;\n }\n return height;\n };\n})();\n\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {TextMetrics} Text metrics.\n */\nfunction measureText(font, text) {\n if (!measureContext) {\n measureContext = createCanvasContext2D(1, 1);\n }\n if (font != measureFont) {\n measureContext.font = font;\n measureFont = measureContext.font;\n }\n return measureContext.measureText(text);\n}\n\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\nexport function measureTextWidth(font, text) {\n return measureText(font, text).width;\n}\n\n/**\n * Measure text width using a cache.\n * @param {string} font The font.\n * @param {string} text The text to measure.\n * @param {Object<string, number>} cache A lookup of cached widths by text.\n * @return {number} The text width.\n */\nexport function measureAndCacheTextWidth(font, text, cache) {\n if (text in cache) {\n return cache[text];\n }\n const width = text\n .split('\\n')\n .reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0);\n cache[text] = width;\n return width;\n}\n\n/**\n * @param {TextState} baseStyle Base style.\n * @param {Array<string>} chunks Text chunks to measure.\n * @return {{width: number, height: number, widths: Array<number>, heights: Array<number>, lineWidths: Array<number>}}} Text metrics.\n */\nexport function getTextDimensions(baseStyle, chunks) {\n const widths = [];\n const heights = [];\n const lineWidths = [];\n let width = 0;\n let lineWidth = 0;\n let height = 0;\n let lineHeight = 0;\n for (let i = 0, ii = chunks.length; i <= ii; i += 2) {\n const text = chunks[i];\n if (text === '\\n' || i === ii) {\n width = Math.max(width, lineWidth);\n lineWidths.push(lineWidth);\n lineWidth = 0;\n height += lineHeight;\n lineHeight = 0;\n continue;\n }\n const font = chunks[i + 1] || baseStyle.font;\n const currentWidth = measureTextWidth(font, text);\n widths.push(currentWidth);\n lineWidth += currentWidth;\n const currentHeight = measureTextHeight(font);\n heights.push(currentHeight);\n lineHeight = Math.max(lineHeight, currentHeight);\n }\n return {width, height, widths, heights, lineWidths};\n}\n\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\nexport function rotateAtOffset(context, rotation, offsetX, offsetY) {\n if (rotation !== 0) {\n context.translate(offsetX, offsetY);\n context.rotate(rotation);\n context.translate(-offsetX, -offsetY);\n }\n}\n\n/**\n * @param {CanvasRenderingContext2D|import(\"../render/canvas/ZIndexContext.js\").ZIndexContextProxy} context Context.\n * @param {import(\"../transform.js\").Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../size.js\").Size} scale Scale.\n */\nexport function drawImageOrLabel(\n context,\n transform,\n opacity,\n labelOrImage,\n originX,\n originY,\n w,\n h,\n x,\n y,\n scale,\n) {\n context.save();\n\n if (opacity !== 1) {\n if (context.globalAlpha === undefined) {\n context.globalAlpha = (context) => (context.globalAlpha *= opacity);\n } else {\n context.globalAlpha *= opacity;\n }\n }\n if (transform) {\n context.transform.apply(context, transform);\n }\n\n if (/** @type {*} */ (labelOrImage).contextInstructions) {\n // label\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n executeLabelInstructions(/** @type {Label} */ (labelOrImage), context);\n } else if (scale[0] < 0 || scale[1] < 0) {\n // flipped image\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (\n labelOrImage\n ),\n originX,\n originY,\n w,\n h,\n 0,\n 0,\n w,\n h,\n );\n } else {\n // if image not flipped translate and scale can be avoided\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (\n labelOrImage\n ),\n originX,\n originY,\n w,\n h,\n x,\n y,\n w * scale[0],\n h * scale[1],\n );\n }\n\n context.restore();\n}\n\n/**\n * @param {Label} label Label.\n * @param {CanvasRenderingContext2D} context Context.\n */\nfunction executeLabelInstructions(label, context) {\n const contextInstructions = label.contextInstructions;\n for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {\n if (Array.isArray(contextInstructions[i + 1])) {\n context[contextInstructions[i]].apply(\n context,\n contextInstructions[i + 1],\n );\n } else {\n context[contextInstructions[i]] = contextInstructions[i + 1];\n }\n }\n}\n","/**\n * @module ol/style/RegularShape\n */\n\nimport ImageState from '../ImageState.js';\nimport ImageStyle from './Image.js';\nimport {asArray} from '../color.js';\nimport {asColorLike} from '../colorlike.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {\n defaultFillStyle,\n defaultLineCap,\n defaultLineJoin,\n defaultLineWidth,\n defaultMiterLimit,\n defaultStrokeStyle,\n} from '../render/canvas.js';\n\n/**\n * Specify radius for regular polygons, or both radius and radius2 for stars.\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} radius Radius of a regular polygon.\n * @property {number} [radius2] Second radius to make a star instead of a regular polygon.\n * @property {number} [angle=0] Shape's angle in radians. A value of 0 will have one of the shape's points facing up.\n * @property {Array<number>} [displacement=[0, 0]] Displacement of the shape in pixels.\n * Positive values will shift the shape right and up.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. Unless two dimensional scaling is required a better\n * result may be obtained with appropriate settings for `radius` and `radius2`.\n * @property {import('./Style.js').DeclutterMode} [declutterMode] Declutter mode.\n */\n\n/**\n * @typedef {Object} RenderOptions\n * @property {import(\"../colorlike.js\").ColorLike|undefined} strokeStyle StrokeStyle.\n * @property {number} strokeWidth StrokeWidth.\n * @property {number} size Size.\n * @property {CanvasLineCap} lineCap LineCap.\n * @property {Array<number>|null} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} miterLimit MiterLimit.\n */\n\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when both `radius` and\n * `radius2` are provided.\n * @api\n */\nclass RegularShape extends ImageStyle {\n /**\n * @param {Options} options Options.\n */\n constructor(options) {\n super({\n opacity: 1,\n rotateWithView:\n options.rotateWithView !== undefined ? options.rotateWithView : false,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n scale: options.scale !== undefined ? options.scale : 1,\n displacement:\n options.displacement !== undefined ? options.displacement : [0, 0],\n declutterMode: options.declutterMode,\n });\n\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n this.canvases_;\n\n /**\n * @private\n * @type {HTMLCanvasElement|null}\n */\n this.hitDetectionCanvas_ = null;\n\n /**\n * @private\n * @type {import(\"./Fill.js\").default|null}\n */\n this.fill_ = options.fill !== undefined ? options.fill : null;\n\n /**\n * @private\n * @type {Array<number>}\n */\n this.origin_ = [0, 0];\n\n /**\n * @private\n * @type {number}\n */\n this.points_ = options.points;\n\n /**\n * @protected\n * @type {number}\n */\n this.radius = options.radius;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.radius2_ = options.radius2;\n\n /**\n * @private\n * @type {number}\n */\n this.angle_ = options.angle !== undefined ? options.angle : 0;\n\n /**\n * @private\n * @type {import(\"./Stroke.js\").default|null}\n */\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.size_;\n\n /**\n * @private\n * @type {RenderOptions}\n */\n this.renderOptions_;\n\n /**\n * @private\n */\n this.imageState_ =\n this.fill_ && this.fill_.loading()\n ? ImageState.LOADING\n : ImageState.LOADED;\n if (this.imageState_ === ImageState.LOADING) {\n this.ready().then(() => (this.imageState_ = ImageState.LOADED));\n }\n this.render();\n }\n\n /**\n * Clones the style.\n * @return {RegularShape} The cloned style.\n * @api\n * @override\n */\n clone() {\n const scale = this.getScale();\n const style = new RegularShape({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n points: this.getPoints(),\n radius: this.getRadius(),\n radius2: this.getRadius2(),\n angle: this.getAngle(),\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n style.setOpacity(this.getOpacity());\n return style;\n }\n\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n * @override\n */\n getAnchor() {\n const size = this.size_;\n const displacement = this.getDisplacement();\n const scale = this.getScaleArray();\n // anchor is scaled by renderer but displacement should not be scaled\n // so divide by scale here\n return [\n size[0] / 2 - displacement[0] / scale[0],\n size[1] / 2 + displacement[1] / scale[1],\n ];\n }\n\n /**\n * Get the angle used in generating the shape.\n * @return {number} Shape's rotation in radians.\n * @api\n */\n getAngle() {\n return this.angle_;\n }\n\n /**\n * Get the fill style for the shape.\n * @return {import(\"./Fill.js\").default|null} Fill style.\n * @api\n */\n getFill() {\n return this.fill_;\n }\n\n /**\n * Set the fill style.\n * @param {import(\"./Fill.js\").default|null} fill Fill style.\n * @api\n */\n setFill(fill) {\n this.fill_ = fill;\n this.render();\n }\n\n /**\n * @return {HTMLCanvasElement} Image element.\n * @override\n */\n getHitDetectionImage() {\n if (!this.hitDetectionCanvas_) {\n this.hitDetectionCanvas_ = this.createHitDetectionCanvas_(\n this.renderOptions_,\n );\n }\n return this.hitDetectionCanvas_;\n }\n\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement} Image or Canvas element.\n * @api\n * @override\n */\n getImage(pixelRatio) {\n let image = this.canvases_[pixelRatio];\n if (!image) {\n const renderOptions = this.renderOptions_;\n const context = createCanvasContext2D(\n renderOptions.size * pixelRatio,\n renderOptions.size * pixelRatio,\n );\n this.draw_(renderOptions, context, pixelRatio);\n\n image = context.canvas;\n this.canvases_[pixelRatio] = image;\n }\n return image;\n }\n\n /**\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel ratio.\n * @override\n */\n getPixelRatio(pixelRatio) {\n return pixelRatio;\n }\n\n /**\n * @return {import(\"../size.js\").Size} Image size.\n * @override\n */\n getImageSize() {\n return this.size_;\n }\n\n /**\n * @return {import(\"../ImageState.js\").default} Image state.\n * @override\n */\n getImageState() {\n return this.imageState_;\n }\n\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n * @override\n */\n getOrigin() {\n return this.origin_;\n }\n\n /**\n * Get the number of points for generating the shape.\n * @return {number} Number of points for stars and regular polygons.\n * @api\n */\n getPoints() {\n return this.points_;\n }\n\n /**\n * Get the (primary) radius for the shape.\n * @return {number} Radius.\n * @api\n */\n getRadius() {\n return this.radius;\n }\n\n /**\n * Get the secondary radius for the shape.\n * @return {number|undefined} Radius2.\n * @api\n */\n getRadius2() {\n return this.radius2_;\n }\n\n /**\n * Get the size of the symbolizer (in pixels).\n * @return {import(\"../size.js\").Size} Size.\n * @api\n * @override\n */\n getSize() {\n return this.size_;\n }\n\n /**\n * Get the stroke style for the shape.\n * @return {import(\"./Stroke.js\").default|null} Stroke style.\n * @api\n */\n getStroke() {\n return this.stroke_;\n }\n\n /**\n * Set the stroke style.\n * @param {import(\"./Stroke.js\").default|null} stroke Stroke style.\n * @api\n */\n setStroke(stroke) {\n this.stroke_ = stroke;\n this.render();\n }\n\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n * @override\n */\n listenImageChange(listener) {}\n\n /**\n * Load not yet loaded URI.\n * @override\n */\n load() {}\n\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n * @override\n */\n unlistenImageChange(listener) {}\n\n /**\n * Calculate additional canvas size needed for the miter.\n * @param {string} lineJoin Line join\n * @param {number} strokeWidth Stroke width\n * @param {number} miterLimit Miter limit\n * @return {number} Additional canvas size needed\n * @private\n */\n calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit) {\n if (\n strokeWidth === 0 ||\n this.points_ === Infinity ||\n (lineJoin !== 'bevel' && lineJoin !== 'miter')\n ) {\n return strokeWidth;\n }\n // m | ^\n // i | |\\ .\n // t >| #\\\n // e | |\\ \\ .\n // r \\s\\\n // | \\t\\ . .\n // \\r\\ . .\n // | \\o\\ . . . . .\n // e \\k\\ . . . .\n // | \\e\\ . . . . .\n // d \\ \\ . . . .\n // | _ _a_ _\\# . . .\n // r1 / ` . .\n // | . .\n // b / . .\n // | . .\n // / r2 . .\n // | . .\n // / . .\n // |α . .\n // / . .\n // ° center\n let r1 = this.radius;\n let r2 = this.radius2_ === undefined ? r1 : this.radius2_;\n if (r1 < r2) {\n const tmp = r1;\n r1 = r2;\n r2 = tmp;\n }\n const points =\n this.radius2_ === undefined ? this.points_ : this.points_ * 2;\n const alpha = (2 * Math.PI) / points;\n const a = r2 * Math.sin(alpha);\n const b = Math.sqrt(r2 * r2 - a * a);\n const d = r1 - b;\n const e = Math.sqrt(a * a + d * d);\n const miterRatio = e / a;\n if (lineJoin === 'miter' && miterRatio <= miterLimit) {\n return miterRatio * strokeWidth;\n }\n // Calculate the distance from center to the stroke corner where\n // it was cut short because of the miter limit.\n // l\n // ----+---- <= distance from center to here is maxr\n // /####|k ##\\\n // /#####^#####\\\n // /#### /+\\# s #\\\n // /### h/+++\\# t #\\\n // /### t/+++++\\# r #\\\n // /### a/+++++++\\# o #\\\n // /### p/++ fill +\\# k #\\\n ///#### /+++++^+++++\\# e #\\\n //#####/+++++/+\\+++++\\#####\\\n const k = strokeWidth / 2 / miterRatio;\n const l = (strokeWidth / 2) * (d / e);\n const maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);\n const bevelAdd = maxr - r1;\n if (this.radius2_ === undefined || lineJoin === 'bevel') {\n return bevelAdd * 2;\n }\n // If outer miter is over the miter limit the inner miter may reach through the\n // center and be longer than the bevel, same calculation as above but swap r1 / r2.\n const aa = r1 * Math.sin(alpha);\n const bb = Math.sqrt(r1 * r1 - aa * aa);\n const dd = r2 - bb;\n const ee = Math.sqrt(aa * aa + dd * dd);\n const innerMiterRatio = ee / aa;\n if (innerMiterRatio <= miterLimit) {\n const innerLength = (innerMiterRatio * strokeWidth) / 2 - r2 - r1;\n return 2 * Math.max(bevelAdd, innerLength);\n }\n return bevelAdd * 2;\n }\n\n /**\n * @return {RenderOptions} The render options\n * @protected\n */\n createRenderOptions() {\n let lineCap = defaultLineCap;\n let lineJoin = defaultLineJoin;\n let miterLimit = 0;\n let lineDash = null;\n let lineDashOffset = 0;\n let strokeStyle;\n let strokeWidth = 0;\n\n if (this.stroke_) {\n strokeStyle = asColorLike(this.stroke_.getColor() ?? defaultStrokeStyle);\n strokeWidth = this.stroke_.getWidth() ?? defaultLineWidth;\n lineDash = this.stroke_.getLineDash();\n lineDashOffset = this.stroke_.getLineDashOffset() ?? 0;\n lineJoin = this.stroke_.getLineJoin() ?? defaultLineJoin;\n lineCap = this.stroke_.getLineCap() ?? defaultLineCap;\n miterLimit = this.stroke_.getMiterLimit() ?? defaultMiterLimit;\n }\n\n const add = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);\n const maxRadius = Math.max(this.radius, this.radius2_ || 0);\n const size = Math.ceil(2 * maxRadius + add);\n\n return {\n strokeStyle: strokeStyle,\n strokeWidth: strokeWidth,\n size: size,\n lineCap: lineCap,\n lineDash: lineDash,\n lineDashOffset: lineDashOffset,\n lineJoin: lineJoin,\n miterLimit: miterLimit,\n };\n }\n\n /**\n * @protected\n */\n render() {\n this.renderOptions_ = this.createRenderOptions();\n const size = this.renderOptions_.size;\n this.canvases_ = {};\n this.hitDetectionCanvas_ = null;\n this.size_ = [size, size];\n }\n\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The rendering context.\n * @param {number} pixelRatio The pixel ratio.\n */\n draw_(renderOptions, context, pixelRatio) {\n context.scale(pixelRatio, pixelRatio);\n // set origin to canvas center\n context.translate(renderOptions.size / 2, renderOptions.size / 2);\n\n this.createPath_(context);\n\n if (this.fill_) {\n let color = this.fill_.getColor();\n if (color === null) {\n color = defaultFillStyle;\n }\n context.fillStyle = asColorLike(color);\n context.fill();\n }\n if (renderOptions.strokeStyle) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n if (renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n context.lineCap = renderOptions.lineCap;\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n }\n\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @return {HTMLCanvasElement} Canvas containing the icon\n */\n createHitDetectionCanvas_(renderOptions) {\n let context;\n if (this.fill_) {\n let color = this.fill_.getColor();\n\n // determine if fill is transparent (or pattern or gradient)\n let opacity = 0;\n if (typeof color === 'string') {\n color = asArray(color);\n }\n if (color === null) {\n opacity = 1;\n } else if (Array.isArray(color)) {\n opacity = color.length === 4 ? color[3] : 1;\n }\n if (opacity === 0) {\n // if a transparent fill style is set, create an extra hit-detection image\n // with a default fill style\n context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.drawHitDetectionCanvas_(renderOptions, context);\n }\n }\n return context ? context.canvas : this.getImage(1);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} context The context to draw in.\n */\n createPath_(context) {\n let points = this.points_;\n const radius = this.radius;\n if (points === Infinity) {\n context.arc(0, 0, radius, 0, 2 * Math.PI);\n } else {\n const radius2 = this.radius2_ === undefined ? radius : this.radius2_;\n if (this.radius2_ !== undefined) {\n points *= 2;\n }\n const startAngle = this.angle_ - Math.PI / 2;\n const step = (2 * Math.PI) / points;\n for (let i = 0; i < points; i++) {\n const angle0 = startAngle + i * step;\n const radiusC = i % 2 === 0 ? radius : radius2;\n context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));\n }\n context.closePath();\n }\n }\n\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The context.\n */\n drawHitDetectionCanvas_(renderOptions, context) {\n // set origin to canvas center\n context.translate(renderOptions.size / 2, renderOptions.size / 2);\n\n this.createPath_(context);\n\n context.fillStyle = defaultFillStyle;\n context.fill();\n if (renderOptions.strokeStyle) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n if (renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n }\n\n /**\n * @override\n */\n ready() {\n return this.fill_ ? this.fill_.ready() : Promise.resolve();\n }\n}\n\nexport default RegularShape;\n","/**\n * @module ol/style/Circle\n */\n\nimport RegularShape from './RegularShape.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {Array<number>} [displacement=[0,0]] displacement\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.\n * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.\n * @property {number} [rotation=0] Rotation in radians\n * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view\n * (meaningful only when used in conjunction with a two dimensional scale).\n * @property {import('./Style.js').DeclutterMode} [declutterMode] Declutter mode\n */\n\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\nclass CircleStyle extends RegularShape {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {radius: 5};\n\n super({\n points: Infinity,\n fill: options.fill,\n radius: options.radius,\n stroke: options.stroke,\n scale: options.scale !== undefined ? options.scale : 1,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n rotateWithView:\n options.rotateWithView !== undefined ? options.rotateWithView : false,\n displacement:\n options.displacement !== undefined ? options.displacement : [0, 0],\n declutterMode: options.declutterMode,\n });\n }\n\n /**\n * Clones the style.\n * @return {CircleStyle} The cloned style.\n * @api\n * @override\n */\n clone() {\n const scale = this.getScale();\n const style = new CircleStyle({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n radius: this.getRadius(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n style.setOpacity(this.getOpacity());\n return style;\n }\n\n /**\n * Set the circle radius.\n *\n * @param {number} radius Circle radius.\n * @api\n */\n setRadius(radius) {\n this.radius = radius;\n this.render();\n }\n}\n\nexport default CircleStyle;\n","/**\n * @module ol/style/Fill\n */\n\nimport ImageState from '../ImageState.js';\nimport {get as getIconImage} from './IconImage.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|import('../colorlike.js').PatternDescriptor|null} [color=null] A color,\n * gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats. For polygon fills (not for {@link import(\"./RegularShape.js\").default} fills),\n * a pattern can also be provided as {@link module:ol/colorlike~PatternDescriptor}.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nclass Fill {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options || {};\n\n /**\n * @private\n * @type {import(\"./IconImage.js\").default|null}\n */\n this.patternImage_ = null;\n\n /**\n * @private\n * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|import('../colorlike.js').PatternDescriptor|null}\n */\n this.color_ = null;\n if (options.color !== undefined) {\n this.setColor(options.color);\n }\n }\n\n /**\n * Clones the style. The color is not cloned if it is a {@link module:ol/colorlike~ColorLike}.\n * @return {Fill} The cloned style.\n * @api\n */\n clone() {\n const color = this.getColor();\n return new Fill({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n });\n }\n\n /**\n * Get the fill color.\n * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|import('../colorlike.js').PatternDescriptor|null} Color.\n * @api\n */\n getColor() {\n return this.color_;\n }\n\n /**\n * Set the color.\n *\n * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|import('../colorlike.js').PatternDescriptor|null} color Color.\n * @api\n */\n setColor(color) {\n if (color !== null && typeof color === 'object' && 'src' in color) {\n const patternImage = getIconImage(\n null,\n color.src,\n 'anonymous',\n undefined,\n color.offset ? null : color.color ? color.color : null,\n !(color.offset && color.size),\n );\n patternImage.ready().then(() => {\n this.patternImage_ = null;\n });\n if (patternImage.getImageState() === ImageState.IDLE) {\n patternImage.load();\n }\n if (patternImage.getImageState() === ImageState.LOADING) {\n this.patternImage_ = patternImage;\n }\n }\n this.color_ = color;\n }\n\n /**\n * @return {boolean} The fill style is loading an image pattern.\n */\n loading() {\n return !!this.patternImage_;\n }\n\n /**\n * @return {Promise<void>} `false` or a promise that resolves when the style is ready to use.\n */\n ready() {\n return this.patternImage_ ? this.patternImage_.ready() : Promise.resolve();\n }\n}\n\nexport default Fill;\n","/**\n * @module ol/style/Stroke\n */\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {CanvasLineCap} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.\n * @property {CanvasLineJoin} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nclass Stroke {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options || {};\n\n /**\n * @private\n * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike}\n */\n this.color_ = options.color !== undefined ? options.color : null;\n\n /**\n * @private\n * @type {CanvasLineCap|undefined}\n */\n this.lineCap_ = options.lineCap;\n\n /**\n * @private\n * @type {Array<number>|null}\n */\n this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.lineDashOffset_ = options.lineDashOffset;\n\n /**\n * @private\n * @type {CanvasLineJoin|undefined}\n */\n this.lineJoin_ = options.lineJoin;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.miterLimit_ = options.miterLimit;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.width_ = options.width;\n }\n\n /**\n * Clones the style.\n * @return {Stroke} The cloned style.\n * @api\n */\n clone() {\n const color = this.getColor();\n return new Stroke({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n lineCap: this.getLineCap(),\n lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n lineDashOffset: this.getLineDashOffset(),\n lineJoin: this.getLineJoin(),\n miterLimit: this.getMiterLimit(),\n width: this.getWidth(),\n });\n }\n\n /**\n * Get the stroke color.\n * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} Color.\n * @api\n */\n getColor() {\n return this.color_;\n }\n\n /**\n * Get the line cap type for the stroke.\n * @return {CanvasLineCap|undefined} Line cap.\n * @api\n */\n getLineCap() {\n return this.lineCap_;\n }\n\n /**\n * Get the line dash style for the stroke.\n * @return {Array<number>|null} Line dash.\n * @api\n */\n getLineDash() {\n return this.lineDash_;\n }\n\n /**\n * Get the line dash offset for the stroke.\n * @return {number|undefined} Line dash offset.\n * @api\n */\n getLineDashOffset() {\n return this.lineDashOffset_;\n }\n\n /**\n * Get the line join type for the stroke.\n * @return {CanvasLineJoin|undefined} Line join.\n * @api\n */\n getLineJoin() {\n return this.lineJoin_;\n }\n\n /**\n * Get the miter limit for the stroke.\n * @return {number|undefined} Miter limit.\n * @api\n */\n getMiterLimit() {\n return this.miterLimit_;\n }\n\n /**\n * Get the stroke width.\n * @return {number|undefined} Width.\n * @api\n */\n getWidth() {\n return this.width_;\n }\n\n /**\n * Set the color.\n *\n * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} color Color.\n * @api\n */\n setColor(color) {\n this.color_ = color;\n }\n\n /**\n * Set the line cap.\n *\n * @param {CanvasLineCap|undefined} lineCap Line cap.\n * @api\n */\n setLineCap(lineCap) {\n this.lineCap_ = lineCap;\n }\n\n /**\n * Set the line dash.\n *\n * @param {Array<number>|null} lineDash Line dash.\n * @api\n */\n setLineDash(lineDash) {\n this.lineDash_ = lineDash;\n }\n\n /**\n * Set the line dash offset.\n *\n * @param {number|undefined} lineDashOffset Line dash offset.\n * @api\n */\n setLineDashOffset(lineDashOffset) {\n this.lineDashOffset_ = lineDashOffset;\n }\n\n /**\n * Set the line join.\n *\n * @param {CanvasLineJoin|undefined} lineJoin Line join.\n * @api\n */\n setLineJoin(lineJoin) {\n this.lineJoin_ = lineJoin;\n }\n\n /**\n * Set the miter limit.\n *\n * @param {number|undefined} miterLimit Miter limit.\n * @api\n */\n setMiterLimit(miterLimit) {\n this.miterLimit_ = miterLimit;\n }\n\n /**\n * Set the width.\n *\n * @param {number|undefined} width Width.\n * @api\n */\n setWidth(width) {\n this.width_ = width;\n }\n}\n\nexport default Stroke;\n","/**\n * @module ol/style/Style\n */\n\nimport CircleStyle from './Circle.js';\nimport Fill from './Fill.js';\nimport Stroke from './Stroke.js';\nimport {assert} from '../asserts.js';\n\n/**\n * Defines how symbols and text are decluttered on layers ith `declutter` set to `true`\n * * **declutter**: Overlapping symbols and text are decluttered.\n * * **obstacle**: Symbols and text are rendered, but serve as obstacle for subsequent attempts\n * to place a symbol or text at the same location.\n * * **none**: No decluttering is done.\n *\n * @typedef {\"declutter\"|\"obstacle\"|\"none\"} DeclutterMode\n */\n\n/**\n * A function that takes a {@link module:ol/Feature~Feature} and a `{number}`\n * representing the view's resolution. The function should return a\n * {@link module:ol/style/Style~Style} or an array of them. This way e.g. a\n * vector layer can be styled. If the function returns `undefined`, the\n * feature will not be rendered.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction\n */\n\n/**\n * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.\n * @typedef {Style|Array<Style>|StyleFunction} StyleLike\n */\n\n/**\n * A function that takes a {@link module:ol/Feature~Feature} as argument and returns an\n * {@link module:ol/geom/Geometry~Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike):\n * (import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined)} GeometryFunction\n */\n\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((import(\"../coordinate.js\").Coordinate|Array<import(\"../coordinate.js\").Coordinate>|Array<Array<import(\"../coordinate.js\").Coordinate>>|Array<Array<Array<import(\"../coordinate.js\").Coordinate>>>),import(\"../render.js\").State): void} RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string|import(\"../geom/Geometry.js\").default|GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {import(\"./Image.js\").default} [image] Image style.\n * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {RenderFunction} [hitDetectionRenderer] Custom renderer for hit detection. If provided will be used\n * in hit detection rendering.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {import(\"./Text.js\").default} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n *\n * ## Feature styles\n *\n * If no style is defined, the following default style is used:\n * ```js\n * import {Circle, Fill, Stroke, Style} from 'ol/style.js';\n *\n * const fill = new Fill({\n * color: 'rgba(255,255,255,0.4)',\n * });\n * const stroke = new Stroke({\n * color: '#3399CC',\n * width: 1.25,\n * });\n * const styles = [\n * new Style({\n * image: new Circle({\n * fill: fill,\n * stroke: stroke,\n * radius: 5,\n * }),\n * fill: fill,\n * stroke: stroke,\n * }),\n * ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n * import {Circle, Fill, Stroke, Style} from 'ol/style.js';\n *\n * const styles = {};\n * const white = [255, 255, 255, 1];\n * const blue = [0, 153, 255, 1];\n * const width = 3;\n * styles['Polygon'] = [\n * new Style({\n * fill: new Fill({\n * color: [255, 255, 255, 0.5],\n * }),\n * }),\n * ];\n * styles['MultiPolygon'] =\n * styles['Polygon'];\n * styles['LineString'] = [\n * new Style({\n * stroke: new Stroke({\n * color: white,\n * width: width + 2,\n * }),\n * }),\n * new Style({\n * stroke: new Stroke({\n * color: blue,\n * width: width,\n * }),\n * }),\n * ];\n * styles['MultiLineString'] = styles['LineString'];\n *\n * styles['Circle'] = styles['Polygon'].concat(\n * styles['LineString']\n * );\n *\n * styles['Point'] = [\n * new Style({\n * image: new Circle({\n * radius: width * 2,\n * fill: new Fill({\n * color: blue,\n * }),\n * stroke: new Stroke({\n * color: white,\n * width: width / 2,\n * }),\n * }),\n * zIndex: Infinity,\n * }),\n * ];\n * styles['MultiPoint'] =\n * styles['Point'];\n * styles['GeometryCollection'] =\n * styles['Polygon'].concat(\n * styles['LineString'],\n * styles['Point']\n * );\n * ```\n *\n * @api\n */\nclass Style {\n /**\n * @param {Options} [options] Style options.\n */\n constructor(options) {\n options = options || {};\n\n /**\n * @private\n * @type {string|import(\"../geom/Geometry.js\").default|GeometryFunction|null}\n */\n this.geometry_ = null;\n\n /**\n * @private\n * @type {!GeometryFunction}\n */\n this.geometryFunction_ = defaultGeometryFunction;\n\n if (options.geometry !== undefined) {\n this.setGeometry(options.geometry);\n }\n\n /**\n * @private\n * @type {import(\"./Fill.js\").default|null}\n */\n this.fill_ = options.fill !== undefined ? options.fill : null;\n\n /**\n * @private\n * @type {import(\"./Image.js\").default|null}\n */\n this.image_ = options.image !== undefined ? options.image : null;\n\n /**\n * @private\n * @type {RenderFunction|null}\n */\n this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n\n /**\n * @private\n * @type {RenderFunction|null}\n */\n this.hitDetectionRenderer_ =\n options.hitDetectionRenderer !== undefined\n ? options.hitDetectionRenderer\n : null;\n\n /**\n * @private\n * @type {import(\"./Stroke.js\").default|null}\n */\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n /**\n * @private\n * @type {import(\"./Text.js\").default|null}\n */\n this.text_ = options.text !== undefined ? options.text : null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.zIndex_ = options.zIndex;\n }\n\n /**\n * Clones the style.\n * @return {Style} The cloned style.\n * @api\n */\n clone() {\n let geometry = this.getGeometry();\n if (geometry && typeof geometry === 'object') {\n geometry = /** @type {import(\"../geom/Geometry.js\").default} */ (\n geometry\n ).clone();\n }\n return new Style({\n geometry: geometry ?? undefined,\n fill: this.getFill() ? this.getFill().clone() : undefined,\n image: this.getImage() ? this.getImage().clone() : undefined,\n renderer: this.getRenderer() ?? undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n text: this.getText() ? this.getText().clone() : undefined,\n zIndex: this.getZIndex(),\n });\n }\n\n /**\n * Get the custom renderer function that was configured with\n * {@link #setRenderer} or the `renderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n getRenderer() {\n return this.renderer_;\n }\n\n /**\n * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n * and `image` options of the style will be ignored.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n setRenderer(renderer) {\n this.renderer_ = renderer;\n }\n\n /**\n * Sets a custom renderer function for this style used\n * in hit detection.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n setHitDetectionRenderer(renderer) {\n this.hitDetectionRenderer_ = renderer;\n }\n\n /**\n * Get the custom renderer function that was configured with\n * {@link #setHitDetectionRenderer} or the `hitDetectionRenderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n getHitDetectionRenderer() {\n return this.hitDetectionRenderer_;\n }\n\n /**\n * Get the geometry to be rendered.\n * @return {string|import(\"../geom/Geometry.js\").default|GeometryFunction|null}\n * Feature property or geometry or function that returns the geometry that will\n * be rendered with this style.\n * @api\n */\n getGeometry() {\n return this.geometry_;\n }\n\n /**\n * Get the function used to generate a geometry for rendering.\n * @return {!GeometryFunction} Function that is called with a feature\n * and returns the geometry to render instead of the feature's geometry.\n * @api\n */\n getGeometryFunction() {\n return this.geometryFunction_;\n }\n\n /**\n * Get the fill style.\n * @return {import(\"./Fill.js\").default|null} Fill style.\n * @api\n */\n getFill() {\n return this.fill_;\n }\n\n /**\n * Set the fill style.\n * @param {import(\"./Fill.js\").default|null} fill Fill style.\n * @api\n */\n setFill(fill) {\n this.fill_ = fill;\n }\n\n /**\n * Get the image style.\n * @return {import(\"./Image.js\").default|null} Image style.\n * @api\n */\n getImage() {\n return this.image_;\n }\n\n /**\n * Set the image style.\n * @param {import(\"./Image.js\").default} image Image style.\n * @api\n */\n setImage(image) {\n this.image_ = image;\n }\n\n /**\n * Get the stroke style.\n * @return {import(\"./Stroke.js\").default|null} Stroke style.\n * @api\n */\n getStroke() {\n return this.stroke_;\n }\n\n /**\n * Set the stroke style.\n * @param {import(\"./Stroke.js\").default|null} stroke Stroke style.\n * @api\n */\n setStroke(stroke) {\n this.stroke_ = stroke;\n }\n\n /**\n * Get the text style.\n * @return {import(\"./Text.js\").default|null} Text style.\n * @api\n */\n getText() {\n return this.text_;\n }\n\n /**\n * Set the text style.\n * @param {import(\"./Text.js\").default} text Text style.\n * @api\n */\n setText(text) {\n this.text_ = text;\n }\n\n /**\n * Get the z-index for the style.\n * @return {number|undefined} ZIndex.\n * @api\n */\n getZIndex() {\n return this.zIndex_;\n }\n\n /**\n * Set a geometry that is rendered instead of the feature's geometry.\n *\n * @param {string|import(\"../geom/Geometry.js\").default|GeometryFunction} geometry\n * Feature property or geometry or function returning a geometry to render\n * for this style.\n * @api\n */\n setGeometry(geometry) {\n if (typeof geometry === 'function') {\n this.geometryFunction_ = geometry;\n } else if (typeof geometry === 'string') {\n this.geometryFunction_ = function (feature) {\n return /** @type {import(\"../geom/Geometry.js\").default} */ (\n feature.get(geometry)\n );\n };\n } else if (!geometry) {\n this.geometryFunction_ = defaultGeometryFunction;\n } else if (geometry !== undefined) {\n this.geometryFunction_ = function () {\n return /** @type {import(\"../geom/Geometry.js\").default} */ (geometry);\n };\n }\n this.geometry_ = geometry;\n }\n\n /**\n * Set the z-index.\n *\n * @param {number|undefined} zIndex ZIndex.\n * @api\n */\n setZIndex(zIndex) {\n this.zIndex_ = zIndex;\n }\n}\n\n/**\n * Convert the provided object into a style function. Functions passed through\n * unchanged. Arrays of Style or single style objects wrapped in a\n * new style function.\n * @param {StyleFunction|Array<Style>|Style} obj\n * A style function, a single style, or an array of styles.\n * @return {StyleFunction} A style function.\n */\nexport function toFunction(obj) {\n let styleFunction;\n\n if (typeof obj === 'function') {\n styleFunction = obj;\n } else {\n /**\n * @type {Array<Style>}\n */\n let styles;\n if (Array.isArray(obj)) {\n styles = obj;\n } else {\n assert(\n typeof (/** @type {?} */ (obj).getZIndex) === 'function',\n 'Expected an `Style` or an array of `Style`',\n );\n const style = /** @type {Style} */ (obj);\n styles = [style];\n }\n styleFunction = function () {\n return styles;\n };\n }\n return styleFunction;\n}\n\n/**\n * @type {Array<Style>|null}\n */\nlet defaultStyles = null;\n\n/**\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array<Style>} Style.\n */\nexport function createDefaultStyle(feature, resolution) {\n // We don't use an immediately-invoked function\n // and a closure so we don't get an error at script evaluation time in\n // browsers that do not support Canvas. (import(\"./Circle.js\").CircleStyle does\n // canvas.getContext('2d') at construction time, which will cause an.error\n // in such browsers.)\n if (!defaultStyles) {\n const fill = new Fill({\n color: 'rgba(255,255,255,0.4)',\n });\n const stroke = new Stroke({\n color: '#3399CC',\n width: 1.25,\n });\n defaultStyles = [\n new Style({\n image: new CircleStyle({\n fill: fill,\n stroke: stroke,\n radius: 5,\n }),\n fill: fill,\n stroke: stroke,\n }),\n ];\n }\n return defaultStyles;\n}\n\n/**\n * Default styles for editing features.\n * @return {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} Styles\n */\nexport function createEditingStyle() {\n /** @type {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} */\n const styles = {};\n const white = [255, 255, 255, 1];\n const blue = [0, 153, 255, 1];\n const width = 3;\n styles['Polygon'] = [\n new Style({\n fill: new Fill({\n color: [255, 255, 255, 0.5],\n }),\n }),\n ];\n styles['MultiPolygon'] = styles['Polygon'];\n\n styles['LineString'] = [\n new Style({\n stroke: new Stroke({\n color: white,\n width: width + 2,\n }),\n }),\n new Style({\n stroke: new Stroke({\n color: blue,\n width: width,\n }),\n }),\n ];\n styles['MultiLineString'] = styles['LineString'];\n\n styles['Circle'] = styles['Polygon'].concat(styles['LineString']);\n\n styles['Point'] = [\n new Style({\n image: new CircleStyle({\n radius: width * 2,\n fill: new Fill({\n color: blue,\n }),\n stroke: new Stroke({\n color: white,\n width: width / 2,\n }),\n }),\n zIndex: Infinity,\n }),\n ];\n styles['MultiPoint'] = styles['Point'];\n\n styles['GeometryCollection'] = styles['Polygon'].concat(\n styles['LineString'],\n styles['Point'],\n );\n\n return styles;\n}\n\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature to get the geometry for.\n * @return {import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined} Geometry to render.\n */\nfunction defaultGeometryFunction(feature) {\n return feature.getGeometry();\n}\n\nexport default Style;\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 CircleGeom from \"ol/geom/Circle\";\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 { fromLonLat, toLonLat } from \"ol/proj\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\ntype InjectableOL = {\n\tCircle: typeof CircleGeom;\n\tFeature: typeof Feature;\n\tGeoJSON: typeof GeoJSON;\n\tStyle: typeof Style;\n\tCircleStyle: typeof Circle;\n\tVectorLayer: typeof VectorLayer;\n\tVectorSource: typeof VectorSource;\n\tStroke: typeof Stroke;\n\ttoLonLat: typeof toLonLat;\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\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 = \"EPSG:3857\" as const;\n\tprivate _vectorSource: undefined | VectorSource<Feature<Geometry>>;\n\tprivate _geoJSONReader: undefined | 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\t/**\n\t * Converts a hexideciaml color to RGB\n\t * @param feature\n\t * @param styling\n\t * @returns an object to red green and blue (RGB) color\n\t */\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 Circle({\n\t\t\t\t\t\tradius: style.pointWidth,\n\t\t\t\t\t\tfill: new 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 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: \"LineString\", 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 Style({\n\t\t\t\t\tstroke: new 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 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\tif (this._vectorSource && this._geoJSONReader) {\n\t\t\tconst olFeature = this._geoJSONReader.readFeature(feature, {\n\t\t\t\tfeatureProjection: this._projection,\n\t\t\t}) as Feature<Geometry>;\n\t\t\tthis._vectorSource.addFeature(olFeature);\n\t\t} else {\n\t\t\tthrow new Error(\"Vector Source not initalised\");\n\t\t}\n\t}\n\n\tprivate removeFeature(id: FeatureId) {\n\t\tif (this._vectorSource) {\n\t\t\tconst deleted = this._vectorSource.getFeatureById(id);\n\t\t\tif (!deleted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._vectorSource.removeFeature(deleted);\n\t\t} else {\n\t\t\tthrow new Error(\"Vector Source not initalised\");\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\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(\"canvas\");\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(fromLonLat([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] = toLonLat(this._map.getCoordinateFromPixel([x, y]));\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\tconst source = this._vectorSource;\n\n\t\tif (!source) {\n\t\t\tthrow new Error(\"Vector Layer source has disappeared\");\n\t\t}\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 string);\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 Required<T> = {\n\t[P in keyof T]-?: T[P];\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","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// Based on Turf.js Circle module\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// Based on Turf.js destination module\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\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","import { LineString, Position } from \"geojson\";\nimport { destination } from \"./destination\";\nimport { bearing } from \"./bearing\";\nimport { haversineDistanceKilometers } from \"./haversine-distance\";\n\n// Based on Turf.js line slice along module\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\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 (this.closingPointId !== undefined) {\n\t\t\t\tthis.store.delete([this.closingPointId]);\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\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.js Rhumb Destination module\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\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 clickedFeature: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedFeatureDistance = Infinity;\n\t\tlet clickedMidPoint: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedMidPointDistance = Infinity;\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 < clickedFeatureDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedFeatureDistance = distance;\n\t\t\t\t\tclickedFeature = feature;\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"LineString\") {\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 < clickedFeatureDistance\n\t\t\t\t\t) {\n\t\t\t\t\t\tclickedFeatureDistance = distanceToLine;\n\t\t\t\t\t\tclickedFeature = 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\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\tclickedFeatureDistance = 0;\n\t\t\t\t\tclickedFeature = feature;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { clickedFeature, clickedMidPoint };\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// Based on turf-bearing: 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// Based on Turf.js 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// Based on turf-transform-rotate: 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\tconsole.log(\"rotatedCoordinates linestring\", rotatedCoordinates);\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// Based on turf-transform-scale: 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\nexport type 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\nexport type 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 is not ${id} 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.js 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 { 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 { 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 { 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","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 { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\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 pixelDistance!: PixelDistanceBehavior;\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\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(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\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","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 { TerraDrawBaseAdapter } from \"./adapters/common/base.adapter\";\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\";\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\n// This object allows 3rd party developers to\n// extend these abstract classes and create there\n// own modes and adapters\nconst TerraDrawExtend = {\n\tTerraDrawBaseDrawMode,\n\tTerraDrawBaseAdapter,\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\n\t// Adapters\n\tTerraDrawGoogleMapsAdapter,\n\tTerraDrawMapboxGLAdapter,\n\tTerraDrawLeafletAdapter,\n\tTerraDrawMapLibreGLAdapter,\n\tTerraDrawOpenLayersAdapter,\n\tTerraDrawArcGISMapsSDKAdapter,\n\tTerraDrawExtend,\n\n\t// Types that are required for 3rd party developers to extend\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"],"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","createPane","clearPanes","values","layer","removeLayer","styleGeoJSONLayer","pointToLayer","latlng","featureStyles","modeStyle","paneId","String","circleMarker","radius","stroke","color","weight","interactive","_feature","isNaN","containerPointToLatLng","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","beneath","moveLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","_setGeoJSONLayerData","getSource","setData","getEmptyGeometries","updateChangedIds","_this$_container$getB","getCanvas","dragRotate","dragPan","_this$_map$project","_this$_map$unproject","canvas","requestAnimationFrame","unchanged","geometryFeatures","_loop","styles","pointId","forceUpdate","updateLineStrings","updatedPolygon","TerraDrawMapLibreGLAdapter","mapboxglAdapter","abstract","uidCounter_","toSize","dest","isArray","ImageStyle","constructor","options","opacity_","opacity","rotateWithView_","rotateWithView","rotation_","scale_","scaleArray_","displacement_","displacement","declutterMode_","declutterMode","clone","getScale","getOpacity","slice","getRotation","getRotateWithView","getDisplacement","getDeclutterMode","getScaleArray","getAnchor","getImage","pixelRatio","getHitDetectionImage","getPixelRatio","getImageState","getImageSize","getOrigin","getSize","setDisplacement","setOpacity","setRotateWithView","setRotation","setScale","listenImageChange","load","unlistenImageChange","ready","Promise","resolve","ImageStyle$1","rgb","min","max","channel","alias","xyz","A","C","D50","D55","D65","D75","F2","F7","F11","E","whitepoint","_xyz","white","g","b","z","luv","arg","o","_u","_v","l","xn","yn","zn","un","vn","yr","lchuv","u","v","c","h","atan2","PI","names","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","whitesmoke","yellow","yellowgreen","baseHues","hsl","t1","t2","t3","val","s","clamp","delta","MAX_CACHE_SIZE","cache","cacheSize","asArray","hasOwnProperty","raw","arguments","Number","parsed","cstr","m","space","parts","alpha","base","parseInt","exec","dims","replace","trim","split","shift","parseFloat","endsWith","pop","test","match","join","parse","parseRgba","normalize","fromString","toString","ua","navigator","userAgent","includes","WORKER_OFFSCREEN_CANVAS","WorkerGlobalScope","OffscreenCanvas","self","IMAGE_DECODE","Image","decode","createCanvasContext2D","width","height","canvasPool","settings","getContext","sharedCanvasContext","getSharedCanvasContext2D","passive","defineProperty","window","error","Disposable$1","disposed","dispose","disposeInternal","Event","defaultPrevented","stopPropagation","propagationStopped","VOID","object","EventTarget","Disposable","super","eventTarget_","pendingRemovals_","dispatching_","listeners_","listeners","listenersForType","dispatchEvent","isString","evt","dispatching","pendingRemovals","propagate","ii","handleEvent","pr","getListeners","hasListener","index","indexOf","splice","EventType","listen","thisArg","once","originalListener","apply","eventsKey","listenOnce","unlistenByKey","getCacheKey","src","crossOrigin","shared","cache_","patternCache_","cacheSize_","maxCacheSize_","canExpireCache","expire","getPattern","set","iconImage","pattern","update","then","createPattern","setSize","maxCacheSize","taintedTestContext","IconImage","image","imageState","hitDetectionImage_","image_","crossOrigin_","canvas_","color_","imageState_","size_","src_","ready_","initializeImage_","isTainted_","tainted_","willReadFrequently","drawImage","getImageData","e","dispatchChangeEvent_","handleImageError_","handleImageLoad_","replaceColor_","context","fillRect","getSrc","HTMLImageElement","reject","catch","complete","handleLoad","unlisten","handleError","ceil","ctx","globalCompositeOperation","fillStyle","onChange","cacheKey","iconImageCache","asColorLike","offset","iconCache","canvasPattern","patternCanvasContext","getIconImage","asCanvasPattern","Observable$1","on","revision_","changed","getRevision","onInternal","len","onceInternal","ol_key","unInternal","unByKey","ObjectEvent","oldValue","defaultFillStyle","defaultLineCap","defaultLineJoin","Observable","ol_uid","values_","setProperties","getKeys","getProperties","assign","getPropertiesInternal","hasProperties","notify","eventType","addChangeListener","removeChangeListener","silent","applyProperties","unset","isEmpty","RegularShape","hitDetectionCanvas_","fill_","fill","origin_","points_","radius2_","radius2","angle_","angle","stroke_","loading","getFill","getPoints","getRadius","getRadius2","getAngle","getStroke","setFill","createHitDetectionCanvas_","renderOptions_","canvases_","renderOptions","draw_","setStroke","calculateLineJoinSize_","lineJoin","strokeWidth","miterLimit","Infinity","r1","r2","tmp","a","sin","miterRatio","k","bevelAdd","aa","dd","innerMiterRatio","createRenderOptions","strokeStyle","lineCap","lineDash","lineDashOffset","getColor","getWidth","getLineDash","getLineDashOffset","getLineJoin","getLineCap","getMiterLimit","maxRadius","translate","createPath_","lineWidth","setLineDash","drawHitDetectionCanvas_","arc","startAngle","step","angle0","radiusC","lineTo","cos","closePath","RegularShape$1","CircleStyle","setRadius","Circle","Fill","patternImage_","setColor","patternImage","Fill$1","Stroke","lineCap_","lineDash_","lineDashOffset_","lineJoin_","miterLimit_","width_","setLineCap","setLineDashOffset","setLineJoin","setMiterLimit","setWidth","Stroke$1","Style","geometry_","geometryFunction_","defaultGeometryFunction","renderer_","renderer","hitDetectionRenderer_","hitDetectionRenderer","text_","text","zIndex_","getRenderer","getText","getZIndex","setRenderer","setHitDetectionRenderer","getHitDetectionRenderer","getGeometryFunction","setImage","setText","setZIndex","Style$1","METERS_PER_UNIT","radians","degrees","ft","Projection$1","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","EPSG3857Projection","Projection","units","resolution","cosh","PROJECTIONS","EPSG4326Projection","transforms","destination","transformFn","sourceCode","destinationCode","cloneTransform","input","output","identityTransform","addProjection","addProj","addTransformFunc","projectionLike","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","getViewport","setAttribute","vectorSource","VectorSource","vectorLayer","VectorLayer","getStyles","hexToRGB","hex","_this2$hexToRGB","addFeature","olFeature","readFeature","featureProjection","removeFeature","_","canvases","querySelectorAll","getInteractions","interaction","setActive","_this$_map$getPixelFr","getPixelFromCoordinate","_toLonLat","lonLat","lon","modulo","toLonLat","getCoordinateFromPixel","TerraDrawArcGISMapsSDKAdapter","_mapView","_featureIdAttributeName","_featureLayerName","_featureLayer","_dragEnabled","_zoomEnabled","_dragHandler","_doubleClickHandler","container","GraphicsLayer","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","Color","fromHex","ModeTypes","SELECT_PROPERTIES","POLYGON_PROPERTIES","isObject","isValidTimestamp","timestamp","Date","valueOf","dateIsValid","TerraDrawBaseDrawMode","_state","_styles","behaviors","validate","pointerDistance","onStyleChange","store","Drawing","_extends","validation","registerBehaviors","behaviorConfig","setDrawing","setStarted","setStopped","registerOnChange","onSelect","onDeselect","onFinish","validateFeature","validStoreFeature","isValidId","isValidStoreFeature","idStrategy","updateType","Provisional","finishedId","deselectedId","selectedId","setMapDraggability","getHexColorStylingValue","defaultValue","getStylingValue","getNumericStylingValue","TerraDrawBaseSelectMode","_TerraDrawBaseDrawMod","_len","args","_key","Select","haversineDistanceKilometers","toRadians","latOrLng","phiOne","lambdaOne","phiTwo","deltaPhi","deltalambda","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","array1","array2","coordinateIsValid","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","dx","dy","_webMercatorXYToLngLa","circleWebMercator","updateGeometry","updateProperty","TerraDrawFreehandMode","startingClick","currentId","closingPointId","minDistance","preventPointsNearClose","currentLineGeometry","_currentLineGeometry$","_this$project","previousLat","_currentLineGeometry$2","_this$project2","closingLat","newGeometry","cleanUpClosingPointId","closingPointWidth","closingPointColor","closingPointOutlineColor","closingPointOutlineWidth","TerraDrawModeBehavior","createBBoxFromPoint","halfDist","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","lineSliceAlong","coords","startDist","stopDist","overshot","direction","interpolated","origCoordsLength","travelled","last","toDegrees","InsertCoordinatesBehavior","generateInsertionCoordinates","segmentLength","line","lineLength","numberOfSegments","isInteger","floor","segments","limitCoordinates","generateInsertionGeodesicCoordinates","numberOfPoints","f","B","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","getDefaultStyling","ValidatePointFeature","TerraDrawPointMode","ClosingPointsBehavior","_startEndPoints","selectedCoords","_properties","_properties2","ids","updatedCoordinates","isClosingPoint","opening","closing","distancePrevious","isClosing","isPreviousClosing","TerraDrawPolygonMode","closingPoints","currentPolygonCoordinates","updatePolygonGeometry","closestCoord","_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","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","featureId","getMidPoints","getUpdated","updatedMidPointCoord","SelectionPointBehavior","_selectionPoints","geometryType","selectionPoints","getCoordinatesAsPoints","selectionPoint","selectionPointFeatureId","getOneUpdated","updatedCoordinate","pointInPolygon","p","p1","p2","inside","ring","len2","pixelDistanceToLine","linePointOne","linePointTwo","square","dist2","w","l2","t","distToSegmentSquared","FeatureAtPointerEventBehavior","createClickBoundingBox","hasSelection","clickedFeature","clickedFeatureDistance","clickedMidPoint","clickedMidPointDistance","nextCoord","distanceToLine","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","console","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","coordinateIndex","modeFlags","deletable","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","sd","swap","calcBBox","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","child","extend","leaf","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","intersects","multiSelect","stack","RBush","maxEntries","_maxEntries","_minEntries","result","nodesToSearch","childBBox","_all","collides","_build","_splitRoot","tmpNode","_insert","item","parent","indexes","goingUp","_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","obj","JSON","stringify","featureValidation","clonedData","createdAt","updatedAt","change","propertiesToUpdate","geometriesToUpdate","_this5","createdProperties","_this6","copyAll","_this7","polygonAreaSquareMeters","polygon","total","ringArea","FACTOR","PI_OVER_180","coordsLength","ValidateMinAreaSquareMeters","minSize","ValidateMaxAreaSquareMeters","maxSize","ValidateNotSelfIntersecting","calculateRelativeAngle","bearingAB","relativeAngle","TerraDrawAngledRectangleMode","lineStart","lineEnd","firstCoordinate","D","ACloserThanC","hypotenuse","adjacent","rectangleAngle","thirdCoordinateXY","fourthCoordinateXY","thirdCoordinate","fourthCoordinate","TerraDraw","_modes","_mode","_adapter","_enabled","_store","_eventListeners","_instanceSelectMode","adapter","duplicateModeTracker","modesMap","modes","modeMap","currentMode","modeKeys","static","getChanged","_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","off","TerraDrawExtend"],"mappings":"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"}
1
+ {"version":3,"file":"terra-draw.module.js","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/validations/min-size.validation.ts","../src/validations/max-size.validation.ts","../src/validations/not-self-intersecting.validation.ts","../src/geometry/calculate-relative-angle.ts","../src/modes/angled-rectangle/angled-rectangle.mode.ts","../src/geometry/determine-halfplane.ts","../src/modes/sector/sector.mode.ts","../src/geometry/clockwise.ts","../src/terra-draw.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(\"canvas\");\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\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 (this.closingPointId !== undefined) {\n\t\t\t\tthis.store.delete([this.closingPointId]);\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 { 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 { 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 { 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","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","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","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 { 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 { TerraDrawBaseAdapter } from \"./adapters/common/base.adapter\";\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\";\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\n// This object allows 3rd party developers to\n// extend these abstract classes and create there\n// own modes and adapters\nconst TerraDrawExtend = {\n\tTerraDrawBaseDrawMode,\n\tTerraDrawBaseAdapter,\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\n\t// Adapters\n\tTerraDrawGoogleMapsAdapter,\n\tTerraDrawMapboxGLAdapter,\n\tTerraDrawLeafletAdapter,\n\tTerraDrawMapLibreGLAdapter,\n\tTerraDrawOpenLayersAdapter,\n\tTerraDrawArcGISMapsSDKAdapter,\n\tTerraDrawExtend,\n\n\t// Types that are required for 3rd party developers to extend\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"],"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","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","ValidateMinAreaSquareMeters","minSize","ValidateMaxAreaSquareMeters","maxSize","ValidateNotSelfIntersecting","calculateRelativeAngle","C","bearingAB","relativeAngle","TerraDrawAngledRectangleMode","lineStart","lineEnd","firstCoordinate","D","ACloserThanC","hypotenuse","adjacent","rectangleAngle","thirdCoordinateXY","fourthCoordinateXY","thirdCoordinate","fourthCoordinate","TerraDrawSectorMode","arcPoints","arcCoordOne","arcCoordTwo","webMercatorCenter","webMercatorArcCoordOne","webMercatorArcCoordTwo","clockwise","secondCoord","thirdCoord","isClockwiseWebMercator","deltaBearing","startBearing","endBearing","normalizedStart","normalizedEnd","bearingStep","pointOnArc","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","TerraDrawExtend"],"mappings":"o/BAAgBA,EAAeC,EAAaC,YAAAA,IAAAA,EAAe,GAC1D,IAAMC,EAAWC,KAAKC,IAAI,GAAIH,GAC9B,OAAOE,KAAKE,MAAML,EAAME,GAAYA,CACrC,CCHa,IAAAI,EAAoB,SAChCC,EACAC,GAEA,IAEMC,EADmBD,EAAjBE,EADiBH,EAAjBG,EAGFA,EAFmBF,EAAVC,EADUF,EAAVE,EAIf,OAAON,KAAKQ,KAAKD,EAAIA,EAAID,EAAIA,EAC9B,ECTaG,EAgBZ,SAAAC,GAUC,IAAAC,EAAAC,KATAC,EAAIH,EAAJG,KACAC,EAAQJ,EAARI,SACAC,EAAUL,EAAVK,WACAC,EAAQN,EAARM,SAnBMH,KAAAA,UACAC,EAAAA,KAAAA,cACAG,EAAAA,KAAAA,YAAa,EAAKL,KAClBI,cAAQ,EAAAJ,KACRG,gBAAU,EAsBhBH,KAAKC,KAAOA,EAGZD,KAAKI,SAAW,WACVL,EAAKM,aACTN,EAAKM,YAAa,EAClBD,EAASF,GAEX,EAGAF,KAAKG,WAAa,WACbJ,EAAKK,WACRL,EAAKM,YAAa,EAClBF,EAAWD,GAEb,EAEAF,KAAKE,SAAWA,CACjB,ECpBqBI,eAAoB,WACzC,SAAAA,EAAYC,GAAyBP,KAsB3BQ,2BACAC,EAAAA,KAAAA,yCACAC,oCAA8B,EAAAV,KAC9BW,oBACAC,EAAAA,KAAAA,iCACAC,UAAyB,IAAIC,SAC7BC,WAEJ,GACIC,KAAAA,WACT,oBACSC,2BAAqB,EAhC9BjB,KAAKQ,sBACmC,iBAAhCD,EAAOW,qBACXX,EAAOW,qBACP,EAEJlB,KAAKU,+BAC4C,iBAAzCH,EAAOY,8BACXZ,EAAOY,8BACP,EAEJnB,KAAKS,6BAC0C,iBAAvCF,EAAOa,4BACXb,EAAOa,4BACP,EAEJpB,KAAKY,qBACkC,iBAA/BL,EAAOc,oBACXd,EAAOc,oBACP,CACL,CAAC,IAAAC,EAAAhB,EAAAiB,iBAAAD,EAiBSE,UAAA,SAAUC,GACnB,OAAsB,IAAlBA,EAAMC,OACF,UACoB,IAAjBD,EAAMC,OACT,OACoB,IAAjBD,EAAMC,OACT,SACoB,IAAjBD,EAAMC,OACT,QAID,SACR,EAACJ,EAESK,wBAAA,SAAwBF,GACjC,IACAG,EADmB5B,KAAK6B,qBACSC,wBAEjC,MAAO,CACNC,WAAYN,EAAMO,QAHPJ,EAAJK,KAIPC,WAAYT,EAAMU,QAJFP,EAAHQ,IAMf,EAACd,EAESe,sBAAA,SACTZ,GAEA,IAAMa,EAAStC,KAAKuC,mBAAmBd,GAEvC,IAAKa,EACJ,OAAO,KAGR,IAAQE,EAAaF,EAAbE,IAAKC,EAAQH,EAARG,IACbC,EAAmC1C,KAAK2B,wBAAwBF,GAAxDM,EAAUW,EAAVX,WAAYG,EAAUQ,EAAVR,WACdR,EAAS1B,KAAKwB,UAAUC,GACxBkB,EAAWC,MAAMC,KAAK7C,KAAKa,WAEjC,MAAO,CACN2B,IAAKxD,EAAewD,EAAKxC,KAAKY,sBAC9B6B,IAAKzD,EAAeyD,EAAKzC,KAAKY,sBAC9BmB,WAAAA,EACAG,WAAAA,EACAR,OAAAA,EACAiB,SAAAA,EAEF,EAACrB,EAQMlB,SAAA,SAAS0C,GACf9C,KAAKiB,sBAAwB6B,EAE7B9C,KAAKe,WAAaf,KAAK+C,sBAEvB/C,KAAKe,WAAWiC,QAAQ,SAACC,GACxBA,EAAS7C,UACV,EACD,EAACkB,EAOM4B,uBAAA,WACN,YAAYtC,oBACb,EAACU,EAEOyB,oBAAA,WAAmBhD,IAAAA,OAC1B,MAAO,CACN,IAAIF,EAAqC,CACxCI,KAAM,cACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAKLQ,EAAM0B,UAAX,CAIA,IAAMC,EAAYrD,EAAKsC,sBAAsBZ,GACxC2B,IAILrD,EAAKiB,WAAa,eAKlBjB,EAAKY,eAAiByC,EAZtB,CAaD,EACAhD,SAAU,SAACF,GACVH,EAAK8B,qBAAqBwB,iBAAiB,cAAenD,EAC3D,EACAC,WAAY,SAACD,GACZH,EAAK8B,qBAAqByB,oBACzB,cACApD,EAEF,IAED,IAAIL,EAAqC,CACxCI,KAAM,cACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAGLQ,EAAM0B,UAAX,CAIA1B,EAAM8B,iBAEN,IAAMH,EAAYrD,EAAKsC,sBAAsBZ,GAC7C,GAAK2B,EAIL,GAAwB,iBAApBrD,EAAKiB,WAERjB,EAAKkB,sBAAsBuC,YAAYJ,GACvCrD,EAAKY,eAAiByC,OAChB,GAAwB,iBAApBrD,EAAKiB,WAA+B,CAE9C,IAAKjB,EAAKY,eACT,OAGD,IAAM8C,EAAc,CACnB9D,EAAGI,EAAKY,eAAeoB,WACvBrC,EAAGK,EAAKY,eAAeuB,YAElBwB,EAAiB,CACtB/D,EAAGyD,EAAUrB,WACbrC,EAAG0D,EAAUlB,YAMRyB,EAAY5D,EAAKkB,sBAAsB2C,WAEvCC,EAAuBtE,EAC5BkE,EACAC,GAwBD,GAlBkB,YAAdC,EAKFE,EAAuB9D,EAAKU,6BACL,cAAdkD,EAKTE,EAAuB9D,EAAKW,+BAGfmD,EAAuB9D,EAAKS,sBAK1C,OAGDT,EAAKiB,WAAa,WAClBjB,EAAKkB,sBAAsB6C,YAC1BV,EACA,SAACW,GACAhE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,EAEF,KAA+B,aAApBhE,EAAKiB,YACfjB,EAAKkB,sBAAsBiD,OAAOd,EAAW,SAACW,GAC7ChE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,EAzED,CA2ED,EACA3D,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,cAAenD,EAC5C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,cAAepD,EAC/C,IAED,IAAIL,EAAmC,CACtCI,KAAM,cACNC,SAAU,SAACuB,GACL1B,EAAKkB,uBAGVQ,EAAM8B,gBACP,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,cAAenD,EAC5C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,cAAepD,EAC/C,IAED,IAAIL,EAAqC,CACxCI,KAAM,YACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAINQ,EAAM0C,SAAWpE,EAAK8B,sBAKrBJ,EAAM0B,UAAX,CAIA,IAAMC,EAAYrD,EAAKsC,sBAAsBZ,GAExC2B,IAImB,aAApBrD,EAAKiB,WACRjB,EAAKkB,sBAAsBmD,UAAUhB,EAAW,SAACW,GAChDhE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,GAEoB,iBAApBhE,EAAKiB,YACe,iBAApBjB,EAAKiB,YAILjB,EAAKkB,sBAAsBoD,QAAQjB,GAKpCrD,EAAKiB,WAAa,eAClBjB,EAAKiE,iBAAgB,GAxBrB,CAyBD,EACA5D,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,YAAanD,EAC1C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,YAAapD,EAC7C,IAED,IAAIL,EAAgB,CACnBI,KAAM,QACNC,SAAU,SAACuB,GAGL1B,EAAKkB,wBAEVlB,EAAKc,iBAAiBY,EAAM6C,KAE5BvE,EAAKkB,sBAAsBsD,QAAQ,CAClCD,IAAK7C,EAAM6C,IACX3B,SAAUC,MAAMC,KAAK9C,EAAKc,WAC1B0C,eAAgB,kBAAM9B,EAAM8B,gBAAgB,IAE9C,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,QAASnD,EACtC,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,QAASpD,EACzC,IAED,IAAIL,EAAgB,CACnBI,KAAM,UACNC,SAAU,SAACuB,GACL1B,EAAKkB,wBAIVlB,EAAKc,UAAU2D,IAAI/C,EAAM6C,KAEzBvE,EAAKkB,sBAAsBwD,UAAU,CACpCH,IAAK7C,EAAM6C,IACX3B,SAAUC,MAAMC,KAAK9C,EAAKc,WAC1B0C,eAAgB,kBAAM9B,EAAM8B,gBAAgB,IAE9C,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,UAAWnD,EACxC,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,UAAWpD,EAC3C,IAGH,EAACoB,EAOMnB,WAAA,WACNH,KAAKe,WAAWiC,QAAQ,SAACC,GACxBA,EAAS9C,YACV,GACAH,KAAK0E,OACN,EAACpE,CAAA,CAhXwC,GChB7BqE,eAA2B,SAAAC,GACvC,SAAAD,EACCpE,GAGqBR,IAAAA,EAQrB,IANAA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAOP,MAgBN8E,aAAO,EAAA/E,EACPgF,uBAAiB,EAAAhF,EACjBiF,UAAI,EAAAjF,EACJkF,UAAI,EAAAlF,EACJmF,cAAQ,EAAAnF,EACRoF,yBAAmB,EAAApF,EACnBqF,6BAAuB,EAAArF,EAqPvBsF,mBAAqC,IAAIvE,IA1QhDf,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKkF,KAAO1E,EAAOgF,KAIdxF,EAAKkF,KAAKO,SAASC,GACvB,MAAU,IAAAC,MAAM,sDAMX,OAHN3F,EAAKa,qBACkC,iBAA/BL,EAAOc,oBACXd,EAAOc,oBACP,EAAEtB,CACP,CArBuC4F,EAAAhB,EAAAC,GAqBtC,IAAAtD,EAAAqD,EAAApD,UAYAoD,OAZArD,EAsBOsE,WAAA,SAAWC,EAAYC,EAAYC,GAC1C,IAAMC,EAAQ,EAAJD,EACV,MAAA,KAAYF,EAAE,IAAIC,EAAE,OAAOC,EAAC,SAASA,EAAC,IAAIA,EAAC,UAAUC,EAAC,QAAQD,EAAC,IAAIA,EAAC,WAAWC,EAAC,IACjF,EAAC1E,EAEMlB,SAAA,SAAS0C,GAA6BmD,IAAAA,EAC5CrB,KAAAA,EAAArD,UAAMnB,SAAQyE,KAAA7E,KAAC8C,GAKf9C,KAAKkF,SAAW,IAAIlF,KAAKgF,KAAKkB,YAC9BlG,KAAKkF,SAASiB,KAAO,WAAc,EAKnCnG,KAAKkF,SAASkB,MAAQ,WACrBH,EAAKhF,uBACJgF,EAAKhF,sBAAsBoF,SAC3BJ,EAAKhF,sBAAsBoF,SAC7B,EACArG,KAAKkF,SAASoB,OAAOtG,KAAKiF,MAK1BjF,KAAKmF,oBAAsBnF,KAAKiF,KAAKsB,KAAKC,YACzC,QACA,SACC/E,GAIA,IAAMgF,EAAgBR,EAAKlF,WAAW2F,KACrC,SAAA5G,GAAO,MAAgB,UAAhBA,EAAJG,IAA2B,GAE3BwG,GACHA,EAAcvG,SAASuB,EAEzB,GAGDzB,KAAKoF,wBAA0BpF,KAAKiF,KAAKsB,KAAKC,YAC7C,YACA,SACC/E,GAIA,IAAMkF,EAAoBV,EAAKlF,WAAW2F,KACzC,SAAAE,GAAO,MAAgB,cAAhBA,EAAJ3G,IAA+B,GAE/B0G,GACHA,EAAkBzG,SAASuB,EAE7B,EAEF,EAACH,EAEMnB,WAAA,WAAU0G,IAAAA,EAAAC,EAAAC,EAChBnC,EAAArD,UAAMpB,WAAU0E,KAAA7E,MACQ,OAAxB6G,EAAI7G,KAACmF,sBAAL0B,EAA0BG,SACE,OAA5BF,EAAI9G,KAACoF,0BAAL0B,EAA8BE,SACjB,OAAbD,EAAI/G,KAACkF,WAAL6B,EAAeT,OAAO,MACtBtG,KAAKkF,cAAW+B,CACjB,EAAC3F,EAODiB,mBAAA,SAAmBd,GAClB,IAAKzB,KAAKkF,SACT,MAAU,IAAAQ,MAAM,sBAGjB,IAAMwB,EAASlH,KAAKiF,KAAKkC,YAEzB,IAAKD,EACJ,OAAO,KAGR,IAAME,EAAKF,EAAOG,eACZC,EAAKJ,EAAOK,eACZC,EAAe,IAAQxH,KAACgF,KAAKyC,aAAaH,EAAIF,GAE9CM,EAAY1H,KAAKiF,KAAKO,SACtBmC,EAAUlG,EAAMO,QAAU0F,EAAU5F,wBAAwBG,KAC5D2F,EAAUnG,EAAMU,QAAUuF,EAAU5F,wBAAwBM,IAC5DyF,EAAc,IAAI7H,KAAKgF,KAAK8C,MAAMH,EAASC,GAE3CG,EAAa/H,KAAKkF,SAAS8C,gBACjC,IAAKD,EACJ,OACD,KAEA,IAAMzF,EAASyF,EAAWE,2BAA2BJ,GAErD,OAAIvF,GAAUkF,EAAaU,SAAS5F,GAC5B,CAAEE,IAAKF,EAAOE,MAAOC,IAAKH,EAAOG,WAI1C,EAACnB,EAMMO,mBAAA,WAGN,OAAW7B,KAACiF,KAAKO,SAAS2C,cADT,4BAElB,EAAC7G,EAQD8G,QAAA,SAAQ5F,EAAaC,GACpB,IAAKzC,KAAKkF,SACT,MAAM,IAAIQ,MAAM,sBAKjB,QAAeuB,IAFAjH,KAAKiF,KAAKkC,YAGxB,MAAU,IAAAzB,MAAM,qBAGjB,IAAMqC,EAAa/H,KAAKkF,SAAS8C,gBACjC,QAAmBf,IAAfc,EACH,MAAU,IAAArC,MAAM,yBAGjB,IAAM2C,EAAQN,EAAWO,2BACxB,IAAQtI,KAACgF,KAAKuD,OAAO9F,EAAKD,IAG3B,GAAc,OAAV6F,EACH,MAAU,IAAA3C,MAAM,8BAGjB,MAAO,CAAE/F,EAAG0I,EAAM1I,EAAGD,EAAG2I,EAAM3I,EAC/B,EAAC4B,EAQDkH,UAAA,SAAU7I,EAAWD,GACpB,IAAKM,KAAKkF,SACT,MAAU,IAAAQ,MAAM,sBAGjB,IAAMqC,EAAa/H,KAAKkF,SAAS8C,gBACjC,QAAmBf,IAAfc,EACH,MAAM,IAAIrC,MAAM,yBAGjB,IAAMpD,EAASyF,EAAWE,2BACzB,IAAIjI,KAAKgF,KAAK8C,MAAMnI,EAAGD,IAGxB,GAAe,OAAX4C,EACH,MAAU,IAAAoD,MAAM,gCAGjB,MAAO,CAAElD,IAAKF,EAAOE,MAAOC,IAAKH,EAAOG,MACzC,EAACnB,EAMDmH,UAAA,SAAUC,GACT,GAAIA,IAAW1I,KAAK8E,QAApB,CASA,GALI9E,KAAK+E,oBACR/E,KAAK+E,kBAAkBiC,SACvBhH,KAAK+E,uBAAoBkC,GAGX,UAAXyB,EAAoB,CAGvB,IAAMC,EAAM3I,KAAKiF,KAAKO,SAEhBoD,EAAWC,SAASV,cADJ,IAAOQ,EAAIlD,GAAE,oBAGnC,GAAImD,EAAU,CACbA,EAASE,UAAUtE,IAAI,0BAEvB,IAAMuE,EAAQF,SAASG,cAAc,SACrCD,EAAME,UAAS,qCAAwCP,EAAM,iBAC7DG,SAASK,qBAAqB,QAAQ,GAAGC,YAAYJ,GACrD/I,KAAK+E,kBAAoBgE,CAC1B,CACD,CAEA/I,KAAK8E,QAAU4D,CAxBf,CAyBD,EAACpH,EAMD8H,qBAAA,SAAqBrF,GAEnB/D,KAAKiF,KAAKoE,WADPtF,EACkB,CAAEuF,wBAAwB,GAE1B,CAAEA,wBAAwB,GAEjD,EAAChI,EAMD0C,gBAAA,SAAgBD,GACf/D,KAAKiF,KAAKoE,WAAW,CAAEE,UAAWxF,GACnC,EAACzC,EASDkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAC,EAAA3J,KAC9DA,KAAK4J,UACRH,EAAQI,WAAW7G,QAAQ,SAAC8G,GAC3B,IAAMC,EAAkBJ,EAAK1E,KAAKsB,KAAKyD,eAAeF,GAClDC,IACHJ,EAAK1E,KAAKsB,KAAKS,OAAO+C,GACtBJ,EAAKtE,mBAAyB,OAACyE,GAEjC,GAEAL,EAAQQ,QAAQjH,QAAQ,SAACkH,GACxB,IAAKA,IAAmBA,EAAezE,GACtC,MAAM,IAAIC,MAAM,wBAGjB,IAAMyE,EAAkBR,EAAK1E,KAAKsB,KAAKyD,eACtCE,EAAezE,IAGhB,IAAK0E,EACJ,MAAU,IAAAzE,MAAM,iDAgBjB,OAZAyE,EAAgBC,gBAAgB,SAACC,EAAUpK,GAC1CkK,EAAgBG,YAAYrK,OAAMgH,EACnC,GAGAsD,OAAOC,KAAKN,EAAeO,YAAYzH,QAAQ,SAACqH,GAC/CF,EAAgBG,YACfD,EACAH,EAAeO,WAAWJ,GAE5B,GAEQH,EAAeQ,SAASC,MAC/B,IAAK,QAEH,IAAMC,EAAcV,EAAeQ,SAASE,YAE5CT,EAAgBU,YACf,IAAIlB,EAAK3E,KAAK8F,KAAKhD,MAClB,IAAI6B,EAAK3E,KAAKuD,OAAOqC,EAAY,GAAIA,EAAY,MAIpD,MACD,IAAK,aAKH,IAHA,IAAMA,EAAcV,EAAeQ,SAASE,YAEtCG,EAAO,GACJC,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IAAK,CAC5C,IAAME,EAAaN,EAAYI,GACzB1I,EAAS,IAAIqH,EAAK3E,KAAKuD,OAC5B2C,EAAW,GACXA,EAAW,IAEZH,EAAKI,KAAK7I,EACX,CAEA6H,EAAgBU,YAAY,IAAIlB,EAAK3E,KAAK8F,KAAKM,WAAWL,IAE3D,MACD,IAAK,UAKH,IAHA,IAAMH,EAAcV,EAAeQ,SAASE,YAEtCS,EAAQ,GACLL,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IAAK,CAE5C,IADA,IAAMD,EAAO,GACJO,EAAI,EAAGA,EAAIV,EAAYI,GAAGC,OAAQK,IAAK,CAC/C,IAAMhJ,EAAS,IAAIqH,EAAK3E,KAAKuD,OAC5BqC,EAAYI,GAAGM,GAAG,GAClBV,EAAYI,GAAGM,GAAG,IAEnBP,EAAKI,KAAK7I,EACX,CACA+I,EAAMF,KAAKJ,EACZ,CAEAZ,EAAgBU,YAAY,IAAIlB,EAAK3E,KAAK8F,KAAKS,QAAQF,IAK3D,GAGA5B,EAAQ+B,QAAQxI,QAAQ,SAACyI,GACxB9B,EAAKtE,mBAAmBb,IAAIiH,EAAehG,IAC3CkE,EAAK1E,KAAKsB,KAAKmF,WAAWD,EAC3B,IAGDhC,EAAQ+B,QAAQxI,QAAQ,SAAC2I,GACxBhC,EAAKtE,mBAAmBb,IAAImH,EAAQlG,GACrC,GAEA,IAAMmG,EAAoB,CACzBjB,KAAM,oBACNkB,SAAQ,GAAAC,OAAMrC,EAAQ+B,UAGvBxL,KAAKiF,KAAKsB,KAAKmF,WAAWE,GAE1B5L,KAAKiF,KAAKsB,KAAKwF,SAAS,SAACJ,GACxB,IAAMK,EAAOL,EAAQM,YAAY,QAC3BC,EAAaP,EAAQQ,cAC3B,IAAKD,EACJ,MAAM,IAAIxG,MAAM,kCAEjB,IAAMiF,EAAOuB,EAAWE,UAClB3B,EAAkC,CAAE,EAE1CkB,EAAQvB,gBAAgB,SAACiC,EAAOhC,GAC/BI,EAAWJ,GAAYgC,CACxB,GAEA,IAAMC,EAAmB5C,EAAQsC,GAAM,CACtCrB,KAAM,UACND,SAAU,CACTC,KAAMA,EACNC,YAAa,IAEdH,WAAAA,IAGD,OAAQE,GACP,IAAK,QAGJ,MAAO,CACN4B,WAAW,EACXC,KAAM,CACLzB,KALWpB,EAAK/D,WAAW,EAAG,EAAG0G,EAAiBG,YAMlDC,UAAWJ,EAAiBK,WAC5BC,YAAa,EACbC,YAAaP,EAAiBQ,kBAC9BC,aAAcT,EAAiBU,kBAC/BC,SAAU,EACVC,MAAO,IAIV,IAAK,aACJ,MAAO,CACNL,YAAaP,EAAiBa,gBAC9BJ,aAAcT,EAAiBc,iBAEjC,IAAK,UACJ,MAAO,CACNP,YAAaP,EAAiBe,oBAC9BN,aAAcT,EAAiBgB,oBAC/BV,YAAaN,EAAiBiB,mBAC9Bb,UAAWJ,EAAiBkB,kBAI/B,MAAM9H,MAAM,uBACb,EACD,EAACpE,EAEOmM,YAAA,WAAWC,IAAAA,EAClB1N,KAAIA,KAAK4J,UACR5J,KAAKiF,KAAKsB,KAAKvD,QAAQ,SAAC2I,GACvB,IAAMlG,EAAKkG,EAAQgC,QACAD,EAAKrI,mBAAmBuI,IAAInI,IAE9CiI,EAAKzI,KAAKsB,KAAKS,OAAO2E,EAExB,GACA3L,KAAKqF,mBAAqB,IAAIvE,IAEhC,EAACQ,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KACpC7E,KAAA,EAAC8N,EAAAnJ,EAAAL,CAAAA,CAAAA,IAAAyJ,UAAAA,IA5bD,WAAmBC,IAAAA,EAClB,OAAOC,SAAQD,OAAAA,EAAAhO,KAAKqF,yBAAL2I,EAAAA,EAAyBE,MAAO,EAChD,KAACvJ,CAAA,CAjCsC,CAAQrE,GCAnC6N,eAAwBvJ,SAAAA,GACpC,SAAAuJ,EACC5N,GAGqBR,IAAAA,EAMsB,OAJ3CA,EAAA6E,EAAAC,KAAA7E,KAAMO,IAAOP,MAONgF,UAAIjF,EAAAA,EACJkF,YAAIlF,EACJqO,OAAuD,CAAA,EAAErO,EACzDsO,gBAAUtO,EAAAA,EACV6J,QAA0C,CAAA,EATjD7J,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKsO,WAAatO,EAAKkF,KAAKqJ,eAAevO,CAC5C,CAZoC4F,EAAAwI,EAAAvJ,GAYnC,IAAAtD,EAAA6M,EAAA5M,UAuSA4M,OAvSA7M,EAcOiN,qBAAA,SAAqBC,EAAcC,GAC1C,IACM1F,EAAQF,SAASG,cAAc,SAKrC,OAHAD,EAAME,UAAwBuF,YAAAA,EAAuBE,oBADlCD,EAFA,KAInB5F,SAASK,qBAAqB,QAAQ,GAAGC,YAAYJ,GACrD/I,KAAKiF,KAAK0J,WAAWH,GACdzF,CACR,EAACzH,EAMOsN,WAAA,WACPrE,OAAOsE,OAAO7O,KAAKoO,QAAQpL,QAAQ,SAACwL,GAC/BA,GACHA,EAAKxH,QAEP,GACAhH,KAAKoO,OAAS,CAAA,CACf,EAAC9M,EAMOmM,YAAA,WAAW,IAAAxH,EAAAjG,KAClBuK,OAAOsE,OAAO7O,KAAK4J,SAAS5G,QAAQ,SAAC8L,GACpC7I,EAAKhB,KAAK8J,YAAYD,EACvB,GACA9O,KAAK4J,QAAU,EAChB,EAACtI,EAMO0N,kBAAA,SACPtF,GAAiC,IAAAC,EAAA3J,KAEjC,MAAO,CAENiP,aAAc,SACbtD,EACAuD,GAEA,IAAKvD,EAAQlB,WACZ,MAAM,IAAI/E,MAAM,6BAEjB,GAAuC,iBAA5BiG,EAAQlB,WAAWuB,KAC7B,MAAM,IAAItG,MAAM,gCAGjB,IAEMyJ,GAAgBC,EADJ1F,EADLiC,EAAQlB,WAAWuB,OAEAL,GAC1B0D,EAASC,OAAOH,EAAcV,QAuBpC,OAtBa9E,EAAKyE,OAAOiB,KAGxB1F,EAAKyE,OAAOiB,GAAU1F,EAAK4E,qBAC1Bc,EACAF,EAAcV,SAeD9E,EAAK3E,KAAKuK,aAAaL,EAXvB,CACdM,OAAQL,EAAc1C,WACtBgD,OAAQN,EAAcnC,oBAAqB,EAC3C0C,MAAOP,EAAcrC,kBACrB6C,OAAQR,EAAcnC,kBACtBJ,YAAa,GACbF,UAAWyC,EAAcxC,WACzB6B,KAAMa,EACNO,aAAa,GAMf,EAGA7G,MAAO,SAAC8G,GACP,IAAKA,IAAaA,EAASpF,WAC1B,MAAO,CACR,EAEA,IAAMkB,EAAUkE,EAIVV,GAAgBC,EADJ1F,EADLiC,EAAQlB,WAAWuB,OAEAL,GAC1B0D,EAASC,OAAOH,EAAcV,QAUpC,OATa9E,EAAKyE,OAAOiB,KAGxB1F,EAAKyE,OAAOiB,GAAU1F,EAAK4E,qBAC1Bc,EACAF,EAAcV,SAIc,eAA1B9C,EAAQjB,SAASC,KACb,CACNiF,aAAa,EACbF,MAAOP,EAAchC,gBACrBwC,OAAQR,EAAc/B,gBACtBoB,KAAMa,GAE6B,YAA1B1D,EAAQjB,SAASC,KACpB,CACNiF,aAAa,EACbhD,YAAauC,EAAc5B,mBAC3Bb,UAAWyC,EAAc3B,iBACzBmC,OAAQR,EAAc7B,oBACtBmC,QAAQ,EACRC,MAAOP,EAAc3B,iBACrBgB,KAAMa,GAID,EACR,EAEF,EAAC/N,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GAKxBa,EAAStC,KAAKiF,KAAK6K,uBAFX,CAAEnQ,EAJK+C,EAAbX,WAIWrC,EAJiBgD,EAAbR,aAOvB,OACgB,OAAfI,EAAOE,KACPuN,MAAMzN,EAAOE,MACE,OAAfF,EAAOG,KACPsN,MAAMzN,EAAOG,KAGd,KAEO,CAAED,IAAKF,EAAOE,IAAKC,IAAKH,EAAOG,IACvC,EAACnB,EAMMO,mBAAA,WACN,YAAYwM,UACb,EAAC/M,EAMM0C,gBAAA,SAAgBD,GAClBA,EACH/D,KAAKiF,KAAK+K,SAASC,SAEnBjQ,KAAKiF,KAAK+K,SAASE,SAErB,EAAC5O,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAA0N,EAAiBnQ,KAAKiF,KAAKmL,uBAAuB,CAAE5N,IAAAA,EAAKC,IAAAA,IACzD,MAAO,CAAE9C,EADAwQ,EAADxQ,EACID,EADAyQ,EAADzQ,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAA2Q,EAAqBrQ,KAAKiF,KAAK6K,uBAAuB,CACrDnQ,EAAAA,EACAD,EAAAA,IAED,MAAO,CAAE8C,IAJE6N,EAAH7N,IAIMC,IAJE4N,EAAH5N,IAKd,EAACnB,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMuH,eAAe,UAE/CtQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GACvBA,EACH/D,KAAKiF,KAAKsL,gBAAgBN,SAE1BjQ,KAAKiF,KAAKsL,gBAAgBL,SAE5B,EAAC5O,EAOMkI,OAAA,SAAOC,EAA2BC,OAAiCgE,EAAA1N,KACzEyJ,EAAQ+B,QAAQxI,QAAQ,SAACwI,GACxBkC,EAAK9D,QAAQ4B,EAAQ/F,IAAgBiI,EAAK1I,KAAKwL,QAC9ChF,EACAkC,EAAKsB,kBAAkBtF,IAExBgE,EAAKzI,KAAKwL,SAAS/C,EAAK9D,QAAQ4B,EAAQ/F,IACzC,GAEAgE,EAAQI,WAAW7G,QAAQ,SAAC0N,GAC3BhD,EAAKzI,KAAK8J,YAAYrB,EAAK9D,QAAQ8G,GACpC,GAEAjH,EAAQQ,QAAQjH,QAAQ,SAACiH,GACxByD,EAAKzI,KAAK8J,YAAYrB,EAAK9D,QAAQK,EAAQxE,KAC3CiI,EAAK9D,QAAQK,EAAQxE,IAAgBiI,EAAK1I,KAAKwL,QAC9CvG,EACAyD,EAAKsB,kBAAkBtF,IAExBgE,EAAKzI,KAAKwL,SAAS/C,EAAK9D,QAAQK,EAAQxE,IACzC,EACD,EAACnE,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cACLzN,KAAK4O,aAEP,EAACtN,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAA7E,KAAC8C,GAEf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KAAA7E,KACpC,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KACxB7E,KAAA,EAACmO,CAAA,CAnTmCvJ,CAAQtE,GCMhCqQ,eAAyB/L,SAAAA,GACrC,SAAA+L,EAAYpQ,GAAiDR,IAAAA,EAIjB,OAH3CA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAQR,MAMP6Q,iBAAW7Q,EAAAA,EACXkF,UAAI,EAAAlF,EACJsO,gBAAU,EAAAtO,EACV8Q,WAAY,EAAK9Q,EA6IjB+Q,WAMJ,CACHC,UAAU,EACVC,QAAQ,EACRC,aAAa,EACbC,UAAU,EACVxH,SAAS,GA/JT3J,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKsO,WAAatO,EAAKkF,KAAKqJ,eAAevO,CAC5C,CANqC4F,EAAAgL,EAAA/L,GAMpC,IAAAtD,EAAAqP,EAAApP,UAmaA,OAnaAD,EAWOmM,YAAA,WAAW,IAAAxH,EAAAjG,KACdA,KAAK6Q,YACc,CAAC,QAAS,aAAc,WAChC7N,QAAQ,SAACmO,GACtB,IAAM1L,EAAW0L,MAAAA,EAAYC,cAC7BnL,EAAKhB,KAAK8J,YAAYtJ,GAIF,YAAhB0L,GACHlL,EAAKhB,KAAK8J,YAAYtJ,EAAK,YAE5BQ,EAAKhB,KAAKoM,aAAa5L,EACxB,GAEAzF,KAAK6Q,WAAY,EAGb7Q,KAAK4Q,cACRU,qBAAqBtR,KAAK4Q,aAC1B5Q,KAAK4Q,iBAAc3J,GAGtB,EAAC3F,EAEOiQ,kBAAA,SAAkB9L,EAAYoG,GACrC7L,KAAKiF,KAAKuM,UAAU/L,EAAI,CACvBkF,KAAM,UACNpE,KAAM,CACLoE,KAAM,oBACNkB,SAAUA,GAEX4F,UAAW,GAEb,EAACnQ,EAEOoQ,cAAA,SAAcjM,GACrB,OAAOzF,KAAKiF,KAAKwL,SAAS,CACzBhL,GAAAA,EACAkM,OAAQlM,EACRkF,KAAM,OAENiH,MAAO,CACN,aAAc,CAAC,MAAO,oBACtB,eAAgB,CAAC,MAAO,wBAG3B,EAACtQ,EAEOuQ,qBAAA,SAAqBpM,GAY5B,OAXczF,KAAKiF,KAAKwL,SAAS,CAChChL,GAAIA,EAAK,WACTkM,OAAQlM,EACRkF,KAAM,OAENiH,MAAO,CACN,aAAc,CAAC,MAAO,uBACtB,aAAc,CAAC,MAAO,yBAKzB,EAACtQ,EAEOwQ,cAAA,SAAcrM,GAYrB,OAXczF,KAAKiF,KAAKwL,SAAS,CAChChL,GAAAA,EACAkM,OAAQlM,EACRkF,KAAM,OAENiH,MAAO,CACN,aAAc,CAAC,MAAO,mBACtB,aAAc,CAAC,MAAO,qBAKzB,EAACtQ,EAEOyQ,eAAA,SAAetM,GActB,OAbczF,KAAKiF,KAAKwL,SAAS,CAChChL,GAAAA,EACAkM,OAAQlM,EACRkF,KAAM,SAENiH,MAAO,CACN,sBAAuB,CAAC,MAAO,qBAC/B,sBAAuB,CAAC,MAAO,qBAC/B,gBAAiB,CAAC,MAAO,cACzB,eAAgB,CAAC,MAAO,gBAK3B,EAACtQ,EAEO0Q,UAAA,SACPvM,EACAwM,GAEoB,UAAhBA,GACHjS,KAAK+R,eAAetM,GAED,eAAhBwM,GACHjS,KAAK8R,cAAcrM,GAEA,YAAhBwM,IACHjS,KAAK0R,cAAcjM,GACnBzF,KAAK6R,qBAAqBpM,GAE5B,EAACnE,EAEO4Q,iBAAA,SACPD,EACApG,GAEA,IAAMpG,QAAWwM,EAAYb,cAI7B,OAHApR,KAAKuR,kBAAkB9L,EAAIoG,GAC3B7L,KAAKgS,UAAUvM,EAAIwM,GAEZxM,CACR,EAACnE,EAEO6Q,qBAAA,SACPF,EACApG,GAEA,IAAMpG,EAAE,MAASwM,EAAYb,cAK7B,OAJCpR,KAAKiF,KAAKmN,UAAU3M,GAAY4M,QAAQ,CACxC1H,KAAM,oBACNkB,SAAUA,IAEJpG,CACR,EAACnE,EAgBOgR,iBAAA,SAAiB7I,GAAyB,IAAAE,EACjD3J,KAAA,GAAA8L,OAAIrC,EAAQQ,QAAYR,EAAQ+B,SAASxI,QAAQ,SAAC2I,GACnB,UAA1BA,EAAQjB,SAASC,KACpBhB,EAAKmH,WAAWE,QAAS,EACW,eAA1BrF,EAAQjB,SAASC,KAC3BhB,EAAKmH,WAAWG,aAAc,EACM,YAA1BtF,EAAQjB,SAASC,OAC3BhB,EAAKmH,WAAWI,UAAW,EAE7B,GAEIzH,EAAQI,WAAWoB,OAAS,IAC/BjL,KAAK8Q,WAAWC,UAAW,GAIA,IAA3BtH,EAAQ+B,QAAQP,QACW,IAA3BxB,EAAQQ,QAAQgB,QACc,IAA9BxB,EAAQI,WAAWoB,SAEnBjL,KAAK8Q,WAAWpH,SAAU,EAE5B,EAACpI,EAOMiB,mBAAA,SAAmBd,GACzB,IAAA8Q,EAAsBvS,KAAKqO,WAAWvM,wBAItC,OAAW9B,KAACwI,UAHF/G,EAAMO,QADJuQ,EAAJtQ,KAEER,EAAMU,QAFCoQ,EAAHnQ,IAKf,EAACd,EAMMO,mBAAA,WACN,OAAO7B,KAAKiF,KAAKuN,WAClB,EAAClR,EAMM0C,gBAAA,SAAgBD,GAClBA,GAGH/D,KAAKiF,KAAKwN,WAAWxC,SACrBjQ,KAAKiF,KAAKyN,QAAQzC,WAElBjQ,KAAKiF,KAAKwN,WAAWvC,UACrBlQ,KAAKiF,KAAKyN,QAAQxC,UAEpB,EAAC5O,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAAkQ,EAAiB3S,KAAKiF,KAAKmD,QAAQ,CAAE5F,IAAAA,EAAKC,IAAAA,IAC1C,MAAO,CAAE9C,EADAgT,EAADhT,EACID,EADAiT,EAADjT,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAkT,EAAqB5S,KAAKiF,KAAKuD,UAAU,CAAE7I,EAAAA,EAAGD,EAAAA,IAC9C,MAAO,CAAE8C,IADEoQ,EAAHpQ,IACMC,IADEmQ,EAAHnQ,IAEd,EAACnB,EAMMmH,UAAA,SAAUC,GAChB,IAAMmK,EAAS7S,KAAKiF,KAAKuN,YACV,UAAX9J,EACHmK,EAAO9J,MAAMuH,eAAe,UAE5BuC,EAAO9J,MAAML,OAASA,CAExB,EAACpH,EAMM8H,qBAAA,SAAqBrF,GACvBA,EACH/D,KAAKiF,KAAKsL,gBAAgBN,SAE1BjQ,KAAKiF,KAAKsL,gBAAgBL,SAE5B,EAAC5O,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAgE,EACzE1N,KAAAA,KAAKsS,iBAAiB7I,GAElBzJ,KAAK4Q,aACRU,qBAAqBtR,KAAK4Q,aAM3B5Q,KAAK4Q,YAAckC,sBAAsB,WAcxC,IAVA,IAAMjH,EAAQ,GAAAC,OACVrC,EAAQ+B,QACR/B,EAAQQ,QACRR,EAAQsJ,WAGN/B,EAAS,GACTC,EAAc,GACdC,EAAW,GAERlG,EAAI,EAAGA,EAAIa,EAASZ,OAAQD,IAAK,CACzC,IAAMW,EAAUE,EAASb,GACjBP,EAAekB,EAAflB,WAEFuI,EAAStJ,EADFe,EAAWuB,MACKL,GAEC,UAA1BA,EAAQjB,SAASC,MACpBF,EAAWkC,WAAaqG,EAAOrG,WAC/BlC,EAAWqC,kBAAoBkG,EAAOlG,kBACtCrC,EAAWuC,kBAAoBgG,EAAOhG,kBACtCvC,EAAWgC,WAAauG,EAAOvG,WAC/BuE,EAAO7F,KAAKQ,IACwB,eAA1BA,EAAQjB,SAASC,MAC3BF,EAAW0C,gBAAkB6F,EAAO7F,gBACpC1C,EAAW2C,gBAAkB4F,EAAO5F,gBACpC6D,EAAY9F,KAAKQ,IACmB,YAA1BA,EAAQjB,SAASC,OAC3BF,EAAW+C,iBAAmBwF,EAAOxF,iBACrC/C,EAAW8C,mBAAqByF,EAAOzF,mBACvC9C,EAAW4C,oBAAsB2F,EAAO3F,oBACxC5C,EAAW6C,oBAAsB0F,EAAO1F,oBACxC4D,EAAS/F,KAAKQ,GAEhB,CAEA,GAAK+B,EAAKmD,UAiBH,CAGN,IASIoC,EAPEC,EAFmBxF,EAAKoD,WAAWC,UACZrD,EAAKoD,WAAWpH,QAKvCyJ,EAAoBD,GAAexF,EAAKoD,WAAWG,YACnDmC,EAAiBF,GAAexF,EAAKoD,WAAWI,UAFjCgC,GAAexF,EAAKoD,WAAWE,UAMnDiC,EAAUvF,EAAKyE,qBACd,QACAnB,IAIEmC,GACHzF,EAAKyE,qBACJ,aACAlB,GAIEmC,GACH1F,EAAKyE,qBACJ,UACAjB,GAQF+B,GAAWvF,EAAKzI,KAAKoO,UAAUJ,EAChC,KAxDqB,CACpB,IAAMA,EAAUvF,EAAKwE,iBACpB,QACAlB,GAEDtD,EAAKwE,iBACJ,aACAjB,GAEDvD,EAAKwE,iBACJ,UACAhB,GAEDxD,EAAKmD,WAAY,EAGjBoC,GAAWvF,EAAKzI,KAAKoO,UAAUJ,EAChC,CA0CAvF,EAAKoD,WAAa,CACjBE,QAAQ,EACRC,aAAa,EACbC,UAAU,EACVH,UAAU,EACVrH,SAAS,EAEX,EACD,EAACpI,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEM4B,uBAAA,WACN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KAAA7E,KACpC,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KACxB7E,KAAA,EAACsB,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAC/B,KAAAA,GACf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAACsK,CAAA,CAzaoC/L,CAAQtE,GCNjCgT,eAA2B1O,SAAAA,GAGvC,SAAA0O,EAAY/S,GAAwC,IAAAR,EAajD,OAZFA,EAAA6E,EAAAC,UAAMtE,IAAQR,MAHPwT,qBAUPxT,EAAAA,EAAKwT,gBAAkB,IAAI5C,EAC1BpQ,GAICR,CACH,CAjBuC4F,EAAA2N,EAAA1O,GAiBtC,IAAAtD,EAAAgS,EAAA/R,UA0FA+R,OA1FAhS,EAEMlB,SAAA,SAAS0C,GACf9C,KAAKuT,gBAAgBnT,SAAS0C,EAC/B,EAACxB,EAEMnB,WAAA,WACNH,KAAKuT,gBAAgBpT,YACtB,EAACmB,EAEM4B,uBAAA,WACN,OAAWlD,KAACuT,gBAAgBrQ,wBAC7B,EAAC5B,EAOMiB,mBAAA,SAAmBd,GACzB,OAAWzB,KAACuT,gBAAgBhR,mBAAmBd,EAChD,EAACH,EAMMO,mBAAA,WACN,OAAW7B,KAACuT,gBAAgB1R,oBAC7B,EAACP,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAKuT,gBAAgBvP,gBAAgBD,EACtC,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,YAAY8Q,gBAAgBnL,QAAQ5F,EAAKC,EAC1C,EAACnB,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,OAAWM,KAACuT,gBAAgB/K,UAAU7I,EAAGD,EAC1C,EAAC4B,EAMMmH,UAAA,SAAUM,GAChB/I,KAAKuT,gBAAgB9K,UAAUM,EAChC,EAACzH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAKuT,gBAAgBnK,qBAAqBrF,EAC3C,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GACxC1J,KAAKuT,gBAAgB/J,OAAOC,EAASC,EACtC,EAACpI,EAMMoD,MAAA,WACN1E,KAAKuT,gBAAgB7O,OACtB,EAAC4O,CAAA,CA3GsC1O,CAAQtE,GCkCzC,MAAMkT,EAAkB,CAE7BC,QAAW,SAAW,EAAIrU,KAAKsU,IAC/BC,QAAY,EAAIvU,KAAKsU,GAAK,QAAW,IACrCE,GAAM,MACNC,EAAK,EACL,QAAS,KAAO,MC4NlB,IAAAC,EA3NA,MAIE,WAAAC,CAAYC,GAKVhU,KAAKiU,MAAQD,EAAQE,KASrBlU,KAAKmU,OAAoDH,EAAa,MAStEhU,KAAKoU,aAA6BnN,IAAnB+M,EAAQK,OAAuBL,EAAQK,OAAS,KAS/DrU,KAAKsU,kBACqBrN,IAAxB+M,EAAQO,YAA4BP,EAAQO,YAAc,KAM5DvU,KAAKwU,sBACyBvN,IAA5B+M,EAAQS,gBAAgCT,EAAQS,gBAAkB,MAMpEzU,KAAK0U,aAA6BzN,IAAnB+M,EAAQW,QAAuBX,EAAQW,OAMtD3U,KAAK4U,aAAe5U,KAAK0U,UAAW1U,KAAKoU,SAMzCpU,KAAK6U,wBAA0Bb,EAAQc,mBAMvC9U,KAAK+U,iBAAmB,KAMxB/U,KAAKgV,eAAiBhB,EAAQiB,aAC/B,CAKD,QAAAC,GACE,OAAOlV,KAAK4U,SACb,CAOD,OAAAO,GACE,OAAOnV,KAAKiU,KACb,CAOD,SAAAmB,GACE,OAAOpV,KAAKoU,OACb,CAOD,QAAAiB,GACE,OAAOrV,KAAKmU,MACb,CASD,gBAAAmB,GACE,OAAOtV,KAAKgV,gBAAkBxB,EAAgBxT,KAAKmU,OACpD,CAOD,cAAAoB,GACE,OAAOvV,KAAKsU,YACb,CAaD,kBAAAkB,GACE,OAAOxV,KAAKwU,gBACb,CAOD,QAAAiB,GACE,OAAOzV,KAAK0U,OACb,CAOD,SAAAgB,CAAUf,GACR3U,KAAK0U,QAAUC,EACf3U,KAAK4U,aAAeD,IAAU3U,KAAKoU,QACpC,CAKD,kBAAAuB,GACE,OAAO3V,KAAK+U,gBACb,CAKD,kBAAAa,CAAmBC,GACjB7V,KAAK+U,iBAAmBc,CACzB,CAOD,SAAAC,CAAUzB,GACRrU,KAAKoU,QAAUC,EACfrU,KAAK4U,aAAe5U,KAAK0U,UAAWL,EACrC,CAQD,cAAA0B,CAAexB,GACbvU,KAAKsU,aAAeC,CACrB,CAQD,qBAAAyB,CAAsBC,GACpBjW,KAAK6U,wBAA0BoB,CAChC,CAOD,sBAAAC,GACE,OAAOlW,KAAK6U,uBACb,GChQI,MAAMsB,EAAS,QAMTC,EAAYhX,KAAKsU,GAAKyC,EAMtBE,EAAS,EAAED,GAAYA,EAAWA,EAAWA,GAM7CE,EAAe,EAAE,KAAM,GAAI,IAAK,IAOhCC,EAAaJ,EAAS/W,KAAKoX,IAAIpX,KAAKqX,IAAIrX,KAAKsU,GAAK,IAM/D,MAAMgD,UAA2BC,EAI/B,WAAA5C,CAAYG,GACV0C,MAAM,CACJ1C,KAAMA,EACN2C,MAAO,IACPxC,OAAQgC,EACR1B,QAAQ,EACRJ,YAAa+B,EACbxB,mBAAoB,SAAUgC,EAAYzO,GACxC,OAAOyO,EAAa1X,KAAK2X,KAAK1O,EAAM,GAAK8N,EAC1C,GAEJ,EASI,MAAMa,EAAc,CACzB,IAAIN,EAAmB,aACvB,IAAIA,EAAmB,eACvB,IAAIA,EAAmB,eACvB,IAAIA,EAAmB,eACvB,IAAIA,EAAmB,8CACvB,IAAIA,EAAmB,iDCrDZL,EAAS,EAAE,KAAM,GAAI,IAAK,IAM1B7C,EAdS,QAcUpU,KAAKsU,GAAe,IAUpD,MAAMuD,UAA2BN,EAK/B,WAAA5C,CAAYG,EAAMO,GAChBmC,MAAM,CACJ1C,KAAMA,EACN2C,MAAO,UACPxC,OAAQgC,EACR5B,gBAAiBA,EACjBE,QAAQ,EACRM,cAAezB,EACfe,YAAa8B,GAEhB,EASI,MAAMW,EAAc,CACzB,IAAIC,EAAmB,UACvB,IAAIA,EAAmB,YAAa,OACpC,IAAIA,EAAmB,iCACvB,IAAIA,EAAmB,4BACvB,IAAIA,EAAmB,gDACvB,IAAIA,EAAmB,+CAAgD,OACvE,IAAIA,EAAmB,6CAA8C,QC3DvE,IAAIC,EAAQ,CAAA,ECERC,EAAa,CAAA,EAiBV,SAAS3S,EAAImN,EAAQyF,EAAaC,GACvC,MAAMC,EAAa3F,EAAOwD,UACpBoC,EAAkBH,EAAYjC,UAC9BmC,KAAcH,IAClBA,EAAWG,GAAc,IAE3BH,EAAWG,GAAYC,GAAmBF,CAC5C,CCmFO,SAASG,EAAeC,EAAOC,GACpC,QAAezQ,IAAXyQ,EACF,IAAK,IAAI1M,EAAI,EAAG2M,EAAKF,EAAMxM,OAAQD,EAAI2M,IAAM3M,EAC3C0M,EAAO1M,GAAKyM,EAAMzM,QAIpB0M,EAASD,EAAMG,QAEjB,OAAOF,CACT,CAOO,SAASG,EAAkBJ,EAAOC,GACvC,QAAezQ,IAAXyQ,GAAwBD,IAAUC,EAAQ,CAC5C,IAAK,IAAI1M,EAAI,EAAG2M,EAAKF,EAAMxM,OAAQD,EAAI2M,IAAM3M,EAC3C0M,EAAO1M,GAAKyM,EAAMzM,GAEpByM,EAAQC,CACT,CACD,OAAOD,CACT,CASO,SAASK,EAAc/P,IFpHvB,SAAamM,EAAMnM,GACxBmP,EAAMhD,GAAQnM,CAChB,CEmHEgQ,CAAQhQ,EAAWoN,UAAWpN,GAC9BiQ,EAAiBjQ,EAAYA,EAAYyP,EAC3C,CAkBO,SAASzJ,EAAIkK,GAClB,MAAiC,iBAAnBA,EFrJZf,EAFgBhD,EEwJiB,IFrJjCgD,EAAMhD,EAAKgE,QAAQ,yCAA0C,aAC7D,KEqJ4B,GAAoB,KFzJ7C,IAAahE,CE0JpB,CAoFO,SAASiE,EAAyBC,IArGlC,SAAwBA,GAC7BA,EAAYpV,QAAQ8U,EACtB,CAoGEO,CAAeD,GACfA,EAAYpV,QAAQ,SAAU2O,GAC5ByG,EAAYpV,QAAQ,SAAUoU,GACxBzF,IAAWyF,GACbY,EAAiBrG,EAAQyF,EAAaI,EAE9C,EACA,EACA,CA0OO,SAASc,EAAUpN,EAAYyG,EAAQyF,GAC5C,MAAMmB,EArBD,SAAsB5G,EAAQyF,GAGnC,OA1BK,SACLoB,EACAC,GAIA,IAAIF,EDpZC,SAAajB,EAAYC,GAC9B,IAAIe,EAIJ,OAHIhB,KAAcH,GAAcI,KAAmBJ,EAAWG,KAC5DgB,EAAYnB,EAAWG,GAAYC,IAE9Be,CACT,CC8YsBI,CAFDF,EAAiBrD,UACZsD,EAAsBtD,WAK9C,OAHKoD,IACHA,EAAgBV,GAEXU,CACT,CAeSI,CAFkB5K,EAAI4D,GACC5D,EAAIqJ,GAEpC,CAiBwBwB,CAAajH,EAAQyF,GAC3C,OAAOmB,EAAcrN,OAAYjE,EAAWiE,EAAWD,OACzD,CAsOO,IAlcL4N,EACAC,EACAC,EAmcAZ,EAAyBa,GACzBb,EAAyBc,GAtczBJ,EA2cEG,EA1cFF,EJ3MK,SAAsBrB,EAAOC,EAAQwB,GAC1C,MAAMjO,EAASwM,EAAMxM,OACrBiO,EAAYA,EAAY,EAAIA,EAAY,OACzBjS,IAAXyQ,IAGAA,EAFEwB,EAAY,EAELzB,EAAMG,QAEN,IAAIhV,MAAMqI,IAGvB,IAAK,IAAID,EAAI,EAAGA,EAAIC,EAAQD,GAAKkO,EAAW,CAC1CxB,EAAO1M,GAAMoL,EAAYqB,EAAMzM,GAAM,IACrC,IAAItL,EAAIyW,EAAS/W,KAAKoX,IAAIpX,KAAKqX,IAAKrX,KAAKsU,KAAO+D,EAAMzM,EAAI,GAAK,IAAO,MAClEtL,EAAI6W,EACN7W,EAAI6W,EACK7W,GAAK6W,IACd7W,GAAK6W,GAEPmB,EAAO1M,EAAI,GAAKtL,CACjB,CACD,OAAOgY,CACT,EIsLEqB,EJ5KK,SAAoBtB,EAAOC,EAAQwB,GACxC,MAAMjO,EAASwM,EAAMxM,OACrBiO,EAAYA,EAAY,EAAIA,EAAY,OACzBjS,IAAXyQ,IAGAA,EAFEwB,EAAY,EAELzB,EAAMG,QAEN,IAAIhV,MAAMqI,IAGvB,IAAK,IAAID,EAAI,EAAGA,EAAIC,EAAQD,GAAKkO,EAC/BxB,EAAO1M,GAAM,IAAMyM,EAAMzM,GAAMoL,EAC/BsB,EAAO1M,EAAI,GACR,IAAM5L,KAAK+Z,KAAK/Z,KAAKga,IAAI3B,EAAMzM,EAAI,GAAKmL,IAAY/W,KAAKsU,GAAK,GAEnE,OAAOgE,CACT,EImmBIuB,EAtcWjW,QAAQ,SAAUqW,GAC7BR,EAAa7V,QAAQ,SAAUsW,GAC7BtB,EAAiBqB,EAAaC,EAAaR,GAC3Cd,EAAiBsB,EAAaD,EAAaN,EACjD,EACA,GCpQa,ICuDDQ,EDvDCC,wBAA2B5U,GACvC,SAAA4U,EACCjZ,GAGqBR,IAAAA,GAErBA,EAAA6E,EAAAC,UAAMtE,IAAQR,MA8BP0Z,gBAAkB,WAAO,MAAA,CAAA,CAAE,EAAC1Z,EAE5BiF,UAAIjF,EAAAA,EACJkF,UAAI,EAAAlF,EACJsO,gBAAUtO,EAAAA,EACV2Z,iBAAW,EAAA3Z,EACX4Z,qBAAa5Z,EACb6Z,oBAAc,EAnCrB7Z,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKiF,KAAOzE,EAAO+E,IAEnBvF,EAAK6Z,eAAiB,IAAI7Z,EAAKiF,KAAK6U,QACpC9Z,EAAK2Z,YAAc,eAAAI,EAAA,OACW,OADXA,EAClB/Z,EAAKiF,KAAK+U,qBAAmBD,EAAI,IAAInD,EAAW,CAAEzC,KAAM,aAAc,EAEvEnU,EAAKsO,WAAatO,EAAKkF,KAAK+U,cAG5Bja,EAAKsO,WAAW4L,aAAa,WAAY,KAEzC,IAAMC,EAAe,IAAIna,EAAKiF,KAAKmV,aAAa,CAC/CtO,SAAU,KAGX9L,EAAK4Z,cAAgBO,EAIrB,IAAME,EAAc,IAAIra,EAAKiF,KAAKqV,YAAY,CAC7C1I,OAAQuI,EACRnR,MAAO,SAAC4C,GAAY,OAAA5L,EAAKua,UAAU3O,EAAS5L,EAAK0Z,kBAAkB,IAGpC,OAAhC1Z,EAAKkF,KAAKwL,SAAS2J,GAAara,CACjC,CAnCuC4F,EAAA6T,EAAA5U,GAmCtC,IAAAtD,EAAAkY,EAAAjY,UAkQAiY,OAlQAlY,EAgBOiZ,SAAA,SAASC,GAChB,MAAO,CACNzU,EAAG0U,SAASD,EAAI5C,MAAM,EAAG,GAAI,IAC7B8C,EAAGD,SAASD,EAAI5C,MAAM,EAAG,GAAI,IAC7B+C,EAAGF,SAASD,EAAI5C,MAAM,EAAG,GAAI,IAE/B,EAACtW,EAEOgZ,UAAA,SAAU3O,EAAsBjC,OAAiCzD,EAAAjG,KAClE0K,EAAWiB,EAAQQ,cACzB,GAAKzB,EAKL,MAAO,CACN5C,MAAO,SAAC6D,GACP,IAAMlB,EAAakB,EAAQiP,gBACrB7R,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,QAASC,YAAa,IACxCH,WAAAA,IAED,OAAO,IAAIxE,EAAKjB,KAAK6V,MAAM,CAC1BC,MAAO,IAAI7U,EAAKjB,KAAK+V,OAAO,CAC3BvL,OAAQzG,EAAM0D,WACduO,KAAM,IAAI/U,EAAKjB,KAAKiW,KAAK,CACxBvL,MAAO3G,EAAM4D,aAEd8C,OAAQ,IAAIxJ,EAAKjB,KAAKkW,OAAO,CAC5BxL,MAAO3G,EAAM+D,kBACbqO,MAAOpS,EAAMiE,uBAIjB,EACA5B,WAAY,SAACO,GACZ,IAAMlB,EAAakB,EAAQiP,gBACrB7R,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,aAAcC,YAAa,IAC7CH,WAAAA,IAED,OAAW,IAAAxE,EAAKjB,KAAK6V,MAAM,CAC1BpL,OAAQ,IAAIxJ,EAAKjB,KAAKkW,OAAO,CAC5BxL,MAAO3G,EAAMoE,gBACbgO,MAAOpS,EAAMqE,mBAGhB,EACA7B,QAAS,SAACI,GACT,IAAMlB,EAAakB,EAAQiP,gBACrB7R,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,UAAWC,YAAa,IAC1CH,WAAAA,IAED2Q,EAAoBnV,EAAKsU,SAASxR,EAAMyE,kBAAhCzH,EAACqV,EAADrV,EAAG2U,EAACU,EAADV,EAAGC,EAACS,EAADT,EAEd,OAAW,IAAA1U,EAAKjB,KAAK6V,MAAM,CAC1BpL,OAAQ,IAAIxJ,EAAKjB,KAAKkW,OAAO,CAC5BxL,MAAO3G,EAAMsE,oBACb8N,MAAOpS,EAAMuE,sBAEd0N,KAAM,IAAI/U,EAAKjB,KAAKiW,KAAK,CACxBvL,MAAe3J,QAAAA,EAAK2U,IAAAA,MAAKC,EAAC,IAAI5R,EAAMwE,0BAGvC,GAvDW7C,EAAS0B,WAwDdT,EACR,EAACrK,EAMOmM,YAAA,WACHzN,KAAK2Z,eACR3Z,KAAK2Z,cAAcjV,OAErB,EAACpD,EAEO+Z,WAAA,SAAW1P,GAClB,IAAM2P,EAAYtb,KAAK4Z,eAAe2B,YAAY5P,EAAS,CAC1D6P,eAAgB,YAChBC,kBAAmBzb,KAAK0Z,gBAEzB1Z,KAAK2Z,cAAc0B,WAAWC,EAC/B,EAACha,EAEOoa,cAAA,SAAcjW,GACrB,IAAMiL,EAAU1Q,KAAK2Z,cAAc3P,eAAevE,GAC7CiL,GAGL1Q,KAAK2Z,cAAc+B,cAAchL,EAClC,EAACpP,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GADV9B,EAAC+C,EAAbX,WAA2BrC,EAACgD,EAAbR,WAEvB,IACC,OAAOlC,KAAKwI,UAAU7I,EAAGD,EAC1B,CAAE,MAAOic,GACR,OAAO,IACR,CACD,EAACra,EAMMO,mBAAA,WACN,IAAM+Z,EAAW5b,KAAKqO,WAAWwN,iBAAiB,UAElD,GAAID,EAAS3Q,OAAS,EACrB,MAAMvF,MACL,+DAIF,OAAOkW,EAAS,EACjB,EAACta,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAKiF,KAAK6W,kBAAkB9Y,QAAQ,SAAC+Y,GACC,YAAjCA,EAAYhI,YAAY9T,MAC3B8b,EAAYC,UAAUjY,EAExB,EACD,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IDoKqCsF,ECpKrCkU,EAAejc,KAAKiF,KAAKiX,uBDsKlB5D,ECrKK,CAAC9V,EAAKC,GDuKhB,iBACewE,KALoBc,ECnKb/H,KAAK0Z,eDwKA3R,EAAa,cCtK1C,MAAO,CAAEpI,EAHDsc,EAAEvc,GAGEA,EAHDuc,EAAA,GAIZ,EAAC3a,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAyc,EDyKK,SAAkBjR,EAAYnD,GACnC,MAAMqU,EAAS9D,EACbpN,OACejE,IAAfc,EAA2BA,EAAa,YACxC,aAEIsU,EAAMD,EAAO,GAInB,OAHIC,GAAO,KAAOA,EAAM,OACtBD,EAAO,GG5RJ,SAAgBE,EAAG3B,GACxB,MAAM5U,EAAIuW,EH2RsB,IG1RhC,OH0RgC,IG1RzBvW,EAAQ,EAAIA,EH0Ra,IG1RLA,CAC7B,CHyRgBwW,CAAOF,EAAM,KAAY,KAEhCD,CACT,CCpLqBI,CAClBxc,KAAKiF,KAAKwX,uBAAuB,CAAC9c,EAAGD,IACrCM,KAAK0Z,eAEN,MAAO,CAAElX,IAJC2Z,EAAE1Z,GAIEA,IAJC0Z,EAAA,GAKhB,EAAC7a,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMuH,eAAe,UAE/CtQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAKiF,KAAK6W,kBAAkB9Y,QAAQ,SAAU+Y,GACR,oBAAjCA,EAAYhI,YAAY9T,MAC3B8b,EAAYC,UAAUjY,EAExB,EACD,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAC,EACzE3J,KAAAA,KAAKyZ,gBAAkB,WAAM,OAAA/P,CAAO,EAEpCD,EAAQI,WAAW7G,QAAQ,SAACyC,GAC3BkE,EAAK+R,cAAcjW,EACpB,GAEAgE,EAAQQ,QAAQjH,QAAQ,SAAC2I,GACxBhC,EAAK+R,cAAc/P,EAAQlG,IAC3BkE,EAAK0R,WAAW1P,EACjB,GAEAlC,EAAQ+B,QAAQxI,QAAQ,SAAC2I,GACxBhC,EAAK0R,WAAW1P,EACjB,EACD,EAACrK,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAC/B,KAAAA,GACf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEM4B,uBAAA,WACN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KAAA7E,KACpC,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KAAA7E,KACxB,EAACwZ,CAAA,EArS8ClZ,GGDnCoc,eAA8B,SAAA9X,GAa1C,SAAA8X,EACCnc,GAGqB,IAAAR,EAWqB,OAT1CA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAQR,MAlBEiF,UAAIjF,EAAAA,EACJ4c,cAAQ5c,EAAAA,EACRsO,gBAAUtO,EAAAA,EACV6c,wBAA0B,SAAQ7c,EAClC8c,kBAAoB,sBAAqB9c,EACzC+c,mBAAa/c,EAAAA,EAEtBgd,cAAe,EAAIhd,EACnBid,cAAe,EAAIjd,EACnBkd,kBAAY,EAAAld,EACZmd,yBAAmB,EAU1Bnd,EAAK4c,SAAWpc,EAAOgF,IACvBxF,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKsO,WAAatO,EAAK4c,SAASQ,UAChCpd,EAAK+c,cAAgB,IAAI/c,EAAKiF,KAAKoY,cAAc,CAChD3X,GAAI1F,EAAK8c,oBAGV9c,EAAK4c,SAASpX,IAAIf,IAAIzE,EAAK+c,eAAe/c,CAC3C,CA7B0C4F,EAAA+W,EAAA9X,GA6BzC,IAAAtD,EAAAob,EAAAnb,UAkNAmb,OAlNApb,EAEMlB,SAAA,SAAS0C,GAA6B,IAAAmD,EAAAjG,KAC5C4E,EAAArD,UAAMnB,SAAQyE,KAAC/B,KAAAA,GAEf9C,KAAKid,aAAejd,KAAK2c,SAASU,GAAG,OAAQ,SAAC5b,GACxCwE,EAAK8W,cACTtb,EAAM6b,iBAER,GACAtd,KAAKkd,oBAAsBld,KAAK2c,SAASU,GAAG,eAAgB,SAAC5b,GACvDwE,EAAK+W,cACTvb,EAAM6b,iBAER,GAEAtd,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEMnB,WAAA,WACNyE,EAAArD,UAAMpB,WAAU0E,KAAA7E,MAEZA,KAAKid,cACRjd,KAAKid,aAAajW,SAGfhH,KAAKkd,qBACRld,KAAKkd,oBAAoBlW,QAE3B,EAAC1F,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KACpC7E,KAAA,EAACsB,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GAC9B,OAAWzB,KAACwI,UAFS9F,EAAbX,WAA4BW,EAAbR,WAGxB,EAACZ,EAMMO,mBAAA,WACN,OAAW7B,KAACqO,WAAWlG,cAAc,qBACtC,EAAC7G,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAK+c,aAAehZ,CACrB,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAM4F,EAAQ,IAAQrI,KAACgF,KAAK8C,MAAM,CAAEyV,UAAW/a,EAAKgb,SAAU/a,IAC9Dgb,EAAiBzd,KAAK2c,SAASe,SAASrV,GACxC,MAAO,CAAE1I,EADA8d,EAAD9d,EACID,EADA+d,EAAD/d,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAie,EAAgC3d,KAAK2c,SAASiB,MAAM,CAAEje,EAAAA,EAAGD,EAAAA,IACzD,MAAO,CAAE8C,IADkBmb,EAATJ,UACO9a,IADTkb,EAARH,SAET,EAAClc,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMuH,eAAe,UAE/CtQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAKgd,aAAejZ,CACrB,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiCC,IAAAA,OACzEF,EAAQ+B,QAAQxI,QAAQ,SAACyI,GACxB9B,EAAK0R,WAAW5P,EAAgB/B,EACjC,GAEAD,EAAQQ,QAAQjH,QAAQ,SAACkH,GACxBP,EAAKkU,kBAAkB3T,EAAezE,IACtCkE,EAAK0R,WAAWnR,EAAgBR,EACjC,GAEAD,EAAQI,WAAW7G,QAAQ,SAAC8G,GAC3BH,EAAKkU,kBAAkB/T,EACxB,EACD,EAACxI,EAMMoD,MAAA,WACN1E,KAAK8c,cAAcgB,SAASC,WAC7B,EAACzc,EAEOuc,kBAAA,SAAkBpY,GAA+BiI,IAAAA,EACxD1N,KAAM2L,EAAU3L,KAAK8c,cAAcgB,SAASpX,KAC3C,SAACgU,GAAM,OAAAA,EAAEsD,WAAWtQ,EAAKkP,2BAA6BnX,CAAE,GAEzDzF,KAAK8c,cAAc9V,OAAO2E,EAC3B,EAACrK,EAEO+Z,WAAA,SACP1P,EACAjC,GAAiC,IAAAuU,EAEjCC,EAA8BvS,EAAQjB,SAA9BE,EAAWsT,EAAXtT,YAAaD,EAAIuT,EAAJvT,KACf5B,EAAQW,EAAQiC,EAAQlB,WAAWuB,MAAgBL,GAErDwS,OAA6BlX,EAC7ByD,OAAiCzD,EAErC,OAAQ0D,GACP,IAAK,QACJD,EAAW,IAAI1K,KAAKgF,KAAK8C,MAAM,CAC9B0V,SAAU5S,EAAY,GACtB2S,UAAW3S,EAAY,KAExBuT,EAAS,IAAQne,KAACgF,KAAKoZ,mBAAmB,CACzC1O,MAAO1P,KAAKqe,gBAAgBtV,EAAM4D,YAClCuB,KAAyB,EAAnBnF,EAAM0D,WAAiB,KAC7B6R,QAAS,CACR5O,MAAO1P,KAAKqe,gBAAgBtV,EAAM+D,mBAClCqO,MAAOpS,EAAMiE,kBAAoB,QAGnC,MACD,IAAK,aACJtC,EAAW,IAAI1K,KAAKgF,KAAKuZ,SAAS,CAAElT,MAAO,CAACT,KAC5CuT,EAAS,IAAIne,KAAKgF,KAAKwZ,iBAAiB,CACvC9O,MAAO1P,KAAKqe,gBAAgBtV,EAAMoE,iBAClCgO,MAAOpS,EAAMqE,gBAAkB,OAEhC,MACD,IAAK,UACJ1C,EAAW,IAAI1K,KAAKgF,KAAKuG,QAAQ,CAAEkT,MAAO7T,IAC1CuT,EAAS,IAAIne,KAAKgF,KAAK0Z,iBAAiB,CACvChP,MAAO1P,KAAKqe,gBACXtV,EAAMyE,iBACNzE,EAAMwE,oBAEP+Q,QAAS,CACR5O,MAAO1P,KAAKqe,gBAAgBtV,EAAMsE,qBAClC8N,MAAOpS,EAAMuE,oBAAsB,QAMvC,IAAMqR,EAAU,IAAQ3e,KAACgF,KAAK4Z,QAAQ,CACrClU,SAAAA,EACAyT,OAAAA,EACAH,YAAUC,EAAA,CAAA,EAAAA,EAAKje,KAAK4c,yBAA0BjR,EAAQlG,GAAEwY,KAI5C,UAATtT,EACH3K,KAAK8c,cAAcgB,SAAStZ,IAAIma,GAEhC3e,KAAK8c,cAAcgB,SAAStZ,IAAIma,EAAS,EAE3C,EAACrd,EAEO+c,gBAAA,SAAgBQ,EAAkBC,GACzC,IAAMpP,EAAQ1P,KAAKgF,KAAK+Z,MAAMC,QAAQH,GAItC,OAHIC,IACHpP,EAAM4M,EAAIwC,GAEJpP,CACR,EAACgN,CAAA,CA/OyC,CAAQpc,IFwDnD,SAAYiZ,GACXA,EAAA,OAAA,SACAA,EAAA,YAAA,cACAA,EAAA,OAAA,QACA,CAJD,CAAYA,IAAAA,EAIX,CAAA,IAqEY,IGnID0F,EHmICC,EACF,WADEA,EAED,WAICC,EACG,eIzJhB,SAASC,EACRzT,GAEA,OAAOsC,QACNtC,GACoB,iBAAZA,GACK,OAAZA,IACC/I,MAAMyc,QAAQ1T,GAElB,UASgB2T,EAAiBC,GAChC,IARD,SAAqBA,GACpB,MACsB,iBAAdA,IACNxP,MAAM,IAAIyP,KAAKD,GAAqBE,UAEvC,CAGMC,CAAYH,GAChB,MAAM,IAAI7Z,MA/Be,oDAkC1B,OACD,CAAA,EDTA,SAAYuZ,GACXA,EAAA,QAAA,UACAA,EAAA,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,OAAA,QACA,CALD,CAAYA,IAAAA,EAKX,CAAA,QASqBU,eAAqBre,WAAAA,IAAAA,EAAAqe,EAAApe,UAmC1C,SAAAoe,EAAY3L,GAA4BhU,KAlC9B4f,YAAM,EAAA5f,KAQN6f,aAAO,EAAA7f,KAaP8f,UAAqC,GACrCC,KAAAA,cACAC,EAAAA,KAAAA,qBACA3e,EAAAA,KAAAA,yBACA4e,EAAAA,KAAAA,mBACAC,EAAAA,KAAAA,WACA9W,EAAAA,KAAAA,iCACAZ,eAAS,EAAAxI,KACToI,aAAO,EAAApI,KACPyI,eAAS,EAAAzI,KAET+H,gBAAU,EAAA/H,KAapB2K,KAAOsU,EAAUkB,QAAOngB,KACxBgM,KAAO,OAXNhM,KAAK4f,OAAS,eACd5f,KAAK6f,QACJ7L,GAAWA,EAAQhB,OAAMoN,EAAA,CAAA,EAAQpM,EAAQhB,QAAY,CAAiB,EACvEhT,KAAKggB,gBAAmBhM,GAAWA,EAAQgM,iBAAoB,GAE/DhgB,KAAK+f,SAAW/L,GAAWA,EAAQqM,WAEnCrgB,KAAK+H,WAAciM,GAAWA,EAAQjM,YAAe,cACtD,QA5C0CzG,EAgChCgf,kBAAA,SAAkBC,GAAwC,EAYnEjf,EAKSkf,WAAA,WACT,GAAoB,YAAhBxgB,KAAK4f,OAGR,MAAU,IAAAla,MAAM,iDAFhB1F,KAAK4f,OAAS,SAIhB,EAACte,EAESmf,WAAA,WACT,GACiB,YAAhBzgB,KAAK4f,QACW,eAAhB5f,KAAK4f,QACW,YAAhB5f,KAAK4f,QACW,cAAhB5f,KAAK4f,OAKL,MAAU,IAAAla,MAAM,iDAHhB1F,KAAK4f,OAAS,UACd5f,KAAKoJ,sBAAqB,EAI5B,EAAC9H,EAESof,WAAA,WACT,GAAoB,YAAhB1gB,KAAK4f,OAIR,MAAU,IAAAla,MAAM,sCAHhB1F,KAAK4f,OAAS,UACd5f,KAAKoJ,sBAAqB,EAI5B,EAAC9H,EAEDlB,SAAA,SAASG,GACR,GAAoB,iBAAhBP,KAAK4f,OAwBR,MAAM,IAAIla,MAAM,gDAvBhB1F,KAAK4f,OAAS,aACd5f,KAAKkgB,MAAQ3f,EAAO2f,MACpBlgB,KAAKkgB,MAAMS,iBAAiBpgB,EAAOqgB,UACnC5gB,KAAKoJ,qBAAuB7I,EAAO6I,qBACnCpJ,KAAKoI,QAAU7H,EAAO6H,QACtBpI,KAAKwI,UAAYjI,EAAOiI,UACxBxI,KAAK6gB,SAAWtgB,EAAOsgB,SACvB7gB,KAAK8gB,WAAavgB,EAAOugB,WACzB9gB,KAAKyI,UAAYlI,EAAOkI,UACxBzI,KAAKigB,cAAgB1f,EAAOqgB,SAC5B5gB,KAAK+gB,SAAWxgB,EAAOwgB,SACvB/gB,KAAKqB,oBAAsBd,EAAOc,oBAElCrB,KAAKsgB,kBAAkB,CACtBtU,KAAMzL,EAAOyL,KACbkU,MAAOlgB,KAAKkgB,MACZ9X,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBwX,gBAAiBhgB,KAAKggB,gBACtB3e,oBAAqBd,EAAOc,oBAC5B0G,WAAY/H,KAAK+H,YAKpB,EAACzG,EAED0f,gBAAA,SAAgBrV,GACf,GAAoB,iBAAhB3L,KAAK4f,OACR,MAAM,IAAIla,MAAM,2BAGjB,IAAMub,ECrHQ,SACftV,EACAuV,GAEA,IAAIC,EACJ,GAAK/B,EAASzT,MAEHA,QAAQlG,GAClB0b,EA/Ce,yBAgDL,GAAsB,iBAAfxV,EAAQlG,IAAyC,iBAAfkG,EAAQlG,GAC3D0b,EA7CyB,+DA8CdD,EAAUvV,EAAQlG,OAElB2Z,EAASzT,EAAQjB,UAEtB,GAAK0U,EAASzT,EAAQlB,YAEtB,GAC2B,iBAA1BkB,EAAQjB,SAASC,MACvB,CAAC,UAAW,aAAc,SAASyW,SAASzV,EAAQjB,SAASC,MAGxD,GAAK/H,MAAMyc,QAAQ1T,EAAQjB,SAASE,kBAGzCe,EAAQlB,WAAWuB,MACe,iBAA5BL,EAAQlB,WAAWuB,KAE1B,MAAM,IAAItG,MAzDU,oDAoDpByb,EArD6B,2CAmD7BA,EApD4B,mDA+C5BA,EAhDuB,iCA8CvBA,EA/CqB,+BA6CrBA,EA9CkB,6DAwClBA,EA5CmB,wBAqEpB,GAAIA,EACH,MAAM,IAAIzb,MAAMyb,GAGjB,OACD,CAAA,CDiF4BE,CACzB1V,EACA3L,KAAKkgB,MAAMoB,WAAWJ,WAIvB,OAAIlhB,KAAK+f,SACG/f,KAAC+f,SAASpU,EAAiC,CACrDvD,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAYiI,cAInBP,CACR,EAAC3f,EAODyf,SAAA,SAASU,EAAuBC,GAA4B,EAAApgB,EAC5Dwf,WAAA,SAAWa,GAA2B,EAAArgB,EACtCuf,SAAA,SAASe,GAAqB,EAAItgB,EAClCmD,UAAA,SAAUhD,GAAiC,EAAAH,EAC3CiD,QAAA,SAAQ9C,GAA6B,EAAIH,EACzCkC,YAAA,SAAY/B,GAA8B,EAAAH,EAC1C+C,QAAA,SAAQ5C,GAA0B,EAAIH,EACtCwC,YAAA,SACCrC,EACAogB,KACGvgB,EACJ4C,OAAA,SACCzC,EACAogB,GACG,EAAAvgB,EACJ8C,UAAA,SACC3C,EACAogB,KACGvgB,EAEMwgB,wBAAA,SACTzV,EACA0V,EACApW,GAEA,OAAO3L,KAAKgiB,gBAAgB3V,EAAO0V,EAAcpW,EAClD,EAACrK,EAES2gB,uBAAA,SACT5V,EACA0V,EACApW,GAEA,OAAW3L,KAACgiB,gBAAgB3V,EAAO0V,EAAcpW,EAClD,EAACrK,EAEO0gB,gBAAA,SACP3V,EACA0V,EACApW,GAEA,YAAc1E,IAAVoF,EACI0V,EACoB,mBAAV1V,EACVA,EAAMV,GAENU,CAET,EAACyB,EAAA6R,EAAArb,CAAAA,CAAAA,IAAAyJ,QAAAA,IAvLD,WACC,OAAO/N,KAAK4f,MACb,EAACsC,IACD,SAAUvG,GACT,UAAUjW,MAAM,yCACjB,GAACpB,CAAAA,IAAAyJ,SAAAA,IAID,WACC,OAAO/N,KAAK6f,OACb,EAACqC,IACD,SAAWxY,GACV,GAAuB,iBAAZA,EACV,MAAM,IAAIhE,MAAM,6BAEjB1F,KAAKigB,cAAc,GAAI,WACvBjgB,KAAK6f,QAAUnW,CAChB,KAACiW,CAAA,CApByCre,GA4LrB6gB,eAEpB,SAAAC,GAAA,SAAAD,IAAAE,IAAAtiB,IAAAA,EAAAsiB,EAAAC,UAAArX,OAAAsX,EAAA3f,IAAAA,MAAAyf,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAAD,EAAAC,GAAAF,UAAAE,GAC6B,OAD7BziB,EAAAqiB,EAAAvd,KAAA4d,MAAAL,EAAAtW,CAAAA,MAAAA,OAAAyW,WACM5X,KAAOsU,EAAUyD,OAAM3iB,CAAA,CAAA,OAD7B4F,EAAAwc,EAAAC,GAC6BD,CAAA,CAD7B,CAAQxC,GEzOM,SAAAgD,EACfnjB,EACAC,GAEA,IAAMmjB,EAAY,SAACC,GAAgB,OAAMA,EAAWzjB,KAAKsU,GAAM,GAAG,EAE5DoP,EAASF,EAAUpjB,EAAS,IAC5BujB,EAAYH,EAAUpjB,EAAS,IAC/BwjB,EAASJ,EAAUnjB,EAAS,IAE5BwjB,EAAWD,EAASF,EACpBI,EAFYN,EAAUnjB,EAAS,IAELsjB,EAE1BzG,EACLld,KAAK+jB,IAAIF,EAAW,GAAK7jB,KAAK+jB,IAAIF,EAAW,GAC7C7jB,KAAKgkB,IAAIN,GACR1jB,KAAKgkB,IAAIJ,GACT5jB,KAAK+jB,IAAID,EAAc,GACvB9jB,KAAK+jB,IAAID,EAAc,GAMzB,OALU,EAAI9jB,KAAKikB,MAAMjkB,KAAKQ,KAAK0c,GAAIld,KAAKQ,KAAK,EAAI0c,IAEtC,OAGG,GACnB,KC3BagH,EAAc,UAErB,SAAUC,EAAiB5P,GAEhC,OADgBA,EAAU,IACRvU,KAAKsU,GAAM,GAC9B,CAEgB,SAAA8P,EAAgBC,GAE/B,OAAOA,GADQH,EAAc,IAE9B,CAEgB,SAAAI,GAAiBjQ,GAEhC,OADgBA,GAAW,EAAIrU,KAAKsU,IAClB,IAAOtU,KAAKsU,EAC/B,CCfA,IAAMiQ,GAAqB,kBACrBC,GAAqB,oBACrBC,GAAI,QAQGC,GAAwB,SACpCthB,EACAC,GAC+B,MAAA,CAC/B9C,EAAW,IAAR6C,EAAY,EAAIA,EAAMohB,GAAqBC,GAC9CnkB,EACS,IAAR+C,EACG,EACArD,KAAKoX,IAAIpX,KAAKqX,IAAIrX,KAAKsU,GAAK,EAAKjR,EAAMmhB,GAAsB,IAAMC,GACvE,EAQYE,GAAwB,SACpCpkB,EACAD,GAAS,MAC0B,CACnC8C,IAAW,IAAN7C,EAAU,EAAIgkB,IAAsBhkB,EAAIkkB,IAC7CphB,IACO,IAAN/C,EACG,GACC,EAAIN,KAAK+Z,KAAK/Z,KAAKga,IAAI1Z,EAAImkB,KAAMzkB,KAAKsU,GAAK,GAAKiQ,GACrD,ECrBD,SAASvM,GACR4M,EACAP,EACAQ,GAEA,IAAMC,EAAaX,EAAiBS,EAAO,IACrCG,EAAYZ,EAAiBS,EAAO,IACpCI,EAAab,EAAiBU,GAC9BxQ,EAAU+P,EAAgBC,GAG1BY,EAAYjlB,KAAKklB,KACtBllB,KAAK+jB,IAAIgB,GAAa/kB,KAAKgkB,IAAI3P,GAC9BrU,KAAKgkB,IAAIe,GAAa/kB,KAAK+jB,IAAI1P,GAAWrU,KAAKgkB,IAAIgB,IAWrD,MAAO,CAHKV,GALXQ,EACA9kB,KAAKikB,MACJjkB,KAAK+jB,IAAIiB,GAAchlB,KAAK+jB,IAAI1P,GAAWrU,KAAKgkB,IAAIe,GACpD/kB,KAAKgkB,IAAI3P,GAAWrU,KAAK+jB,IAAIgB,GAAa/kB,KAAK+jB,IAAIkB,KAGzCX,GAAiBW,GAG9B,CAEgB,SAAAE,GAAOvQ,GAUtB,IAJA,IAAQwQ,EAAkDxQ,EAAlDwQ,OAAQC,EAA0CzQ,EAA1CyQ,iBAAkBpjB,EAAwB2S,EAAxB3S,oBAC5BqjB,EAAQ1Q,EAAQ0Q,MAAQ1Q,EAAQ0Q,MAAQ,GAExC9Z,EAA0B,GACvBI,EAAI,EAAGA,EAAI0Z,EAAO1Z,IAAK,CAC/B,IAAM2Z,EAAmBvN,GACxBoN,EACAC,GACM,IAALzZ,EAAY0Z,GAGd9Z,EAAYO,KAAK,CAChBnM,EAAe2lB,EAAiB,GAAItjB,GACpCrC,EAAe2lB,EAAiB,GAAItjB,IAEtC,CAGA,OAFAuJ,EAAYO,KAAKP,EAAY,IAEtB,CACND,KAAM,UACND,SAAU,CAAEC,KAAM,UAAWC,YAAa,CAACA,IAC3CH,WAAY,GAEd,UC3DgBma,GACfjZ,GAEA,IAMIkZ,EANE7Q,EAAiC,CACtC8Q,QAAS,GAOV,GAA8B,YAA1BnZ,EAAQjB,SAASC,KACpBka,EAAQlZ,EAAQjB,SAASE,oBACW,eAA1Be,EAAQjB,SAASC,KAG3B,UAAUjF,MAAM,yDAFhBmf,EAAQ,CAAClZ,EAAQjB,SAASE,YAG3B,CAKA,IAHA,IAAM8M,EAAqB,GAGlBqN,EAAQ,EAAGA,EAAQF,EAAM5Z,OAAQ8Z,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQH,EAAME,GAAO9Z,OAAS,EAAG+Z,IACpD,IAAK,IAAIC,EAAQ,EAAGA,EAAQJ,EAAM5Z,OAAQga,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQL,EAAMI,GAAOha,OAAS,EAAGia,IAEpDC,EAA0BJ,EAAOC,EAAOC,EAAOC,GAMnD,OAAOxN,EAAOzM,OAAS,EAQvB,SAASma,EAAUC,GAClB,OAAOA,EAAO,EAAIrR,EAAQ8Q,SAAWO,EAAO,EAAIrR,EAAQ8Q,OACzD,CAEA,SAASK,EACRJ,EACAC,EACAC,EACAC,GAEA,IAYII,EAZEC,EAASV,EAAME,GAAOC,GACtBQ,EAAOX,EAAME,GAAOC,EAAQ,GAC5BS,EAASZ,EAAMI,GAAOC,GACtBQ,EAAOb,EAAMI,GAAOC,EAAQ,GAE5BS,EAyDR,SACCJ,EACAC,EACAC,EACAC,GAEA,GACCE,GAAYL,EAAQE,IACpBG,GAAYL,EAAQG,IACpBE,GAAYJ,EAAMC,IAClBG,GAAYF,EAAMD,GAElB,OAAO,KAGR,IAAMI,EAAKN,EAAO,GACjBO,EAAKP,EAAO,GACZQ,EAAKP,EAAK,GACVQ,EAAKR,EAAK,GACVS,EAAKR,EAAO,GACZS,EAAKT,EAAO,GACZU,EAAKT,EAAK,GACVU,EAAKV,EAAK,GAELW,GAASR,EAAKE,IAAOG,EAAKE,IAAON,EAAKE,IAAOC,EAAKE,GACxD,OAAc,IAAVE,EACI,KASD,GALJR,EAAKG,EAAKF,EAAKC,IAAOE,EAAKE,IAAON,EAAKE,IAAOE,EAAKG,EAAKF,EAAKC,IAAOE,IAGpER,EAAKG,EAAKF,EAAKC,IAAOG,EAAKE,IAAON,EAAKE,IAAOC,EAAKG,EAAKF,EAAKC,IAAOE,EAGxE,CA7FuBC,CAAUf,EAAQC,EAAMC,EAAQC,GAEhC,OAAjBC,IAaHL,EADGI,EAAK,KAAOD,EAAO,IACbE,EAAa,GAAKF,EAAO,KAAOC,EAAK,GAAKD,EAAO,KAEjDE,EAAa,GAAKF,EAAO,KAAOC,EAAK,GAAKD,EAAO,IAKvDL,EAbAI,EAAK,KAAOD,EAAO,IACbI,EAAa,GAAKJ,EAAO,KAAOC,EAAK,GAAKD,EAAO,KAEjDI,EAAa,GAAKJ,EAAO,KAAOC,EAAK,GAAKD,EAAO,MAUnCH,EAAUE,KAoBtBK,EAAaY,WAMzB7O,EAAOvM,KAAKwa,IACb,CACD,CAEA,SAASC,GAAYY,EAAkBC,GACtC,OAAOD,EAAO,KAAOC,EAAO,IAAMD,EAAO,KAAOC,EAAO,EACxD,CClHgB,SAAAC,GACfxb,EACA7J,GAEA,OACuB,IAAtB6J,EAAWD,QACc,iBAAlBC,EAAW,IACO,iBAAlBA,EAAW,IACAyb,WAAlBzb,EAAW,IACOyb,WAAlBzb,EAAW,KAbkB1I,EAcd0I,EAAW,MAbZ,KAAO1I,GAAO,MALAC,EAmBdyI,EAAW,MAlBX,IAAMzI,GAAO,IAmB3BmkB,GAAiB1b,EAAW,KAAO7J,GACnCulB,GAAiB1b,EAAW,KAAO7J,MArBPoB,EAICD,CAmB/B,CAEgB,SAAAokB,GAAiBva,GAGhC,IAFA,IAAIwa,EAAU,EACVC,EAAY,EACT1nB,KAAKE,MAAM+M,EAAQwa,GAAWA,IAAYxa,GAChDwa,GAAW,GACXC,IAGD,OAAOA,CACR,CCtBgB,SAAAC,GACfpb,EACAtK,GAEA,MAC2B,YAA1BsK,EAAQjB,SAASC,MACuB,IAAxCgB,EAAQjB,SAASE,YAAYK,QAC7BU,EAAQjB,SAASE,YAAY,GAAGK,QAAU,GAC1CU,EAAQjB,SAASE,YAAY,GAAGoc,MAAM,SAAC9b,GACtC,OAAAwb,GAAkBxb,EAAY7J,EAAoB,KAhB3B4lB,EAmBvBtb,EAAQjB,SAASE,YAAY,GAAG,IAjBnB,MAFmCsc,EAoBhDvb,EAAQjB,SAASE,YAAY,GAC5Be,EAAQjB,SAASE,YAAY,GAAGK,OAAS,IAnBR,IACnCgc,EAAc,KAAOC,EAAc,GAHrC,IAA0BD,EAAyBC,CAyBnD,CAEgB,SAAAC,GACfxb,EACAtK,GAEA,OACC0lB,GAAuBpb,EAAStK,KAC/BujB,GAAejZ,EAElB,CCQa,IAAAyb,gBAAoBhF,SAAAA,GAiBhC,SAAAgF,EAAYpT,GAA0D,IAAAqT,EAAAtnB,GACrEA,EAAAqiB,EAAAvd,KAAA7E,KAAMgU,IAAQhU,MAjBfgM,KAAO,SAAQjM,EACPykB,YAAM,EAAAzkB,EACNunB,WAAa,EAACvnB,EACdwnB,qBAAexnB,EAAAA,EACfynB,eAAS,EAAAznB,EACT0nB,aAAO1nB,EAAAA,EACP2nB,yBAA2B,KAalC,IAAMC,EAAiB,CACtBC,MAAO,aAWR,GAPC7nB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAA,CAAA,EAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAKW,QAAvB3T,MAAAA,OAAAA,EAAAA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EACpB2H,CAAAA,EAAAA,EAAqB/T,EAAQwT,WAClCO,CACL,CAIoC,OAFpChoB,EAAK2nB,yBAC6B,OADLL,EAC5BrT,MAAAA,OAAAA,EAAAA,EAAS0T,0BAAwBL,EAAI,KACtCtnB,EAAKggB,SAAkB,MAAP/L,OAAO,EAAPA,EAASqM,WAAWtgB,CACrC,CA7CgC4F,EAAAyhB,EAAAhF,GA6C/B,IAAA9gB,EAAA8lB,EAAA7lB,UA+PA6lB,OA/PA9lB,EAEO0mB,MAAA,WACP,QAA6B/gB,IAAzBjH,KAAKunB,gBAAT,CAIA,IAAM9F,EAAazhB,KAAKunB,gBAExB,GAAIvnB,KAAK+f,UAAY0B,EAAY,CAChC,IAAMwG,EAAkBjoB,KAAKkgB,MAAMgI,gBAAyBzG,GAiB5D,IAfczhB,KAAK+f,SAClB,CACCpV,KAAM,UACNlF,GAAIgc,EACJ/W,SAAUud,EACVxd,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAY4O,SAKzB,MAEF,CAEAnoB,KAAKwkB,YAASvd,EACdjH,KAAKunB,qBAAkBtgB,EACvBjH,KAAKsnB,WAAa,EAEC,YAAftnB,KAAKooB,OACRpoB,KAAKygB,aAINzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QApCrD,CAqCD,EAAC/mB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,GAAwB,IAApBzB,KAAKsnB,WAAkB,CAC1BtnB,KAAKwkB,OAAS,CAAC/iB,EAAMe,IAAKf,EAAMgB,KAChC,IAAM+lB,EAAiBjE,GAAO,CAC7BC,OAAQxkB,KAAKwkB,OACbC,iBAAkBzkB,KAAK0nB,yBACvBrmB,oBAAqBrB,KAAKqB,sBAG3BonB,EAAoBzoB,KAAKkgB,MAAMwI,OAAO,CACrC,CACChe,SAAU8d,EAAe9d,SACzBD,WAAY,CACXuB,KAAMhM,KAAKgM,KACXyY,iBAAkBzkB,KAAK0nB,6BAI1B1nB,KAAKunB,gBATWkB,EAShB,GACAzoB,KAAKsnB,aACLtnB,KAAKwgB,YACN,MAEsB,IAApBxgB,KAAKsnB,YACLtnB,KAAKwkB,aACoBvd,IAAzBjH,KAAKunB,iBAELvnB,KAAK2oB,aAAalnB,GAInBzB,KAAKgoB,OAEP,EAAC1mB,EAGDkC,YAAA,SAAY/B,GACXzB,KAAK2oB,aAAalnB,EACnB,EAACH,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGdinB,QAAA,WACC,IAAMK,EAAY5oB,KAAKunB,gBAEvBvnB,KAAKwkB,YAASvd,EACdjH,KAAKunB,qBAAkBtgB,EACvBjH,KAAKsnB,WAAa,EACC,YAAftnB,KAAKooB,OACRpoB,KAAKygB,aAGN,SACmBxZ,IAAd2hB,GACH5oB,KAAKkgB,MAAK,OAAQ,CAAC0I,GAErB,CAAE,MAAOzH,GACV,CAAA,EAAC7f,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,ECrON,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,ID4NR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,GAETuE,GAGDA,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,UAAC8G,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCmb,GAAsCxb,EAAS3L,KAAKqB,oBAKvD,EAACC,EAEOqnB,aAAA,SAAalnB,GACpB,GAAwB,IAApBzB,KAAKsnB,YAAoBtnB,KAAKwkB,QAAUxkB,KAAKunB,gBAAiB,CACjE,IAKIyB,EALEC,EAAYtG,EAA4B3iB,KAAKwkB,OAAQ,CAC1D/iB,EAAMe,IACNf,EAAMgB,MAKP,GAAwB,iBAApBzC,KAAK+H,WAA+B,CAGvC,IAAMmhB,EE9RM,SACfvX,EACAxN,GAEA,IAAMglB,EAAiE,IAA9CxG,EAA4BhR,EAAQxN,GAC7D,GAAyB,IAArBglB,EACH,OAAO,EAGR,IAAAC,EAAyBtF,GAAsBnS,EAAO,GAAIA,EAAO,IAAtDoU,EAAEqD,EAALzpB,EAAUqmB,EAAEoD,EAAL1pB,EACf2pB,EAAyBvF,GAAsB3f,EAAO,GAAIA,EAAO,IAA/C+hB,EAAEmD,EAAL3pB,EAIf,OAH0BN,KAAKQ,KAC9BR,KAAKC,IAFOgqB,EAAL1pB,EAEOomB,EAAI,GAAK3mB,KAAKC,IAAI6mB,EAAKF,EAAI,IAEfmD,CAC5B,CF+QuBG,CAA+BtpB,KAAKwkB,OAAQ,CAC9D/iB,EAAMe,IACNf,EAAMgB,MAGPumB,EJlOE,SAA4BhV,GAejC,IATA,IAAQwQ,EAAkDxQ,EAAlDwQ,OAA0BnjB,EAAwB2S,EAAxB3S,oBAC5BqjB,EAAQ1Q,EAAQ0Q,MAAQ1Q,EAAQ0Q,MAAQ,GAExC6E,EAAkC,IAHkBvV,EAA1CyQ,iBAMhB2E,EAAiBtF,GADEU,EAAM,GAANA,EAAM,IACjB7kB,EAACypB,EAADzpB,EAAGD,EAAC0pB,EAAD1pB,EAELkL,EAA0B,GACvBI,EAAI,EAAGA,EAAI0Z,EAAO1Z,IAAK,CAC/B,IAAMwe,EAAe,IAAJxe,EAAW0Z,EAAStlB,KAAKsU,GAAM,IAC1C+V,EAAKF,EAAenqB,KAAKgkB,IAAIoG,GAC7BE,EAAKH,EAAenqB,KAAK+jB,IAAIqG,GAEnCG,EAAqB5F,GADHpkB,EAAI8pB,EAAI/pB,EAAIgqB,GACjBjnB,EAAGknB,EAAHlnB,IACbmI,EAAYO,KAAK,CAChBnM,EAFU2qB,EAAHnnB,IAEanB,GACpBrC,EAAeyD,EAAKpB,IAEtB,CAKA,OAFAuJ,EAAYO,KAAKP,EAAY,IAEtB,CACND,KAAM,UACND,SAAU,CAAEC,KAAM,UAAWC,YAAa,CAACA,IAC3CH,WAAY,GAEd,CI+LoBmf,CAAkB,CACjCpF,OAAQxkB,KAAKwkB,OACbC,iBAAkBwE,EAAYC,EAC9B7nB,oBAAqBrB,KAAKqB,qBAE5B,SAA+B,UAApBrB,KAAK+H,WAOf,UAAUrC,MAAM,sBANhBsjB,EAAgBzE,GAAO,CACtBC,OAAQxkB,KAAKwkB,OACbC,iBAAkBwE,EAClB5nB,oBAAqBrB,KAAKqB,qBAI5B,CAEA,GAAIrB,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACNlF,GAAIzF,KAAKunB,gBACT7c,SAAUse,EAActe,SACxBD,WAAY,CACXga,iBAAkBwE,IAGpB,CACC7gB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAYiI,cAKzB,OAIFxhB,KAAKkgB,MAAM2J,eAAe,CACzB,CAAEpkB,GAAIzF,KAAKunB,gBAAiB7c,SAAUse,EAActe,YAErD1K,KAAKkgB,MAAM4J,eAAe,CACzB,CACCrkB,GAAIzF,KAAKunB,gBACTld,SAAU,mBACVgC,MAAO4c,IAGV,CACD,EAAC7B,CAAA,CA5S+BhF,CAAQzC,GGE5BoK,gBAAsB,SAAA3H,GAWlC,SAAA2H,EAAY/V,OAA8DjU,GACzEA,EAAAqiB,EAAAvd,KAAA7E,KAAMgU,IAAQhU,MAXfgM,KAAO,WAAUjM,EAETiqB,eAAgB,EAAKjqB,EACrBkqB,iBAASlqB,EACTmqB,oBAAcnqB,EAAAA,EACdoqB,iBAAW,EAAApqB,EACXynB,iBAASznB,EACT0nB,aAAO1nB,EAAAA,EACPqqB,4BAAsB,EAK7B,IAAMzC,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAgBR,GAZCjoB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,KAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAGhB5nB,EAAKqqB,uBACHpW,GAAWA,EAAQoW,yBAA2B,EAEhDrqB,EAAKoqB,YAAenW,GAAWA,EAAQmW,aAAgB,GAI5B,QAAvBnW,MAAAA,OAAAA,EAAAA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EACpB2H,GAAAA,EAAqB/T,EAAQwT,WAClCO,CACL,CAEoC,OAApChoB,EAAKggB,eAAW/L,SAAAA,EAASqM,WAAWtgB,CACrC,CA3CkC4F,EAAAokB,EAAA3H,GA2CjC,IAAA9gB,EAAAyoB,EAAAxoB,UAmTA,OAnTAD,EAEO0mB,MAAA,WACP,QAAuB/gB,IAAnBjH,KAAKiqB,UAAT,CAIA,IAAMxI,EAAazhB,KAAKiqB,UAExB,GAAIjqB,KAAK+f,UAAY0B,EAAY,CAChC,IAAMwG,EAAkBjoB,KAAKkgB,MAAMgI,gBAAyBzG,GAiB5D,IAfczhB,KAAK+f,SAClB,CACCpV,KAAM,UACNlF,GAAIgc,EACJ/W,SAAUud,EACVxd,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAY4O,SAKzB,MAEF,CAEAnoB,KAAKkqB,gBAAkBlqB,KAAKkgB,MAAK,OAAQ,CAAClgB,KAAKkqB,iBAC/ClqB,KAAKgqB,eAAgB,EACrBhqB,KAAKiqB,eAAYhjB,EACjBjH,KAAKkqB,oBAAiBjjB,EAEH,YAAfjH,KAAKooB,OACRpoB,KAAKygB,aAINzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QArCrD,CAsCD,EAAC/mB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GACX,QAAuBwF,IAAnBjH,KAAKiqB,YAAkD,IAAvBjqB,KAAKgqB,cAAzC,CAIA,IAAMK,EAAsBrqB,KAAKkgB,MAAMgI,gBACtCloB,KAAKiqB,WAINK,EACCD,EAAoBzf,YAAY,GAFXyf,EAAoBzf,YAAY,GAAGK,OAAS,GAGlEsf,EAAiBvqB,KAAKoI,QAFJkiB,EAAEE,GAAWF,EAAA,IAGzB7G,EAAWlkB,EAChB,CAAEI,EAFM4qB,EAAD5qB,EAEFD,EAFM6qB,EAAD7qB,GAGV,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGjCuoB,EAAiCJ,EAAoBzf,YAAY,GAAG,GACpE8f,EAAqC1qB,KAAKoI,QADzBqiB,EAAEE,GAAUF,EAAA,IAO7B,GALwBlrB,EACvB,CAAEI,EAFgB+qB,EAAX/qB,EAEQD,EAFgBgrB,EAAXhrB,GAGpB,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGXlC,KAAKggB,iBAK1B,GAJAhgB,KAAKyI,UAAUzI,KAAKynB,QAAQO,OAIxBhoB,KAAKoqB,uBACR,YAGDpqB,KAAKyI,UAAUzI,KAAKynB,QAAQG,OAK7B,KAAInE,EAAWzjB,KAAKmqB,aAApB,CAIAE,EAAoBzf,YAAY,GAAGggB,MAEnC,IAAMC,EAAc,CACnBlgB,KAAM,UACNC,YAAa,CAAA,GAAAkB,OAERue,EAAoBzf,YAAY,GAAE,CACrC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB4nB,EAAoBzf,YAAY,GAAG,OAKtC,GAAI5K,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACNlF,GAAIzF,KAAKiqB,UACTvf,SAAUmgB,EACVpgB,WAAY,IAEb,CACCrC,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAYiI,cAKzB,OAIFxhB,KAAKkgB,MAAM2J,eAAe,CACzB,CACCpkB,GAAIzF,KAAKiqB,UACTvf,SAAUmgB,IAvCZ,CAtCA,CAgFD,EAACvpB,EAGD+C,QAAA,SAAQ5C,GACP,IAA2B,IAAvBzB,KAAKgqB,cAAyB,CACjC,IAAAvB,EAAoCzoB,KAAKkgB,MAAMwI,OAAO,CACrD,CACChe,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,OAE1B,CACCtB,SAAU,CACTC,KAAM,QACNC,YAAa,CAACnJ,EAAMe,IAAKf,EAAMgB,MAEhCgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SApBTke,EAAczB,KA6BhC,OALAzoB,KAAKiqB,UAxBWxB,EAAA,GAyBhBzoB,KAAKkqB,eAAiBA,EACtBlqB,KAAKgqB,eAAgB,OACrBhqB,KAAKwgB,YAGN,CAEAxgB,KAAKgoB,OACN,EAAC1mB,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGdinB,QAAA,WACC,IAAMK,EAAY5oB,KAAKiqB,UACjBa,EAAwB9qB,KAAKkqB,eAEnClqB,KAAKkqB,oBAAiBjjB,EACtBjH,KAAKiqB,eAAYhjB,EACjBjH,KAAKgqB,eAAgB,EACF,YAAfhqB,KAAKooB,OACRpoB,KAAKygB,aAGN,SACmBxZ,IAAd2hB,GACH5oB,KAAKkgB,MAAK,OAAQ,CAAC0I,SAEU3hB,IAA1B6jB,GACH9qB,KAAKkgB,aAAa,CAAC4K,GAErB,CAAE,MAAO3J,GAAO,CACjB,EAAC7f,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,EF7TN,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IEoTR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,GAETuE,GAEU,YAAjBrH,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAO+X,kBACZ/X,EAAOvG,WACPd,GAGDqH,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOgY,kBACZhY,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOiY,yBACZjY,EAAOlG,kBACPnB,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAOkY,yBACZ,EACAvf,GAGDqH,EAAOvE,OAAS,GAETuE,GAGDA,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAC8G,KAAAA,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+a,GAAuBpb,EAAS3L,KAAKqB,oBAKxC,EAAC0oB,CAAA,CA9ViC,CAAQpK,GCrC9BwL,GASZ,SAAArrB,GACC,IAAAogB,EAAKpgB,EAALogB,MACAlU,EAAIlM,EAAJkM,KACA5D,EAAOtI,EAAPsI,QACAI,EAAS1I,EAAT0I,UACAwX,EAAelgB,EAAfkgB,gBACA3e,EAAmBvB,EAAnBuB,oBACA0G,EAAUjI,EAAViI,WAAU/H,KAfDkgB,WAAK,EAAAlgB,KACLgM,UACA5D,EAAAA,KAAAA,oBACAI,eAAS,EAAAxI,KACTggB,qBACA3e,EAAAA,KAAAA,yBACA0G,EAAAA,KAAAA,gBAWT,EAAA/H,KAAKkgB,MAAQA,EACblgB,KAAKgM,KAAOA,EACZhM,KAAKoI,QAAUA,EACfpI,KAAKwI,UAAYA,EACjBxI,KAAKggB,gBAAkBA,EACvBhgB,KAAKqB,oBAAsBA,EAC3BrB,KAAK+H,WAAaA,CACnB,ECnCe,SAAAqjB,GAAmBtrB,GAWlC,IAVA0I,EAAS1I,EAAT0I,UACAH,EAAKvI,EAALuI,MAUMgjB,EATSvrB,EAAfkgB,gBASmC,EAC3BrgB,EAAS0I,EAAT1I,EAAGD,EAAM2I,EAAN3I,EAEX,MAAO,CACNiL,KAAM,UACNF,WAAY,CAAE,EACdC,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACCpC,EAAU7I,EAAI0rB,EAAU3rB,EAAI2rB,GAC5B7iB,EAAU7I,EAAI0rB,EAAU3rB,EAAI2rB,GAC5B7iB,EAAU7I,EAAI0rB,EAAU3rB,EAAI2rB,GAC5B7iB,EAAU7I,EAAI0rB,EAAU3rB,EAAI2rB,GAC5B7iB,EAAU7I,EAAI0rB,EAAU3rB,EAAI2rB,IAC3B9lB,IAAI,SAAC+lB,GAAM,MAAA,CAACA,EAAE9oB,IAAK8oB,EAAE7oB,IAAI,KAI/B,CC9BA,IAAa8oB,gBAAyB,SAAAC,GACrC,SAAAD,EAAYhrB,GAAsB,OACjCirB,EAAA3mB,KAAMtE,KAAAA,IAAOP,IACd,CASC,OAZoC2F,EAAA4lB,EAAAC,GAGpCD,EAAAhqB,UAEMmnB,OAAA,SAAOjnB,GAEb,OAAO2pB,GAAoB,CAC1B5iB,UAAWxI,KAAKwI,UAChBH,MAAO,CAAE1I,EAH+B8B,EAAjCM,WAGKrC,EAH4B+B,EAAlBS,YAItB8d,gBAAiBhgB,KAAKggB,iBAExB,EAACuL,CAAA,CAZoC,CAAQJ,ICEjCM,gBAAsB,SAAAD,GAClC,SAAAC,EAAYlrB,GACX,OAAAirB,EAAA3mB,KAAMtE,KAAAA,IAAOP,IACd,CAUC,OAbiC2F,EAAA8lB,EAAAD,GAGjCC,EAAAlqB,UACMmqB,QAAA,SAAQC,EAAiCC,GAC/C,IAAArB,EAAiBvqB,KAAKoI,QAAQwjB,EAAiB,GAAIA,EAAiB,IAOpE,OALiBrsB,EAChB,CAAEI,EAHM4qB,EAAD5qB,EAGFD,EAHM6qB,EAAD7qB,GAIV,CAAEC,EAAGgsB,EAAW5pB,WAAYrC,EAAGisB,EAAWzpB,YAI5C,EAACupB,CAAA,CAbiC,CAAQN,ICC9BU,gBAAiB,SAAAL,GAC7B,SAAAK,EACUtrB,EACQurB,EACAC,OAA0ChsB,EAAA,OAE3DA,EAAAyrB,EAAA3mB,UAAMtE,UAJGA,YAAAR,EAAAA,EACQ+rB,qBAAA/rB,EACAgsB,sBAAA,EAAAhsB,EAMXisB,iCAAmC,SAACvqB,GAC1C,OAAO1B,EAAKksB,aAAaxqB,EAAO,SAACkK,GAChC,OAAOsC,QACNtC,EAAQlB,YAAckB,EAAQlB,WAAWuB,OAASjM,EAAKiM,KAEzD,EACD,EAACjM,EAEMmsB,uBAAyB,SAC/BzqB,EACA0qB,GAEA,OAAOpsB,EAAKksB,aAAaxqB,EAAO,SAACkK,GAChC,OAAOsC,QACNtC,EAAQlB,YACPkB,EAAQlB,WAAWuB,OAASjM,EAAKiM,MACjCL,EAAQlG,KAAO0mB,EAElB,EACD,EA3BUpsB,EAAMQ,OAANA,EACQR,EAAa+rB,cAAbA,EACA/rB,EAAgBgsB,iBAAhBA,EAA0ChsB,CAG5D,CAyDC8rB,OAhE4BlmB,EAAAkmB,EAAAL,GAO5BK,EAAAtqB,UAwBO0qB,aAAA,SACPxqB,EACA2qB,OAAqCnmB,EAAAjG,KAE/BqsB,EAAOrsB,KAAK+rB,iBAAiBrD,OAAOjnB,GAEpCoK,EAAW7L,KAAKkgB,MAAMoM,OAAOD,EAAMD,GAEnCG,EAA4D,CACjE1H,WAAO5d,EACPulB,QAAS7F,UAsBV,OAnBA9a,EAAS7I,QAAQ,SAAC2I,GACjB,IAAIf,EACJ,GAA8B,YAA1Be,EAAQjB,SAASC,KACpBC,EAAce,EAAQjB,SAASE,YAAY,OACjCe,IAA0B,eAA1BA,EAAQjB,SAASC,KAG3B,OAFAC,EAAce,EAAQjB,SAASE,WAGhC,CAEAA,EAAY5H,QAAQ,SAAC6hB,GACpB,IAAM4H,EAAOxmB,EAAK6lB,cAAcJ,QAAQjqB,EAAOojB,GAC3C4H,EAAOF,EAAQC,SAAWC,EAAOxmB,EAAK+Z,kBACzCuM,EAAQ1H,MAAQA,EAChB0H,EAAQC,QAAUC,EAEpB,EACD,GAEOF,EAAQ1H,KAChB,EAACgH,CAAA,CAhE4B,CAAQV,aCGtB/T,GACf4M,EACAP,EACAQ,GAEA,IAAMC,EAAaX,EAAiBS,EAAO,IACrCG,EAAYZ,EAAiBS,EAAO,IACpCI,EAAab,EAAiBU,GAC9BxQ,EAAU+P,EAAgBC,GAE1BY,EAAYjlB,KAAKklB,KACtBllB,KAAK+jB,IAAIgB,GAAa/kB,KAAKgkB,IAAI3P,GAC9BrU,KAAKgkB,IAAIe,GAAa/kB,KAAK+jB,IAAI1P,GAAWrU,KAAKgkB,IAAIgB,IAWrD,MAAO,CAHKV,GALXQ,EACA9kB,KAAKikB,MACJjkB,KAAK+jB,IAAIiB,GAAchlB,KAAK+jB,IAAI1P,GAAWrU,KAAKgkB,IAAIe,GACpD/kB,KAAKgkB,IAAI3P,GAAWrU,KAAK+jB,IAAIgB,GAAa/kB,KAAK+jB,IAAIkB,KAGzCX,GAAiBW,GAG9B,CAGgB,SAAAqI,GAAsB5sB,EAErC2jB,EACAQ,GAFE,IAAAtkB,EAACG,EAADH,EAAGD,EAACI,EAADJ,EAKC0kB,EAAab,EAAiBU,GASpC,MAAO,CAAEtkB,EAHIA,EAHE8jB,EAAWrkB,KAAKgkB,IAAIgB,GAMjB1kB,EAFLA,EAHE+jB,EAAWrkB,KAAK+jB,IAAIiB,GAMpC,CC/CgB,SAAAH,GAAQ2D,EAAiB+E,GACxC,IAAMC,EAAOrJ,EAAiBqE,EAAM,IAC9BiF,EAAOtJ,EAAiBoJ,EAAI,IAC5BG,EAAOvJ,EAAiBqE,EAAM,IAC9BmF,EAAOxJ,EAAiBoJ,EAAI,IAC5BrQ,EAAIld,KAAK+jB,IAAI0J,EAAOD,GAAQxtB,KAAKgkB,IAAI2J,GACrCpS,EACLvb,KAAKgkB,IAAI0J,GAAQ1tB,KAAK+jB,IAAI4J,GAC1B3tB,KAAK+jB,IAAI2J,GAAQ1tB,KAAKgkB,IAAI2J,GAAQ3tB,KAAKgkB,IAAIyJ,EAAOD,GAEnD,OAAOlJ,GAAiBtkB,KAAKikB,MAAM/G,EAAG3B,GACvC,CAEM,SAAUqS,GAAkBltB,EAAA8G,GAES,IAMtC4iB,EAAQpqB,KAAKikB,MANHzc,EAALlH,EADKI,EAALJ,EACFkH,EAALjH,EADKG,EAALH,GAmBF,OATA6pB,GAAiB,IAAMpqB,KAAKsU,IAGhB,IACX8V,GAAS,IACCA,GAAS,MACnBA,GAAS,KAGHA,CACR,CAEgB,SAAAyD,GAAiBhJ,GAChC,OAAQA,EAAU,KAAO,GAC1B,UCpCgBiJ,GACfC,EACAC,EACAC,GAQA,IANA,IAKIC,EAAUC,EAAWC,EALnB5V,EAAoB,GAEpB6V,EAAmBN,EAAOliB,OAE5ByiB,EAAY,EAEP1iB,EAAI,EAAGA,EAAImiB,EAAOliB,UACtBmiB,GAAaM,GAAa1iB,IAAMmiB,EAAOliB,OAAS,GADlBD,IAAK,CAG5B0iB,GAAAA,EAAYN,GAA8B,IAAjBxV,EAAM3M,OAAc,CAEvD,KADAqiB,EAAWF,EAAYM,GAGtB,OADA9V,EAAMzM,KAAKgiB,EAAOniB,IACX4M,EAER2V,EAAYtJ,GAAQkJ,EAAOniB,GAAImiB,EAAOniB,EAAI,IAAM,IAChDwiB,EAAepW,GAAY+V,EAAOniB,GAAIsiB,EAAUC,GAChD3V,EAAMzM,KAAKqiB,EACZ,CAEA,GAAIE,GAAaL,EAEhB,OADAC,EAAWD,EAAWK,IAKtBH,EAAYtJ,GAAQkJ,EAAOniB,GAAImiB,EAAOniB,EAAI,IAAM,IAChDwiB,EAAepW,GAAY+V,EAAOniB,GAAIsiB,EAAUC,GAChD3V,EAAMzM,KAAKqiB,GACJ5V,IANNA,EAAMzM,KAAKgiB,EAAOniB,IACX4M,GAYT,GAJI8V,GAAaN,GAChBxV,EAAMzM,KAAKgiB,EAAOniB,IAGfA,IAAMmiB,EAAOliB,OAAS,EACzB,OAAO2M,EAGR8V,GAAa/K,EAA4BwK,EAAOniB,GAAImiB,EAAOniB,EAAI,GAChE,CAEA,GAAI0iB,EAAYN,GAAaD,EAAOliB,SAAWwiB,EAC9C,UAAU/nB,MAAM,iCAGjB,IAAMioB,EAAOR,EAAOA,EAAOliB,OAAS,GACpC,MAAO,CAAC0iB,EAAMA,EACf,CC5DA,SAAS/K,GAAUjP,GAClB,OAAOA,GAAWvU,KAAKsU,GAAK,IAC7B,CAEA,SAASka,GAAUna,GAClB,OAAOA,GAAW,IAAMrU,KAAKsU,GAC9B,CCDa,IAAAma,gBAA0BrC,SAAAA,GACtC,SAAAqC,EAAqBttB,GAAsB,IAAAR,EAAA,OAC1CA,EAAAyrB,EAAA3mB,UAAMtE,UADcA,YAAAR,EAAAA,EAAMQ,OAANA,EAAsBR,CAE3C,CAHsC4F,EAAAkoB,EAAArC,GAGrC,IAAAlqB,EAAAusB,EAAAtsB,UAqEA,OArEAD,EAEMwsB,6BAAA,SACN7G,EACAC,EACA6G,GAKA,IAHA,IAAMC,EAAO,CAAC/G,EAAeC,GAEzB+G,EAAa,EACRjjB,EAAI,EAAGA,EAAIgjB,EAAK/iB,OAAS,EAAGD,IACpCijB,GAActL,EAA4BqL,EAAK,GAAIA,EAAK,IAIzD,GAAIC,GAAcF,EACjB,OAAOC,EAGR,IAAIE,EAAmBD,EAAaF,EAAgB,EAG/CI,OAAOC,UAAUF,KACrBA,EAAmB9uB,KAAKivB,MAAMH,GAAoB,GAInD,IADA,IAAMI,EAAyB,GACtBtjB,EAAI,EAAGA,EAAIkjB,EAAkBljB,IAAK,CAC1C,IAAMsT,EAAU4O,GACfc,EACAD,EAAgB/iB,EAChB+iB,GAAiB/iB,EAAI,IAEtBsjB,EAASnjB,KAAKmT,EACf,CAGA,IADA,IAAM1T,EAA0B,GACvBI,EAAI,EAAGA,EAAIsjB,EAASrjB,OAAQD,IAEpCJ,EAAYO,KADCmjB,EAAStjB,GACA,IAKvB,OAF2BhL,KAAKuuB,iBAAiB3jB,EAGlD,EAACtJ,EAEMktB,qCAAA,SACNvH,EACAC,EACA6G,GAEA,IAAMtK,EAAWd,EAA4BsE,EAAeC,GAEtDtc,EDtDQ,SACfgd,EACA+E,EACA8B,GAEA,IAAMzd,EAAqB,GAErB8b,EAAOlK,GAAUgF,EAAM,IACvBgF,EAAOhK,GAAUgF,EAAM,IACvBmF,EAAOnK,GAAU+J,EAAI,IACrBE,EAAOjK,GAAU+J,EAAI,IAE3B8B,GAAkB,EAGlB,IAAMzoB,EACL,EACA5G,KAAKklB,KACJllB,KAAKQ,KACJR,KAAAC,IAAAD,KAAK+jB,KAAK4J,EAAOD,GAAQ,GAAM,GAC9B1tB,KAAKgkB,IAAI0J,GAAQ1tB,KAAKgkB,IAAI2J,GAAK3tB,KAAAC,IAAGD,KAAK+jB,KAAK0J,EAAOD,GAAQ,GAAM,KAIrE,GAAU,IAAN5mB,GAAW+J,MAAM/J,GAEpB,OAAOgL,EAGR,IAAK,IAAIhG,EAAI,EAAGA,GAAKyjB,EAAgBzjB,IAAK,CACzC,IAAM0jB,EAAI1jB,EAAIyjB,EACRE,EAAIvvB,KAAK+jB,KAAK,EAAIuL,GAAK1oB,GAAK5G,KAAK+jB,IAAInd,GACrC4oB,EAAIxvB,KAAK+jB,IAAIuL,EAAI1oB,GAAK5G,KAAK+jB,IAAInd,GAG/BrG,EACLgvB,EAAIvvB,KAAKgkB,IAAI0J,GAAQ1tB,KAAKgkB,IAAIwJ,GAAQgC,EAAIxvB,KAAKgkB,IAAI2J,GAAQ3tB,KAAKgkB,IAAIyJ,GAC/DntB,EACLivB,EAAIvvB,KAAKgkB,IAAI0J,GAAQ1tB,KAAK+jB,IAAIyJ,GAAQgC,EAAIxvB,KAAKgkB,IAAI2J,GAAQ3tB,KAAK+jB,IAAI0J,GAC/DgC,EAAIF,EAAIvvB,KAAK+jB,IAAI2J,GAAQ8B,EAAIxvB,KAAK+jB,IAAI4J,GAG5C,KAAIhd,MAAMpQ,IAAMoQ,MAAMrQ,IAAMqQ,MAAM8e,IAAlC,CAKA,IAAMpsB,EAAMrD,KAAKikB,MAAMwL,EAAGzvB,KAAKQ,KAAKR,KAAAC,IAAAM,EAAK,GAACP,KAAAC,IAAGK,EAAK,KAC5C2c,EAAMjd,KAAKikB,MAAM3jB,EAAGC,GAEtBoQ,MAAMtN,IAAQsN,MAAMsM,IAKxBrL,EAAO7F,KAAK,CAACyiB,GAAUvR,GAAMuR,GAAUnrB,IAVvC,CAWD,CAEA,OAAOuO,EAAO4G,MAAM,GAAI,EACzB,CCLsBkX,CACnB7H,EACAC,EAHsB9nB,KAAKivB,MAAM5K,EAAWsK,IAQ7C,OAF2B/tB,KAAKuuB,iBAAiB3jB,EAGlD,EAACtJ,EAEOitB,iBAAA,SAAiB3jB,OAAuB3E,EAAAjG,KAC/C,OAAO4K,EAAYrF,IAAI,SAAC2F,GAAU,MAAK,CACtClM,EAAekM,EAAW,GAAIjF,EAAK1F,OAAOc,qBAC1CrC,EAAekM,EAAW,GAAIjF,EAAK1F,OAAOc,qBAC1C,EACF,EAACwsB,CAAA,CAxEqCrC,CAAQL,ICL/B,SAAA4D,GACf7jB,EACAgc,GAEA,OACChc,EAAW,KAAOgc,EAAc,IAAMhc,EAAW,KAAOgc,EAAc,EAExE,CCsDa,IAAA8H,gBAAwB,SAAA5M,GAiBpC,SAAA4M,EAAYhb,GAA2D,IAAAjU,GACtEA,EAAAqiB,EAAAvd,KAAA7E,KAAMgU,IAASjU,MAjBhBiM,KAAO,aAAYjM,EAEXkvB,kBAAoB,EAAClvB,EACrBkqB,eAAS,EAAAlqB,EACTmqB,oBAAc,EAAAnqB,EACdynB,eAASznB,EAAAA,EACTmvB,qBAAenvB,EAAAA,EACf0nB,aAAO1nB,EAAAA,EACPovB,WAAY,EAAKpvB,EACjBqvB,uBAAiB,EAAArvB,EACjBsvB,6BAAuB,EAAAtvB,EAGvBuvB,cAAQ,EAAAvvB,EACRwvB,iBAAW,EAKlB,IAAM5H,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAcR,GAVCjoB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAA,CAAA,EAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAGhB5nB,EAAKmvB,mBACJlb,QAAgC/M,IAArB+M,EAAQsb,WAAyBtb,EAAQsb,SAI1B,QAAvBtb,MAAAA,OAAAA,EAAAA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EACpB2H,CAAAA,EAAAA,EAAqB/T,EAAQwT,WAClCO,CACL,CAIoD,OAFpDhoB,EAAKggB,SAAkB,MAAP/L,OAAO,EAAPA,EAASqM,WAEzBtgB,EAAKqvB,wBAAoBpb,SAAAA,EAASob,kBAAkBrvB,CACrD,CAjDoC4F,EAAAqpB,EAAA5M,GAiDnC,IAAA9gB,EAAA0tB,EAAAztB,UAmdAytB,OAndA1tB,EAEO0mB,MAAA,WACP,QAAuB/gB,IAAnBjH,KAAKiqB,UAAT,CAIA,IAAMI,EAAsBrqB,KAAKkgB,MAAMgI,gBACtCloB,KAAKiqB,WAINI,EAAoBzf,YAAYggB,MAEhC5qB,KAAKwvB,iBAAgB,GAAA1jB,OAChBue,EAAoBzf,kBACxB3D,EACAsS,EAAYkW,QAGb,IAAMhO,EAAazhB,KAAKiqB,UAGxBjqB,KAAKkqB,gBAAkBlqB,KAAKkgB,MAAY,OAAC,CAAClgB,KAAKkqB,iBAC/ClqB,KAAKivB,kBAAoB,EACzBjvB,KAAKiqB,eAAYhjB,EACjBjH,KAAKkqB,oBAAiBjjB,EACtBjH,KAAKqvB,6BAA0BpoB,EAGZ,YAAfjH,KAAKooB,OACRpoB,KAAKygB,aAINzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QA9BrD,CA+BD,EAAC/mB,EAEOkuB,iBAAA,SACP5kB,EACA8kB,EACAnO,GAEA,GAAKvhB,KAAKiqB,UAAV,CAIA,IAAM0F,EAAkB,CAAEhlB,KAAM,aAAcC,YAAAA,GAE9C,GAAI5K,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACND,SAAUilB,GAEX,CACCvnB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYA,IAKb,OAIF,IAAMqO,EAAa,CAClB,CACCnqB,GAAIzF,KAAKiqB,UACTvf,SAAUilB,IAOR3vB,KAAKkqB,gBAAkBwF,GAC1BE,EAAWzkB,KAAK,CACf1F,GAAIzF,KAAKkqB,eACTxf,SAAU,CACTC,KAAM,QACNC,YAAa8kB,KAKG,WAAfnO,IACHvhB,KAAKqvB,wBAA0BM,EAAgB/kB,aAGhD5K,KAAKkgB,MAAM2J,eAAe+F,EA/C1B,CAgDD,EAACtuB,EAEOuuB,0BAAA,SAA0BC,EAAsBC,GACvD,IAAK/vB,KAAKovB,oBAAsBpvB,KAAKqvB,wBACpC,MAAM,IAAI3pB,MAAM,kCAIjB,GAAwC,WAApC1F,KAAKovB,kBAAkBY,SAC1B,MAAU,IAAAtqB,MAAM,2BAGjB,IACMuqB,EADWtN,EAA4BmN,EAAYC,IACrB/vB,KAAKovB,kBAAkB/iB,MAAQ,GAC/D6jB,EAAkC,GAiBtC,MAfwB,UAApBlwB,KAAK+H,WACRmoB,EACClwB,KAAKuvB,YAAYf,qCAChBsB,EACAC,EACAE,GAE4B,iBAApBjwB,KAAK+H,aACfmoB,EAAsBlwB,KAAKuvB,YAAYzB,6BACtCgC,EACAC,EACAE,IAIKC,CACR,EAAC5uB,EAEO6uB,WAAA,SAAWC,GAClB,IAAOC,EAAarwB,KAAKkgB,MAAMwI,OAAO,CACrC,CACChe,SAAU,CACTC,KAAM,aACNC,YAAa,CACZwlB,EACAA,IAGF3lB,WAAY,CAAEuB,KAAMhM,KAAKgM,SATX,GAYhBhM,KAAKqvB,wBAA0B,CAACe,EAAeA,GAC/CpwB,KAAKiqB,UAAYoG,EACjBrwB,KAAKivB,oBACLjvB,KAAKwgB,YACN,EAAClf,EAEOgvB,kBAAA,SAAkBC,GACzB,GAAKvwB,KAAKiqB,UAAV,CAIA,IAIMuG,EAJsBxwB,KAAKkgB,MAAMgI,gBACtCloB,KAAKiqB,WAGyCrf,YAE/C6lB,EAAkBzwB,KAAKkgB,MAAMwI,OAAO,CACnC,CACChe,SAAU,CACTC,KAAM,QACNC,eAAWkB,OAAMykB,IAElB9lB,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKkqB,eATSuG,EAAA,GAadzwB,KAAKyI,UAAUzI,KAAKynB,QAAQO,OAE5B,IAAM0I,EAAsB,GAAA5kB,OAAO0kB,EAAkB,CAAED,IAGvDvwB,KAAKwvB,iBACJkB,OAH8BzpB,EAK9BsS,EAAYkW,QAGbzvB,KAAKivB,mBAhCL,CAiCD,EAAC3tB,EAEOqvB,aAAA,SACPJ,EACAK,GAEA,GAAK5wB,KAAKiqB,UAAV,CAGA,IAIMuG,EAJsBxwB,KAAKkgB,MAAMgI,gBACtCloB,KAAKiqB,WAGyCrf,YAG/C9K,EAAmCE,KAAKqvB,wBACrCrvB,KAAKqvB,wBAAwBrvB,KAAKqvB,wBAAwBpkB,OAAS,GACnEulB,EAAmBA,EAAmBvlB,OAAS,GAGlDsf,EAAiBvqB,KAAKoI,QALJtI,EAAA,GAAaA,EAK/B,IAOA,GANiBP,EAChB,CAAEI,EAFM4qB,EAAD5qB,EAEFD,EAFM6qB,EAAD7qB,GAGV,CAAEC,EAAGixB,EAASjxB,EAAGD,EAAGkxB,EAASlxB,IAEIM,KAAKggB,gBAGtChgB,KAAKgoB,YADN,CAOAhoB,KAAKyI,UAAUzI,KAAKynB,QAAQO,OAE5B,IAAM6I,EAAsB/kB,GAAAA,OAAO0kB,EAAoBD,CAAAA,IAIvDvwB,KAAKwvB,iBACJqB,EAHAL,EAAmBA,EAAmBvlB,OAAS,GAK/CsO,EAAYkW,QAGbzvB,KAAKivB,mBAhBL,CAvBA,CAwCD,EAAC3tB,EAGDgf,kBAAA,SAAkB/f,GACjBP,KAAKsvB,SAAW,IAAIzD,GACnBtrB,EACA,IAAIkrB,GAAsBlrB,GAC1B,IAAIgrB,GAAyBhrB,IAG9BP,KAAKuvB,YAAc,IAAI1B,GAA0BttB,EAClD,EAACe,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKmvB,WAAY,EACjBnvB,KAAKyI,UAAUzI,KAAKynB,QAAQG,YAEL3gB,IAAnBjH,KAAKiqB,WAAsD,IAA3BjqB,KAAKivB,kBAAzC,CAGA,IAIMuB,EAJsBxwB,KAAKkgB,MAAMgI,gBACtCloB,KAAKiqB,WAGyCrf,YAG/C4lB,EAAmB5F,MAEnB,IAGM2F,EAFLvwB,KAAKkvB,iBACLlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,YACC,CAACxoB,EAAMe,IAAKf,EAAMgB,KAIrE,GAAIzC,KAAKkqB,eAAgB,CACxB,IAAA4G,EACCN,EAAmBA,EAAmBvlB,OAAS,GAChDyf,EAAiB1qB,KAAKoI,QAFJ0oB,EAAEtG,GAAWsG,EAE/B,IACiBvxB,EAChB,CAAEI,EAFM+qB,EAAD/qB,EAEFD,EAFMgrB,EAADhrB,GAGV,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGClC,KAAKggB,iBAGtChgB,KAAKyI,UAAUzI,KAAKynB,QAAQO,MAE9B,CAEA,IAAIgG,EAAIliB,GAAAA,OAAO0kB,EAAoBD,CAAAA,IAEnC,GACCvwB,KAAKovB,mBACLpvB,KAAKiqB,WACLjqB,KAAKqvB,wBACJ,CACD,IAAMS,EACL9vB,KAAKqvB,wBAAwBrvB,KAAKqvB,wBAAwBpkB,OAAS,GAC9D8kB,EAAWQ,EACjB,IAAKxB,GAAqBe,EAAYC,GAAW,CAChD,IAAMG,EAAsBlwB,KAAK6vB,0BAChCC,EACAC,GAED/B,EAAI,GAAAliB,OACA9L,KAAKqvB,wBAAwBzX,MAAM,GAAI,GACvCsY,EACHK,CAAAA,GAEF,CACD,CAGAvwB,KAAKwvB,iBAAiBxB,OAAM/mB,EAAWsS,EAAYiI,YAzDnD,CA0DD,EAAClgB,EAGD+C,QAAA,SAAQ5C,GAKHzB,KAAKivB,kBAAoB,IAAMjvB,KAAKmvB,WACvCnvB,KAAKwD,YAAY/B,GAElBzB,KAAKmvB,WAAY,EAEjB,IAIMoB,EAHLvwB,KAAKiqB,WACLjqB,KAAKkvB,iBACLlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,YACC,CAACxoB,EAAMe,IAAKf,EAAMgB,KAEtC,IAA3BzC,KAAKivB,kBACRjvB,KAAKmwB,WAAWI,GACqB,IAA3BvwB,KAAKivB,mBAA2BjvB,KAAKiqB,UAC/CjqB,KAAKswB,kBAAkBC,GACbvwB,KAAKiqB,WACfjqB,KAAK2wB,aAAaJ,EAAc,CAC/B5wB,EAAG8B,EAAMM,WACTrC,EAAG+B,EAAMS,YAGZ,EAACZ,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,QAChC7nB,KAAKuoB,UAGF9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QAChC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdinB,QAAA,WACC,IAAMK,EAAY5oB,KAAKiqB,UAEvBjqB,KAAKkqB,oBAAiBjjB,EACtBjH,KAAKiqB,eAAYhjB,EACjBjH,KAAKivB,kBAAoB,EACN,YAAfjvB,KAAKooB,OACRpoB,KAAKygB,aAGN,SACmBxZ,IAAd2hB,GACH5oB,KAAKkgB,MAAK,OAAQ,CAAC0I,SAEQ3hB,IAAxBjH,KAAKkqB,gBACRlqB,KAAKkgB,MAAY,OAAC,CAAClgB,KAAKkqB,gBAE1B,CAAE,MAAO/I,GACV,CAAA,EAAC7f,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAQ2Q,CAAAA,Ed3fd,CACNvjB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IckfR,MACkB,YAAjB9C,EAAQhB,MACkB,eAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAO7F,gBAAkBnN,KAAK8hB,wBAC7B9hB,KAAKgT,OAAO7F,gBACZ6F,EAAO7F,gBACPxB,GAGDqH,EAAO5F,gBAAkBpN,KAAKiiB,uBAC7BjiB,KAAKgT,OAAO5F,gBACZ4F,EAAO5F,gBACPzB,GAGDqH,EAAOvE,OAAS,GAETuE,GAEU,YAAjBrH,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOgY,kBACZhY,EAAOrG,WACPhB,GAGDqH,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAO+X,kBACZ/X,EAAOvG,WACPd,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOiY,yBACZ,UACAtf,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAOkY,yBACZ,EACAvf,GAGDqH,EAAOvE,OAAS,GAETuE,GAGDA,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAA7E,KAAC2L,IAEE,eAA1BA,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCL,EAAQjB,SAASE,YAAYK,QAAU,CAK1C,EAAC+jB,CAAA,CApgBmC,CAAQrP,GC5D7B,SAAAqR,GACfrlB,EACAtK,GAEA,MAC2B,UAA1BsK,EAAQjB,SAASC,MACjB+b,GAAkB/a,EAAQjB,SAASE,YAAavJ,EAElD,CCuBa,IAAA4vB,yBAAmB7O,GAK/B,SAAA6O,EAAYjd,GAAqD,IAAAjU,GAChEA,EAAAqiB,EAAAvd,KAAMmP,KAAAA,IAAQhU,MALfgM,KAAO,QAAOjM,EAEN0nB,aAIP,EAAA,IAAME,EAAiB,CACtBe,OAAQ,aAOR,OAHA3oB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAQuH,CAAAA,EAAAA,EAAmB3T,EAAQyT,SAEhCE,EACf5nB,CACF,CAhB+B4F,EAAAsrB,EAAA7O,GAgB9B,IAAA9gB,EAAA2vB,EAAA1vB,UA2HA0vB,OA3HA3vB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQiB,OAC7B,EAACpnB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,IAAKzB,KAAKkgB,MACT,MAAU,IAAAxa,MAAM,iCAGjB,IAAMgF,EAAW,CAChBC,KAAM,QACNC,YAAa,CAACnJ,EAAMe,IAAKf,EAAMgB,MAG1BgI,EAAa,CAAEuB,KAAMhM,KAAKgM,MAEhC,IAAIhM,KAAK+f,UACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACND,SAAAA,EACAD,WAAAA,GAED,CACCrC,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAY4O,SAX3B,CAoBA,IAAAM,EAAkBzoB,KAAKkgB,MAAMwI,OAAO,CAAC,CAAEhe,SAAAA,EAAUD,WAAAA,KAGjDzK,KAAK+gB,SAHS0H,EAGd,GAAuB,CAAEzc,KAAMhM,KAAKgM,KAAMqc,OAAQ,QALlD,CAMD,EAAC/mB,EAGDkC,YAAA,WAAgB,EAAAlC,EAGhBmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,WAAY,EAAAjD,EAGZinB,QAAA,WAAY,EAAAjnB,EAGZwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,WAAW,EAAA5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAQ2Q,CAAAA,EhB5Hd,CACNvjB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IgBmJR,MA/BkB,YAAjB9C,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,OAEjCgH,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAOvG,WACZuG,EAAOvG,WACPd,GAGDqH,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOrG,WACZqG,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOlG,kBACZkG,EAAOlG,kBACPnB,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAOhG,kBACZ,EACArB,GAGDqH,EAAOvE,OAAS,IAGVuE,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCglB,GAAqBrlB,EAAS3L,KAAKqB,oBAKtC,EAAC4vB,CAAA,EA3IsCtR,GC7B3BuR,gBAAsB,SAAA1F,GAClC,SAAA0F,EACU3wB,EACQurB,GAAoC,IAAA/rB,EAAA,OAErDA,EAAAyrB,EAAA3mB,KAAMtE,KAAAA,IAAOP,MAHJO,YAAA,EAAAR,EACQ+rB,mBAAA/rB,EAAAA,EAKVoxB,gBAA4B,GAN1BpxB,EAAMQ,OAANA,EACQR,EAAa+rB,cAAbA,EAAoC/rB,CAGtD,CANkC4F,EAAAurB,EAAA1F,GAMjC,IAAAlqB,EAAA4vB,EAAA3vB,UAQsB,OARtBD,EAUMonB,OAAA,SAAO0I,EAA4BplB,GAAY,IAAAqlB,EAAAC,EACrD,GAAItxB,KAAKuxB,IAAItmB,OACZ,MAAU,IAAAvF,MAAM,8CAGjB,GAAI0rB,EAAenmB,QAAU,EAC5B,MAAU,IAAAvF,MAAM,mCAGjB1F,KAAKmxB,gBAAkBnxB,KAAKkgB,MAAMwI,OAEjC,CACC,CACChe,SAAU,CACTC,KAAM,QACNC,YAAawmB,EAAe,IAE7B3mB,YAAU4mB,EACTrlB,CAAAA,KAAAA,GAAIqlB,EACHlS,IAAmC,EAAIkS,IAI1C,CACC3mB,SAAU,CACTC,KAAM,QACNC,YAAawmB,EAAeA,EAAenmB,OAAS,IAErDR,YAAU6mB,EACTtlB,CAAAA,KAAAA,GAAIslB,EACHnS,IAAmC,EAAImS,KAK7C,EAAChwB,EAAA,OAEM,WACFtB,KAAKuxB,IAAItmB,SACZjL,KAAKkgB,MAAK,OAAQlgB,KAAKuxB,KACvBvxB,KAAKmxB,gBAAkB,GAEzB,EAAC7vB,EAEMkwB,OAAA,SAAOC,GACb,GAAwB,IAApBzxB,KAAKuxB,IAAItmB,OACZ,MAAU,IAAAvF,MAAM,+BAGjB1F,KAAKkgB,MAAM2J,eAEV,CACC,CACCpkB,GAAIzF,KAAKuxB,IAAI,GACb7mB,SAAU,CACTC,KAAM,QACNC,YAAa6mB,EAAmB,KAIlC,CACChsB,GAAIzF,KAAKuxB,IAAI,GACb7mB,SAAU,CACTC,KAAM,QACNC,YAAa6mB,EAAmBA,EAAmBxmB,OAAS,MAKjE,EAAC3J,EAEMowB,eAAA,SAAejwB,GACrB,IAAMkwB,EAAU3xB,KAAKkgB,MAAMgI,gBAAgBloB,KAAKuxB,IAAI,IAC9CK,EAAU5xB,KAAKkgB,MAAMgI,gBAAgBloB,KAAKuxB,IAAI,IAE9C9N,EAAWzjB,KAAK8rB,cAAcJ,QACnCjqB,EACAkwB,EAAQ/mB,aAGHinB,EAAmB7xB,KAAK8rB,cAAcJ,QAC3CjqB,EACAmwB,EAAQhnB,aAMT,MAAO,CAAEknB,UAHSrO,EAAWzjB,KAAKggB,gBAGd+R,kBAFMF,EAAmB7xB,KAAKggB,gBAGnD,EAAClS,EAAAojB,EAAA,CAAA,CAAA5sB,IAAAyJ,MAAAA,IA/FD,WACC,OAAW/N,KAACmxB,gBAAgBrlB,QAC7B,EAACoW,IAED,SAAQvG,GAAe,KAAAuV,CAAA,CAdW,CAAQ/F,ICkD9B6G,gBAAqB5P,SAAAA,GAejC,SAAA4P,EAAYhe,OAAqDjU,GAChEA,EAAAqiB,EAAAvd,KAAA7E,KAAMgU,IAASjU,MAfhBiM,KAAO,UAASjM,EAERkvB,kBAAoB,EAAClvB,EACrBkqB,eAASlqB,EAAAA,EACTynB,eAASznB,EAAAA,EACTmvB,uBAAenvB,EAGfuvB,cAAQ,EAAAvvB,EACR+rB,mBAAa,EAAA/rB,EACbkyB,mBAAalyB,EAAAA,EACb0nB,aAAO1nB,EAAAA,EACPovB,WAAY,EAKnB,IAAMxH,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAcR,GAVCjoB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAA,CAAA,EAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAGhB5nB,EAAKmvB,mBACJlb,QAAgC/M,IAArB+M,EAAQsb,WAAyBtb,EAAQsb,SAI1B,QAAhB,MAAPtb,OAAO,EAAPA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EAAA,GACpB2H,EAAqB/T,EAAQwT,WAClCO,CACL,CAAC,OAAAhoB,CACF,CA3CiC4F,EAAAqsB,EAAA5P,GA2ChC,IAAA9gB,EAAA0wB,EAAAzwB,UA0dAywB,OA1dA1wB,EAEO0mB,MAAA,WACP,QAAuB/gB,IAAnBjH,KAAKiqB,UAAT,CAIA,IAAMiI,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GAKd,KAAIsnB,EAA0BjnB,OAAS,IAIvBjL,KAAKmyB,sBAAqBrmB,GAAAA,OACrComB,EAA0Bta,MAAM,GAAI,GAAE,CAAEsa,EAA0B,KACtE3Y,EAAY4O,QAGb,CAIA,IAAM1G,EAAazhB,KAAKiqB,UAExBjqB,KAAKivB,kBAAoB,EACzBjvB,KAAKiqB,eAAYhjB,EACjBjH,KAAKiyB,cAAa,SAGC,YAAfjyB,KAAKooB,OACRpoB,KAAKygB,aAGNzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QAbrD,CApBA,CAkCD,EAAC/mB,EAGDgf,kBAAA,SAAkB/f,GACjBP,KAAK8rB,cAAgB,IAAIL,GAAsBlrB,GAC/CP,KAAKsvB,SAAW,IAAIzD,GACnBtrB,EACAP,KAAK8rB,cACL,IAAIP,GAAyBhrB,IAE9BP,KAAKiyB,cAAgB,IAAIf,GAAsB3wB,EAAQP,KAAK8rB,cAC7D,EAACxqB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKmvB,WAAY,EACjBnvB,KAAKyI,UAAUzI,KAAKynB,QAAQG,YAEL3gB,IAAnBjH,KAAKiqB,WAAsD,IAA3BjqB,KAAKivB,kBAAzC,CAIA,IAaIwC,EAbEW,EAAepyB,KAAKkvB,gBACvBlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,gBACjDhjB,EAEGirB,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GASd,GAPIwnB,IACH3wB,EAAMe,IAAM4vB,EAAa,GACzB3wB,EAAMgB,IAAM2vB,EAAa,IAKK,IAA3BpyB,KAAKivB,kBAAyB,CAGjC,IAAMnK,EAAU,EAAI1lB,KAAKC,IAAI,GAAIW,KAAKqB,oBAAsB,GACtDgxB,EAASjzB,KAAKkzB,IAAI,KAAUxN,GAElC2M,EAAqB,CACpBS,EAA0B,GAC1B,CAACzwB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,IAAM4vB,GACxBH,EAA0B,GAE5B,SAAsC,IAA3BlyB,KAAKivB,kBACfwC,EAAqB,CACpBS,EAA0B,GAC1BA,EAA0B,GAC1B,CAACzwB,EAAMe,IAAKf,EAAMgB,KAClByvB,EAA0B,QAErB,CACN,IAAAK,EACCvyB,KAAKiyB,cAAcP,eAAejwB,GADC8wB,EAAjBR,mBAAFQ,EAATT,WAIP9xB,KAAKyI,UAAUzI,KAAKynB,QAAQO,OAE5ByJ,EAAkB,GAAA3lB,OACdomB,EAA0Bta,MAAM,GAAI,GACvCsa,CAAAA,EAA0B,GAC1BA,EAA0B,MAG3BT,EAAkB,GAAA3lB,OACdomB,EAA0Bta,MAAM,GAAI,GACvC,CAAA,CAACnW,EAAMe,IAAKf,EAAMgB,KAClByvB,EAA0B,IAG7B,CAEAlyB,KAAKmyB,sBAAsBV,EAAoBlY,EAAYiI,YAzD3D,CA0DD,EAAClgB,EAEO6wB,sBAAA,SACPvnB,EACA2W,GAEA,IAAKvhB,KAAKiqB,UACT,OACD,EAEA,IAAM0F,EAAkB,CACvBhlB,KAAM,UACNC,YAAa,CAACA,IAGf,QAAI5K,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACND,SAAUilB,GAEX,CACCvnB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAAA,MASHvhB,KAAKkgB,MAAM2J,eAAe,CACzB,CAAEpkB,GAAIzF,KAAKiqB,UAAWvf,SAAUilB,KAG1B,GACR,EAACruB,EAGD+C,QAAA,SAAQ5C,GAUP,GALIzB,KAAKivB,kBAAoB,IAAMjvB,KAAKmvB,WACvCnvB,KAAKwD,YAAY/B,GAElBzB,KAAKmvB,WAAY,EAEc,IAA3BnvB,KAAKivB,kBAAyB,CACjC,IAAMmD,EAAepyB,KAAKkvB,gBACvBlvB,KAAKsvB,SAAStD,iCAAiCvqB,QAC/CwF,EAECmrB,IACH3wB,EAAMe,IAAM4vB,EAAa,GACzB3wB,EAAMgB,IAAM2vB,EAAa,IAG1B,IAAA3J,EAAgBzoB,KAAKkgB,MAAMwI,OAAO,CACjC,CACChe,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKiqB,UAhBOxB,EAAA,GAiBZzoB,KAAKivB,oBAGLjvB,KAAKwgB,YACN,MAAW,GAA2B,IAA3BxgB,KAAKivB,mBAA2BjvB,KAAKiqB,UAAW,CAC1D,IAAMmI,EAAepyB,KAAKkvB,gBACvBlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,gBACjDhjB,EAECmrB,IACH3wB,EAAMe,IAAM4vB,EAAa,GACzB3wB,EAAMgB,IAAM2vB,EAAa,IAG1B,IAAMI,EAAyBxyB,KAAKkgB,MAAMgI,gBACzCloB,KAAKiqB,WASN,GALoB8E,GACnB,CAACttB,EAAMe,IAAKf,EAAMgB,KAFQ+vB,EAAuB5nB,YAAY,GAAG,IAOhE,OAaD,IAVgB5K,KAAKmyB,sBACpB,CACCK,EAAuB5nB,YAAY,GAAG,GACtC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB+vB,EAAuB5nB,YAAY,GAAG,IAEvC2O,EAAYkW,QAIZ,OAGDzvB,KAAKivB,mBACN,MAAW,GAA2B,IAA3BjvB,KAAKivB,mBAA2BjvB,KAAKiqB,UAAW,CAC1D,IAAMmI,EAAepyB,KAAKkvB,gBACvBlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,gBACjDhjB,EAECmrB,IACH3wB,EAAMe,IAAM4vB,EAAa,GACzB3wB,EAAMgB,IAAM2vB,EAAa,IAG1B,IAAMF,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GAQd,GALoBmkB,GACnB,CAACttB,EAAMe,IAAKf,EAAMgB,KAFQyvB,EAA0B,IAOpD,OAcD,IAXgBlyB,KAAKmyB,sBACpB,CACCD,EAA0B,GAC1BA,EAA0B,GAC1B,CAACzwB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClByvB,EAA0B,IAE3B3Y,EAAYkW,QAIZ,OAG8B,IAA3BzvB,KAAKivB,mBACRjvB,KAAKiyB,cAAcvJ,OAAOwJ,EAA2B,WAGtDlyB,KAAKivB,mBACN,MAAO,GAAIjvB,KAAKiqB,UAAW,CAC1B,IAAMmI,EAAepyB,KAAKkvB,gBACvBlvB,KAAKsvB,SAASpD,uBAAuBzqB,EAAOzB,KAAKiqB,gBACjDhjB,EAEGirB,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GAEd6nB,EACCzyB,KAAKiyB,cAAcP,eAAejwB,GAEnC,GAHoCgxB,EAAjBV,mBAAFU,EAATX,UAIP9xB,KAAKgoB,YACC,CAaN,GAZIoK,IACH3wB,EAAMe,IAAM4vB,EAAa,GACzB3wB,EAAMgB,IAAM2vB,EAAa,IAKNrD,GACnB,CAACttB,EAAMe,IAAKf,EAAMgB,KAFlByvB,EAA0BlyB,KAAKivB,kBAAoB,IAOnD,OAGD,IAAM7b,QCtaTxI,KAAAA,EDsawC,CAAA,GAAAkB,OAEhComB,EAA0Bta,MAAM,GAAI,IACvC,CAACnW,EAAMe,IAAKf,EAAMgB,KAClByvB,EAA0B,SC1a/BtnB,EAA4B,CAC3B,CACC,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,MAIC,CACND,KAAM,UACND,SAAU,CACTC,KAAM,UACNC,YAAAA,GAEDH,WAAY,KDmaV,IAJgBzK,KAAKmyB,sBACpB/e,EAAe1I,SAASE,YAAY,GACpC2O,EAAYkW,QAGZ,OAEDzvB,KAAKivB,oBAGDjvB,KAAKiyB,cAAcV,IAAItmB,QAC1BjL,KAAKiyB,cAAcT,OAAOpe,EAAe1I,SAASE,YAAY,GAEhE,CACD,CC9bI,IACLA,CD8bA,EAACtJ,EAGDiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDmD,UAAA,aAAcnD,EAGdwC,YAAA,WAGC9D,KAAKyI,UAAU,QAChB,EAACnH,EAGD4C,OAAA,WAAW,EAAA5C,EAGX8C,UAAA,WAECpE,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDinB,QAAA,WACC,IAAMK,EAAY5oB,KAAKiqB,UAEvBjqB,KAAKiqB,eAAYhjB,EACjBjH,KAAKivB,kBAAoB,EACN,YAAfjvB,KAAKooB,OACRpoB,KAAKygB,aAGN,SACmBxZ,IAAd2hB,GACH5oB,KAAKkgB,MAAY,OAAC,CAAC0I,IAEhB5oB,KAAKiyB,cAAcV,IAAItmB,QAC1BjL,KAAKiyB,cAAoB,QAE3B,CAAE,MAAO9Q,GAAO,CACjB,EAAC7f,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,ElBlfN,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IkByeR,GAAI9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,KAAM,CAC1C,GAA8B,YAA1BL,EAAQjB,SAASC,KA0BpB,OAzBAqI,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,GACTuE,EACD,GAA8B,UAA1BrH,EAAQjB,SAASC,KAyB3B,OAxBAqI,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAO+X,kBACZ/X,EAAOvG,WACPd,GAGDqH,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOgY,kBACZhY,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOiY,yBACZjY,EAAOlG,kBACPnB,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAOkY,yBACZ,EACAvf,GAEDqH,EAAOvE,OAAS,GACTuE,CAET,CAEA,OAAOA,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAC8G,KAAAA,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+a,GAAuBpb,EAAS3L,KAAKqB,oBAKxC,EAAC2wB,CAAA,CArgBgC5P,CAAQzC,GEd7B+S,gBAAuBtQ,SAAAA,GAQnC,SAAAsQ,EACC1e,GAAgE,IAAAjU,GAEhEA,EAAAqiB,EAAAvd,KAAA7E,KAAMgU,IAASjU,MAVhBiM,KAAO,YAAWjM,EACVykB,YAAMzkB,EAAAA,EACNunB,WAAa,EAACvnB,EACd4yB,wBAAkB5yB,EAAAA,EAClBynB,eAASznB,EAAAA,EACT0nB,aAOP,EAAA,IAAME,EAAiB,CACtBC,MAAO,aAWR,GAPC7nB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAQuH,CAAAA,EAAAA,EAAmB3T,EAAQyT,SAEhCE,EAKW,QAAhB,MAAP3T,OAAO,EAAPA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EACpB2H,CAAAA,EAAAA,EAAqB/T,EAAQwT,WAClCO,CACL,CAAC,OAAAhoB,CACF,CAlCmC4F,EAAA+sB,EAAAtQ,GAkClC,IAAA9gB,EAAAoxB,EAAAnxB,UAyMAmxB,OAzMApxB,EAEOsxB,gBAAA,SAAgBnxB,EAA4B8f,GACnD,GAAwB,IAApBvhB,KAAKsnB,YAAoBtnB,KAAKwkB,QAAUxkB,KAAK2yB,mBAAoB,CACpE,IAEME,EAFW7yB,KAAKkgB,MAAMgI,gBAAgBloB,KAAK2yB,oBAEpB/nB,YAA6B,GAAG,GAEvDigB,EAAc,CACnBlgB,KAAM,UACNC,YAAa,CACZ,CACCioB,EACA,CAACpxB,EAAMe,IAAKqwB,EAAW,IACvB,CAACpxB,EAAMe,IAAKf,EAAMgB,KAClB,CAACowB,EAAW,GAAIpxB,EAAMgB,KACtBowB,KAKH,GAAI7yB,KAAK+f,WACM/f,KAAK+f,SAClB,CACCta,GAAIzF,KAAK2yB,mBACTjoB,SAAUmgB,GAEX,CACCziB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAAA,IAKD,OAIFvhB,KAAKkgB,MAAM2J,eAAe,CACzB,CACCpkB,GAAIzF,KAAK2yB,mBACTjoB,SAAUmgB,IAGb,CACD,EAACvpB,EAEO0mB,MAAA,WACP,IAAMvG,EAAazhB,KAAK2yB,mBACxB3yB,KAAKwkB,YAASvd,EACdjH,KAAK2yB,wBAAqB1rB,EAC1BjH,KAAKsnB,WAAa,EAEC,YAAftnB,KAAKooB,OACRpoB,KAAKygB,aAGNgB,GACCzhB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QACvD,EAAC/mB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,GAAwB,IAApBzB,KAAKsnB,WAAkB,CAC1BtnB,KAAKwkB,OAAS,CAAC/iB,EAAMe,IAAKf,EAAMgB,KAChC,IAAAgmB,EAAoBzoB,KAAKkgB,MAAMwI,OAAO,CACrC,CACChe,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CACXuB,KAAMhM,KAAKgM,SAIdhM,KAAK2yB,mBAlBWlK,EAAA,GAmBhBzoB,KAAKsnB,aACLtnB,KAAKwgB,YACN,MACCxgB,KAAK4yB,gBAAgBnxB,EAAO8X,EAAY4O,QAExCnoB,KAAKgoB,OAEP,EAAC1mB,EAGDkC,YAAA,SAAY/B,GACXzB,KAAK4yB,gBAAgBnxB,EAAO8X,EAAYiI,YACzC,EAAClgB,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdinB,QAAA,WACC,IAAMK,EAAY5oB,KAAK2yB,mBAEvB3yB,KAAKwkB,YAASvd,EACdjH,KAAK2yB,wBAAqB1rB,EAC1BjH,KAAKsnB,WAAa,EAEC,YAAftnB,KAAKooB,OACRpoB,KAAKygB,kBAGYxZ,IAAd2hB,GACH5oB,KAAKkgB,MAAY,OAAC,CAAC0I,GAErB,EAACtnB,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,EpBjON,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IoBwNR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCgH,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,GAETuE,GAGDA,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCmb,GAAsCxb,EAAS3L,KAAKqB,oBAKvD,EAACqxB,CAAA,CA3OkCtQ,CAAQzC,GCF/BmT,gBAAoB1Q,SAAAA,GAIhC,SAAA0Q,EAAY9e,GAAsD,IAAAjU,EAEpC,OAD7BA,EAAAqiB,EAAAvd,KAAA7E,KAAM,CAAEgT,OAAQgB,EAAQhB,UAAUjT,MAJ5B4K,KAAOsU,EAAU8T,OAAMhzB,EACvBiM,KAAO,SAIbjM,EAAKiM,KAAOgI,EAAQgf,SAASjzB,CAC9B,CAPgC4F,EAAAmtB,EAAA1Q,GAO/B,IAAA9gB,EAAAwxB,EAAAvxB,UAmHA,OAnHAD,EAGDgf,kBAAA,SAAkBC,GAKjBvgB,KAAKgM,KAAOuU,EAAevU,IAC5B,EAAC1K,EAGDsmB,MAAA,WACC5nB,KAAKygB,YACN,EAACnf,EAGDgnB,KAAA,WACCtoB,KAAK0gB,YACN,EAACpf,EAGDiD,QAAA,WAAY,EAAAjD,EAGZmD,UAAA,WAAc,EAAAnD,EAGd+C,QAAA,aAAY/C,EAGZwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdkC,YAAA,WAAgB,EAAAlC,EAGhBinB,QAAA,aAAYjnB,EAGZunB,aAAA,SAAald,GAGZ,MAAO,CACNgB,WAAY3M,KAAK8hB,wBAChB9hB,KAAKgT,OAAOrG,WrBzFF,UqB2FVhB,GAEDc,WAAYzM,KAAKiiB,uBAChBjiB,KAAKgT,OAAOvG,WrB3FF,EqB6FVd,GAEDmB,kBAAmB9M,KAAK8hB,wBACvB9hB,KAAKgT,OAAOlG,kBrBlGK,UqBoGjBnB,GAEDqB,kBAAmBhN,KAAKiiB,uBACvBjiB,KAAKgT,OAAOhG,kBrBtGK,EqBwGjBrB,GAED6B,iBAAkBxN,KAAK8hB,wBACtB9hB,KAAKgT,OAAOxF,iBrBjHI,UqBmHhB7B,GAED4B,mBAAoBvN,KAAKiiB,uBACxBjiB,KAAKgT,OAAOzF,mBrBnHM,GqBqHlB5B,GAED0B,oBAAqBrN,KAAK8hB,wBACzB9hB,KAAKgT,OAAO3F,oBrB1HO,UqB4HnB1B,GAED2B,oBAAqBtN,KAAKiiB,uBACzBjiB,KAAKgT,OAAO1F,oBrB9HO,EqBgInB3B,GAEDyB,gBAAiBpN,KAAKiiB,uBACrBjiB,KAAKgT,OAAO5F,gBrB5HG,EqB8HfzB,GAEDwB,gBAAiBnN,KAAK8hB,wBACrB9hB,KAAKgT,OAAO7F,gBrBlIG,UqBoIfxB,GAED8C,OAAQzO,KAAKiiB,uBACZjiB,KAAKgT,OAAOvE,OrBrIN,EqBuIN9C,GAGH,EAACrK,EAED0f,gBAAA,SAAgBrV,GACf,OACCyW,EAAA7gB,UAAMyf,gBAAenc,KAAC8G,KAAAA,KACrBqlB,GAAqBrlB,EAAS3L,KAAKqB,sBACnC0lB,GAAuBpb,EAAS3L,KAAKqB,+BC1JxCsK,EACAtK,GAEA,MAC2B,eAA1BsK,EAAQjB,SAASC,MACjBgB,EAAQjB,SAASE,YAAYK,QAAU,GACvCU,EAAQjB,SAASE,YAAYoc,MAAM,SAAC9b,GAAU,OAC7Cwb,GAAkBxb,EAAY7J,EAAoB,EAGrD,CDiJI4xB,CAA0BtnB,EAAS3L,KAAKqB,qBAE3C,EAACyxB,CAAA,CA1H+B1Q,CAAQzC,GEjCzB,SAAAuT,GAAatL,EAAiB+E,GAC7C,IAAM9pB,EAAO+kB,EACPuL,EAAKxG,EAMLyG,EAAO7P,EAAiB1gB,EAAK,IAC7BwwB,EAAO9P,EAAiB4P,EAAG,IAC7BG,EAAc/P,EAAiB4P,EAAG,GAAKtwB,EAAK,IAG5CywB,EAAcl0B,KAAKsU,KACtB4f,GAAe,EAAIl0B,KAAKsU,IAErB4f,GAAel0B,KAAKsU,KACvB4f,GAAe,EAAIl0B,KAAKsU,IAGzB,IAAM6f,EAAWn0B,KAAKoX,IACrBpX,KAAKqX,IAAI4c,EAAO,EAAIj0B,KAAKsU,GAAK,GAAKtU,KAAKqX,IAAI2c,EAAO,EAAIh0B,KAAKsU,GAAK,IAK5D8f,GAAW9P,GAFHtkB,KAAKikB,MAAMiQ,EAAaC,IAEK,KAAO,IAIlD,OAFgBC,EAAU,MAAQ,IAAMA,GAAWA,CAGpD,CC/BgB,SAAAC,GACfzP,EACA0P,EACAzP,GAEA,IACI0P,EAAmBD,EADKA,EAAiB,IAI5CC,GAAoBv0B,KAAKw0B,IAAID,IAG9B,IAAME,EAAQF,EAAmBrQ,EAC3BwQ,EAAW9P,EAAO,GAAK5kB,KAAKsU,GAAM,IAClC0f,EAAO7P,EAAiBS,EAAO,IAC/B+P,EAAQxQ,EAAiBU,GAEzB+P,EAAWH,EAAQz0B,KAAKgkB,IAAI2Q,GAC9BV,EAAOD,EAAOY,EAGd50B,KAAKw0B,IAAIP,GAAQj0B,KAAKsU,GAAK,IAC9B2f,EAAOA,EAAO,EAAIj0B,KAAKsU,GAAK2f,GAAQj0B,KAAKsU,GAAK2f,GAG/C,IAAMY,EAAW70B,KAAKoX,IACrBpX,KAAKqX,IAAI4c,EAAO,EAAIj0B,KAAKsU,GAAK,GAAKtU,KAAKqX,IAAI2c,EAAO,EAAIh0B,KAAKsU,GAAK,IAG5DwgB,EAAI90B,KAAKw0B,IAAIK,GAAY,MAASD,EAAWC,EAAW70B,KAAKgkB,IAAIgQ,GAMjEhc,EAAc,EACN,KAJE0c,EADKD,EAAQz0B,KAAK+jB,IAAI4Q,GAAUG,GAK3B90B,KAAKsU,GAAK,KAAO,IAAO,IACpC,IAAP2f,EAAcj0B,KAAKsU,IAWrB,OANA0D,EAAY,IACXA,EAAY,GAAK4M,EAAO,GAAK,KACzB,IACDA,EAAO,GAAK5M,EAAY,GAAK,IAC7B,IACA,EACGA,CACR,CC7CM,SAAU+c,GACfC,EACAC,EACAvN,EACA1e,EACAI,GAEA,IAAM8rB,EAAyBlsB,EAAQgsB,EAAa,GAAIA,EAAa,IAC/DG,EAAyBnsB,EAAQisB,EAAa,GAAIA,EAAa,IAErEG,EAAqBhsB,GACnB8rB,EAAuB30B,EAAI40B,EAAuB50B,GAAK,GACvD20B,EAAuB50B,EAAI60B,EAAuB70B,GAAK,GAF5C+C,EAAG+xB,EAAH/xB,IAKb,MAAO,CAACzD,EALGw1B,EAAHhyB,IAKoBskB,GAAY9nB,EAAeyD,EAAKqkB,GAC7D,UAGgB2N,GACfL,EACAC,EACAvN,GAEA,IAEM4N,EAAWjB,GAAiBW,EAFqC,IAA1DzR,EAA4ByR,EAAcC,GAEA,EADvCnB,GAAakB,EAAcC,IAE3C,MAAO,CACNr1B,EAAe01B,EAAS,GAAI5N,GAC5B9nB,EAAe01B,EAAS,GAAI5N,GAE9B,CCjCgB,SAAA6N,GAAsB70B,GAcrC,IAbA,IAAA80B,EAAa90B,EAAb80B,cACA9N,EAAShnB,EAATgnB,UACAte,EAAS1I,EAAT0I,UACAJ,EAAOtI,EAAPsI,QACAL,EAAUjI,EAAViI,WAQM8sB,EAA6B,GAC1B7pB,EAAI,EAAGA,EAAI4pB,EAAc3pB,OAAS,EAAGD,IAAK,CAClD,IAAI8pB,OACJ,EAAA,GAAmB,iBAAf/sB,EACH+sB,EAAMX,GACLS,EAAc5pB,GACd4pB,EAAc5pB,EAAI,GAClB8b,EACA1e,EACAI,OAEK,IAAmB,UAAfT,EAOV,UAAUrC,MAAM,sBANhBovB,EAAML,GACLG,EAAc5pB,GACd4pB,EAAc5pB,EAAI,GAClB8b,EAIF,CAEA+N,EAAe1pB,KAAK2pB,EACrB,CACA,OAAOD,CACR,CCnCa,IAAAE,gBAAiB,SAAAvJ,GAC7B,SAAAuJ,EACUx0B,EACQy0B,GAA8C,IAAAj1B,EAAA,OAE/DA,EAAAyrB,EAAA3mB,KAAA7E,KAAMO,IAAQR,MAHLQ,YAAAR,EAAAA,EACQi1B,4BAAAj1B,EAAAA,EAKVk1B,WAAuB,GANrBl1B,EAAMQ,OAANA,EACQR,EAAsBi1B,uBAAtBA,EAA8Cj1B,CAGhE,CAN6B4F,EAAAovB,EAAAvJ,GAM5B,IAAAlqB,EAAAyzB,EAAAxzB,UAQsBwzB,OARtBzzB,EAUM4zB,OAAA,SAAOC,EAAoB9zB,GACjC,IAAM+zB,EAAWp1B,KAAKkgB,MAAMgI,gBAAgBiN,GAC5CE,EACCr1B,KAAKkgB,MAAMoV,kBAAkBH,GADtBI,EAAiBF,EAAjBE,kBAAmBC,EAAeH,EAAfG,gBAErB9qB,EAAW1K,KAAKkgB,MAAMgI,gBAC3BqN,GAIK9D,EACa,YAAlB/mB,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAEb6mB,EAAmBgE,OACjBD,EAA6B,EAC9B,EACAJ,EAASxqB,aAKVF,EAASE,YACU,YAAlBF,EAASC,KAAqB,CAAC8mB,GAAsBA,EAItDzxB,KAAKkgB,MAAM2J,eAAe,CAAC,CAAEpkB,GAAI8vB,EAA6B7qB,SAAAA,KAM9D1K,KAAKkgB,MAAK,OAAOpU,GAAAA,OAAK9L,KAAKi1B,WAAej1B,KAAKg1B,uBAAuBzD,MAItEvxB,KAAK0oB,OACJ+I,EACA8D,EACAl0B,GAEDrB,KAAKg1B,uBAAuBtM,OAC3B+I,EACA/mB,EAASC,KACT4qB,EAEF,EAACj0B,EAEMonB,OAAA,SACN0I,EACAsE,EACAr0B,GAA2B,IAAA4E,EAAAjG,KAE3B,IAAKA,KAAKkgB,MAAMtS,IAAI8nB,GACnB,MAAM,IAAIhwB,MAAM,4CAGjB1F,KAAKi1B,WAAaj1B,KAAKkgB,MAAMwI,ODrCf,SACf0I,EACA3mB,EACAqc,EACA1e,EACAI,EACAT,GAEA,OAAO4sB,GAAuB,CAC7BC,cAAexD,EACftK,UAAAA,EACA1e,QAAAA,EACAI,UAAAA,EACAT,WAAAA,IACExC,IAAI,SAACsf,EAAO7Z,GAAO,MAAA,CACrBN,SAAU,CAAEC,KAAM,QAASC,YAAaia,GACxCpa,WAAYA,EAAWO,GACvB,EACF,CCoBG2qB,CACCvE,EACA,SAACpmB,GAAC,IAAAlL,EAAA,OAAAA,EAAA,CACDkM,KAAM/F,EAAK+F,OACVkT,IAA8B,EAAIpf,EACnC01B,gBAAiBxqB,EAAClL,EAClBy1B,kBAAmBG,EAAS51B,CAAA,EAE7BuB,EACArB,KAAKO,OAAO6H,QACZpI,KAAKO,OAAOiI,UACZxI,KAAK+H,YAGR,EAACzG,EAAA,OAEM,WACFtB,KAAKi1B,WAAWhqB,SACnBjL,KAAKkgB,MAAY,OAAClgB,KAAKi1B,YACvBj1B,KAAKi1B,WAAa,GAEpB,EAAC3zB,EAEMs0B,WAAA,SAAWnE,GAA8B9nB,IAAAA,EAC/C3J,KAAA,GAA+B,IAA3BA,KAAKi1B,WAAWhqB,OAIpB,OAAO0pB,GAAuB,CAC7BC,cAAenD,EACf3K,UAAW9mB,KAAKqB,oBAChB+G,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBT,WAAY/H,KAAKO,OAAOwH,aACtBxC,IAAI,SAACswB,EAAsB7qB,GAAC,MAAM,CACpCvF,GAAIkE,EAAKsrB,WAAWjqB,GACpBN,SAAU,CACTC,KAAM,QACNC,YAAairB,GAEd,EACF,EAAC/nB,EAAAinB,EAAAzwB,CAAAA,CAAAA,IAAAyJ,MAAAA,IA1GD,WACC,OAAW/N,KAACi1B,WAAWnpB,QACxB,EAACoW,IAED,SAAQvG,QAAeoZ,CAAA,CAdM,CAAQ5J,ICLzB2K,gBAAuB,SAAAtK,GACnC,SAAAsK,EAAYv1B,GAAsBR,IAAAA,EAIQ,OAHzCA,EAAAyrB,EAAA3mB,KAAA7E,KAAMO,IAAQR,MAGPg2B,iBAAgC,GAAEh2B,CAF1C,CAHmC4F,EAAAmwB,EAAAtK,GAGlC,IAAAlqB,EAAAw0B,EAAAv0B,UAQyBu0B,OARzBx0B,EAUMonB,OAAA,SACN0I,EACAzmB,EACA+qB,GAAoB,IAAAzvB,EAAAjG,KAEpBA,KAAK+1B,iBAAmB/1B,KAAKkgB,MAAMwI,gBCnBpC0I,EACA4E,EACAvrB,GAWA,IATA,IAAMwrB,EAAkB,GAIlBhrB,EACY,YAAjB+qB,EACG5E,EAAenmB,OAAS,EACxBmmB,EAAenmB,OAEVD,EAAI,EAAGA,EAAIC,EAAQD,IAC3BirB,EAAgB9qB,KAAK,CACpBT,SAAU,CACTC,KAAM,QACNC,YAAawmB,EAAepmB,IAE7BP,WAAYA,EAAWO,KAIzB,OAAOirB,CACR,CDJGC,CAAuB9E,EAAgBzmB,EAAM,SAACK,SAAO,CACpDgB,KAAM/F,EAAK+F,KACXmqB,gBAAgB,EAChBC,wBAAyBV,EACzBW,MAAOrrB,EACP,GAEH,EAAC1J,EAAA,OAEM,WACFtB,KAAKuxB,IAAItmB,SACZjL,KAAKkgB,MAAK,OAAQlgB,KAAKuxB,KACvBvxB,KAAK+1B,iBAAmB,GAE1B,EAACz0B,EAEMs0B,WAAA,SAAWnE,GACjB,GAAqC,IAAjCzxB,KAAK+1B,iBAAiB9qB,OAI1B,OAAOjL,KAAK+1B,iBAAiBxwB,IAAI,SAACE,EAAIuF,GACrC,MAAO,CACNvF,GAAAA,EACAiF,SAAU,CACTC,KAAM,QACNC,YAAa6mB,EAAmBzmB,IAGnC,EACD,EAAC1J,EAEMg1B,cAAA,SAAcD,EAAeE,GACnC,QAAqCtvB,IAAjCjH,KAAK+1B,iBAAiBM,GAI1B,MAAO,CACN5wB,GAAIzF,KAAK+1B,iBAAiBM,GAC1B3rB,SAAU,CACTC,KAAM,QACNC,YAAa2rB,GAGhB,EAACzoB,EAAAgoB,EAAA,CAAA,CAAAxxB,IAAAyJ,MAAAA,IAxDD,WACC,YAAYgoB,iBAAiBjqB,QAC9B,EAACoW,IAED,SAAQvG,GAAkB,KAAAma,CAAA,CAXS,CAAQ3K,aEC5BqL,GAAenuB,EAAiBoW,GAE/C,IADA,IAYqBgY,EAAaC,EAAcC,EAZ5CC,GAAS,EACJ5rB,EAAI,EAAG6rB,EAAMpY,EAAMxT,OAAQD,EAAI6rB,EAAK7rB,IAE5C,IADA,IAAM8rB,EAAOrY,EAAMzT,GACVM,EAAI,EAAGyrB,EAAOD,EAAK7rB,OAAQ+rB,EAAID,EAAO,EAAGzrB,EAAIyrB,EAAMC,EAAI1rB,KAS/BorB,EARRI,EAAKxrB,IAU3B,IAFiBmrB,EARFpuB,GAUR,KAFqCsuB,EARbG,EAAKE,IAUnB,GAAKP,EAAE,IAC3BA,EAAE,IAAOE,EAAG,GAAKD,EAAG,KAAOD,EAAE,GAAKC,EAAG,KAAQC,EAAG,GAAKD,EAAG,IAAMA,EAAG,KAV/DE,GAAUA,GAIb,OAAOA,CACR,CCjBO,IAAMK,GAAsB,SAClC5uB,EACA6uB,EACAC,GAEA,IAAMC,EAAS,SAACz3B,GACf,OAAOA,EAAIA,CACZ,EACM03B,EAAQ,SAACC,EAA6BC,GAC3C,OAAOH,EAAOE,EAAE33B,EAAI43B,EAAE53B,GAAKy3B,EAAOE,EAAE53B,EAAI63B,EAAE73B,EAC3C,EAkBA,OAAON,KAAKQ,KAjBiB,SAC5B62B,EACAa,EACAC,GAEA,IAAMC,EAAKH,EAAMC,EAAGC,GAEpB,GAAW,IAAPC,EACH,OAAOH,EAAMZ,EAAGa,GAGjB,IAAIG,IAAMhB,EAAE92B,EAAI23B,EAAE33B,IAAM43B,EAAE53B,EAAI23B,EAAE33B,IAAM82B,EAAE/2B,EAAI43B,EAAE53B,IAAM63B,EAAE73B,EAAI43B,EAAE53B,IAAM83B,EAGlE,OAFAC,EAAIr4B,KAAKkzB,IAAI,EAAGlzB,KAAKs4B,IAAI,EAAGD,IAErBJ,EAAMZ,EAAG,CAAE92B,EAAG23B,EAAE33B,EAAI83B,GAAKF,EAAE53B,EAAI23B,EAAE33B,GAAID,EAAG43B,EAAE53B,EAAI+3B,GAAKF,EAAE73B,EAAI43B,EAAE53B,IACnE,CAEiBi4B,CAAqBtvB,EAAO6uB,EAAcC,GAC5D,ECnBaS,gBAA8BpM,SAAAA,GAC1C,SAAAoM,EACUr3B,EACQs3B,EACA/L,GAAoC,IAAA/rB,EAAA,OAErDA,EAAAyrB,EAAA3mB,KAAA7E,KAAMO,IAAQR,MAJLQ,YAAAR,EAAAA,EACQ83B,4BAAA93B,EAAAA,EACA+rB,mBAAA,EAFR/rB,EAAMQ,OAANA,EACQR,EAAsB83B,uBAAtBA,EACA93B,EAAa+rB,cAAbA,EAAoC/rB,CAGtD,CAgGC63B,OAvGyCjyB,EAAAiyB,EAAApM,GAOzCoM,EAAAr2B,UAEMmF,KAAA,SAAKjF,EAA4Bq2B,GAYvC,IAXA,IAAIC,OAAiD9wB,EACjD+wB,EAAuBrR,SACvBsR,OAAsDhxB,EACtDixB,EAA4BvR,SAC5BwR,OAAoDlxB,EACpDmxB,EAA0BzR,SAC1B0R,OAAmDpxB,EAEjDolB,EAAOrsB,KAAK63B,uBAAuBnP,OAAOjnB,GAC1CoK,EAAW7L,KAAKkgB,MAAMoM,OAAOD,GAE1BrhB,EAAI,EAAGA,EAAIa,EAASZ,OAAQD,IAAK,CACzC,IAAMW,EAAUE,EAASb,GACnBN,EAAWiB,EAAQjB,SAEzB,GAAsB,UAAlBA,EAASC,KAAkB,CAO9B,GAJyBgB,EAAQlB,WAAW0rB,iBAE1C2B,GAAgBnsB,EAAQlB,WAAWyU,GAGpC,SAGD,IAAMuE,EAAWzjB,KAAK8rB,cAAcJ,QACnCjqB,EACAiJ,EAASE,aAOTe,EAAQlB,WAAWyU,IACnBuE,EAAWzjB,KAAKggB,iBAChByD,EAAW2U,GAEXA,EAA0B3U,EAC1B0U,EAAkBxsB,IAEjBA,EAAQlB,WAAWyU,IACpBuE,EAAWzjB,KAAKggB,iBAChByD,EAAWuU,IAEXA,EAAuBvU,EACvBsU,EAAepsB,EAEjB,MAAWjB,GAAkB,eAAlBA,EAASC,KAAuB,CAC1C,GAAIotB,EACH,SAGD,IAAK,IAAI/sB,EAAI,EAAGA,EAAIN,EAASE,YAAYK,OAAS,EAAGD,IAAK,CACzD,IAAM6Z,EAAQna,EAASE,YAAYI,GAC7BstB,EAAY5tB,EAASE,YAAYI,EAAI,GACrCutB,EAAiBtB,GACtB,CAAEt3B,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,YAChClC,KAAKoI,QAAQyc,EAAM,GAAIA,EAAM,IAC7B7kB,KAAKoI,QAAQkwB,EAAU,GAAIA,EAAU,KAIrCC,EAAiBv4B,KAAKggB,iBACtBuY,EAAiBL,IAEjBA,EAA4BK,EAC5BN,EAAoBtsB,EAEtB,CACD,MAAO,GAAsB,YAAlBjB,EAASC,KAAoB,CACvC,GAAIotB,GAAgBE,EAGnB,SAG0BzB,GAC1B,CAAC/0B,EAAMe,IAAKf,EAAMgB,KAClBiI,EAASE,eAITytB,EAAiB1sB,EAEnB,CACD,CAEA,MAAO,CACN6sB,eAAgBT,GAAgBE,GAAqBI,EACrDF,gBAAAA,EAEF,EAACP,CAAA,CAvGyCpM,CAAQL,ICDtCsN,yBAAoBjN,GAChC,SAAAiN,EACUl4B,EACQm4B,EACAzC,EACA0C,OAA2B54B,EAAA,OAE5CA,EAAAyrB,EAAA3mB,UAAMtE,UALGA,YAAAR,EAAAA,EACQ24B,4BAAA34B,EACAk2B,qBAAAl2B,EAAAA,EACA44B,eAAA,EAAA54B,EAKV64B,iBAAqC,KAAI74B,EAEzC84B,kBAVE94B,EAAAA,EAAMQ,OAANA,EACQR,EAAoB24B,qBAApBA,EACA34B,EAAek2B,gBAAfA,EACAl2B,EAAS44B,UAATA,EAA2B54B,CAG7C,CARgC4F,EAAA8yB,EAAAjN,GAQ/B,IAAAlqB,EAAAm3B,EAAAl3B,UAuJAk3B,OAvJAn3B,EAMDw3B,cAAA,SAAcr3B,EAA4BgE,GACzCzF,KAAK44B,iBAAmBnzB,EACxBzF,KAAK64B,aAAe,CAACp3B,EAAMe,IAAKf,EAAMgB,IACvC,EAACnB,EAEDy3B,aAAA,WACC/4B,KAAK44B,iBAAmB,KACxB54B,KAAK64B,kBAAe5xB,CACrB,EAAC3F,EAED03B,WAAA,WACC,OAAiC,OAA1Bh5B,KAAK44B,gBACb,EAACt3B,EAED23B,QAAA,SAAQx3B,EAA4BmgB,GACnC,IAAQ4W,EAAmBx4B,KAAK04B,qBAAqBhyB,KAAKjF,GAAO,GAAzD+2B,eAIR,SAAKA,GAAkBA,EAAe/yB,KAAOmc,EAK9C,EAACtgB,EAED43B,KAAA,SAAKz3B,EAA4Buf,GAChC,GAAKhhB,KAAK44B,iBAAV,CAIA,IAAMluB,EAAW1K,KAAKkgB,MAAMgI,gBAAgBloB,KAAK44B,kBAC3CO,EAAa,CAAC13B,EAAMe,IAAKf,EAAMgB,KAGrC,GAAsB,YAAlBiI,EAASC,MAAwC,eAAlBD,EAASC,KAAuB,CAClE,IAAIyuB,EACAC,EAWJ,GAPCA,EAFqB,YAAlB3uB,EAASC,MACZyuB,EAAgB1uB,EAASE,YAAY,IACXK,OAAS,GAGnCmuB,EAAgB1uB,EAASE,aACCK,QAGtBjL,KAAK64B,aACT,OAAO,EAGR,IAAK,IAAI7tB,EAAI,EAAGA,EAAIquB,EAAWruB,IAAK,CACnC,IAAME,EAAakuB,EAAcpuB,GAC3B6oB,EAAQ,CACb7zB,KAAK64B,aAAa,GAAKM,EAAW,GAClCn5B,KAAK64B,aAAa,GAAKM,EAAW,IAI7BG,EAAat6B,EAClBkM,EAAW,GAAK2oB,EAAM,GACtB7zB,KAAKO,OAAOc,qBAGPk4B,EAAav6B,EAClBkM,EAAW,GAAK2oB,EAAM,GACtB7zB,KAAKO,OAAOc,qBAMb,GACCi4B,EAAa,KACbA,GAAc,KACdC,EAAa,IACbA,GAAc,GAEd,OAAO,EAGRH,EAAcpuB,GAAK,CAACsuB,EAAYC,EACjC,CAIsB,YAAlB7uB,EAASC,OACZyuB,EAAcA,EAAcnuB,OAAS,GAAK,CACzCmuB,EAAc,GAAG,GACjBA,EAAc,GAAG,KAInB,IAAMI,EACLx5B,KAAKi2B,gBAAgBL,WAAWwD,IAAkB,GAE7CK,EAAmBz5B,KAAK24B,UAAU/C,WAAWwD,IAAkB,GAErE,GAAIpY,IACWA,EACb,CACCrW,KAAM,UACNlF,GAAIzF,KAAK44B,iBACTluB,SAAAA,EACAD,WAAY,IAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,oBACjCkgB,WAAYhI,EAAYiI,cAKzB,OACD,EAIDxhB,KAAKkgB,MAAM2J,gBACV,CAAEpkB,GAAIzF,KAAK44B,iBAAkBluB,SAAAA,IAAUoB,OACpC0tB,EACAC,IAGJz5B,KAAK64B,aAAe,CAACp3B,EAAMe,IAAKf,EAAMgB,IAGvC,KAA6B,UAAlBiI,EAASC,OAGnB3K,KAAKkgB,MAAM2J,eAAe,CACzB,CACCpkB,GAAIzF,KAAK44B,iBACTluB,SAAU,CACTC,KAAM,QACNC,YAAauuB,MAKhBn5B,KAAK64B,aAAe,CAACp3B,EAAMe,IAAKf,EAAMgB,KAlHvC,CAoHD,EAACg2B,CAAA,EA/JuCtN,ICC5BuO,gBAAuBlO,SAAAA,GACnC,SAAAkO,EACUn5B,EACQurB,EACAmK,EACA0C,GAA2B,IAAA54B,EAAA,OAE5CA,EAAAyrB,EAAA3mB,KAAMtE,KAAAA,IAAQR,MALLQ,YAAA,EAAAR,EACQ+rB,qBAAA/rB,EACAk2B,qBAAAl2B,EAAAA,EACA44B,eAAA,EAAA54B,EAKV45B,kBAA6D,CACpEl0B,GAAI,KACJ4wB,OAAQ,GAVCt2B,EAAMQ,OAANA,EACQR,EAAa+rB,cAAbA,EACA/rB,EAAek2B,gBAAfA,EACAl2B,EAAS44B,UAATA,EAA2B54B,CAG7C,CARmC4F,EAAA+zB,EAAAlO,GAQlC,IAAAlqB,EAAAo4B,EAAAn4B,UA8LA,OA9LAD,EAOOs4B,qBAAA,SACPn4B,EACAiJ,GAEA,IAMImvB,EANEC,EAAoB,CACzBrN,KAAM9F,SACN0P,OAAQ,EACR0D,2BAA2B,GAK5B,GAAsB,eAAlBrvB,EAASC,KACZkvB,EAAkBnvB,EAASE,oBACC,YAAlBF,EAASC,KAKnB,OAAOmvB,EAJPD,EAAkBnvB,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAII,EAAI,EAAGA,EAAI6uB,EAAgB5uB,OAAQD,IAAK,CAChD,IACMyY,EAAWzjB,KAAK8rB,cAAcJ,QAAQjqB,EAD9Bo4B,EAAgB7uB,IAG9B,GACCyY,EAAWzjB,KAAKggB,iBAChByD,EAAWqW,EAAkBrN,KAC5B,CAID,IAAMsN,EACa,YAAlBrvB,EAASC,OACRK,IAAM6uB,EAAgB5uB,OAAS,GAAW,IAAND,GAEtC8uB,EAAkBrN,KAAOhJ,EACzBqW,EAAkBzD,MAAQ0D,EAA4B,EAAI/uB,EAC1D8uB,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACx4B,EAEM04B,kBAAA,SACNv4B,EACAmgB,GAEA,IAAMlX,EAAW1K,KAAKkgB,MAAMgI,gBAAgBtG,GACtCkY,EAAoB95B,KAAK45B,qBAAqBn4B,EAAOiJ,GAG3D,OAAiC,IAA7BovB,EAAkBzD,OACb,EAEFyD,EAAkBzD,KAC1B,EAAC/0B,EAEM43B,KAAA,SACNz3B,EACAw4B,EACAjZ,GAEA,IAAKhhB,KAAK25B,kBAAkBl0B,GAC3B,OAAO,EAER,IAAM4wB,EAAQr2B,KAAK25B,kBAAkBtD,MAC/B3rB,EAAW1K,KAAKkgB,MAAMgI,gBAAgBloB,KAAK25B,kBAAkBl0B,IAE7Do0B,EACa,eAAlBnvB,EAASC,KACND,EAASE,YACTF,EAASE,YAAY,GAQnB2rB,EAAoB,CAAC90B,EAAMe,IAAKf,EAAMgB,KAK5C,GACChB,EAAMe,IAAM,KACZf,EAAMe,KAAO,KACbf,EAAMgB,IAAM,IACZhB,EAAMgB,KAAO,GAEb,OAAO,EAKR,GApBmB,YAAlBiI,EAASC,MACR0rB,IAAUwD,EAAgB5uB,OAAS,GAAe,IAAVorB,EAwBzCwD,EAAgBxD,GAASE,MALK,CAC9B,IAAM2D,EAAiBL,EAAgB5uB,OAAS,EAChD4uB,EAAgB,GAAKtD,EACrBsD,EAAgBK,GAAkB3D,CACnC,CAIA,IAAM4D,EAAwBn6B,KAAKi2B,gBAAgBK,cAClDD,EACAE,GAGKiD,EAAyBW,EAC5B,CAACA,GACD,GAEGV,EAAmBz5B,KAAK24B,UAAU/C,WAAWiE,IAAoB,GAEvE,QACmB,UAAlBnvB,EAASC,OACRsvB,GACDrV,GAAe,CACdja,KAAM,UACND,SAAUA,EACVD,WAAY,CAAA,KAMVuW,IACWA,EACb,CACCrW,KAAM,UACNlF,GAAIzF,KAAK25B,kBAAkBl0B,GAC3BiF,SAAAA,EACAD,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,oBACjCkgB,WAAYhI,EAAYiI,gBAU3BxhB,KAAKkgB,MAAM2J,eAAc,CAExB,CACCpkB,GAAIzF,KAAK25B,kBAAkBl0B,GAC3BiF,SAAUA,IACVoB,OAEE0tB,EACAC,IAGG,GACR,EAACn4B,EAED03B,WAAA,WACC,OAAqC,OAA9Bh5B,KAAK25B,kBAAkBl0B,EAC/B,EAACnE,EAEDw3B,cAAA,SAAcrzB,EAAe4wB,GAC5Br2B,KAAK25B,kBAAoB,CACxBl0B,GAAAA,EACA4wB,MAAAA,EAEF,EAAC/0B,EAEDy3B,aAAA,WACC/4B,KAAK25B,kBAAoB,CACxBl0B,GAAI,KACJ4wB,OAAQ,EAEV,EAACqD,CAAA,CAtMkClO,CAAQL,ICLtC,SAAUiP,GAASC,GACxB,IAAIC,EAAO,EACPC,EAAO,EACP1D,EAAM,EAaV,OAV2B,YAA1BwD,EAAQ3vB,SAASC,KACd0vB,EAAQ3vB,SAASE,YAAY,GAAGgN,MAAM,GAAI,GAC1CyiB,EAAQ3vB,SAASE,aAET5H,QAAQ,SAAC6hB,GACpByV,GAAQzV,EAAM,GACd0V,GAAQ1V,EAAM,GACdgS,GACD,GAAG,GAEI,CAACyD,EAAOzD,EAAK0D,EAAO1D,EAC5B,UChBgB2D,GAAcpjB,EAAuB4M,GAGpD5M,EAAY,IACXA,EAAY,GAAK4M,EAAO,GAAK,KACzB,IACDA,EAAO,GAAK5M,EAAY,GAAK,IAC7B,IACA,EAIJ,IAAMyM,EAAIP,EACJ8P,EAAQpP,EAAO,GAAK5kB,KAAKsU,GAAM,IAC/B2f,EAAQjc,EAAY,GAAKhY,KAAKsU,GAAM,IACpCsgB,EAAWX,EAAOD,EACpBqH,EAAer7B,KAAKw0B,IAAIxc,EAAY,GAAK4M,EAAO,IAAM5kB,KAAKsU,GAAM,IAGjE+mB,EAAcr7B,KAAKsU,KACtB+mB,GAAe,EAAIr7B,KAAKsU,IAKzB,IAAMugB,EAAW70B,KAAKoX,IACrBpX,KAAKqX,IAAI4c,EAAO,EAAIj0B,KAAKsU,GAAK,GAAKtU,KAAKqX,IAAI2c,EAAO,EAAIh0B,KAAKsU,GAAK,IAE5DwgB,EAAI90B,KAAKw0B,IAAIK,GAAY,MAASD,EAAWC,EAAW70B,KAAKgkB,IAAIgQ,GASvE,OANch0B,KAAKQ,KAClBo0B,EAAWA,EAAWE,EAAIA,EAAIuG,EAAcA,GAGd5W,CAGhC,UCnCgB6W,GAAoB/uB,GACnC,IAKMgvB,GAJqB,YAA1BhvB,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAEsBrF,IAAI,SAACsf,GAC/C,IAAAuE,EAAiBtF,GAAsBe,EAAM,GAAIA,EAAM,IACvD,MAAO,CADEuE,EAADzpB,EAAIypB,EAAD1pB,EAEZ,GAEA,MAA8B,YAA1BiM,EAAQjB,SAASC,KAOtB,SAAkCgwB,GAUjC,IANA,IAAIC,EAAO,EACPC,EAAY,EACZC,EAAY,EAEVC,EAAIJ,EAAuB1vB,OAExBD,EAAI,EAAGA,EAAI+vB,EAAI,EAAG/vB,IAAK,CAC/B,IAAAgwB,EAAiBL,EAAuB3vB,GAAjC+a,EAAEiV,KAAEhV,EAAEgV,EAAA,GACbC,EAAiBN,EAAuB3vB,EAAI,GAArCib,EAAEgV,EAAA,GAAE/U,EAAE+U,KAEPC,EAAenV,EAAKG,EAAKD,EAAKD,EACpC4U,GAAQM,EACRL,IAAc9U,EAAKE,GAAMiV,EACzBJ,IAAc9U,EAAKE,GAAMgV,CAC1B,CAMA,MAAO,CAAEv7B,EAHTk7B,GAAa,GADbD,GAAQ,GAIel7B,EAFvBo7B,GAAa,EAAIF,EAGlB,CA/BSO,CAAyBR,GAiClC,SAAqCS,GAQpC,IAJA,IAAML,EAAIK,EAAWnwB,OACjBowB,EAAS,EACTC,EAAS,EAEJtwB,EAAI,EAAGA,EAAI+vB,EAAG/vB,IAAK,CAC3B,IAAAuwB,EAAeH,EAAWpwB,GAC1BqwB,GADQE,KAERD,GAFWC,EACXF,EAED,CAEA,MAAO,CAAE17B,EAAG07B,EAASN,EAAGr7B,EAAG47B,EAASP,EACrC,CA9CSS,CAA4Bb,EAErC,KCRac,gBAAsBjQ,SAAAA,GAClC,SAAAiQ,EACUl7B,EACQ01B,EACA0C,GAA2B54B,IAAAA,EAAA,OAE5CA,EAAAyrB,EAAA3mB,KAAA7E,KAAMO,IAAQR,MAJLQ,YAAA,EAAAR,EACQk2B,qBAAA,EAAAl2B,EACA44B,eAAA54B,EAAAA,EAKV27B,iBAPE37B,EAAAA,EAAMQ,OAANA,EACQR,EAAek2B,gBAAfA,EACAl2B,EAAS44B,UAATA,EAA2B54B,CAG7C,CAPkC4F,EAAA81B,EAAAjQ,GAOjC,IAAAlqB,EAAAm6B,EAAAl6B,UAgHAk6B,OAhHAn6B,EAIDq6B,MAAA,WACC37B,KAAK07B,iBAAcz0B,CACpB,EAAC3F,EAEDs6B,OAAA,SACCn6B,EACAmgB,EACAZ,GAA4B,IAAA/a,EAAAjG,KAEtB0K,EAAW1K,KAAKkgB,MAAMgI,gBAC3BtG,GAID,GAAsB,YAAlBlX,EAASC,MAAwC,eAAlBD,EAASC,KAA5C,CAIA,IAEIsZ,EAFEkV,EAAa,CAAC13B,EAAMe,IAAKf,EAAMgB,KAG/BkJ,EAAU,CAAEhB,KAAM,UAAWD,SAAAA,EAAUD,WAAY,CAAA,GAIzD,GAA+B,iBAA3BzK,KAAKO,OAAOwH,WAA+B,CAM9C,GAFAkc,EAAU+I,GAHgB0N,GAAoB/uB,GACpBmY,GAAsBriB,EAAMe,IAAKf,EAAMgB,OAI5DzC,KAAK07B,YAET,YADA17B,KAAK07B,YAAczX,ICZmB,SACzCtY,EACA6d,GAEA,GAAc,IAAVA,GAAyB,MAAVA,IAA4B,MAAXA,EACnC,OAAO7d,EAGR,IAMMkwB,EANqB,oBAMVrS,EAGXsS,GANqB,YAA1BnwB,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAIiBrF,IAAI,SAAAzF,GACzC,OAAAgkB,GAD8ChkB,EAAE2C,GAAG3C,EACnD,GAA+B,GAI1Bs6B,EAAW0B,EAAkBC,OAClC,SAACC,EAA+BnX,GAAqC,MAAA,CACpEllB,EAAGq8B,EAAIr8B,EAAIklB,EAAMllB,EACjBD,EAAGs8B,EAAIt8B,EAAImlB,EAAMnlB,EACjB,EACD,CAAEC,EAAG,EAAGD,EAAG,IAEZ06B,EAASz6B,GAAKm8B,EAAkB7wB,OAChCmvB,EAAS16B,GAAKo8B,EAAkB7wB,OAGhC,IAYMgxB,EAZ2BH,EAAkBv2B,IAAI,SAACsf,GAAK,MAAM,CAClEllB,EACCy6B,EAASz6B,GACRklB,EAAMllB,EAAIy6B,EAASz6B,GAAKP,KAAKgkB,IAAIyY,IACjChX,EAAMnlB,EAAI06B,EAAS16B,GAAKN,KAAK+jB,IAAI0Y,GACnCn8B,EACC06B,EAAS16B,GACRmlB,EAAMllB,EAAIy6B,EAASz6B,GAAKP,KAAK+jB,IAAI0Y,IACjChX,EAAMnlB,EAAI06B,EAAS16B,GAAKN,KAAKgkB,IAAIyY,GACnC,GAGmDt2B,IACnD,SAAAqB,GAAA,IAAGjH,EAACiH,EAADjH,EAAGD,EAACkH,EAADlH,EACL,MAAA,CACCqkB,GAAsBpkB,EAAGD,GAAG8C,IAC5BuhB,GAAsBpkB,EAAGD,GAAG+C,IAChB,GAGe,YAA1BkJ,EAAQjB,SAASC,KACpBgB,EAAQjB,SAASE,YAAY,GAAKqxB,EAElCtwB,EAAQjB,SAASE,YAAcqxB,CAIjC,CD1CGC,CAA2BvwB,IAFb3L,KAAK07B,YAAczX,GAGlC,SAAsC,UAA3BjkB,KAAKO,OAAOwH,WAgBtB,MAAU,IAAArC,MAAM,0BAThB,GANAue,EAAUiP,GACTkH,GAAS,CAAEzvB,KAAM,UAAWD,SAAAA,EAAUD,WAAY,CAAA,IAClD0uB,IAIIn5B,KAAK07B,YAET,YADA17B,KAAK07B,YAAczX,EAAU,MC9DjB,SACftY,EACA6d,GAGA,GAAc,IAAVA,GAAyB,MAAVA,IAA4B,MAAXA,EACnC,OAAO7d,EAIR,IAAMwwB,EAAQ/B,GAASzuB,IAGI,YAA1BA,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAER5H,QAAQ,SAACo5B,GACrB,IACMC,EADenJ,GAAaiJ,EAAOC,GACP5S,EAC5B/F,EAAW+W,GAAc2B,EAAOC,GAChCE,EAAY7I,GAAiB0I,EAAO1Y,EAAU4Y,GACpDD,EAAY,GAAKE,EAAU,GAC3BF,EAAY,GAAKE,EAAU,EAC5B,EAGD,CDyCGC,CAAgB5wB,IAFF3L,KAAK07B,aAAezX,EAAU,MAK7C,CAGA,IAAMmV,EACa,YAAlB1uB,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAGbwuB,EAAcp2B,QAAQ,SAACkI,GACtBA,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,oBACpD,GAEA,IAAMo4B,EAAmBz5B,KAAK24B,UAAU/C,WAAWwD,IAAkB,GAE/DI,EACLx5B,KAAKi2B,gBAAgBL,WAAWwD,IAAkB,GAEnD,GAAIpY,IAEDA,EACA,CACCvb,GAAImc,EACJjX,KAAM,UACND,SAAAA,EACAD,WAAY,IAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,oBACjCkgB,WAAYhI,EAAYiI,cAI1B,OACD,EAIDxhB,KAAKkgB,MAAM2J,eAAc,CACxB,CAAEpkB,GAAImc,EAAYlX,SAAAA,IAAUoB,OACzB0tB,EACAC,IAGoB,iBAApBz5B,KAAK+H,WACR/H,KAAK07B,YAAczX,EACW,UAApBjkB,KAAK+H,aACf/H,KAAK07B,YAAczX,EAAU,IA1F9B,CA4FD,EAACwX,CAAA,CAvHiCjQ,CAAQL,IEG9BqR,gBAAqB,SAAAhR,GACjC,SAAAgR,EACUj8B,EACQ01B,EACA0C,GAA2B,IAAA54B,EAAA,OAE5CA,EAAAyrB,EAAA3mB,KAAMtE,KAAAA,IAAOP,MAJJO,YAAAR,EAAAA,EACQk2B,qBAAA,EAAAl2B,EACA44B,eAAA54B,EAAAA,EAKV08B,kBAPE18B,EAAAA,EAAMQ,OAANA,EACQR,EAAek2B,gBAAfA,EACAl2B,EAAS44B,UAATA,EAA2B54B,CAG7C,CAPiC4F,EAAA62B,EAAAhR,GAOhC,IAAAlqB,EAAAk7B,EAAAj7B,UA6GAi7B,OA7GAl7B,EAIDq6B,MAAA,WACC37B,KAAKy8B,kBAAex1B,CACrB,EAAC3F,EAED4L,MAAA,SACCzL,EACAmgB,EACAZ,GAA4B/a,IAAAA,EAE5BjG,KAAM0K,EAAW1K,KAAKkgB,MAAMgI,gBAC3BtG,GAID,GAAsB,YAAlBlX,EAASC,MAAwC,eAAlBD,EAASC,KAA5C,CAIA,IAMI8Y,EANE0V,EAAa,CAAC13B,EAAMe,IAAKf,EAAMgB,KAE/BkJ,EAAU,CAAEhB,KAAM,UAAWD,SAAAA,EAAUD,WAAY,IAMnDiyB,EAAoBhC,GAAoB/uB,GAE9C,GAA+B,iBAA3B3L,KAAKO,OAAOwH,WAA+B,CAC9C,IAAM40B,EAAsB7Y,GAAsBriB,EAAMe,IAAKf,EAAMgB,KACnEghB,EAAWlkB,EAAkBm9B,EAAmBC,EACjD,KAAW,IAA2B,UAA3B38B,KAAKO,OAAOwH,WAMtB,UAAUrC,MAAM,sBALhB+d,EAAWd,EACVyX,GAAS,CAAEzvB,KAAM,UAAWD,SAAAA,EAAUD,WAAY,CAAE,IACpD0uB,EAIF,CAGA,GAAKn5B,KAAKy8B,aAAV,CAKA,IAAMvvB,EAAQ,GAAKlN,KAAKy8B,aAAehZ,GAAYA,EAEnD,GAA+B,iBAA3BzjB,KAAKO,OAAOwH,WAA+B,CAC9C,IAAA4hB,EAAqB5F,GACpB2Y,EAAkB/8B,EAClB+8B,EAAkBh9B,IC7BN,SACfiM,EACAixB,EACA5Y,GAEA,GAAe,IAAX4Y,EACH,OAAOjxB,EAGR,IAMMmwB,GALqB,YAA1BnwB,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAGiBrF,IAAI,SAAAzF,GAAU,OACnDgkB,GAD8ChkB,EAAE2C,GAAG3C,EAAA,GACpB,GAG1B48B,EAAoB5Y,GAAsBE,EAAO,GAAIA,EAAO,IAS5D6Y,EAN0Bf,EAAkBv2B,IAAI,SAACsf,GAAW,MAAA,CACjEllB,EAAG+8B,EAAkB/8B,GAAKklB,EAAMllB,EAAI+8B,EAAkB/8B,GAAKi9B,EAC3Dl9B,EAAGg9B,EAAkBh9B,GAAKmlB,EAAMnlB,EAAIg9B,EAAkBh9B,GAAKk9B,EAC3D,GAGiDr3B,IAAI,SAAAqB,OAAGjH,EAACiH,EAADjH,EAAGD,EAACkH,EAADlH,EAAQ,MAAA,CACnEqkB,GAAsBpkB,EAAGD,GAAG8C,IAC5BuhB,GAAsBpkB,EAAGD,GAAG+C,IAC5B,GAE6B,YAA1BkJ,EAAQjB,SAASC,KACpBgB,EAAQjB,SAASE,YAAY,GAAKiyB,EAElClxB,EAAQjB,SAASE,YAAciyB,CAIjC,CDTGC,CAA0BnxB,EAASuB,EAAO,CAJ/Byc,EAAHnnB,IAAQmnB,EAAHlnB,KAKd,KAAsC,UAA3BzC,KAAKO,OAAOwH,YCxEnB,SACL4D,EACAixB,EACA5Y,EACA+Y,QAAAA,IAAAA,IAAAA,EAAyB,MAGV,IAAXH,IAKuB,YAA1BjxB,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAER5H,QAAQ,SAACo5B,GACrB,IAAMY,EAAmBxC,GAAcxW,EAAQoY,GACzCnY,EAAUiP,GAAalP,EAAQoY,GAE/Ba,EAAWxJ,GAAiBzP,EADdgZ,EAAmBJ,EACgB3Y,GAE1C,MAAT8Y,GAAyB,OAATA,IACnBX,EAAY,GAAKa,EAAS,IAGd,MAATF,GAAyB,OAATA,IACnBX,EAAY,GAAKa,EAAS,GAE5B,EAGD,CD0CGC,CAAevxB,EAASuB,EADTktB,GAASzuB,IAKzB,IAAMytB,EACa,YAAlB1uB,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAGbwuB,EAAcp2B,QAAQ,SAACkI,GACtBA,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,oBACpD,GAEA,IAAMo4B,EAAmBz5B,KAAK24B,UAAU/C,WAAWwD,IAAkB,GAE/DI,EACLx5B,KAAKi2B,gBAAgBL,WAAWwD,IAAkB,GAEnD,GAAIpY,IAEDA,EACA,CACCvb,GAAImc,EACJjX,KAAM,UACND,SAAAA,EACAD,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,oBACjCkgB,WAAYhI,EAAYiI,cAI1B,OAAO,EAKTxhB,KAAKkgB,MAAM2J,eACV,CAAA,CAAEpkB,GAAImc,EAAYlX,SAAAA,IAAUoB,OACzB0tB,EACAC,IAGJz5B,KAAKy8B,aAAehZ,CA5DpB,MAFCzjB,KAAKy8B,aAAehZ,CA1BrB,CAyFD,EAAC+Y,CAAA,CApHgC,CAAQrR,IEe7BgS,yBAA6B3R,GACzC,SAAA2R,EACU58B,EACQurB,EACAmK,EACA0C,OAA2B54B,EAAA,OAE5CA,EAAAyrB,EAAA3mB,UAAMtE,UALGA,YAAAR,EAAAA,EACQ+rB,qBAAA/rB,EACAk2B,qBAAAl2B,EAAAA,EACA44B,eAAA,EAAA54B,EAKVq9B,aAAe,KAAMr9B,EAErB45B,kBAA6D,CACpEl0B,GAAI,KACJ4wB,OAAQ,GACRt2B,EAYOs9B,gBAAkB,CACzBC,SAAU,CACT,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,IAlCKv9B,EAAMQ,OAANA,EACQR,EAAa+rB,cAAbA,EACA/rB,EAAek2B,gBAAfA,EACAl2B,EAAS44B,UAATA,EAA2B54B,CAG7C,CARyC4F,EAAAw3B,EAAA3R,GAQxC,IAAAlqB,EAAA67B,EAAA57B,UAmsBA47B,OAnsBA77B,EAgCOs4B,qBAAA,SACPn4B,EACAiJ,GAEA,IAMImvB,EANEC,EAAoB,CACzBrN,KAAM9F,SACN0P,OAAQ,EACR0D,2BAA2B,GAK5B,GAAsB,eAAlBrvB,EAASC,KACZkvB,EAAkBnvB,EAASE,gBACjBF,IAAkB,YAAlBA,EAASC,KAKnB,OAAOmvB,EAJPD,EAAkBnvB,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAII,EAAI,EAAGA,EAAI6uB,EAAgB5uB,OAAQD,IAAK,CAChD,IACMyY,EAAWzjB,KAAK8rB,cAAcJ,QAAQjqB,EAD9Bo4B,EAAgB7uB,IAG9B,GACCyY,EAAWzjB,KAAKggB,iBAChByD,EAAWqW,EAAkBrN,KAC5B,CAID,IAAMsN,EACa,YAAlBrvB,EAASC,OACRK,IAAM6uB,EAAgB5uB,OAAS,GAAW,IAAND,GAEtC8uB,EAAkBrN,KAAOhJ,EACzBqW,EAAkBzD,MAAQ0D,EAA4B,EAAI/uB,EAC1D8uB,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACx4B,EAEOi8B,uBAAA,SACPlH,EACAmH,EACAC,GAEA,OAAQpH,GACP,KAAM,EACL,GAAImH,GAAa,GAAKC,GAAa,EAClC,SAED,MACD,KAAK,EACJ,GAAIA,GAAa,EAChB,OAAO,EAER,MACD,KAAM,EACL,GAAID,GAAa,GAAKC,GAAa,EAClC,SAED,MACD,KAAM,EACL,GAAID,GAAa,EAChB,OAAO,EAER,MACD,KAAM,EACL,GAAIA,GAAa,GAAKC,GAAa,EAClC,SAED,MACD,KAAM,EACL,GAAIA,GAAa,EAChB,OAAO,EAER,MACD,OACC,GAAID,GAAa,GAAKC,GAAa,EAClC,OAAO,EAER,MACD,KAAM,EACL,GAAID,GAAa,EAChB,OAAO,EAOV,QACD,EAACl8B,EAEOo8B,kCAAA,WACP,IAAK19B,KAAK25B,kBAAkBl0B,KAAwC,IAAlCzF,KAAK25B,kBAAkBtD,MACxD,YAGD,IAAM1qB,EAAU3L,KAAK29B,WAAW39B,KAAK25B,kBAAkBl0B,IACvD,IAAKkG,EACJ,OACD,KAEA,IAAMytB,EAAgBp5B,KAAK49B,yBAAyBjyB,EAAQjB,UAG5D,MAAO,CACNmzB,YAHmB79B,KAAK89B,mBAAmB1E,GAI3CztB,QAAAA,EACAytB,cAAAA,EACA2E,mBAAoB3E,EAAcp5B,KAAK25B,kBAAkBtD,OAE3D,EAAC/0B,EAEO08B,sBAAA,SAAsBv8B,GAC7B,IAAMw8B,EAAcj+B,KAAK09B,oCACzB,IAAKO,EACJ,OAAO,KAER,IAAiBJ,EAChBI,EADgBJ,YAAazE,EAC7B6E,EAD6B7E,cAAe2E,EAC5CE,EAD4CF,mBAGvCG,EAAoBxD,GAFzBuD,EADOtyB,SAKR,IAAKuyB,EACJ,OACD,KAEA,IAAMC,EAAsBra,GAC3Bia,EAAmB,GACnBA,EAAmB,IAGZK,EAAqBp+B,KAAKq+B,sBACjCR,EACAM,GAFOC,iBAKFE,EAAoBxa,GAAsBriB,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKu+B,iBAAiB,CACrBH,iBAAAA,EACAhF,cAAAA,EACAkF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM9E,CACR,EAAC93B,EAEOk9B,2BAAA,SAA2B/8B,GAClC,IAAMw8B,EAAcj+B,KAAK09B,oCACzB,IAAKO,EACJ,YAED,IAAiBJ,EAChBI,EADgBJ,YAAazE,EAC7B6E,EAD6B7E,cAAe2E,EAC5CE,EAD4CF,mBAGvCG,EAAoBxD,GAFzBuD,EADOtyB,SAKR,IAAKuyB,EACJ,OAAO,KAGR,IAAMC,EAAsBra,GAC3Bia,EAAmB,GACnBA,EAAmB,IAGZK,EAAqBp+B,KAAKq+B,sBACjCR,EACAM,GAFOC,iBAKFE,EAAoBxa,GAAsBriB,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKy+B,sBAAsB,CAC1BL,iBAAAA,EACAhF,cAAAA,EACAkF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM9E,CACR,EAAC93B,EAEOm9B,sBAAA,SAAA3+B,OAEPo+B,EAAiBp+B,EAAjBo+B,kBACAC,EAAmBr+B,EAAnBq+B,oBACAG,EAAiBx+B,EAAjBw+B,kBACAlF,EAAat5B,EAAbs5B,cAiBA,IANcp5B,KAAKu9B,uBAfHz9B,EAAhBs+B,iBAYwBF,EAAkBv+B,EAAI2+B,EAAkB3+B,EACxCu+B,EAAkBx+B,EAAI4+B,EAAkB5+B,GAS/D,YAGD,IAAIwN,EACH3N,EAAkB2+B,EAAmBI,GACrC/+B,EAAkB2+B,EAAmBC,GActC,OAZIjxB,EAAQ,IACXA,EAAQlN,KAAKo9B,cAGdp9B,KAAK0+B,wBACJtF,EACA8E,EAAkBv+B,EAClBu+B,EAAkBx+B,EAClBwN,EACAA,GAGMksB,CACR,EAAC93B,EAEOq9B,6BAAA,SAA6Bl9B,GACpC,IAAMw8B,EAAcj+B,KAAK09B,oCACzB,IAAKO,EACJ,OAAO,KAGR,IAAQJ,EAAmDI,EAAnDJ,YAAazE,EAAsC6E,EAAtC7E,cAAe2E,EAAuBE,EAAvBF,mBAE9BI,EAAsBra,GAC3Bia,EAAmB,GACnBA,EAAmB,IAGpBa,EAAgD5+B,KAAKq+B,sBACpDR,EACAM,GAFOU,EAAiBD,EAAjBC,kBAAmBT,EAAgBQ,EAAhBR,iBAKrBF,EAAoB,CACzBv+B,EAAGk+B,EAAYgB,GAAmB,GAClCn/B,EAAGm+B,EAAYgB,GAAmB,IAE7BP,EAAoBxa,GAAsBriB,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKy+B,sBAAsB,CAC1BL,iBAAAA,EACAhF,cAAAA,EACAkF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM9E,CACR,EAAC93B,EAEOw9B,wBAAA,SAAwBr9B,GAC/B,IAAMw8B,EAAcj+B,KAAK09B,oCACzB,IAAKO,EACJ,YAGD,IAAQJ,EAAmDI,EAAnDJ,YAAazE,EAAsC6E,EAAtC7E,cAAe2E,EAAuBE,EAAvBF,mBAE9BI,EAAsBra,GAC3Bia,EAAmB,GACnBA,EAAmB,IAGpBgB,EAAgD/+B,KAAKq+B,sBACpDR,EACAM,GAFOU,EAAiBE,EAAjBF,kBAAmBT,EAAgBW,EAAhBX,iBAKrBF,EAAoB,CACzBv+B,EAAGk+B,EAAYgB,GAAmB,GAClCn/B,EAAGm+B,EAAYgB,GAAmB,IAE7BP,EAAoBxa,GAAsBriB,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKu+B,iBAAiB,CACrBH,iBAAAA,EACAhF,cAAAA,EACAkF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM9E,CACR,EAAC93B,EAEOi9B,iBAAA,SAAA33B,GACP,IAAAw3B,EAAgBx3B,EAAhBw3B,iBACAF,EAAiBt3B,EAAjBs3B,kBACAC,EAAmBv3B,EAAnBu3B,oBACAG,EAAiB13B,EAAjB03B,kBACAlF,EAAaxyB,EAAbwyB,cAQM4F,EAAkBd,EAAkBv+B,EAAI2+B,EAAkB3+B,EAC1Ds/B,EAAkBf,EAAkBx+B,EAAI4+B,EAAkB5+B,EAQhE,IANcM,KAAKu9B,uBAClBa,EACAY,EACAC,GAIA,OACD,KAEA,IAAIC,EAAS,EAEQ,IAApBF,GACqB,IAArBZ,GACqB,IAArBA,IAGAc,EAAS,GADgBhB,EAAkBv+B,EAAIw+B,EAAoBx+B,EAClCq/B,GAAmBA,GAGrD,IAAIG,EAAS,EAUb,OARqB,IAApBF,GACqB,IAArBb,GACqB,IAArBA,IAGAe,EAAS,GADgBjB,EAAkBx+B,EAAIy+B,EAAoBz+B,EAClCu/B,GAAmBA,GAGhDj/B,KAAKo/B,cAAcF,EAAQC,IAI5BD,EAAS,IACZA,EAASl/B,KAAKo9B,cAGX+B,EAAS,IACZA,EAASn/B,KAAKo9B,cAGfp9B,KAAK0+B,wBACJtF,EACA8E,EAAkBv+B,EAClBu+B,EAAkBx+B,EAClBw/B,EACAC,GAGM/F,GAlBP,IAmBD,EAAC93B,EAEOq8B,WAAA,SAAWl4B,GAClB,GAAkC,OAA9BzF,KAAK25B,kBAAkBl0B,GAC1B,OAAO,KAGR,IAAMiF,EAAW1K,KAAKkgB,MAAMgI,gBAAgBziB,GAG5C,MAAsB,YAAlBiF,EAASC,MAAwC,eAAlBD,EAASC,KACpC,KAGQ,CAAEA,KAAM,UAAWD,SAAAA,EAAUD,WAAY,CAAA,EAK1D,EAACnJ,EAEOs8B,yBAAA,SAAyBlzB,GAEhC,MAAyB,YAAlBA,EAASC,KACbD,EAASE,YAAY,GACrBF,EAASE,WACb,EAACtJ,EAEO89B,cAAA,SAAcF,EAAgBC,GACrC,IAAME,GAAUtvB,MAAMmvB,IAAWC,EAAShR,OAAOmR,iBAC3CC,GAAUxvB,MAAMovB,IAAWA,EAAShR,OAAOmR,iBAEjD,OAAOD,GAAUE,CAClB,EAACj+B,EAEOo9B,wBAAA,SACP9zB,EACA40B,EACAC,EACAP,EACAC,GAEAv0B,EAAY5H,QAAQ,SAACkI,GACpB,IAAAke,EAAiBtF,GAAsB5Y,EAAW,GAAIA,EAAW,IAKjEye,EAAqB5F,GAHJyb,GAFRpW,EAADzpB,EAEwB6/B,GAAWN,EAC1BO,GAHLrW,EAAD1pB,EAGqB+/B,GAAWN,GAE9B18B,EAAGknB,EAAHlnB,IAEbyI,EAAW,GAFAye,EAAHnnB,IAGR0I,EAAW,GAAKzI,CACjB,EACD,EAACnB,EAEOw8B,mBAAA,SAAmBlzB,GAC1B,IAAMyhB,EAAyC,CAC9C1F,SACAA,UACCA,UACAA,WAIF/b,EAAcA,EAAYrF,IAAI,SAACsf,GAC9B,IAAAwE,EAAiBvF,GAAsBe,EAAM,GAAIA,EAAM,IACvD,MAAO,CADEwE,EAAD1pB,EAAI0pB,EAAD3pB,EAEZ,IAEYsD,QAAQ,SAAA08B,GAAE,IAAA//B,EAAC+/B,EAAEhgC,GAAAA,EAACggC,EAAA,GACrB//B,EAAI0sB,EAAK,KACZA,EAAK,GAAK1sB,GAGPD,EAAI2sB,EAAK,KACZA,EAAK,GAAK3sB,GAGPC,EAAI0sB,EAAK,KACZA,EAAK,GAAK1sB,GAGPD,EAAI2sB,EAAK,KACZA,EAAK,GAAK3sB,EAEZ,GAEA,IAAOigC,EAA4BtT,EAAtBuT,GAAAA,EAAsBvT,EAAI,GAAnBwT,EAAexT,KAATyT,EAASzT,EAAI,GAsBvC,MAAO,CAVS,CAACsT,EAAMG,GAKR,EAAEH,EAAOE,GAAQ,EAAGC,GAJlB,CAACD,EAAMC,GAKP,CAACD,EAAMC,GAASF,EAAQE,GAAS,GAJjC,CAACD,EAAMD,GAKN,EAAED,EAAOE,GAAQ,EAAGD,GAJtB,CAACD,EAAMC,GAKP,CAACD,EAAMG,GAASF,EAAQE,GAAS,GAYlD,EAACx+B,EAEO+8B,sBAAA,SACPR,EACAkC,GAKA,IAHA,IAAIC,EACAC,EAAkBtZ,SAEb3b,EAAI,EAAGA,EAAI6yB,EAAY5yB,OAAQD,IAAK,CAC5C,IAAMyY,EAAWlkB,EAChB,CAAEI,EAAGogC,EAAWpgC,EAAGD,EAAGqgC,EAAWrgC,GACjC,CAAEC,EAAGk+B,EAAY7yB,GAAG,GAAItL,EAAGm+B,EAAY7yB,GAAG,KAGvCyY,EAAWwc,IACdD,EAAeh1B,EACfi1B,EAAkBxc,EAEpB,CAEA,QAAqBxc,IAAjB+4B,EACH,MAAU,IAAAt6B,MAAM,+BASjB,MAAO,CACNm5B,kBALqB7+B,KAAKq9B,gBAA0B,SACpD2C,GAKA5B,iBAAkB4B,EAEpB,EAAC1+B,EAKM03B,WAAA,WACN,OAAqC,OAA9Bh5B,KAAK25B,kBAAkBl0B,EAC/B,EAACnE,EAQMw3B,cAAA,SAAcrzB,EAAe4wB,GACnCr2B,KAAK25B,kBAAoB,CACxBl0B,GAAAA,EACA4wB,MAAAA,EAEF,EAAC/0B,EAMMy3B,aAAA,WACN/4B,KAAK25B,kBAAoB,CACxBl0B,GAAI,KACJ4wB,OAAQ,EAEV,EAAC/0B,EAQM04B,kBAAA,SACNv4B,EACAmgB,GAEA,IAAMlX,EAAW1K,KAAKkgB,MAAMgI,gBAAgBtG,GACtCkY,EAAoB95B,KAAK45B,qBAAqBn4B,EAAOiJ,GAG3D,OAAiC,IAA7BovB,EAAkBzD,OACb,EAEFyD,EAAkBzD,KAC1B,EAAC/0B,EAQM43B,KAAA,SACNz3B,EACAy+B,EACAlf,GAEA,IAAKhhB,KAAK25B,kBAAkBl0B,GAC3B,OACD,EAEA,IAAMkG,EAAU3L,KAAK29B,WAAW39B,KAAK25B,kBAAkBl0B,IACvD,IAAKkG,EACJ,OAAO,EAGR,IAAIytB,EAAmC,KAYvC,GAVqB,WAAjB8G,EACH9G,EAAgBp5B,KAAKg+B,sBAAsBv8B,GAChB,aAAjBy+B,EACV9G,EAAgBp5B,KAAK8+B,wBAAwBr9B,GAClB,iBAAjBy+B,EACV9G,EAAgBp5B,KAAKw+B,2BAA2B/8B,GACrB,mBAAjBy+B,IACV9G,EAAgBp5B,KAAK2+B,6BAA6Bl9B,KAG9C23B,EACJ,OAAO,EAIR,IAAK,IAAIpuB,EAAI,EAAGA,EAAIouB,EAAcnuB,OAAQD,IAAK,CAC9C,IAAME,EAAakuB,EAAcpuB,GAKjC,GAJAE,EAAW,GAAKlM,EAAekM,EAAW,GAAIlL,KAAKqB,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIlL,KAAKqB,sBAG9CqlB,GAAkBxb,EAAYlL,KAAKqB,qBACvC,QAEF,CAGA,IAAMo4B,EAAmBz5B,KAAK24B,UAAU/C,WAAWwD,IAAkB,GAC/DI,EACLx5B,KAAKi2B,gBAAgBL,WAAWwD,IAAkB,GAE7CzJ,EAAkB,CACvBhlB,KAAMgB,EAAQjB,SAASC,KACvBC,YAC2B,YAA1Be,EAAQjB,SAASC,KAAqB,CAACyuB,GAAiBA,GAG1D,QAAIpY,IACWA,EACb,CACCvb,GAAIzF,KAAK25B,kBAAkBl0B,GAC3BkF,KAAM,UACND,SAAUilB,EACVllB,WAAY,IAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,oBACjCkgB,WAAYhI,EAAYiI,gBAS3BxhB,KAAKkgB,MAAM2J,gBACV,CACCpkB,GAAIzF,KAAK25B,kBAAkBl0B,GAC3BiF,SAAUilB,IACV7jB,OACE0tB,EACAC,IAGG,GACR,EAAC0D,CAAA,EA3sBgDhS,ICqErCgV,gBAAoBC,SAAAA,GAyBhC,SAAAD,EAAYnsB,OAAsDqsB,EAAAtgC,GACjEA,EAAAqgC,EAAAv7B,KAAMmP,KAAAA,IAAQhU,MAzBRgM,KAAO,SAAQjM,EAEdugC,wBAAyB,EAAIvgC,EAC7BwgC,kBAAoB,EAACxgC,EACrBygC,eAAiB,EAACzgC,EAClB0gC,SAAwB,GAAE1gC,EAE1B2gC,WAAK3gC,EAAAA,EACLynB,eAAS,EAAAznB,EAGTk2B,qBAAe,EAAAl2B,EACf44B,eAAS54B,EAAAA,EACT24B,4BAAoB34B,EACpB+rB,mBAAa,EAAA/rB,EACbgsB,sBAAgBhsB,EAAAA,EAChB4gC,iBAAW5gC,EAAAA,EACX6gC,oBAAc,EAAA7gC,EACd8gC,mBAAa,EAAA9gC,EACb+gC,kBAAY/gC,EAAAA,EACZghC,mCAA2BhhC,EAC3B0nB,aAAO,EAAA1nB,EACPihC,YAA0C,CAAE,EAKnDjhC,EAAK2gC,MAAQ1sB,GAAWA,EAAQ0sB,MAAQ1sB,EAAQ0sB,MAAQ,GAExD,IAAM/Y,EAAiB,CACtBsZ,YAAa,OACbC,UAAW,OACXC,QAAS,OACTC,eAAgB,aAWjB,GAPCrhC,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,KAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAKW,QAAvB3T,MAAAA,OAAAA,EAAAA,EAASwT,WACZznB,EAAKynB,UAAY,CAChB6Z,SAAU,KACVC,OAAQ,KACR1F,OAAQ,KACR1uB,MAAO,UAEF,CACN,IAAM6a,EAAmB,CACxBsZ,SAAU,SACVC,OAAQ,SACR1F,OAAQ,CAAC,UAAW,KACpB1uB,MAAO,CAAC,UAAW,MAEpBnN,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,EAAA,CAAA,EACpB2H,EAAqB/T,EAAQwT,WAClCO,CACL,CAWA,GATAhoB,EAAKwgC,kBACHvsB,QAC8B/M,IAA9B+M,EAAQusB,mBACRvsB,EAAQusB,mBACT,EAEDxgC,EAAKugC,uBAAwDD,OAAlCA,EAAU,MAAPrsB,OAAO,EAAPA,EAASssB,yBAAsBD,EAGzDrsB,GAAWA,EAAQ0sB,OAAS1sB,EAAQ0sB,MACvC,IAAK,IAAM10B,KAAQgI,EAAQ0sB,MAAO,CACjC,IAAM/0B,EAAUqI,EAAQ0sB,MAAM10B,GAAML,QAChCA,GAAWA,EAAQ0U,aACtBtgB,EAAKihC,YAAYh1B,GAAQL,EAAQ0U,WAInC,CACA,OAAAtgB,CACF,CApFgC4F,EAAAw6B,EAAAC,GAoF/B,IAAA9+B,EAAA6+B,EAAA5+B,UAuyBA,OAvyBAD,EAEDigC,cAAA,SAAc7L,GACb11B,KAAKwhC,OAAO9L,GAAW,EACxB,EAACp0B,EAEDmgC,aAAA,WACC,GAAoB,YAAhBzhC,KAAK4f,OAGR,MAAM,IAAIla,MAAM,mDAFhB1F,KAAK4f,OAAS,WAIhB,EAACte,EAEDgf,kBAAA,SAAkB/f,GACjBP,KAAK8rB,cAAgB,IAAIL,GAAsBlrB,GAC/CP,KAAK+rB,iBAAmB,IAAIR,GAAyBhrB,GACrDP,KAAK04B,qBAAuB,IAAId,GAC/Br3B,EACAP,KAAK+rB,iBACL/rB,KAAK8rB,eAGN9rB,KAAKi2B,gBAAkB,IAAIH,GAAuBv1B,GAClDP,KAAK24B,UAAY,IAAI5D,GAAiBx0B,EAAQP,KAAKi2B,iBAEnDj2B,KAAK6gC,cAAgB,IAAIpF,GACxBl7B,EACAP,KAAKi2B,gBACLj2B,KAAK24B,WAGN34B,KAAK8gC,aAAe,IAAItE,GACvBj8B,EACAP,KAAKi2B,gBACLj2B,KAAK24B,WAGN34B,KAAK2gC,YAAc,IAAIlI,GACtBl4B,EACAP,KAAK04B,qBACL14B,KAAKi2B,gBACLj2B,KAAK24B,WAEN34B,KAAK4gC,eAAiB,IAAIlH,GACzBn5B,EACAP,KAAK8rB,cACL9rB,KAAKi2B,gBACLj2B,KAAK24B,WAEN34B,KAAK+gC,4BAA8B,IAAI5D,GACtC58B,EACAP,KAAK8rB,cACL9rB,KAAKi2B,gBACLj2B,KAAK24B,UAEP,EAACr3B,EAEMogC,gBAAA,WACN1hC,KAAKqhC,UACN,EAAC//B,EAEO+/B,SAAA,eAAQp7B,EAAAjG,KACT2hC,EAAyB3hC,KAAKygC,SAClCrU,OAAO,SAAC3mB,GAAO,OAAAQ,EAAKia,MAAMtS,IAAInI,EAAG,GACjCF,IAAI,SAACE,GAAQ,MAAA,CACbA,GAAAA,EACA4E,SAAU6U,EACV7S,OAAO,EACP,GAEFrM,KAAKkgB,MAAM4J,eAAe6X,GAE1B3hC,KAAK8gB,WAAW9gB,KAAKygC,SAAS,IAC9BzgC,KAAKygC,SAAW,GAChBzgC,KAAKi2B,gBAAsB,SAC3Bj2B,KAAK24B,UAAS,QACf,EAACr3B,EAEOsgC,eAAA,WAMP5hC,KAAKkgB,MAAK,OAAQlgB,KAAKygC,UACvBzgC,KAAKygC,SAAW,EACjB,EAACn/B,EAEOugC,aAAA,SAAapgC,GAA0BkI,IAAAA,OAC9C,GAAK3J,KAAKi2B,gBAAgB1E,IAAItmB,OAA9B,CAIA,IAAI62B,EAOAC,EAAyBpb,SAkB7B,GAhBA3mB,KAAKi2B,gBAAgB1E,IAAIvuB,QAAQ,SAACyC,GACjC,IAAMiF,EAAWf,EAAKuW,MAAMgI,gBAAuBziB,GAC7Cge,EAAW9Z,EAAKmiB,cAAcJ,QAAQjqB,EAAOiJ,EAASE,aAG3D6Y,EAAW9Z,EAAKqW,iBAChByD,EAAWse,IAEXA,EAAyBte,EACzBqe,EAA6Bn4B,EAAKuW,MAAMoV,kBAAkB7vB,GAK5D,GAEKq8B,EAAL,CAIA,IAAMpM,EAAYoM,EAA2B1L,wBACvC4L,EAAkBF,EAA2BzL,MAG7C5rB,EAAazK,KAAKkgB,MAAMoV,kBAAkBI,GAC1CuM,EAAYjiC,KAAK0gC,MAAMj2B,EAAWuB,MAClCqU,EAAargB,KAAKghC,YAAYv2B,EAAWuB,MAS/C,GALEi2B,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQf,aAClBq3B,EAAUt2B,QAAQf,YAAYs3B,UAEhC,CAIA,IAEIt3B,EAFEF,EAAW1K,KAAKkgB,MAAMgI,gBAAgBwN,GAG5C,GAAsB,YAAlBhrB,EAASC,MAIZ,IAHAC,EAAcF,EAASE,YAAY,IAGnBK,QAAU,EACzB,YAEK,GAAsB,eAAlBP,EAASC,OACnBC,EAAcF,EAASE,aAGPK,QAAU,EACzB,OAKF,GAAKL,EAAL,CAoBA,GAfoB,YAAlBF,EAASC,MAA0C,IAApBq3B,GAChCA,IAAoBp3B,EAAYK,OAAS,GAKzCL,EAAYu3B,QACZv3B,EAAYggB,MACZhgB,EAAYO,KAAK,CAACP,EAAY,GAAG,GAAIA,EAAY,GAAG,MAGpDA,EAAY6qB,OAAOuM,EAAiB,GAIjC3hB,IACWA,EACb,CACC5a,GAAIiwB,EACJ/qB,KAAM,UACND,SAAAA,EACAD,WAAAA,GAED,CACCrC,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAYhI,EAAYkW,SAIzB,OAIFzvB,KAAKkgB,MAAY,OAAA,GAAApU,OAAK9L,KAAK24B,UAAUpH,IAAQvxB,KAAKi2B,gBAAgB1E,MAClEvxB,KAAKkgB,MAAM2J,eAAe,CACzB,CACCpkB,GAAIiwB,EACJhrB,SAAAA,KAIF1K,KAAKi2B,gBAAgBvN,OACpB9d,EACAF,EAASC,KACT+qB,GAIAuM,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQf,aAClBq3B,EAAUt2B,QAAQf,YAAYw3B,WAE9BpiC,KAAK24B,UAAUjQ,OAAO9d,EAAa8qB,EAAW11B,KAAKqB,oBA1DpD,CAxBA,CAnBA,CA7BA,CAoID,EAACC,EAEOkgC,OAAA,SAAO9L,EAAsB2M,GACpC,QADoCA,IAAAA,IAAAA,GAAa,GAC7CriC,KAAKygC,SAAS,KAAO/K,EAAzB,CAIA,IAAAL,EAAiBr1B,KAAKkgB,MAAMoV,kBAAkBI,GAGxCuM,EAAYjiC,KAAK0gC,MAHXrL,EAAJrpB,MAMR,GAAKi2B,GAAcA,EAAUt2B,QAA7B,CAIA,IAAM22B,EAAuBtiC,KAAKygC,SAAS,GAG3C,GAAI6B,EAAsB,CAEzB,GAAIA,IAAyB5M,EAC5B,OAIA11B,KAAKqhC,UAEP,CAEIgB,GACHriC,KAAKyI,UAAUzI,KAAKynB,QAAQwZ,aAI7BjhC,KAAKygC,SAAW,CAAC/K,GAEjB11B,KAAKkgB,MAAM4J,eAAe,CACzB,CAAErkB,GAAIiwB,EAAWrrB,SAAU,WAAYgC,OAAO,KAE/CrM,KAAK6gB,SAAS6U,GAGd,IAAA6M,EAA8BviC,KAAKkgB,MAAMgI,gBAAgBwN,GAAjD/qB,EAAI43B,EAAJ53B,KAAMC,EAAW23B,EAAX33B,YAEd,GAAa,eAATD,GAAkC,YAATA,EAA7B,CAMA,IAAMymB,EACI,eAATzmB,EAAwBC,EAAcA,EAAY,GAE/CwmB,GAAkB6Q,GAAaA,EAAUt2B,QAAQf,cACpD5K,KAAKi2B,gBAAgBvN,OAAO0I,EAAgBzmB,EAAM+qB,GAE9CuM,EAAUt2B,QAAQf,YAAYw3B,WACjCpiC,KAAK24B,UAAUjQ,OACd0I,EACAsE,EACA11B,KAAKqB,qBAdR,CAjCA,CAVA,CA6DD,EAACC,EAEOkhC,YAAA,SAAY/gC,GACnB,IAAAghC,EAA4CziC,KAAK04B,qBAAqBhyB,KACrEjF,EACAzB,KAAKygC,SAASx1B,OAAS,GAFhButB,EAAciK,EAAdjK,eAAgBL,EAAesK,EAAftK,gBAKxB,GAAIn4B,KAAKygC,SAASx1B,QAAUktB,EAI3Bn4B,KAAK24B,UAAUzD,OACdiD,EAAgB1yB,GAChBzF,KAAKqB,0BAMP,GAAIm3B,GAAkBA,EAAe/yB,GACpCzF,KAAKwhC,OAAOhJ,EAAe/yB,IAAI,QACzB,GAAIzF,KAAKygC,SAASx1B,QAAUjL,KAAKsgC,uBAEvC,YADAtgC,KAAKqhC,UAGP,EAAC//B,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyhC,cACN,EAACngC,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAKygB,aACLzgB,KAAK0gB,YACN,EAACpf,EAGD+C,QAAA,SAAQ5C,GACc,UAAjBA,EAAMC,OAGkB,SAAjBD,EAAMC,QAChB1B,KAAKwiC,YAAY/gC,GAHjBzB,KAAK6hC,aAAapgC,EAKpB,EAACH,EAEOohC,SAAA,SAASjhC,GAChB,OACCzB,KAAKwnB,UAAUta,OACflN,KAAKwnB,UAAUta,MAAM8Z,MAAM,SAAC1iB,UAAQ7C,EAAMkB,SAASye,SAAS9c,EAAI,EAElE,EAAChD,EAEOqhC,UAAA,SAAUlhC,GACjB,OACCzB,KAAKwnB,UAAUoU,QACf57B,KAAKwnB,UAAUoU,OAAO5U,MAAM,SAAC1iB,GAAG,OAAK7C,EAAMkB,SAASye,SAAS9c,EAAI,EAEnE,EAAChD,EAEOshC,uBAAA,SAAuBnhC,GAC9B,IAAMohC,EAAiB7iC,KAAK2iC,UAAUlhC,GAChCqhC,EAAc9iC,KAAK0iC,SAASjhC,IAG9BohC,GAAkBC,IACrBrhC,EAAM8B,gBAER,EAACjC,EAGDmD,UAAA,SAAUhD,GACTzB,KAAK4iC,uBAAuBnhC,EAC7B,EAACH,EAGDiD,QAAA,SAAQ9C,GAGP,GAFAzB,KAAK4iC,uBAAuBnhC,GAExBzB,KAAKwnB,UAAgB,QAAI/lB,EAAM6C,MAAQtE,KAAKwnB,UAAgB,OAAE,CACjE,IAAKxnB,KAAKygC,SAASx1B,OAClB,OAODjL,KAAK8gB,WADsB9gB,KAAKygC,SAAS,IAIzCzgC,KAAK4hC,iBAGL5hC,KAAKi2B,gBAAe,SACpBj2B,KAAK24B,UAAS,QACf,MACC34B,KAAKwnB,UAAU6Z,UACf5/B,EAAM6C,MAAQtE,KAAKwnB,UAAU6Z,UAE7BrhC,KAAKuoB,SAEP,EAACjnB,EAGDinB,QAAA,WACKvoB,KAAKygC,SAASx1B,QACjBjL,KAAKqhC,UAEP,EAAC//B,EAGDwC,YAAA,SACCrC,EACAogB,GAIA,GAAK7hB,KAAKygC,SAASx1B,OAAnB,CAMA,IAAMR,EAAazK,KAAKkgB,MAAMoV,kBAAkBt1B,KAAKygC,SAAS,IACxDwB,EAAYjiC,KAAK0gC,MAAMj2B,EAAWuB,MAUxC,GARCi2B,GACAA,EAAUt2B,UACTs2B,EAAUt2B,QAAQpC,WACjB04B,EAAUt2B,QAAQf,aAClBq3B,EAAUt2B,QAAQf,YAAYrB,WAC9B04B,EAAUt2B,QAAQf,aAClBq3B,EAAUt2B,QAAQf,YAAYm4B,WAEjC,CAIA/iC,KAAKwgC,eAAiB,EAEtB,IAAM5e,EAAa5hB,KAAKygC,SAAS,GAC3BuC,EAA2BhjC,KAAK4gC,eAAe5G,kBACpDv4B,EACAmgB,GAID,OACCqgB,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQf,cACjBq3B,EAAUt2B,QAAQf,YAAYrB,WAC9B04B,EAAUt2B,QAAQf,YAAYm4B,aACD,IAA9BC,GAEAhjC,KAAKyI,UAAUzI,KAAKynB,QAAQyZ,WAGxBe,EAAUt2B,QAAQf,YAAYm4B,UACjC/iC,KAAK+gC,4BAA4BjI,cAChClX,EACAohB,GAIDhjC,KAAK4gC,eAAe9H,cAAclX,EAAYohB,QAG/CnhB,GAAmB,IAMnBogB,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQpC,WAClBvJ,KAAK2gC,YAAY1H,QAAQx3B,EAAOmgB,IAEhC5hB,KAAKyI,UAAUzI,KAAKynB,QAAQyZ,WAC5BlhC,KAAK2gC,YAAY7H,cAAcr3B,EAAOmgB,QACtCC,GAAmB,SARpB,CArCA,CAjBA,CAiED,EAACvgB,EAGD4C,OAAA,SACCzC,EACAogB,GAEA,IAAMD,EAAa5hB,KAAKygC,SAAS,GAGjC,GAAK7e,EAAL,CAIA,IAAMnX,EAAazK,KAAKkgB,MAAMoV,kBAAkB1T,GAC1CqgB,EAAYjiC,KAAK0gC,MAAMj2B,EAAWuB,MAClCi3B,GAGqC,KAFzChB,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQu3B,mBAOpB,GAJAljC,KAAKwgC,iBAIDxgC,KAAKwgC,eAAiBxgC,KAAKugC,mBAAsB,EAArD,CAIA,IAAMlgB,EAAargB,KAAKghC,YAAYv2B,EAAWuB,MAG/C,GACCi2B,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQw3B,YAClBnjC,KAAK2iC,UAAUlhC,GAIf,OAFAogB,GAAmB,QACnB7hB,KAAK6gC,cAAcjF,OAAOn6B,EAAOmgB,EAAYvB,GAK9C,GACC4hB,GACAA,EAAUt2B,SACVs2B,EAAUt2B,QAAQy3B,WAClBpjC,KAAK0iC,SAASjhC,GAId,OAFAogB,GAAmB,QACnB7hB,KAAK8gC,aAAa5zB,MAAMzL,EAAOmgB,EAAYvB,GAI5C,GACCrgB,KAAK+gC,4BAA4B/H,cACjCiJ,EAAUt2B,SACVs2B,EAAUt2B,QAAQf,aAClBq3B,EAAUt2B,QAAQf,YAAYm4B,UAC7B,CACD,GAAwB,UAApB/iC,KAAK+H,WACR,MAAU,IAAArC,MACT,2DAUF,OANAmc,GAAmB,QACnB7hB,KAAK+gC,4BAA4B7H,KAChCz3B,EACAwgC,EAAUt2B,QAAQf,YAAYm4B,UAC9B1iB,EAGF,CAGIrgB,KAAK4gC,eAAe5H,aACvBh5B,KAAK4gC,eAAe1H,KAAKz3B,EAAOwhC,EAAkB5iB,GAK/CrgB,KAAK2gC,YAAY3H,aACpBh5B,KAAK2gC,YAAYzH,KAAKz3B,EAAO4e,GAI9BwB,GAAmB,EA7DnB,CAhBA,CA8ED,EAACvgB,EAGD8C,UAAA,SACCuX,EACAkG,GAEA7hB,KAAKyI,UAAUzI,KAAKynB,QAAQ0Z,SAIxBnhC,KAAK4gC,eAAe5H,aACvBh5B,KAAK+gB,SAAS/gB,KAAKygC,SAAS,GAAI,CAC/Bz0B,KAAMhM,KAAKgM,KACXqc,OAAQ,mBAECroB,KAAK2gC,YAAY3H,aAC3Bh5B,KAAK+gB,SAAS/gB,KAAKygC,SAAS,GAAI,CAC/Bz0B,KAAMhM,KAAKgM,KACXqc,OAAQ,gBAECroB,KAAK+gC,4BAA4B/H,cAC3Ch5B,KAAK+gB,SAAS/gB,KAAKygC,SAAS,GAAI,CAC/Bz0B,KAAMhM,KAAKgM,KACXqc,OAAQ,yBAIVroB,KAAK4gC,eAAe7H,eACpB/4B,KAAK2gC,YAAY5H,eACjB/4B,KAAK+gC,4BAA4BhI,eACjC/4B,KAAK6gC,cAAclF,QACnB37B,KAAK8gC,aAAanF,QAClB9Z,GAAmB,EACpB,EAACvgB,EAGDkC,YAAA,SAAY/B,GAA0B,IAAAiM,EAAA1N,KACrC,GAAKA,KAAKygC,SAASx1B,QAKnB,IAAIjL,KAAK2gC,YAAY3H,aAArB,CAIA,IAAIqK,GAAiB,EACrBrjC,KAAK24B,UAAUpH,IAAIvuB,QAAQ,SAACyC,GAC3B,IAAI49B,EAAJ,CAGA,IAAM34B,EAAWgD,EAAKwS,MAAMgI,gBAAuBziB,GAClCiI,EAAKoe,cAAcJ,QAAQjqB,EAAOiJ,EAASE,aAE7C8C,EAAKsS,kBACnBqjB,GAAiB,EALlB,CAOD,GAEA,IAAIC,GAAuB,EAY3B,GATAtjC,KAAKi2B,gBAAgB1E,IAAIvuB,QAAQ,SAACyC,GACjC,IAAMiF,EAAWgD,EAAKwS,MAAMgI,gBAAuBziB,GAClCiI,EAAKoe,cAAcJ,QAAQjqB,EAAOiJ,EAASE,aAC7C8C,EAAKsS,kBACnBqjB,GAAiB,EACjBC,GAAuB,EAEzB,GAEID,EACHrjC,KAAKyI,UAAUzI,KAAKynB,QAAQ2Z,oBAD7B,CAMA,IAAwBmC,EACvBvjC,KAAK04B,qBAAqBhyB,KAAKjF,GAAO,GAD/B+2B,eAQPx4B,KAAKyI,UAJLzI,KAAKygC,SAASx1B,OAAS,IACrBs4B,GAAuBA,EAAoB99B,KAAOzF,KAAKygC,SAAS,IACjE6C,GAEctjC,KAAKynB,QAAQwZ,YAGb,QAdhB,CA9BA,OANCjhC,KAAKyI,UAAU,QAoDjB,EAACnH,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,E3Cl1BN,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,I2Cy0BR,GACC9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACP,UAA1BL,EAAQjB,SAASC,KAChB,CACD,GAAIgB,EAAQlB,WAAW0rB,eA2BtB,OA1BAnjB,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOwwB,oBACZxwB,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOywB,2BACZzwB,EAAOlG,kBACPnB,GAGDqH,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAO0wB,oBACZ1wB,EAAOvG,WACPd,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAO2wB,2BACZ,EACAh4B,GAGDqH,EAAOvE,OAAS,GAETuE,EAGR,GAAIrH,EAAQlB,WAAW2qB,SA2BtB,OA1BApiB,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAO4wB,cACZ5wB,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAO6wB,qBACZ7wB,EAAOlG,kBACPnB,GAGDqH,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAO8wB,cACZ,EACAn4B,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAO+wB,qBACZ,EACAp4B,GAGDqH,EAAOvE,OAAS,GAETuE,CAET,MAAO,GAAIrH,EAAQlB,WAAWyU,GAA6B,CAI1D,GAA8B,YAA1BvT,EAAQjB,SAASC,KA0BpB,OAzBAqI,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOgxB,qBACZhxB,EAAOxF,iBACP7B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAOixB,4BACZjxB,EAAO1F,oBACP3B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAOkxB,4BACZlxB,EAAO3F,oBACP1B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOmxB,2BACZnxB,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,GACTuE,KAC6B,eAA1BrH,EAAQjB,SAASC,KAc3B,OAbAqI,EAAO7F,gBAAkBnN,KAAK8hB,wBAC7B9hB,KAAKgT,OAAOoxB,wBACZpxB,EAAO7F,gBACPxB,GAGDqH,EAAO5F,gBAAkBpN,KAAKiiB,uBAC7BjiB,KAAKgT,OAAOqxB,wBACZrxB,EAAO5F,gBACPzB,GAGDqH,EAAOvE,OAAS,GACTuE,EACD,GAA8B,UAA1BrH,EAAQjB,SAASC,KA0B3B,OAzBAqI,EAAOvG,WAAazM,KAAKiiB,uBACxBjiB,KAAKgT,OAAOsxB,mBACZtxB,EAAOvG,WACPd,GAGDqH,EAAOrG,WAAa3M,KAAK8hB,wBACxB9hB,KAAKgT,OAAOuxB,mBACZvxB,EAAOrG,WACPhB,GAGDqH,EAAOlG,kBAAoB9M,KAAK8hB,wBAC/B9hB,KAAKgT,OAAOwxB,0BACZxxB,EAAOlG,kBACPnB,GAGDqH,EAAOhG,kBAAoBhN,KAAKiiB,uBAC/BjiB,KAAKgT,OAAOyxB,0BACZzxB,EAAOhG,kBACPrB,GAGDqH,EAAOvE,OAAS,GACTuE,CAET,CAEA,OAAOA,CACR,EAACmtB,CAAA,CA33B+BC,CAAQje,GC/F5BuiB,yBAAoBtiB,GAAAsiB,SAAAA,IAAA,QAAA3kC,EAAAsiB,EAAAC,UAAArX,OAAAsX,EAAA,IAAA3f,MAAAyf,GAAAG,EAAAA,EAAAA,EAAAH,EAAAG,IAAAD,EAAAC,GAAAF,UAAAE,GAEjBziB,OAFiBA,EAAAqiB,EAAAvd,KAAA4d,MAAAL,SAAAtW,OAAAyW,KAAAviB,MAChC2K,KAAOsU,EAAU0lB,OAAM5kC,EACvBiM,KAAO,SAAQjM,CAAA,CAFiB4F,EAAA++B,EAAAtiB,OAEjB9gB,EAAAojC,EAAAnjC,UAad,OAbcD,EACfsmB,MAAA,aAAUtmB,EACVgnB,KAAA,aAAShnB,EACTiD,QAAA,WAAY,EAAAjD,EACZmD,UAAA,WAAc,EAAAnD,EACd+C,QAAA,WAAY,EAAA/C,EACZwC,YAAA,aAAgBxC,EAChB4C,OAAA,aAAW5C,EACX8C,UAAA,aAAc9C,EACdkC,YAAA,aAAgBlC,EAChBinB,QAAA,WAAY,EAAAjnB,EACZunB,aAAA,WACC,OAAAzI,EAAY2Q,G5CpBN,CACNvjB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,G4CUT,EAACi2B,CAAA,EAfuC/kB,GCJnC,SAAUilB,GACfC,EACA7N,EACA/0B,EACA6iC,EACAC,GAEA,KAAOD,EAAQ7iC,GAAM,CACpB,GAAI6iC,EAAQ7iC,EAAO,IAAK,CACvB,IAAM84B,EAAI+J,EAAQ7iC,EAAO,EACnB4R,EAAImjB,EAAI/0B,EAAO,EACf4sB,EAAIzvB,KAAKoX,IAAIukB,GACbiK,EAAI,GAAM5lC,KAAKga,IAAK,EAAIyV,EAAK,GAC7BoW,EACL,GAAM7lC,KAAKQ,KAAMivB,EAAImW,GAAKjK,EAAIiK,GAAMjK,IAAMlnB,EAAIknB,EAAI,EAAI,GAAK,EAAI,GAGhE6J,GAAYC,EAAK7N,EAFD53B,KAAKkzB,IAAIrwB,EAAM7C,KAAKivB,MAAM2I,EAAKnjB,EAAImxB,EAAKjK,EAAIkK,IAC3C7lC,KAAKs4B,IAAIoN,EAAO1lC,KAAKivB,MAAM2I,GAAM+D,EAAIlnB,GAAKmxB,EAAKjK,EAAIkK,IAC7BF,EACxC,CAEA,IAAMtN,EAAIoN,EAAI7N,GACVhsB,EAAI/I,EACJqJ,EAAIw5B,EAKR,IAHAI,GAAKL,EAAK5iC,EAAM+0B,GACZ+N,EAAQF,EAAIC,GAAQrN,GAAK,GAAGyN,GAAKL,EAAK5iC,EAAM6iC,GAEzC95B,EAAIM,GAAG,CAIb,IAHA45B,GAAKL,EAAK75B,EAAGM,GACbN,IACAM,IACOy5B,EAAQF,EAAI75B,GAAIysB,GAAK,GAAGzsB,IAC/B,KAAO+5B,EAAQF,EAAIv5B,GAAImsB,GAAK,GAAGnsB,GAChC,CAE8B,IAA1By5B,EAAQF,EAAI5iC,GAAOw1B,GACtByN,GAAKL,EAAK5iC,EAAMqJ,GAGhB45B,GAAKL,IADLv5B,EACaw5B,GAGVx5B,GAAK0rB,IAAG/0B,EAAOqJ,EAAI,GACnB0rB,GAAK1rB,IAAGw5B,EAAQx5B,EAAI,EACzB,CACD,CAEA,SAAS45B,GAAQL,EAAU75B,EAAWM,GACrC,IAAM65B,EAAMN,EAAI75B,GAChB65B,EAAI75B,GAAK65B,EAAIv5B,GACbu5B,EAAIv5B,GAAK65B,CACV,CCvCA,SAASC,GAASC,EAAYC,GAC7BC,GAASF,EAAM,EAAGA,EAAKG,SAASv6B,OAAQq6B,EAAQD,EACjD,CAGA,SAASE,GACRF,EACArO,EACAP,EACA6O,EACAG,GAEKA,IAAUA,EAAWC,GAAW,KACrCD,EAASE,KAAOhf,SAChB8e,EAASG,KAAOjf,SAChB8e,EAASI,MAAQlf,SACjB8e,EAASK,MAAQnf,SAEjB,IAAK,IAAI3b,EAAIgsB,EAAGhsB,EAAIyrB,EAAGzrB,IAAK,CAC3B,IAAM+6B,EAAQV,EAAKG,SAASx6B,GAC5Bg7B,GAAOP,EAAUJ,EAAKY,KAAOX,EAAOS,GAASA,EAC9C,CAEA,OAAON,CACR,CAEA,SAASO,GAAO1pB,EAAS3B,GAKxB,OAJA2B,EAAEqpB,KAAOvmC,KAAKs4B,IAAIpb,EAAEqpB,KAAMhrB,EAAEgrB,MAC5BrpB,EAAEspB,KAAOxmC,KAAKs4B,IAAIpb,EAAEspB,KAAMjrB,EAAEirB,MAC5BtpB,EAAEupB,KAAOzmC,KAAKkzB,IAAIhW,EAAEupB,KAAMlrB,EAAEkrB,MAC5BvpB,EAAEwpB,KAAO1mC,KAAKkzB,IAAIhW,EAAEwpB,KAAMnrB,EAAEmrB,MACrBxpB,CACR,CAEA,SAAS4pB,GAAgB5pB,EAAS3B,GACjC,OAAO2B,EAAEqpB,KAAOhrB,EAAEgrB,IACnB,CACA,SAASQ,GAAgB7pB,EAAS3B,GACjC,OAAO2B,EAAEspB,KAAOjrB,EAAEirB,IACnB,CAEA,SAASQ,GAAS9pB,GACjB,OAAQA,EAAEupB,KAAOvpB,EAAEqpB,OAASrpB,EAAEwpB,KAAOxpB,EAAEspB,KACxC,CACA,SAASS,GAAW/pB,GAMnB,OAAOA,EAAEupB,KAAOvpB,EAAEqpB,MAAQrpB,EAAEwpB,KAAOxpB,EAAEspB,KACtC,CAkBA,SAAS19B,GAASoU,EAAS3B,GAC1B,OACC2B,EAAEqpB,MAAQhrB,EAAEgrB,MAAQrpB,EAAEspB,MAAQjrB,EAAEirB,MAAQjrB,EAAEkrB,MAAQvpB,EAAEupB,MAAQlrB,EAAEmrB,MAAQxpB,EAAEwpB,IAE1E,CAEA,SAASQ,GAAWhqB,EAAS3B,GAC5B,OACCA,EAAEgrB,MAAQrpB,EAAEupB,MAAQlrB,EAAEirB,MAAQtpB,EAAEwpB,MAAQnrB,EAAEkrB,MAAQvpB,EAAEqpB,MAAQhrB,EAAEmrB,MAAQxpB,EAAEspB,IAE1E,CAEA,SAASF,GAAWF,GACnB,MAAO,CACNA,SAAAA,EACAe,OAAQ,EACRN,MAAM,EACNN,KAAMhf,SACNif,KAAMjf,SACNkf,MAAOlf,SACPmf,MAAOnf,SAET,CAKA,SAAS6f,GACR3B,EACA5iC,EACA6iC,EACA/J,EACAgK,GAIA,IAFA,IAAM0B,EAAQ,CAACxkC,EAAM6iC,GAEd2B,EAAMx7B,QAIZ,MAHA65B,EAAQ2B,EAAM7b,QACd3oB,EAAOwkC,EAAM7b,QAEOmQ,GAApB,CAEA,IAAMjG,EAAM7yB,EAAO7C,KAAKsnC,MAAM5B,EAAQ7iC,GAAQ84B,EAAI,GAAKA,EACvD6J,GAAYC,EAAK/P,EAAK7yB,EAAM6iC,EAAOC,GAEnC0B,EAAMt7B,KAAKlJ,EAAM6yB,EAAKA,EAAKgQ,GAE7B,CAEA,IAAa6B,gBAAK,WAKjB,SAAAA,EAAYC,GAAkB5mC,KAJtB6mC,iBACAC,EAAAA,KAAAA,wBACAvgC,UAAI,EAIXvG,KAAK6mC,YAAcznC,KAAKkzB,IAAI,EAAGsU,GAC/B5mC,KAAK8mC,YAAc1nC,KAAKkzB,IAAI,EAAGlzB,KAAKsnC,KAAwB,GAAnB1mC,KAAK6mC,cAC9C7mC,KAAK0E,OACN,CAAC,IAAApD,EAAAqlC,EAAAplC,iBAAAD,EAEDgrB,OAAA,SAAOD,GACN,IAAIgZ,EAAOrlC,KAAKuG,KACVwgC,EAAiB,GAEvB,IAAKT,GAAWja,EAAMgZ,GACrB,OAAO0B,EAMR,IAHA,IAAMzB,EAAStlC,KAAKslC,OACd0B,EAAgB,GAEf3B,GAAM,CACZ,IAAK,IAAIr6B,EAAI,EAAGA,EAAIq6B,EAAKG,SAASv6B,OAAQD,IAAK,CAC9C,IAAM+6B,EAAQV,EAAKG,SAASx6B,GACtBi8B,EAAY5B,EAAKY,KAAOX,EAAOS,GAASA,EAE1CO,GAAWja,EAAM4a,KAChB5B,EAAKY,KAAMc,EAAO57B,KAAK46B,GAClB79B,GAASmkB,EAAM4a,GAAYjnC,KAAKknC,KAAKnB,EAAOgB,GAChDC,EAAc77B,KAAK46B,GAE1B,CACAV,EAAO2B,EAAcpc,KACtB,CAEA,OAAOmc,CACR,EAACzlC,EAED6lC,SAAA,SAAS9a,GACR,IAAIgZ,EAAOrlC,KAAKuG,KAGhB,GADkB+/B,GAAWja,EAAMgZ,GAGlC,IADA,IAAM2B,EAAgB,GACf3B,GAAM,CACZ,IAAK,IAAIr6B,EAAI,EAAGA,EAAIq6B,EAAKG,SAASv6B,OAAQD,IAAK,CAC9C,IAAM+6B,EAAQV,EAAKG,SAASx6B,GACtBi8B,EAAY5B,EAAKY,KAAOjmC,KAAKslC,OAAOS,GAASA,EAEnD,GAAIO,GAAWja,EAAM4a,GAAY,CAChC,GAAI5B,EAAKY,MAAQ/9B,GAASmkB,EAAM4a,GAC/B,SAEDD,EAAc77B,KAAK46B,EACpB,CACD,CACAV,EAAO2B,EAAcpc,KACtB,CAGD,OAAO,CACR,EAACtpB,EAED8lC,KAAA,SAAK7gC,GACJ,GAAIA,EAAK0E,OAASjL,KAAK8mC,YACtB,IAAK,IAAI97B,EAAI,EAAGA,EAAIzE,EAAK0E,OAAQD,IAChChL,KAAKk1B,OAAO3uB,EAAKyE,QAFnB,CAQA,IAAIq6B,EAAOrlC,KAAKqnC,OAAO9gC,EAAKqR,QAAS,EAAGrR,EAAK0E,OAAS,EAAG,GAEzD,GAAKjL,KAAKuG,KAAKi/B,SAASv6B,OAGjB,GAAIjL,KAAKuG,KAAKggC,SAAWlB,EAAKkB,OAEpCvmC,KAAKsnC,WAAWtnC,KAAKuG,KAAM8+B,OACrB,CACN,GAAIrlC,KAAKuG,KAAKggC,OAASlB,EAAKkB,OAAQ,CAEnC,IAAMgB,EAAUvnC,KAAKuG,KACrBvG,KAAKuG,KAAO8+B,EACZA,EAAOkC,CACR,CAGAvnC,KAAKwnC,QAAQnC,EAAMrlC,KAAKuG,KAAKggC,OAASlB,EAAKkB,OAAS,GAAG,EACxD,MAdCvmC,KAAKuG,KAAO8+B,CAPb,CAsBD,EAAC/jC,EAED4zB,OAAA,SAAOuS,GACNznC,KAAKwnC,QAAQC,EAAMznC,KAAKuG,KAAKggC,OAAS,EACvC,EAACjlC,EAEDoD,MAAA,WACC1E,KAAKuG,KAAOm/B,GAAW,GACxB,EAACpkC,EAED0F,OAAA,SAAOygC,GAUN,IATA,IAIIz8B,EACA08B,EALArC,EAAoBrlC,KAAKuG,KACvB8lB,EAAOrsB,KAAKslC,OAAOmC,GACnB18B,EAAO,GACP48B,EAAoB,GAGtBC,GAAU,EAGPvC,GAAQt6B,EAAKE,QAAQ,CAS3B,GARKo6B,IAEJA,EAAOt6B,EAAK6f,MACZ8c,EAAS38B,EAAKA,EAAKE,OAAS,GAC5BD,EAAI28B,EAAQ/c,MACZgd,GAAU,GAGPvC,EAAKY,KAAM,CAGd,IAAM5P,EAAQgP,EAAKG,SAASqC,QAAQJ,IAErB,IAAXpR,IAEHgP,EAAKG,SAAS/P,OAAOY,EAAO,GAC5BtrB,EAAKI,KAAKk6B,GACVrlC,KAAK8nC,UAAU/8B,GAEjB,CAEK68B,GAAYvC,EAAKY,OAAQ/9B,GAASm9B,EAAMhZ,GAOlCqb,GAET18B,IACDq6B,EAAOqC,EAAOlC,SAASx6B,GACvB48B,GAAU,GAEVvC,EAAO,MAXPt6B,EAAKI,KAAKk6B,GACVsC,EAAQx8B,KAAKH,GACbA,EAAI,EACJ08B,EAASrC,EACTA,EAAOA,EAAKG,SAAS,GASvB,CACD,EAAClkC,EAEOgkC,OAAA,SAAUmC,GACjB,OAAOA,CACR,EAACnmC,EAEOymC,YAAA,SAAYzrB,EAAS3B,GAC5B,OAAO2B,EAAEqpB,KAAOhrB,EAAEgrB,IACnB,EAACrkC,EACO0mC,YAAA,SAAY1rB,EAAS3B,GAC5B,OAAO2B,EAAEspB,KAAOjrB,EAAEirB,IACnB,EAACtkC,EAEO4lC,KAAA,SAAK7B,EAAY0B,GAExB,IADA,IAAMC,EAAgB,GACf3B,GACFA,EAAKY,KAAMc,EAAO57B,KAAIsX,MAAXskB,EAAe1B,EAAKG,UAC9BwB,EAAc77B,KAAIsX,MAAlBukB,EAAsB3B,EAAKG,UAEhCH,EAAO2B,EAAcpc,MAEtB,OAAOmc,CACR,EAACzlC,EAEO+lC,OAAA,SAAOY,EAAehmC,EAAc6iC,EAAeyB,GAC1D,IAEIlB,EAFE6C,EAAIpD,EAAQ7iC,EAAO,EACrBkmC,EAAInoC,KAAK6mC,YAGb,GAAIqB,GAAKC,EAIR,OADA/C,GADAC,EAAOK,GAAWuC,EAAMrwB,MAAM3V,EAAM6iC,EAAQ,IAC7B9kC,KAAKslC,QACbD,EAGHkB,IAEJA,EAASnnC,KAAKsnC,KAAKtnC,KAAKoX,IAAI0xB,GAAK9oC,KAAKoX,IAAI2xB,IAG1CA,EAAI/oC,KAAKsnC,KAAKwB,EAAI9oC,KAAKC,IAAI8oC,EAAG5B,EAAS,MAGxClB,EAAOK,GAAW,KACbO,MAAO,EACZZ,EAAKkB,OAASA,EAId,IAAM6B,EAAKhpC,KAAKsnC,KAAKwB,EAAIC,GACnBE,EAAKD,EAAKhpC,KAAKsnC,KAAKtnC,KAAKQ,KAAKuoC,IAEpC3B,GAAYyB,EAAOhmC,EAAM6iC,EAAOuD,EAAIroC,KAAK+nC,aAEzC,IAAK,IAAI/8B,EAAI/I,EAAM+I,GAAK85B,EAAO95B,GAAKq9B,EAAI,CACvC,IAAMC,EAASlpC,KAAKs4B,IAAI1sB,EAAIq9B,EAAK,EAAGvD,GAEpC0B,GAAYyB,EAAOj9B,EAAGs9B,EAAQF,EAAIpoC,KAAKgoC,aAEvC,IAAK,IAAI18B,EAAIN,EAAGM,GAAKg9B,EAAQh9B,GAAK88B,EAAI,CACrC,IAAMG,EAASnpC,KAAKs4B,IAAIpsB,EAAI88B,EAAK,EAAGE,GAGpCjD,EAAKG,SAASr6B,KAAKnL,KAAKqnC,OAAOY,EAAO38B,EAAGi9B,EAAQhC,EAAS,GAC3D,CACD,CAIA,OAFAnB,GAASC,EAAMrlC,KAAKslC,QAEbD,CACR,EAAC/jC,EAEOknC,eAAA,SAAenc,EAAYgZ,EAAYoD,EAAe19B,GAC7D,KACCA,EAAKI,KAAKk6B,IAENA,EAAKY,MAAQl7B,EAAKE,OAAS,IAAMw9B,GAHzB,CAWZ,IAJA,IAAIC,EAAU/hB,SACVgiB,EAAiBhiB,SACjBiiB,SAEK59B,EAAI,EAAGA,EAAIq6B,EAAKG,SAASv6B,OAAQD,IAAK,CAC9C,IAAM+6B,EAAQV,EAAKG,SAASx6B,GAEtB4vB,EAAOwL,GAASL,GAChB8C,GAjTYvsB,EAiTe+P,EAjTN1R,EAiTYorB,GA/SxC3mC,KAAKkzB,IAAI3X,EAAEkrB,KAAMvpB,EAAEupB,MAAQzmC,KAAKs4B,IAAI/c,EAAEgrB,KAAMrpB,EAAEqpB,QAC9CvmC,KAAKkzB,IAAI3X,EAAEmrB,KAAMxpB,EAAEwpB,MAAQ1mC,KAAKs4B,IAAI/c,EAAEirB,KAAMtpB,EAAEspB,OA8SGhL,GAI5CiO,EAAcF,GACjBA,EAAiBE,EACjBH,EAAU9N,EAAO8N,EAAU9N,EAAO8N,EAClCE,EAAa7C,GACH8C,IAAgBF,GAEtB/N,EAAO8N,IACVA,EAAU9N,EACVgO,EAAa7C,EAGhB,CAEAV,EAAOuD,GAAcvD,EAAKG,SAAS,EACpC,CAnUF,IAAsBlpB,EAAS3B,EAqU7B,OAAO0qB,CACR,EAAC/jC,EAEOkmC,QAAA,SAAQC,EAAYgB,EAAeK,GAC1C,IAAMzc,EAAOyc,EAASrB,EAAOznC,KAAKslC,OAAOmC,GACnCsB,EAAqB,GAGrB1D,EAAOrlC,KAAKwoC,eAAenc,EAAMrsB,KAAKuG,KAAMkiC,EAAOM,GAOzD,IAJA1D,EAAKG,SAASr6B,KAAKs8B,GACnBzB,GAAOX,EAAMhZ,GAGNoc,GAAS,GACXM,EAAWN,GAAOjD,SAASv6B,OAASjL,KAAK6mC,aAC5C7mC,KAAKgpC,OAAOD,EAAYN,GACxBA,IAKFzoC,KAAKipC,oBAAoB5c,EAAM0c,EAAYN,EAC5C,EAACnnC,EAGO0nC,OAAA,SAAOD,EAAoBN,GAClC,IAAMpD,EAAO0D,EAAWN,GAClBN,EAAI9C,EAAKG,SAASv6B,OAClB4I,EAAI7T,KAAK8mC,YAEf9mC,KAAKkpC,iBAAiB7D,EAAMxxB,EAAGs0B,GAE/B,IAAMgB,EAAanpC,KAAKopC,kBAAkB/D,EAAMxxB,EAAGs0B,GAE7CkB,EAAU3D,GACfL,EAAKG,SAAS/P,OAAO0T,EAAY9D,EAAKG,SAASv6B,OAASk+B,IAEzDE,EAAQ9C,OAASlB,EAAKkB,OACtB8C,EAAQpD,KAAOZ,EAAKY,KAEpBb,GAASC,EAAMrlC,KAAKslC,QACpBF,GAASiE,EAASrpC,KAAKslC,QAEnBmD,EAAOM,EAAWN,EAAQ,GAAGjD,SAASr6B,KAAKk+B,GACtCrpC,KAACsnC,WAAWjC,EAAMgE,EAC5B,EAAC/nC,EAEOgmC,WAAA,SAAWjC,EAAYgE,GAE9BrpC,KAAKuG,KAAOm/B,GAAW,CAACL,EAAMgE,IAC9BrpC,KAAKuG,KAAKggC,OAASlB,EAAKkB,OAAS,EACjCvmC,KAAKuG,KAAK0/B,MAAO,EACjBb,GAASplC,KAAKuG,KAAMvG,KAAKslC,OAC1B,EAAChkC,EAEO8nC,kBAAA,SAAkB/D,EAAYxxB,EAAWs0B,GAKhD,IAJA,IAAI9R,EAxXoB/Z,EAAS3B,EAC5BgrB,EACAC,EACAC,EACAC,EAqXDwD,EAAa3iB,SACb+hB,EAAU/hB,SAEL3b,EAAI6I,EAAG7I,GAAKm9B,EAAIt0B,EAAG7I,IAAK,CAChC,IAAMu+B,EAAQhE,GAASF,EAAM,EAAGr6B,EAAGhL,KAAKslC,QAClCkE,EAAQjE,GAASF,EAAMr6B,EAAGm9B,EAAGnoC,KAAKslC,QAElCmE,GAhYiBntB,EAgYUitB,EAhYD5uB,EAgYQ6uB,EA/XpC7D,EAAOvmC,KAAKkzB,IAAIhW,EAAEqpB,KAAMhrB,EAAEgrB,MAC1BC,EAAOxmC,KAAKkzB,IAAIhW,EAAEspB,KAAMjrB,EAAEirB,MAC1BC,EAAOzmC,KAAKs4B,IAAIpb,EAAEupB,KAAMlrB,EAAEkrB,MAC1BC,EAAO1mC,KAAKs4B,IAAIpb,EAAEwpB,KAAMnrB,EAAEmrB,MAEzB1mC,KAAKkzB,IAAI,EAAGuT,EAAOF,GAAQvmC,KAAKkzB,IAAI,EAAGwT,EAAOF,IA2X7ChL,EAAOwL,GAASmD,GAASnD,GAASoD,GAGpCC,EAAUH,GACbA,EAAaG,EACbpT,EAAQrrB,EAER09B,EAAU9N,EAAO8N,EAAU9N,EAAO8N,GACxBe,IAAYH,GAElB1O,EAAO8N,IACVA,EAAU9N,EACVvE,EAAQrrB,EAGX,CAEA,OAAOqrB,GAAS8R,EAAIt0B,CACrB,EAACvS,EAGO4nC,iBAAA,SAAiB7D,EAAYxxB,EAAWs0B,GAC/C,IAAMJ,EAAc1C,EAAKY,KAAOjmC,KAAK+nC,YAAc7B,GAC7C8B,EAAc3C,EAAKY,KAAOjmC,KAAKgoC,YAAc7B,GACnCnmC,KAAK0pC,eAAerE,EAAMxxB,EAAGs0B,EAAGJ,GAChC/nC,KAAK0pC,eAAerE,EAAMxxB,EAAGs0B,EAAGH,IAK/C3C,EAAKG,SAASmE,KAAK5B,EAErB,EAACzmC,EAGOooC,eAAA,SACPrE,EACAxxB,EACAs0B,EACApD,GAEAM,EAAKG,SAASmE,KAAK5E,GAOnB,IALA,IAAMO,EAAStlC,KAAKslC,OACdsE,EAAWrE,GAASF,EAAM,EAAGxxB,EAAGyxB,GAChCuE,EAAYtE,GAASF,EAAM8C,EAAIt0B,EAAGs0B,EAAG7C,GACvCwE,EAASzD,GAAWuD,GAAYvD,GAAWwD,GAEtC7+B,EAAI6I,EAAG7I,EAAIm9B,EAAIt0B,EAAG7I,IAAK,CAC/B,IAAM+6B,EAAQV,EAAKG,SAASx6B,GAC5Bg7B,GAAO4D,EAAUvE,EAAKY,KAAOX,EAAOS,GAASA,GAC7C+D,GAAUzD,GAAWuD,EACtB,CAEA,IAAK,IAAI5+B,EAAIm9B,EAAIt0B,EAAI,EAAG7I,GAAK6I,EAAG7I,IAAK,CACpC,IAAM+6B,EAAQV,EAAKG,SAASx6B,GAC5Bg7B,GAAO6D,EAAWxE,EAAKY,KAAOX,EAAOS,GAASA,GAC9C+D,GAAUzD,GAAWwD,EACtB,CAEA,OAAOC,CACR,EAACxoC,EAEO2nC,oBAAA,SAAoB5c,EAAYthB,EAAc09B,GAErD,IAAK,IAAIz9B,EAAIy9B,EAAOz9B,GAAK,EAAGA,IAC3Bg7B,GAAOj7B,EAAKC,GAAIqhB,EAElB,EAAC/qB,EAEOwmC,UAAA,SAAU/8B,GAEjB,IAAK,IAAyBg/B,EAArB/+B,EAAID,EAAKE,OAAS,EAAaD,GAAK,EAAGA,IACf,IAA5BD,EAAKC,GAAGw6B,SAASv6B,OAChBD,EAAI,GACP++B,EAAWh/B,EAAKC,EAAI,GAAGw6B,UACd/P,OAAOsU,EAASlC,QAAQ98B,EAAKC,IAAK,GACrChL,KAAK0E,QAEZ0gC,GAASr6B,EAAKC,GAAIhL,KAAKslC,OAG1B,EAACqB,CAAA,CAzZgB,GCnILqD,gBAAY,WAKxB,SAAAA,EAAYh2B,GAAgChU,KAJpCiqC,UACAC,EAAAA,KAAAA,qBACAC,cAAQ,EAGfnqC,KAAKiqC,KAAO,IAAItD,GACf3yB,GAAWA,EAAQ4yB,WAAa5yB,EAAQ4yB,WAAa,GAEtD5mC,KAAKkqC,SAAW,IAAIE,IACpBpqC,KAAKmqC,SAAW,IAAIC,GACrB,CAAC,IAAA9oC,EAAA0oC,EAAAzoC,iBAAAD,EAEO+oC,QAAA,SAAQ1+B,EAA+B0gB,GAC9CrsB,KAAKkqC,SAAShoB,IAAIvW,EAAQlG,GAAiB4mB,GAC3CrsB,KAAKmqC,SAASjoB,IAAImK,EAAM1gB,EAAQlG,GACjC,EAACnE,EAEOgkC,OAAA,SAAO35B,GACd,IAGIf,EAHE0/B,EAAuB,GACvBC,EAAsB,GAG5B,GAA8B,YAA1B5+B,EAAQjB,SAASC,KACpBC,EAAce,EAAQjB,SAASE,YAAY,QACrC,GAA8B,eAA1Be,EAAQjB,SAASC,KAC3BC,EAAce,EAAQjB,SAASE,gBACrBe,IAA0B,UAA1BA,EAAQjB,SAASC,KAG3B,MAAU,IAAAjF,MAAM,mDAFhBkF,EAAc,CAACe,EAAQjB,SAASE,YAGjC,CAEA,IAAK,IAAII,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IACvCu/B,EAAUp/B,KAAKP,EAAYI,GAAG,IAC9Bs/B,EAAWn/B,KAAKP,EAAYI,GAAG,IAGhC,IAAMw/B,EAASprC,KAAKs4B,IAAGjV,MAARrjB,KAAYmrC,GACrBE,EAASrrC,KAAKkzB,IAAG7P,MAARrjB,KAAYmrC,GAI3B,MAAO,CACN5E,KAJcvmC,KAAKs4B,IAAGjV,MAARrjB,KAAYkrC,GAK1B1E,KAAM4E,EACN3E,KALczmC,KAAKkzB,IAAG7P,MAARrjB,KAAYkrC,GAM1BxE,KAAM2E,EAER,EAACnpC,EAED4zB,OAAA,SAAOvpB,GACN,GAAI3L,KAAKkqC,SAASn8B,IAAIuB,OAAO3D,EAAQlG,KACpC,MAAM,IAAIC,MAAM,0BAEjB,IAAM2mB,EAAOrsB,KAAKslC,OAAO35B,GACzB3L,KAAKqqC,QAAQ1+B,EAAS0gB,GACtBrsB,KAAKiqC,KAAK/U,OAAO7I,EAClB,EAAC/qB,EAED8lC,KAAA,SAAKv7B,GAAgC,IAAA9L,EAAAC,KAC9BonC,EAAe,GACfsD,EAAuB,IAAI5pC,IACjC+K,EAAS7I,QAAQ,SAAC2I,GACjB,IAAM0gB,EAAOtsB,EAAKulC,OAAO35B,GAEzB,GADA5L,EAAKsqC,QAAQ1+B,EAAS0gB,GAClBqe,EAAQ98B,IAAI0B,OAAO3D,EAAQlG,KAC9B,UAAUC,oCAAoCiG,EAAQlG,IAEvDilC,EAAQlmC,IAAI8K,OAAO3D,EAAQlG,KAC3B2hC,EAAKj8B,KAAKkhB,EACX,GACArsB,KAAKiqC,KAAK7C,KAAKA,EAChB,EAAC9lC,EAEDkwB,OAAA,SAAO7lB,GACN3L,KAAKgH,OAAO2E,EAAQlG,IACpB,IAAM4mB,EAAOrsB,KAAKslC,OAAO35B,GACzB3L,KAAKqqC,QAAQ1+B,EAAS0gB,GACtBrsB,KAAKiqC,KAAK/U,OAAO7I,EAClB,EAAC/qB,EAED0F,OAAA,SAAO0uB,GACN,IAAM2P,EAAOrlC,KAAKkqC,SAASn8B,IAAI2nB,GAC/B,IAAK2P,EACJ,MAAM,IAAI3/B,MAASgwB,EAA+C,wCAGnE11B,KAAKiqC,KAAKjjC,OAAOq+B,EAClB,EAAC/jC,EAEDoD,MAAA,WACC1E,KAAKiqC,KAAKvlC,OACX,EAACpD,EAEDgrB,OAAA,SAAO3gB,GAA6B,IAAA1F,EACnCjG,KACA,OADcA,KAAKiqC,KAAK3d,OAAOtsB,KAAKslC,OAAO35B,IAC9BpG,IAAI,SAAC8/B,GACjB,OAAOp/B,EAAKkkC,SAASp8B,IAAIs3B,EAC1B,EACD,EAAC/jC,EAED6lC,SAAA,SAASx7B,GACR,YAAYs+B,KAAK9C,SAASnnC,KAAKslC,OAAO35B,GACvC,EAACq+B,CAAA,CAxGuB,GCsCZW,GAAoB,CAChCh9B,MAAO,WAAiB,MC1CjB,uCAAuCuK,QAAQ,QAAS,SAAUoT,GACxE,IAAMvlB,EAAqB,GAAhB3G,KAAKwrC,SAAiB,EAEjC,OADU,KAALtf,EAAWvlB,EAAS,EAAJA,EAAW,GACvBwgB,SAAS,GACnB,EDsC4C,EAC5CrF,UAAW,SAACzb,GAAa,MAAmB,iBAAPA,GAAiC,KAAdA,EAAGwF,MAAa,GAG5D4/B,gBACZ,WAAA,SAAAA,EAAYtqC,GAWL+gB,KAAAA,gBAECwpB,EAAAA,KAAAA,oBAEAC,kBAAY,EAAA/qC,KAEZkgB,WAAK,EAAAlgB,KAKLgrC,UAAgC,WAAQ,EArB/ChrC,KAAKkgB,MAAQ,CAAA,EACblgB,KAAK+qC,aAAe,IAAIf,GAIxBhqC,KAAK8qC,SAAUvqC,IAA6B,IAAnBA,EAAOuqC,QAChC9qC,KAAKshB,WACJ/gB,GAAUA,EAAO+gB,WAAa/gB,EAAO+gB,WAAaqpB,EACpD,CAAC,IAAArpC,EAAAupC,EAAAtpC,iBAAAD,EAeO2pC,MAAA,SAASC,GAChB,OAAOC,KAAKC,MAAMD,KAAKE,UAAUH,GAClC,EAAC5pC,EAEDqM,MAAA,WACC,OAAW3N,KAACshB,WAAW3T,OACxB,EAACrM,EAEDsM,IAAA,SAAInI,GACH,OAAOwI,QAAQjO,KAAKkgB,MAAMza,GAC3B,EAACnE,EAED8lC,KAAA,SACC7gC,EACA+kC,GAAoE,IAAAvrC,EAEpEC,KAAA,GAAoB,IAAhBuG,EAAK0E,OAAT,CAKA,IAAMsgC,EAAavrC,KAAKirC,MAAM1kC,GAI9BglC,EAAWvoC,QAAQ,SAAC2I,GACfA,QAAQlG,KACXkG,EAAQlG,GAAK1F,EAAKuhB,WAAW3T,SAG1B5N,EAAK+qC,UACHn/B,EAAQlB,WAAW+gC,UAGvBlsB,EAAiB3T,EAAQlB,WAAW+gC,WAFpC7/B,EAAQlB,WAAW+gC,WAAa,IAAIhsB,KAKhC7T,EAAQlB,WAAWghC,UAGvBnsB,EAAiB3T,EAAQlB,WAAWghC,WAFpC9/B,EAAQlB,WAAWghC,WAAa,IAAIjsB,KAKvC,GAEA,IAAM/V,EAAuB,GAC7B8hC,EAAWvoC,QAAQ,SAAC2I,GACnB,IAAMlG,EAAKkG,EAAQlG,GACnB,GAAI6lC,IACaA,EAAkB3/B,GAKjC,UAAUjG,MACED,WAAAA,oBAAoB0lC,KAAKE,UAAU1/B,IAMjD,GAAI5L,EAAK6N,IAAInI,GACZ,MAAU,IAAAC,MAAK,wCAAyCD,GAGzD1F,EAAKmgB,MAAMza,GAAMkG,EACjBlC,EAAQ0B,KAAK1F,EACd,GACAzF,KAAK+qC,aAAa3D,KAAKmE,GACvBvrC,KAAKgrC,UAAUvhC,EAAS,SAnDxB,CAoDD,EAACnI,EAEDgrB,OAAA,SACCD,EACAD,GAAmDnmB,IAAAA,EAEnDjG,KAAM6L,EAAW7L,KAAK+qC,aAAaze,OAAOD,GAAM9mB,IAAI,SAACE,GAAE,OAAKQ,EAAKia,MAAMza,EAAG,GAC1E,OACQzF,KAAKirC,MADT7e,EACevgB,EAASugB,OAAOA,GAEhBvgB,EAEpB,EAACvK,EAEDqf,iBAAA,SAAiBC,GAChB5gB,KAAKgrC,UAAY,SAACzZ,EAAKma,GACtB9qB,EAAS2Q,EAAKma,EACf,CACD,EAACpqC,EAED4mB,gBAAA,SAAkDziB,GACjD,IAAMkG,EAAU3L,KAAKkgB,MAAMza,GAC3B,IAAKkG,EACJ,MAAM,IAAIjG,kCACmBD,EAAE,gCAGhC,OAAWzF,KAACirC,MAAMt/B,EAAQjB,SAC3B,EAACpJ,EAEDg0B,kBAAA,SAAkB7vB,GACjB,IAAMkG,EAAU3L,KAAKkgB,MAAMza,GAC3B,IAAKkG,EACJ,MAAU,IAAAjG,MACmBD,4BAAAA,EAAkC,kCAGhE,OAAOzF,KAAKirC,MAAMt/B,EAAQlB,WAC3B,EAACnJ,EAEDwoB,eAAA,SACC6hB,GAAsEhiC,IAAAA,EAEtE3J,KAAMuxB,EAAmB,GACzBoa,EAAmB3oC,QAAQ,SAAAlD,GAAG,IAAA2F,EAAE3F,EAAF2F,GAAI4E,EAAQvK,EAARuK,SAAUgC,EAAKvM,EAALuM,MACrCV,EAAUhC,EAAKuW,MAAMza,GAE3B,IAAKkG,EACJ,MAAU,IAAAjG,MAAK,yBACWD,EAA8B,8BAIzD8rB,EAAIpmB,KAAK1F,GAETkG,EAAQlB,WAAWJ,GAAYgC,EAG3B1C,EAAKmhC,UACRn/B,EAAQlB,WAAWghC,WAAa,IAAIjsB,KAEtC,GAEIxf,KAAKgrC,WACRhrC,KAAKgrC,UAAUzZ,EAAK,SAEtB,EAACjwB,EAEDuoB,eAAA,SACC+hB,GAAyE,IAAAl+B,EAAA1N,KAEnEuxB,EAAmB,GACzBqa,EAAmB5oC,QAAQ,SAAA4D,GAAG,IAAAnB,EAAEmB,EAAFnB,GAAIiF,EAAQ9D,EAAR8D,SACjC6mB,EAAIpmB,KAAK1F,GAET,IAAMkG,EAAU+B,EAAKwS,MAAMza,GAE3B,IAAKkG,EACJ,MAAM,IAAIjG,MACgBD,yBAAAA,EAA8B,8BAIzDkG,EAAQjB,SAAWgD,EAAKu9B,MAAMvgC,GAE9BgD,EAAKq9B,aAAavZ,OAAO7lB,GAGrB+B,EAAKo9B,UACRn/B,EAAQlB,WAAWghC,WAAa,IAAIjsB,KAEtC,GAEIxf,KAAKgrC,WACRhrC,KAAKgrC,UAAUzZ,EAAK,SAEtB,EAACjwB,EAEDonB,OAAA,SACC7c,GAGG,IAAAggC,EAAA7rC,KAEGuxB,EAAmB,GAwCzB,OAvCA1lB,EAAS7I,QAAQ,SAAA08B,GAA6B,IACzC8L,EADe9gC,EAAQg1B,EAARh1B,SAAUD,EAAUi1B,EAAVj1B,WAEzBqhC,EAAiB1rB,EAAA,CAAA,EAAQ3V,GAEzBohC,EAAKf,UACRU,GAAa,IAAIhsB,KAEb/U,GACHqhC,EAAkBN,UACe,iBAAzB/gC,EAAW+gC,UACf/gC,EAAW+gC,UACXA,EACJM,EAAkBL,UACe,iBAAzBhhC,EAAWghC,UACfhhC,EAAWghC,UACXD,GAEJM,EAAoB,CAAEN,UAAAA,EAAWC,UAAWD,IAI9C,IAAM/lC,EAAKomC,EAAKl+B,QACVhC,EAAU,CACflG,GAAAA,EACAkF,KAAM,UACND,SAAAA,EACAD,WAAYqhC,GAGbD,EAAK3rB,MAAMza,GAAMkG,EACjBkgC,EAAKd,aAAa7V,OAAOvpB,GAEzB4lB,EAAIpmB,KAAK1F,EACV,GAEIzF,KAAKgrC,WACRhrC,KAAKgrC,UAAS,GAAAl/B,OAAKylB,GAAM,UAGnBA,CACR,EAACjwB,EAED,OAAA,SAAOiwB,GAAgBwa,IAAAA,EACtBxa,KAAAA,EAAIvuB,QAAQ,SAACyC,GACZ,IAAIsmC,EAAK7rB,MAAMza,GAId,MAAU,IAAAC,MAAM,kDAHTqmC,EAAK7rB,MAAMza,GAClBsmC,EAAKhB,aAAa/jC,OAAOvB,EAI3B,GAEIzF,KAAKgrC,WACRhrC,KAAKgrC,UAASl/B,GAAAA,OAAKylB,GAAM,SAE3B,EAACjwB,EAED0qC,QAAA,eAAOC,EAAAjsC,KACN,OAAOA,KAAKirC,MAAM1gC,OAAOC,KAAKxK,KAAKkgB,OAAO3a,IAAI,SAACE,GAAE,OAAKwmC,EAAK/rB,MAAMza,EAAG,GACrE,EAACnE,EAEDoD,MAAA,WACC1E,KAAKkgB,MAAQ,CAAA,EACblgB,KAAK+qC,aAAarmC,OACnB,EAACpD,EAED4M,KAAA,WACC,OAAO3D,OAAOC,KAAKxK,KAAKkgB,OAAOjV,MAChC,EAAC4/B,CAAA,CA3QD,GE1CK,SAAUqB,GAAwBC,GACvC,IAAMhf,EAASgf,EAAQvhC,YACnBwhC,EAAQ,EACZ,GAAIjf,GAAUA,EAAOliB,OAAS,EAAG,CAChCmhC,GAAShtC,KAAKw0B,IAAIyY,GAASlf,EAAO,KAClC,IAAK,IAAIniB,EAAI,EAAGA,EAAImiB,EAAOliB,OAAQD,IAClCohC,GAAShtC,KAAKw0B,IAAIyY,GAASlf,EAAOniB,IAEpC,CACA,OAAOohC,CACR,CAEA,IAAME,GAAUhpB,EAAcA,EAAe,EACvCipB,GAAcntC,KAAKsU,GAAK,IAE9B,SAAS24B,GAASlf,GACjB,IAAMqf,EAAerf,EAAOliB,OAE5B,GAAIuhC,GAAgB,EACnB,OACD,EAKA,IAHA,IAAIJ,EAAQ,EAERphC,EAAI,EACDA,EAAIwhC,GAUVJ,IANCjf,EAAOniB,EAAI,GAAKwhC,GAAgBxhC,EAAI,GAAKwhC,EAAexhC,EAAI,GAIxC,GAAKuhC,GAPZpf,EAAOniB,GAKA,GAAKuhC,IAIGntC,KAAK+jB,IARnBgK,EAAOniB,EAAI,IAAMwhC,EAAe,EAAIxhC,EAAI,GAKhC,GAAKuhC,IAK5BvhC,IAGD,OAAOohC,EAAQE,EAChB,CC5Ca,IAAAG,GAA8B,SAC1C9gC,EACA+gC,GAEA,MAA8B,YAA1B/gC,EAAQjB,SAASC,MAIduhC,GAAwBvgC,EAAQjB,UAAYgiC,CACpD,ECTaC,GAA8B,SAC1ChhC,EACAihC,GAEA,MAA8B,YAA1BjhC,EAAQjB,SAASC,MAIRuhC,GAAwBvgC,EAAQjB,UAC/BkiC,CACf,ECTaC,GAA8B,SAC1ClhC,GAEA,OAC2B,YAA1BA,EAAQjB,SAASC,MACS,eAA1BgB,EAAQjB,SAASC,QAKWia,GAC5BjZ,EAIF,ECVgB,SAAAmhC,GACfne,EACAC,EACAme,GAEA,IAAMC,EAAYhgB,GAAmB2B,EAAGC,GAIpCqe,EAHcjgB,GAAmB4B,EAAGme,GAGRC,EAUhC,OAPIC,EAAgB,IACnBA,GAAiB,KAMR,IAAG7tC,KAAKw0B,IAFJqZ,EAAgB,GAEP,GACxB,CC2Ba,IAAAC,gBAA6B9qB,SAAAA,GAWzC,SAAA8qB,EAAYl5B,GAAqDjU,IAAAA,GAChEA,EAAAqiB,EAAAvd,KAAMmP,KAAAA,IAASjU,MAXhBiM,KAAO,mBAAkBjM,EAEjBkvB,kBAAoB,EAAClvB,EACrBkqB,eAASlqB,EAAAA,EACTynB,eAAS,EAAAznB,EAGT0nB,eAAO1nB,EACPovB,WAAY,EAKnB,IAAMxH,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAWR,GAPCjoB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAQuH,GAAAA,EAAmB3T,EAAQyT,SAEhCE,EAKW,QAAhB,MAAP3T,OAAO,EAAPA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,KACpB2H,EAAqB/T,EAAQwT,WAClCO,CACL,CAAC,OAAAhoB,CACF,CApCyC4F,EAAAunC,EAAA9qB,GAoCxC,IAAA9gB,EAAA4rC,EAAA3rC,UAuUA,OAvUAD,EAEO0mB,MAAA,WACP,QAAuB/gB,IAAnBjH,KAAKiqB,UAAT,CAIA,IAAMxI,EAAazhB,KAAKiqB,UAExBjqB,KAAKivB,kBAAoB,EACzBjvB,KAAKiqB,eAAYhjB,EAGE,YAAfjH,KAAKooB,OACRpoB,KAAKygB,aAGNzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QAZrD,CAaD,EAAC/mB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKmvB,WAAY,EACjBnvB,KAAKyI,UAAUzI,KAAKynB,QAAQG,YAEL3gB,IAAnBjH,KAAKiqB,WAAsD,IAA3BjqB,KAAKivB,kBAAzC,CAIA,IAIIwC,ECxILppB,EACA8kC,EACAC,EAOMlS,ED2HChJ,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GAId,GAA+B,IAA3B5K,KAAKivB,kBAAyB,CAGjC,IAAMnK,EAAU,EAAI1lB,KAAKC,IAAI,GAAIW,KAAKqB,oBAAsB,GACtDgxB,EAASjzB,KAAKkzB,IAAI,KAAUxN,GAElC2M,EAAqB,CACpBS,EAA0B,GAC1B,CAACzwB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,IAAM4vB,GACxBH,EAA0B,GAE5B,MAAW,GAA2B,IAA3BlyB,KAAKivB,kBAAyB,CACxC,IAAMoe,EAAkBnb,EAA0B,GAC5CtG,EAAmBsG,EAA0B,GAC7CwC,EAAWP,GAChBkZ,EACAzhB,EACA5rB,KAAKqB,oBACLrB,KAAKoI,QACLpI,KAAKwI,WAGAmmB,EAAI7K,GAAsBupB,EAAgB,GAAIA,EAAgB,IAC9Dze,EAAI9K,GAAsB4Q,EAAS,GAAIA,EAAS,IAChDqY,EAAIjpB,GAAsB8H,EAAiB,GAAIA,EAAiB,IAChE0hB,EAAIxpB,GAAsBriB,EAAMe,IAAKf,EAAMgB,KAK3C8qC,EAFchuC,EAAkB+tC,EAAG3e,GACrBpvB,EAAkB+tC,EAAGP,GAKnCE,EAAgBH,GAAuBne,EAAGC,EAAG0e,GAC7CvZ,EAAQwZ,EACX,GAAKN,EACLH,GAAuBne,EAAGC,EAAG0e,GAAK,GAI/BE,EAAajuC,EAAkBqvB,EAAG0e,GAClCG,EAAWruC,KAAKgkB,IAAIG,EAAiBwQ,IAAUyZ,EAY/CE,EAT6B1gB,GAAmB2B,EAAGoe,IAMlC,WCrLnB7R,IAPNkS,EDyLwCE,GCtLR3tC,GAJhCwtC,ED0LqCJ,GCtLSptC,KAL9C0I,ED2LkCsmB,GCrLuBjvB,EAAIytC,EAAUztC,IADnB0tC,EAAQ1tC,EAAIytC,EAAUztC,IACjD2I,EAAM1I,EAAIwtC,EAAUxtC,IAO7B,MAGR,OACGu7B,GAJK,MAKR,QAGA,SDyK4B,GAAK,IAIjCyS,EAAoBjhB,GACzBiC,EACA8e,EACAC,GAEKE,EAAqBlhB,GAC1BqgB,EACAU,EACAC,GAIKG,EAAkB9pB,GACvB4pB,EAAkBhuC,EAClBguC,EAAkBjuC,GAEbouC,EAAmB/pB,GACxB6pB,EAAmBjuC,EACnBiuC,EAAmBluC,GAIpB+xB,EAAqB,CACpBS,EAA0B,GAC1BA,EAA0B,GAC1B,CAAC4b,EAAiBtrC,IAAKsrC,EAAiBrrC,KACxC,CAACorC,EAAgBrrC,IAAKqrC,EAAgBprC,KACtCyvB,EAA0B,GAE5B,CAEAT,GACCzxB,KAAKmyB,sBACJnyB,KAAKiqB,UACLwH,EACAlY,EAAYiI,YAnGd,CAqGD,EAAClgB,EAEO6wB,sBAAA,SACP1sB,EACAmF,EACA2W,GAEA,IAAMoO,EAAkB,CACvBhlB,KAAM,UACNC,YAAa,CAACA,IAGf,QAAI5K,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACND,SAAUilB,GAEX,CACCvnB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAAA,MASHvhB,KAAKkgB,MAAM2J,eAAe,CAAC,CAAEpkB,GAAAA,EAAIiF,SAAUilB,QAG5C,EAACruB,EAGD+C,QAAA,SAAQ5C,GAUP,GALIzB,KAAKivB,kBAAoB,IAAMjvB,KAAKmvB,WACvCnvB,KAAKwD,YAAY/B,GAElBzB,KAAKmvB,WAAY,EAEc,IAA3BnvB,KAAKivB,kBAAyB,CACjC,IAAAxG,EAAgBzoB,KAAKkgB,MAAMwI,OAAO,CACjC,CACChe,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKiqB,UAhBOxB,EAAA,GAiBZzoB,KAAKivB,oBAGLjvB,KAAKwgB,YACN,MAAO,GAA+B,IAA3BxgB,KAAKivB,mBAA2BjvB,KAAKiqB,UAAW,CAC1D,IAAMuI,EAAyBxyB,KAAKkgB,MAAMgI,gBACzCloB,KAAKiqB,WASN,GALoB8E,GACnB,CAACttB,EAAMe,IAAKf,EAAMgB,KAFQ+vB,EAAuB5nB,YAAY,GAAG,IAOhE,OAcD,IAXgB5K,KAAKmyB,sBACpBnyB,KAAKiqB,UACL,CACCuI,EAAuB5nB,YAAY,GAAG,GACtC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB+vB,EAAuB5nB,YAAY,GAAG,IAEvC2O,EAAYkW,QAIZ,OAGDzvB,KAAKivB,mBACN,MAAsC,IAA3BjvB,KAAKivB,mBAA2BjvB,KAAKiqB,WAC/CjqB,KAAKgoB,OAEP,EAAC1mB,EAGDiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDmD,UAAA,aAAcnD,EAGdwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGdinB,QAAA,WACC,IACKvoB,KAAKiqB,WACRjqB,KAAKkgB,MAAY,OAAC,CAAClgB,KAAKiqB,WAE1B,CAAE,MAAO9I,GAAO,CAChBnhB,KAAKiqB,eAAYhjB,EACjBjH,KAAKivB,kBAAoB,EACN,YAAfjvB,KAAKooB,OACRpoB,KAAKygB,YAEP,EAACnf,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,EvDpXN,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IuDyYR,OA9BI9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACN,YAA1BL,EAAQjB,SAASC,OACpBqI,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,IAIXuE,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,UAAC8G,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+a,GAAuBpb,EAAS3L,KAAKqB,oBAKxC,EAAC6rC,CAAA,CA3WwC9qB,CAAQzC,GECrCouB,gBAAoB,SAAA3rB,GAahC,SAAA2rB,EAAY/5B,GAA0DjU,IAAAA,GACrEA,EAAAqiB,EAAAvd,KAAMmP,KAAAA,IAASjU,MAbhBiM,KAAO,SAAQjM,EAEPkvB,kBAAoB,EAAClvB,EACrBkqB,eAASlqB,EAAAA,EACTynB,iBAASznB,EACTwtB,eAASxtB,EAAAA,EACTiuC,eAAS,EAAAjuC,EAGT0nB,aAAO,EAAA1nB,EACPovB,WAAY,EAKnB,IAAMxH,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAWR,GAPCjoB,EAAK0nB,QADFzT,GAAWA,EAAQyT,QACVrH,EAAA,GAAQuH,EAAmB3T,EAAQyT,SAEhCE,EAKW,QAAvB3T,MAAAA,OAAAA,EAAAA,EAASwT,WACZznB,EAAKynB,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/nB,EAAKynB,UACJxT,GAAWA,EAAQwT,UAASpH,KACpB2H,EAAqB/T,EAAQwT,WAClCO,CACL,CAE0C,OAA1ChoB,EAAKiuC,WAAmB,MAAPh6B,OAAO,EAAPA,EAASg6B,YAAa,GAAGjuC,CAC3C,CAxCgC4F,EAAAooC,EAAA3rB,GAwC/B,IAAA9gB,EAAAysC,EAAAxsC,UAmWA,OAnWAD,EAEO0mB,MAAA,WACP,QAAuB/gB,IAAnBjH,KAAKiqB,UAAT,CAIA,IAAMxI,EAAazhB,KAAKiqB,UAExBjqB,KAAKivB,kBAAoB,EACzBjvB,KAAKiqB,eAAYhjB,EACjBjH,KAAKutB,eAAYtmB,EAGE,YAAfjH,KAAKooB,OACRpoB,KAAKygB,aAGNzgB,KAAK+gB,SAASU,EAAY,CAAEzV,KAAMhM,KAAKgM,KAAMqc,OAAQ,QAbrD,CAcD,EAAC/mB,EAGDsmB,MAAA,WACC5nB,KAAKygB,aACLzgB,KAAKyI,UAAUzI,KAAKynB,QAAQG,MAC7B,EAACtmB,EAGDgnB,KAAA,WACCtoB,KAAKuoB,UACLvoB,KAAK0gB,aACL1gB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKmvB,WAAY,EACjBnvB,KAAKyI,UAAUzI,KAAKynB,QAAQG,YAEL3gB,IAAnBjH,KAAKiqB,WAAsD,IAA3BjqB,KAAKivB,kBAAzC,CAIA,IAIIwC,EAJES,EAA4BlyB,KAAKkgB,MAAMgI,gBAC5CloB,KAAKiqB,WACJrf,YAAY,GAId,GAA+B,IAA3B5K,KAAKivB,kBAAyB,CAGjC,IAAMnK,EAAU,EAAI1lB,KAAKC,IAAI,GAAIW,KAAKqB,oBAAsB,GACtDgxB,EAASjzB,KAAKkzB,IAAI,KAAUxN,GAElC2M,EAAqB,CACpBS,EAA0B,GAC1B,CAACzwB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,IAAM4vB,GACxBH,EAA0B,GAE5B,MAAW,GAA2B,IAA3BlyB,KAAKivB,kBAAyB,CACxC,IAAMzK,EAAS0N,EAA0B,GACnC+b,EAAc/b,EAA0B,GACxCgc,EAAc,CAACzsC,EAAMe,IAAKf,EAAMgB,KAGhC0rC,EAAoBrqB,GAAsBU,EAAO,GAAIA,EAAO,IAC5D4pB,EAAyBtqB,GAC9BmqB,EAAY,GACZA,EAAY,IAEPI,EAAyBvqB,GAC9BoqB,EAAY,GACZA,EAAY,IAKb,QAAuBjnC,IAAnBjH,KAAKutB,UAAyB,CACjC,IAAM+gB,WChLT9pB,EACA+pB,EACAC,GAWA,OARqBD,EAAY5uC,EAAI6kB,EAAO7kB,IACK6uC,EAAW9uC,EAAI8kB,EAAO9kB,IADrB6uC,EAAY7uC,EAAI8kB,EAAO9kB,IACpD8uC,EAAW7uC,EAAI6kB,EAAO7kB,IAO3B,CACjB,CDkKsB8uC,CACjBN,EACAC,EACAC,GAEDruC,KAAKutB,UAAY+gB,EAAY,YAAc,eAC5C,CAGA,IAwBII,EAxBEl/B,EAASjQ,EACd4uC,EACAC,GAIKO,EAAe3hB,GACpBmhB,EACAC,GAEKQ,EAAa5hB,GAClBmhB,EACAE,GAIK5f,EAAiBzuB,KAAKguC,UACtBpjC,EAA0B,CAAC4Z,GAG3BqqB,EAAkB5hB,GAAiB0hB,GACnCG,EAAgB7hB,GAAiB2hB,GAIhB,kBAAnB5uC,KAAKutB,WACRmhB,EAAeI,EAAgBD,GACZ,IAClBH,GAAgB,MAGjBA,EAAeG,EAAkBC,GACd,IAClBJ,GAAgB,KAIlB,IAAMK,GACgB,kBAAnB/uC,KAAKutB,UAAgC,GAAK,GAAKmhB,EACjDjgB,EAGD7jB,EAAYO,KAAK8iC,GAGjB,IAAK,IAAIjjC,EAAI,EAAGA,GAAKyjB,EAAgBzjB,IAAK,CACzC,IACMgkC,EAAatiB,GAClByhB,EACA3+B,EAHsBq/B,EAAkB7jC,EAAI+jC,GAM7CplB,EAAqB5F,GAAsBirB,EAAWrvC,EAAGqvC,EAAWtvC,GAAvD+C,EAAGknB,EAAHlnB,IAEP61B,EAAY,CACjBt5B,EAHU2qB,EAAHnnB,IAGaxC,KAAKqB,qBACzBrC,EAAeyD,EAAKzC,KAAKqB,sBAIzBi3B,EAAU,KAAO1tB,EAAYA,EAAYK,OAAS,GAAG,IACrDqtB,EAAU,KAAO1tB,EAAYA,EAAYK,OAAS,GAAG,IAErDL,EAAYO,KAAKmtB,EAEnB,CAGA1tB,EAAYO,KAAKqZ,GAEjBiN,EAAkB3lB,GAAAA,OAAOlB,EAC1B,CAEA6mB,GACCzxB,KAAKmyB,sBACJnyB,KAAKiqB,UACLwH,EACAlY,EAAYiI,YA7Hd,CA+HD,EAAClgB,EAEO6wB,sBAAA,SACP1sB,EACAmF,EACA2W,GAEA,IAAMoO,EAAkB,CACvBhlB,KAAM,UACNC,YAAa,CAACA,IAGf,QAAI5K,KAAK+f,WACM/f,KAAK+f,SAClB,CACCpV,KAAM,UACND,SAAUilB,GAEX,CACCvnB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChBnH,oBAAqBrB,KAAKqB,oBAC1BkgB,WAAAA,MASHvhB,KAAKkgB,MAAM2J,eAAe,CAAC,CAAEpkB,GAAAA,EAAIiF,SAAUilB,KAG5C,GAAA,EAACruB,EAGD+C,QAAA,SAAQ5C,GAUP,GALIzB,KAAKivB,kBAAoB,IAAMjvB,KAAKmvB,WACvCnvB,KAAKwD,YAAY/B,GAElBzB,KAAKmvB,WAAY,EAEc,IAA3BnvB,KAAKivB,kBAAyB,CACjC,IAAAxG,EAAgBzoB,KAAKkgB,MAAMwI,OAAO,CACjC,CACChe,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKiqB,UAhBOxB,EAgBZ,GACAzoB,KAAKivB,oBAGLjvB,KAAKwgB,YACN,SAAsC,IAA3BxgB,KAAKivB,mBAA2BjvB,KAAKiqB,UAAW,CAC1D,IAAMuI,EAAyBxyB,KAAKkgB,MAAMgI,gBACzCloB,KAAKiqB,WASN,GALoB8E,GACnB,CAACttB,EAAMe,IAAKf,EAAMgB,KAFQ+vB,EAAuB5nB,YAAY,GAAG,IAOhE,OAcD,IAXgB5K,KAAKmyB,sBACpBnyB,KAAKiqB,UACL,CACCuI,EAAuB5nB,YAAY,GAAG,GACtC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB+vB,EAAuB5nB,YAAY,GAAG,IAEvC2O,EAAYkW,QAIZ,OAGDzvB,KAAKivB,mBACN,MAAsC,IAA3BjvB,KAAKivB,mBAA2BjvB,KAAKiqB,WAC/CjqB,KAAKgoB,OAEP,EAAC1mB,EAGDiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKwnB,UAAUK,OAChC7nB,KAAKuoB,UACK9mB,EAAM6C,MAAQtE,KAAKwnB,UAAUM,QACvC9nB,KAAKgoB,OAEP,EAAC1mB,EAGDmD,UAAA,WAAc,EAAAnD,EAGdwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGdinB,QAAA,WACC,IACKvoB,KAAKiqB,WACRjqB,KAAKkgB,MAAK,OAAQ,CAAClgB,KAAKiqB,WAE1B,CAAE,MAAO9I,GAAO,CAChBnhB,KAAKiqB,eAAYhjB,EACjBjH,KAAKutB,eAAYtmB,EACjBjH,KAAKivB,kBAAoB,EACN,YAAfjvB,KAAKooB,OACRpoB,KAAKygB,YAEP,EAACnf,EAGDunB,aAAA,SAAald,GACZ,IAAMqH,EAAMoN,EAAA,CAAA,EzDrZN,CACN5S,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IyD0aR,OA9BI9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACN,YAA1BL,EAAQjB,SAASC,OACpBqI,EAAOxF,iBAAmBxN,KAAK8hB,wBAC9B9hB,KAAKgT,OAAOtG,UACZsG,EAAOxF,iBACP7B,GAGDqH,EAAO3F,oBAAsBrN,KAAK8hB,wBACjC9hB,KAAKgT,OAAO8V,aACZ9V,EAAO3F,oBACP1B,GAGDqH,EAAO1F,oBAAsBtN,KAAKiiB,uBACjCjiB,KAAKgT,OAAO+V,aACZ/V,EAAO1F,oBACP3B,GAGDqH,EAAOzF,mBAAqBvN,KAAKiiB,uBAChCjiB,KAAKgT,OAAOpG,YACZoG,EAAOzF,mBACP5B,GAGDqH,EAAOvE,OAAS,IAIXuE,CACR,EAAC1R,EAED0f,gBAAA,SAAgBrV,GACf,QAAAyW,EAAA7gB,UAAUyf,gBAAenc,KAAC8G,KAAAA,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+a,GAAuBpb,EAAS3L,KAAKqB,oBAKxC,EAAC0sC,CAAA,CA3Y+B,CAAQpuB,GEcnCsvB,gBAAS,WAmBd,SAAAA,EAAYj7B,GAKX,IAAAjU,EAvBOmvC,KAAAA,KAAAA,mBAGAC,WAAK,EAAAnvC,KACLovC,cACAC,EAAAA,KAAAA,UAAW,OACXC,YAAM,EAAAtvC,KACNuvC,qBAAe,EAAAvvC,KASfwvC,yBAQP,EAAAxvC,KAAKovC,SAAWp7B,EAAQy7B,QAExBzvC,KAAKmvC,MAAQ,IAAIzK,GAGjB,IAAMgL,EAAuB,IAAI5uC,IAG3B6uC,EAAW37B,EAAQ47B,MAAM7T,OAE5B,SAAC8T,EAASC,GACZ,GAAIJ,EAAqB9hC,IAAIkiC,EAAY9jC,MACxC,MAAM,IAAItG,MAAK,sBAAuBoqC,EAAY9jC,KAAoB,kBAIvE,OAFA0jC,EAAqBlrC,IAAIsrC,EAAY9jC,MACrC6jC,EAAQC,EAAY9jC,MAAQ8jC,EACrBD,CACR,EAAG,CAAE,GAGCE,EAAWxlC,OAAOC,KAAKmlC,GAG7B,GAAwB,IAApBI,EAAS9kC,OACZ,UAAUvF,MAAM,qBAIjBqqC,EAAS/sC,QAAQ,SAACgJ,GACjB,GAAI2jC,EAAS3jC,GAAMrB,OAASsU,EAAUyD,OAAtC,CAGA,GAAI3iB,EAAKyvC,oBACR,MAAM,IAAI9pC,MAAM,gDAEhB3F,EAAKyvC,oBAAsBxjC,CAJ5B,CAMD,GAEAhM,KAAKkvC,OAAM9uB,EAAA,CAAA,EAAQuvB,EAAU,CAAAK,OAAQhwC,KAAKmvC,QAC1CnvC,KAAKuvC,gBAAkB,CACtB7D,OAAQ,GACRlK,OAAQ,GACRH,SAAU,GACVvZ,OAAQ,GACRmoB,MAAO,IAERjwC,KAAKsvC,OAAS,IAAIzE,GAAwB,CACzCC,UAAS92B,EAAQ82B,QACjBxpB,WAAYtN,EAAQsN,WAAatN,EAAQsN,gBAAara,IAGvD,IAAMipC,EAAa,SAClB3e,GAKA,IAAM4e,EAAkC,GAElCp9B,EAAYhT,EAAKuvC,OAAOtD,UAAU5f,OAAO,SAACsC,GAC/C,OAAI6C,EAAInQ,SAASsN,EAAEjpB,MAClB0qC,EAAQhlC,KAAKujB,MAKf,GAEA,MAAO,CAAEyhB,QAAAA,EAASp9B,UAAAA,EACnB,EAEMgO,EAAW,SAACU,EAAuBC,GACnC3hB,EAAKsvC,UAIVtvC,EAAKwvC,gBAAgBznB,OAAO9kB,QAAQ,SAACC,GACpCA,EAASwe,EAAYC,EACtB,EACD,EAEMd,EAA+B,SAAC2Q,EAAK9vB,GAC1C,GAAK1B,EAAKsvC,SAAV,CAIAtvC,EAAKwvC,gBAAgB7D,OAAO1oC,QAAQ,SAACC,GACpCA,EAASsuB,EAAK9vB,EACf,GAEA,IAAA2uC,EAA+BF,EAAW3e,GAAlC4e,EAAOC,EAAPD,QAASp9B,EAASq9B,EAATr9B,UAEH,WAAVtR,EACH1B,EAAKqvC,SAAS5lC,OACb,CACCgC,QAAS2kC,EACTtmC,WAAY,GACZkJ,UAAAA,EACA9I,QAAS,IAEVlK,EAAKswC,iBAEc,WAAV5uC,EACV1B,EAAKqvC,SAAS5lC,OACb,CACCgC,QAAS,GACT3B,WAAY,GACZkJ,UAAAA,EACA9I,QAASkmC,GAEVpwC,EAAKswC,iBAEc,WAAV5uC,EACV1B,EAAKqvC,SAAS5lC,OACb,CAAEgC,QAAS,GAAI3B,WAAY0nB,EAAKxe,UAAAA,EAAW9I,QAAS,IACpDlK,EAAKswC,iBAEc,YAAV5uC,GACV1B,EAAKqvC,SAAS5lC,OACb,CAAEgC,QAAS,GAAI3B,WAAY,GAAIkJ,UAAAA,EAAW9I,QAAS,IACnDlK,EAAKswC,gBApCP,CAuCD,EAEMxvB,EAAW,SAACe,GACjB,GAAK7hB,EAAKsvC,SAAV,CAIAtvC,EAAKwvC,gBAAgB/N,OAAOx+B,QAAQ,SAACC,GACpCA,EAAS2e,EACV,GAEA,IAAA0uB,EAA+BJ,EAAW,CAACtuB,IAE3C7hB,EAAKqvC,SAAS5lC,OACb,CAAEgC,QAAS,GAAI3B,WAAY,GAAIkJ,UAHNu9B,EAATv9B,UAG0B9I,QAH5BqmC,EAAPH,SAIPpwC,EAAKswC,gBAVN,CAYD,EAEMvvB,EAAa,SAACa,GACnB,GAAK5hB,EAAKsvC,SAAV,CAIAtvC,EAAKwvC,gBAAgBlO,SAASr+B,QAAQ,SAACC,GACtCA,GACD,GAEA,IAAAstC,EAA+BL,EAAW,CAACvuB,IAAnCwuB,EAAOI,EAAPJ,QAKJA,GACHpwC,EAAKqvC,SAAS5lC,OACb,CACCgC,QAAS,GACT3B,WAAY,GACZkJ,UAVuBw9B,EAATx9B,UAWd9I,QAASkmC,GAEVpwC,EAAKswC,gBAnBP,CAsBD,EAGA9lC,OAAOC,KAAKxK,KAAKkvC,QAAQlsC,QAAQ,SAACwtC,GACjCzwC,EAAKmvC,OAAOsB,GAAQpwC,SAAS,CAC5B4L,KAAMwkC,EACNtwB,MAAOngB,EAAKuvC,OACZ7mC,UAAW1I,EAAKqvC,SAAS3mC,UAAUxE,KAAKlE,EAAKqvC,UAC7ChnC,QAASrI,EAAKqvC,SAAShnC,QAAQnE,KAAKlE,EAAKqvC,UACzC5mC,UAAWzI,EAAKqvC,SAAS5mC,UAAUvE,KAAKlE,EAAKqvC,UAC7ChmC,qBAAsBrJ,EAAKqvC,SAAShmC,qBAAqBnF,KACxDlE,EAAKqvC,UAENxuB,SAAUA,EACVC,SAAUA,EACVC,WAAYA,EACZC,SAAUA,EACV1f,oBAAqBtB,EAAKqvC,SAASlsC,0BAErC,EACD,CAAC,IAAA5B,EAAA2tC,EAAA1tC,UAqMA,OArMAD,EAEOmvC,aAAA,WACP,IAAKzwC,KAAKqvC,SACT,UAAU3pC,MAAM,4BAElB,EAACpE,EAEO+uC,cAAA,WAAapqC,IAAAA,EACpBjG,KAAM0wC,EAEF,CAAE,EAkBN,OAhBAnmC,OAAOC,KAAKxK,KAAKkvC,QAAQlsC,QAAQ,SAACgJ,GACjC0kC,EAAW1kC,GAAQ,SAACL,GAEnB,OACC1F,EAAKupC,qBACL7jC,EAAQlB,WAAWyU,GAEZjZ,EAAKipC,OAAOjpC,EAAKupC,qBAAqB3mB,aAAa5kB,KACzDgC,EAAKipC,OAAOjpC,EAAKupC,qBADXvpC,CAEL0F,GAII1F,EAAKipC,OAAOljC,GAAM6c,aAAa5kB,KAAKgC,EAAKipC,OAAOljC,GAAhD/F,CAAuD0F,EAC/D,CACD,GACO+kC,CACR,EAACpvC,EAEOqvC,mBAAA,SAAA7wC,EAQPkU,GANC,IAAAxR,EAAG1C,EAAH0C,IACAC,EAAG3C,EAAH2C,IAOKud,EACLhM,QAAuC/M,IAA5B+M,EAAQgM,gBAChBhM,EAAQgM,gBACR,GAEE4wB,GACL58B,QAA4C/M,IAAjC+M,EAAQ48B,sBAChB58B,EAAQ48B,qBAGNpoC,EAAYxI,KAAKovC,SAAS5mC,UAAUvE,KAAKjE,KAAKovC,UAC9ChnC,EAAUpI,KAAKovC,SAAShnC,QAAQnE,KAAKjE,KAAKovC,UAE1CyB,EAAazoC,EAAQ5F,EAAKC,GAE1B4pB,EAAOjB,GAAoB,CAChC5iB,UAAAA,EACAH,MAAOwoC,EACP7wB,gBAAAA,IAOD,OAJiBhgB,KAAKsvC,OAAOhjB,OAAOD,GAIpBD,OAAO,SAACzgB,GACvB,GACCilC,IACCjlC,EAAQlB,WAAWyU,IACnBvT,EAAQlB,WAA4C,gBAErD,SAGD,GAA8B,UAA1BkB,EAAQjB,SAASC,KAAkB,CACtC,IAAMmmC,EAAmBnlC,EAAQjB,SAASE,YACpCmmC,EAAU3oC,EAAQ0oC,EAAiB,GAAIA,EAAiB,IAE9D,OADiBvxC,EAAkBsxC,EAAYE,GAC7B/wB,CACnB,CAAO,GAA8B,eAA1BrU,EAAQjB,SAASC,KAAuB,CAGlD,IAFA,IAAMC,EAA0Be,EAAQjB,SAASE,YAExCI,EAAI,EAAGA,EAAIJ,EAAYK,OAAS,EAAGD,IAAK,CAChD,IAAM6Z,EAAQja,EAAYI,GACpBstB,EAAY1tB,EAAYI,EAAI,GAOlC,GANuBisB,GACtB4Z,EACAzoC,EAAQyc,EAAM,GAAIA,EAAM,IACxBzc,EAAQkwB,EAAU,GAAIA,EAAU,KAGZtY,EACpB,OACD,CACD,CACA,QACD,CAMC,QAL4BwW,GAC3B,CAACh0B,EAAKC,GACNkJ,EAAQjB,SAASE,mBAGlB,CAIF,EACD,EAACtJ,EAEO0vC,cAAA,WAGP,GAFAhxC,KAAKywC,gBAEAzwC,KAAKwvC,oBACT,MAAM,IAAI9pC,MAAM,sCAcjB,OAXoB1F,KAAKixC,YAGLjxC,KAAKwvC,qBACxBxvC,KAAKkxC,QAAQlxC,KAAKwvC,qBAGAxvC,KAAKkvC,OACvBlvC,KAAKwvC,oBAIP,EAACluC,EAWD6vC,cAAA,SACCnlC,EACAgH,GAGA,GADAhT,KAAKywC,gBACAzwC,KAAKkvC,OAAOljC,GAChB,MAAU,IAAAtG,MAAM,kCAIhB1F,KAAKkvC,OAAOljC,GAAqCgH,OAASA,CAC5D,EAAC1R,EASD8vC,YAAA,WAEC,OAAWpxC,KAACsvC,OAAOtD,SACpB,EAAC1qC,EAQDoD,MAAA,WACC1E,KAAKywC,eACLzwC,KAAKovC,SAAS1qC,OACf,EAACpD,EA+BD2vC,QAAA,WAEC,OAAOjxC,KAAKmvC,MAAMnjC,IACnB,EAAC1K,EASD4vC,QAAA,SAAQllC,GAGP,GAFAhM,KAAKywC,gBAEDzwC,KAAKkvC,OAAOljC,GAcf,MAAM,IAAItG,MAAM,kCAThB1F,KAAKmvC,MAAM7mB,OAGXtoB,KAAKmvC,MAAQnvC,KAAKkvC,OAAOljC,GAGzBhM,KAAKmvC,MAAMvnB,OAKb,EAACtmB,EASD+vC,eAAA,SAAe9f,GACdvxB,KAAKywC,eACLzwC,KAAKsvC,OAAa,OAAC/d,EACpB,EAACjwB,EASDigC,cAAA,SAAc97B,GACOzF,KAAKgxC,gBACbzP,cAAc97B,EAC3B,EAACnE,EASDogC,gBAAA,SAAgBj8B,GACIzF,KAAKgxC,gBACbtP,gBAAgBj8B,EAC5B,EAACnE,EAUDgwC,aAAA,WACC,OAAOtxC,KAAKsvC,OAAO3hC,OACpB,EAACrM,EAQDiwC,WAAA,SAAW9rC,GACV,OAAWzF,KAACsvC,OAAO1hC,IAAInI,EACxB,EAACnE,EAWDkwC,YAAA,SAAY3lC,OAAgClC,EAAA3J,KAC3CA,KAAKywC,eAEmB,IAApB5kC,EAASZ,QAIbjL,KAAKsvC,OAAOlI,KAAKv7B,EAAU,SAACF,GAU3B,GATwBsC,QACvBtC,GACoB,iBAAZA,GACP,eAAgBA,GACc,iBAAvBA,EAAQlB,YACQ,OAAvBkB,EAAQlB,YACR,SAAUkB,EAAQlB,YAGC,CACpB,IAAMgnC,EACL9nC,EAAKulC,OACHvjC,EAA6ClB,WAAWuB,MAI3D,QAAKylC,GAKcA,EAAYzwB,gBAAgB/c,KAAKwtC,EAC7CpxB,CAAW1U,EACnB,CAGA,QACD,EACD,EAACrK,EAQDsmB,MAAA,WAAK,IAAAla,EAAA1N,KACJA,KAAKqvC,UAAW,EAChBrvC,KAAKovC,SAAShvC,SAAS,CACtBiG,QAAS,WACRqH,EAAK6hC,gBAAgBU,MAAMjtC,QAAQ,SAACC,GACnCA,GACD,EACD,EACAW,SAAU,WACT,OAAO8J,EAAKyhC,MAAM/mB,KACnB,EACA/jB,QAAS,SAAC5C,GACTiM,EAAKyhC,MAAM9qC,QAAQ5C,EACpB,EACA+B,YAAa,SAAC/B,GACbiM,EAAKyhC,MAAM3rC,YAAY/B,EACxB,EACAgD,UAAW,SAAChD,GACXiM,EAAKyhC,MAAM1qC,UAAUhD,EACtB,EACA8C,QAAS,SAAC9C,GACTiM,EAAKyhC,MAAM5qC,QAAQ9C,EACpB,EACAqC,YAAa,SAACrC,EAAOogB,GACpBnU,EAAKyhC,MAAMrrC,YAAYrC,EAAOogB,EAC/B,EACA3d,OAAQ,SAACzC,EAAOogB,GACfnU,EAAKyhC,MAAMjrC,OAAOzC,EAAOogB,EAC1B,EACAzd,UAAW,SAAC3C,EAAOogB,GAClBnU,EAAKyhC,MAAM/qC,UAAU3C,EAAOogB,EAC7B,EACAhU,QAAS,WAGRH,EAAKyhC,MAAM5mB,UAGX7a,EAAK4hC,OAAO5qC,OACb,GAEF,EAACpD,EASDowC,oBAAA,SACCC,EACA39B,GAIA,OAAWhU,KAAC2wC,mBACX,CACCnuC,IAJmBmvC,EAAbnvC,IAKNC,IALmBkvC,EAARlvC,KAOZuR,EAEF,EAAC1S,EASDswC,0BAAA,SACCnwC,EACAuS,GAEA,IAIM29B,EAJqB3xC,KAAKovC,SAAS7sC,mBAAmB0B,KAC3DjE,KAAKovC,SAGS7sC,CAAmBd,GAIlC,OAAe,OAAXkwC,EACI,GAGD3xC,KAAK2wC,mBAAmBgB,EAAQ39B,EACxC,EAAC1S,EAQDgnB,KAAA,WACCtoB,KAAKqvC,UAAW,EAChBrvC,KAAKovC,SAASjvC,YACf,EAACmB,EAUD+b,GAAA,SACC5b,EACAvB,GAEA,IAAM2xC,EAAY7xC,KAAKuvC,gBACtB9tC,GAEIowC,EAAUzwB,SAASlhB,IACvB2xC,EAAU1mC,KAAKjL,EAEjB,EAACoB,EAUDwwC,IAAA,SACCrwC,EACAvB,GAEA,IAAM2xC,EAAY7xC,KAAKuvC,gBACtB9tC,GAEGowC,EAAUzwB,SAASlhB,IACtB2xC,EAAUpc,OAAOoc,EAAUhK,QAAQ3nC,GAAW,EAEhD,EAAC4N,EAAAmhC,IAAA3qC,IAAA,UAAAyJ,IAhTD,WACC,OAAO/N,KAAKqvC,QACb,EAACntB,IAOD,SAAYvG,GACX,MAAM,IAAIjW,MAAM,uBACjB,KAACupC,CAAA,CA1Za,GAqsBT8C,GAAkB,CACvBpyB,sBAAAA,EACArf,qBAAAA"}