leaflet-tual 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,257 @@
1
1
  # leaflet-tual
2
+
3
+ > Framework-agnostic interactive canvas and annotation toolkit for Leaflet maps, with optional React bindings.
4
+
5
+ Draw arrows, place geometric shapes, sketch freehand paths, measure geodesic distances, drop interactive sticky notes, and render text annotations that stay geographically locked to Leaflet map coordinates across zoom levels and pan movements.
6
+
7
+ ---
8
+
9
+ ## Package Layout & Subpath Exports
10
+
11
+ | Import | Surface | React required? |
12
+ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
13
+ | `leaflet-tual` / `leaflet-tual/core` | Framework-agnostic core (`createLeafletTual`, `createLeafletTualController`, `paintLeafletTual`, geo math, 2D renderers) | No |
14
+ | `leaflet-tual/react` | React bindings (`<LeafletTual>`, `<TualToolbar>`, `useLeafletTual`, `useLeafletSync`) | Yes (optional peer) |
15
+
16
+ ---
17
+
18
+ ## Features
19
+
20
+ - **Geographically Synchronized**: All items store latitude/longitude coordinates (`GeoPoint`). Projections adapt automatically during zoom, pan, and window resize.
21
+ - **Rich Vector Arrows**: Linear, curved (quadratic Bezier), bi-directional, elbow, and s-curve arrow styles with customizable arrowheads, dashed patterns, and text labels.
22
+ - **Real-World Distance Ruler**: Dedicated measurement line tool that calculates and displays real-world geodesic distances (`m`, `km`, `ft`, `mi`) live with perpendicular end-caps and draggable endpoints.
23
+ - **Geometric Shapes**: Star, square, circle, actor/person, triangle, diamond, hexagon, and map marker with stroke, fill, and aspect ratio locking.
24
+ - **Freehand Sketching**: Smooth free-drawing with customizable stroke widths and dashed lines.
25
+ - **Sticky Notes & Text Overlays**: Draggable HTML sticky notes with color palettes and minimizable views, plus floating text annotations.
26
+ - **Read-Only Mode**: Display annotations for review or inspection while keeping Leaflet map pan, zoom, and click interactions completely unobstructed.
27
+ - **Undo / Redo History**: Built-in undo/redo stack in uncontrolled mode, or fully controlled via `items` and `onItemsChange`.
28
+ - **Customizable Toolbar**: Floating on-map toolbar with multiple positions or completely decoupled external toolbar.
29
+
30
+ ---
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install leaflet-tual leaflet react-leaflet
36
+ ```
37
+
38
+ Ensure Leaflet CSS is imported in your application:
39
+
40
+ ```ts
41
+ import 'leaflet/dist/leaflet.css'
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Quick Start
47
+
48
+ ### Vanilla JS / Framework-Agnostic (`leaflet-tual`)
49
+
50
+ ```ts
51
+ import L from 'leaflet'
52
+ import { createLeafletTual } from 'leaflet-tual'
53
+ import 'leaflet/dist/leaflet.css'
54
+
55
+ const map = L.map('map').setView([41.0082, 28.9784], 13)
56
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map)
57
+
58
+ const canvas = createLeafletTual(map, {
59
+ initialItems: [],
60
+ onChange: (items) => console.log('Items updated:', items),
61
+ })
62
+
63
+ // Programmatic control
64
+ canvas.controller.setTool('arrow-curved')
65
+ canvas.controller.setActiveColor('#2563eb')
66
+ ```
67
+
68
+ ### React Basic Usage (`leaflet-tual/react`)
69
+
70
+ ```tsx
71
+ import { MapContainer, TileLayer } from 'react-leaflet'
72
+ import { LeafletTual } from 'leaflet-tual/react'
73
+ import 'leaflet/dist/leaflet.css'
74
+
75
+ export function Map() {
76
+ return (
77
+ <MapContainer center={[41.0082, 28.9784]} zoom={13} style={{ height: '100vh', width: '100%' }}>
78
+ <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
79
+ <LeafletTual toolbarPosition="top-center" />
80
+ </MapContainer>
81
+ )
82
+ }
83
+ ```
84
+
85
+ ### Controlled Controller
86
+
87
+ ```tsx
88
+ import { MapContainer, TileLayer } from 'react-leaflet'
89
+ import { LeafletTual, useLeafletTual } from 'leaflet-tual/react'
90
+ import 'leaflet/dist/leaflet.css'
91
+
92
+ export function MapWithController() {
93
+ const controller = useLeafletTual({
94
+ initialItems: [
95
+ {
96
+ id: 'arrow-1',
97
+ type: 'arrow',
98
+ arrowStyle: 'curved',
99
+ start: { lat: 41.0082, lng: 28.9784 },
100
+ end: { lat: 41.0256, lng: 28.9742 },
101
+ color: '#2563eb',
102
+ strokeWidth: 3,
103
+ label: 'Navigation Route',
104
+ createdAt: Date.now(),
105
+ },
106
+ ],
107
+ })
108
+
109
+ return (
110
+ <MapContainer center={[41.01, 28.97]} zoom={13} style={{ height: '100vh', width: '100%' }}>
111
+ <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
112
+ <LeafletTual controller={controller} toolbarPosition="top-center" />
113
+ </MapContainer>
114
+ )
115
+ }
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Read-Only Mode
121
+
122
+ To present annotations in a view-only state without editing capabilities:
123
+
124
+ ```tsx
125
+ <LeafletTual readOnly />
126
+ ```
127
+
128
+ Or toggle it dynamically via the controller:
129
+
130
+ ```tsx
131
+ const controller = useLeafletTual({ readOnly: true })
132
+
133
+ // Later toggle programmatically:
134
+ controller.setReadOnly(false)
135
+ ```
136
+
137
+ ### Read-Only Behavior
138
+
139
+ When `readOnly` is enabled:
140
+ - **Map Interaction**: The drawing surface layer is removed from the DOM and drawing pointer listeners are disabled, ensuring Leaflet map panning, zooming, and clicking are 100% unobstructed.
141
+ - **Toolbar**: Hidden by default (`showToolbar` defaults to `false` when `readOnly` is active, unless explicitly overridden with `showToolbar={true}`). If forced visible, creation tools and mutation actions are disabled.
142
+ - **Selection & Handles**: Bounding box selection handles, control points, and rotation/resize grips are hidden.
143
+ - **Sticky Notes**: Title and body text inputs are set to `readOnly`, dragging is disabled, and delete buttons are removed. Note minimize/expand toggles remain usable for viewing convenience.
144
+ - **Text Overlays**: Double-click editing is disabled, dragging is disabled, and text formatting controls are hidden.
145
+ - **Mutations Guarded**: Controller mutation methods (`addItem`, `updateItem`, `removeItem`, `deleteSelected`, `clearAll`, `undo`, `redo`, `importJSON`, `setActiveTool`) are safeguarded against state changes.
146
+ - **CSS Styling**: The root overlay container receives the `rlc-readonly` class and `data-readonly="true"` attribute for custom styling.
147
+
148
+ ---
149
+
150
+ ## Sticky Note 3-State Lifecycle
151
+
152
+ Sticky notes support three presentation states across panning and zooming:
153
+ 1. **Expanded (`'expanded'` / `minimized: false`)**: Full card showing header, title input, and editable textarea body.
154
+ 2. **Collapsed (`'collapsed'` / `minimized: true`)**: Header pill bar (110px–220px) showing title input and action buttons without the body.
155
+ 3. **Compact (`'compact'` / `minimized: 'compact'`)**: Ultra-compact pill shape (34px–140px, `borderRadius: 9999px`) featuring a note icon, truncated title, and expand trigger. Ideal for high-density maps and low-zoom overviews.
156
+
157
+ Use the header's **Compact** and **Expand/Collapse** buttons to cycle states, or set `collapseState: 'compact'` on any `NoteItem`. When `autoMinimizeNotesZoom` is enabled, notes automatically adapt between all three states based on map zoom levels.
158
+
159
+ ---
160
+
161
+ ## API Reference
162
+
163
+ ### `<LeafletTual>` Props
164
+
165
+ | Prop | Type | Default | Description |
166
+ | :--- | :--- | :--- | :--- |
167
+ | `readOnly` | `boolean` | `false` | Enables read-only mode (disables drawing, editing, and selection). |
168
+ | `controller` | `LeafletTualController` | `undefined` | Optional external controller from `useLeafletTual()`. |
169
+ | `map` | `L.Map` | `undefined` | Leaflet map instance (auto-inferred via `useMap()` when inside `<MapContainer>`). |
170
+ | `initialItems` | `TualItem[]` | `[]` | Initial annotations (when not providing an external controller). |
171
+ | `showToolbar` | `boolean` | `!readOnly` | Whether to display the toolbar. Defaults to `false` when `readOnly` is true. |
172
+ | `toolbarPosition` | `ToolbarPosition \| 'none'` | `'top-center'` | Toolbar position (`'top'`, `'bottom'`, `'left'`, `'right'`, `'top-center'`, `'bottom-center'`, `'left-center'`, `'right-center'`, `'none'`). |
173
+ | `toolbarOrientation` | `'horizontal' \| 'vertical'` | Inferred from position | Toolbar orientation. Inferred as `'vertical'` for left/right positions and `'horizontal'` for top/bottom positions. |
174
+ | `collapsible` | `boolean` | `true` | Whether the toolbar can be collapsed to a compact trigger button. |
175
+ | `defaultCollapsed` | `boolean` | `false` | Initial collapsed state when uncontrolled. |
176
+ | `collapsed` | `boolean` | `undefined` | Controlled collapsed state. |
177
+ | `onCollapsedChange` | `(collapsed: boolean) => void` | `undefined` | Callback fired when the toolbar collapses or expands. |
178
+ | `showCollapseButton` | `boolean` | `true` | Whether to display the collapse toggle button. |
179
+ | `labels` | `TualLabels` | `{}` | Custom labels and tooltips (supports `collapseToolbar`, `expandToolbar`, etc.). |
180
+ | `icons` | `TualIcons` | `{}` | Custom icons for toolbar buttons (supports `collapseToolbar`, `expandToolbar`, etc.). |
181
+ | `classNames` | `LeafletTualClassNames` | `{}` | Custom CSS classes for container, canvas, toolbar, notes, and text. State-aware slots include `toolButtonActive` (active tool), `swatchButtonActive` (selected color), and `actionButtonDisabled` (disabled undo/redo history buttons). |
182
+ | `styles` | `LeafletTualStyles` | `{}` | Inline CSS styles for container, canvas, toolbar, notes, and text. State-aware slots mirror `classNames` (e.g. `actionButtonDisabled` overrides only disabled undo/redo buttons). Disabled action buttons are automatically dimmed with `opacity: 0.45` and a `not-allowed` cursor. |
183
+ | `arrowTheme` / `annotationTheme` | `TualAnnotationTheme` | `{}` | Custom theme for 2D canvas shapes, arrows, and label pills (supports `labelMinShapeSize`, `labelMaxTextWidth`, `fitLabelsToShape`). |
184
+ | `clampOverlaysToViewport` | `boolean` | `true` | Keeps sticky note and text overlays inside map viewport boundaries so they never bleed off container edges on zoom or pan. |
185
+ | `autoMinimizeNotesZoom` | `number` | `undefined` | Optional map zoom level threshold below which sticky notes automatically collapse into compact pill badges at low zoom. |
186
+ | `strokeColors` | `string[]` | Built-in palette | Color swatches shown in the contextual settings bar. |
187
+ | `strokeWidthOptions` | `number[]` | `[1, 2, 3, 4, 5, 6, 8, 10, 12]` | Pixel widths listed in the **Width** select box for arrows, shapes, and free draw. Style it via the `toolbarSelect` slot in `classNames` / `styles`. |
188
+ | `fontSizeOptions` | `readonly number[]` | `[10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48]` | Font sizes (in pixels) listed in the **Size** select box for text overlays. Style it via the `toolbarSelect` slot in `classNames` / `styles`. |
189
+ | `customToolbarItems` | `CustomToolbarItem[]` | `[]` | Custom buttons or items injected into the toolbar. |
190
+ | `onChange` / `onItemsChange` | `(items: TualItem[]) => void` | `undefined` | Callback fired immediately on every mutation, stroke point, or attribute update. |
191
+ | `onChangeComplete` / `onItemsChangeComplete` | `(items: TualItem[], targetItem?: TualItem \| null) => void` | `undefined` | Callback fired when editing finishes (e.g. user draws and clicks outside activating Select (V) mode, deselects, presses Escape, or blurs note/text editing). |
192
+ | `onEditEnd` / `onEditComplete` | `(items: TualItem[], targetItem?: TualItem \| null) => void` | `undefined` | Aliases for `onChangeComplete`. |
193
+ | `onItemSelect` | `(item: TualItem \| null) => void` | `undefined` | Callback fired when an item is selected or deselected. |
194
+ | `onItemCreate` | `(item: TualItem) => void` | `undefined` | Callback fired when a new item is created. |
195
+ | `onItemChange` | `(item: TualItem) => void` | `undefined` | Callback fired when an existing item is updated. |
196
+ | `onItemChangeComplete` | `(item: TualItem) => void` | `undefined` | Callback fired when an item completes editing. |
197
+ | `onItemDelete` | `(id: string) => void` | `undefined` | Callback fired when an item is deleted. |
198
+
199
+ ### `useLeafletTual(options)` Options
200
+
201
+ | Option | Type | Default | Description |
202
+ | :--- | :--- | :--- | :--- |
203
+ | `readOnly` | `boolean` | `false` | Sets initial read-only state. |
204
+ | `initialItems` | `TualItem[]` | `[]` | Initial annotations array (uncontrolled mode). |
205
+ | `items` | `TualItem[]` | `undefined` | Controlled annotations array. |
206
+ | `maxHistory` | `number` | `50` | Maximum undo/redo stack depth in uncontrolled mode. |
207
+ | `onChange` / `onItemsChange` | `(items: TualItem[]) => void` | `undefined` | Immediate change callback fired on every modification. |
208
+ | `onChangeComplete` / `onItemsChangeComplete` | `(items: TualItem[], targetItem?: TualItem \| null) => void` | `undefined` | Completion callback fired when an edit finishes (click outside activating Select (V) mode, deselect, blur, Escape). |
209
+ | `onEditEnd` / `onEditComplete` | `(items: TualItem[], targetItem?: TualItem \| null) => void` | `undefined` | Aliases for `onChangeComplete`. |
210
+ | `onItemSelect` | `(item: TualItem \| null) => void` | `undefined` | Callback fired on selection change. |
211
+ | `onItemCreate` | `(item: TualItem) => void` | `undefined` | Callback fired when a new item is created. |
212
+ | `onItemChange` | `(item: TualItem) => void` | `undefined` | Callback fired when an existing item is updated. |
213
+ | `onItemChangeComplete` | `(item: TualItem) => void` | `undefined` | Callback fired when an item finishes editing. |
214
+ | `onItemDelete` | `(id: string) => void` | `undefined` | Callback fired when an item is deleted. |
215
+ | `initialTool` | `TualTool` | `'select'` | Active tool on mount. |
216
+ | `defaultColor` | `string` | `'#2563eb'` | Default stroke color. |
217
+ | `defaultStrokeWidth` | `number` | `3` | Default stroke width in pixels. |
218
+ | `defaultNoteColor` | `string` | `'#fef08a'` | Default sticky note background color. |
219
+ | `defaultFontSize` | `number` | `16` | Default text overlay font size. |
220
+ | `defaultShape` | `ShapeKind` | `'square'` | Default shape type. |
221
+
222
+ ### `LeafletTualController` Methods & State
223
+
224
+ | Property / Method | Type | Description |
225
+ | :--- | :--- | :--- |
226
+ | `readOnly` | `boolean` | Current read-only mode state. |
227
+ | `setReadOnly(readOnly)` | `(readOnly: boolean) => void` | Toggles read-only mode dynamically. |
228
+ | `items` | `TualItem[]` | All current canvas items. |
229
+ | `selectedItem` | `TualItem \| null` | Currently selected canvas item. |
230
+ | `selectedId` | `string \| null` | ID of the currently selected canvas item. |
231
+ | `isEditingLabel` | `boolean` | Whether label edit mode is active for the selected shape/item. |
232
+ | `setEditingLabel(editing)` | `(editing: boolean) => void` | Toggles label edit mode for the focused shape/item. |
233
+ | `activeTool` | `TualTool` | Currently active tool. |
234
+ | `activeColor` | `string` | Currently active color. |
235
+ | `strokeWidth` | `number` | Currently active stroke width. |
236
+ | `dashed` | `boolean` | Whether dashed line is active. |
237
+ | `shapeFilled` | `boolean` | Whether shape fill is active. |
238
+ | `canUndo` | `boolean` | Whether undo is possible (`false` in read-only mode). |
239
+ | `canRedo` | `boolean` | Whether redo is possible (`false` in read-only mode). |
240
+ | `setTool(tool)` | `(tool: TualTool) => void` | Change active tool. |
241
+ | `selectItem(id)` | `(id: string \| null) => void` | Select an item by ID or clear selection with `null`. |
242
+ | `addItem(item)` | `(item: TualItem) => void` | Add a new annotation. |
243
+ | `updateItem(id, updater)` | `(id: string, updater: Partial<TualItem> \| fn) => void` | Update an existing item. |
244
+ | `removeItem(id)` | `(id: string) => void` | Remove an item by ID. |
245
+ | `deleteSelected()` | `() => void` | Delete the currently selected item. |
246
+ | `clearAll()` | `() => void` | Remove all canvas items. |
247
+ | `undo()` | `() => void` | Revert to previous history snapshot. Snapshots are recorded when an edit completes (`onChangeComplete`), so an interaction (draw, drag, style tweak) collapses into one step. |
248
+ | `redo()` | `() => void` | Re-apply reverted history snapshot. |
249
+ | `notifyChangeComplete(targetItem?)` | `(targetItem?: TualItem \| null) => void` | Programmatically triggers `onChangeComplete` / `onItemsChangeComplete` with the current finalized items. |
250
+ | `exportJSON()` | `() => string` | Export canvas items to JSON string. |
251
+ | `importJSON(json)` | `(json: string) => void` | Import canvas items from JSON string. |
252
+
253
+ ---
254
+
255
+ ## License
256
+
257
+ MIT © Yusuf Arslan
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var Le=Object.defineProperty;var ct=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var ft=Object.prototype.hasOwnProperty;var ht=(e,t)=>{for(var n in t)Le(e,n,{get:t[n],enumerable:!0})},mt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ut(t))!ft.call(e,o)&&o!==n&&Le(e,o,{get:()=>t[o],enumerable:!(r=ct(t,o))||r.enumerable});return e};var yt=e=>mt(Le({},"__esModule",{value:!0}),e);var Ct={};ht(Ct,{DEFAULT_ANNOTATION_THEME:()=>bt,DEFAULT_FONT_SIZE:()=>Ee,DEFAULT_FONT_SIZE_OPTIONS:()=>at,DEFAULT_NOTE_BG:()=>Ae,DEFAULT_NOTE_TEXT:()=>wt,DEFAULT_STROKE_COLOR:()=>De,DEFAULT_STROKE_WIDTH:()=>Ce,DEFAULT_STROKE_WIDTH_OPTIONS:()=>it,FONT_SIZE_OPTIONS:()=>Tt,NOTE_COLOR_THEMES:()=>U,STROKE_COLORS:()=>gt,STROKE_WIDTH_OPTIONS:()=>St,TOOL_TO_ARROW_STYLE:()=>Ie,VERSION:()=>Dt,bindBlockMapDblClick:()=>nt,bindLeafletSync:()=>tt,buildArrowItem:()=>be,buildRulerItem:()=>dt,calculateGeodesicDistance:()=>fe,calculateLineDistance:()=>xt,calculateZoomFontSize:()=>Pt,clampNotePosition:()=>Mt,clampTextPosition:()=>Lt,computeDefaultControlGeoPoint:()=>ie,constrainAngleTo45Degrees:()=>F,constrainToAspectRatio:()=>re,createDraftNote:()=>Ye,createDraftText:()=>je,createId:()=>K,createLeafletTual:()=>It,createLeafletTualController:()=>ot,distanceToQuadraticBezier:()=>Re,distanceToSegment:()=>Y,drawArrowHead:()=>he,drawTualHandle:()=>j,drawTualLabelPill:()=>Z,formatRealWorldDistance:()=>Oe,geoToScreen:()=>O,getMapDimensions:()=>le,getQuadraticBezierPoint:()=>ue,getQuadraticEndAngle:()=>ae,hitTestArrow:()=>Fe,hitTestArrowHandle:()=>We,hitTestFreeDraw:()=>He,hitTestRuler:()=>Ne,hitTestRulerHandle:()=>Ge,hitTestShape:()=>Be,hitTestShapeHandle:()=>_e,paintLeafletTual:()=>et,projectArrow:()=>V,projectFreeDraw:()=>se,projectRuler:()=>ee,projectShape:()=>Q,renderArrowOnCanvas:()=>ye,renderFreeDrawOnCanvas:()=>pe,renderRulerOnCanvas:()=>we,renderShapeOnCanvas:()=>Se,resolveNoteTheme:()=>vt,screenToGeo:()=>L,startArrowBodyDrag:()=>$e,startArrowDrag:()=>ze,startArrowHandleDrag:()=>Ue,startFreeDrawBodyDrag:()=>Ze,startFreeDrawDrag:()=>Te,startRulerBodyDrag:()=>Qe,startRulerDrag:()=>Ke,startRulerHandleDrag:()=>Ve,startShapeBodyDrag:()=>qe,startShapeDrag:()=>Xe,startShapeHandleDrag:()=>Je,traceArrowPath:()=>me,tracePolygonShape:()=>ge,truncateTualText:()=>ke});module.exports=yt(Ct);var rt={name:"leaflet-tual",version:"1.0.0",description:"Framework-agnostic interactive canvas and annotation toolkit for Leaflet maps \u2014 draw arrows, shapes, freehand sketches, rulers, notes, and text pinned to geo-coordinates. Optional React bindings.",type:"module",sideEffects:!1,main:"./dist/index.cjs",module:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:{types:"./dist/index.d.ts",default:"./dist/index.js"},require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},default:"./dist/index.js"},"./core":{types:"./dist/index.d.ts",import:{types:"./dist/index.d.ts",default:"./dist/index.js"},require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},default:"./dist/index.js"},"./react":{types:"./dist/react.d.ts",import:{types:"./dist/react.d.ts",default:"./dist/react.js"},require:{types:"./dist/react.d.cts",default:"./dist/react.cjs"},default:"./dist/react.js"},"./package.json":"./package.json"},files:["dist","README.md"],author:"Yusuf Arslan",license:"MIT",repository:{type:"git",url:"git+https://github.com/yusufarsln98/leaflet-tual.git",directory:"packages/leaflet-tual"},bugs:{url:"https://github.com/yusufarsln98/leaflet-tual/issues"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},keywords:["leaflet","leaflet-tual","tual","tuval","canvas","annotation","map-tools","arrows","notes","gis","overlay","framework-agnostic","vanilla-js","react","react-leaflet"],scripts:{build:"tsup",dev:"tsup --watch",lint:"eslint src --ext ts,tsx",typecheck:"tsc --noEmit",format:'prettier --write "src/**/*.{ts,tsx}"',"format:check":'prettier --check "src/**/*.{ts,tsx}"',test:"vitest run","test:watch":"vitest",version:"changeset version",release:"npm run build && changeset publish"},peerDependencies:{leaflet:"^1.9.0",react:"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","react-leaflet":"^4.0.0 || ^5.0.0"},peerDependenciesMeta:{react:{optional:!0},"react-dom":{optional:!0},"react-leaflet":{optional:!0}},devDependencies:{"@changesets/cli":"^2.27.1","@testing-library/dom":"^10.4.0","@testing-library/react":"^16.2.0","@types/leaflet":"^1.9.16","@types/node":"^22.13.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0",eslint:"^9.20.0","eslint-plugin-react-hooks":"^5.1.0",jsdom:"^26.0.0",leaflet:"^1.9.4",prettier:"^3.5.0",react:"^19.0.0","react-dom":"^19.0.0","react-leaflet":"^5.0.0",tsup:"^8.5.1",typescript:"^5.7.0","typescript-eslint":"^8.24.0",vitest:"^3.0.0"}};var Ie={"arrow-linear":"linear","arrow-curved":"curved","arrow-bi":"bi","arrow-elbow":"elbow","arrow-s-curve":"s-curve"},gt=["#000000","#4b5563","#2563eb","#dc2626","#16a34a","#d97706","#9333ea","#0891b2"],U=[{name:"Amber",bg:"#fef9c3",border:"#fde047",header:"#fef08a",text:"#422006"},{name:"Sky",bg:"#e0f2fe",border:"#7dd3fc",header:"#bae6fd",text:"#0c4a6e"},{name:"Emerald",bg:"#dcfce7",border:"#86efac",header:"#bbf7d0",text:"#064e3b"},{name:"Rose",bg:"#ffe4e6",border:"#fda4af",header:"#fecdd3",text:"#881337"},{name:"Violet",bg:"#f3e8ff",border:"#d8b4fe",header:"#e9d5ff",text:"#3b0764"},{name:"Dark Slate",bg:"#1e293b",border:"#334155",header:"#0f172a",text:"#f8fafc"},{name:"Midnight",bg:"#111827",border:"#374151",header:"#030712",text:"#f9fafb"}],De="#000000",Ce=2,it=[1,2,3,4,5,6,8,10,12],St=it,Ae="#fef9c3",wt="#422006",Ee=16,at=[10,12,14,16,18,20,24,28,32,36,40,48],Tt=at,bt={selectionGlowColor:"rgba(0, 0, 0, 0.2)",selectionGlowWidth:6,guideLineDash:[4,4],guideLineColor:"rgba(100, 100, 100, 0.6)",guideLineWidth:1.2,endpointHandleColor:"#4f4f4f",controlHandleColor:"#4f4f4f",handleFillColor:"#ffffff",handleRadius:5,handleStrokeWidth:2,shadowColor:"rgba(0, 0, 0, 0.2)",shadowBlur:3,shadowOffsetY:1.5,labelBackgroundColor:"#ffffff",labelTextColor:"#000000",labelFont:"12px system-ui, -apple-system, sans-serif",labelBorderWidth:1,labelBorderRadius:2,labelPaddingX:6,labelPaddingY:18,shapeDefaultFillOpacity:.16,shapeBorderRadius:0};var lt=0;function K(e="rlc"){lt+=1;let t=Math.random().toString(36).slice(2,8);return`${e}-${Date.now().toString(36)}-${lt}-${t}`}function O(e,t){let n=e.latLngToContainerPoint([t.lat,t.lng]);return{x:n.x,y:n.y}}function L(e,t){let n=e.containerPointToLatLng([t.x,t.y]);return{lat:n.lat,lng:n.lng}}function re(e,t,n=1){let r=n>0?n:1,o=t.x-e.x,a=t.y-e.y,l=Math.abs(o),s=Math.abs(a),i=o>=0?1:-1,d=a>=0?1:-1;return l/r>=s?{x:e.x+i*l,y:e.y+d*(l/r)}:{x:e.x+i*(s*r),y:e.y+d*s}}function F(e,t){let n=t.x-e.x,r=t.y-e.y,o=Math.hypot(n,r);if(o===0)return t;let a=Math.atan2(r,n),l=Math.PI/4,s=Math.round(a/l)*l;return{x:e.x+Math.cos(s)*o,y:e.y+Math.sin(s)*o}}function ie(e,t,n=.25){let r=(e.lat+t.lat)/2,o=(e.lng+t.lng)/2,a=t.lat-e.lat,l=t.lng-e.lng;return{lat:r+l*n,lng:o-a*n}}function ue(e,t,n,r){let o=1-r;return{x:o*o*e.x+2*o*r*t.x+r*r*n.x,y:o*o*e.y+2*o*r*t.y+r*r*n.y}}function ae(e,t,n){let r=n.x-t.x,o=n.y-t.y;return Math.hypot(r,o)<.001?Math.atan2(n.y-e.y,n.x-e.x):Math.atan2(o,r)}function Y(e,t,n){let r=(n.x-t.x)**2+(n.y-t.y)**2;if(r===0)return Math.hypot(e.x-t.x,e.y-t.y);let o=((e.x-t.x)*(n.x-t.x)+(e.y-t.y)*(n.y-t.y))/r;o=Math.max(0,Math.min(1,o));let a=t.x+o*(n.x-t.x),l=t.y+o*(n.y-t.y);return Math.hypot(e.x-a,e.y-l)}function Re(e,t,n,r,o=24){let a=1/0,l=t;for(let s=1;s<=o;s+=1){let i=ue(t,n,r,s/o),d=Y(e,l,i);d<a&&(a=d),l=i}return a}function le(e){if(!e)return null;try{let t=e.getSize?.();if(t&&t.x>0&&t.y>0)return{width:t.x,height:t.y}}catch{}try{let t=e.getContainer?.()?.getBoundingClientRect?.();if(t&&t.width>0&&t.height>0)return{width:t.width,height:t.height}}catch{}return null}function ke(e,t,n){if(!t||n<=0)return"";if(e.measureText(t).width<=n)return t;let r="\u2026";if(e.measureText(r).width>=n)return"";let o=0,a=t.length,l="";for(;o<=a;){let s=Math.floor((o+a)/2),i=t.slice(0,s)+r;e.measureText(i).width<=n?(l=i,o=s+1):a=s-1}return l||r}function Pt(e=16,t,n=14,r){if(t===null||typeof t!="number")return e;let o=r?.scaleFactor??1.22,a=r?.min??9,l=r?.max??72,s=e*Math.pow(o,t-n);return Math.round(Math.max(a,Math.min(l,s)))}function fe(e,t){let r=(t.lat-e.lat)*Math.PI/180,o=(t.lng-e.lng)*Math.PI/180,a=e.lat*Math.PI/180,l=t.lat*Math.PI/180,s=Math.sin(r/2),i=Math.sin(o/2),d=s*s+Math.cos(a)*Math.cos(l)*i*i;return 6371e3*(2*Math.atan2(Math.sqrt(d),Math.sqrt(1-d)))}function Oe(e,t="metric"){if(t==="imperial"){let r=e*3.28084;if(r<1e3)return`${Math.round(r)} ft`;let o=r/5280;return`${o>=10?o.toFixed(1):o.toFixed(2)} mi`}if(e<1e3)return`${Math.round(e)} m`;let n=e/1e3;return`${n>=10?n.toFixed(1):n.toFixed(2)} km`}function xt(e){let t=0;for(let n=0;n<e.length-1;n+=1)t+=fe(e[n],e[n+1]);return t}function j(e,t,n,r,o,a=2){e.save(),e.beginPath(),e.arc(t.x,t.y,o,0,Math.PI*2),e.fillStyle=r,e.fill(),e.lineWidth=a,e.strokeStyle=n,e.stroke(),e.restore()}function Z(e,t,n,r,o,a,l){e.save(),e.font=l?.labelFont??"12px system-ui, -apple-system, sans-serif";let s=l?.labelPaddingX??6,i=Math.max(10,a-s*2),d=ke(e,t,i);if(d){let u=e.measureText(d),p=Math.round(u.width+s*2),h=l?.labelPaddingY??18,m=Math.round(n-p/2),f=Math.round(r-h/2),y=l?.labelBorderRadius??2;l?.labelShadowColor&&(e.shadowColor=l.labelShadowColor,e.shadowBlur=l.labelShadowBlur??3),e.fillStyle=l?.labelBackgroundColor??"#ffffff",e.strokeStyle=l?.labelBorderColor??o,e.lineWidth=l?.labelBorderWidth??1,e.beginPath(),typeof e.roundRect=="function"?e.roundRect(m,f,p,h,y):e.rect(m,f,p,h),e.fill(),e.stroke(),e.fillStyle=l?.labelTextColor??"#000000",e.textAlign="center",e.textBaseline="middle",e.fillText(d,n,r)}e.restore()}function he(e,t,n,r,o,a=!0){let l=Math.PI/6.5,s=t.x-r*Math.cos(n-l),i=t.y-r*Math.sin(n-l),d=t.x-r*Math.cos(n+l),u=t.y-r*Math.sin(n+l);e.save(),e.setLineDash([]),e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(s,i),a?(e.lineTo(d,u),e.closePath(),e.fillStyle=o,e.fill()):(e.moveTo(t.x,t.y),e.lineTo(d,u),e.strokeStyle=o,e.lineWidth=Math.max(2,r/4.5),e.lineCap="round",e.stroke()),e.restore()}function me(e,t,n){let{start:r,end:o,control:a}=t;if(e.moveTo(r.x,r.y),n==="curved")e.quadraticCurveTo(a.x,a.y,o.x,o.y);else if(n==="elbow")e.lineTo(a.x,r.y),e.lineTo(a.x,o.y),e.lineTo(o.x,o.y);else if(n==="s-curve"){let l=o.x-r.x,s=o.y-r.y;e.bezierCurveTo(r.x+l*.5,r.y,r.x+l*.5,r.y+s,o.x,o.y)}else e.lineTo(o.x,o.y)}function V(e,t){let n=O(e,t.start),r=O(e,t.end),o=t.arrowStyle==="curved"||t.arrowStyle==="s-curve",a=t.controlPoint?t.controlPoint:o?ie(t.start,t.end):{lat:(t.start.lat+t.end.lat)/2,lng:(t.start.lng+t.end.lng)/2},l=O(e,a);return{start:n,end:r,control:l}}function ye(e,t,n,r={}){let{start:o,end:a,control:l}=t,s=Math.hypot(a.x-o.x,a.y-o.y);if(s<2)return;let i=r.theme,d=Math.max(12,n.strokeWidth*3.8),u=Math.atan2(a.y-o.y,a.x-o.x),p=Math.atan2(o.y-a.y,o.x-a.x);if(n.arrowStyle==="curved")u=ae(o,l,a),p=ae(a,l,o);else if(n.arrowStyle==="elbow"){let f=a.x-l.x,y=a.y-o.y;u=Math.abs(f)>1?Math.atan2(0,f):Math.atan2(y,0);let w=o.x-l.x;p=Math.abs(w)>1?Math.atan2(0,w):Math.atan2(-y,0)}else if(n.arrowStyle==="s-curve"){let f=a.x-o.x;u=ae(o,{x:o.x+f*.5,y:a.y},a)}e.save(),r.isPreview&&(e.globalAlpha=.85),r.isSelected&&(e.save(),e.beginPath(),me(e,t,n.arrowStyle),e.strokeStyle=i?.selectionGlowColor??"rgba(0, 0, 0, 0.2)",e.lineWidth=n.strokeWidth+(i?.selectionGlowWidth??6),e.lineCap="round",e.lineJoin="round",e.stroke(),e.restore()),e.save(),e.shadowColor=i?.shadowColor??"rgba(0, 0, 0, 0.2)",e.shadowBlur=i?.shadowBlur??3,e.shadowOffsetY=i?.shadowOffsetY??1.5,e.beginPath(),me(e,t,n.arrowStyle),e.strokeStyle=n.color,e.lineWidth=n.strokeWidth,e.lineCap="round",e.lineJoin="round";let h=!!(n.dashed||n.arrowStyle==="dashed");e.setLineDash(h?[n.strokeWidth*3,n.strokeWidth*2]:[]),e.stroke();let m=n.headStyle??(n.arrowStyle==="bi"?"both":"triangle");if(m!=="none"&&(he(e,a,u,d,n.color,m!=="open"),m==="both"&&he(e,o,p,d,n.color,!0)),e.restore(),n.label){let f=typeof i?.labelMinShapeSize=="number"?i.labelMinShapeSize:24;if(f<=0||s>=f){let y=n.arrowStyle==="curved"?ue(o,l,a,.5):n.arrowStyle==="elbow"?{x:l.x,y:(o.y+a.y)/2}:{x:(o.x+a.x)/2,y:(o.y+a.y)/2},w=i?.fitLabelsToShape!==!1,b=i?.labelMaxTextWidth??(w?Math.max(48,Math.min(280,s*1.6)):1/0);Z(e,n.label,Math.round(y.x),Math.round(y.y),n.color,b,i)}}if(r.isSelected){let f=i?.handleRadius??5,y=i?.handleFillColor??"#ffffff",w=i?.endpointHandleColor??"#4f4f4f",b=i?.controlHandleColor??"#767676",I=i?.handleStrokeWidth??2;(n.arrowStyle==="curved"||n.arrowStyle==="elbow")&&(e.save(),e.beginPath(),e.setLineDash(i?.guideLineDash?[...i.guideLineDash]:[4,4]),e.moveTo(o.x,o.y),e.lineTo(l.x,l.y),e.lineTo(a.x,a.y),e.strokeStyle=i?.guideLineColor??"rgba(100, 100, 100, 0.6)",e.lineWidth=i?.guideLineWidth??1.2,e.stroke(),e.restore(),j(e,l,b,y,f+.5,I)),j(e,o,w,y,f,I),j(e,a,w,y,f,I)}e.restore()}function We(e,t,n,r=11){return Math.hypot(e.x-t.end.x,e.y-t.end.y)<=r?"end":Math.hypot(e.x-t.start.x,e.y-t.start.y)<=r?"start":(n.arrowStyle==="curved"||n.arrowStyle==="elbow")&&Math.hypot(e.x-t.control.x,e.y-t.control.y)<=r?"control":null}function Fe(e,t,n,r=9){let o=Math.max(r,n.strokeWidth/2+6);if(n.arrowStyle==="curved")return Re(e,t.start,t.control,t.end)<=o;if(n.arrowStyle==="elbow"){let a={x:t.control.x,y:t.start.y},l={x:t.control.x,y:t.end.y};return Y(e,t.start,a)<=o||Y(e,a,l)<=o||Y(e,l,t.end)<=o}return Y(e,t.start,t.end)<=o}function se(e,t){return t.points.map(n=>O(e,n))}function st(e,t){if(t.length===0)return;if(e.moveTo(t[0].x,t[0].y),t.length===1){e.lineTo(t[0].x+.5,t[0].y+.5);return}if(t.length===2){e.lineTo(t[1].x,t[1].y);return}for(let r=1;r<t.length-1;r+=1){let o=(t[r].x+t[r+1].x)/2,a=(t[r].y+t[r+1].y)/2;e.quadraticCurveTo(t[r].x,t[r].y,o,a)}let n=t[t.length-1];e.lineTo(n.x,n.y)}function pe(e,t,n,r={}){if(t.length===0)return;let o=r.theme;e.save(),r.isPreview&&(e.globalAlpha=.9),r.isSelected&&(e.save(),e.beginPath(),st(e,t),e.strokeStyle=o?.selectionGlowColor??"rgba(0, 0, 0, 0.2)",e.lineWidth=n.strokeWidth+(o?.selectionGlowWidth??6),e.lineCap="round",e.lineJoin="round",e.stroke(),e.restore()),e.save(),e.shadowColor=o?.shadowColor??"rgba(0, 0, 0, 0.2)",e.shadowBlur=o?.shadowBlur??3,e.shadowOffsetY=o?.shadowOffsetY??1,e.beginPath(),st(e,t),e.strokeStyle=n.color,e.lineWidth=n.strokeWidth,e.lineCap="round",e.lineJoin="round",n.dashed?e.setLineDash([n.strokeWidth*3,n.strokeWidth*2]):e.setLineDash([]),e.stroke(),e.restore(),e.restore()}function He(e,t,n,r=9){if(t.length===0)return!1;let o=Math.max(r,n.strokeWidth/2+6);if(t.length===1)return Math.hypot(e.x-t[0].x,e.y-t[0].y)<=o;let a=1/0,l=1/0,s=-1/0,i=-1/0;for(let d=0;d<t.length;d+=1){let u=t[d];u.x<a&&(a=u.x),u.y<l&&(l=u.y),u.x>s&&(s=u.x),u.y>i&&(i=u.y)}if(e.x<a-o||e.x>s+o||e.y<l-o||e.y>i+o)return!1;for(let d=0;d<t.length-1;d+=1)if(Y(e,t[d],t[d+1])<=o)return!0;return!1}function ge(e,t,n,r){let{minX:o,minY:a,maxX:l,maxY:s,width:i,height:d,cx:u,cy:p}=t;if(n==="square"){let h=r?.shapeBorderRadius??0;h>0&&typeof e.roundRect=="function"?e.roundRect(o,a,i,d,h):e.rect(o,a,i,d);return}if(n==="circle"){e.ellipse(u,p,i/2,d/2,0,0,Math.PI*2);return}if(n==="triangle"){e.moveTo(u,a),e.lineTo(l,s),e.lineTo(o,s),e.closePath();return}if(n==="diamond"){e.moveTo(u,a),e.lineTo(l,p),e.lineTo(u,s),e.lineTo(o,p),e.closePath();return}if(n==="hexagon"){let h=i/2,m=d/2;for(let f=0;f<6;f+=1){let y=Math.PI/3*f-Math.PI/6,w=u+h*Math.cos(y),b=p+m*Math.sin(y);f===0?e.moveTo(w,b):e.lineTo(w,b)}e.closePath();return}if(n==="star"){let m=i/2,f=d/2,y=m*.42,w=f*.42;for(let b=0;b<10;b+=1){let I=b%2===0?m:y,x=b%2===0?f:w,A=b*Math.PI/5-Math.PI/2,H=u+I*Math.cos(A),W=p+x*Math.sin(A);b===0?e.moveTo(H,W):e.lineTo(H,W)}e.closePath();return}if(n==="marker"||n==="cloud"){let h=i/2,m=d*.36,f=a+m;e.moveTo(u,s),e.bezierCurveTo(o+i*.05,a+d*.7,o,a+d*.5,o,f),e.ellipse(u,f,h,m,0,Math.PI,0,!1),e.bezierCurveTo(l,a+d*.5,l-i*.05,a+d*.7,u,s),e.closePath();let y=h*.35,w=m*.35;y>=2.5&&w>=2.5&&(e.moveTo(u+y,f),e.ellipse(u,f,y,w,0,Math.PI*2,0,!0),e.closePath());return}if(n==="actor"){let h=Math.min(i,d)*.16,m=a+h+d*.04,f=m+h,y=a+d*.64,w=a+d*.42,b=i*.36,I=i*.32;e.moveTo(u+h,m),e.arc(u,m,h,0,Math.PI*2),e.closePath(),e.moveTo(u,f),e.lineTo(u,y),e.moveTo(u-b,w),e.lineTo(u+b,w),e.moveTo(u,y),e.lineTo(u-I,s),e.moveTo(u,y),e.lineTo(u+I,s)}}function Q(e,t){let n=O(e,t.start),r=O(e,t.end),o=Math.min(n.x,r.x),a=Math.min(n.y,r.y),l=Math.max(n.x,r.x),s=Math.max(n.y,r.y),i=Math.max(4,l-o),d=Math.max(4,s-a);return{start:n,end:r,minX:o,minY:a,maxX:l,maxY:s,width:i,height:d,cx:o+i/2,cy:a+d/2}}function Se(e,t,n,r={}){if(t.width<4&&t.height<4)return;let o=r.theme;if(e.save(),r.isPreview&&(e.globalAlpha=.85),r.isSelected&&(e.save(),e.beginPath(),ge(e,t,n.shape,o),e.strokeStyle=o?.selectionGlowColor??"rgba(0, 0, 0, 0.2)",e.lineWidth=n.strokeWidth+(o?.selectionGlowWidth??6),e.lineCap="round",e.lineJoin="round",e.stroke(),e.restore()),e.save(),e.shadowColor=o?.shadowColor??"rgba(0, 0, 0, 0.2)",e.shadowBlur=o?.shadowBlur??3,e.shadowOffsetY=o?.shadowOffsetY??1.5,e.beginPath(),ge(e,t,n.shape,o),n.filled){let a=o?.shapeDefaultFillOpacity??.16,l=Math.round(Math.min(1,Math.max(0,a))*255).toString(16).padStart(2,"0");e.fillStyle=n.fillColor??`${n.color}${l}`,e.fill()}if(e.strokeStyle=n.color,e.lineWidth=n.strokeWidth,e.lineCap="round",e.lineJoin="round",e.setLineDash(n.dashed?[n.strokeWidth*3,n.strokeWidth*2]:[]),e.stroke(),e.restore(),n.label){let a=typeof o?.labelMinShapeSize=="number"?o.labelMinShapeSize:18;if(a<=0||Math.max(t.width,t.height)>=a&&t.width>=8&&t.height>=8){let l=n.shape==="actor"?t.maxY+14:t.cy,s=o?.fitLabelsToShape!==!1,i=o?.labelMaxTextWidth??(s?Math.max(48,Math.min(280,t.width*2.2)):1/0);Z(e,n.label,Math.round(t.cx),Math.round(l),n.color,i,o)}}if(r.isSelected){let a=o?.handleRadius??5,l=o?.handleFillColor??"#ffffff",s=o?.endpointHandleColor??"#4f4f4f",i=o?.handleStrokeWidth??2;e.save(),e.setLineDash(o?.guideLineDash?[...o.guideLineDash]:[4,4]),e.strokeStyle=o?.guideLineColor??"rgba(100, 100, 100, 0.6)",e.lineWidth=o?.guideLineWidth??1.2,e.strokeRect(t.minX,t.minY,t.width,t.height),e.restore(),j(e,t.start,s,l,a,i),j(e,t.end,s,l,a,i)}e.restore()}function _e(e,t,n=11){return Math.hypot(e.x-t.end.x,e.y-t.end.y)<=n?"end":Math.hypot(e.x-t.start.x,e.y-t.start.y)<=n?"start":null}function Be(e,t,n=8){return e.x>=t.minX-n&&e.x<=t.maxX+n&&e.y>=t.minY-n&&e.y<=t.maxY+n}function ee(e,t){let n=O(e,t.start),r=O(e,t.end),o={x:(n.x+r.x)/2,y:(n.y+r.y)/2},a=Math.hypot(r.x-n.x,r.y-n.y),l=Math.atan2(r.y-n.y,r.x-n.x);return{start:n,end:r,mid:o,lengthPx:a,angle:l}}function we(e,t,n,r={}){let{start:o,end:a,mid:l,lengthPx:s,angle:i}=t;if(s<2)return;let d=r.theme;e.save(),r.isPreview&&(e.globalAlpha=.9),r.isSelected&&(e.save(),e.beginPath(),e.moveTo(o.x,o.y),e.lineTo(a.x,a.y),e.strokeStyle=d?.selectionGlowColor??"rgba(0, 0, 0, 0.2)",e.lineWidth=n.strokeWidth+(d?.selectionGlowWidth??6),e.lineCap="round",e.stroke(),e.restore()),e.save(),e.shadowColor=d?.shadowColor??"rgba(0, 0, 0, 0.2)",e.shadowBlur=d?.shadowBlur??3,e.shadowOffsetY=d?.shadowOffsetY??1.5,e.beginPath(),e.moveTo(o.x,o.y),e.lineTo(a.x,a.y),e.strokeStyle=n.color,e.lineWidth=n.strokeWidth,e.lineCap="round",n.dashed?e.setLineDash([n.strokeWidth*3,n.strokeWidth*2]):e.setLineDash([]),e.stroke();let u=i+Math.PI/2,p=Math.max(7,n.strokeWidth*3.2),h=Math.cos(u)*p,m=Math.sin(u)*p;e.beginPath(),e.setLineDash([]),e.moveTo(o.x-h,o.y-m),e.lineTo(o.x+h,o.y+m),e.moveTo(a.x-h,a.y-m),e.lineTo(a.x+h,a.y+m),e.stroke(),e.restore();let f=fe(n.start,n.end),y=n.label?n.label:Oe(f,n.unit);if(y){let w=d?.fitLabelsToShape!==!1,b=d?.labelMaxTextWidth??(w?Math.max(50,Math.min(300,s*1.5)):1/0);Z(e,y,Math.round(l.x),Math.round(l.y),n.color,b,d)}if(r.isSelected){let w=d?.handleRadius??5,b=d?.handleFillColor??"#ffffff",I=d?.endpointHandleColor??"#4f4f4f",x=d?.handleStrokeWidth??2;j(e,o,I,b,w,x),j(e,a,I,b,w,x)}e.restore()}function Ge(e,t,n=11){return Math.hypot(e.x-t.end.x,e.y-t.end.y)<=n?"end":Math.hypot(e.x-t.start.x,e.y-t.start.y)<=n?"start":null}function Ne(e,t,n,r=9){let o=Math.max(r,n.strokeWidth/2+6);return Y(e,t.start,t.end)<=o}function vt(e){let t=U.find(r=>r.bg===e);if(t)return t;let n=e?.startsWith("#")&&e.length===7&&parseInt(e.slice(1),16)<8947848||e==="#111827"||e==="#1e293b"||e==="#0f172a";return{name:"Custom",bg:e,border:n?"rgba(255, 255, 255, 0.16)":"rgba(0, 0, 0, 0.12)",header:n?"rgba(255, 255, 255, 0.08)":"rgba(0, 0, 0, 0.06)",text:n?"#f8fafc":"#0f172a"}}function Mt(e,t,n,r,o,a=!0){let l=a!==!1?le(e):null;if(!l||o||!(t.x>=-120&&t.x<=l.width+120&&t.y>=-120&&t.y<=l.height+120))return t;let i=r?95:n.width??230,d=r?22:n.height??100,u=8,p=16+u,h=Math.max(p,l.width-i+16-u),m=12+u,f=Math.max(m,l.height-d+12-u);return{x:Math.max(p,Math.min(h,t.x)),y:Math.max(m,Math.min(f,t.y))}}function Lt(e,t,n,r,o,a,l=!0){let s=l!==!1?le(e):null;if(!s||a||!(t.x>=-100&&t.x<=s.width+100&&t.y>=-100&&t.y<=s.height+100))return t;let d=o?35:Math.max(24,(n.text||"Text").length*r/3.6),u=o?11:r/2+4,p=8,h=d+p,m=Math.max(h,s.width-d-p),f=u+p,y=Math.max(f,s.height-u-p);return{x:Math.max(h,Math.min(m,t.x)),y:Math.max(f,Math.min(y,t.y))}}function Te(e,t,n,r,o,a,l,s,i,d,u,p){s.current={screenPoints:[n],geoPoints:[r]},e.dragging.disable(),d();let h=f=>{if(!s.current)return;let y=t.getBoundingClientRect(),w={x:f.clientX-y.left,y:f.clientY-y.top},b=s.current.screenPoints,I=b[b.length-1];Math.hypot(w.x-I.x,w.y-I.y)<2.5||(b.push(w),s.current.geoPoints.push(L(e,w)),i.current===null&&(i.current=window.requestAnimationFrame(()=>{i.current=null,d()})))},m=f=>{window.removeEventListener("pointermove",h),window.removeEventListener("pointerup",m),e.dragging.enable(),i.current!==null&&(window.cancelAnimationFrame(i.current),i.current=null);let y=s.current;s.current=null,y&&y.geoPoints.length>=1?(u({id:K("freedraw"),type:"freedraw",points:y.geoPoints,color:o,strokeWidth:a,dashed:l,createdAt:Date.now()}),f.shiftKey||p("select")):d()};window.addEventListener("pointermove",h),window.addEventListener("pointerup",m)}function Ye(e,t,n="Field Note"){let r=U.find(o=>o.bg===t)??U[0];return{id:K("note"),type:"note",position:e,title:n,text:"",backgroundColor:r.bg,textColor:r.text,width:230,createdAt:Date.now()}}function je(e,t,n,r,o){return{id:K("text"),type:"text",position:e,text:"",color:t,initialFontSize:n,baseZoom:o,fontWeight:r,createdAt:Date.now()}}function Xe(e,t,n,r,o,a,l,s,i,d,u,p){d({shape:o,startGeo:r,currentGeo:r}),e.dragging.disable();let h=f=>{let y=t.getBoundingClientRect(),w={x:f.clientX-y.left,y:f.clientY-y.top},b=f.shiftKey?re(n,w,1):w;d({shape:o,startGeo:r,currentGeo:L(e,b)})},m=f=>{window.removeEventListener("pointermove",h),window.removeEventListener("pointerup",m),e.dragging.enable();let y=t.getBoundingClientRect(),w={x:f.clientX-y.left,y:f.clientY-y.top},b=f.shiftKey?re(n,w,1):w,I=Math.hypot(w.x-n.x,w.y-n.y),x=I>=10?r:L(e,{x:n.x-45,y:n.y-45}),A=I>=10?L(e,b):L(e,{x:n.x+45,y:n.y+45});u({id:K("shape"),type:"shape",shape:o,start:x,end:A,color:a,filled:l,strokeWidth:s,dashed:i,createdAt:Date.now()}),d(null),p("select")};window.addEventListener("pointermove",h),window.addEventListener("pointerup",m)}function be(e,t,n,r,o,a){return{id:K("arrow"),type:"arrow",arrowStyle:e,start:t,end:n,controlPoint:e==="curved"?ie(t,n):e==="elbow"?{lat:(t.lat+n.lat)/2,lng:(t.lng+n.lng)/2}:void 0,color:r,strokeWidth:o,dashed:a,headStyle:e==="bi"?"both":"triangle",createdAt:Date.now()}}function ze(e,t,n,r,o,a,l,s,i,d,u){i({arrowStyle:o,startGeo:r,currentGeo:r}),e.dragging.disable();let p=m=>{let f=t.getBoundingClientRect(),y={x:m.clientX-f.left,y:m.clientY-f.top},w=m.shiftKey?F(n,y):y;i({arrowStyle:o,startGeo:r,currentGeo:L(e,w)})},h=m=>{window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",h),e.dragging.enable();let f=t.getBoundingClientRect(),y={x:m.clientX-f.left,y:m.clientY-f.top},w=m.shiftKey?F(n,y):y;Math.hypot(y.x-n.x,y.y-n.y)>=8&&(d(be(o,r,L(e,w),a,l,s)),i(null),u("select"))};window.addEventListener("pointermove",p),window.addEventListener("pointerup",h)}function dt(e,t,n,r,o){return{id:K("ruler"),type:"ruler",start:e,end:t,color:n,strokeWidth:r,dashed:o,unit:"metric",createdAt:Date.now()}}function Ke(e,t,n,r,o,a,l,s,i,d){s({startGeo:r,currentGeo:r}),e.dragging.disable();let u=h=>{let m=t.getBoundingClientRect(),f={x:h.clientX-m.left,y:h.clientY-m.top},y=h.shiftKey?F(n,f):f;s({startGeo:r,currentGeo:L(e,y)})},p=h=>{window.removeEventListener("pointermove",u),window.removeEventListener("pointerup",p),e.dragging.enable();let m=t.getBoundingClientRect(),f={x:h.clientX-m.left,y:h.clientY-m.top},y=h.shiftKey?F(n,f):f;Math.hypot(f.x-n.x,f.y-n.y)>=8&&(i(dt(r,L(e,y),o,a,l)),s(null),d("select"))};window.addEventListener("pointermove",u),window.addEventListener("pointerup",p)}function te(e,t){e.dragging.disable();let n=()=>{e.dragging.enable(),window.removeEventListener("pointermove",t),window.removeEventListener("pointerup",n)};window.addEventListener("pointermove",t),window.addEventListener("pointerup",n)}function Ue(e,t,n,r,o,a){te(e,l=>{let s=o(l),i=l.shiftKey;if(r==="start"){let d=i?F(n.end,s):s;a(t.id,{start:L(e,d)})}else if(r==="end"){let d=i?F(n.start,s):s;a(t.id,{end:L(e,d)})}else r==="control"&&a(t.id,{controlPoint:L(e,s)})})}function Je(e,t,n,r,o,a){let l=r==="start"?n.end:n.start,s=n.width>4&&n.height>4?n.width/n.height:1;te(e,i=>{let d=o(i),u=i.shiftKey?re(l,d,s):d,p=L(e,u);a(t.id,r==="start"?{start:p}:{end:p})})}function $e(e,t,n,r,o,a){let l=n.start,s=n.end,i=n.control,d=!!t.controlPoint;te(e,u=>{let p=o(u),h=p.x-r.x,m=p.y-r.y,f={start:L(e,{x:l.x+h,y:l.y+m}),end:L(e,{x:s.x+h,y:s.y+m})};(t.arrowStyle==="curved"||t.arrowStyle==="elbow")&&d&&(f.controlPoint=L(e,{x:i.x+h,y:i.y+m})),a(t.id,f)})}function qe(e,t,n,r,o,a){let l=n.start,s=n.end;te(e,i=>{let d=o(i),u=d.x-r.x,p=d.y-r.y;a(t.id,{start:L(e,{x:l.x+u,y:l.y+p}),end:L(e,{x:s.x+u,y:s.y+p})})})}function Ze(e,t,n,r,o,a){te(e,l=>{let s=o(l),i=s.x-r.x,d=s.y-r.y;a(t.id,{points:n.map(u=>L(e,{x:u.x+i,y:u.y+d}))})})}function Ve(e,t,n,r,o,a){te(e,l=>{let s=o(l),i=l.shiftKey;if(r==="start"){let d=i?F(n.end,s):s;a(t.id,{start:L(e,d)})}else if(r==="end"){let d=i?F(n.start,s):s;a(t.id,{end:L(e,d)})}})}function Qe(e,t,n,r,o,a){let l=n.start,s=n.end;te(e,i=>{let d=o(i),u=d.x-r.x,p=d.y-r.y;a(t.id,{start:L(e,{x:l.x+u,y:l.y+p}),end:L(e,{x:s.x+u,y:s.y+p})})})}function et({map:e,canvas:t,width:n,height:r,arrowItems:o,shapeItems:a,freeDrawItems:l,rulerItems:s,selectedId:i,draftShape:d,draftArrow:u,draftRuler:p,draftFreeDraw:h,activeColor:m,strokeWidth:f,dashed:y,shapeFilled:w,annotationTheme:b,arrowTheme:I,isReadOnly:x}){if(!e||!t||n===0||r===0)return;let A=b??I,H=typeof window<"u"&&window.devicePixelRatio||1,W=Math.round(n*H),X=Math.round(r*H);t.width!==W&&(t.width=W),t.height!==X&&(t.height=X);let M=t.getContext("2d");if(M){M.save(),typeof M.scale=="function"&&M.scale(H,H),M.clearRect(0,0,n,r);for(let P of l){let E=se(e,P);pe(M,E,P,{isSelected:!x&&P.id===i,theme:A})}for(let P of a){let E=Q(e,P);Se(M,E,P,{isSelected:!x&&P.id===i,theme:A})}for(let P of o){let E=V(e,P);ye(M,E,P,{isSelected:!x&&P.id===i,theme:A})}for(let P of s){let E=ee(e,P);we(M,E,P,{isSelected:!x&&P.id===i,theme:A})}if(!x&&h&&h.screenPoints.length>0&&pe(M,h.screenPoints,{color:m,strokeWidth:f,dashed:y},{isPreview:!0,theme:A}),!x&&d){let P={id:"draft-shape",type:"shape",shape:d.shape,start:d.startGeo,end:d.currentGeo,color:m,filled:w,strokeWidth:f,dashed:y,createdAt:0},E=Q(e,P);Se(M,E,P,{isPreview:!0,isSelected:!0,theme:A})}if(!x&&u){let P={id:"draft-arrow",type:"arrow",arrowStyle:u.arrowStyle,start:u.startGeo,end:u.currentGeo,color:m,strokeWidth:f,dashed:y,createdAt:0},E=V(e,P);ye(M,E,P,{isPreview:!0,isSelected:!0,theme:A})}if(!x&&p){let P={id:"draft-ruler",type:"ruler",start:p.startGeo,end:p.currentGeo,color:m,strokeWidth:f,dashed:y,unit:"metric",createdAt:0},E=ee(e,P);we(M,E,P,{isPreview:!0,isSelected:!0,theme:A})}M.restore()}}function tt(e,t){let n=()=>{let r=e.getSize();t({width:r.x,height:r.y})};return n(),e.on("move",n),e.on("zoom",n),e.on("zoomanim",n),e.on("viewreset",n),e.on("resize",n),()=>{e.off("move",n),e.off("zoom",n),e.off("zoomanim",n),e.off("viewreset",n),e.off("resize",n)}}function nt(e){let t=e.getContainer();if(!t)return()=>{};let n=o=>{let a=o.target;if(!a?.closest?.("[data-tual-overlay], input, textarea, select, button, .rlc-overlay"))return;let l=Object.prototype.hasOwnProperty.call(a,"_leaflet_disable_events"),s=a._leaflet_disable_events;a._leaflet_disable_events=!0;let i=!!e.doubleClickZoom?.enabled?.();i&&e.doubleClickZoom.disable(),setTimeout(()=>{l?a._leaflet_disable_events=s:delete a._leaflet_disable_events,i&&e.doubleClickZoom.enable()},0)},r=o=>{if(o.target?.closest?.("textarea, input, select, button, [data-tual-note-resize], .rlc-note-resize-handle")&&e.dragging?.enabled?.()){e.dragging.disable();let l=()=>{e.dragging.enable(),window.removeEventListener("mouseup",l,!0),window.removeEventListener("touchend",l,!0),window.removeEventListener("pointerup",l,!0)};window.addEventListener("mouseup",l,{capture:!0,once:!0}),window.addEventListener("touchend",l,{capture:!0,once:!0}),window.addEventListener("pointerup",l,{capture:!0,once:!0})}};return t.addEventListener("dblclick",n,!0),t.addEventListener("mousedown",r,!0),t.addEventListener("touchstart",r,!0),()=>{t.removeEventListener("dblclick",n,!0),t.removeEventListener("mousedown",r,!0),t.removeEventListener("touchstart",r,!0)}}function ot(e={}){let t=Math.max(0,(e.maxHistory??50)-1),n=[],r=e.items??e.initialItems??[],o=[],a=r,l=e.initialTool??"select",s=!!(e.readOnly??!1),i=null,d=!1,u=e.defaultShape??"square",p=!0,h=e.defaultColor??De,m=e.defaultStrokeWidth??Ce,f=!1,y=e.defaultNoteColor??Ae,w=e.defaultFontSize??Ee,b="bold",I=new Set,x=()=>{for(let c of I)c(v)},A=c=>{e.onItemsChange?.(c),e.onChange?.(c)},H=(c,g)=>{e.onItemsChangeComplete?.(c,g),e.onChangeComplete?.(c,g),e.onEditEnd?.(c,g),e.onEditComplete?.(c,g),g&&e.onItemChangeComplete?.(g)},W=c=>{let g=c(r);return r=g,A(g),x(),g},X=c=>{if(r===a)return;let g=a;a=r,n=[...n,g].slice(-t),o=[],H(r,c),x()},M=c=>{if(i!==c){let g=i;i=c,d=!1,g!==null&&c===null&&X(),e.onItemSelect?.(r.find(R=>R.id===c)??null),x()}},P=c=>{s&&c!=="select"||(l=c,e.onToolChange?.(c),x())},E=c=>{s=!!c,s&&l!=="select"&&(l="select"),x()},G=(c,g)=>{i&&W(R=>R.map(z=>z.id===i&&c(z)?g(z):z))},de=c=>{s||(u=c,G(g=>g.type==="shape",g=>({...g,shape:c})),x())},ce=c=>{s||(p=c,G(g=>g.type==="shape",g=>({...g,filled:c})),x())},Pe=c=>{s||(h=c,G(g=>g.type!=="note",g=>({...g,color:c})),x())},xe=c=>{s||(m=c,G(g=>g.type==="arrow"||g.type==="freedraw"||g.type==="shape"||g.type==="ruler",g=>({...g,strokeWidth:c})),x())},ve=c=>{s||(f=c,G(g=>g.type==="arrow"||g.type==="freedraw"||g.type==="shape"||g.type==="ruler",g=>({...g,dashed:c})),x())},S=c=>{if(s)return;y=c;let g=U.find(R=>R.bg===c);G(R=>R.type==="note",R=>({...R,backgroundColor:c,textColor:g?.text??R.textColor})),x()},D=c=>{s||(w=c,G(g=>g.type==="text",g=>({...g,initialFontSize:c})),x())},C=c=>{s||(b=c,G(g=>g.type==="text",g=>({...g,fontWeight:c})),x())},k=c=>{d=c,x()},J=c=>{s||(W(g=>[...g,c]),M(c.id),e.onItemCreate?.(c))},$=(c,g)=>{if(s){let z=Object.keys(g);if(z.length!==1||z[0]!=="minimized")return}let R;W(z=>z.map(Me=>Me.id===c?(R={...Me,...g},R):Me)),R&&e.onItemChange?.(R)},_=c=>{s||(W(g=>g.filter(R=>R.id!==c)),i===c&&M(null),e.onItemDelete?.(c),X())},N=()=>{!s&&i&&_(i)},B=()=>{s||(W(()=>[]),M(null),X())},v={get items(){return r},get activeTool(){return l},setActiveTool:P,get readOnly(){return s},setReadOnly:E,get activeShape(){return u},setActiveShape:de,get shapeFilled(){return p},setShapeFilled:ce,get selectedId(){return i},setSelectedId:M,get selectedItem(){return r.find(c=>c.id===i)??null},get isEditingLabel(){return d},setEditingLabel:k,get labelEditMode(){return d},setLabelEditMode:k,get activeColor(){return h},setActiveColor:Pe,get strokeWidth(){return m},setStrokeWidth:xe,get dashed(){return f},setDashed:ve,get noteColor(){return y},setNoteColor:S,get fontSize(){return w},setFontSize:D,get fontWeight(){return b},setFontWeight:C,addItem:J,updateItem:$,removeItem:_,deleteSelected:N,clearAll:B,clear:B,deleteItem:_,setTool:P,selectItem:M,undo:()=>{if(s||n.length===0)return;let c=n[n.length-1];o=[r,...o],n=n.slice(0,-1),r=c,a=c,A(c),H(c,null),x()},redo:()=>{if(s||o.length===0)return;let c=o[0];n=[...n,r],o=o.slice(1),r=c,a=c,A(c),H(c,null),x()},get canUndo(){return!s&&n.length>0},get canRedo(){return!s&&o.length>0},notifyChangeComplete:X,exportJSON:()=>JSON.stringify(r,null,2),importJSON:c=>{if(s)return!1;try{let g=JSON.parse(c);return Array.isArray(g)?(W(()=>g),M(null),X(),!0):!1}catch{return!1}},subscribe(c){return I.add(c),()=>{I.delete(c)}},getState(){return v},destroy(){I.clear()}};return v}function It(e,t={}){let{controller:n,annotationTheme:r,arrowTheme:o,labels:a,zIndex:l=650,...s}=t,i=n??ot(s),d=e.getContainer(),u=document.createElement("div");u.setAttribute("data-tual-overlay","true"),u.style.position="absolute",u.style.inset="0",u.style.pointerEvents="none",u.style.zIndex=String(l),u.style.overflow="hidden";let p=document.createElement("canvas");p.style.position="absolute",p.style.top="0",p.style.left="0",p.style.pointerEvents="none";let h=document.createElement("div");h.style.position="absolute",h.style.inset="0",h.style.pointerEvents="none",u.appendChild(p),u.appendChild(h),d.appendChild(u);let m={width:0,height:0},f=null,y=null,w=null,b={current:null},I={current:null},x=S=>{f=S,M()},A=S=>{y=S,M()},H=S=>{w=S,M()},W=()=>{b.current=null,I.current!==null&&typeof window<"u"&&(window.cancelAnimationFrame(I.current),I.current=null)},X=()=>{let S=!i.readOnly&&i.activeTool!=="select";h.style.pointerEvents=S?"auto":"none",h.style.cursor=S?"crosshair":"default",p.style.width=`${m.width}px`,p.style.height=`${m.height}px`},M=()=>{X();let S=i.items;et({map:e,canvas:p,width:m.width,height:m.height,arrowItems:S.filter(D=>D.type==="arrow"),shapeItems:S.filter(D=>D.type==="shape"),freeDrawItems:S.filter(D=>D.type==="freedraw"),rulerItems:S.filter(D=>D.type==="ruler"),selectedId:i.selectedId,draftShape:y,draftArrow:f,draftRuler:w,draftFreeDraw:b.current,activeColor:i.activeColor,strokeWidth:i.strokeWidth,dashed:i.dashed,shapeFilled:i.shapeFilled,annotationTheme:r,arrowTheme:o,isReadOnly:i.readOnly})},P=S=>{let D=d.getBoundingClientRect();return{x:S.clientX-D.left,y:S.clientY-D.top}},E=S=>{if(S.button!==0||i.readOnly)return;S.stopPropagation(),S.preventDefault();let D=P(S),C=L(e,D),{activeTool:k,activeShape:J,shapeFilled:$,activeColor:_,strokeWidth:N,dashed:B,noteColor:q,fontSize:ne,fontWeight:oe}=i;if(k==="freedraw"){Te(e,d,D,C,_,N,B,b,I,M,i.addItem,i.setActiveTool);return}if(k==="shape"){Xe(e,d,D,C,J,_,$,N,B,A,i.addItem,i.setActiveTool);return}if(k==="note"){i.addItem(Ye(C,q,a?.noteDefaultTitle??"Field Note")),i.setActiveTool("select");return}if(k==="text"){i.addItem(je(C,_,ne,oe,e.getZoom?.()??14)),i.setActiveTool("select");return}if(k==="ruler"){Ke(e,d,D,C,_,N,B,H,i.addItem,i.setActiveTool);return}let T=Ie[k];if(T)if(!f)ze(e,d,D,C,T,_,N,B,x,i.addItem,i.setActiveTool);else{let v=O(e,f.startGeo),c=S.shiftKey?F(v,D):D;Math.hypot(c.x-v.x,c.y-v.y)>=4&&i.addItem(be(f.arrowStyle,f.startGeo,L(e,c),_,N,B)),x(null),i.setActiveTool("select")}},G=S=>{if(!f)return;let D=P(S),C=O(e,f.startGeo),k=S.shiftKey?F(C,D):D;x({...f,currentGeo:L(e,k)})},de=S=>{if(S.button!==0||i.readOnly||i.activeTool!=="select"||S.target?.closest("[data-tual-toolbar], [data-tual-note], [data-tual-text], .leaflet-control"))return;let C=P(S),k=i.items,J=k.filter(T=>T.type==="arrow"),$=k.filter(T=>T.type==="shape"),_=k.filter(T=>T.type==="freedraw"),N=k.filter(T=>T.type==="ruler"),B=i.selectedId,q=J.find(T=>T.id===B);if(q){let T=V(e,q),v=We(C,T,q);if(v){S.stopPropagation(),S.preventDefault(),Ue(e,q,T,v,P,i.updateItem);return}}let ne=$.find(T=>T.id===B);if(ne){let T=Q(e,ne),v=_e(C,T);if(v){S.stopPropagation(),S.preventDefault(),Je(e,ne,T,v,P,i.updateItem);return}}let oe=N.find(T=>T.id===B);if(oe){let T=ee(e,oe),v=Ge(C,T);if(v){S.stopPropagation(),S.preventDefault(),Ve(e,oe,T,v,P,i.updateItem);return}}for(let T=J.length-1;T>=0;T-=1){let v=J[T],c=V(e,v);if(Fe(C,c,v)){S.stopPropagation(),S.preventDefault(),i.setSelectedId(v.id),$e(e,v,c,C,P,i.updateItem);return}}for(let T=$.length-1;T>=0;T-=1){let v=$[T],c=Q(e,v);if(Be(C,c)){S.stopPropagation(),S.preventDefault(),i.setSelectedId(v.id),qe(e,v,c,C,P,i.updateItem);return}}for(let T=_.length-1;T>=0;T-=1){let v=_[T],c=se(e,v);if(He(C,c,v)){S.stopPropagation(),S.preventDefault(),i.setSelectedId(v.id),Ze(e,v,c,C,P,i.updateItem);return}}for(let T=N.length-1;T>=0;T-=1){let v=N[T],c=ee(e,v);if(Ne(C,c,v)){S.stopPropagation(),S.preventDefault(),i.setSelectedId(v.id),Qe(e,v,c,C,P,i.updateItem);return}}B&&(i.setSelectedId(null),i.notifyChangeComplete())},ce=S=>{if(i.readOnly)return;let D=S.target;D&&(D.tagName==="INPUT"||D.tagName==="TEXTAREA"||D.isContentEditable)||(S.key==="Escape"?(f=null,y=null,w=null,W(),i.setSelectedId(null),i.setActiveTool("select"),i.notifyChangeComplete(),M()):(S.key==="Delete"||S.key==="Backspace")&&i.selectedId&&(S.preventDefault(),i.deleteSelected()))};h.addEventListener("pointerdown",E),h.addEventListener("pointermove",G),d.addEventListener("pointerdown",de,{capture:!0}),typeof window<"u"&&window.addEventListener("keydown",ce);let Pe=tt(e,S=>{m=S,M()}),xe=nt(e),ve=i.subscribe(()=>{M()});return M(),{controller:i,container:u,canvas:p,repaint:M,destroy(){h.removeEventListener("pointerdown",E),h.removeEventListener("pointermove",G),d.removeEventListener("pointerdown",de,{capture:!0}),typeof window<"u"&&window.removeEventListener("keydown",ce),W(),Pe(),xe(),ve(),n||i.destroy(),u.remove()}}}var Dt=rt.version;0&&(module.exports={DEFAULT_ANNOTATION_THEME,DEFAULT_FONT_SIZE,DEFAULT_FONT_SIZE_OPTIONS,DEFAULT_NOTE_BG,DEFAULT_NOTE_TEXT,DEFAULT_STROKE_COLOR,DEFAULT_STROKE_WIDTH,DEFAULT_STROKE_WIDTH_OPTIONS,FONT_SIZE_OPTIONS,NOTE_COLOR_THEMES,STROKE_COLORS,STROKE_WIDTH_OPTIONS,TOOL_TO_ARROW_STYLE,VERSION,bindBlockMapDblClick,bindLeafletSync,buildArrowItem,buildRulerItem,calculateGeodesicDistance,calculateLineDistance,calculateZoomFontSize,clampNotePosition,clampTextPosition,computeDefaultControlGeoPoint,constrainAngleTo45Degrees,constrainToAspectRatio,createDraftNote,createDraftText,createId,createLeafletTual,createLeafletTualController,distanceToQuadraticBezier,distanceToSegment,drawArrowHead,drawTualHandle,drawTualLabelPill,formatRealWorldDistance,geoToScreen,getMapDimensions,getQuadraticBezierPoint,getQuadraticEndAngle,hitTestArrow,hitTestArrowHandle,hitTestFreeDraw,hitTestRuler,hitTestRulerHandle,hitTestShape,hitTestShapeHandle,paintLeafletTual,projectArrow,projectFreeDraw,projectRuler,projectShape,renderArrowOnCanvas,renderFreeDrawOnCanvas,renderRulerOnCanvas,renderShapeOnCanvas,resolveNoteTheme,screenToGeo,startArrowBodyDrag,startArrowDrag,startArrowHandleDrag,startFreeDrawBodyDrag,startFreeDrawDrag,startRulerBodyDrag,startRulerDrag,startRulerHandleDrag,startShapeBodyDrag,startShapeDrag,startShapeHandleDrag,traceArrowPath,tracePolygonShape,truncateTualText});
2
+ //# sourceMappingURL=index.cjs.map