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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../package.json","../src/core/shared/constants.ts","../src/core/shared/geo.ts","../src/core/shared/tual-render.ts","../src/core/entities/arrow/arrow-geometry.ts","../src/core/entities/arrow/render-arrow.ts","../src/core/entities/freedraw/render-freedraw.ts","../src/core/entities/shape/trace-shape.ts","../src/core/entities/shape/render-shape.ts","../src/core/entities/ruler/render-ruler.ts","../src/core/entities/note/note-geometry.ts","../src/core/entities/text/text-geometry.ts","../src/core/features/freedraw-drag-handler.ts","../src/core/features/drawing-drag-handlers.ts","../src/core/features/select-drag-handlers.ts","../src/core/features/tual-painter.ts","../src/core/features/map-sync.ts","../src/core/features/tual-controller.ts","../src/core/features/create-leaflet-tual.ts","../src/core/index.ts"],"sourcesContent":["{\n \"name\": \"leaflet-tual\",\n \"version\": \"1.0.0\",\n \"description\": \"Framework-agnostic interactive canvas and annotation toolkit for Leaflet maps — draw arrows, shapes, freehand sketches, rulers, notes, and text pinned to geo-coordinates. Optional React bindings.\",\n \"type\": \"module\",\n \"sideEffects\": false,\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"default\": \"./dist/index.js\"\n },\n \"./core\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n },\n \"default\": \"./dist/index.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react.d.ts\",\n \"import\": {\n \"types\": \"./dist/react.d.ts\",\n \"default\": \"./dist/react.js\"\n },\n \"require\": {\n \"types\": \"./dist/react.d.cts\",\n \"default\": \"./dist/react.cjs\"\n },\n \"default\": \"./dist/react.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"author\": \"Yusuf Arslan\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/yusufarsln98/leaflet-tual.git\",\n \"directory\": \"packages/leaflet-tual\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/yusufarsln98/leaflet-tual/issues\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"keywords\": [\n \"leaflet\",\n \"leaflet-tual\",\n \"tual\",\n \"tuval\",\n \"canvas\",\n \"annotation\",\n \"map-tools\",\n \"arrows\",\n \"notes\",\n \"gis\",\n \"overlay\",\n \"framework-agnostic\",\n \"vanilla-js\",\n \"react\",\n \"react-leaflet\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint src --ext ts,tsx\",\n \"typecheck\": \"tsc --noEmit\",\n \"format\": \"prettier --write \\\"src/**/*.{ts,tsx}\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.{ts,tsx}\\\"\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"version\": \"changeset version\",\n \"release\": \"npm run build && changeset publish\"\n },\n \"peerDependencies\": {\n \"leaflet\": \"^1.9.0\",\n \"react\": \"^18.0.0 || ^19.0.0\",\n \"react-dom\": \"^18.0.0 || ^19.0.0\",\n \"react-leaflet\": \"^4.0.0 || ^5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"react-leaflet\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.1\",\n \"@testing-library/dom\": \"^10.4.0\",\n \"@testing-library/react\": \"^16.2.0\",\n \"@types/leaflet\": \"^1.9.16\",\n \"@types/node\": \"^22.13.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"eslint\": \"^9.20.0\",\n \"eslint-plugin-react-hooks\": \"^5.1.0\",\n \"jsdom\": \"^26.0.0\",\n \"leaflet\": \"^1.9.4\",\n \"prettier\": \"^3.5.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"react-leaflet\": \"^5.0.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.7.0\",\n \"typescript-eslint\": \"^8.24.0\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","import type { ArrowStyle, TualAnnotationTheme } from '../types/index.js'\n\nexport const TOOL_TO_ARROW_STYLE: Record<string, ArrowStyle | undefined> = {\n 'arrow-linear': 'linear',\n 'arrow-curved': 'curved',\n 'arrow-bi': 'bi',\n 'arrow-elbow': 'elbow',\n 'arrow-s-curve': 's-curve',\n}\n\nexport const STROKE_COLORS = [\n '#000000', // Black (Default)\n '#4b5563', // Slate Gray\n '#2563eb', // Blue\n '#dc2626', // Red\n '#16a34a', // Green\n '#d97706', // Amber\n '#9333ea', // Purple\n '#0891b2', // Cyan\n] as const\n\nexport interface NoteColorTheme {\n name: string\n bg: string\n border: string\n header: string\n text: string\n}\n\nexport const NOTE_COLOR_THEMES: readonly NoteColorTheme[] = [\n {\n name: 'Amber',\n bg: '#fef9c3',\n border: '#fde047',\n header: '#fef08a',\n text: '#422006',\n },\n {\n name: 'Sky',\n bg: '#e0f2fe',\n border: '#7dd3fc',\n header: '#bae6fd',\n text: '#0c4a6e',\n },\n {\n name: 'Emerald',\n bg: '#dcfce7',\n border: '#86efac',\n header: '#bbf7d0',\n text: '#064e3b',\n },\n {\n name: 'Rose',\n bg: '#ffe4e6',\n border: '#fda4af',\n header: '#fecdd3',\n text: '#881337',\n },\n {\n name: 'Violet',\n bg: '#f3e8ff',\n border: '#d8b4fe',\n header: '#e9d5ff',\n text: '#3b0764',\n },\n {\n name: 'Dark Slate',\n bg: '#1e293b',\n border: '#334155',\n header: '#0f172a',\n text: '#f8fafc',\n },\n {\n name: 'Midnight',\n bg: '#111827',\n border: '#374151',\n header: '#030712',\n text: '#f9fafb',\n },\n] as const\n\nexport const DEFAULT_STROKE_COLOR = '#000000'\nexport const DEFAULT_STROKE_WIDTH = 2\nexport const DEFAULT_STROKE_WIDTH_OPTIONS: readonly number[] = [\n 1, 2, 3, 4, 5, 6, 8, 10, 12,\n] as const\nexport const STROKE_WIDTH_OPTIONS = DEFAULT_STROKE_WIDTH_OPTIONS\nexport const DEFAULT_NOTE_BG = '#fef9c3'\nexport const DEFAULT_NOTE_TEXT = '#422006'\nexport const DEFAULT_FONT_SIZE = 16\nexport const DEFAULT_FONT_SIZE_OPTIONS: readonly number[] = [\n 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48,\n] as const\nexport const FONT_SIZE_OPTIONS = DEFAULT_FONT_SIZE_OPTIONS\n\n/**\n * Super simple unified annotation default theme matching basic HTML element appearance.\n */\nexport const DEFAULT_ANNOTATION_THEME: Readonly<TualAnnotationTheme> = {\n selectionGlowColor: 'rgba(0, 0, 0, 0.2)',\n selectionGlowWidth: 6,\n guideLineDash: [4, 4],\n guideLineColor: 'rgba(100, 100, 100, 0.6)',\n guideLineWidth: 1.2,\n endpointHandleColor: '#4f4f4f',\n controlHandleColor: '#4f4f4f',\n handleFillColor: '#ffffff',\n handleRadius: 5,\n handleStrokeWidth: 2,\n shadowColor: 'rgba(0, 0, 0, 0.2)',\n shadowBlur: 3,\n shadowOffsetY: 1.5,\n labelBackgroundColor: '#ffffff',\n labelTextColor: '#000000',\n labelFont: '12px system-ui, -apple-system, sans-serif',\n labelBorderWidth: 1,\n labelBorderRadius: 2,\n labelPaddingX: 6,\n labelPaddingY: 18,\n shapeDefaultFillOpacity: 0.16,\n shapeBorderRadius: 0,\n} as const\n\n\n\n","import type L from 'leaflet'\nimport type { GeoPoint, ScreenPoint } from '../types/index.js'\n\nlet idCounter = 0\n\nexport function createId(prefix = 'rlc'): string {\n idCounter += 1\n const randomPart = Math.random().toString(36).slice(2, 8)\n return `${prefix}-${Date.now().toString(36)}-${idCounter}-${randomPart}`\n}\n\nexport function geoToScreen(map: L.Map, point: GeoPoint): ScreenPoint {\n const containerPt = map.latLngToContainerPoint([point.lat, point.lng])\n return { x: containerPt.x, y: containerPt.y }\n}\n\nexport function screenToGeo(map: L.Map, point: ScreenPoint): GeoPoint {\n const latLng = map.containerPointToLatLng([point.x, point.y])\n return { lat: latLng.lat, lng: latLng.lng }\n}\n\nexport function constrainToAspectRatio(\n anchor: ScreenPoint,\n target: ScreenPoint,\n aspectRatio = 1,\n): ScreenPoint {\n const safeRatio = aspectRatio > 0 ? aspectRatio : 1\n const dx = target.x - anchor.x\n const dy = target.y - anchor.y\n const absDx = Math.abs(dx)\n const absDy = Math.abs(dy)\n const signX = dx >= 0 ? 1 : -1\n const signY = dy >= 0 ? 1 : -1\n\n if (absDx / safeRatio >= absDy) {\n return {\n x: anchor.x + signX * absDx,\n y: anchor.y + signY * (absDx / safeRatio),\n }\n }\n return {\n x: anchor.x + signX * (absDy * safeRatio),\n y: anchor.y + signY * absDy,\n }\n}\n\nexport function constrainAngleTo45Degrees(\n anchor: ScreenPoint,\n target: ScreenPoint,\n): ScreenPoint {\n const dx = target.x - anchor.x\n const dy = target.y - anchor.y\n const dist = Math.hypot(dx, dy)\n if (dist === 0) return target\n const angle = Math.atan2(dy, dx)\n const snapStep = Math.PI / 4\n const snappedAngle = Math.round(angle / snapStep) * snapStep\n return {\n x: anchor.x + Math.cos(snappedAngle) * dist,\n y: anchor.y + Math.sin(snappedAngle) * dist,\n }\n}\n\nexport function computeDefaultControlGeoPoint(\n start: GeoPoint,\n end: GeoPoint,\n curvature = 0.25,\n): GeoPoint {\n const midLat = (start.lat + end.lat) / 2\n const midLng = (start.lng + end.lng) / 2\n const dLat = end.lat - start.lat\n const dLng = end.lng - start.lng\n return {\n lat: midLat + dLng * curvature,\n lng: midLng - dLat * curvature,\n }\n}\n\nexport function getQuadraticBezierPoint(\n p0: ScreenPoint,\n p1: ScreenPoint,\n p2: ScreenPoint,\n t: number,\n): ScreenPoint {\n const invT = 1 - t\n return {\n x: invT * invT * p0.x + 2 * invT * t * p1.x + t * t * p2.x,\n y: invT * invT * p0.y + 2 * invT * t * p1.y + t * t * p2.y,\n }\n}\n\nexport function getQuadraticEndAngle(\n p0: ScreenPoint,\n p1: ScreenPoint,\n p2: ScreenPoint,\n): number {\n const dx = p2.x - p1.x\n const dy = p2.y - p1.y\n if (Math.hypot(dx, dy) < 0.001) {\n return Math.atan2(p2.y - p0.y, p2.x - p0.x)\n }\n return Math.atan2(dy, dx)\n}\n\nexport function distanceToSegment(\n p: ScreenPoint,\n v: ScreenPoint,\n w: ScreenPoint,\n): number {\n const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2\n if (l2 === 0) return Math.hypot(p.x - v.x, p.y - v.y)\n let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2\n t = Math.max(0, Math.min(1, t))\n const projX = v.x + t * (w.x - v.x)\n const projY = v.y + t * (w.y - v.y)\n return Math.hypot(p.x - projX, p.y - projY)\n}\n\nexport function distanceToQuadraticBezier(\n p: ScreenPoint,\n p0: ScreenPoint,\n p1: ScreenPoint,\n p2: ScreenPoint,\n steps = 24,\n): number {\n let minDistance = Infinity\n let prev = p0\n for (let i = 1; i <= steps; i += 1) {\n const curr = getQuadraticBezierPoint(p0, p1, p2, i / steps)\n const dist = distanceToSegment(p, prev, curr)\n if (dist < minDistance) minDistance = dist\n prev = curr\n }\n return minDistance\n}\n\nexport function getMapDimensions(\n map: L.Map | null | undefined,\n): { width: number; height: number } | null {\n if (!map) return null\n try {\n const size = map.getSize?.()\n if (size && size.x > 0 && size.y > 0) return { width: size.x, height: size.y }\n } catch { /* ignore */ }\n try {\n const rect = map.getContainer?.()?.getBoundingClientRect?.()\n if (rect && rect.width > 0 && rect.height > 0) return { width: rect.width, height: rect.height }\n } catch { /* ignore */ }\n return null\n}\n\nexport function truncateTualText(\n ctx: CanvasRenderingContext2D,\n text: string,\n maxWidth: number,\n): string {\n if (!text || maxWidth <= 0) return ''\n if (ctx.measureText(text).width <= maxWidth) return text\n\n const ellipsis = '…'\n if (ctx.measureText(ellipsis).width >= maxWidth) return ''\n\n let low = 0\n let high = text.length\n let best = ''\n while (low <= high) {\n const mid = Math.floor((low + high) / 2)\n const candidate = text.slice(0, mid) + ellipsis\n if (ctx.measureText(candidate).width <= maxWidth) {\n best = candidate\n low = mid + 1\n } else {\n high = mid - 1\n }\n }\n return best || ellipsis\n}\n\nexport function calculateZoomFontSize(\n initialFontSize = 16,\n currentZoom: number | null,\n baseZoom = 14,\n options?: { min?: number; max?: number; scaleFactor?: number },\n): number {\n if (currentZoom === null || typeof currentZoom !== 'number') return initialFontSize\n const factor = options?.scaleFactor ?? 1.22\n const min = options?.min ?? 9\n const max = options?.max ?? 72\n const scaled = initialFontSize * Math.pow(factor, currentZoom - baseZoom)\n return Math.round(Math.max(min, Math.min(max, scaled)))\n}\n\nexport function calculateGeodesicDistance(p1: GeoPoint, p2: GeoPoint): number {\n const R = 6371000 // Earth radius in meters\n const dLat = ((p2.lat - p1.lat) * Math.PI) / 180\n const dLng = ((p2.lng - p1.lng) * Math.PI) / 180\n const lat1 = (p1.lat * Math.PI) / 180\n const lat2 = (p2.lat * Math.PI) / 180\n\n const sinDLat = Math.sin(dLat / 2)\n const sinDLng = Math.sin(dLng / 2)\n const a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLng * sinDLng\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))\n return R * c\n}\n\nexport function formatRealWorldDistance(\n meters: number,\n unit: 'metric' | 'imperial' = 'metric',\n): string {\n if (unit === 'imperial') {\n const feet = meters * 3.28084\n if (feet < 1000) {\n return `${Math.round(feet)} ft`\n }\n const miles = feet / 5280\n return `${miles >= 10 ? miles.toFixed(1) : miles.toFixed(2)} mi`\n }\n\n if (meters < 1000) {\n return `${Math.round(meters)} m`\n }\n const km = meters / 1000\n return `${km >= 10 ? km.toFixed(1) : km.toFixed(2)} km`\n}\n\nexport function calculateLineDistance(points: GeoPoint[]): number {\n let total = 0\n for (let i = 0; i < points.length - 1; i += 1) {\n total += calculateGeodesicDistance(points[i], points[i + 1])\n }\n return total\n}\n","import type { TualAnnotationTheme, ScreenPoint } from '../types/index.js'\nimport { truncateTualText } from './geo.js'\n\nexport function drawTualHandle(\n ctx: CanvasRenderingContext2D,\n pt: ScreenPoint,\n strokeColor: string,\n fillColor: string,\n radius: number,\n strokeWidth = 2,\n) {\n ctx.save()\n ctx.beginPath()\n ctx.arc(pt.x, pt.y, radius, 0, Math.PI * 2)\n ctx.fillStyle = fillColor\n ctx.fill()\n ctx.lineWidth = strokeWidth\n ctx.strokeStyle = strokeColor\n ctx.stroke()\n ctx.restore()\n}\n\nexport function drawTualLabelPill(\n ctx: CanvasRenderingContext2D,\n label: string,\n midX: number,\n midY: number,\n strokeColor: string,\n maxAllowedBoxWidth: number,\n theme?: TualAnnotationTheme,\n) {\n ctx.save()\n ctx.font = theme?.labelFont ?? '12px system-ui, -apple-system, sans-serif'\n const padX = theme?.labelPaddingX ?? 6\n const maxTextWidth = Math.max(10, maxAllowedBoxWidth - padX * 2)\n const displayText = truncateTualText(ctx, label, maxTextWidth)\n\n if (displayText) {\n const metrics = ctx.measureText(displayText)\n const boxW = Math.round(metrics.width + padX * 2)\n const boxH = theme?.labelPaddingY ?? 18\n const boxX = Math.round(midX - boxW / 2)\n const boxY = Math.round(midY - boxH / 2)\n const borderRadius = theme?.labelBorderRadius ?? 2\n\n if (theme?.labelShadowColor) {\n ctx.shadowColor = theme.labelShadowColor\n ctx.shadowBlur = theme.labelShadowBlur ?? 3\n }\n\n ctx.fillStyle = theme?.labelBackgroundColor ?? '#ffffff'\n ctx.strokeStyle = theme?.labelBorderColor ?? strokeColor\n ctx.lineWidth = theme?.labelBorderWidth ?? 1\n ctx.beginPath()\n if (typeof ctx.roundRect === 'function') {\n ctx.roundRect(boxX, boxY, boxW, boxH, borderRadius)\n } else {\n ctx.rect(boxX, boxY, boxW, boxH)\n }\n ctx.fill()\n ctx.stroke()\n\n ctx.fillStyle = theme?.labelTextColor ?? '#000000'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(displayText, midX, midY)\n }\n ctx.restore()\n}\n\n","import type { ArrowItem, ScreenPoint } from '../../types/index.js'\nimport type { ProjectedArrow } from './render-arrow.js'\n\nexport function drawArrowHead(\n ctx: CanvasRenderingContext2D,\n tip: ScreenPoint,\n angle: number,\n size: number,\n color: string,\n filled = true,\n) {\n const spread = Math.PI / 6.5\n const x1 = tip.x - size * Math.cos(angle - spread)\n const y1 = tip.y - size * Math.sin(angle - spread)\n const x2 = tip.x - size * Math.cos(angle + spread)\n const y2 = tip.y - size * Math.sin(angle + spread)\n\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(tip.x, tip.y)\n ctx.lineTo(x1, y1)\n if (filled) {\n ctx.lineTo(x2, y2)\n ctx.closePath()\n ctx.fillStyle = color\n ctx.fill()\n } else {\n ctx.moveTo(tip.x, tip.y)\n ctx.lineTo(x2, y2)\n ctx.strokeStyle = color\n ctx.lineWidth = Math.max(2, size / 4.5)\n ctx.lineCap = 'round'\n ctx.stroke()\n }\n ctx.restore()\n}\n\nexport function traceArrowPath(\n ctx: CanvasRenderingContext2D,\n projected: ProjectedArrow,\n arrowStyle: ArrowItem['arrowStyle'],\n) {\n const { start, end, control } = projected\n ctx.moveTo(start.x, start.y)\n if (arrowStyle === 'curved') {\n ctx.quadraticCurveTo(control.x, control.y, end.x, end.y)\n } else if (arrowStyle === 'elbow') {\n ctx.lineTo(control.x, start.y)\n ctx.lineTo(control.x, end.y)\n ctx.lineTo(end.x, end.y)\n } else if (arrowStyle === 's-curve') {\n const dx = end.x - start.x\n const dy = end.y - start.y\n ctx.bezierCurveTo(start.x + dx * 0.5, start.y, start.x + dx * 0.5, start.y + dy, end.x, end.y)\n } else {\n ctx.lineTo(end.x, end.y)\n }\n}\n\n","import type L from 'leaflet'\nimport type { ArrowItem, ArrowRenderTheme, ScreenPoint } from '../../types/index.js'\nimport {\n computeDefaultControlGeoPoint,\n distanceToQuadraticBezier,\n distanceToSegment,\n geoToScreen,\n getQuadraticBezierPoint,\n getQuadraticEndAngle,\n} from '../../shared/geo.js'\nimport { drawTualHandle, drawTualLabelPill } from '../../shared/tual-render.js'\nimport { drawArrowHead, traceArrowPath } from './arrow-geometry.js'\n\nexport type ArrowHandleType = 'start' | 'end' | 'control'\n\nexport interface ProjectedArrow {\n start: ScreenPoint\n end: ScreenPoint\n control: ScreenPoint\n}\n\nexport function projectArrow(map: L.Map, arrow: ArrowItem): ProjectedArrow {\n const start = geoToScreen(map, arrow.start)\n const end = geoToScreen(map, arrow.end)\n const needsOffsetControl =\n arrow.arrowStyle === 'curved' || arrow.arrowStyle === 's-curve'\n const controlGeo = arrow.controlPoint\n ? arrow.controlPoint\n : needsOffsetControl\n ? computeDefaultControlGeoPoint(arrow.start, arrow.end)\n : {\n lat: (arrow.start.lat + arrow.end.lat) / 2,\n lng: (arrow.start.lng + arrow.end.lng) / 2,\n }\n const control = geoToScreen(map, controlGeo)\n return { start, end, control }\n}\n\nexport function renderArrowOnCanvas(\n ctx: CanvasRenderingContext2D,\n projected: ProjectedArrow,\n arrow: Pick<\n ArrowItem,\n 'arrowStyle' | 'color' | 'strokeWidth' | 'dashed' | 'headStyle' | 'label'\n >,\n options: {\n isSelected?: boolean\n isPreview?: boolean\n theme?: ArrowRenderTheme\n } = {},\n) {\n const { start, end, control } = projected\n const dist = Math.hypot(end.x - start.x, end.y - start.y)\n if (dist < 2) return\n\n const theme = options.theme\n const headSize = Math.max(12, arrow.strokeWidth * 3.8)\n\n let endAngle = Math.atan2(end.y - start.y, end.x - start.x)\n let startAngle = Math.atan2(start.y - end.y, start.x - end.x)\n\n if (arrow.arrowStyle === 'curved') {\n endAngle = getQuadraticEndAngle(start, control, end)\n startAngle = getQuadraticEndAngle(end, control, start)\n } else if (arrow.arrowStyle === 'elbow') {\n const dx = end.x - control.x\n const dy = end.y - start.y\n endAngle = Math.abs(dx) > 1 ? Math.atan2(0, dx) : Math.atan2(dy, 0)\n const sdx = start.x - control.x\n startAngle = Math.abs(sdx) > 1 ? Math.atan2(0, sdx) : Math.atan2(-dy, 0)\n } else if (arrow.arrowStyle === 's-curve') {\n const dx = end.x - start.x\n endAngle = getQuadraticEndAngle(start, { x: start.x + dx * 0.5, y: end.y }, end)\n }\n\n ctx.save()\n if (options.isPreview) ctx.globalAlpha = 0.85\n\n if (options.isSelected) {\n ctx.save()\n ctx.beginPath()\n traceArrowPath(ctx, projected, arrow.arrowStyle)\n ctx.strokeStyle = theme?.selectionGlowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.lineWidth = arrow.strokeWidth + (theme?.selectionGlowWidth ?? 6)\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.stroke()\n ctx.restore()\n }\n\n ctx.save()\n ctx.shadowColor = theme?.shadowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.shadowBlur = theme?.shadowBlur ?? 3\n ctx.shadowOffsetY = theme?.shadowOffsetY ?? 1.5\n\n ctx.beginPath()\n traceArrowPath(ctx, projected, arrow.arrowStyle)\n ctx.strokeStyle = arrow.color\n ctx.lineWidth = arrow.strokeWidth\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n const isDashed = Boolean(arrow.dashed || (arrow.arrowStyle as string) === 'dashed')\n ctx.setLineDash(isDashed ? [arrow.strokeWidth * 3, arrow.strokeWidth * 2] : [])\n ctx.stroke()\n\n const headStyle = arrow.headStyle ?? (arrow.arrowStyle === 'bi' ? 'both' : 'triangle')\n if (headStyle !== 'none') {\n drawArrowHead(ctx, end, endAngle, headSize, arrow.color, headStyle !== 'open')\n if (headStyle === 'both') {\n drawArrowHead(ctx, start, startAngle, headSize, arrow.color, true)\n }\n }\n ctx.restore()\n\n if (arrow.label) {\n const minArrowSize = typeof theme?.labelMinShapeSize === 'number' ? theme.labelMinShapeSize : 24\n if (minArrowSize <= 0 || dist >= minArrowSize) {\n const rawMid =\n arrow.arrowStyle === 'curved'\n ? getQuadraticBezierPoint(start, control, end, 0.5)\n : arrow.arrowStyle === 'elbow'\n ? { x: control.x, y: (start.y + end.y) / 2 }\n : { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 }\n const fitToShape = theme?.fitLabelsToShape !== false\n const maxW = theme?.labelMaxTextWidth ?? (fitToShape ? Math.max(48, Math.min(280, dist * 1.6)) : Infinity)\n drawTualLabelPill(ctx, arrow.label, Math.round(rawMid.x), Math.round(rawMid.y), arrow.color, maxW, theme)\n }\n }\n\n if (options.isSelected) {\n const handleRadius = theme?.handleRadius ?? 5\n const fill = theme?.handleFillColor ?? '#ffffff'\n const endpointColor = theme?.endpointHandleColor ?? '#4f4f4f'\n const controlColor = theme?.controlHandleColor ?? '#767676'\n const strokeWidth = theme?.handleStrokeWidth ?? 2\n\n if (arrow.arrowStyle === 'curved' || arrow.arrowStyle === 'elbow') {\n ctx.save()\n ctx.beginPath()\n ctx.setLineDash(theme?.guideLineDash ? [...theme.guideLineDash] : [4, 4])\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(control.x, control.y)\n ctx.lineTo(end.x, end.y)\n ctx.strokeStyle = theme?.guideLineColor ?? 'rgba(100, 100, 100, 0.6)'\n ctx.lineWidth = theme?.guideLineWidth ?? 1.2\n ctx.stroke()\n ctx.restore()\n drawTualHandle(ctx, control, controlColor, fill, handleRadius + 0.5, strokeWidth)\n }\n drawTualHandle(ctx, start, endpointColor, fill, handleRadius, strokeWidth)\n drawTualHandle(ctx, end, endpointColor, fill, handleRadius, strokeWidth)\n }\n\n ctx.restore()\n}\n\nexport function hitTestArrowHandle(\n point: ScreenPoint,\n projected: ProjectedArrow,\n arrow: ArrowItem,\n tolerance = 11,\n): ArrowHandleType | null {\n if (Math.hypot(point.x - projected.end.x, point.y - projected.end.y) <= tolerance) return 'end'\n if (Math.hypot(point.x - projected.start.x, point.y - projected.start.y) <= tolerance) return 'start'\n if (\n (arrow.arrowStyle === 'curved' || arrow.arrowStyle === 'elbow') &&\n Math.hypot(point.x - projected.control.x, point.y - projected.control.y) <= tolerance\n ) {\n return 'control'\n }\n return null\n}\n\nexport function hitTestArrow(\n point: ScreenPoint,\n projected: ProjectedArrow,\n arrow: ArrowItem,\n tolerance = 9,\n): boolean {\n const hitThreshold = Math.max(tolerance, arrow.strokeWidth / 2 + 6)\n if (arrow.arrowStyle === 'curved') {\n return distanceToQuadraticBezier(point, projected.start, projected.control, projected.end) <= hitThreshold\n }\n if (arrow.arrowStyle === 'elbow') {\n const c1 = { x: projected.control.x, y: projected.start.y }\n const c2 = { x: projected.control.x, y: projected.end.y }\n return (\n distanceToSegment(point, projected.start, c1) <= hitThreshold ||\n distanceToSegment(point, c1, c2) <= hitThreshold ||\n distanceToSegment(point, c2, projected.end) <= hitThreshold\n )\n }\n return distanceToSegment(point, projected.start, projected.end) <= hitThreshold\n}\n","import type L from 'leaflet'\nimport type {\n TualAnnotationTheme,\n FreeDrawItem,\n ScreenPoint,\n} from '../../types/index.js'\nimport { distanceToSegment, geoToScreen } from '../../shared/geo.js'\n\nexport function projectFreeDraw(\n map: L.Map,\n item: Pick<FreeDrawItem, 'points'>,\n): ScreenPoint[] {\n return item.points.map((pt) => geoToScreen(map, pt))\n}\n\nfunction traceSmoothPolyline(\n ctx: CanvasRenderingContext2D,\n points: ScreenPoint[],\n) {\n if (points.length === 0) return\n ctx.moveTo(points[0].x, points[0].y)\n\n if (points.length === 1) {\n ctx.lineTo(points[0].x + 0.5, points[0].y + 0.5)\n return\n }\n\n if (points.length === 2) {\n ctx.lineTo(points[1].x, points[1].y)\n return\n }\n\n for (let i = 1; i < points.length - 1; i += 1) {\n const midX = (points[i].x + points[i + 1].x) / 2\n const midY = (points[i].y + points[i + 1].y) / 2\n ctx.quadraticCurveTo(points[i].x, points[i].y, midX, midY)\n }\n\n const last = points[points.length - 1]\n ctx.lineTo(last.x, last.y)\n}\n\nexport function renderFreeDrawOnCanvas(\n ctx: CanvasRenderingContext2D,\n screenPoints: ScreenPoint[],\n item: Pick<FreeDrawItem, 'color' | 'strokeWidth' | 'dashed'>,\n options: {\n isSelected?: boolean\n isPreview?: boolean\n theme?: TualAnnotationTheme\n } = {},\n) {\n if (screenPoints.length === 0) return\n\n const theme = options.theme\n ctx.save()\n\n if (options.isPreview) {\n ctx.globalAlpha = 0.9\n }\n\n if (options.isSelected) {\n ctx.save()\n ctx.beginPath()\n traceSmoothPolyline(ctx, screenPoints)\n ctx.strokeStyle = theme?.selectionGlowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.lineWidth = item.strokeWidth + (theme?.selectionGlowWidth ?? 6)\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.stroke()\n ctx.restore()\n }\n\n ctx.save()\n ctx.shadowColor = theme?.shadowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.shadowBlur = theme?.shadowBlur ?? 3\n ctx.shadowOffsetY = theme?.shadowOffsetY ?? 1\n\n ctx.beginPath()\n traceSmoothPolyline(ctx, screenPoints)\n ctx.strokeStyle = item.color\n ctx.lineWidth = item.strokeWidth\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n if (item.dashed) {\n ctx.setLineDash([item.strokeWidth * 3, item.strokeWidth * 2])\n } else {\n ctx.setLineDash([])\n }\n ctx.stroke()\n ctx.restore()\n\n ctx.restore()\n}\n\nexport function hitTestFreeDraw(\n point: ScreenPoint,\n screenPoints: ScreenPoint[],\n item: FreeDrawItem,\n tolerance = 9,\n): boolean {\n if (screenPoints.length === 0) return false\n const threshold = Math.max(tolerance, item.strokeWidth / 2 + 6)\n if (screenPoints.length === 1) {\n return (\n Math.hypot(point.x - screenPoints[0].x, point.y - screenPoints[0].y) <=\n threshold\n )\n }\n\n // Fast bounding box check before segment iteration\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (let i = 0; i < screenPoints.length; i += 1) {\n const p = screenPoints[i]\n if (p.x < minX) minX = p.x\n if (p.y < minY) minY = p.y\n if (p.x > maxX) maxX = p.x\n if (p.y > maxY) maxY = p.y\n }\n if (\n point.x < minX - threshold ||\n point.x > maxX + threshold ||\n point.y < minY - threshold ||\n point.y > maxY + threshold\n ) {\n return false\n }\n\n for (let i = 0; i < screenPoints.length - 1; i += 1) {\n if (\n distanceToSegment(point, screenPoints[i], screenPoints[i + 1]) <=\n threshold\n ) {\n return true\n }\n }\n return false\n}\n\n","import type {\n TualAnnotationTheme,\n ShapeKind,\n} from '../../types/index.js'\nimport type { ProjectedShape } from './render-shape.js'\n\nexport function tracePolygonShape(\n ctx: CanvasRenderingContext2D,\n proj: ProjectedShape,\n kind: ShapeKind,\n theme?: TualAnnotationTheme,\n) {\n const { minX, minY, maxX, maxY, width, height, cx, cy } = proj\n\n if (kind === 'square') {\n const radius = theme?.shapeBorderRadius ?? 0\n if (radius > 0 && typeof ctx.roundRect === 'function') {\n ctx.roundRect(minX, minY, width, height, radius)\n } else {\n ctx.rect(minX, minY, width, height)\n }\n return\n }\n\n if (kind === 'circle') {\n ctx.ellipse(cx, cy, width / 2, height / 2, 0, 0, Math.PI * 2)\n return\n }\n\n if (kind === 'triangle') {\n ctx.moveTo(cx, minY)\n ctx.lineTo(maxX, maxY)\n ctx.lineTo(minX, maxY)\n ctx.closePath()\n return\n }\n\n if (kind === 'diamond') {\n ctx.moveTo(cx, minY)\n ctx.lineTo(maxX, cy)\n ctx.lineTo(cx, maxY)\n ctx.lineTo(minX, cy)\n ctx.closePath()\n return\n }\n\n if (kind === 'hexagon') {\n const rx = width / 2\n const ry = height / 2\n for (let i = 0; i < 6; i += 1) {\n const angle = (Math.PI / 3) * i - Math.PI / 6\n const px = cx + rx * Math.cos(angle)\n const py = cy + ry * Math.sin(angle)\n if (i === 0) ctx.moveTo(px, py)\n else ctx.lineTo(px, py)\n }\n ctx.closePath()\n return\n }\n\n if (kind === 'star') {\n const spikes = 5\n const outerRx = width / 2\n const outerRy = height / 2\n const innerRx = outerRx * 0.42\n const innerRy = outerRy * 0.42\n for (let i = 0; i < spikes * 2; i += 1) {\n const rx = i % 2 === 0 ? outerRx : innerRx\n const ry = i % 2 === 0 ? outerRy : innerRy\n const angle = (i * Math.PI) / spikes - Math.PI / 2\n const px = cx + rx * Math.cos(angle)\n const py = cy + ry * Math.sin(angle)\n if (i === 0) ctx.moveTo(px, py)\n else ctx.lineTo(px, py)\n }\n ctx.closePath()\n return\n }\n\n if (kind === 'marker' || (kind as string) === 'cloud') {\n const rx = width / 2\n const ry = height * 0.36\n const headCy = minY + ry\n ctx.moveTo(cx, maxY)\n ctx.bezierCurveTo(minX + width * 0.05, minY + height * 0.7, minX, minY + height * 0.5, minX, headCy)\n ctx.ellipse(cx, headCy, rx, ry, 0, Math.PI, 0, false)\n ctx.bezierCurveTo(maxX, minY + height * 0.5, maxX - width * 0.05, minY + height * 0.7, cx, maxY)\n ctx.closePath()\n\n const innerRx = rx * 0.35\n const innerRy = ry * 0.35\n if (innerRx >= 2.5 && innerRy >= 2.5) {\n ctx.moveTo(cx + innerRx, headCy)\n ctx.ellipse(cx, headCy, innerRx, innerRy, 0, Math.PI * 2, 0, true)\n ctx.closePath()\n }\n return\n }\n\n if (kind === 'actor') {\n const headRadius = Math.min(width, height) * 0.16\n const headCy = minY + headRadius + height * 0.04\n const neckY = headCy + headRadius\n const hipY = minY + height * 0.64\n const armY = minY + height * 0.42\n const armSpan = width * 0.36\n const legSpan = width * 0.32\n\n ctx.moveTo(cx + headRadius, headCy)\n ctx.arc(cx, headCy, headRadius, 0, Math.PI * 2)\n ctx.closePath()\n ctx.moveTo(cx, neckY)\n ctx.lineTo(cx, hipY)\n ctx.moveTo(cx - armSpan, armY)\n ctx.lineTo(cx + armSpan, armY)\n ctx.moveTo(cx, hipY)\n ctx.lineTo(cx - legSpan, maxY)\n ctx.moveTo(cx, hipY)\n ctx.lineTo(cx + legSpan, maxY)\n }\n}\n\n","import type L from 'leaflet'\nimport type {\n TualAnnotationTheme,\n ScreenPoint,\n ShapeItem,\n} from '../../types/index.js'\nimport { geoToScreen } from '../../shared/geo.js'\nimport { drawTualHandle, drawTualLabelPill } from '../../shared/tual-render.js'\nimport { tracePolygonShape } from './trace-shape.js'\n\nexport type ShapeHandleType = 'start' | 'end'\n\nexport interface ProjectedShape {\n start: ScreenPoint\n end: ScreenPoint\n minX: number\n minY: number\n maxX: number\n maxY: number\n width: number\n height: number\n cx: number\n cy: number\n}\n\nexport function projectShape(map: L.Map, shape: ShapeItem): ProjectedShape {\n const start = geoToScreen(map, shape.start)\n const end = geoToScreen(map, shape.end)\n const minX = Math.min(start.x, end.x)\n const minY = Math.min(start.y, end.y)\n const maxX = Math.max(start.x, end.x)\n const maxY = Math.max(start.y, end.y)\n const width = Math.max(4, maxX - minX)\n const height = Math.max(4, maxY - minY)\n return {\n start,\n end,\n minX,\n minY,\n maxX,\n maxY,\n width,\n height,\n cx: minX + width / 2,\n cy: minY + height / 2,\n }\n}\n\nexport function renderShapeOnCanvas(\n ctx: CanvasRenderingContext2D,\n projected: ProjectedShape,\n shape: Pick<\n ShapeItem,\n 'shape' | 'color' | 'fillColor' | 'filled' | 'strokeWidth' | 'dashed' | 'label'\n >,\n options: {\n isSelected?: boolean\n isPreview?: boolean\n theme?: TualAnnotationTheme\n } = {},\n) {\n if (projected.width < 4 && projected.height < 4) return\n\n const theme = options.theme\n ctx.save()\n if (options.isPreview) ctx.globalAlpha = 0.85\n\n if (options.isSelected) {\n ctx.save()\n ctx.beginPath()\n tracePolygonShape(ctx, projected, shape.shape, theme)\n ctx.strokeStyle = theme?.selectionGlowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.lineWidth = shape.strokeWidth + (theme?.selectionGlowWidth ?? 6)\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.stroke()\n ctx.restore()\n }\n\n ctx.save()\n ctx.shadowColor = theme?.shadowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.shadowBlur = theme?.shadowBlur ?? 3\n ctx.shadowOffsetY = theme?.shadowOffsetY ?? 1.5\n\n ctx.beginPath()\n tracePolygonShape(ctx, projected, shape.shape, theme)\n\n if (shape.filled) {\n const defaultFillOpacity = theme?.shapeDefaultFillOpacity ?? 0.16\n const fillHex = Math.round(Math.min(1, Math.max(0, defaultFillOpacity)) * 255)\n .toString(16)\n .padStart(2, '0')\n ctx.fillStyle = shape.fillColor ?? `${shape.color}${fillHex}`\n ctx.fill()\n }\n\n ctx.strokeStyle = shape.color\n ctx.lineWidth = shape.strokeWidth\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.setLineDash(shape.dashed ? [shape.strokeWidth * 3, shape.strokeWidth * 2] : [])\n ctx.stroke()\n ctx.restore()\n\n if (shape.label) {\n const minShapeSize = typeof theme?.labelMinShapeSize === 'number' ? theme.labelMinShapeSize : 18\n if (\n minShapeSize <= 0 ||\n (Math.max(projected.width, projected.height) >= minShapeSize &&\n projected.width >= 8 &&\n projected.height >= 8)\n ) {\n const rawLabelY = shape.shape === 'actor' ? projected.maxY + 14 : projected.cy\n const fitToShape = theme?.fitLabelsToShape !== false\n const maxW =\n theme?.labelMaxTextWidth ??\n (fitToShape ? Math.max(48, Math.min(280, projected.width * 2.2)) : Infinity)\n drawTualLabelPill(ctx, shape.label, Math.round(projected.cx), Math.round(rawLabelY), shape.color, maxW, theme)\n }\n }\n\n if (options.isSelected) {\n const handleRadius = theme?.handleRadius ?? 5\n const fill = theme?.handleFillColor ?? '#ffffff'\n const endpointColor = theme?.endpointHandleColor ?? '#4f4f4f'\n const strokeWidth = theme?.handleStrokeWidth ?? 2\n\n ctx.save()\n ctx.setLineDash(theme?.guideLineDash ? [...theme.guideLineDash] : [4, 4])\n ctx.strokeStyle = theme?.guideLineColor ?? 'rgba(100, 100, 100, 0.6)'\n ctx.lineWidth = theme?.guideLineWidth ?? 1.2\n ctx.strokeRect(projected.minX, projected.minY, projected.width, projected.height)\n ctx.restore()\n\n drawTualHandle(ctx, projected.start, endpointColor, fill, handleRadius, strokeWidth)\n drawTualHandle(ctx, projected.end, endpointColor, fill, handleRadius, strokeWidth)\n }\n\n ctx.restore()\n}\n\nexport function hitTestShapeHandle(\n point: ScreenPoint,\n projected: ProjectedShape,\n tolerance = 11,\n): ShapeHandleType | null {\n if (Math.hypot(point.x - projected.end.x, point.y - projected.end.y) <= tolerance) return 'end'\n if (Math.hypot(point.x - projected.start.x, point.y - projected.start.y) <= tolerance) return 'start'\n return null\n}\n\nexport function hitTestShape(\n point: ScreenPoint,\n projected: ProjectedShape,\n tolerance = 8,\n): boolean {\n return (\n point.x >= projected.minX - tolerance &&\n point.x <= projected.maxX + tolerance &&\n point.y >= projected.minY - tolerance &&\n point.y <= projected.maxY + tolerance\n )\n}\n","import type L from 'leaflet'\nimport type {\n TualAnnotationTheme,\n RulerItem,\n ScreenPoint,\n} from '../../types/index.js'\nimport {\n calculateGeodesicDistance,\n distanceToSegment,\n formatRealWorldDistance,\n geoToScreen,\n} from '../../shared/geo.js'\nimport {\n drawTualHandle,\n drawTualLabelPill,\n} from '../../shared/tual-render.js'\n\nexport type RulerHandleType = 'start' | 'end'\n\nexport interface ProjectedRuler {\n start: ScreenPoint\n end: ScreenPoint\n mid: ScreenPoint\n lengthPx: number\n angle: number\n}\n\nexport function projectRuler(\n map: L.Map,\n ruler: Pick<RulerItem, 'start' | 'end'>,\n): ProjectedRuler {\n const start = geoToScreen(map, ruler.start)\n const end = geoToScreen(map, ruler.end)\n const mid = { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 }\n const lengthPx = Math.hypot(end.x - start.x, end.y - start.y)\n const angle = Math.atan2(end.y - start.y, end.x - start.x)\n return { start, end, mid, lengthPx, angle }\n}\n\nexport function renderRulerOnCanvas(\n ctx: CanvasRenderingContext2D,\n projected: ProjectedRuler,\n ruler: Pick<\n RulerItem,\n 'start' | 'end' | 'color' | 'strokeWidth' | 'dashed' | 'label' | 'unit'\n >,\n options: {\n isSelected?: boolean\n isPreview?: boolean\n theme?: TualAnnotationTheme\n } = {},\n) {\n const { start, end, mid, lengthPx, angle } = projected\n if (lengthPx < 2) return\n\n const theme = options.theme\n ctx.save()\n\n if (options.isPreview) {\n ctx.globalAlpha = 0.9\n }\n\n // Selection Glow\n if (options.isSelected) {\n ctx.save()\n ctx.beginPath()\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n ctx.strokeStyle = theme?.selectionGlowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.lineWidth = ruler.strokeWidth + (theme?.selectionGlowWidth ?? 6)\n ctx.lineCap = 'round'\n ctx.stroke()\n ctx.restore()\n }\n\n // Shadow\n ctx.save()\n ctx.shadowColor = theme?.shadowColor ?? 'rgba(0, 0, 0, 0.2)'\n ctx.shadowBlur = theme?.shadowBlur ?? 3\n ctx.shadowOffsetY = theme?.shadowOffsetY ?? 1.5\n\n // Main measurement line\n ctx.beginPath()\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n ctx.strokeStyle = ruler.color\n ctx.lineWidth = ruler.strokeWidth\n ctx.lineCap = 'round'\n if (ruler.dashed) {\n ctx.setLineDash([ruler.strokeWidth * 3, ruler.strokeWidth * 2])\n } else {\n ctx.setLineDash([])\n }\n ctx.stroke()\n\n // Perpendicular end tick marks (T-caps)\n const perp = angle + Math.PI / 2\n const tickLen = Math.max(7, ruler.strokeWidth * 3.2)\n const dx = Math.cos(perp) * tickLen\n const dy = Math.sin(perp) * tickLen\n\n ctx.beginPath()\n ctx.setLineDash([])\n // Start cap\n ctx.moveTo(start.x - dx, start.y - dy)\n ctx.lineTo(start.x + dx, start.y + dy)\n // End cap\n ctx.moveTo(end.x - dx, end.y - dy)\n ctx.lineTo(end.x + dx, end.y + dy)\n ctx.stroke()\n ctx.restore()\n\n // Real world distance label badge\n const distMeters = calculateGeodesicDistance(ruler.start, ruler.end)\n const displayLabel = ruler.label\n ? ruler.label\n : formatRealWorldDistance(distMeters, ruler.unit)\n\n if (displayLabel) {\n const fitToShape = theme?.fitLabelsToShape !== false\n const maxW =\n theme?.labelMaxTextWidth ??\n (fitToShape ? Math.max(50, Math.min(300, lengthPx * 1.5)) : Infinity)\n drawTualLabelPill(\n ctx,\n displayLabel,\n Math.round(mid.x),\n Math.round(mid.y),\n ruler.color,\n maxW,\n theme,\n )\n }\n\n // Drag handles when selected\n if (options.isSelected) {\n const handleRadius = theme?.handleRadius ?? 5\n const fill = theme?.handleFillColor ?? '#ffffff'\n const endpointColor = theme?.endpointHandleColor ?? '#4f4f4f'\n const strokeWidth = theme?.handleStrokeWidth ?? 2\n\n drawTualHandle(ctx, start, endpointColor, fill, handleRadius, strokeWidth)\n drawTualHandle(ctx, end, endpointColor, fill, handleRadius, strokeWidth)\n }\n\n ctx.restore()\n}\n\nexport function hitTestRulerHandle(\n point: ScreenPoint,\n projected: ProjectedRuler,\n tolerance = 11,\n): RulerHandleType | null {\n if (Math.hypot(point.x - projected.end.x, point.y - projected.end.y) <= tolerance) {\n return 'end'\n }\n if (Math.hypot(point.x - projected.start.x, point.y - projected.start.y) <= tolerance) {\n return 'start'\n }\n return null\n}\n\nexport function hitTestRuler(\n point: ScreenPoint,\n projected: ProjectedRuler,\n ruler: RulerItem,\n tolerance = 9,\n): boolean {\n const hitThreshold = Math.max(tolerance, ruler.strokeWidth / 2 + 6)\n return distanceToSegment(point, projected.start, projected.end) <= hitThreshold\n}\n\n","import type L from 'leaflet'\nimport type { NoteItem, ScreenPoint } from '../../types/index.js'\nimport { NOTE_COLOR_THEMES } from '../../shared/constants.js'\nimport { getMapDimensions } from '../../shared/geo.js'\n\nexport interface ResolvedNoteTheme {\n name: string\n bg: string\n border: string\n header: string\n text: string\n}\n\nexport function resolveNoteTheme(backgroundColor: string): ResolvedNoteTheme {\n const matchedTheme = NOTE_COLOR_THEMES.find((t) => t.bg === backgroundColor)\n if (matchedTheme) return matchedTheme\n\n const isDarkBg =\n (backgroundColor?.startsWith('#') &&\n backgroundColor.length === 7 &&\n parseInt(backgroundColor.slice(1), 16) < 0x888888) ||\n backgroundColor === '#111827' ||\n backgroundColor === '#1e293b' ||\n backgroundColor === '#0f172a'\n\n return {\n name: 'Custom',\n bg: backgroundColor,\n border: isDarkBg ? 'rgba(255, 255, 255, 0.16)' : 'rgba(0, 0, 0, 0.12)',\n header: isDarkBg ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.06)',\n text: isDarkBg ? '#f8fafc' : '#0f172a',\n }\n}\n\nexport function clampNotePosition(\n map: L.Map,\n screenPos: ScreenPoint,\n item: NoteItem,\n isCompact: boolean,\n isDragging: boolean,\n clampToViewport = true,\n): ScreenPoint {\n const mapDims = clampToViewport !== false ? getMapDimensions(map) : null\n if (!mapDims || isDragging) return screenPos\n\n const isAnchorNearViewport =\n screenPos.x >= -120 &&\n screenPos.x <= mapDims.width + 120 &&\n screenPos.y >= -120 &&\n screenPos.y <= mapDims.height + 120\n\n if (!isAnchorNearViewport) return screenPos\n\n const cardWidth = isCompact ? 95 : (item.width ?? 230)\n const cardHeight = isCompact ? 22 : (item.height ?? 100)\n const pad = 8\n const minX = 16 + pad\n const maxX = Math.max(minX, mapDims.width - cardWidth + 16 - pad)\n const minY = 12 + pad\n const maxY = Math.max(minY, mapDims.height - cardHeight + 12 - pad)\n\n return {\n x: Math.max(minX, Math.min(maxX, screenPos.x)),\n y: Math.max(minY, Math.min(maxY, screenPos.y)),\n }\n}\n\n","import type L from 'leaflet'\nimport type { ScreenPoint, TextItem } from '../../types/index.js'\nimport { getMapDimensions } from '../../shared/geo.js'\n\nexport function clampTextPosition(\n map: L.Map,\n screenPos: ScreenPoint,\n item: TextItem,\n dynamicFontSize: number,\n isCompact: boolean,\n isDragging: boolean,\n clampToViewport = true,\n): ScreenPoint {\n const mapDims = clampToViewport !== false ? getMapDimensions(map) : null\n if (!mapDims || isDragging) return screenPos\n\n const isAnchorNearViewport =\n screenPos.x >= -100 &&\n screenPos.x <= mapDims.width + 100 &&\n screenPos.y >= -100 &&\n screenPos.y <= mapDims.height + 100\n\n if (!isAnchorNearViewport) return screenPos\n\n const approxHalfW = isCompact\n ? 35\n : Math.max(24, ((item.text || 'Text').length * dynamicFontSize) / 3.6)\n const approxHalfH = isCompact ? 11 : dynamicFontSize / 2 + 4\n const pad = 8\n\n const minX = approxHalfW + pad\n const maxX = Math.max(minX, mapDims.width - approxHalfW - pad)\n const minY = approxHalfH + pad\n const maxY = Math.max(minY, mapDims.height - approxHalfH - pad)\n\n return {\n x: Math.max(minX, Math.min(maxX, screenPos.x)),\n y: Math.max(minY, Math.min(maxY, screenPos.y)),\n }\n}\n\n","import type L from 'leaflet'\nimport type { FreeDrawItem, GeoPoint, ScreenPoint } from '../types/index.js'\nimport { createId, screenToGeo } from '../shared/index.js'\n\nexport function startFreeDrawDrag(\n map: L.Map,\n mapContainer: HTMLElement,\n pt: ScreenPoint,\n geo: GeoPoint,\n activeColor: string,\n strokeWidth: number,\n dashed: boolean,\n draftFreeDrawRef: { current: { screenPoints: ScreenPoint[]; geoPoints: GeoPoint[] } | null },\n rafIdRef: { current: number | null },\n paintCanvas: () => void,\n addItem: (item: FreeDrawItem) => void,\n setActiveTool: (tool: 'select') => void,\n) {\n draftFreeDrawRef.current = { screenPoints: [pt], geoPoints: [geo] }\n map.dragging.disable()\n paintCanvas()\n\n const handleWindowMove = (moveEvent: PointerEvent) => {\n if (!draftFreeDrawRef.current) return\n const rect = mapContainer.getBoundingClientRect()\n const currScreen = { x: moveEvent.clientX - rect.left, y: moveEvent.clientY - rect.top }\n const pts = draftFreeDrawRef.current.screenPoints\n const prevPt = pts[pts.length - 1]\n if (Math.hypot(currScreen.x - prevPt.x, currScreen.y - prevPt.y) < 2.5) return\n pts.push(currScreen)\n draftFreeDrawRef.current.geoPoints.push(screenToGeo(map, currScreen))\n\n if (rafIdRef.current === null) {\n rafIdRef.current = window.requestAnimationFrame(() => {\n rafIdRef.current = null\n paintCanvas()\n })\n }\n }\n\n const handleWindowUp = (upEvent: PointerEvent) => {\n window.removeEventListener('pointermove', handleWindowMove)\n window.removeEventListener('pointerup', handleWindowUp)\n map.dragging.enable()\n if (rafIdRef.current !== null) {\n window.cancelAnimationFrame(rafIdRef.current)\n rafIdRef.current = null\n }\n\n const draft = draftFreeDrawRef.current\n draftFreeDrawRef.current = null\n if (draft && draft.geoPoints.length >= 1) {\n addItem({\n id: createId('freedraw'),\n type: 'freedraw',\n points: draft.geoPoints,\n color: activeColor,\n strokeWidth,\n dashed,\n createdAt: Date.now(),\n })\n if (!upEvent.shiftKey) setActiveTool('select')\n } else {\n paintCanvas()\n }\n }\n\n window.addEventListener('pointermove', handleWindowMove)\n window.addEventListener('pointerup', handleWindowUp)\n}\n\n","import type L from 'leaflet'\nimport type {\n ArrowItem,\n ArrowStyle,\n DraftArrowState,\n DraftRulerState,\n DraftShapeState,\n GeoPoint,\n NoteItem,\n RulerItem,\n ScreenPoint,\n ShapeItem,\n ShapeKind,\n TextItem,\n} from '../types/index.js'\nimport {\n computeDefaultControlGeoPoint,\n constrainAngleTo45Degrees,\n constrainToAspectRatio,\n createId,\n NOTE_COLOR_THEMES,\n screenToGeo,\n} from '../shared/index.js'\n\nexport function createDraftNote(geo: GeoPoint, noteColor: string, defaultTitle = 'Field Note'): NoteItem {\n const theme = NOTE_COLOR_THEMES.find((t) => t.bg === noteColor) ?? NOTE_COLOR_THEMES[0]\n return {\n id: createId('note'),\n type: 'note',\n position: geo,\n title: defaultTitle,\n text: '',\n backgroundColor: theme.bg,\n textColor: theme.text,\n width: 230,\n createdAt: Date.now(),\n }\n}\n\nexport function createDraftText(\n geo: GeoPoint,\n activeColor: string,\n fontSize: number,\n fontWeight: 'normal' | 'bold',\n currentZoom: number,\n): TextItem {\n return {\n id: createId('text'),\n type: 'text',\n position: geo,\n text: '',\n color: activeColor,\n initialFontSize: fontSize,\n baseZoom: currentZoom,\n fontWeight,\n createdAt: Date.now(),\n }\n}\n\nexport { startFreeDrawDrag } from './freedraw-drag-handler.js'\n\nexport function startShapeDrag(\n map: L.Map,\n mapContainer: HTMLElement,\n startScreen: ScreenPoint,\n startGeo: GeoPoint,\n activeShape: ShapeKind,\n activeColor: string,\n shapeFilled: boolean,\n strokeWidth: number,\n dashed: boolean,\n setDraftShape: (draft: DraftShapeState | null) => void,\n addItem: (item: ShapeItem) => void,\n setActiveTool: (tool: 'select') => void,\n) {\n setDraftShape({ shape: activeShape, startGeo, currentGeo: startGeo })\n map.dragging.disable()\n\n const handleWindowMove = (moveEvent: PointerEvent) => {\n const rect = mapContainer.getBoundingClientRect()\n const rawScreen = { x: moveEvent.clientX - rect.left, y: moveEvent.clientY - rect.top }\n const currScreen = moveEvent.shiftKey ? constrainToAspectRatio(startScreen, rawScreen, 1) : rawScreen\n setDraftShape({ shape: activeShape, startGeo, currentGeo: screenToGeo(map, currScreen) })\n }\n\n const handleWindowUp = (upEvent: PointerEvent) => {\n window.removeEventListener('pointermove', handleWindowMove)\n window.removeEventListener('pointerup', handleWindowUp)\n map.dragging.enable()\n\n const rect = mapContainer.getBoundingClientRect()\n const rawEndScreen = { x: upEvent.clientX - rect.left, y: upEvent.clientY - rect.top }\n const endScreen = upEvent.shiftKey ? constrainToAspectRatio(startScreen, rawEndScreen, 1) : rawEndScreen\n const dragDist = Math.hypot(rawEndScreen.x - startScreen.x, rawEndScreen.y - startScreen.y)\n\n const finalStartGeo = dragDist >= 10 ? startGeo : screenToGeo(map, { x: startScreen.x - 45, y: startScreen.y - 45 })\n const finalEndGeo = dragDist >= 10 ? screenToGeo(map, endScreen) : screenToGeo(map, { x: startScreen.x + 45, y: startScreen.y + 45 })\n\n addItem({\n id: createId('shape'),\n type: 'shape',\n shape: activeShape,\n start: finalStartGeo,\n end: finalEndGeo,\n color: activeColor,\n filled: shapeFilled,\n strokeWidth,\n dashed,\n createdAt: Date.now(),\n })\n setDraftShape(null)\n setActiveTool('select')\n }\n\n window.addEventListener('pointermove', handleWindowMove)\n window.addEventListener('pointerup', handleWindowUp)\n}\n\nexport function buildArrowItem(\n arrowStyle: ArrowStyle,\n startGeo: GeoPoint,\n endGeo: GeoPoint,\n activeColor: string,\n strokeWidth: number,\n dashed: boolean,\n): ArrowItem {\n return {\n id: createId('arrow'),\n type: 'arrow',\n arrowStyle,\n start: startGeo,\n end: endGeo,\n controlPoint:\n arrowStyle === 'curved'\n ? computeDefaultControlGeoPoint(startGeo, endGeo)\n : arrowStyle === 'elbow'\n ? { lat: (startGeo.lat + endGeo.lat) / 2, lng: (startGeo.lng + endGeo.lng) / 2 }\n : undefined,\n color: activeColor,\n strokeWidth,\n dashed,\n headStyle: arrowStyle === 'bi' ? 'both' : 'triangle',\n createdAt: Date.now(),\n }\n}\n\nexport function startArrowDrag(\n map: L.Map,\n mapContainer: HTMLElement,\n startScreen: ScreenPoint,\n startGeo: GeoPoint,\n arrowStyle: ArrowStyle,\n activeColor: string,\n strokeWidth: number,\n dashed: boolean,\n setDraftArrow: (draft: DraftArrowState | null) => void,\n addItem: (item: ArrowItem) => void,\n setActiveTool: (tool: 'select') => void,\n) {\n setDraftArrow({ arrowStyle, startGeo, currentGeo: startGeo })\n map.dragging.disable()\n\n const handleWindowMove = (moveEvent: PointerEvent) => {\n const rect = mapContainer.getBoundingClientRect()\n const rawScreen = { x: moveEvent.clientX - rect.left, y: moveEvent.clientY - rect.top }\n const currScreen = moveEvent.shiftKey ? constrainAngleTo45Degrees(startScreen, rawScreen) : rawScreen\n setDraftArrow({ arrowStyle, startGeo, currentGeo: screenToGeo(map, currScreen) })\n }\n\n const handleWindowUp = (upEvent: PointerEvent) => {\n window.removeEventListener('pointermove', handleWindowMove)\n window.removeEventListener('pointerup', handleWindowUp)\n map.dragging.enable()\n\n const rect = mapContainer.getBoundingClientRect()\n const rawEndScreen = { x: upEvent.clientX - rect.left, y: upEvent.clientY - rect.top }\n const endScreen = upEvent.shiftKey ? constrainAngleTo45Degrees(startScreen, rawEndScreen) : rawEndScreen\n if (Math.hypot(rawEndScreen.x - startScreen.x, rawEndScreen.y - startScreen.y) >= 8) {\n addItem(buildArrowItem(arrowStyle, startGeo, screenToGeo(map, endScreen), activeColor, strokeWidth, dashed))\n setDraftArrow(null)\n setActiveTool('select')\n }\n }\n\n window.addEventListener('pointermove', handleWindowMove)\n window.addEventListener('pointerup', handleWindowUp)\n}\n\nexport function buildRulerItem(\n startGeo: GeoPoint,\n endGeo: GeoPoint,\n activeColor: string,\n strokeWidth: number,\n dashed: boolean,\n): RulerItem {\n return {\n id: createId('ruler'),\n type: 'ruler',\n start: startGeo,\n end: endGeo,\n color: activeColor,\n strokeWidth,\n dashed,\n unit: 'metric',\n createdAt: Date.now(),\n }\n}\n\nexport function startRulerDrag(\n map: L.Map,\n mapContainer: HTMLElement,\n startScreen: ScreenPoint,\n startGeo: GeoPoint,\n activeColor: string,\n strokeWidth: number,\n dashed: boolean,\n setDraftRuler: (draft: DraftRulerState | null) => void,\n addItem: (item: RulerItem) => void,\n setActiveTool: (tool: 'select') => void,\n) {\n setDraftRuler({ startGeo, currentGeo: startGeo })\n map.dragging.disable()\n\n const handleWindowMove = (moveEvent: PointerEvent) => {\n const rect = mapContainer.getBoundingClientRect()\n const rawScreen = { x: moveEvent.clientX - rect.left, y: moveEvent.clientY - rect.top }\n const currScreen = moveEvent.shiftKey ? constrainAngleTo45Degrees(startScreen, rawScreen) : rawScreen\n setDraftRuler({ startGeo, currentGeo: screenToGeo(map, currScreen) })\n }\n\n const handleWindowUp = (upEvent: PointerEvent) => {\n window.removeEventListener('pointermove', handleWindowMove)\n window.removeEventListener('pointerup', handleWindowUp)\n map.dragging.enable()\n\n const rect = mapContainer.getBoundingClientRect()\n const rawEndScreen = { x: upEvent.clientX - rect.left, y: upEvent.clientY - rect.top }\n const endScreen = upEvent.shiftKey ? constrainAngleTo45Degrees(startScreen, rawEndScreen) : rawEndScreen\n if (Math.hypot(rawEndScreen.x - startScreen.x, rawEndScreen.y - startScreen.y) >= 8) {\n addItem(buildRulerItem(startGeo, screenToGeo(map, endScreen), activeColor, strokeWidth, dashed))\n setDraftRuler(null)\n setActiveTool('select')\n }\n }\n\n window.addEventListener('pointermove', handleWindowMove)\n window.addEventListener('pointerup', handleWindowUp)\n}\n\n","import type L from 'leaflet'\nimport type { ArrowItem, FreeDrawItem, RulerItem, ScreenPoint, ShapeItem } from '../types/index.js'\nimport {\n constrainAngleTo45Degrees,\n constrainToAspectRatio,\n screenToGeo,\n} from '../shared/geo.js'\nimport type {\n ArrowHandleType,\n ProjectedArrow,\n ProjectedRuler,\n ProjectedShape,\n RulerHandleType,\n ShapeHandleType,\n} from '../entities/index.js'\n\nfunction bindWindowDrag(map: L.Map, onMove: (e: PointerEvent) => void) {\n map.dragging.disable()\n const onUp = () => {\n map.dragging.enable()\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n }\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n}\n\nexport function startArrowHandleDrag(\n map: L.Map,\n arrow: ArrowItem,\n projected: ProjectedArrow,\n handle: ArrowHandleType,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<ArrowItem>) => void,\n) {\n bindWindowDrag(map, (moveEvent) => {\n const rawPt = getLocalPoint(moveEvent)\n const shouldLock = moveEvent.shiftKey\n if (handle === 'start') {\n const snappedPt = shouldLock ? constrainAngleTo45Degrees(projected.end, rawPt) : rawPt\n updateItem(arrow.id, { start: screenToGeo(map, snappedPt) })\n } else if (handle === 'end') {\n const snappedPt = shouldLock ? constrainAngleTo45Degrees(projected.start, rawPt) : rawPt\n updateItem(arrow.id, { end: screenToGeo(map, snappedPt) })\n } else if (handle === 'control') {\n updateItem(arrow.id, { controlPoint: screenToGeo(map, rawPt) })\n }\n })\n}\n\nexport function startShapeHandleDrag(\n map: L.Map,\n shape: ShapeItem,\n projected: ProjectedShape,\n handle: ShapeHandleType,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<ShapeItem>) => void,\n) {\n const anchorScreen = handle === 'start' ? projected.end : projected.start\n const initialRatio = projected.width > 4 && projected.height > 4 ? projected.width / projected.height : 1\n\n bindWindowDrag(map, (moveEvent) => {\n const rawPt = getLocalPoint(moveEvent)\n const nextPt = moveEvent.shiftKey ? constrainToAspectRatio(anchorScreen, rawPt, initialRatio) : rawPt\n const nextGeo = screenToGeo(map, nextPt)\n updateItem(shape.id, handle === 'start' ? { start: nextGeo } : { end: nextGeo })\n })\n}\n\nexport function startArrowBodyDrag(\n map: L.Map,\n arrow: ArrowItem,\n projected: ProjectedArrow,\n originPt: ScreenPoint,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<ArrowItem>) => void,\n) {\n const initialStartScreen = projected.start\n const initialEndScreen = projected.end\n const initialControlScreen = projected.control\n const hadCustomControl = Boolean(arrow.controlPoint)\n\n bindWindowDrag(map, (moveEvent) => {\n const nextPt = getLocalPoint(moveEvent)\n const dx = nextPt.x - originPt.x\n const dy = nextPt.y - originPt.y\n const patch: Partial<ArrowItem> = {\n start: screenToGeo(map, { x: initialStartScreen.x + dx, y: initialStartScreen.y + dy }),\n end: screenToGeo(map, { x: initialEndScreen.x + dx, y: initialEndScreen.y + dy }),\n }\n if ((arrow.arrowStyle === 'curved' || arrow.arrowStyle === 'elbow') && hadCustomControl) {\n patch.controlPoint = screenToGeo(map, {\n x: initialControlScreen.x + dx,\n y: initialControlScreen.y + dy,\n })\n }\n updateItem(arrow.id, patch)\n })\n}\n\nexport function startShapeBodyDrag(\n map: L.Map,\n shape: ShapeItem,\n projected: ProjectedShape,\n originPt: ScreenPoint,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<ShapeItem>) => void,\n) {\n const initialStartScreen = projected.start\n const initialEndScreen = projected.end\n\n bindWindowDrag(map, (moveEvent) => {\n const nextPt = getLocalPoint(moveEvent)\n const dx = nextPt.x - originPt.x\n const dy = nextPt.y - originPt.y\n updateItem(shape.id, {\n start: screenToGeo(map, { x: initialStartScreen.x + dx, y: initialStartScreen.y + dy }),\n end: screenToGeo(map, { x: initialEndScreen.x + dx, y: initialEndScreen.y + dy }),\n })\n })\n}\n\nexport function startFreeDrawBodyDrag(\n map: L.Map,\n fd: FreeDrawItem,\n initialScreenPts: ScreenPoint[],\n originPt: ScreenPoint,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<FreeDrawItem>) => void,\n) {\n bindWindowDrag(map, (moveEvent) => {\n const nextPt = getLocalPoint(moveEvent)\n const dx = nextPt.x - originPt.x\n const dy = nextPt.y - originPt.y\n updateItem(fd.id, {\n points: initialScreenPts.map((sp) => screenToGeo(map, { x: sp.x + dx, y: sp.y + dy })),\n })\n })\n}\n\nexport function startRulerHandleDrag(\n map: L.Map,\n ruler: RulerItem,\n projected: ProjectedRuler,\n handle: RulerHandleType,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<RulerItem>) => void,\n) {\n bindWindowDrag(map, (moveEvent) => {\n const rawPt = getLocalPoint(moveEvent)\n const shouldLock = moveEvent.shiftKey\n if (handle === 'start') {\n const snappedPt = shouldLock ? constrainAngleTo45Degrees(projected.end, rawPt) : rawPt\n updateItem(ruler.id, { start: screenToGeo(map, snappedPt) })\n } else if (handle === 'end') {\n const snappedPt = shouldLock ? constrainAngleTo45Degrees(projected.start, rawPt) : rawPt\n updateItem(ruler.id, { end: screenToGeo(map, snappedPt) })\n }\n })\n}\n\nexport function startRulerBodyDrag(\n map: L.Map,\n ruler: RulerItem,\n projected: ProjectedRuler,\n originPt: ScreenPoint,\n getLocalPoint: (e: PointerEvent) => ScreenPoint,\n updateItem: (id: string, patch: Partial<RulerItem>) => void,\n) {\n const initialStartScreen = projected.start\n const initialEndScreen = projected.end\n\n bindWindowDrag(map, (moveEvent) => {\n const nextPt = getLocalPoint(moveEvent)\n const dx = nextPt.x - originPt.x\n const dy = nextPt.y - originPt.y\n updateItem(ruler.id, {\n start: screenToGeo(map, { x: initialStartScreen.x + dx, y: initialStartScreen.y + dy }),\n end: screenToGeo(map, { x: initialEndScreen.x + dx, y: initialEndScreen.y + dy }),\n })\n })\n}\n\n","import type L from 'leaflet'\nimport type {\n ArrowItem,\n ArrowRenderTheme,\n TualAnnotationTheme,\n DraftArrowState,\n DraftRulerState,\n DraftShapeState,\n FreeDrawItem,\n GeoPoint,\n RulerItem,\n ScreenPoint,\n ShapeItem,\n} from '../types/index.js'\nimport {\n projectArrow,\n projectFreeDraw,\n projectRuler,\n projectShape,\n renderArrowOnCanvas,\n renderFreeDrawOnCanvas,\n renderRulerOnCanvas,\n renderShapeOnCanvas,\n} from '../entities/index.js'\n\nexport interface PaintLeafletTualOptions {\n map: L.Map | null\n canvas: HTMLCanvasElement | null\n width: number\n height: number\n arrowItems: ArrowItem[]\n shapeItems: ShapeItem[]\n freeDrawItems: FreeDrawItem[]\n rulerItems: RulerItem[]\n selectedId: string | null\n draftShape: DraftShapeState | null\n draftArrow: DraftArrowState | null\n draftRuler?: DraftRulerState | null\n draftFreeDraw?: {\n screenPoints: ScreenPoint[]\n geoPoints: GeoPoint[]\n } | null\n activeColor: string\n strokeWidth: number\n dashed: boolean\n shapeFilled: boolean\n annotationTheme?: TualAnnotationTheme\n arrowTheme?: ArrowRenderTheme\n isReadOnly: boolean\n}\n\nexport function paintLeafletTual({\n map,\n canvas,\n width,\n height,\n arrowItems,\n shapeItems,\n freeDrawItems,\n rulerItems,\n selectedId,\n draftShape,\n draftArrow,\n draftRuler,\n draftFreeDraw,\n activeColor,\n strokeWidth,\n dashed,\n shapeFilled,\n annotationTheme,\n arrowTheme,\n isReadOnly,\n}: PaintLeafletTualOptions) {\n if (!map || !canvas || width === 0 || height === 0) return\n\n const effectiveTheme = annotationTheme ?? arrowTheme\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1\n const targetW = Math.round(width * dpr)\n const targetH = Math.round(height * dpr)\n if (canvas.width !== targetW) {\n canvas.width = targetW\n }\n if (canvas.height !== targetH) {\n canvas.height = targetH\n }\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.save()\n if (typeof ctx.scale === 'function') {\n ctx.scale(dpr, dpr)\n }\n ctx.clearRect(0, 0, width, height)\n\n for (const fd of freeDrawItems) {\n const screenPts = projectFreeDraw(map, fd)\n renderFreeDrawOnCanvas(ctx, screenPts, fd, {\n isSelected: !isReadOnly && fd.id === selectedId,\n theme: effectiveTheme,\n })\n }\n\n for (const shp of shapeItems) {\n const projected = projectShape(map, shp)\n renderShapeOnCanvas(ctx, projected, shp, {\n isSelected: !isReadOnly && shp.id === selectedId,\n theme: effectiveTheme,\n })\n }\n\n for (const arrow of arrowItems) {\n const projected = projectArrow(map, arrow)\n renderArrowOnCanvas(ctx, projected, arrow, {\n isSelected: !isReadOnly && arrow.id === selectedId,\n theme: effectiveTheme,\n })\n }\n\n for (const ruler of rulerItems) {\n const projected = projectRuler(map, ruler)\n renderRulerOnCanvas(ctx, projected, ruler, {\n isSelected: !isReadOnly && ruler.id === selectedId,\n theme: effectiveTheme,\n })\n }\n\n if (!isReadOnly && draftFreeDraw && draftFreeDraw.screenPoints.length > 0) {\n renderFreeDrawOnCanvas(\n ctx,\n draftFreeDraw.screenPoints,\n {\n color: activeColor,\n strokeWidth,\n dashed,\n },\n {\n isPreview: true,\n theme: effectiveTheme,\n },\n )\n }\n\n if (!isReadOnly && draftShape) {\n const tempShape: ShapeItem = {\n id: 'draft-shape',\n type: 'shape',\n shape: draftShape.shape,\n start: draftShape.startGeo,\n end: draftShape.currentGeo,\n color: activeColor,\n filled: shapeFilled,\n strokeWidth,\n dashed,\n createdAt: 0,\n }\n const projected = projectShape(map, tempShape)\n renderShapeOnCanvas(ctx, projected, tempShape, {\n isPreview: true,\n isSelected: true,\n theme: effectiveTheme,\n })\n }\n\n if (!isReadOnly && draftArrow) {\n const tempArrow: ArrowItem = {\n id: 'draft-arrow',\n type: 'arrow',\n arrowStyle: draftArrow.arrowStyle,\n start: draftArrow.startGeo,\n end: draftArrow.currentGeo,\n color: activeColor,\n strokeWidth,\n dashed,\n createdAt: 0,\n }\n const projected = projectArrow(map, tempArrow)\n renderArrowOnCanvas(ctx, projected, tempArrow, {\n isPreview: true,\n isSelected: true,\n theme: effectiveTheme,\n })\n }\n\n if (!isReadOnly && draftRuler) {\n const tempRuler: RulerItem = {\n id: 'draft-ruler',\n type: 'ruler',\n start: draftRuler.startGeo,\n end: draftRuler.currentGeo,\n color: activeColor,\n strokeWidth,\n dashed,\n unit: 'metric',\n createdAt: 0,\n }\n const projected = projectRuler(map, tempRuler)\n renderRulerOnCanvas(ctx, projected, tempRuler, {\n isPreview: true,\n isSelected: true,\n theme: effectiveTheme,\n })\n }\n\n ctx.restore()\n}\n\n\n","import type L from 'leaflet'\n\nexport interface MapViewportDimensions {\n width: number\n height: number\n}\n\nexport function bindLeafletSync(\n map: L.Map,\n onSync: (dimensions: MapViewportDimensions) => void,\n): () => void {\n const sync = () => {\n const size = map.getSize()\n onSync({ width: size.x, height: size.y })\n }\n\n sync()\n\n map.on('move', sync)\n map.on('zoom', sync)\n map.on('zoomanim', sync)\n map.on('viewreset', sync)\n map.on('resize', sync)\n\n return () => {\n map.off('move', sync)\n map.off('zoom', sync)\n map.off('zoomanim', sync)\n map.off('viewreset', sync)\n map.off('resize', sync)\n }\n}\n\ntype LeafletFlaggedElement = HTMLElement & { _leaflet_disable_events?: boolean }\n\nexport function bindBlockMapDblClick(map: L.Map): () => void {\n const container = map.getContainer()\n if (!container) return () => {}\n\n const handleDblClickCapture = (e: MouseEvent) => {\n const target = e.target as LeafletFlaggedElement | null\n if (\n !target?.closest?.(\n '[data-tual-overlay], input, textarea, select, button, .rlc-overlay',\n )\n ) {\n return\n }\n\n const hadFlag = Object.prototype.hasOwnProperty.call(\n target,\n '_leaflet_disable_events',\n )\n const previous = target._leaflet_disable_events\n target._leaflet_disable_events = true\n\n const wasZoomEnabled = Boolean(map.doubleClickZoom?.enabled?.())\n if (wasZoomEnabled) {\n map.doubleClickZoom.disable()\n }\n\n setTimeout(() => {\n if (hadFlag) {\n target._leaflet_disable_events = previous\n } else {\n delete target._leaflet_disable_events\n }\n if (wasZoomEnabled) {\n map.doubleClickZoom.enable()\n }\n }, 0)\n }\n\n const handleMouseDownCapture = (e: MouseEvent | TouchEvent) => {\n const target = e.target as HTMLElement | null\n if (\n target?.closest?.(\n 'textarea, input, select, button, [data-tual-note-resize], .rlc-note-resize-handle',\n )\n ) {\n if (map.dragging?.enabled?.()) {\n map.dragging.disable()\n const handleUp = () => {\n map.dragging.enable()\n window.removeEventListener('mouseup', handleUp, true)\n window.removeEventListener('touchend', handleUp, true)\n window.removeEventListener('pointerup', handleUp, true)\n }\n window.addEventListener('mouseup', handleUp, {\n capture: true,\n once: true,\n })\n window.addEventListener('touchend', handleUp, {\n capture: true,\n once: true,\n })\n window.addEventListener('pointerup', handleUp, {\n capture: true,\n once: true,\n })\n }\n }\n }\n\n container.addEventListener('dblclick', handleDblClickCapture, true)\n container.addEventListener('mousedown', handleMouseDownCapture, true)\n container.addEventListener('touchstart', handleMouseDownCapture, true)\n\n return () => {\n container.removeEventListener('dblclick', handleDblClickCapture, true)\n container.removeEventListener('mousedown', handleMouseDownCapture, true)\n container.removeEventListener('touchstart', handleMouseDownCapture, true)\n }\n}\n\n","import type {\n TualItem,\n TualTool,\n LeafletTualController,\n ShapeKind,\n UseLeafletTualOptions,\n} from '../types/index.js'\nimport {\n DEFAULT_FONT_SIZE,\n DEFAULT_NOTE_BG,\n DEFAULT_STROKE_COLOR,\n DEFAULT_STROKE_WIDTH,\n NOTE_COLOR_THEMES,\n} from '../shared/constants.js'\n\nexport interface LeafletTualStore extends LeafletTualController {\n subscribe: (listener: (controller: LeafletTualController) => void) => () => void\n getState: () => LeafletTualController\n destroy: () => void\n}\n\nexport function createLeafletTualController(\n options: UseLeafletTualOptions = {},\n): LeafletTualStore {\n const maxPast = Math.max(0, (options.maxHistory ?? 50) - 1)\n let past: TualItem[][] = []\n let present: TualItem[] = options.items ?? options.initialItems ?? []\n let future: TualItem[][] = []\n let committedItems: TualItem[] = present\n\n let activeTool: TualTool = options.initialTool ?? 'select'\n let readOnly = Boolean(options.readOnly ?? false)\n let selectedId: string | null = null\n let isEditingLabel = false\n\n let activeShape: ShapeKind = options.defaultShape ?? 'square'\n let shapeFilled = true\n let activeColor = options.defaultColor ?? DEFAULT_STROKE_COLOR\n let strokeWidth = options.defaultStrokeWidth ?? DEFAULT_STROKE_WIDTH\n let dashed = false\n let noteColor = options.defaultNoteColor ?? DEFAULT_NOTE_BG\n let fontSize = options.defaultFontSize ?? DEFAULT_FONT_SIZE\n let fontWeight: 'normal' | 'bold' = 'bold'\n\n const listeners = new Set<(controller: LeafletTualController) => void>()\n\n const notifyListeners = () => {\n for (const listener of listeners) {\n listener(store)\n }\n }\n\n const triggerChange = (next: TualItem[]) => {\n options.onItemsChange?.(next)\n options.onChange?.(next)\n }\n\n const triggerChangeComplete = (finalItems: TualItem[], targetItem?: TualItem | null) => {\n options.onItemsChangeComplete?.(finalItems, targetItem)\n options.onChangeComplete?.(finalItems, targetItem)\n options.onEditEnd?.(finalItems, targetItem)\n options.onEditComplete?.(finalItems, targetItem)\n if (targetItem) options.onItemChangeComplete?.(targetItem)\n }\n\n const commitItems = (updater: (prev: TualItem[]) => TualItem[]) => {\n const next = updater(present)\n present = next\n triggerChange(next)\n notifyListeners()\n return next\n }\n\n const notifyChangeComplete = (targetItem?: TualItem | null) => {\n if (present === committedItems) return\n const anchor = committedItems\n committedItems = present\n past = [...past, anchor].slice(-maxPast)\n future = []\n triggerChangeComplete(present, targetItem)\n notifyListeners()\n }\n\n const setSelectedId = (id: string | null) => {\n if (selectedId !== id) {\n const prev = selectedId\n selectedId = id\n isEditingLabel = false\n if (prev !== null && id === null) notifyChangeComplete()\n options.onItemSelect?.(present.find((it) => it.id === id) ?? null)\n notifyListeners()\n }\n }\n\n const setActiveTool = (tool: TualTool) => {\n if (readOnly && tool !== 'select') return\n activeTool = tool\n options.onToolChange?.(tool)\n notifyListeners()\n }\n\n const setReadOnly = (nextReadOnly: boolean) => {\n readOnly = Boolean(nextReadOnly)\n if (readOnly && activeTool !== 'select') {\n activeTool = 'select'\n }\n notifyListeners()\n }\n\n const patchSelected = (predicate: (it: TualItem) => boolean, patcher: (it: any) => any) => {\n if (!selectedId) return\n commitItems((prev) =>\n prev.map((it) => (it.id === selectedId && predicate(it) ? patcher(it) : it)),\n )\n }\n\n const setActiveShape = (shape: ShapeKind) => {\n if (readOnly) return\n activeShape = shape\n patchSelected((it) => it.type === 'shape', (it) => ({ ...it, shape }))\n notifyListeners()\n }\n\n const setShapeFilled = (filled: boolean) => {\n if (readOnly) return\n shapeFilled = filled\n patchSelected((it) => it.type === 'shape', (it) => ({ ...it, filled }))\n notifyListeners()\n }\n\n const setActiveColor = (color: string) => {\n if (readOnly) return\n activeColor = color\n patchSelected((it) => it.type !== 'note', (it) => ({ ...it, color }))\n notifyListeners()\n }\n\n const setStrokeWidth = (width: number) => {\n if (readOnly) return\n strokeWidth = width\n patchSelected(\n (it) =>\n it.type === 'arrow' ||\n it.type === 'freedraw' ||\n it.type === 'shape' ||\n it.type === 'ruler',\n (it) => ({ ...it, strokeWidth: width }),\n )\n notifyListeners()\n }\n\n const setDashed = (nextDashed: boolean) => {\n if (readOnly) return\n dashed = nextDashed\n patchSelected(\n (it) =>\n it.type === 'arrow' ||\n it.type === 'freedraw' ||\n it.type === 'shape' ||\n it.type === 'ruler',\n (it) => ({ ...it, dashed: nextDashed }),\n )\n notifyListeners()\n }\n\n const setNoteColor = (bg: string) => {\n if (readOnly) return\n noteColor = bg\n const theme = NOTE_COLOR_THEMES.find((t) => t.bg === bg)\n patchSelected(\n (it) => it.type === 'note',\n (it) => ({ ...it, backgroundColor: bg, textColor: theme?.text ?? it.textColor }),\n )\n notifyListeners()\n }\n\n const setFontSize = (size: number) => {\n if (readOnly) return\n fontSize = size\n patchSelected((it) => it.type === 'text', (it) => ({ ...it, initialFontSize: size }))\n notifyListeners()\n }\n\n const setFontWeight = (weight: 'normal' | 'bold') => {\n if (readOnly) return\n fontWeight = weight\n patchSelected((it) => it.type === 'text', (it) => ({ ...it, fontWeight: weight }))\n notifyListeners()\n }\n\n const setEditingLabel = (editing: boolean) => {\n isEditingLabel = editing\n notifyListeners()\n }\n\n const addItem = (item: TualItem) => {\n if (readOnly) return\n commitItems((prev) => [...prev, item])\n setSelectedId(item.id)\n options.onItemCreate?.(item)\n }\n\n const updateItem = (id: string, patch: Partial<TualItem>) => {\n if (readOnly) {\n const patchKeys = Object.keys(patch)\n if (patchKeys.length !== 1 || patchKeys[0] !== 'minimized') return\n }\n let updated: TualItem | undefined\n commitItems((prev) =>\n prev.map((item) => {\n if (item.id === id) {\n updated = { ...item, ...patch } as TualItem\n return updated\n }\n return item\n }),\n )\n if (updated) options.onItemChange?.(updated)\n }\n\n const removeItem = (id: string) => {\n if (readOnly) return\n commitItems((prev) => prev.filter((item) => item.id !== id))\n if (selectedId === id) setSelectedId(null)\n options.onItemDelete?.(id)\n notifyChangeComplete()\n }\n\n const deleteSelected = () => {\n if (!readOnly && selectedId) removeItem(selectedId)\n }\n\n const clearAll = () => {\n if (readOnly) return\n commitItems(() => [])\n setSelectedId(null)\n notifyChangeComplete()\n }\n\n const undo = () => {\n if (readOnly || past.length === 0) return\n const restored = past[past.length - 1]\n future = [present, ...future]\n past = past.slice(0, -1)\n present = restored\n committedItems = restored\n triggerChange(restored)\n triggerChangeComplete(restored, null)\n notifyListeners()\n }\n\n const redo = () => {\n if (readOnly || future.length === 0) return\n const next = future[0]\n past = [...past, present]\n future = future.slice(1)\n present = next\n committedItems = next\n triggerChange(next)\n triggerChangeComplete(next, null)\n notifyListeners()\n }\n\n const exportJSON = () => JSON.stringify(present, null, 2)\n\n const importJSON = (json: string): boolean => {\n if (readOnly) return false\n try {\n const parsed = JSON.parse(json)\n if (!Array.isArray(parsed)) return false\n commitItems(() => parsed as TualItem[])\n setSelectedId(null)\n notifyChangeComplete()\n return true\n } catch {\n return false\n }\n }\n\n const store: LeafletTualStore = {\n get items() {\n return present\n },\n get activeTool() {\n return activeTool\n },\n setActiveTool,\n get readOnly() {\n return readOnly\n },\n setReadOnly,\n get activeShape() {\n return activeShape\n },\n setActiveShape,\n get shapeFilled() {\n return shapeFilled\n },\n setShapeFilled,\n get selectedId() {\n return selectedId\n },\n setSelectedId,\n get selectedItem() {\n return present.find((it) => it.id === selectedId) ?? null\n },\n get isEditingLabel() {\n return isEditingLabel\n },\n setEditingLabel,\n get labelEditMode() {\n return isEditingLabel\n },\n setLabelEditMode: setEditingLabel,\n get activeColor() {\n return activeColor\n },\n setActiveColor,\n get strokeWidth() {\n return strokeWidth\n },\n setStrokeWidth,\n get dashed() {\n return dashed\n },\n setDashed,\n get noteColor() {\n return noteColor\n },\n setNoteColor,\n get fontSize() {\n return fontSize\n },\n setFontSize,\n get fontWeight() {\n return fontWeight\n },\n setFontWeight,\n addItem,\n updateItem,\n removeItem,\n deleteSelected,\n clearAll,\n clear: clearAll,\n deleteItem: removeItem,\n setTool: setActiveTool,\n selectItem: setSelectedId,\n undo,\n redo,\n get canUndo() {\n return !readOnly && past.length > 0\n },\n get canRedo() {\n return !readOnly && future.length > 0\n },\n notifyChangeComplete,\n exportJSON,\n importJSON,\n subscribe(listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n getState() {\n return store\n },\n destroy() {\n listeners.clear()\n },\n }\n\n return store\n}\n\n\n","import type L from 'leaflet'\nimport type {\n ArrowItem,\n ArrowRenderTheme,\n TualAnnotationTheme,\n TualLabels,\n DraftArrowState,\n DraftRulerState,\n DraftShapeState,\n FreeDrawItem,\n GeoPoint,\n RulerItem,\n ScreenPoint,\n ShapeItem,\n UseLeafletTualOptions,\n} from '../types/index.js'\nimport {\n constrainAngleTo45Degrees,\n geoToScreen,\n screenToGeo,\n TOOL_TO_ARROW_STYLE,\n} from '../shared/index.js'\nimport {\n hitTestArrow,\n hitTestArrowHandle,\n hitTestFreeDraw,\n hitTestRuler,\n hitTestRulerHandle,\n hitTestShape,\n hitTestShapeHandle,\n projectArrow,\n projectFreeDraw,\n projectRuler,\n projectShape,\n} from '../entities/index.js'\nimport {\n buildArrowItem,\n createDraftNote,\n createDraftText,\n startArrowDrag,\n startFreeDrawDrag,\n startRulerDrag,\n startShapeDrag,\n} from './drawing-drag-handlers.js'\nimport {\n startArrowBodyDrag,\n startArrowHandleDrag,\n startFreeDrawBodyDrag,\n startRulerBodyDrag,\n startRulerHandleDrag,\n startShapeBodyDrag,\n startShapeHandleDrag,\n} from './select-drag-handlers.js'\nimport { paintLeafletTual } from './tual-painter.js'\nimport { bindBlockMapDblClick, bindLeafletSync } from './map-sync.js'\nimport {\n createLeafletTualController,\n type LeafletTualStore,\n} from './tual-controller.js'\n\nexport interface CreateLeafletTualOptions extends UseLeafletTualOptions {\n controller?: LeafletTualStore\n annotationTheme?: TualAnnotationTheme\n arrowTheme?: ArrowRenderTheme\n labels?: TualLabels\n}\n\nexport interface LeafletTualInstance {\n controller: LeafletTualStore\n container: HTMLDivElement\n canvas: HTMLCanvasElement\n repaint: () => void\n destroy: () => void\n}\n\nexport function createLeafletTual(\n map: L.Map,\n options: CreateLeafletTualOptions = {},\n): LeafletTualInstance {\n const {\n controller: externalController,\n annotationTheme,\n arrowTheme,\n labels,\n zIndex = 650,\n ...controllerOptions\n } = options\n\n const controller = externalController ?? createLeafletTualController(controllerOptions)\n const mapContainer = map.getContainer()\n\n const container = document.createElement('div')\n container.setAttribute('data-tual-overlay', 'true')\n container.style.position = 'absolute'\n container.style.inset = '0'\n container.style.pointerEvents = 'none'\n container.style.zIndex = String(zIndex)\n container.style.overflow = 'hidden'\n\n const canvas = document.createElement('canvas')\n canvas.style.position = 'absolute'\n canvas.style.top = '0'\n canvas.style.left = '0'\n canvas.style.pointerEvents = 'none'\n\n const drawingSurface = document.createElement('div')\n drawingSurface.style.position = 'absolute'\n drawingSurface.style.inset = '0'\n drawingSurface.style.pointerEvents = 'none'\n\n container.appendChild(canvas)\n container.appendChild(drawingSurface)\n mapContainer.appendChild(container)\n\n let viewport = { width: 0, height: 0 }\n let draftArrow: DraftArrowState | null = null\n let draftShape: DraftShapeState | null = null\n let draftRuler: DraftRulerState | null = null\n const draftFreeDrawRef: {\n current: { screenPoints: ScreenPoint[]; geoPoints: GeoPoint[] } | null\n } = { current: null }\n const rafIdRef: { current: number | null } = { current: null }\n\n const setDraftArrow = (next: DraftArrowState | null) => {\n draftArrow = next\n repaint()\n }\n\n const setDraftShape = (next: DraftShapeState | null) => {\n draftShape = next\n repaint()\n }\n\n const setDraftRuler = (next: DraftRulerState | null) => {\n draftRuler = next\n repaint()\n }\n\n const clearDraftFreeDraw = () => {\n draftFreeDrawRef.current = null\n if (rafIdRef.current !== null && typeof window !== 'undefined') {\n window.cancelAnimationFrame(rafIdRef.current)\n rafIdRef.current = null\n }\n }\n\n const updateSurfaceInteractivity = () => {\n const isDrawing = !controller.readOnly && controller.activeTool !== 'select'\n drawingSurface.style.pointerEvents = isDrawing ? 'auto' : 'none'\n drawingSurface.style.cursor = isDrawing ? 'crosshair' : 'default'\n canvas.style.width = `${viewport.width}px`\n canvas.style.height = `${viewport.height}px`\n }\n\n const repaint = () => {\n updateSurfaceInteractivity()\n const items = controller.items\n paintLeafletTual({\n map,\n canvas,\n width: viewport.width,\n height: viewport.height,\n arrowItems: items.filter((it): it is ArrowItem => it.type === 'arrow'),\n shapeItems: items.filter((it): it is ShapeItem => it.type === 'shape'),\n freeDrawItems: items.filter((it): it is FreeDrawItem => it.type === 'freedraw'),\n rulerItems: items.filter((it): it is RulerItem => it.type === 'ruler'),\n selectedId: controller.selectedId,\n draftShape,\n draftArrow,\n draftRuler,\n draftFreeDraw: draftFreeDrawRef.current,\n activeColor: controller.activeColor,\n strokeWidth: controller.strokeWidth,\n dashed: controller.dashed,\n shapeFilled: controller.shapeFilled,\n annotationTheme,\n arrowTheme,\n isReadOnly: controller.readOnly,\n })\n }\n\n const getLocalPoint = (e: PointerEvent | MouseEvent): ScreenPoint => {\n const rect = mapContainer.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n\n const handleSurfacePointerDown = (e: PointerEvent) => {\n if (e.button !== 0 || controller.readOnly) return\n e.stopPropagation()\n e.preventDefault()\n\n const pt = getLocalPoint(e)\n const geo = screenToGeo(map, pt)\n const { activeTool, activeShape, shapeFilled, activeColor, strokeWidth, dashed, noteColor, fontSize, fontWeight } =\n controller\n\n if (activeTool === 'freedraw') {\n startFreeDrawDrag(\n map,\n mapContainer,\n pt,\n geo,\n activeColor,\n strokeWidth,\n dashed,\n draftFreeDrawRef,\n rafIdRef,\n repaint,\n controller.addItem,\n controller.setActiveTool,\n )\n return\n }\n\n if (activeTool === 'shape') {\n startShapeDrag(\n map,\n mapContainer,\n pt,\n geo,\n activeShape,\n activeColor,\n shapeFilled,\n strokeWidth,\n dashed,\n setDraftShape,\n controller.addItem,\n controller.setActiveTool,\n )\n return\n }\n\n if (activeTool === 'note') {\n controller.addItem(createDraftNote(geo, noteColor, labels?.noteDefaultTitle ?? 'Field Note'))\n controller.setActiveTool('select')\n return\n }\n\n if (activeTool === 'text') {\n controller.addItem(\n createDraftText(geo, activeColor, fontSize, fontWeight, map.getZoom?.() ?? 14),\n )\n controller.setActiveTool('select')\n return\n }\n\n if (activeTool === 'ruler') {\n startRulerDrag(\n map,\n mapContainer,\n pt,\n geo,\n activeColor,\n strokeWidth,\n dashed,\n setDraftRuler,\n controller.addItem,\n controller.setActiveTool,\n )\n return\n }\n\n const arrowStyle = TOOL_TO_ARROW_STYLE[activeTool]\n if (!arrowStyle) return\n\n if (!draftArrow) {\n startArrowDrag(\n map,\n mapContainer,\n pt,\n geo,\n arrowStyle,\n activeColor,\n strokeWidth,\n dashed,\n setDraftArrow,\n controller.addItem,\n controller.setActiveTool,\n )\n } else {\n const startScreen = geoToScreen(map, draftArrow.startGeo)\n const endScreen = e.shiftKey ? constrainAngleTo45Degrees(startScreen, pt) : pt\n if (Math.hypot(endScreen.x - startScreen.x, endScreen.y - startScreen.y) >= 4) {\n controller.addItem(\n buildArrowItem(\n draftArrow.arrowStyle,\n draftArrow.startGeo,\n screenToGeo(map, endScreen),\n activeColor,\n strokeWidth,\n dashed,\n ),\n )\n }\n setDraftArrow(null)\n controller.setActiveTool('select')\n }\n }\n\n const handleSurfacePointerMove = (e: PointerEvent) => {\n if (!draftArrow) return\n const rawPt = getLocalPoint(e)\n const startScreen = geoToScreen(map, draftArrow.startGeo)\n const nextPt = e.shiftKey ? constrainAngleTo45Degrees(startScreen, rawPt) : rawPt\n setDraftArrow({ ...draftArrow, currentGeo: screenToGeo(map, nextPt) })\n }\n\n const handleContainerPointerDown = (e: PointerEvent) => {\n if (e.button !== 0 || controller.readOnly || controller.activeTool !== 'select') return\n const target = e.target as HTMLElement | null\n if (target?.closest('[data-tual-toolbar], [data-tual-note], [data-tual-text], .leaflet-control')) {\n return\n }\n\n const pt = getLocalPoint(e)\n const items = controller.items\n const arrowItems = items.filter((it): it is ArrowItem => it.type === 'arrow')\n const shapeItems = items.filter((it): it is ShapeItem => it.type === 'shape')\n const freeDrawItems = items.filter((it): it is FreeDrawItem => it.type === 'freedraw')\n const rulerItems = items.filter((it): it is RulerItem => it.type === 'ruler')\n const selectedId = controller.selectedId\n\n const selectedArrow = arrowItems.find((a) => a.id === selectedId)\n if (selectedArrow) {\n const projected = projectArrow(map, selectedArrow)\n const handle = hitTestArrowHandle(pt, projected, selectedArrow)\n if (handle) {\n e.stopPropagation()\n e.preventDefault()\n startArrowHandleDrag(map, selectedArrow, projected, handle, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n const selectedShape = shapeItems.find((s) => s.id === selectedId)\n if (selectedShape) {\n const projected = projectShape(map, selectedShape)\n const handle = hitTestShapeHandle(pt, projected)\n if (handle) {\n e.stopPropagation()\n e.preventDefault()\n startShapeHandleDrag(map, selectedShape, projected, handle, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n const selectedRuler = rulerItems.find((r) => r.id === selectedId)\n if (selectedRuler) {\n const projected = projectRuler(map, selectedRuler)\n const handle = hitTestRulerHandle(pt, projected)\n if (handle) {\n e.stopPropagation()\n e.preventDefault()\n startRulerHandleDrag(map, selectedRuler, projected, handle, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n for (let i = arrowItems.length - 1; i >= 0; i -= 1) {\n const arrow = arrowItems[i]\n const projected = projectArrow(map, arrow)\n if (hitTestArrow(pt, projected, arrow)) {\n e.stopPropagation()\n e.preventDefault()\n controller.setSelectedId(arrow.id)\n startArrowBodyDrag(map, arrow, projected, pt, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n for (let i = shapeItems.length - 1; i >= 0; i -= 1) {\n const shp = shapeItems[i]\n const projected = projectShape(map, shp)\n if (hitTestShape(pt, projected)) {\n e.stopPropagation()\n e.preventDefault()\n controller.setSelectedId(shp.id)\n startShapeBodyDrag(map, shp, projected, pt, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n for (let i = freeDrawItems.length - 1; i >= 0; i -= 1) {\n const fd = freeDrawItems[i]\n const initialScreenPts = projectFreeDraw(map, fd)\n if (hitTestFreeDraw(pt, initialScreenPts, fd)) {\n e.stopPropagation()\n e.preventDefault()\n controller.setSelectedId(fd.id)\n startFreeDrawBodyDrag(map, fd, initialScreenPts, pt, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n for (let i = rulerItems.length - 1; i >= 0; i -= 1) {\n const ruler = rulerItems[i]\n const projected = projectRuler(map, ruler)\n if (hitTestRuler(pt, projected, ruler)) {\n e.stopPropagation()\n e.preventDefault()\n controller.setSelectedId(ruler.id)\n startRulerBodyDrag(map, ruler, projected, pt, getLocalPoint, controller.updateItem)\n return\n }\n }\n\n if (selectedId) {\n controller.setSelectedId(null)\n controller.notifyChangeComplete()\n }\n }\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (controller.readOnly) return\n const target = e.target as HTMLElement | null\n if (\n target &&\n (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)\n ) {\n return\n }\n if (e.key === 'Escape') {\n draftArrow = null\n draftShape = null\n draftRuler = null\n clearDraftFreeDraw()\n controller.setSelectedId(null)\n controller.setActiveTool('select')\n controller.notifyChangeComplete()\n repaint()\n } else if ((e.key === 'Delete' || e.key === 'Backspace') && controller.selectedId) {\n e.preventDefault()\n controller.deleteSelected()\n }\n }\n\n drawingSurface.addEventListener('pointerdown', handleSurfacePointerDown)\n drawingSurface.addEventListener('pointermove', handleSurfacePointerMove)\n mapContainer.addEventListener('pointerdown', handleContainerPointerDown, { capture: true })\n if (typeof window !== 'undefined') {\n window.addEventListener('keydown', handleKeyDown)\n }\n\n const unbindSync = bindLeafletSync(map, (dims) => {\n viewport = dims\n repaint()\n })\n const unbindDblClick = bindBlockMapDblClick(map)\n const unsubscribeController = controller.subscribe(() => {\n repaint()\n })\n\n repaint()\n\n return {\n controller,\n container,\n canvas,\n repaint,\n destroy() {\n drawingSurface.removeEventListener('pointerdown', handleSurfacePointerDown)\n drawingSurface.removeEventListener('pointermove', handleSurfacePointerMove)\n mapContainer.removeEventListener('pointerdown', handleContainerPointerDown, { capture: true })\n if (typeof window !== 'undefined') {\n window.removeEventListener('keydown', handleKeyDown)\n }\n clearDraftFreeDraw()\n unbindSync()\n unbindDblClick()\n unsubscribeController()\n if (!externalController) {\n controller.destroy()\n }\n container.remove()\n },\n }\n}\n\n\n","/**\n * leaflet-tual — core (framework-agnostic)\n *\n * Interactive canvas and annotation toolkit for Leaflet maps — draw vector\n * arrows, geometric shapes, freehand sketches, rulers, sticky notes, and text\n * overlays that stay geographically synchronized with Leaflet across panning\n * and zooming.\n *\n * This module is the entire framework-agnostic public surface. It has zero\n * dependency on React or any UI framework, so it can be used directly from\n * vanilla JavaScript, TypeScript, Vue, Svelte, Angular, or a plain `<script>` tag.\n *\n * React users: see `leaflet-tual/react` for `<LeafletTual>`, `<TualToolbar>`,\n * `useLeafletTual`, and `useLeafletSync`.\n */\n\nimport pkg from '../../package.json'\n\nexport * from './types/index.js'\nexport * from './shared/index.js'\nexport * from './entities/index.js'\nexport * from './features/index.js'\n\nexport const VERSION: string = pkg.version\n\n"],"mappings":"AAAA,IAAAA,GAAA,CACE,KAAQ,eACR,QAAW,QACX,YAAe,2MACf,KAAQ,SACR,YAAe,GACf,KAAQ,mBACR,OAAU,kBACV,MAAS,oBACT,QAAW,CACT,IAAK,CACH,MAAS,oBACT,OAAU,CACR,MAAS,oBACT,QAAW,iBACb,EACA,QAAW,CACT,MAAS,qBACT,QAAW,kBACb,EACA,QAAW,iBACb,EACA,SAAU,CACR,MAAS,oBACT,OAAU,CACR,MAAS,oBACT,QAAW,iBACb,EACA,QAAW,CACT,MAAS,qBACT,QAAW,kBACb,EACA,QAAW,iBACb,EACA,UAAW,CACT,MAAS,oBACT,OAAU,CACR,MAAS,oBACT,QAAW,iBACb,EACA,QAAW,CACT,MAAS,qBACT,QAAW,kBACb,EACA,QAAW,iBACb,EACA,iBAAkB,gBACpB,EACA,MAAS,CACP,OACA,WACF,EACA,OAAU,eACV,QAAW,MACX,WAAc,CACZ,KAAQ,MACR,IAAO,uDACP,UAAa,uBACf,EACA,KAAQ,CACN,IAAO,qDACT,EACA,cAAiB,CACf,OAAU,SACV,SAAY,6BACd,EACA,SAAY,CACV,UACA,eACA,OACA,QACA,SACA,aACA,YACA,SACA,QACA,MACA,UACA,qBACA,aACA,QACA,eACF,EACA,QAAW,CACT,MAAS,OACT,IAAO,eACP,KAAQ,0BACR,UAAa,eACb,OAAU,uCACV,eAAgB,uCAChB,KAAQ,aACR,aAAc,SACd,QAAW,oBACX,QAAW,oCACb,EACA,iBAAoB,CAClB,QAAW,SACX,MAAS,qBACT,YAAa,qBACb,gBAAiB,kBACnB,EACA,qBAAwB,CACtB,MAAS,CACP,SAAY,EACd,EACA,YAAa,CACX,SAAY,EACd,EACA,gBAAiB,CACf,SAAY,EACd,CACF,EACA,gBAAmB,CACjB,kBAAmB,UACnB,uBAAwB,UACxB,yBAA0B,UAC1B,iBAAkB,UAClB,cAAe,WACf,eAAgB,UAChB,mBAAoB,UACpB,OAAU,UACV,4BAA6B,SAC7B,MAAS,UACT,QAAW,SACX,SAAY,SACZ,MAAS,UACT,YAAa,UACb,gBAAiB,SACjB,KAAQ,SACR,WAAc,SACd,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","names":["package_default","TOOL_TO_ARROW_STYLE","STROKE_COLORS","NOTE_COLOR_THEMES","DEFAULT_STROKE_COLOR","DEFAULT_STROKE_WIDTH","DEFAULT_STROKE_WIDTH_OPTIONS","STROKE_WIDTH_OPTIONS","DEFAULT_NOTE_BG","DEFAULT_NOTE_TEXT","DEFAULT_FONT_SIZE","DEFAULT_FONT_SIZE_OPTIONS","FONT_SIZE_OPTIONS","DEFAULT_ANNOTATION_THEME","idCounter","createId","prefix","randomPart","geoToScreen","map","point","containerPt","screenToGeo","latLng","constrainToAspectRatio","anchor","target","aspectRatio","safeRatio","dx","dy","absDx","absDy","signX","signY","constrainAngleTo45Degrees","dist","angle","snapStep","snappedAngle","computeDefaultControlGeoPoint","start","end","curvature","midLat","midLng","dLat","dLng","getQuadraticBezierPoint","p0","p1","p2","t","invT","getQuadraticEndAngle","distanceToSegment","p","v","w","l2","projX","projY","distanceToQuadraticBezier","steps","minDistance","prev","i","curr","getMapDimensions","size","rect","truncateTualText","ctx","text","maxWidth","ellipsis","low","high","best","mid","candidate","calculateZoomFontSize","initialFontSize","currentZoom","baseZoom","options","factor","min","max","scaled","calculateGeodesicDistance","lat1","lat2","sinDLat","sinDLng","a","formatRealWorldDistance","meters","unit","feet","miles","km","calculateLineDistance","points","total","drawTualHandle","ctx","pt","strokeColor","fillColor","radius","strokeWidth","drawTualLabelPill","label","midX","midY","maxAllowedBoxWidth","theme","padX","maxTextWidth","displayText","truncateTualText","metrics","boxW","boxH","boxX","boxY","borderRadius","drawArrowHead","ctx","tip","angle","size","color","filled","spread","x1","y1","x2","y2","traceArrowPath","projected","arrowStyle","start","end","control","dx","dy","projectArrow","map","arrow","start","geoToScreen","end","needsOffsetControl","controlGeo","computeDefaultControlGeoPoint","control","renderArrowOnCanvas","ctx","projected","options","dist","theme","headSize","endAngle","startAngle","getQuadraticEndAngle","dx","dy","sdx","traceArrowPath","isDashed","headStyle","drawArrowHead","minArrowSize","rawMid","getQuadraticBezierPoint","fitToShape","maxW","drawTualLabelPill","handleRadius","fill","endpointColor","controlColor","strokeWidth","drawTualHandle","hitTestArrowHandle","point","tolerance","hitTestArrow","hitThreshold","distanceToQuadraticBezier","c1","c2","distanceToSegment","projectFreeDraw","map","item","pt","geoToScreen","traceSmoothPolyline","ctx","points","i","midX","midY","last","renderFreeDrawOnCanvas","screenPoints","options","theme","hitTestFreeDraw","point","tolerance","threshold","minX","minY","maxX","maxY","p","distanceToSegment","tracePolygonShape","ctx","proj","kind","theme","minX","minY","maxX","maxY","width","height","cx","cy","radius","rx","ry","i","angle","px","py","outerRx","outerRy","innerRx","innerRy","headCy","headRadius","neckY","hipY","armY","armSpan","legSpan","projectShape","map","shape","start","geoToScreen","end","minX","minY","maxX","maxY","width","height","renderShapeOnCanvas","ctx","projected","options","theme","tracePolygonShape","defaultFillOpacity","fillHex","minShapeSize","rawLabelY","fitToShape","maxW","drawTualLabelPill","handleRadius","fill","endpointColor","strokeWidth","drawTualHandle","hitTestShapeHandle","point","tolerance","hitTestShape","projectRuler","map","ruler","start","geoToScreen","end","mid","lengthPx","angle","renderRulerOnCanvas","ctx","projected","options","theme","perp","tickLen","dx","dy","distMeters","calculateGeodesicDistance","displayLabel","formatRealWorldDistance","fitToShape","maxW","drawTualLabelPill","handleRadius","fill","endpointColor","strokeWidth","drawTualHandle","hitTestRulerHandle","point","tolerance","hitTestRuler","hitThreshold","distanceToSegment","resolveNoteTheme","backgroundColor","matchedTheme","NOTE_COLOR_THEMES","t","isDarkBg","clampNotePosition","map","screenPos","item","isCompact","isDragging","clampToViewport","mapDims","getMapDimensions","cardWidth","cardHeight","pad","minX","maxX","minY","maxY","clampTextPosition","map","screenPos","item","dynamicFontSize","isCompact","isDragging","clampToViewport","mapDims","getMapDimensions","approxHalfW","approxHalfH","pad","minX","maxX","minY","maxY","startFreeDrawDrag","map","mapContainer","pt","geo","activeColor","strokeWidth","dashed","draftFreeDrawRef","rafIdRef","paintCanvas","addItem","setActiveTool","handleWindowMove","moveEvent","rect","currScreen","pts","prevPt","screenToGeo","handleWindowUp","upEvent","draft","createId","createDraftNote","geo","noteColor","defaultTitle","theme","NOTE_COLOR_THEMES","t","createId","createDraftText","activeColor","fontSize","fontWeight","currentZoom","startShapeDrag","map","mapContainer","startScreen","startGeo","activeShape","shapeFilled","strokeWidth","dashed","setDraftShape","addItem","setActiveTool","handleWindowMove","moveEvent","rect","rawScreen","currScreen","constrainToAspectRatio","screenToGeo","handleWindowUp","upEvent","rawEndScreen","endScreen","dragDist","finalStartGeo","finalEndGeo","buildArrowItem","arrowStyle","endGeo","computeDefaultControlGeoPoint","startArrowDrag","setDraftArrow","constrainAngleTo45Degrees","buildRulerItem","startRulerDrag","setDraftRuler","bindWindowDrag","map","onMove","onUp","startArrowHandleDrag","arrow","projected","handle","getLocalPoint","updateItem","moveEvent","rawPt","shouldLock","snappedPt","constrainAngleTo45Degrees","screenToGeo","startShapeHandleDrag","shape","anchorScreen","initialRatio","nextPt","constrainToAspectRatio","nextGeo","startArrowBodyDrag","originPt","initialStartScreen","initialEndScreen","initialControlScreen","hadCustomControl","dx","dy","patch","startShapeBodyDrag","startFreeDrawBodyDrag","fd","initialScreenPts","sp","startRulerHandleDrag","ruler","startRulerBodyDrag","paintLeafletTual","map","canvas","width","height","arrowItems","shapeItems","freeDrawItems","rulerItems","selectedId","draftShape","draftArrow","draftRuler","draftFreeDraw","activeColor","strokeWidth","dashed","shapeFilled","annotationTheme","arrowTheme","isReadOnly","effectiveTheme","dpr","targetW","targetH","ctx","fd","screenPts","projectFreeDraw","renderFreeDrawOnCanvas","shp","projected","projectShape","renderShapeOnCanvas","arrow","projectArrow","renderArrowOnCanvas","ruler","projectRuler","renderRulerOnCanvas","tempShape","tempArrow","tempRuler","bindLeafletSync","map","onSync","sync","size","bindBlockMapDblClick","container","handleDblClickCapture","e","target","hadFlag","previous","wasZoomEnabled","handleMouseDownCapture","handleUp","createLeafletTualController","options","maxPast","past","present","future","committedItems","activeTool","readOnly","selectedId","isEditingLabel","activeShape","shapeFilled","activeColor","DEFAULT_STROKE_COLOR","strokeWidth","DEFAULT_STROKE_WIDTH","dashed","noteColor","DEFAULT_NOTE_BG","fontSize","DEFAULT_FONT_SIZE","fontWeight","listeners","notifyListeners","listener","store","triggerChange","next","triggerChangeComplete","finalItems","targetItem","commitItems","updater","notifyChangeComplete","anchor","setSelectedId","id","prev","it","setActiveTool","tool","setReadOnly","nextReadOnly","patchSelected","predicate","patcher","setActiveShape","shape","setShapeFilled","filled","setActiveColor","color","setStrokeWidth","width","setDashed","nextDashed","setNoteColor","bg","theme","NOTE_COLOR_THEMES","t","setFontSize","size","setFontWeight","weight","setEditingLabel","editing","addItem","item","updateItem","patch","patchKeys","updated","removeItem","deleteSelected","clearAll","restored","json","parsed","createLeafletTual","map","options","externalController","annotationTheme","arrowTheme","labels","zIndex","controllerOptions","controller","createLeafletTualController","mapContainer","container","canvas","drawingSurface","viewport","draftArrow","draftShape","draftRuler","draftFreeDrawRef","rafIdRef","setDraftArrow","next","repaint","setDraftShape","setDraftRuler","clearDraftFreeDraw","updateSurfaceInteractivity","isDrawing","items","paintLeafletTual","it","getLocalPoint","e","rect","handleSurfacePointerDown","pt","geo","screenToGeo","activeTool","activeShape","shapeFilled","activeColor","strokeWidth","dashed","noteColor","fontSize","fontWeight","startFreeDrawDrag","startShapeDrag","createDraftNote","createDraftText","startRulerDrag","arrowStyle","TOOL_TO_ARROW_STYLE","startArrowDrag","startScreen","geoToScreen","endScreen","constrainAngleTo45Degrees","buildArrowItem","handleSurfacePointerMove","rawPt","nextPt","handleContainerPointerDown","arrowItems","shapeItems","freeDrawItems","rulerItems","selectedId","selectedArrow","a","projected","projectArrow","handle","hitTestArrowHandle","startArrowHandleDrag","selectedShape","s","projectShape","hitTestShapeHandle","startShapeHandleDrag","selectedRuler","r","projectRuler","hitTestRulerHandle","startRulerHandleDrag","i","arrow","hitTestArrow","startArrowBodyDrag","shp","hitTestShape","startShapeBodyDrag","fd","initialScreenPts","projectFreeDraw","hitTestFreeDraw","startFreeDrawBodyDrag","ruler","hitTestRuler","startRulerBodyDrag","handleKeyDown","target","unbindSync","bindLeafletSync","dims","unbindDblClick","bindBlockMapDblClick","unsubscribeController","VERSION","package_default"]}