snap-dnd 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/snap.core.js CHANGED
@@ -10,4 +10,3 @@ var p=class{constructor(){this._listeners=new Map}on(e,t){let n=this._listeners.
10
10
  opacity: 0.8;
11
11
  will-change: transform;
12
12
  `,this._ghost.classList.add("snap-ghost"),document.body.appendChild(this._ghost)}_updateGhost(e){if(!this._ghost)return;let t=e.x-this._ghostOffset.x,n=e.y-this._ghostOffset.y;this._ghost.style.transform=`translate(${t-parseFloat(this._ghost.style.left)}px, ${n-parseFloat(this._ghost.style.top)}px)`}_removeGhost(){this._ghost&&(this._ghost.remove(),this._ghost=null)}_cleanup(e){e.classList.remove("snap-dragging"),this._options.ghostClass&&e.classList.remove(this._options.ghostClass),this._removeGhost()}_extractDataAttributes(e){let t={};for(let i of e.attributes)if(i.name.startsWith("data-drag-")){let s=i.name.slice(10);t[s]=i.value}let n=e.dataset.draggable;return n&&n!==""&&(t.type=n),t}destroy(){this.disable();for(let e of this._listenerUnsubscribers)e();this._listenerUnsubscribers=[],this._pointerSensor.destroy()}};var S=class{constructor(e,t={}){this._isActive=!1;this._element=e,this._options=t}get element(){return this._element}get isActive(){return this._isActive}setOptions(e){Object.assign(this._options,e)}containsPoint(e,t){let n=r.get(this._element);return T(e,t,n)}accepts(e){let{accepts:t}=this._options;if(!t)return!0;if(typeof t=="function")return t(e);for(let i of t)if(e.hasType(i)||e.getData("type")===i)return!0;let n=this._element.dataset.accepts;if(n){let i=n.split(",").map(s=>s.trim());for(let s of i)if(e.hasType(s)||e.getData("type")===s)return!0}return!1}setActive(e){this._isActive!==e&&(this._isActive=e,e?this._element.classList.add("snap-drop-active"):this._element.classList.remove("snap-drop-active"))}getInsertionIndex(e,t,n,i){let s=Array.from(this._element.querySelectorAll(n)).filter(l=>l!==i);if(s.length===0)return 0;let a=r.get(s[0]),h=r.get(s[s.length-1]),v=Math.abs(h.top-a.top)>Math.abs(h.left-a.left);for(let l=0;l<s.length;l++){let g=r.get(s[l]),m=H(g);if(v){if(t<m.y)return l}else if(e<m.x)return l}return s.length}getClosestItem(e,t,n,i){let s=Array.from(this._element.querySelectorAll(n)).filter(f=>f!==i);if(s.length===0)return null;let a=null,h=1/0,v="after",l=r.get(s[0]),g=r.get(s[s.length-1]),m=Math.abs(g.top-l.top)>Math.abs(g.left-l.left);for(let f of s){let A=r.get(f),b=H(A),w=e-b.x,Z=t-b.y,I=Math.sqrt(w*w+Z*Z);I<h&&(h=I,a=f,v=m?t<b.y?"before":"after":e<b.x?"before":"after")}return a?{element:a,position:v}:null}updateBounds(){r.update(this._element)}destroy(){this.setActive(!1),r.remove(this._element)}},u=class{constructor(){this._zones=new Map}register(e,t){let n=this._zones.get(e);return n?(t&&n.setOptions(t),n):(n=new S(e,t),this._zones.set(e,n),n)}unregister(e){let t=this._zones.get(e);t&&(t.destroy(),this._zones.delete(e))}get(e){return this._zones.get(e)}getElements(){return[...this._zones.keys()]}getAll(){return[...this._zones.values()]}findAtPoint(e,t){for(let n of this._zones.values())if(n.containsPoint(e,t))return n;return null}clear(){for(let e of this._zones.values())e.destroy();this._zones.clear()}updateAllBounds(){r.invalidateAll()}destroy(){this.clear()}};var R={draggableSelector:"[data-draggable]",dropZoneSelector:"[data-droppable]",axis:"both",autoRefresh:!1},M=class{constructor(e,t={}){this._imperativeDraggables=new Map;this._imperativeDropZones=new Map;this._plugins=[];this._behaviors=[];this._stateUnsubscribers=[];this._observer=null;this._refreshScheduled=!1;this._destroyed=!1;this._scrollHandler=null;this._resizeHandler=null;this._container=e,this._options={...R,...t},this._state=new c,this._dropZoneManager=new u,this._engine=new P({container:this._container,state:this._state,options:this._options,getDropZones:()=>this._getDropZones(),getItemData:n=>this._getItemData(n),getItemAxis:n=>this._getItemAxis(n)}),this._setupStateListeners(),this._scanDeclarativeElements(),this._options.autoRefresh&&this._setupAutoRefresh(),this._setupScrollResize(),this.enable()}get options(){return this._options}enable(){this._engine.enable()}disable(){this._engine.disable()}destroy(){this._destroyed=!0,this.disable();for(let e of this._stateUnsubscribers)e();this._stateUnsubscribers=[];for(let e of this._plugins)e.destroy();this._plugins=[];for(let e of this._behaviors)e.destroy();this._behaviors=[],this._engine.destroy(),this._state.destroy(),this._dropZoneManager.destroy(),this._observer?.disconnect(),this._observer=null,this._scrollHandler&&(window.removeEventListener("scroll",this._scrollHandler,!0),this._scrollHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null),this._imperativeDraggables.clear(),this._imperativeDropZones.clear()}refresh(){this._scanDeclarativeElements(),r.invalidateAll()}addDraggable(e,t){this._imperativeDraggables.set(e,t??{})}removeDraggable(e){this._imperativeDraggables.delete(e)}addDropZone(e,t){this._imperativeDropZones.set(e,t??{}),this._dropZoneManager.register(e,t)}removeDropZone(e){this._imperativeDropZones.delete(e),this._dropZoneManager.unregister(e)}isDragging(){return this._state.isDragging()}getActiveElement(){return this._state.getActiveElement()}use(e){return this._plugins.push(e),e.init(this),this}addBehavior(e){return this._behaviors.push(e),this}setOptions(e){Object.assign(this._options,e),this._engine.updateOptions(this._options)}_getDropZones(){let e=this._options.dropZoneSelector??"[data-droppable]",t=this._container instanceof ShadowRoot?this._container:this._container,n=Array.from(t.querySelectorAll(e)),i=[...this._imperativeDropZones.keys()];return[...new Set([...n,...i])]}_getItemData(e){return this._imperativeDraggables.get(e)?.data}_getItemAxis(e){let t=this._imperativeDraggables.get(e);if(t?.axis)return t.axis;let n=e.dataset.dragAxis;if(n==="x"||n==="y"||n==="both")return n}_scanDeclarativeElements(){let e=this._options.dropZoneSelector??"[data-droppable]",n=(this._container instanceof ShadowRoot?this._container:this._container).querySelectorAll(e);for(let i of n)this._imperativeDropZones.has(i)||this._dropZoneManager.register(i)}_setupStateListeners(){this._stateUnsubscribers.push(this._state.subscribe("dragstart",e=>{for(let t of this._behaviors)t.onDragStart?.(e)})),this._stateUnsubscribers.push(this._state.subscribe("dragmove",e=>{for(let t of this._behaviors)t.onDragMove?.(e)})),this._stateUnsubscribers.push(this._state.subscribe("dragend",e=>{for(let t of this._behaviors)t.onDragEnd?.(e)}))}_setupAutoRefresh(){this._observer=new MutationObserver(t=>{if(this._destroyed)return;let n=!1;for(let i of t)if(i.type==="childList"){n=!0;break}n&&!this._refreshScheduled&&(this._refreshScheduled=!0,requestAnimationFrame(()=>{this._destroyed||(this._refreshScheduled=!1,this.refresh())}))});let e=this._container instanceof ShadowRoot?this._container:this._container;this._observer.observe(e,{childList:!0,subtree:!0})}_setupScrollResize(){this._scrollHandler=()=>{this._state.isDragging()&&r.invalidateAll()},window.addEventListener("scroll",this._scrollHandler,!0),this._resizeHandler=()=>{r.invalidateAll()},window.addEventListener("resize",this._resizeHandler)}},O=M;export{c as DragState,S as DropZone,u as DropZoneManager,M as Snap,O as default};
13
- //# sourceMappingURL=snap.core.js.map
package/dist/snap.esm.js CHANGED
@@ -46,4 +46,3 @@ var _=class{constructor(){this._listeners=new Map}on(e,t){let n=this._listeners.
46
46
  height: 1px;
47
47
  background: rgba(0, 120, 255, 0.2);
48
48
  `,this._guideContainer.appendChild(a)}t.appendChild(this._guideContainer)}_removeGuides(){this._guideContainer?.remove(),this._guideContainer=null}};var k=class{constructor(e={}){this.name="constraint-axis";this._bounds=null;this._options=e}onDragStart(e){this._options.containWithinParent?this._calculateParentBounds(e.element):this._options.bounds&&(this._bounds={minX:this._options.bounds.minX??-1/0,maxX:this._options.bounds.maxX??1/0,minY:this._options.bounds.minY??-1/0,maxY:this._options.bounds.maxY??1/0})}onDragMove(e){}onDragEnd(){this._bounds=null}destroy(){this._bounds=null}constrain(e,t){let{x:n,y:o}=e,i=this._options.axis??"both";return i==="x"?o=t.y:i==="y"&&(n=t.x),this._bounds&&(n=Math.max(this._bounds.minX,Math.min(this._bounds.maxX,n)),o=Math.max(this._bounds.minY,Math.min(this._bounds.maxY,o))),{x:n,y:o}}getBounds(){return this._bounds}_calculateParentBounds(e){let t=e.parentElement;if(!t)return;let n=t.getBoundingClientRect(),o=e.getBoundingClientRect();this._bounds={minX:n.left,maxX:n.right-o.width,minY:n.top,maxY:n.bottom-o.height}}};export{R as AutoScroll,P as BoundsCache,k as ConstraintAxis,S as DragEngine,b as DragState,H as DropZone,T as DropZoneManager,_ as EventEmitter,w as FileDrop,M as FileSensor,O as Kanban,x as ObjectPool,y as PointerSensor,D as RAFThrottle,C as Snap,E as SnapDataTransfer,F as SnapGrid,A as Sortable,h as boundsCache,W as createFileDropZone,G as default,g as pointPool,X as rafThrottle,Y as rectPool};
49
- //# sourceMappingURL=snap.esm.js.map
package/package.json CHANGED
@@ -1,28 +1,32 @@
1
1
  {
2
2
  "name": "snap-dnd",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "A zero-dependency, memory-optimized drag and drop library for vanilla JS and Web Components",
5
5
  "type": "module",
6
- "main": "./dist/snap.umd.js",
6
+ "main": "./dist/snap.esm.js",
7
7
  "module": "./dist/snap.esm.js",
8
- "types": "./dist/snap.d.ts",
8
+ "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/snap.esm.js",
12
- "require": "./dist/snap.umd.js"
12
+ "types": "./dist/index.d.ts"
13
13
  },
14
14
  "./core": {
15
- "import": "./dist/snap.core.js"
15
+ "import": "./dist/snap.core.js",
16
+ "types": "./dist/index.d.ts"
16
17
  }
17
18
  },
18
19
  "files": [
19
- "dist"
20
+ "dist/snap.esm.js",
21
+ "dist/snap.core.js",
22
+ "dist/index.d.ts",
23
+ "dist/types/index.d.ts"
20
24
  ],
21
25
  "sideEffects": false,
22
26
  "scripts": {
23
27
  "build": "npm run build:full && npm run build:core",
24
- "build:full": "esbuild src/index.ts --bundle --format=esm --minify --sourcemap --outfile=dist/snap.esm.js && esbuild src/index.ts --bundle --format=iife --global-name=Snap --minify --sourcemap --outfile=dist/snap.umd.js",
25
- "build:core": "esbuild src/core-only.ts --bundle --format=esm --minify --sourcemap --outfile=dist/snap.core.js",
28
+ "build:full": "esbuild src/index.ts --bundle --format=esm --minify --outfile=dist/snap.esm.js",
29
+ "build:core": "esbuild src/core-only.ts --bundle --format=esm --minify --outfile=dist/snap.core.js",
26
30
  "dev": "esbuild src/index.ts --bundle --format=esm --watch --outfile=dist/snap.esm.js",
27
31
  "typecheck": "tsc --noEmit",
28
32
  "test": "vitest",
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/utils/EventEmitter.ts", "../src/utils/DataTransfer.ts", "../src/core/DragState.ts", "../src/utils/RAFThrottle.ts", "../src/utils/ObjectPool.ts", "../src/sensors/PointerSensor.ts", "../src/utils/BoundsCache.ts", "../src/core/DragEngine.ts", "../src/core/DropZone.ts", "../src/core/Snap.ts"],
4
- "sourcesContent": ["/**\n * Lightweight pub/sub event emitter\n * Optimized for minimal allocations\n */\nimport type { Unsubscribe } from '../types/index.js';\n\nexport type EventCallback<T = unknown> = (data: T) => void;\n\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private _listeners = new Map<keyof Events, Set<EventCallback>>();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n let listeners = this._listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this._listeners.set(event, listeners);\n }\n listeners.add(callback as EventCallback);\n\n return () => {\n listeners!.delete(callback as EventCallback);\n if (listeners!.size === 0) {\n this._listeners.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n const unsubscribe = this.on(event, (data) => {\n unsubscribe();\n callback(data);\n });\n return unsubscribe;\n }\n\n /**\n * Emit an event to all subscribers\n */\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n const listeners = this._listeners.get(event);\n if (listeners) {\n // Iterate over a copy to allow unsubscribe during emit\n for (const callback of [...listeners]) {\n callback(data);\n }\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners\n */\n off<K extends keyof Events>(event?: K): void {\n if (event) {\n this._listeners.delete(event);\n } else {\n this._listeners.clear();\n }\n }\n\n /**\n * Check if there are any listeners for an event\n */\n hasListeners<K extends keyof Events>(event: K): boolean {\n const listeners = this._listeners.get(event);\n return listeners !== undefined && listeners.size > 0;\n }\n\n /**\n * Get the number of listeners for an event\n */\n listenerCount<K extends keyof Events>(event: K): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n\n /**\n * Clear all listeners\n */\n destroy(): void {\n this._listeners.clear();\n }\n}\n", "/**\n * Custom DataTransfer implementation for passing data during drag operations\n * Not the browser's native DataTransfer\n */\nimport type { DataTransfer as IDataTransfer } from '../types/index.js';\n\nexport class SnapDataTransfer implements IDataTransfer {\n private _data = new Map<string, unknown>();\n\n /**\n * Set data for a given type\n */\n setData(type: string, value: unknown): void {\n this._data.set(type, value);\n }\n\n /**\n * Get data for a given type\n */\n getData<T = unknown>(type: string): T | undefined {\n return this._data.get(type) as T | undefined;\n }\n\n /**\n * Check if a type exists\n */\n hasType(type: string): boolean {\n return this._data.has(type);\n }\n\n /**\n * Get all registered types\n */\n get types(): string[] {\n return [...this._data.keys()];\n }\n\n /**\n * Clear all data\n */\n clear(): void {\n this._data.clear();\n }\n\n /**\n * Create a copy of this transfer\n */\n clone(): SnapDataTransfer {\n const copy = new SnapDataTransfer();\n for (const [key, value] of this._data) {\n copy.setData(key, value);\n }\n return copy;\n }\n}\n", "/**\n * Centralized drag state management\n * Single source of truth for the current drag session\n */\nimport type {\n DragSession,\n DragPhase,\n Point,\n StateEvent,\n Unsubscribe,\n} from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { SnapDataTransfer } from '../utils/DataTransfer.js';\n\n// Internal events\ninterface StateEvents {\n dragstart: DragSession;\n dragmove: DragSession;\n dragend: DragSession;\n dropzoneenter: DragSession;\n dropzoneleave: DragSession;\n drop: DragSession;\n}\n\nexport class DragState extends EventEmitter<StateEvents> {\n private _session: DragSession | null = null;\n private _idCounter = 0;\n\n /**\n * Get current drag session (null if not dragging)\n */\n get session(): DragSession | null {\n return this._session;\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._session !== null && this._session.phase === 'dragging';\n }\n\n /**\n * Get the element being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._session?.element ?? null;\n }\n\n /**\n * Get current drop zone\n */\n getCurrentDropZone(): HTMLElement | null {\n return this._session?.dropZone ?? null;\n }\n\n /**\n * Start a new drag session\n */\n startDrag(\n element: HTMLElement,\n origin: Point,\n initialData?: Record<string, unknown>\n ): DragSession {\n // End any existing session\n if (this._session) {\n this.cancelDrag();\n }\n\n const data = new SnapDataTransfer();\n if (initialData) {\n for (const [key, value] of Object.entries(initialData)) {\n data.setData(key, value);\n }\n }\n\n this._session = {\n id: `drag-${++this._idCounter}`,\n element,\n origin: { x: origin.x, y: origin.y },\n current: { x: origin.x, y: origin.y },\n delta: { x: 0, y: 0 },\n data,\n dropZone: null,\n phase: 'dragging',\n };\n\n this.emit('dragstart', this._session);\n return this._session;\n }\n\n /**\n * Update position during drag\n */\n updatePosition(point: Point): void {\n if (!this._session || this._session.phase !== 'dragging') return;\n\n this._session.current.x = point.x;\n this._session.current.y = point.y;\n this._session.delta.x = point.x - this._session.origin.x;\n this._session.delta.y = point.y - this._session.origin.y;\n\n this.emit('dragmove', this._session);\n }\n\n /**\n * Set or clear drop zone target\n */\n setDropTarget(zone: HTMLElement | null): void {\n if (!this._session) return;\n\n const previous = this._session.dropZone;\n if (previous === zone) return;\n\n // Emit leave for previous zone\n if (previous) {\n this._session.dropZone = null;\n this.emit('dropzoneleave', this._session);\n }\n\n // Emit enter for new zone\n if (zone) {\n this._session.dropZone = zone;\n this.emit('dropzoneenter', this._session);\n }\n }\n\n /**\n * Complete the drag with a drop\n */\n endDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'dropping';\n\n // Emit drop if over a valid drop zone\n if (session.dropZone) {\n this.emit('drop', session);\n }\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Cancel the current drag\n */\n cancelDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'cancelled';\n session.dropZone = null;\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(event: StateEvent, callback: (session: DragSession) => void): Unsubscribe {\n return this.on(event, callback);\n }\n\n /**\n * Reset state\n */\n reset(): void {\n if (this._session) {\n this.cancelDrag();\n }\n }\n\n /**\n * Cleanup\n */\n override destroy(): void {\n this.reset();\n super.destroy();\n }\n}\n", "/**\n * RAF-based throttling for high-frequency events\n * Ensures only one callback per animation frame\n */\nexport class RAFThrottle<T> {\n private _rafId: number | null = null;\n private _pending: T | null = null;\n private _callback: (data: T) => void;\n\n constructor(callback: (data: T) => void) {\n this._callback = callback;\n }\n\n /**\n * Queue data to be processed on next animation frame\n * Only the most recent data will be processed\n */\n queue(data: T): void {\n this._pending = data;\n\n if (this._rafId === null) {\n this._rafId = requestAnimationFrame(this._process);\n }\n }\n\n /**\n * Cancel any pending frame\n */\n cancel(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n this._pending = null;\n }\n\n /**\n * Process immediately if there's pending data\n */\n flush(): void {\n if (this._pending !== null) {\n this.cancel();\n this._callback(this._pending);\n this._pending = null;\n }\n }\n\n /**\n * Check if there's a pending frame\n */\n get isPending(): boolean {\n return this._rafId !== null;\n }\n\n private _process = (): void => {\n this._rafId = null;\n if (this._pending !== null) {\n const data = this._pending;\n this._pending = null;\n this._callback(data);\n }\n };\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.cancel();\n }\n}\n\n/**\n * Create a throttled function using RAF\n */\nexport function rafThrottle<T extends (...args: unknown[]) => void>(\n fn: T\n): T & { cancel: () => void; flush: () => void } {\n let rafId: number | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n const throttled = ((...args: Parameters<T>) => {\n lastArgs = args;\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n rafId = null;\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n });\n }\n }) as T & { cancel: () => void; flush: () => void };\n\n throttled.cancel = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n lastArgs = null;\n };\n\n throttled.flush = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n };\n\n return throttled;\n}\n", "/**\n * Generic object pool for reusing frequently allocated objects\n * Reduces GC pressure during drag operations\n */\nexport class ObjectPool<T> {\n private _pool: T[] = [];\n private _factory: () => T;\n private _reset: (obj: T) => void;\n private _maxSize: number;\n\n constructor(\n factory: () => T,\n reset: (obj: T) => void,\n initialSize = 10,\n maxSize = 100\n ) {\n this._factory = factory;\n this._reset = reset;\n this._maxSize = maxSize;\n\n // Pre-allocate objects\n for (let i = 0; i < initialSize; i++) {\n this._pool.push(factory());\n }\n }\n\n /**\n * Get an object from the pool or create a new one\n */\n acquire(): T {\n return this._pool.pop() ?? this._factory();\n }\n\n /**\n * Return an object to the pool for reuse\n */\n release(obj: T): void {\n if (this._pool.length < this._maxSize) {\n this._reset(obj);\n this._pool.push(obj);\n }\n }\n\n /**\n * Clear all pooled objects\n */\n clear(): void {\n this._pool.length = 0;\n }\n\n /**\n * Current pool size\n */\n get size(): number {\n return this._pool.length;\n }\n}\n\n// Pre-configured pools for common types\nimport type { Point, Rect } from '../types/index.js';\n\nexport const pointPool = new ObjectPool<Point>(\n () => ({ x: 0, y: 0 }),\n (p) => {\n p.x = 0;\n p.y = 0;\n }\n);\n\nexport const rectPool = new ObjectPool<Rect>(\n () => ({ x: 0, y: 0, width: 0, height: 0 }),\n (r) => {\n r.x = 0;\n r.y = 0;\n r.width = 0;\n r.height = 0;\n }\n);\n\n/**\n * Helper to get a point from pool with initial values\n */\nexport function acquirePoint(x: number, y: number): Point {\n const p = pointPool.acquire();\n p.x = x;\n p.y = y;\n return p;\n}\n\n/**\n * Helper to get a rect from pool with initial values\n */\nexport function acquireRect(\n x: number,\n y: number,\n width: number,\n height: number\n): Rect {\n const r = rectPool.acquire();\n r.x = x;\n r.y = y;\n r.width = width;\n r.height = height;\n return r;\n}\n", "/**\n * Unified pointer event sensor\n * Handles mouse, touch, and pointer events through event delegation\n */\nimport type { Point, Sensor } from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { RAFThrottle } from '../utils/RAFThrottle.js';\nimport { acquirePoint, pointPool } from '../utils/ObjectPool.js';\n\nexport interface PointerSensorEvents {\n pointerdown: PointerStartEvent;\n pointermove: PointerMoveEvent;\n pointerup: PointerEndEvent;\n pointercancel: PointerEndEvent;\n}\n\nexport interface PointerStartEvent {\n element: HTMLElement;\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerMoveEvent {\n position: Point;\n delta: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerEndEvent {\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerSensorOptions {\n container: HTMLElement | ShadowRoot;\n draggableSelector: string;\n handleSelector?: string;\n delay?: number;\n distance?: number;\n}\n\nexport class PointerSensor\n extends EventEmitter<PointerSensorEvents>\n implements Sensor\n{\n private _container: HTMLElement | ShadowRoot;\n private _options: PointerSensorOptions;\n private _attached = false;\n\n // Active drag state\n private _activePointerId: number | null = null;\n private _activeElement: HTMLElement | null = null;\n private _startPosition: Point | null = null;\n private _isDragging = false;\n private _delayTimer: number | null = null;\n\n // RAF throttle for move events\n private _moveThrottle: RAFThrottle<PointerEvent>;\n\n constructor(options: PointerSensorOptions) {\n super();\n this._container = options.container;\n this._options = options;\n\n this._moveThrottle = new RAFThrottle((e) => this._processMove(e));\n }\n\n /**\n * Attach event listeners\n */\n attach(): void {\n if (this._attached) return;\n\n const target = this._getEventTarget();\n target.addEventListener('pointerdown', this._onPointerDown, {\n passive: false,\n });\n\n this._attached = true;\n }\n\n /**\n * Detach event listeners\n */\n detach(): void {\n if (!this._attached) return;\n\n const target = this._getEventTarget();\n target.removeEventListener('pointerdown', this._onPointerDown);\n\n this._cleanup();\n this._attached = false;\n }\n\n /**\n * Check if currently tracking a drag\n */\n get isActive(): boolean {\n return this._activePointerId !== null;\n }\n\n /**\n * Check if drag has started (past delay/distance threshold)\n */\n get isDragging(): boolean {\n return this._isDragging;\n }\n\n private _getEventTarget(): HTMLElement | Document {\n // For ShadowRoot, attach to the host element\n if (this._container instanceof ShadowRoot) {\n return this._container.host as HTMLElement;\n }\n return this._container;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n // Only handle primary pointer (left mouse button, first touch)\n if (!e.isPrimary || e.button !== 0) return;\n\n // Already tracking a pointer\n if (this._activePointerId !== null) return;\n\n // Find draggable element using event delegation\n const draggable = this._findDraggable(e);\n if (!draggable) return;\n\n // Check if click was on handle (if handle selector is specified)\n if (this._options.handleSelector) {\n const handle = this._findHandle(e, draggable);\n if (!handle) return;\n }\n\n // Prevent default to avoid text selection and native drag\n e.preventDefault();\n\n // Store initial state\n this._activePointerId = e.pointerId;\n this._activeElement = draggable;\n this._startPosition = acquirePoint(e.clientX, e.clientY);\n this._isDragging = false;\n\n // Set pointer capture for reliable tracking\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n\n // Attach move/up listeners\n const target = this._getEventTarget();\n target.addEventListener('pointermove', this._onPointerMove, {\n passive: true,\n });\n target.addEventListener('pointerup', this._onPointerUp);\n target.addEventListener('pointercancel', this._onPointerCancel);\n\n // Handle delay threshold\n const delay = this._options.delay ?? 0;\n if (delay > 0) {\n this._delayTimer = window.setTimeout(() => {\n this._delayTimer = null;\n this._startDrag(e);\n }, delay);\n } else if ((this._options.distance ?? 0) === 0) {\n // No delay or distance, start immediately\n this._startDrag(e);\n }\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n // Queue for RAF processing\n this._moveThrottle.queue(e);\n };\n\n private _processMove = (e: PointerEvent): void => {\n if (!this._startPosition || !this._activeElement) return;\n\n const position = acquirePoint(e.clientX, e.clientY);\n\n // Check distance threshold if not yet dragging\n if (!this._isDragging) {\n const distance = this._options.distance ?? 0;\n if (distance > 0) {\n const dx = position.x - this._startPosition.x;\n const dy = position.y - this._startPosition.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < distance) {\n pointPool.release(position);\n return;\n }\n\n // Distance threshold reached, start drag\n this._clearDelayTimer();\n this._startDrag(e);\n }\n }\n\n if (this._isDragging) {\n const delta = acquirePoint(\n position.x - this._startPosition.x,\n position.y - this._startPosition.y\n );\n\n this.emit('pointermove', {\n position,\n delta,\n pointerId: e.pointerId,\n originalEvent: e,\n });\n\n // Note: caller is responsible for releasing position/delta\n } else {\n pointPool.release(position);\n }\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.flush();\n\n if (this._isDragging) {\n this.emit('pointerup', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _onPointerCancel = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.cancel();\n\n if (this._isDragging) {\n this.emit('pointercancel', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _startDrag(e: PointerEvent): void {\n if (this._isDragging || !this._activeElement || !this._startPosition) return;\n\n this._isDragging = true;\n\n this.emit('pointerdown', {\n element: this._activeElement,\n position: { x: this._startPosition.x, y: this._startPosition.y },\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n private _findDraggable(e: PointerEvent): HTMLElement | null {\n const target = e.target as Element;\n\n // Handle shadow DOM by using composedPath\n const path = e.composedPath();\n\n for (const el of path) {\n if (!(el instanceof HTMLElement)) continue;\n\n if (el.matches(this._options.draggableSelector)) {\n return el;\n }\n\n // Stop at container boundary\n if (el === this._container || el === (this._container as ShadowRoot).host) {\n break;\n }\n }\n\n // Fallback for non-composed path\n return target.closest?.(this._options.draggableSelector) as HTMLElement | null;\n }\n\n private _findHandle(e: PointerEvent, draggable: HTMLElement): HTMLElement | null {\n if (!this._options.handleSelector) return draggable;\n\n const target = e.target as Element;\n const handle = target.closest?.(this._options.handleSelector) as HTMLElement | null;\n\n // Handle must be inside the draggable\n if (handle && draggable.contains(handle)) {\n return handle;\n }\n\n return null;\n }\n\n private _clearDelayTimer(): void {\n if (this._delayTimer !== null) {\n clearTimeout(this._delayTimer);\n this._delayTimer = null;\n }\n }\n\n private _cleanup(): void {\n this._clearDelayTimer();\n this._moveThrottle.cancel();\n\n // Release pooled objects\n if (this._startPosition) {\n pointPool.release(this._startPosition);\n this._startPosition = null;\n }\n\n // Remove move/up listeners\n const target = this._getEventTarget();\n target.removeEventListener('pointermove', this._onPointerMove);\n target.removeEventListener('pointerup', this._onPointerUp);\n target.removeEventListener('pointercancel', this._onPointerCancel);\n\n this._activePointerId = null;\n this._activeElement = null;\n this._isDragging = false;\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n this.detach();\n this._moveThrottle.destroy();\n super.destroy();\n }\n}\n", "/**\n * Cached bounding rect manager using WeakMap\n * Automatically cleans up when elements are removed from DOM\n */\nexport class BoundsCache {\n private _cache = new WeakMap<Element, DOMRect>();\n private _dirty = new WeakSet<Element>();\n private _invalidateAll = false;\n\n /**\n * Get cached bounds for an element, or compute and cache\n */\n get(element: Element): DOMRect {\n if (this._invalidateAll || this._dirty.has(element)) {\n return this._update(element);\n }\n\n const cached = this._cache.get(element);\n if (cached) {\n return cached;\n }\n\n return this._update(element);\n }\n\n /**\n * Mark a specific element's bounds as dirty\n */\n invalidate(element: Element): void {\n this._dirty.add(element);\n }\n\n /**\n * Mark all cached bounds as dirty (e.g., on scroll/resize)\n */\n invalidateAll(): void {\n this._invalidateAll = true;\n }\n\n /**\n * Force update bounds for an element\n */\n update(element: Element): DOMRect {\n return this._update(element);\n }\n\n /**\n * Remove element from cache\n */\n remove(element: Element): void {\n this._cache.delete(element);\n }\n\n /**\n * Clear the dirty flag after a frame\n */\n clearDirty(): void {\n this._invalidateAll = false;\n // WeakSet doesn't have clear(), but dirty elements\n // will be refreshed on next get() call\n }\n\n private _update(element: Element): DOMRect {\n const rect = element.getBoundingClientRect();\n this._cache.set(element, rect);\n this._dirty.delete(element);\n return rect;\n }\n}\n\n// Singleton instance for shared use\nexport const boundsCache = new BoundsCache();\n\n/**\n * Check if a point is inside a rect\n */\nexport function pointInRect(x: number, y: number, rect: DOMRect): boolean {\n return (\n x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom\n );\n}\n\n/**\n * Check if two rects intersect\n */\nexport function rectsIntersect(a: DOMRect, b: DOMRect): boolean {\n return !(\n a.right < b.left ||\n a.left > b.right ||\n a.bottom < b.top ||\n a.top > b.bottom\n );\n}\n\n/**\n * Get the center point of a rect\n */\nexport function rectCenter(rect: DOMRect): { x: number; y: number } {\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n}\n\n/**\n * Calculate distance between two points\n */\nexport function distance(\n x1: number,\n y1: number,\n x2: number,\n y2: number\n): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return Math.sqrt(dx * dx + dy * dy);\n}\n", "/**\n * DragEngine orchestrates the drag operation\n * Coordinates between sensors, state, and drop zones\n */\nimport type { Point, SnapOptions, Axis } from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport {\n PointerSensor,\n type PointerStartEvent,\n type PointerMoveEvent,\n type PointerEndEvent,\n} from '../sensors/PointerSensor.js';\nimport { boundsCache, pointInRect } from '../utils/BoundsCache.js';\nimport { pointPool } from '../utils/ObjectPool.js';\n\nexport interface DragEngineOptions {\n container: HTMLElement | ShadowRoot;\n state: DragState;\n options: SnapOptions;\n getDropZones: () => HTMLElement[];\n getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n getItemAxis: (element: HTMLElement) => Axis | undefined;\n}\n\nexport class DragEngine {\n private _container: HTMLElement | ShadowRoot;\n private _state: DragState;\n private _options: SnapOptions;\n private _getDropZones: () => HTMLElement[];\n private _getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n private _getItemAxis: (element: HTMLElement) => Axis | undefined;\n\n private _pointerSensor: PointerSensor;\n private _enabled = false;\n private _listenerUnsubscribers: (() => void)[] = [];\n\n // Ghost element for visual feedback\n private _ghost: HTMLElement | null = null;\n private _ghostOffset: Point = { x: 0, y: 0 };\n\n constructor(engineOptions: DragEngineOptions) {\n this._container = engineOptions.container;\n this._state = engineOptions.state;\n this._options = engineOptions.options;\n this._getDropZones = engineOptions.getDropZones;\n this._getItemData = engineOptions.getItemData;\n this._getItemAxis = engineOptions.getItemAxis;\n\n // Initialize pointer sensor\n this._pointerSensor = new PointerSensor({\n container: this._container,\n draggableSelector: this._options.draggableSelector ?? '[data-draggable]',\n handleSelector: this._options.handleSelector,\n delay: this._options.delay,\n distance: this._options.distance,\n });\n\n this._setupListeners();\n }\n\n /**\n * Enable drag engine\n */\n enable(): void {\n if (this._enabled) return;\n this._pointerSensor.attach();\n this._enabled = true;\n }\n\n /**\n * Disable drag engine\n */\n disable(): void {\n if (!this._enabled) return;\n this._pointerSensor.detach();\n this._state.reset();\n this._removeGhost();\n this._enabled = false;\n }\n\n /**\n * Check if enabled\n */\n get isEnabled(): boolean {\n return this._enabled;\n }\n\n /**\n * Update options\n */\n updateOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n }\n\n private _setupListeners(): void {\n this._listenerUnsubscribers.push(\n this._pointerSensor.on('pointerdown', this._onPointerDown),\n this._pointerSensor.on('pointermove', this._onPointerMove),\n this._pointerSensor.on('pointerup', this._onPointerUp),\n this._pointerSensor.on('pointercancel', this._onPointerCancel)\n );\n }\n\n private _onPointerDown = (event: PointerStartEvent): void => {\n const { element, position } = event;\n\n // Get item data from data attributes or imperative registration\n const data = this._getItemData(element) ?? this._extractDataAttributes(element);\n\n // Start drag session\n const session = this._state.startDrag(element, position, data);\n\n // Call user callback\n const startEvent = {\n element,\n position: { x: position.x, y: position.y },\n data: session.data,\n cancel: () => {\n this._state.cancelDrag();\n },\n };\n\n const result = this._options.onDragStart?.(startEvent);\n if (result === false) {\n this._state.cancelDrag();\n return;\n }\n\n // Create ghost element\n this._createGhost(element, position);\n\n // Add dragging class\n element.classList.add('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.add(this._options.ghostClass);\n }\n\n // Invalidate bounds cache (positions may change)\n boundsCache.invalidateAll();\n };\n\n private _onPointerMove = (event: PointerMoveEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n let { position } = event;\n\n // Apply axis constraints\n const axis = this._getItemAxis(session.element) ?? this._options.axis ?? 'both';\n if (axis !== 'both') {\n position = this._applyAxisConstraint(position, session.origin, axis);\n }\n\n // Apply grid snapping\n if (this._options.grid) {\n position = this._applyGridSnap(position, this._options.grid);\n }\n\n // Update state\n this._state.updatePosition(position);\n\n // Update ghost position\n this._updateGhost(position);\n\n // Hit test drop zones\n this._updateDropZone(position);\n\n // Call user callback\n this._options.onDragMove?.({\n element: session.element,\n position: { x: session.current.x, y: session.current.y },\n delta: { x: session.delta.x, y: session.delta.y },\n dropZone: session.dropZone,\n });\n };\n\n private _onPointerUp = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n // End drag and get final session\n const finalSession = this._state.endDrag();\n if (!finalSession) return;\n\n // Remove visual feedback\n this._cleanup(finalSession.element);\n\n // Call drop callback if over valid zone\n if (finalSession.dropZone) {\n this._options.onDrop?.({\n element: finalSession.element,\n dropZone: finalSession.dropZone,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n data: finalSession.data,\n });\n }\n\n // Call end callback\n this._options.onDragEnd?.({\n element: finalSession.element,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n delta: { x: finalSession.delta.x, y: finalSession.delta.y },\n cancelled: false,\n });\n };\n\n private _onPointerCancel = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n const element = session.element;\n this._state.cancelDrag();\n this._cleanup(element);\n\n this._options.onDragEnd?.({\n element,\n position: event.position,\n delta: { x: 0, y: 0 },\n cancelled: true,\n });\n };\n\n private _applyAxisConstraint(position: Point, origin: Point, axis: Axis): Point {\n if (axis === 'x') {\n return { x: position.x, y: origin.y };\n }\n if (axis === 'y') {\n return { x: origin.x, y: position.y };\n }\n return position;\n }\n\n private _applyGridSnap(position: Point, grid: { x: number; y: number }): Point {\n return {\n x: Math.round(position.x / grid.x) * grid.x,\n y: Math.round(position.y / grid.y) * grid.y,\n };\n }\n\n private _updateDropZone(position: Point): void {\n const dropZones = this._getDropZones();\n let foundZone: HTMLElement | null = null;\n\n for (const zone of dropZones) {\n const rect = boundsCache.get(zone);\n if (pointInRect(position.x, position.y, rect)) {\n foundZone = zone;\n break;\n }\n }\n\n const session = this._state.session;\n if (!session) return;\n\n // Handle zone change\n if (foundZone !== session.dropZone) {\n if (session.dropZone) {\n this._options.onDropZoneLeave?.({\n element: session.element,\n dropZone: session.dropZone,\n });\n }\n\n this._state.setDropTarget(foundZone);\n\n if (foundZone) {\n this._options.onDropZoneEnter?.({\n element: session.element,\n dropZone: foundZone,\n position,\n });\n }\n }\n }\n\n private _createGhost(element: HTMLElement, position: Point): void {\n const rect = element.getBoundingClientRect();\n\n // Calculate offset from cursor to element origin\n this._ghostOffset = {\n x: position.x - rect.left,\n y: position.y - rect.top,\n };\n\n // Clone element for ghost\n this._ghost = element.cloneNode(true) as HTMLElement;\n this._ghost.style.cssText = `\n position: fixed;\n left: ${rect.left}px;\n top: ${rect.top}px;\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n pointer-events: none;\n z-index: 9999;\n opacity: 0.8;\n will-change: transform;\n `;\n this._ghost.classList.add('snap-ghost');\n\n // Append to body (not container, to avoid transform issues)\n document.body.appendChild(this._ghost);\n }\n\n private _updateGhost(position: Point): void {\n if (!this._ghost) return;\n\n const x = position.x - this._ghostOffset.x;\n const y = position.y - this._ghostOffset.y;\n\n // Use transform for better performance\n this._ghost.style.transform = `translate(${x - parseFloat(this._ghost.style.left)}px, ${y - parseFloat(this._ghost.style.top)}px)`;\n }\n\n private _removeGhost(): void {\n if (this._ghost) {\n this._ghost.remove();\n this._ghost = null;\n }\n }\n\n private _cleanup(element: HTMLElement): void {\n element.classList.remove('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.remove(this._options.ghostClass);\n }\n this._removeGhost();\n }\n\n private _extractDataAttributes(element: HTMLElement): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n\n // Extract data-drag-* attributes\n for (const attr of element.attributes) {\n if (attr.name.startsWith('data-drag-')) {\n const key = attr.name.slice(10); // Remove 'data-drag-'\n data[key] = attr.value;\n }\n }\n\n // Also include data-draggable value if present\n const draggableValue = element.dataset.draggable;\n if (draggableValue && draggableValue !== '') {\n data.type = draggableValue;\n }\n\n return data;\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.disable();\n\n // Unsubscribe from pointer sensor events\n for (const unsub of this._listenerUnsubscribers) {\n unsub();\n }\n this._listenerUnsubscribers = [];\n\n this._pointerSensor.destroy();\n }\n}\n", "/**\n * DropZone manages individual drop target areas\n * Handles hit testing and insertion index calculation\n */\nimport type { DataTransfer, DropZoneOptions, Point } from '../types/index.js';\nimport { boundsCache, pointInRect, rectCenter } from '../utils/BoundsCache.js';\n\nexport class DropZone {\n private _element: HTMLElement;\n private _options: DropZoneOptions;\n private _isActive = false;\n\n constructor(element: HTMLElement, options: DropZoneOptions = {}) {\n this._element = element;\n this._options = options;\n }\n\n /**\n * The DOM element for this drop zone\n */\n get element(): HTMLElement {\n return this._element;\n }\n\n /**\n * Whether this zone is currently active (being hovered)\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<DropZoneOptions>): void {\n Object.assign(this._options, options);\n }\n\n /**\n * Check if a point is inside this drop zone\n */\n containsPoint(x: number, y: number): boolean {\n const rect = boundsCache.get(this._element);\n return pointInRect(x, y, rect);\n }\n\n /**\n * Check if this zone accepts the given data\n */\n accepts(data: DataTransfer): boolean {\n const { accepts } = this._options;\n\n if (!accepts) return true;\n\n if (typeof accepts === 'function') {\n return accepts(data);\n }\n\n // Array of type strings\n for (const type of accepts) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n\n // Check data-accepts attribute on element\n const elementAccepts = this._element.dataset.accepts;\n if (elementAccepts) {\n const acceptedTypes = elementAccepts.split(',').map((s) => s.trim());\n for (const type of acceptedTypes) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Set active state and add/remove CSS class\n */\n setActive(active: boolean): void {\n if (this._isActive === active) return;\n\n this._isActive = active;\n\n if (active) {\n this._element.classList.add('snap-drop-active');\n } else {\n this._element.classList.remove('snap-drop-active');\n }\n }\n\n /**\n * Calculate insertion index for sortable behavior\n * Returns the index where an item should be inserted based on position\n */\n getInsertionIndex(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): number {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return 0;\n\n // Determine if list is vertical or horizontal\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) return i;\n } else {\n if (x < center.x) return i;\n }\n }\n\n return items.length;\n }\n\n /**\n * Get closest item to a point (for visual feedback)\n */\n getClosestItem(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): { element: HTMLElement; position: 'before' | 'after' } | null {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return null;\n\n let closestItem: HTMLElement | null = null;\n let closestDistance = Infinity;\n let position: 'before' | 'after' = 'after';\n\n // Determine orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (const item of items) {\n const rect = boundsCache.get(item);\n const center = rectCenter(rect);\n\n const dx = x - center.x;\n const dy = y - center.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < closestDistance) {\n closestDistance = distance;\n closestItem = item;\n position = isVertical ? (y < center.y ? 'before' : 'after') : (x < center.x ? 'before' : 'after');\n }\n }\n\n if (!closestItem) return null;\n\n return { element: closestItem, position };\n }\n\n /**\n * Force update cached bounds\n */\n updateBounds(): void {\n boundsCache.update(this._element);\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.setActive(false);\n boundsCache.remove(this._element);\n }\n}\n\n/**\n * DropZoneManager handles multiple drop zones\n */\nexport class DropZoneManager {\n private _zones = new Map<HTMLElement, DropZone>();\n\n /**\n * Register a drop zone\n */\n register(element: HTMLElement, options?: DropZoneOptions): DropZone {\n let zone = this._zones.get(element);\n if (zone) {\n if (options) zone.setOptions(options);\n return zone;\n }\n\n zone = new DropZone(element, options);\n this._zones.set(element, zone);\n return zone;\n }\n\n /**\n * Unregister a drop zone\n */\n unregister(element: HTMLElement): void {\n const zone = this._zones.get(element);\n if (zone) {\n zone.destroy();\n this._zones.delete(element);\n }\n }\n\n /**\n * Get drop zone for an element\n */\n get(element: HTMLElement): DropZone | undefined {\n return this._zones.get(element);\n }\n\n /**\n * Get all drop zone elements\n */\n getElements(): HTMLElement[] {\n return [...this._zones.keys()];\n }\n\n /**\n * Get all drop zones\n */\n getAll(): DropZone[] {\n return [...this._zones.values()];\n }\n\n /**\n * Find drop zone at point\n */\n findAtPoint(x: number, y: number): DropZone | null {\n for (const zone of this._zones.values()) {\n if (zone.containsPoint(x, y)) {\n return zone;\n }\n }\n return null;\n }\n\n /**\n * Clear all drop zones\n */\n clear(): void {\n for (const zone of this._zones.values()) {\n zone.destroy();\n }\n this._zones.clear();\n }\n\n /**\n * Update all bounds (e.g., after scroll/resize)\n */\n updateAllBounds(): void {\n boundsCache.invalidateAll();\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.clear();\n }\n}\n", "/**\n * Snap - Main entry point for the drag and drop library\n * Coordinates all subsystems and provides the public API\n */\nimport type {\n SnapOptions,\n SnapInstance,\n ItemOptions,\n DropZoneOptions,\n Axis,\n Plugin,\n Behavior,\n} from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport { DragEngine } from './DragEngine.js';\nimport { DropZoneManager } from './DropZone.js';\nimport { boundsCache } from '../utils/BoundsCache.js';\n\n// Default options\nconst defaultOptions: SnapOptions = {\n draggableSelector: '[data-draggable]',\n dropZoneSelector: '[data-droppable]',\n axis: 'both',\n autoRefresh: false,\n};\n\nexport class Snap implements SnapInstance {\n private _container: HTMLElement | ShadowRoot;\n private _options: SnapOptions;\n private _state: DragState;\n private _engine: DragEngine;\n private _dropZoneManager: DropZoneManager;\n\n // Imperative registrations\n private _imperativeDraggables = new Map<HTMLElement, ItemOptions>();\n private _imperativeDropZones = new Map<HTMLElement, DropZoneOptions>();\n\n // Plugins and behaviors\n private _plugins: Plugin[] = [];\n private _behaviors: Behavior[] = [];\n\n // State listener unsubscribers\n private _stateUnsubscribers: (() => void)[] = [];\n\n // MutationObserver for auto-refresh\n private _observer: MutationObserver | null = null;\n private _refreshScheduled = false;\n private _destroyed = false;\n\n // Scroll/resize handlers\n private _scrollHandler: (() => void) | null = null;\n private _resizeHandler: (() => void) | null = null;\n\n constructor(\n container: HTMLElement | ShadowRoot,\n options: SnapOptions = {}\n ) {\n this._container = container;\n this._options = { ...defaultOptions, ...options };\n\n // Initialize subsystems\n this._state = new DragState();\n this._dropZoneManager = new DropZoneManager();\n\n this._engine = new DragEngine({\n container: this._container,\n state: this._state,\n options: this._options,\n getDropZones: () => this._getDropZones(),\n getItemData: (el) => this._getItemData(el),\n getItemAxis: (el) => this._getItemAxis(el),\n });\n\n // Setup state listeners for behaviors\n this._setupStateListeners();\n\n // Initial scan for declarative elements\n this._scanDeclarativeElements();\n\n // Setup auto-refresh if enabled\n if (this._options.autoRefresh) {\n this._setupAutoRefresh();\n }\n\n // Setup scroll/resize handlers\n this._setupScrollResize();\n\n // Enable by default\n this.enable();\n }\n\n /**\n * Current options\n */\n get options(): SnapOptions {\n return this._options;\n }\n\n /**\n * Enable drag and drop\n */\n enable(): void {\n this._engine.enable();\n }\n\n /**\n * Disable drag and drop\n */\n disable(): void {\n this._engine.disable();\n }\n\n /**\n * Cleanup and destroy instance\n */\n destroy(): void {\n this._destroyed = true;\n this.disable();\n\n // Unsubscribe from state listeners\n for (const unsub of this._stateUnsubscribers) {\n unsub();\n }\n this._stateUnsubscribers = [];\n\n // Destroy plugins\n for (const plugin of this._plugins) {\n plugin.destroy();\n }\n this._plugins = [];\n\n // Destroy behaviors\n for (const behavior of this._behaviors) {\n behavior.destroy();\n }\n this._behaviors = [];\n\n // Cleanup subsystems\n this._engine.destroy();\n this._state.destroy();\n this._dropZoneManager.destroy();\n\n // Cleanup observers\n this._observer?.disconnect();\n this._observer = null;\n\n // Cleanup event handlers\n if (this._scrollHandler) {\n window.removeEventListener('scroll', this._scrollHandler, true);\n this._scrollHandler = null;\n }\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n this._resizeHandler = null;\n }\n\n // Clear registrations\n this._imperativeDraggables.clear();\n this._imperativeDropZones.clear();\n }\n\n /**\n * Re-scan for declarative elements (call after DOM changes)\n */\n refresh(): void {\n this._scanDeclarativeElements();\n boundsCache.invalidateAll();\n }\n\n /**\n * Register a draggable element imperatively\n */\n addDraggable(element: HTMLElement, options?: ItemOptions): void {\n this._imperativeDraggables.set(element, options ?? {});\n }\n\n /**\n * Unregister a draggable element\n */\n removeDraggable(element: HTMLElement): void {\n this._imperativeDraggables.delete(element);\n }\n\n /**\n * Register a drop zone imperatively\n */\n addDropZone(element: HTMLElement, options?: DropZoneOptions): void {\n this._imperativeDropZones.set(element, options ?? {});\n this._dropZoneManager.register(element, options);\n }\n\n /**\n * Unregister a drop zone\n */\n removeDropZone(element: HTMLElement): void {\n this._imperativeDropZones.delete(element);\n this._dropZoneManager.unregister(element);\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._state.isDragging();\n }\n\n /**\n * Get the element currently being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._state.getActiveElement();\n }\n\n /**\n * Register a plugin\n */\n use(plugin: Plugin): this {\n this._plugins.push(plugin);\n plugin.init(this);\n return this;\n }\n\n /**\n * Add a behavior\n */\n addBehavior(behavior: Behavior): this {\n this._behaviors.push(behavior);\n return this;\n }\n\n /**\n * Update options dynamically\n */\n setOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n this._engine.updateOptions(this._options);\n }\n\n // Internal methods\n\n private _getDropZones(): HTMLElement[] {\n // Combine declarative and imperative drop zones\n const selector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n const declarative = Array.from(\n containerEl.querySelectorAll<HTMLElement>(selector)\n );\n\n const imperative = [...this._imperativeDropZones.keys()];\n\n // Unique elements\n return [...new Set([...declarative, ...imperative])];\n }\n\n private _getItemData(element: HTMLElement): Record<string, unknown> | undefined {\n return this._imperativeDraggables.get(element)?.data;\n }\n\n private _getItemAxis(element: HTMLElement): Axis | undefined {\n // Check imperative first\n const imperative = this._imperativeDraggables.get(element);\n if (imperative?.axis) return imperative.axis;\n\n // Check data attribute\n const axis = element.dataset.dragAxis as Axis | undefined;\n if (axis === 'x' || axis === 'y' || axis === 'both') {\n return axis;\n }\n\n return undefined;\n }\n\n private _scanDeclarativeElements(): void {\n const dropZoneSelector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n // Register declarative drop zones\n const dropZones = containerEl.querySelectorAll<HTMLElement>(dropZoneSelector);\n for (const zone of dropZones) {\n if (!this._imperativeDropZones.has(zone)) {\n this._dropZoneManager.register(zone);\n }\n }\n }\n\n private _setupStateListeners(): void {\n // Forward state events to behaviors, store unsubscribers for cleanup\n this._stateUnsubscribers.push(\n this._state.subscribe('dragstart', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragStart?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragmove', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragMove?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragend', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragEnd?.(session);\n }\n })\n );\n }\n\n private _setupAutoRefresh(): void {\n this._observer = new MutationObserver((mutations) => {\n // Guard against destroyed instance\n if (this._destroyed) return;\n\n let needsRefresh = false;\n\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n needsRefresh = true;\n break;\n }\n }\n\n if (needsRefresh && !this._refreshScheduled) {\n this._refreshScheduled = true;\n // Debounce refresh\n requestAnimationFrame(() => {\n // Guard against destroyed instance in RAF callback\n if (this._destroyed) return;\n this._refreshScheduled = false;\n this.refresh();\n });\n }\n });\n\n const target = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n this._observer.observe(target, {\n childList: true,\n subtree: true,\n });\n }\n\n private _setupScrollResize(): void {\n // Invalidate bounds cache on scroll (capture phase for nested scrollers)\n this._scrollHandler = () => {\n if (this._state.isDragging()) {\n boundsCache.invalidateAll();\n }\n };\n window.addEventListener('scroll', this._scrollHandler, true);\n\n // Invalidate on resize\n this._resizeHandler = () => {\n boundsCache.invalidateAll();\n };\n window.addEventListener('resize', this._resizeHandler);\n }\n}\n\n// Export as default and named\nexport default Snap;\n"],
5
- "mappings": "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",
6
- "names": ["EventEmitter", "event", "callback", "listeners", "unsubscribe", "data", "SnapDataTransfer", "_SnapDataTransfer", "type", "value", "copy", "key", "DragState", "EventEmitter", "element", "origin", "initialData", "data", "SnapDataTransfer", "key", "value", "point", "zone", "previous", "session", "event", "callback", "RAFThrottle", "callback", "data", "ObjectPool", "factory", "reset", "initialSize", "maxSize", "i", "obj", "pointPool", "p", "rectPool", "r", "acquirePoint", "x", "y", "PointerSensor", "EventEmitter", "options", "e", "draggable", "acquirePoint", "target", "delay", "position", "distance", "dx", "dy", "pointPool", "delta", "RAFThrottle", "path", "el", "handle", "BoundsCache", "element", "cached", "rect", "boundsCache", "pointInRect", "x", "y", "rectCenter", "rect", "DragEngine", "engineOptions", "event", "element", "position", "data", "session", "startEvent", "boundsCache", "axis", "finalSession", "PointerSensor", "options", "origin", "grid", "dropZones", "foundZone", "zone", "rect", "pointInRect", "x", "y", "attr", "key", "draggableValue", "unsub", "DropZone", "element", "options", "x", "y", "rect", "boundsCache", "pointInRect", "data", "accepts", "type", "elementAccepts", "acceptedTypes", "active", "itemSelector", "excludeElement", "items", "el", "firstRect", "lastRect", "isVertical", "i", "center", "rectCenter", "closestItem", "closestDistance", "position", "item", "dx", "dy", "distance", "DropZoneManager", "zone", "defaultOptions", "Snap", "container", "options", "DragState", "DropZoneManager", "DragEngine", "el", "unsub", "plugin", "behavior", "boundsCache", "element", "selector", "containerEl", "declarative", "imperative", "axis", "dropZoneSelector", "dropZones", "zone", "session", "mutations", "needsRefresh", "mutation", "target", "Snap_default"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/utils/EventEmitter.ts", "../src/utils/DataTransfer.ts", "../src/core/DragState.ts", "../src/utils/RAFThrottle.ts", "../src/utils/ObjectPool.ts", "../src/sensors/PointerSensor.ts", "../src/utils/BoundsCache.ts", "../src/core/DragEngine.ts", "../src/core/DropZone.ts", "../src/core/Snap.ts", "../src/plugins/Sortable.ts", "../src/plugins/Kanban.ts", "../src/sensors/FileSensor.ts", "../src/plugins/FileDrop.ts", "../src/behaviors/AutoScroll.ts", "../src/behaviors/SnapGrid.ts", "../src/behaviors/ConstraintAxis.ts"],
4
- "sourcesContent": ["/**\n * Lightweight pub/sub event emitter\n * Optimized for minimal allocations\n */\nimport type { Unsubscribe } from '../types/index.js';\n\nexport type EventCallback<T = unknown> = (data: T) => void;\n\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private _listeners = new Map<keyof Events, Set<EventCallback>>();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n let listeners = this._listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this._listeners.set(event, listeners);\n }\n listeners.add(callback as EventCallback);\n\n return () => {\n listeners!.delete(callback as EventCallback);\n if (listeners!.size === 0) {\n this._listeners.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n const unsubscribe = this.on(event, (data) => {\n unsubscribe();\n callback(data);\n });\n return unsubscribe;\n }\n\n /**\n * Emit an event to all subscribers\n */\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n const listeners = this._listeners.get(event);\n if (listeners) {\n // Iterate over a copy to allow unsubscribe during emit\n for (const callback of [...listeners]) {\n callback(data);\n }\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners\n */\n off<K extends keyof Events>(event?: K): void {\n if (event) {\n this._listeners.delete(event);\n } else {\n this._listeners.clear();\n }\n }\n\n /**\n * Check if there are any listeners for an event\n */\n hasListeners<K extends keyof Events>(event: K): boolean {\n const listeners = this._listeners.get(event);\n return listeners !== undefined && listeners.size > 0;\n }\n\n /**\n * Get the number of listeners for an event\n */\n listenerCount<K extends keyof Events>(event: K): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n\n /**\n * Clear all listeners\n */\n destroy(): void {\n this._listeners.clear();\n }\n}\n", "/**\n * Custom DataTransfer implementation for passing data during drag operations\n * Not the browser's native DataTransfer\n */\nimport type { DataTransfer as IDataTransfer } from '../types/index.js';\n\nexport class SnapDataTransfer implements IDataTransfer {\n private _data = new Map<string, unknown>();\n\n /**\n * Set data for a given type\n */\n setData(type: string, value: unknown): void {\n this._data.set(type, value);\n }\n\n /**\n * Get data for a given type\n */\n getData<T = unknown>(type: string): T | undefined {\n return this._data.get(type) as T | undefined;\n }\n\n /**\n * Check if a type exists\n */\n hasType(type: string): boolean {\n return this._data.has(type);\n }\n\n /**\n * Get all registered types\n */\n get types(): string[] {\n return [...this._data.keys()];\n }\n\n /**\n * Clear all data\n */\n clear(): void {\n this._data.clear();\n }\n\n /**\n * Create a copy of this transfer\n */\n clone(): SnapDataTransfer {\n const copy = new SnapDataTransfer();\n for (const [key, value] of this._data) {\n copy.setData(key, value);\n }\n return copy;\n }\n}\n", "/**\n * Centralized drag state management\n * Single source of truth for the current drag session\n */\nimport type {\n DragSession,\n DragPhase,\n Point,\n StateEvent,\n Unsubscribe,\n} from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { SnapDataTransfer } from '../utils/DataTransfer.js';\n\n// Internal events\ninterface StateEvents {\n dragstart: DragSession;\n dragmove: DragSession;\n dragend: DragSession;\n dropzoneenter: DragSession;\n dropzoneleave: DragSession;\n drop: DragSession;\n}\n\nexport class DragState extends EventEmitter<StateEvents> {\n private _session: DragSession | null = null;\n private _idCounter = 0;\n\n /**\n * Get current drag session (null if not dragging)\n */\n get session(): DragSession | null {\n return this._session;\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._session !== null && this._session.phase === 'dragging';\n }\n\n /**\n * Get the element being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._session?.element ?? null;\n }\n\n /**\n * Get current drop zone\n */\n getCurrentDropZone(): HTMLElement | null {\n return this._session?.dropZone ?? null;\n }\n\n /**\n * Start a new drag session\n */\n startDrag(\n element: HTMLElement,\n origin: Point,\n initialData?: Record<string, unknown>\n ): DragSession {\n // End any existing session\n if (this._session) {\n this.cancelDrag();\n }\n\n const data = new SnapDataTransfer();\n if (initialData) {\n for (const [key, value] of Object.entries(initialData)) {\n data.setData(key, value);\n }\n }\n\n this._session = {\n id: `drag-${++this._idCounter}`,\n element,\n origin: { x: origin.x, y: origin.y },\n current: { x: origin.x, y: origin.y },\n delta: { x: 0, y: 0 },\n data,\n dropZone: null,\n phase: 'dragging',\n };\n\n this.emit('dragstart', this._session);\n return this._session;\n }\n\n /**\n * Update position during drag\n */\n updatePosition(point: Point): void {\n if (!this._session || this._session.phase !== 'dragging') return;\n\n this._session.current.x = point.x;\n this._session.current.y = point.y;\n this._session.delta.x = point.x - this._session.origin.x;\n this._session.delta.y = point.y - this._session.origin.y;\n\n this.emit('dragmove', this._session);\n }\n\n /**\n * Set or clear drop zone target\n */\n setDropTarget(zone: HTMLElement | null): void {\n if (!this._session) return;\n\n const previous = this._session.dropZone;\n if (previous === zone) return;\n\n // Emit leave for previous zone\n if (previous) {\n this._session.dropZone = null;\n this.emit('dropzoneleave', this._session);\n }\n\n // Emit enter for new zone\n if (zone) {\n this._session.dropZone = zone;\n this.emit('dropzoneenter', this._session);\n }\n }\n\n /**\n * Complete the drag with a drop\n */\n endDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'dropping';\n\n // Emit drop if over a valid drop zone\n if (session.dropZone) {\n this.emit('drop', session);\n }\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Cancel the current drag\n */\n cancelDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'cancelled';\n session.dropZone = null;\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(event: StateEvent, callback: (session: DragSession) => void): Unsubscribe {\n return this.on(event, callback);\n }\n\n /**\n * Reset state\n */\n reset(): void {\n if (this._session) {\n this.cancelDrag();\n }\n }\n\n /**\n * Cleanup\n */\n override destroy(): void {\n this.reset();\n super.destroy();\n }\n}\n", "/**\n * RAF-based throttling for high-frequency events\n * Ensures only one callback per animation frame\n */\nexport class RAFThrottle<T> {\n private _rafId: number | null = null;\n private _pending: T | null = null;\n private _callback: (data: T) => void;\n\n constructor(callback: (data: T) => void) {\n this._callback = callback;\n }\n\n /**\n * Queue data to be processed on next animation frame\n * Only the most recent data will be processed\n */\n queue(data: T): void {\n this._pending = data;\n\n if (this._rafId === null) {\n this._rafId = requestAnimationFrame(this._process);\n }\n }\n\n /**\n * Cancel any pending frame\n */\n cancel(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n this._pending = null;\n }\n\n /**\n * Process immediately if there's pending data\n */\n flush(): void {\n if (this._pending !== null) {\n this.cancel();\n this._callback(this._pending);\n this._pending = null;\n }\n }\n\n /**\n * Check if there's a pending frame\n */\n get isPending(): boolean {\n return this._rafId !== null;\n }\n\n private _process = (): void => {\n this._rafId = null;\n if (this._pending !== null) {\n const data = this._pending;\n this._pending = null;\n this._callback(data);\n }\n };\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.cancel();\n }\n}\n\n/**\n * Create a throttled function using RAF\n */\nexport function rafThrottle<T extends (...args: unknown[]) => void>(\n fn: T\n): T & { cancel: () => void; flush: () => void } {\n let rafId: number | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n const throttled = ((...args: Parameters<T>) => {\n lastArgs = args;\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n rafId = null;\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n });\n }\n }) as T & { cancel: () => void; flush: () => void };\n\n throttled.cancel = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n lastArgs = null;\n };\n\n throttled.flush = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n };\n\n return throttled;\n}\n", "/**\n * Generic object pool for reusing frequently allocated objects\n * Reduces GC pressure during drag operations\n */\nexport class ObjectPool<T> {\n private _pool: T[] = [];\n private _factory: () => T;\n private _reset: (obj: T) => void;\n private _maxSize: number;\n\n constructor(\n factory: () => T,\n reset: (obj: T) => void,\n initialSize = 10,\n maxSize = 100\n ) {\n this._factory = factory;\n this._reset = reset;\n this._maxSize = maxSize;\n\n // Pre-allocate objects\n for (let i = 0; i < initialSize; i++) {\n this._pool.push(factory());\n }\n }\n\n /**\n * Get an object from the pool or create a new one\n */\n acquire(): T {\n return this._pool.pop() ?? this._factory();\n }\n\n /**\n * Return an object to the pool for reuse\n */\n release(obj: T): void {\n if (this._pool.length < this._maxSize) {\n this._reset(obj);\n this._pool.push(obj);\n }\n }\n\n /**\n * Clear all pooled objects\n */\n clear(): void {\n this._pool.length = 0;\n }\n\n /**\n * Current pool size\n */\n get size(): number {\n return this._pool.length;\n }\n}\n\n// Pre-configured pools for common types\nimport type { Point, Rect } from '../types/index.js';\n\nexport const pointPool = new ObjectPool<Point>(\n () => ({ x: 0, y: 0 }),\n (p) => {\n p.x = 0;\n p.y = 0;\n }\n);\n\nexport const rectPool = new ObjectPool<Rect>(\n () => ({ x: 0, y: 0, width: 0, height: 0 }),\n (r) => {\n r.x = 0;\n r.y = 0;\n r.width = 0;\n r.height = 0;\n }\n);\n\n/**\n * Helper to get a point from pool with initial values\n */\nexport function acquirePoint(x: number, y: number): Point {\n const p = pointPool.acquire();\n p.x = x;\n p.y = y;\n return p;\n}\n\n/**\n * Helper to get a rect from pool with initial values\n */\nexport function acquireRect(\n x: number,\n y: number,\n width: number,\n height: number\n): Rect {\n const r = rectPool.acquire();\n r.x = x;\n r.y = y;\n r.width = width;\n r.height = height;\n return r;\n}\n", "/**\n * Unified pointer event sensor\n * Handles mouse, touch, and pointer events through event delegation\n */\nimport type { Point, Sensor } from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { RAFThrottle } from '../utils/RAFThrottle.js';\nimport { acquirePoint, pointPool } from '../utils/ObjectPool.js';\n\nexport interface PointerSensorEvents {\n pointerdown: PointerStartEvent;\n pointermove: PointerMoveEvent;\n pointerup: PointerEndEvent;\n pointercancel: PointerEndEvent;\n}\n\nexport interface PointerStartEvent {\n element: HTMLElement;\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerMoveEvent {\n position: Point;\n delta: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerEndEvent {\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerSensorOptions {\n container: HTMLElement | ShadowRoot;\n draggableSelector: string;\n handleSelector?: string;\n delay?: number;\n distance?: number;\n}\n\nexport class PointerSensor\n extends EventEmitter<PointerSensorEvents>\n implements Sensor\n{\n private _container: HTMLElement | ShadowRoot;\n private _options: PointerSensorOptions;\n private _attached = false;\n\n // Active drag state\n private _activePointerId: number | null = null;\n private _activeElement: HTMLElement | null = null;\n private _startPosition: Point | null = null;\n private _isDragging = false;\n private _delayTimer: number | null = null;\n\n // RAF throttle for move events\n private _moveThrottle: RAFThrottle<PointerEvent>;\n\n constructor(options: PointerSensorOptions) {\n super();\n this._container = options.container;\n this._options = options;\n\n this._moveThrottle = new RAFThrottle((e) => this._processMove(e));\n }\n\n /**\n * Attach event listeners\n */\n attach(): void {\n if (this._attached) return;\n\n const target = this._getEventTarget();\n target.addEventListener('pointerdown', this._onPointerDown, {\n passive: false,\n });\n\n this._attached = true;\n }\n\n /**\n * Detach event listeners\n */\n detach(): void {\n if (!this._attached) return;\n\n const target = this._getEventTarget();\n target.removeEventListener('pointerdown', this._onPointerDown);\n\n this._cleanup();\n this._attached = false;\n }\n\n /**\n * Check if currently tracking a drag\n */\n get isActive(): boolean {\n return this._activePointerId !== null;\n }\n\n /**\n * Check if drag has started (past delay/distance threshold)\n */\n get isDragging(): boolean {\n return this._isDragging;\n }\n\n private _getEventTarget(): HTMLElement | Document {\n // For ShadowRoot, attach to the host element\n if (this._container instanceof ShadowRoot) {\n return this._container.host as HTMLElement;\n }\n return this._container;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n // Only handle primary pointer (left mouse button, first touch)\n if (!e.isPrimary || e.button !== 0) return;\n\n // Already tracking a pointer\n if (this._activePointerId !== null) return;\n\n // Find draggable element using event delegation\n const draggable = this._findDraggable(e);\n if (!draggable) return;\n\n // Check if click was on handle (if handle selector is specified)\n if (this._options.handleSelector) {\n const handle = this._findHandle(e, draggable);\n if (!handle) return;\n }\n\n // Prevent default to avoid text selection and native drag\n e.preventDefault();\n\n // Store initial state\n this._activePointerId = e.pointerId;\n this._activeElement = draggable;\n this._startPosition = acquirePoint(e.clientX, e.clientY);\n this._isDragging = false;\n\n // Set pointer capture for reliable tracking\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n\n // Attach move/up listeners\n const target = this._getEventTarget();\n target.addEventListener('pointermove', this._onPointerMove, {\n passive: true,\n });\n target.addEventListener('pointerup', this._onPointerUp);\n target.addEventListener('pointercancel', this._onPointerCancel);\n\n // Handle delay threshold\n const delay = this._options.delay ?? 0;\n if (delay > 0) {\n this._delayTimer = window.setTimeout(() => {\n this._delayTimer = null;\n this._startDrag(e);\n }, delay);\n } else if ((this._options.distance ?? 0) === 0) {\n // No delay or distance, start immediately\n this._startDrag(e);\n }\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n // Queue for RAF processing\n this._moveThrottle.queue(e);\n };\n\n private _processMove = (e: PointerEvent): void => {\n if (!this._startPosition || !this._activeElement) return;\n\n const position = acquirePoint(e.clientX, e.clientY);\n\n // Check distance threshold if not yet dragging\n if (!this._isDragging) {\n const distance = this._options.distance ?? 0;\n if (distance > 0) {\n const dx = position.x - this._startPosition.x;\n const dy = position.y - this._startPosition.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < distance) {\n pointPool.release(position);\n return;\n }\n\n // Distance threshold reached, start drag\n this._clearDelayTimer();\n this._startDrag(e);\n }\n }\n\n if (this._isDragging) {\n const delta = acquirePoint(\n position.x - this._startPosition.x,\n position.y - this._startPosition.y\n );\n\n this.emit('pointermove', {\n position,\n delta,\n pointerId: e.pointerId,\n originalEvent: e,\n });\n\n // Note: caller is responsible for releasing position/delta\n } else {\n pointPool.release(position);\n }\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.flush();\n\n if (this._isDragging) {\n this.emit('pointerup', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _onPointerCancel = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.cancel();\n\n if (this._isDragging) {\n this.emit('pointercancel', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _startDrag(e: PointerEvent): void {\n if (this._isDragging || !this._activeElement || !this._startPosition) return;\n\n this._isDragging = true;\n\n this.emit('pointerdown', {\n element: this._activeElement,\n position: { x: this._startPosition.x, y: this._startPosition.y },\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n private _findDraggable(e: PointerEvent): HTMLElement | null {\n const target = e.target as Element;\n\n // Handle shadow DOM by using composedPath\n const path = e.composedPath();\n\n for (const el of path) {\n if (!(el instanceof HTMLElement)) continue;\n\n if (el.matches(this._options.draggableSelector)) {\n return el;\n }\n\n // Stop at container boundary\n if (el === this._container || el === (this._container as ShadowRoot).host) {\n break;\n }\n }\n\n // Fallback for non-composed path\n return target.closest?.(this._options.draggableSelector) as HTMLElement | null;\n }\n\n private _findHandle(e: PointerEvent, draggable: HTMLElement): HTMLElement | null {\n if (!this._options.handleSelector) return draggable;\n\n const target = e.target as Element;\n const handle = target.closest?.(this._options.handleSelector) as HTMLElement | null;\n\n // Handle must be inside the draggable\n if (handle && draggable.contains(handle)) {\n return handle;\n }\n\n return null;\n }\n\n private _clearDelayTimer(): void {\n if (this._delayTimer !== null) {\n clearTimeout(this._delayTimer);\n this._delayTimer = null;\n }\n }\n\n private _cleanup(): void {\n this._clearDelayTimer();\n this._moveThrottle.cancel();\n\n // Release pooled objects\n if (this._startPosition) {\n pointPool.release(this._startPosition);\n this._startPosition = null;\n }\n\n // Remove move/up listeners\n const target = this._getEventTarget();\n target.removeEventListener('pointermove', this._onPointerMove);\n target.removeEventListener('pointerup', this._onPointerUp);\n target.removeEventListener('pointercancel', this._onPointerCancel);\n\n this._activePointerId = null;\n this._activeElement = null;\n this._isDragging = false;\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n this.detach();\n this._moveThrottle.destroy();\n super.destroy();\n }\n}\n", "/**\n * Cached bounding rect manager using WeakMap\n * Automatically cleans up when elements are removed from DOM\n */\nexport class BoundsCache {\n private _cache = new WeakMap<Element, DOMRect>();\n private _dirty = new WeakSet<Element>();\n private _invalidateAll = false;\n\n /**\n * Get cached bounds for an element, or compute and cache\n */\n get(element: Element): DOMRect {\n if (this._invalidateAll || this._dirty.has(element)) {\n return this._update(element);\n }\n\n const cached = this._cache.get(element);\n if (cached) {\n return cached;\n }\n\n return this._update(element);\n }\n\n /**\n * Mark a specific element's bounds as dirty\n */\n invalidate(element: Element): void {\n this._dirty.add(element);\n }\n\n /**\n * Mark all cached bounds as dirty (e.g., on scroll/resize)\n */\n invalidateAll(): void {\n this._invalidateAll = true;\n }\n\n /**\n * Force update bounds for an element\n */\n update(element: Element): DOMRect {\n return this._update(element);\n }\n\n /**\n * Remove element from cache\n */\n remove(element: Element): void {\n this._cache.delete(element);\n }\n\n /**\n * Clear the dirty flag after a frame\n */\n clearDirty(): void {\n this._invalidateAll = false;\n // WeakSet doesn't have clear(), but dirty elements\n // will be refreshed on next get() call\n }\n\n private _update(element: Element): DOMRect {\n const rect = element.getBoundingClientRect();\n this._cache.set(element, rect);\n this._dirty.delete(element);\n return rect;\n }\n}\n\n// Singleton instance for shared use\nexport const boundsCache = new BoundsCache();\n\n/**\n * Check if a point is inside a rect\n */\nexport function pointInRect(x: number, y: number, rect: DOMRect): boolean {\n return (\n x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom\n );\n}\n\n/**\n * Check if two rects intersect\n */\nexport function rectsIntersect(a: DOMRect, b: DOMRect): boolean {\n return !(\n a.right < b.left ||\n a.left > b.right ||\n a.bottom < b.top ||\n a.top > b.bottom\n );\n}\n\n/**\n * Get the center point of a rect\n */\nexport function rectCenter(rect: DOMRect): { x: number; y: number } {\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n}\n\n/**\n * Calculate distance between two points\n */\nexport function distance(\n x1: number,\n y1: number,\n x2: number,\n y2: number\n): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return Math.sqrt(dx * dx + dy * dy);\n}\n", "/**\n * DragEngine orchestrates the drag operation\n * Coordinates between sensors, state, and drop zones\n */\nimport type { Point, SnapOptions, Axis } from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport {\n PointerSensor,\n type PointerStartEvent,\n type PointerMoveEvent,\n type PointerEndEvent,\n} from '../sensors/PointerSensor.js';\nimport { boundsCache, pointInRect } from '../utils/BoundsCache.js';\nimport { pointPool } from '../utils/ObjectPool.js';\n\nexport interface DragEngineOptions {\n container: HTMLElement | ShadowRoot;\n state: DragState;\n options: SnapOptions;\n getDropZones: () => HTMLElement[];\n getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n getItemAxis: (element: HTMLElement) => Axis | undefined;\n}\n\nexport class DragEngine {\n private _container: HTMLElement | ShadowRoot;\n private _state: DragState;\n private _options: SnapOptions;\n private _getDropZones: () => HTMLElement[];\n private _getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n private _getItemAxis: (element: HTMLElement) => Axis | undefined;\n\n private _pointerSensor: PointerSensor;\n private _enabled = false;\n private _listenerUnsubscribers: (() => void)[] = [];\n\n // Ghost element for visual feedback\n private _ghost: HTMLElement | null = null;\n private _ghostOffset: Point = { x: 0, y: 0 };\n\n constructor(engineOptions: DragEngineOptions) {\n this._container = engineOptions.container;\n this._state = engineOptions.state;\n this._options = engineOptions.options;\n this._getDropZones = engineOptions.getDropZones;\n this._getItemData = engineOptions.getItemData;\n this._getItemAxis = engineOptions.getItemAxis;\n\n // Initialize pointer sensor\n this._pointerSensor = new PointerSensor({\n container: this._container,\n draggableSelector: this._options.draggableSelector ?? '[data-draggable]',\n handleSelector: this._options.handleSelector,\n delay: this._options.delay,\n distance: this._options.distance,\n });\n\n this._setupListeners();\n }\n\n /**\n * Enable drag engine\n */\n enable(): void {\n if (this._enabled) return;\n this._pointerSensor.attach();\n this._enabled = true;\n }\n\n /**\n * Disable drag engine\n */\n disable(): void {\n if (!this._enabled) return;\n this._pointerSensor.detach();\n this._state.reset();\n this._removeGhost();\n this._enabled = false;\n }\n\n /**\n * Check if enabled\n */\n get isEnabled(): boolean {\n return this._enabled;\n }\n\n /**\n * Update options\n */\n updateOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n }\n\n private _setupListeners(): void {\n this._listenerUnsubscribers.push(\n this._pointerSensor.on('pointerdown', this._onPointerDown),\n this._pointerSensor.on('pointermove', this._onPointerMove),\n this._pointerSensor.on('pointerup', this._onPointerUp),\n this._pointerSensor.on('pointercancel', this._onPointerCancel)\n );\n }\n\n private _onPointerDown = (event: PointerStartEvent): void => {\n const { element, position } = event;\n\n // Get item data from data attributes or imperative registration\n const data = this._getItemData(element) ?? this._extractDataAttributes(element);\n\n // Start drag session\n const session = this._state.startDrag(element, position, data);\n\n // Call user callback\n const startEvent = {\n element,\n position: { x: position.x, y: position.y },\n data: session.data,\n cancel: () => {\n this._state.cancelDrag();\n },\n };\n\n const result = this._options.onDragStart?.(startEvent);\n if (result === false) {\n this._state.cancelDrag();\n return;\n }\n\n // Create ghost element\n this._createGhost(element, position);\n\n // Add dragging class\n element.classList.add('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.add(this._options.ghostClass);\n }\n\n // Invalidate bounds cache (positions may change)\n boundsCache.invalidateAll();\n };\n\n private _onPointerMove = (event: PointerMoveEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n let { position } = event;\n\n // Apply axis constraints\n const axis = this._getItemAxis(session.element) ?? this._options.axis ?? 'both';\n if (axis !== 'both') {\n position = this._applyAxisConstraint(position, session.origin, axis);\n }\n\n // Apply grid snapping\n if (this._options.grid) {\n position = this._applyGridSnap(position, this._options.grid);\n }\n\n // Update state\n this._state.updatePosition(position);\n\n // Update ghost position\n this._updateGhost(position);\n\n // Hit test drop zones\n this._updateDropZone(position);\n\n // Call user callback\n this._options.onDragMove?.({\n element: session.element,\n position: { x: session.current.x, y: session.current.y },\n delta: { x: session.delta.x, y: session.delta.y },\n dropZone: session.dropZone,\n });\n };\n\n private _onPointerUp = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n // End drag and get final session\n const finalSession = this._state.endDrag();\n if (!finalSession) return;\n\n // Remove visual feedback\n this._cleanup(finalSession.element);\n\n // Call drop callback if over valid zone\n if (finalSession.dropZone) {\n this._options.onDrop?.({\n element: finalSession.element,\n dropZone: finalSession.dropZone,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n data: finalSession.data,\n });\n }\n\n // Call end callback\n this._options.onDragEnd?.({\n element: finalSession.element,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n delta: { x: finalSession.delta.x, y: finalSession.delta.y },\n cancelled: false,\n });\n };\n\n private _onPointerCancel = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n const element = session.element;\n this._state.cancelDrag();\n this._cleanup(element);\n\n this._options.onDragEnd?.({\n element,\n position: event.position,\n delta: { x: 0, y: 0 },\n cancelled: true,\n });\n };\n\n private _applyAxisConstraint(position: Point, origin: Point, axis: Axis): Point {\n if (axis === 'x') {\n return { x: position.x, y: origin.y };\n }\n if (axis === 'y') {\n return { x: origin.x, y: position.y };\n }\n return position;\n }\n\n private _applyGridSnap(position: Point, grid: { x: number; y: number }): Point {\n return {\n x: Math.round(position.x / grid.x) * grid.x,\n y: Math.round(position.y / grid.y) * grid.y,\n };\n }\n\n private _updateDropZone(position: Point): void {\n const dropZones = this._getDropZones();\n let foundZone: HTMLElement | null = null;\n\n for (const zone of dropZones) {\n const rect = boundsCache.get(zone);\n if (pointInRect(position.x, position.y, rect)) {\n foundZone = zone;\n break;\n }\n }\n\n const session = this._state.session;\n if (!session) return;\n\n // Handle zone change\n if (foundZone !== session.dropZone) {\n if (session.dropZone) {\n this._options.onDropZoneLeave?.({\n element: session.element,\n dropZone: session.dropZone,\n });\n }\n\n this._state.setDropTarget(foundZone);\n\n if (foundZone) {\n this._options.onDropZoneEnter?.({\n element: session.element,\n dropZone: foundZone,\n position,\n });\n }\n }\n }\n\n private _createGhost(element: HTMLElement, position: Point): void {\n const rect = element.getBoundingClientRect();\n\n // Calculate offset from cursor to element origin\n this._ghostOffset = {\n x: position.x - rect.left,\n y: position.y - rect.top,\n };\n\n // Clone element for ghost\n this._ghost = element.cloneNode(true) as HTMLElement;\n this._ghost.style.cssText = `\n position: fixed;\n left: ${rect.left}px;\n top: ${rect.top}px;\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n pointer-events: none;\n z-index: 9999;\n opacity: 0.8;\n will-change: transform;\n `;\n this._ghost.classList.add('snap-ghost');\n\n // Append to body (not container, to avoid transform issues)\n document.body.appendChild(this._ghost);\n }\n\n private _updateGhost(position: Point): void {\n if (!this._ghost) return;\n\n const x = position.x - this._ghostOffset.x;\n const y = position.y - this._ghostOffset.y;\n\n // Use transform for better performance\n this._ghost.style.transform = `translate(${x - parseFloat(this._ghost.style.left)}px, ${y - parseFloat(this._ghost.style.top)}px)`;\n }\n\n private _removeGhost(): void {\n if (this._ghost) {\n this._ghost.remove();\n this._ghost = null;\n }\n }\n\n private _cleanup(element: HTMLElement): void {\n element.classList.remove('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.remove(this._options.ghostClass);\n }\n this._removeGhost();\n }\n\n private _extractDataAttributes(element: HTMLElement): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n\n // Extract data-drag-* attributes\n for (const attr of element.attributes) {\n if (attr.name.startsWith('data-drag-')) {\n const key = attr.name.slice(10); // Remove 'data-drag-'\n data[key] = attr.value;\n }\n }\n\n // Also include data-draggable value if present\n const draggableValue = element.dataset.draggable;\n if (draggableValue && draggableValue !== '') {\n data.type = draggableValue;\n }\n\n return data;\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.disable();\n\n // Unsubscribe from pointer sensor events\n for (const unsub of this._listenerUnsubscribers) {\n unsub();\n }\n this._listenerUnsubscribers = [];\n\n this._pointerSensor.destroy();\n }\n}\n", "/**\n * DropZone manages individual drop target areas\n * Handles hit testing and insertion index calculation\n */\nimport type { DataTransfer, DropZoneOptions, Point } from '../types/index.js';\nimport { boundsCache, pointInRect, rectCenter } from '../utils/BoundsCache.js';\n\nexport class DropZone {\n private _element: HTMLElement;\n private _options: DropZoneOptions;\n private _isActive = false;\n\n constructor(element: HTMLElement, options: DropZoneOptions = {}) {\n this._element = element;\n this._options = options;\n }\n\n /**\n * The DOM element for this drop zone\n */\n get element(): HTMLElement {\n return this._element;\n }\n\n /**\n * Whether this zone is currently active (being hovered)\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<DropZoneOptions>): void {\n Object.assign(this._options, options);\n }\n\n /**\n * Check if a point is inside this drop zone\n */\n containsPoint(x: number, y: number): boolean {\n const rect = boundsCache.get(this._element);\n return pointInRect(x, y, rect);\n }\n\n /**\n * Check if this zone accepts the given data\n */\n accepts(data: DataTransfer): boolean {\n const { accepts } = this._options;\n\n if (!accepts) return true;\n\n if (typeof accepts === 'function') {\n return accepts(data);\n }\n\n // Array of type strings\n for (const type of accepts) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n\n // Check data-accepts attribute on element\n const elementAccepts = this._element.dataset.accepts;\n if (elementAccepts) {\n const acceptedTypes = elementAccepts.split(',').map((s) => s.trim());\n for (const type of acceptedTypes) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Set active state and add/remove CSS class\n */\n setActive(active: boolean): void {\n if (this._isActive === active) return;\n\n this._isActive = active;\n\n if (active) {\n this._element.classList.add('snap-drop-active');\n } else {\n this._element.classList.remove('snap-drop-active');\n }\n }\n\n /**\n * Calculate insertion index for sortable behavior\n * Returns the index where an item should be inserted based on position\n */\n getInsertionIndex(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): number {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return 0;\n\n // Determine if list is vertical or horizontal\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) return i;\n } else {\n if (x < center.x) return i;\n }\n }\n\n return items.length;\n }\n\n /**\n * Get closest item to a point (for visual feedback)\n */\n getClosestItem(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): { element: HTMLElement; position: 'before' | 'after' } | null {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return null;\n\n let closestItem: HTMLElement | null = null;\n let closestDistance = Infinity;\n let position: 'before' | 'after' = 'after';\n\n // Determine orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (const item of items) {\n const rect = boundsCache.get(item);\n const center = rectCenter(rect);\n\n const dx = x - center.x;\n const dy = y - center.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < closestDistance) {\n closestDistance = distance;\n closestItem = item;\n position = isVertical ? (y < center.y ? 'before' : 'after') : (x < center.x ? 'before' : 'after');\n }\n }\n\n if (!closestItem) return null;\n\n return { element: closestItem, position };\n }\n\n /**\n * Force update cached bounds\n */\n updateBounds(): void {\n boundsCache.update(this._element);\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.setActive(false);\n boundsCache.remove(this._element);\n }\n}\n\n/**\n * DropZoneManager handles multiple drop zones\n */\nexport class DropZoneManager {\n private _zones = new Map<HTMLElement, DropZone>();\n\n /**\n * Register a drop zone\n */\n register(element: HTMLElement, options?: DropZoneOptions): DropZone {\n let zone = this._zones.get(element);\n if (zone) {\n if (options) zone.setOptions(options);\n return zone;\n }\n\n zone = new DropZone(element, options);\n this._zones.set(element, zone);\n return zone;\n }\n\n /**\n * Unregister a drop zone\n */\n unregister(element: HTMLElement): void {\n const zone = this._zones.get(element);\n if (zone) {\n zone.destroy();\n this._zones.delete(element);\n }\n }\n\n /**\n * Get drop zone for an element\n */\n get(element: HTMLElement): DropZone | undefined {\n return this._zones.get(element);\n }\n\n /**\n * Get all drop zone elements\n */\n getElements(): HTMLElement[] {\n return [...this._zones.keys()];\n }\n\n /**\n * Get all drop zones\n */\n getAll(): DropZone[] {\n return [...this._zones.values()];\n }\n\n /**\n * Find drop zone at point\n */\n findAtPoint(x: number, y: number): DropZone | null {\n for (const zone of this._zones.values()) {\n if (zone.containsPoint(x, y)) {\n return zone;\n }\n }\n return null;\n }\n\n /**\n * Clear all drop zones\n */\n clear(): void {\n for (const zone of this._zones.values()) {\n zone.destroy();\n }\n this._zones.clear();\n }\n\n /**\n * Update all bounds (e.g., after scroll/resize)\n */\n updateAllBounds(): void {\n boundsCache.invalidateAll();\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.clear();\n }\n}\n", "/**\n * Snap - Main entry point for the drag and drop library\n * Coordinates all subsystems and provides the public API\n */\nimport type {\n SnapOptions,\n SnapInstance,\n ItemOptions,\n DropZoneOptions,\n Axis,\n Plugin,\n Behavior,\n} from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport { DragEngine } from './DragEngine.js';\nimport { DropZoneManager } from './DropZone.js';\nimport { boundsCache } from '../utils/BoundsCache.js';\n\n// Default options\nconst defaultOptions: SnapOptions = {\n draggableSelector: '[data-draggable]',\n dropZoneSelector: '[data-droppable]',\n axis: 'both',\n autoRefresh: false,\n};\n\nexport class Snap implements SnapInstance {\n private _container: HTMLElement | ShadowRoot;\n private _options: SnapOptions;\n private _state: DragState;\n private _engine: DragEngine;\n private _dropZoneManager: DropZoneManager;\n\n // Imperative registrations\n private _imperativeDraggables = new Map<HTMLElement, ItemOptions>();\n private _imperativeDropZones = new Map<HTMLElement, DropZoneOptions>();\n\n // Plugins and behaviors\n private _plugins: Plugin[] = [];\n private _behaviors: Behavior[] = [];\n\n // State listener unsubscribers\n private _stateUnsubscribers: (() => void)[] = [];\n\n // MutationObserver for auto-refresh\n private _observer: MutationObserver | null = null;\n private _refreshScheduled = false;\n private _destroyed = false;\n\n // Scroll/resize handlers\n private _scrollHandler: (() => void) | null = null;\n private _resizeHandler: (() => void) | null = null;\n\n constructor(\n container: HTMLElement | ShadowRoot,\n options: SnapOptions = {}\n ) {\n this._container = container;\n this._options = { ...defaultOptions, ...options };\n\n // Initialize subsystems\n this._state = new DragState();\n this._dropZoneManager = new DropZoneManager();\n\n this._engine = new DragEngine({\n container: this._container,\n state: this._state,\n options: this._options,\n getDropZones: () => this._getDropZones(),\n getItemData: (el) => this._getItemData(el),\n getItemAxis: (el) => this._getItemAxis(el),\n });\n\n // Setup state listeners for behaviors\n this._setupStateListeners();\n\n // Initial scan for declarative elements\n this._scanDeclarativeElements();\n\n // Setup auto-refresh if enabled\n if (this._options.autoRefresh) {\n this._setupAutoRefresh();\n }\n\n // Setup scroll/resize handlers\n this._setupScrollResize();\n\n // Enable by default\n this.enable();\n }\n\n /**\n * Current options\n */\n get options(): SnapOptions {\n return this._options;\n }\n\n /**\n * Enable drag and drop\n */\n enable(): void {\n this._engine.enable();\n }\n\n /**\n * Disable drag and drop\n */\n disable(): void {\n this._engine.disable();\n }\n\n /**\n * Cleanup and destroy instance\n */\n destroy(): void {\n this._destroyed = true;\n this.disable();\n\n // Unsubscribe from state listeners\n for (const unsub of this._stateUnsubscribers) {\n unsub();\n }\n this._stateUnsubscribers = [];\n\n // Destroy plugins\n for (const plugin of this._plugins) {\n plugin.destroy();\n }\n this._plugins = [];\n\n // Destroy behaviors\n for (const behavior of this._behaviors) {\n behavior.destroy();\n }\n this._behaviors = [];\n\n // Cleanup subsystems\n this._engine.destroy();\n this._state.destroy();\n this._dropZoneManager.destroy();\n\n // Cleanup observers\n this._observer?.disconnect();\n this._observer = null;\n\n // Cleanup event handlers\n if (this._scrollHandler) {\n window.removeEventListener('scroll', this._scrollHandler, true);\n this._scrollHandler = null;\n }\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n this._resizeHandler = null;\n }\n\n // Clear registrations\n this._imperativeDraggables.clear();\n this._imperativeDropZones.clear();\n }\n\n /**\n * Re-scan for declarative elements (call after DOM changes)\n */\n refresh(): void {\n this._scanDeclarativeElements();\n boundsCache.invalidateAll();\n }\n\n /**\n * Register a draggable element imperatively\n */\n addDraggable(element: HTMLElement, options?: ItemOptions): void {\n this._imperativeDraggables.set(element, options ?? {});\n }\n\n /**\n * Unregister a draggable element\n */\n removeDraggable(element: HTMLElement): void {\n this._imperativeDraggables.delete(element);\n }\n\n /**\n * Register a drop zone imperatively\n */\n addDropZone(element: HTMLElement, options?: DropZoneOptions): void {\n this._imperativeDropZones.set(element, options ?? {});\n this._dropZoneManager.register(element, options);\n }\n\n /**\n * Unregister a drop zone\n */\n removeDropZone(element: HTMLElement): void {\n this._imperativeDropZones.delete(element);\n this._dropZoneManager.unregister(element);\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._state.isDragging();\n }\n\n /**\n * Get the element currently being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._state.getActiveElement();\n }\n\n /**\n * Register a plugin\n */\n use(plugin: Plugin): this {\n this._plugins.push(plugin);\n plugin.init(this);\n return this;\n }\n\n /**\n * Add a behavior\n */\n addBehavior(behavior: Behavior): this {\n this._behaviors.push(behavior);\n return this;\n }\n\n /**\n * Update options dynamically\n */\n setOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n this._engine.updateOptions(this._options);\n }\n\n // Internal methods\n\n private _getDropZones(): HTMLElement[] {\n // Combine declarative and imperative drop zones\n const selector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n const declarative = Array.from(\n containerEl.querySelectorAll<HTMLElement>(selector)\n );\n\n const imperative = [...this._imperativeDropZones.keys()];\n\n // Unique elements\n return [...new Set([...declarative, ...imperative])];\n }\n\n private _getItemData(element: HTMLElement): Record<string, unknown> | undefined {\n return this._imperativeDraggables.get(element)?.data;\n }\n\n private _getItemAxis(element: HTMLElement): Axis | undefined {\n // Check imperative first\n const imperative = this._imperativeDraggables.get(element);\n if (imperative?.axis) return imperative.axis;\n\n // Check data attribute\n const axis = element.dataset.dragAxis as Axis | undefined;\n if (axis === 'x' || axis === 'y' || axis === 'both') {\n return axis;\n }\n\n return undefined;\n }\n\n private _scanDeclarativeElements(): void {\n const dropZoneSelector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n // Register declarative drop zones\n const dropZones = containerEl.querySelectorAll<HTMLElement>(dropZoneSelector);\n for (const zone of dropZones) {\n if (!this._imperativeDropZones.has(zone)) {\n this._dropZoneManager.register(zone);\n }\n }\n }\n\n private _setupStateListeners(): void {\n // Forward state events to behaviors, store unsubscribers for cleanup\n this._stateUnsubscribers.push(\n this._state.subscribe('dragstart', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragStart?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragmove', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragMove?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragend', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragEnd?.(session);\n }\n })\n );\n }\n\n private _setupAutoRefresh(): void {\n this._observer = new MutationObserver((mutations) => {\n // Guard against destroyed instance\n if (this._destroyed) return;\n\n let needsRefresh = false;\n\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n needsRefresh = true;\n break;\n }\n }\n\n if (needsRefresh && !this._refreshScheduled) {\n this._refreshScheduled = true;\n // Debounce refresh\n requestAnimationFrame(() => {\n // Guard against destroyed instance in RAF callback\n if (this._destroyed) return;\n this._refreshScheduled = false;\n this.refresh();\n });\n }\n });\n\n const target = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n this._observer.observe(target, {\n childList: true,\n subtree: true,\n });\n }\n\n private _setupScrollResize(): void {\n // Invalidate bounds cache on scroll (capture phase for nested scrollers)\n this._scrollHandler = () => {\n if (this._state.isDragging()) {\n boundsCache.invalidateAll();\n }\n };\n window.addEventListener('scroll', this._scrollHandler, true);\n\n // Invalidate on resize\n this._resizeHandler = () => {\n boundsCache.invalidateAll();\n };\n window.addEventListener('resize', this._resizeHandler);\n }\n}\n\n// Export as default and named\nexport default Snap;\n", "/**\n * Sortable plugin - enables reordering items within a container\n */\nimport type {\n Plugin,\n SnapInstance,\n SortableOptions,\n DragSession,\n} from '../types/index.js';\nimport { boundsCache, rectCenter } from '../utils/BoundsCache.js';\n\nconst defaultOptions: SortableOptions = {\n animation: 150,\n ghostClass: 'snap-sortable-ghost',\n placeholderClass: 'snap-sortable-placeholder',\n};\n\nexport class Sortable implements Plugin {\n name = 'sortable';\n\n private _snap: SnapInstance | null = null;\n private _options: SortableOptions;\n private _placeholder: HTMLElement | null = null;\n private _originalIndex: number = -1;\n private _currentIndex: number = -1;\n private _container: HTMLElement | null = null;\n private _items: HTMLElement[] = [];\n private _unsubscribers: (() => void)[] = [];\n\n constructor(options: SortableOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Subscribe to state events via the snap options callbacks\n // We wrap them to add sortable behavior\n const originalOnDragStart = snap.options.onDragStart;\n const originalOnDragMove = snap.options.onDragMove;\n const originalOnDrop = snap.options.onDrop;\n const originalOnDragEnd = snap.options.onDragEnd;\n\n snap.setOptions({\n onDragStart: (e) => {\n this._onDragStart(e.element);\n return originalOnDragStart?.(e);\n },\n onDragMove: (e) => {\n this._onDragMove(e.position.x, e.position.y);\n originalOnDragMove?.(e);\n },\n onDrop: (e) => {\n // Add insertion index to event\n const enhancedEvent = {\n ...e,\n insertionIndex: this._currentIndex,\n sourceContainer: this._container ?? undefined,\n };\n originalOnDrop?.(enhancedEvent);\n },\n onDragEnd: (e) => {\n this._onDragEnd();\n originalOnDragEnd?.(e);\n },\n });\n }\n\n destroy(): void {\n this._cleanup();\n for (const unsub of this._unsubscribers) {\n unsub();\n }\n this._unsubscribers = [];\n this._snap = null;\n }\n\n private _onDragStart(element: HTMLElement): void {\n // Find container and items\n this._container = element.parentElement;\n if (!this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n this._items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n );\n\n this._originalIndex = this._items.indexOf(element);\n this._currentIndex = this._originalIndex;\n\n if (this._originalIndex === -1) return;\n\n // Create placeholder\n this._createPlaceholder(element);\n\n // Add ghost class\n if (this._options.ghostClass) {\n element.classList.add(this._options.ghostClass);\n }\n }\n\n private _onDragMove(x: number, y: number): void {\n if (!this._placeholder || !this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n // Get current items (excluding the dragged element)\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n if (items.length === 0) {\n this._currentIndex = 0;\n return;\n }\n\n // Determine list orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical =\n Math.abs(lastRect.top - firstRect.top) >\n Math.abs(lastRect.left - firstRect.left);\n\n // Find new index\n let newIndex = items.length;\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) {\n newIndex = i;\n break;\n }\n } else {\n if (x < center.x) {\n newIndex = i;\n break;\n }\n }\n }\n\n // Adjust for original position\n if (newIndex > this._originalIndex) {\n newIndex++;\n }\n\n if (newIndex !== this._currentIndex) {\n this._currentIndex = newIndex;\n this._movePlaceholder(newIndex);\n }\n }\n\n private _onDragEnd(): void {\n this._cleanup();\n }\n\n private _createPlaceholder(element: HTMLElement): void {\n const rect = element.getBoundingClientRect();\n\n this._placeholder = document.createElement('div');\n this._placeholder.className = this._options.placeholderClass ?? '';\n this._placeholder.style.cssText = `\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n box-sizing: border-box;\n `;\n\n // Insert placeholder at original position\n element.parentNode?.insertBefore(this._placeholder, element);\n }\n\n private _movePlaceholder(index: number): void {\n if (!this._placeholder || !this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement);\n\n // Remove placeholder from current position\n this._placeholder.remove();\n\n // Insert at new position\n if (index >= items.length) {\n this._container.appendChild(this._placeholder);\n } else {\n // Find the item to insert before\n let insertBefore = items[index];\n if (insertBefore === this._placeholder) {\n insertBefore = items[index + 1];\n }\n if (insertBefore) {\n this._container.insertBefore(this._placeholder, insertBefore);\n } else {\n this._container.appendChild(this._placeholder);\n }\n }\n\n // Animate other items if animation enabled\n if (this._options.animation && this._options.animation > 0) {\n this._animateItems();\n }\n }\n\n private _animateItems(): void {\n if (!this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Get positions before\n const positions = new Map<HTMLElement, DOMRect>();\n for (const item of items) {\n positions.set(item, item.getBoundingClientRect());\n }\n\n // Force reflow\n void this._container.offsetHeight;\n\n // Animate from old to new positions\n for (const item of items) {\n const oldRect = positions.get(item);\n const newRect = item.getBoundingClientRect();\n\n if (!oldRect) continue;\n\n const dx = oldRect.left - newRect.left;\n const dy = oldRect.top - newRect.top;\n\n if (dx !== 0 || dy !== 0) {\n item.style.transform = `translate(${dx}px, ${dy}px)`;\n item.style.transition = 'none';\n\n requestAnimationFrame(() => {\n item.style.transition = `transform ${this._options.animation}ms ease`;\n item.style.transform = '';\n });\n }\n }\n }\n\n private _cleanup(): void {\n // Remove placeholder\n this._placeholder?.remove();\n this._placeholder = null;\n\n // Remove ghost class from dragged element\n const activeElement = this._snap?.getActiveElement();\n if (activeElement && this._options.ghostClass) {\n activeElement.classList.remove(this._options.ghostClass);\n }\n\n // Reset state\n this._container = null;\n this._items = [];\n this._originalIndex = -1;\n this._currentIndex = -1;\n\n // Invalidate bounds cache\n boundsCache.invalidateAll();\n }\n\n /**\n * Get the current insertion index during drag\n */\n getCurrentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Get the original index of the dragged item\n */\n getOriginalIndex(): number {\n return this._originalIndex;\n }\n}\n", "/**\n * Kanban plugin - enables moving items between multiple containers\n */\nimport type {\n Plugin,\n SnapInstance,\n KanbanOptions,\n Point,\n} from '../types/index.js';\nimport { boundsCache, pointInRect, rectCenter } from '../utils/BoundsCache.js';\n\nconst defaultOptions: Required<KanbanOptions> = {\n containers: '[data-droppable]',\n items: '[data-draggable]',\n animation: 150,\n};\n\nexport class Kanban implements Plugin {\n name = 'kanban';\n\n private _snap: SnapInstance | null = null;\n private _options: Required<KanbanOptions>;\n private _sourceContainer: HTMLElement | null = null;\n private _targetContainer: HTMLElement | null = null;\n private _placeholder: HTMLElement | null = null;\n private _originalIndex: number = -1;\n private _currentIndex: number = -1;\n\n constructor(options: KanbanOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Wrap snap callbacks\n const originalOnDragStart = snap.options.onDragStart;\n const originalOnDragMove = snap.options.onDragMove;\n const originalOnDropZoneEnter = snap.options.onDropZoneEnter;\n const originalOnDropZoneLeave = snap.options.onDropZoneLeave;\n const originalOnDrop = snap.options.onDrop;\n const originalOnDragEnd = snap.options.onDragEnd;\n\n snap.setOptions({\n onDragStart: (e) => {\n this._onDragStart(e.element);\n return originalOnDragStart?.(e);\n },\n onDragMove: (e) => {\n this._onDragMove(e.position);\n originalOnDragMove?.(e);\n },\n onDropZoneEnter: (e) => {\n this._onDropZoneEnter(e.dropZone);\n originalOnDropZoneEnter?.(e);\n },\n onDropZoneLeave: (e) => {\n this._onDropZoneLeave(e.dropZone);\n originalOnDropZoneLeave?.(e);\n },\n onDrop: (e) => {\n const enhancedEvent = {\n ...e,\n insertionIndex: this._currentIndex,\n sourceContainer: this._sourceContainer ?? undefined,\n };\n originalOnDrop?.(enhancedEvent);\n },\n onDragEnd: (e) => {\n this._onDragEnd();\n originalOnDragEnd?.(e);\n },\n });\n }\n\n destroy(): void {\n this._cleanup();\n this._snap = null;\n }\n\n private _onDragStart(element: HTMLElement): void {\n // Find source container\n this._sourceContainer = element.closest(this._options.containers);\n if (!this._sourceContainer) return;\n\n // Get original index within source container\n const items = Array.from(\n this._sourceContainer.querySelectorAll<HTMLElement>(this._options.items)\n );\n this._originalIndex = items.indexOf(element);\n\n // Create placeholder\n this._createPlaceholder(element);\n }\n\n private _onDragMove(position: Point): void {\n if (!this._targetContainer || !this._placeholder) return;\n\n // Calculate insertion index in target container\n const newIndex = this._calculateInsertionIndex(\n this._targetContainer,\n position.x,\n position.y\n );\n\n if (newIndex !== this._currentIndex) {\n this._currentIndex = newIndex;\n this._movePlaceholder(newIndex);\n }\n }\n\n private _onDropZoneEnter(dropZone: HTMLElement): void {\n // Check if it's a valid container\n if (!dropZone.matches(this._options.containers)) return;\n\n this._targetContainer = dropZone;\n this._targetContainer.classList.add('snap-kanban-target');\n\n // Insert placeholder into new container\n if (this._placeholder) {\n this._targetContainer.appendChild(this._placeholder);\n this._currentIndex = this._getItemCount(this._targetContainer);\n }\n }\n\n private _onDropZoneLeave(dropZone: HTMLElement): void {\n if (dropZone !== this._targetContainer) return;\n\n dropZone.classList.remove('snap-kanban-target');\n\n // Remove placeholder from old container\n this._placeholder?.remove();\n\n this._targetContainer = null;\n this._currentIndex = -1;\n }\n\n private _onDragEnd(): void {\n this._cleanup();\n }\n\n private _createPlaceholder(element: HTMLElement): void {\n const rect = element.getBoundingClientRect();\n\n this._placeholder = document.createElement('div');\n this._placeholder.className = 'snap-kanban-placeholder';\n this._placeholder.style.cssText = `\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n box-sizing: border-box;\n opacity: 0.5;\n border: 2px dashed #ccc;\n border-radius: 4px;\n background: rgba(0, 0, 0, 0.05);\n `;\n\n // Insert in source container initially\n element.parentNode?.insertBefore(this._placeholder, element);\n }\n\n private _movePlaceholder(index: number): void {\n if (!this._placeholder || !this._targetContainer) return;\n\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n this._targetContainer.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Remove from current position\n this._placeholder.remove();\n\n // Insert at new position\n if (index >= items.length) {\n this._targetContainer.appendChild(this._placeholder);\n } else {\n const insertBefore = items[index];\n if (insertBefore) {\n this._targetContainer.insertBefore(this._placeholder, insertBefore);\n } else {\n this._targetContainer.appendChild(this._placeholder);\n }\n }\n\n // Animate if enabled\n if (this._options.animation > 0) {\n this._animateItems(this._targetContainer);\n }\n }\n\n private _calculateInsertionIndex(\n container: HTMLElement,\n x: number,\n y: number\n ): number {\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n if (items.length === 0) return 0;\n\n // Determine orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical =\n Math.abs(lastRect.top - firstRect.top) >\n Math.abs(lastRect.left - firstRect.left);\n\n // Find insertion point\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) return i;\n } else {\n if (x < center.x) return i;\n }\n }\n\n return items.length;\n }\n\n private _getItemCount(container: HTMLElement): number {\n const activeElement = this._snap?.getActiveElement();\n return Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder).length;\n }\n\n private _animateItems(container: HTMLElement): void {\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Store old positions\n const positions = new Map<HTMLElement, DOMRect>();\n for (const item of items) {\n positions.set(item, item.getBoundingClientRect());\n }\n\n // Force reflow\n void container.offsetHeight;\n\n // Animate\n for (const item of items) {\n const oldRect = positions.get(item);\n const newRect = item.getBoundingClientRect();\n\n if (!oldRect) continue;\n\n const dx = oldRect.left - newRect.left;\n const dy = oldRect.top - newRect.top;\n\n if (dx !== 0 || dy !== 0) {\n item.style.transform = `translate(${dx}px, ${dy}px)`;\n item.style.transition = 'none';\n\n requestAnimationFrame(() => {\n item.style.transition = `transform ${this._options.animation}ms ease`;\n item.style.transform = '';\n });\n }\n }\n }\n\n private _cleanup(): void {\n // Remove placeholder\n this._placeholder?.remove();\n this._placeholder = null;\n\n // Remove classes\n this._sourceContainer?.classList.remove('snap-kanban-source');\n this._targetContainer?.classList.remove('snap-kanban-target');\n\n // Reset state\n this._sourceContainer = null;\n this._targetContainer = null;\n this._originalIndex = -1;\n this._currentIndex = -1;\n\n boundsCache.invalidateAll();\n }\n\n /**\n * Get source container during drag\n */\n getSourceContainer(): HTMLElement | null {\n return this._sourceContainer;\n }\n\n /**\n * Get target container during drag\n */\n getTargetContainer(): HTMLElement | null {\n return this._targetContainer;\n }\n\n /**\n * Get current insertion index\n */\n getCurrentIndex(): number {\n return this._currentIndex;\n }\n}\n", "/**\n * File drop sensor for handling external file drags\n * Uses native HTML5 drag and drop API since pointer events\n * don't work for external drags\n */\nimport type { Point, Sensor } from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\n\nexport interface FileSensorEvents {\n dragenter: FileDragEvent;\n dragover: FileDragEvent;\n dragleave: FileDragEvent;\n drop: FileDropEvent;\n}\n\nexport interface FileDragEvent {\n position: Point;\n dropZone: HTMLElement;\n originalEvent: DragEvent;\n}\n\nexport interface FileDropEvent {\n files: File[];\n position: Point;\n dropZone: HTMLElement;\n originalEvent: DragEvent;\n}\n\nexport interface FileSensorOptions {\n container: HTMLElement | ShadowRoot;\n dropZoneSelector: string;\n accept?: string[];\n multiple?: boolean;\n maxSize?: number;\n}\n\nexport class FileSensor\n extends EventEmitter<FileSensorEvents>\n implements Sensor\n{\n private _container: HTMLElement | ShadowRoot;\n private _options: FileSensorOptions;\n private _attached = false;\n private _dragCount = 0;\n private _currentDropZone: HTMLElement | null = null;\n\n constructor(options: FileSensorOptions) {\n super();\n this._container = options.container;\n this._options = options;\n }\n\n attach(): void {\n if (this._attached) return;\n\n const target = this._getEventTarget();\n target.addEventListener('dragenter', this._onDragEnter, { passive: false });\n target.addEventListener('dragover', this._onDragOver, { passive: false });\n target.addEventListener('dragleave', this._onDragLeave, { passive: false });\n target.addEventListener('drop', this._onDrop, { passive: false });\n\n this._attached = true;\n }\n\n detach(): void {\n if (!this._attached) return;\n\n const target = this._getEventTarget();\n target.removeEventListener('dragenter', this._onDragEnter);\n target.removeEventListener('dragover', this._onDragOver);\n target.removeEventListener('dragleave', this._onDragLeave);\n target.removeEventListener('drop', this._onDrop);\n\n this._dragCount = 0;\n this._currentDropZone = null;\n this._attached = false;\n }\n\n private _getEventTarget(): HTMLElement | Document {\n if (this._container instanceof ShadowRoot) {\n return this._container.host as HTMLElement;\n }\n return this._container;\n }\n\n private _onDragEnter = (e: DragEvent): void => {\n // Only handle file drags\n if (!this._hasFiles(e)) return;\n\n this._dragCount++;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n e.preventDefault();\n\n if (dropZone !== this._currentDropZone) {\n if (this._currentDropZone) {\n this.emit('dragleave', {\n position: { x: e.clientX, y: e.clientY },\n dropZone: this._currentDropZone,\n originalEvent: e,\n });\n }\n\n this._currentDropZone = dropZone;\n this.emit('dragenter', {\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n }\n };\n\n private _onDragOver = (e: DragEvent): void => {\n if (!this._hasFiles(e)) return;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n // Must prevent default to allow drop\n e.preventDefault();\n\n // Set drop effect\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'copy';\n }\n\n this.emit('dragover', {\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n };\n\n private _onDragLeave = (e: DragEvent): void => {\n if (!this._hasFiles(e)) return;\n\n this._dragCount--;\n\n // Only emit leave when truly leaving the container\n if (this._dragCount === 0 && this._currentDropZone) {\n this.emit('dragleave', {\n position: { x: e.clientX, y: e.clientY },\n dropZone: this._currentDropZone,\n originalEvent: e,\n });\n this._currentDropZone = null;\n }\n };\n\n private _onDrop = (e: DragEvent): void => {\n e.preventDefault();\n this._dragCount = 0;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n const files = this._getFiles(e);\n if (files.length === 0) return;\n\n this.emit('drop', {\n files,\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n\n this._currentDropZone = null;\n };\n\n private _findDropZone(e: DragEvent): HTMLElement | null {\n const target = e.target as Element;\n\n // Use composedPath for shadow DOM\n const path = e.composedPath();\n for (const el of path) {\n if (!(el instanceof HTMLElement)) continue;\n\n if (el.matches(this._options.dropZoneSelector)) {\n return el;\n }\n\n if (el === this._container || el === (this._container as ShadowRoot).host) {\n break;\n }\n }\n\n return target.closest?.(this._options.dropZoneSelector) as HTMLElement | null;\n }\n\n private _hasFiles(e: DragEvent): boolean {\n if (!e.dataTransfer) return false;\n\n // Check for files in types\n const types = e.dataTransfer.types;\n return types.includes('Files') || types.includes('application/x-moz-file');\n }\n\n private _getFiles(e: DragEvent): File[] {\n if (!e.dataTransfer?.files) return [];\n\n let files = Array.from(e.dataTransfer.files);\n\n // Filter by accept\n const accept = this._options.accept;\n if (accept && accept.length > 0) {\n files = files.filter((file) => this._matchesAccept(file, accept));\n }\n\n // Filter by max size\n const maxSize = this._options.maxSize;\n if (maxSize && maxSize > 0) {\n files = files.filter((file) => file.size <= maxSize);\n }\n\n // Limit to single file if not multiple\n if (!this._options.multiple && files.length > 1) {\n files = [files[0]];\n }\n\n return files;\n }\n\n private _matchesAccept(file: File, accept: string[]): boolean {\n for (const pattern of accept) {\n // Extension match (e.g., \".pdf\")\n if (pattern.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(pattern.toLowerCase())) {\n return true;\n }\n continue;\n }\n\n // MIME type match (e.g., \"image/*\" or \"application/pdf\")\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (file.type.startsWith(prefix)) {\n return true;\n }\n continue;\n }\n\n // Exact MIME match\n if (file.type === pattern) {\n return true;\n }\n }\n\n return false;\n }\n\n destroy(): void {\n this.detach();\n super.destroy();\n }\n}\n", "/**\n * FileDrop plugin - enables file drop zones for external files\n */\nimport type {\n Plugin,\n SnapInstance,\n FileDropOptions,\n FileDropEvent,\n} from '../types/index.js';\nimport {\n FileSensor,\n type FileDropEvent as SensorDropEvent,\n} from '../sensors/FileSensor.js';\n\nconst defaultOptions: FileDropOptions = {\n multiple: true,\n};\n\nexport class FileDrop implements Plugin {\n name = 'file-drop';\n\n private _snap: SnapInstance | null = null;\n private _options: FileDropOptions;\n private _sensor: FileSensor | null = null;\n private _onFileDrop: ((event: FileDropEvent) => void) | null = null;\n\n constructor(options: FileDropOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Get container element\n const container = this._getContainer();\n if (!container) return;\n\n // Initialize file sensor\n this._sensor = new FileSensor({\n container,\n dropZoneSelector: snap.options.dropZoneSelector ?? '[data-file-drop]',\n accept: this._options.accept,\n multiple: this._options.multiple,\n maxSize: this._options.maxSize,\n });\n\n // Setup event handlers\n this._setupEventHandlers();\n\n // Attach sensor\n this._sensor.attach();\n }\n\n destroy(): void {\n this._sensor?.destroy();\n this._sensor = null;\n this._snap = null;\n this._onFileDrop = null;\n }\n\n /**\n * Set callback for file drop events\n */\n onFileDrop(callback: (event: FileDropEvent) => void): this {\n this._onFileDrop = callback;\n return this;\n }\n\n /**\n * Update file drop options\n */\n setOptions(options: Partial<FileDropOptions>): void {\n Object.assign(this._options, options);\n }\n\n private _getContainer(): HTMLElement | ShadowRoot | null {\n if (!this._snap) return null;\n\n // Access internal container - this is a bit of a hack\n // In a real implementation, we'd expose this properly\n return (this._snap as unknown as { _container: HTMLElement | ShadowRoot })._container;\n }\n\n private _setupEventHandlers(): void {\n if (!this._sensor) return;\n\n // Handle drag enter\n this._sensor.on('dragenter', (e) => {\n e.dropZone.classList.add('snap-file-drag-over');\n });\n\n // Handle drag leave\n this._sensor.on('dragleave', (e) => {\n e.dropZone.classList.remove('snap-file-drag-over');\n });\n\n // Handle drop\n this._sensor.on('drop', (e: SensorDropEvent) => {\n e.dropZone.classList.remove('snap-file-drag-over');\n\n const event: FileDropEvent = {\n files: e.files,\n position: e.position,\n dropZone: e.dropZone,\n };\n\n // Call plugin callback\n this._onFileDrop?.(event);\n\n // Also emit through snap options if configured\n const snapOptions = this._snap?.options as unknown as {\n onFileDrop?: (event: FileDropEvent) => void;\n };\n snapOptions?.onFileDrop?.(event);\n });\n }\n}\n\n/**\n * Simple file drop zone creation helper\n * For basic use cases without full Snap instance\n */\nexport function createFileDropZone(\n element: HTMLElement,\n options: FileDropOptions & {\n onDrop: (files: File[]) => void;\n onDragEnter?: () => void;\n onDragLeave?: () => void;\n }\n): () => void {\n const { onDrop, onDragEnter, onDragLeave, ...fileOptions } = options;\n\n let dragCount = 0;\n\n const handleDragEnter = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n dragCount++;\n if (dragCount === 1) {\n element.classList.add('snap-file-drag-over');\n onDragEnter?.();\n }\n };\n\n const handleDragOver = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'copy';\n }\n };\n\n const handleDragLeave = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n dragCount--;\n if (dragCount === 0) {\n element.classList.remove('snap-file-drag-over');\n onDragLeave?.();\n }\n };\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault();\n dragCount = 0;\n element.classList.remove('snap-file-drag-over');\n\n let files = Array.from(e.dataTransfer?.files ?? []);\n\n // Filter by accept\n if (fileOptions.accept?.length) {\n files = files.filter((file) => matchesAccept(file, fileOptions.accept!));\n }\n\n // Filter by max size\n if (fileOptions.maxSize) {\n files = files.filter((file) => file.size <= fileOptions.maxSize!);\n }\n\n // Limit to single file if not multiple\n if (!fileOptions.multiple && files.length > 1) {\n files = [files[0]];\n }\n\n if (files.length > 0) {\n onDrop(files);\n }\n };\n\n // Attach handlers\n element.addEventListener('dragenter', handleDragEnter);\n element.addEventListener('dragover', handleDragOver);\n element.addEventListener('dragleave', handleDragLeave);\n element.addEventListener('drop', handleDrop);\n\n // Return cleanup function\n return () => {\n element.removeEventListener('dragenter', handleDragEnter);\n element.removeEventListener('dragover', handleDragOver);\n element.removeEventListener('dragleave', handleDragLeave);\n element.removeEventListener('drop', handleDrop);\n element.classList.remove('snap-file-drag-over');\n };\n}\n\nfunction hasFiles(e: DragEvent): boolean {\n if (!e.dataTransfer) return false;\n const types = e.dataTransfer.types;\n return types.includes('Files') || types.includes('application/x-moz-file');\n}\n\nfunction matchesAccept(file: File, accept: string[]): boolean {\n for (const pattern of accept) {\n if (pattern.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(pattern.toLowerCase())) {\n return true;\n }\n continue;\n }\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (file.type.startsWith(prefix)) {\n return true;\n }\n continue;\n }\n if (file.type === pattern) {\n return true;\n }\n }\n return false;\n}\n", "/**\n * AutoScroll behavior - scrolls containers when dragging near edges\n */\nimport type { Behavior, DragSession, AutoScrollOptions } from '../types/index.js';\n\nconst defaultOptions: Required<AutoScrollOptions> = {\n threshold: 40,\n maxSpeed: 15,\n acceleration: 2,\n};\n\nexport class AutoScroll implements Behavior {\n name = 'auto-scroll';\n\n private _options: Required<AutoScrollOptions>;\n private _scrollableAncestors: Element[] = [];\n private _rafId: number | null = null;\n private _active = false;\n\n constructor(options: AutoScrollOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n onDragStart(session: DragSession): void {\n this._scrollableAncestors = this._findScrollableAncestors(session.element);\n this._active = true;\n }\n\n onDragMove(session: DragSession): void {\n if (!this._active || this._rafId !== null) return;\n\n this._rafId = requestAnimationFrame(() => {\n this._rafId = null;\n this._performScroll(session.current.x, session.current.y);\n });\n }\n\n onDragEnd(): void {\n this._active = false;\n this._scrollableAncestors = [];\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n destroy(): void {\n this.onDragEnd();\n }\n\n private _performScroll(x: number, y: number): void {\n for (const ancestor of this._scrollableAncestors) {\n const rect = ancestor.getBoundingClientRect();\n const speed = this._calculateScrollSpeed(x, y, rect);\n\n if (speed.x !== 0 || speed.y !== 0) {\n ancestor.scrollBy({\n left: speed.x,\n top: speed.y,\n behavior: 'instant',\n });\n }\n }\n }\n\n private _calculateScrollSpeed(\n x: number,\n y: number,\n rect: DOMRect\n ): { x: number; y: number } {\n const { threshold, maxSpeed } = this._options;\n let scrollX = 0;\n let scrollY = 0;\n\n // Left edge\n if (x < rect.left + threshold) {\n scrollX = -this._getSpeed(rect.left + threshold - x);\n }\n // Right edge\n else if (x > rect.right - threshold) {\n scrollX = this._getSpeed(x - (rect.right - threshold));\n }\n\n // Top edge\n if (y < rect.top + threshold) {\n scrollY = -this._getSpeed(rect.top + threshold - y);\n }\n // Bottom edge\n else if (y > rect.bottom - threshold) {\n scrollY = this._getSpeed(y - (rect.bottom - threshold));\n }\n\n return { x: scrollX, y: scrollY };\n }\n\n private _getSpeed(distance: number): number {\n const { threshold, maxSpeed, acceleration } = this._options;\n const ratio = Math.min(distance / threshold, 1);\n return Math.pow(ratio, acceleration) * maxSpeed;\n }\n\n private _findScrollableAncestors(element: HTMLElement): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = element.parentElement;\n\n while (current && current !== document.body) {\n const style = getComputedStyle(current);\n const overflowX = style.overflowX;\n const overflowY = style.overflowY;\n\n const isScrollableX =\n (overflowX === 'auto' || overflowX === 'scroll') &&\n current.scrollWidth > current.clientWidth;\n\n const isScrollableY =\n (overflowY === 'auto' || overflowY === 'scroll') &&\n current.scrollHeight > current.clientHeight;\n\n if (isScrollableX || isScrollableY) {\n ancestors.push(current);\n }\n\n current = current.parentElement;\n }\n\n // Also include document scroll\n if (\n document.documentElement.scrollHeight > window.innerHeight ||\n document.documentElement.scrollWidth > window.innerWidth\n ) {\n ancestors.push(document.documentElement);\n }\n\n return ancestors;\n }\n}\n", "/**\n * SnapGrid behavior - snaps drag position to a grid\n * Note: This is handled in DragEngine via options.grid\n * This behavior provides additional grid-related features\n */\nimport type { Behavior, DragSession, GridOptions } from '../types/index.js';\n\nexport interface SnapGridOptions extends GridOptions {\n /** Only snap when within threshold of grid line */\n threshold?: number;\n /** Show visual grid guides */\n showGuides?: boolean;\n}\n\nexport class SnapGrid implements Behavior {\n name = 'snap-grid';\n\n private _options: SnapGridOptions;\n private _guideContainer: HTMLElement | null = null;\n\n constructor(options: SnapGridOptions) {\n this._options = options;\n }\n\n onDragStart(session: DragSession): void {\n if (this._options.showGuides) {\n this._createGuides(session.element);\n }\n }\n\n onDragMove(_session: DragSession): void {\n // Grid snapping is handled by DragEngine\n // This behavior could add additional visual feedback\n }\n\n onDragEnd(): void {\n this._removeGuides();\n }\n\n destroy(): void {\n this._removeGuides();\n }\n\n /**\n * Snap a point to the grid\n */\n snap(x: number, y: number): { x: number; y: number } {\n return {\n x: Math.round(x / this._options.x) * this._options.x,\n y: Math.round(y / this._options.y) * this._options.y,\n };\n }\n\n /**\n * Snap with threshold - only snap when close to grid line\n */\n snapWithThreshold(\n x: number,\n y: number,\n threshold?: number\n ): { x: number; y: number } {\n const t = threshold ?? this._options.threshold ?? 5;\n const snapped = this.snap(x, y);\n\n return {\n x: Math.abs(x - snapped.x) < t ? snapped.x : x,\n y: Math.abs(y - snapped.y) < t ? snapped.y : y,\n };\n }\n\n private _createGuides(element: HTMLElement): void {\n const container = element.offsetParent || document.body;\n const rect = container.getBoundingClientRect();\n\n this._guideContainer = document.createElement('div');\n this._guideContainer.style.cssText = `\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 9998;\n `;\n\n // Create vertical lines\n const cols = Math.ceil(rect.width / this._options.x);\n for (let i = 1; i < cols; i++) {\n const line = document.createElement('div');\n line.style.cssText = `\n position: absolute;\n left: ${i * this._options.x}px;\n top: 0;\n bottom: 0;\n width: 1px;\n background: rgba(0, 120, 255, 0.2);\n `;\n this._guideContainer.appendChild(line);\n }\n\n // Create horizontal lines\n const rows = Math.ceil(rect.height / this._options.y);\n for (let i = 1; i < rows; i++) {\n const line = document.createElement('div');\n line.style.cssText = `\n position: absolute;\n top: ${i * this._options.y}px;\n left: 0;\n right: 0;\n height: 1px;\n background: rgba(0, 120, 255, 0.2);\n `;\n this._guideContainer.appendChild(line);\n }\n\n container.appendChild(this._guideContainer);\n }\n\n private _removeGuides(): void {\n this._guideContainer?.remove();\n this._guideContainer = null;\n }\n}\n", "/**\n * ConstraintAxis behavior - constrain movement to specific axis\n * Note: Basic axis constraint is handled in DragEngine via options.axis\n * This behavior adds additional constraint features like bounds\n */\nimport type { Behavior, DragSession, Axis, Point } from '../types/index.js';\n\nexport interface ConstraintOptions {\n axis?: Axis;\n /** Bounding rectangle to constrain within */\n bounds?: {\n minX?: number;\n maxX?: number;\n minY?: number;\n maxY?: number;\n };\n /** Constrain to parent element bounds */\n containWithinParent?: boolean;\n}\n\nexport class ConstraintAxis implements Behavior {\n name = 'constraint-axis';\n\n private _options: ConstraintOptions;\n private _bounds: {\n minX: number;\n maxX: number;\n minY: number;\n maxY: number;\n } | null = null;\n\n constructor(options: ConstraintOptions = {}) {\n this._options = options;\n }\n\n onDragStart(session: DragSession): void {\n if (this._options.containWithinParent) {\n this._calculateParentBounds(session.element);\n } else if (this._options.bounds) {\n this._bounds = {\n minX: this._options.bounds.minX ?? -Infinity,\n maxX: this._options.bounds.maxX ?? Infinity,\n minY: this._options.bounds.minY ?? -Infinity,\n maxY: this._options.bounds.maxY ?? Infinity,\n };\n }\n }\n\n onDragMove(_session: DragSession): void {\n // Constraint is applied in DragEngine\n // This behavior provides bounds calculation\n }\n\n onDragEnd(): void {\n this._bounds = null;\n }\n\n destroy(): void {\n this._bounds = null;\n }\n\n /**\n * Apply constraints to a point\n */\n constrain(point: Point, origin: Point): Point {\n let { x, y } = point;\n\n // Apply axis constraint\n const axis = this._options.axis ?? 'both';\n if (axis === 'x') {\n y = origin.y;\n } else if (axis === 'y') {\n x = origin.x;\n }\n\n // Apply bounds constraint\n if (this._bounds) {\n x = Math.max(this._bounds.minX, Math.min(this._bounds.maxX, x));\n y = Math.max(this._bounds.minY, Math.min(this._bounds.maxY, y));\n }\n\n return { x, y };\n }\n\n /**\n * Get current bounds\n */\n getBounds(): typeof this._bounds {\n return this._bounds;\n }\n\n private _calculateParentBounds(element: HTMLElement): void {\n const parent = element.parentElement;\n if (!parent) return;\n\n const parentRect = parent.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n // Calculate bounds that keep element within parent\n this._bounds = {\n minX: parentRect.left,\n maxX: parentRect.right - elementRect.width,\n minY: parentRect.top,\n maxY: parentRect.bottom - elementRect.height,\n };\n }\n}\n"],
5
- "mappings": "AAQO,IAAMA,EAAN,KAA2D,CAA3D,cACL,KAAQ,WAAa,IAAI,IAKzB,GACEC,EACAC,EACa,CACb,IAAIC,EAAY,KAAK,WAAW,IAAIF,CAAK,EACzC,OAAKE,IACHA,EAAY,IAAI,IAChB,KAAK,WAAW,IAAIF,EAAOE,CAAS,GAEtCA,EAAU,IAAID,CAAyB,EAEhC,IAAM,CACXC,EAAW,OAAOD,CAAyB,EACvCC,EAAW,OAAS,GACtB,KAAK,WAAW,OAAOF,CAAK,CAEhC,CACF,CAKA,KACEA,EACAC,EACa,CACb,IAAME,EAAc,KAAK,GAAGH,EAAQI,GAAS,CAC3CD,EAAY,EACZF,EAASG,CAAI,CACf,CAAC,EACD,OAAOD,CACT,CAKA,KAA6BH,EAAUI,EAAuB,CAC5D,IAAMF,EAAY,KAAK,WAAW,IAAIF,CAAK,EAC3C,GAAIE,EAEF,QAAWD,IAAY,CAAC,GAAGC,CAAS,EAClCD,EAASG,CAAI,CAGnB,CAKA,IAA4BJ,EAAiB,CACvCA,EACF,KAAK,WAAW,OAAOA,CAAK,EAE5B,KAAK,WAAW,MAAM,CAE1B,CAKA,aAAqCA,EAAmB,CACtD,IAAME,EAAY,KAAK,WAAW,IAAIF,CAAK,EAC3C,OAAOE,IAAc,QAAaA,EAAU,KAAO,CACrD,CAKA,cAAsCF,EAAkB,CACtD,OAAO,KAAK,WAAW,IAAIA,CAAK,GAAG,MAAQ,CAC7C,CAKA,SAAgB,CACd,KAAK,WAAW,MAAM,CACxB,CACF,ECtFO,IAAMK,EAAN,MAAMC,CAA0C,CAAhD,cACL,KAAQ,MAAQ,IAAI,IAKpB,QAAQC,EAAcC,EAAsB,CAC1C,KAAK,MAAM,IAAID,EAAMC,CAAK,CAC5B,CAKA,QAAqBD,EAA6B,CAChD,OAAO,KAAK,MAAM,IAAIA,CAAI,CAC5B,CAKA,QAAQA,EAAuB,CAC7B,OAAO,KAAK,MAAM,IAAIA,CAAI,CAC5B,CAKA,IAAI,OAAkB,CACpB,MAAO,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,CAC9B,CAKA,OAAc,CACZ,KAAK,MAAM,MAAM,CACnB,CAKA,OAA0B,CACxB,IAAME,EAAO,IAAIH,EACjB,OAAW,CAACI,EAAKF,CAAK,IAAK,KAAK,MAC9BC,EAAK,QAAQC,EAAKF,CAAK,EAEzB,OAAOC,CACT,CACF,EC9BO,IAAME,EAAN,cAAwBC,CAA0B,CAAlD,kCACL,KAAQ,SAA+B,KACvC,KAAQ,WAAa,EAKrB,IAAI,SAA8B,CAChC,OAAO,KAAK,QACd,CAKA,YAAsB,CACpB,OAAO,KAAK,WAAa,MAAQ,KAAK,SAAS,QAAU,UAC3D,CAKA,kBAAuC,CACrC,OAAO,KAAK,UAAU,SAAW,IACnC,CAKA,oBAAyC,CACvC,OAAO,KAAK,UAAU,UAAY,IACpC,CAKA,UACEC,EACAC,EACAC,EACa,CAET,KAAK,UACP,KAAK,WAAW,EAGlB,IAAMC,EAAO,IAAIC,EACjB,GAAIF,EACF,OAAW,CAACG,EAAKC,CAAK,IAAK,OAAO,QAAQJ,CAAW,EACnDC,EAAK,QAAQE,EAAKC,CAAK,EAI3B,YAAK,SAAW,CACd,GAAI,QAAQ,EAAE,KAAK,UAAU,GAC7B,QAAAN,EACA,OAAQ,CAAE,EAAGC,EAAO,EAAG,EAAGA,EAAO,CAAE,EACnC,QAAS,CAAE,EAAGA,EAAO,EAAG,EAAGA,EAAO,CAAE,EACpC,MAAO,CAAE,EAAG,EAAG,EAAG,CAAE,EACpB,KAAAE,EACA,SAAU,KACV,MAAO,UACT,EAEA,KAAK,KAAK,YAAa,KAAK,QAAQ,EAC7B,KAAK,QACd,CAKA,eAAeI,EAAoB,CAC7B,CAAC,KAAK,UAAY,KAAK,SAAS,QAAU,aAE9C,KAAK,SAAS,QAAQ,EAAIA,EAAM,EAChC,KAAK,SAAS,QAAQ,EAAIA,EAAM,EAChC,KAAK,SAAS,MAAM,EAAIA,EAAM,EAAI,KAAK,SAAS,OAAO,EACvD,KAAK,SAAS,MAAM,EAAIA,EAAM,EAAI,KAAK,SAAS,OAAO,EAEvD,KAAK,KAAK,WAAY,KAAK,QAAQ,EACrC,CAKA,cAAcC,EAAgC,CAC5C,GAAI,CAAC,KAAK,SAAU,OAEpB,IAAMC,EAAW,KAAK,SAAS,SAC3BA,IAAaD,IAGbC,IACF,KAAK,SAAS,SAAW,KACzB,KAAK,KAAK,gBAAiB,KAAK,QAAQ,GAItCD,IACF,KAAK,SAAS,SAAWA,EACzB,KAAK,KAAK,gBAAiB,KAAK,QAAQ,GAE5C,CAKA,SAA8B,CAC5B,GAAI,CAAC,KAAK,SAAU,OAAO,KAE3B,IAAME,EAAU,KAAK,SACrB,OAAAA,EAAQ,MAAQ,WAGZA,EAAQ,UACV,KAAK,KAAK,OAAQA,CAAO,EAG3B,KAAK,KAAK,UAAWA,CAAO,EAC5B,KAAK,SAAW,KAETA,CACT,CAKA,YAAiC,CAC/B,GAAI,CAAC,KAAK,SAAU,OAAO,KAE3B,IAAMA,EAAU,KAAK,SACrB,OAAAA,EAAQ,MAAQ,YAChBA,EAAQ,SAAW,KAEnB,KAAK,KAAK,UAAWA,CAAO,EAC5B,KAAK,SAAW,KAETA,CACT,CAKA,UAAUC,EAAmBC,EAAuD,CAClF,OAAO,KAAK,GAAGD,EAAOC,CAAQ,CAChC,CAKA,OAAc,CACR,KAAK,UACP,KAAK,WAAW,CAEpB,CAKS,SAAgB,CACvB,KAAK,MAAM,EACX,MAAM,QAAQ,CAChB,CACF,ECtLO,IAAMC,EAAN,KAAqB,CAK1B,YAAYC,EAA6B,CAJzC,KAAQ,OAAwB,KAChC,KAAQ,SAAqB,KAgD7B,KAAQ,SAAW,IAAY,CAE7B,GADA,KAAK,OAAS,KACV,KAAK,WAAa,KAAM,CAC1B,IAAMC,EAAO,KAAK,SAClB,KAAK,SAAW,KAChB,KAAK,UAAUA,CAAI,CACrB,CACF,EAnDE,KAAK,UAAYD,CACnB,CAMA,MAAMC,EAAe,CACnB,KAAK,SAAWA,EAEZ,KAAK,SAAW,OAClB,KAAK,OAAS,sBAAsB,KAAK,QAAQ,EAErD,CAKA,QAAe,CACT,KAAK,SAAW,OAClB,qBAAqB,KAAK,MAAM,EAChC,KAAK,OAAS,MAEhB,KAAK,SAAW,IAClB,CAKA,OAAc,CACR,KAAK,WAAa,OACpB,KAAK,OAAO,EACZ,KAAK,UAAU,KAAK,QAAQ,EAC5B,KAAK,SAAW,KAEpB,CAKA,IAAI,WAAqB,CACvB,OAAO,KAAK,SAAW,IACzB,CAcA,SAAgB,CACd,KAAK,OAAO,CACd,CACF,EAKO,SAASC,EACdC,EAC+C,CAC/C,IAAIC,EAAuB,KACvBC,EAAiC,KAE/BC,EAAa,IAAIC,IAAwB,CAC7CF,EAAWE,EACPH,IAAU,OACZA,EAAQ,sBAAsB,IAAM,CAClCA,EAAQ,KACJC,IAAa,OACfF,EAAG,GAAGE,CAAQ,EACdA,EAAW,KAEf,CAAC,EAEL,EAEA,OAAAC,EAAU,OAAS,IAAM,CACnBF,IAAU,OACZ,qBAAqBA,CAAK,EAC1BA,EAAQ,MAEVC,EAAW,IACb,EAEAC,EAAU,MAAQ,IAAM,CAClBF,IAAU,OACZ,qBAAqBA,CAAK,EAC1BA,EAAQ,MAENC,IAAa,OACfF,EAAG,GAAGE,CAAQ,EACdA,EAAW,KAEf,EAEOC,CACT,CC7GO,IAAME,EAAN,KAAoB,CAMzB,YACEC,EACAC,EACAC,EAAc,GACdC,EAAU,IACV,CAVF,KAAQ,MAAa,CAAC,EAWpB,KAAK,SAAWH,EAChB,KAAK,OAASC,EACd,KAAK,SAAWE,EAGhB,QAAS,EAAI,EAAG,EAAID,EAAa,IAC/B,KAAK,MAAM,KAAKF,EAAQ,CAAC,CAE7B,CAKA,SAAa,CACX,OAAO,KAAK,MAAM,IAAI,GAAK,KAAK,SAAS,CAC3C,CAKA,QAAQI,EAAc,CAChB,KAAK,MAAM,OAAS,KAAK,WAC3B,KAAK,OAAOA,CAAG,EACf,KAAK,MAAM,KAAKA,CAAG,EAEvB,CAKA,OAAc,CACZ,KAAK,MAAM,OAAS,CACtB,CAKA,IAAI,MAAe,CACjB,OAAO,KAAK,MAAM,MACpB,CACF,EAKaC,EAAY,IAAIN,EAC3B,KAAO,CAAE,EAAG,EAAG,EAAG,CAAE,GACnBO,GAAM,CACLA,EAAE,EAAI,EACNA,EAAE,EAAI,CACR,CACF,EAEaC,EAAW,IAAIR,EAC1B,KAAO,CAAE,EAAG,EAAG,EAAG,EAAG,MAAO,EAAG,OAAQ,CAAE,GACxC,GAAM,CACL,EAAE,EAAI,EACN,EAAE,EAAI,EACN,EAAE,MAAQ,EACV,EAAE,OAAS,CACb,CACF,EAKO,SAASS,EAAaC,EAAWC,EAAkB,CACxD,IAAMJ,EAAID,EAAU,QAAQ,EAC5B,OAAAC,EAAE,EAAIG,EACNH,EAAE,EAAII,EACCJ,CACT,CC3CO,IAAMK,EAAN,cACGC,CAEV,CAeE,YAAYC,EAA+B,CACzC,MAAM,EAbR,KAAQ,UAAY,GAGpB,KAAQ,iBAAkC,KAC1C,KAAQ,eAAqC,KAC7C,KAAQ,eAA+B,KACvC,KAAQ,YAAc,GACtB,KAAQ,YAA6B,KA8DrC,KAAQ,eAAkBC,GAA0B,CAKlD,GAHI,CAACA,EAAE,WAAaA,EAAE,SAAW,GAG7B,KAAK,mBAAqB,KAAM,OAGpC,IAAMC,EAAY,KAAK,eAAeD,CAAC,EAIvC,GAHI,CAACC,GAGD,KAAK,SAAS,gBAEZ,CADW,KAAK,YAAYD,EAAGC,CAAS,EAC/B,OAIfD,EAAE,eAAe,EAGjB,KAAK,iBAAmBA,EAAE,UAC1B,KAAK,eAAiBC,EACtB,KAAK,eAAiBC,EAAaF,EAAE,QAASA,EAAE,OAAO,EACvD,KAAK,YAAc,GAGlBA,EAAE,OAAuB,kBAAkBA,EAAE,SAAS,EAGvD,IAAMG,EAAS,KAAK,gBAAgB,EACpCA,EAAO,iBAAiB,cAAe,KAAK,eAAgB,CAC1D,QAAS,EACX,CAAC,EACDA,EAAO,iBAAiB,YAAa,KAAK,YAAY,EACtDA,EAAO,iBAAiB,gBAAiB,KAAK,gBAAgB,EAG9D,IAAMC,EAAQ,KAAK,SAAS,OAAS,EACjCA,EAAQ,EACV,KAAK,YAAc,OAAO,WAAW,IAAM,CACzC,KAAK,YAAc,KACnB,KAAK,WAAWJ,CAAC,CACnB,EAAGI,CAAK,GACE,KAAK,SAAS,UAAY,KAAO,GAE3C,KAAK,WAAWJ,CAAC,CAErB,EAEA,KAAQ,eAAkBA,GAA0B,CAC9CA,EAAE,YAAc,KAAK,kBAGzB,KAAK,cAAc,MAAMA,CAAC,CAC5B,EAEA,KAAQ,aAAgBA,GAA0B,CAChD,GAAI,CAAC,KAAK,gBAAkB,CAAC,KAAK,eAAgB,OAElD,IAAMK,EAAWH,EAAaF,EAAE,QAASA,EAAE,OAAO,EAGlD,GAAI,CAAC,KAAK,YAAa,CACrB,IAAMM,EAAW,KAAK,SAAS,UAAY,EAC3C,GAAIA,EAAW,EAAG,CAChB,IAAMC,EAAKF,EAAS,EAAI,KAAK,eAAe,EACtCG,EAAKH,EAAS,EAAI,KAAK,eAAe,EAG5C,GAFa,KAAK,KAAKE,EAAKA,EAAKC,EAAKA,CAAE,EAE7BF,EAAU,CACnBG,EAAU,QAAQJ,CAAQ,EAC1B,MACF,CAGA,KAAK,iBAAiB,EACtB,KAAK,WAAWL,CAAC,CACnB,CACF,CAEA,GAAI,KAAK,YAAa,CACpB,IAAMU,EAAQR,EACZG,EAAS,EAAI,KAAK,eAAe,EACjCA,EAAS,EAAI,KAAK,eAAe,CACnC,EAEA,KAAK,KAAK,cAAe,CACvB,SAAAA,EACA,MAAAK,EACA,UAAWV,EAAE,UACb,cAAeA,CACjB,CAAC,CAGH,MACES,EAAU,QAAQJ,CAAQ,CAE9B,EAEA,KAAQ,aAAgBL,GAA0B,CAC5CA,EAAE,YAAc,KAAK,mBAEzB,KAAK,cAAc,MAAM,EAErB,KAAK,aACP,KAAK,KAAK,YAAa,CACrB,SAAUE,EAAaF,EAAE,QAASA,EAAE,OAAO,EAC3C,UAAWA,EAAE,UACb,cAAeA,CACjB,CAAC,EAGH,KAAK,SAAS,EAChB,EAEA,KAAQ,iBAAoBA,GAA0B,CAChDA,EAAE,YAAc,KAAK,mBAEzB,KAAK,cAAc,OAAO,EAEtB,KAAK,aACP,KAAK,KAAK,gBAAiB,CACzB,SAAUE,EAAaF,EAAE,QAASA,EAAE,OAAO,EAC3C,UAAWA,EAAE,UACb,cAAeA,CACjB,CAAC,EAGH,KAAK,SAAS,EAChB,EAzLE,KAAK,WAAaD,EAAQ,UAC1B,KAAK,SAAWA,EAEhB,KAAK,cAAgB,IAAIY,EAAaX,GAAM,KAAK,aAAaA,CAAC,CAAC,CAClE,CAKA,QAAe,CACb,GAAI,KAAK,UAAW,OAEL,KAAK,gBAAgB,EAC7B,iBAAiB,cAAe,KAAK,eAAgB,CAC1D,QAAS,EACX,CAAC,EAED,KAAK,UAAY,EACnB,CAKA,QAAe,CACb,GAAI,CAAC,KAAK,UAAW,OAEN,KAAK,gBAAgB,EAC7B,oBAAoB,cAAe,KAAK,cAAc,EAE7D,KAAK,SAAS,EACd,KAAK,UAAY,EACnB,CAKA,IAAI,UAAoB,CACtB,OAAO,KAAK,mBAAqB,IACnC,CAKA,IAAI,YAAsB,CACxB,OAAO,KAAK,WACd,CAEQ,iBAA0C,CAEhD,OAAI,KAAK,sBAAsB,WACtB,KAAK,WAAW,KAElB,KAAK,UACd,CAsIQ,WAAWA,EAAuB,CACpC,KAAK,aAAe,CAAC,KAAK,gBAAkB,CAAC,KAAK,iBAEtD,KAAK,YAAc,GAEnB,KAAK,KAAK,cAAe,CACvB,QAAS,KAAK,eACd,SAAU,CAAE,EAAG,KAAK,eAAe,EAAG,EAAG,KAAK,eAAe,CAAE,EAC/D,UAAWA,EAAE,UACb,cAAeA,CACjB,CAAC,EACH,CAEQ,eAAeA,EAAqC,CAC1D,IAAMG,EAASH,EAAE,OAGXY,EAAOZ,EAAE,aAAa,EAE5B,QAAWa,KAAMD,EACf,GAAMC,aAAc,YAEpB,IAAIA,EAAG,QAAQ,KAAK,SAAS,iBAAiB,EAC5C,OAAOA,EAIT,GAAIA,IAAO,KAAK,YAAcA,IAAQ,KAAK,WAA0B,KACnE,MAKJ,OAAOV,EAAO,UAAU,KAAK,SAAS,iBAAiB,CACzD,CAEQ,YAAYH,EAAiBC,EAA4C,CAC/E,GAAI,CAAC,KAAK,SAAS,eAAgB,OAAOA,EAG1C,IAAMa,EADSd,EAAE,OACK,UAAU,KAAK,SAAS,cAAc,EAG5D,OAAIc,GAAUb,EAAU,SAASa,CAAM,EAC9BA,EAGF,IACT,CAEQ,kBAAyB,CAC3B,KAAK,cAAgB,OACvB,aAAa,KAAK,WAAW,EAC7B,KAAK,YAAc,KAEvB,CAEQ,UAAiB,CACvB,KAAK,iBAAiB,EACtB,KAAK,cAAc,OAAO,EAGtB,KAAK,iBACPL,EAAU,QAAQ,KAAK,cAAc,EACrC,KAAK,eAAiB,MAIxB,IAAMN,EAAS,KAAK,gBAAgB,EACpCA,EAAO,oBAAoB,cAAe,KAAK,cAAc,EAC7DA,EAAO,oBAAoB,YAAa,KAAK,YAAY,EACzDA,EAAO,oBAAoB,gBAAiB,KAAK,gBAAgB,EAEjE,KAAK,iBAAmB,KACxB,KAAK,eAAiB,KACtB,KAAK,YAAc,EACrB,CAKA,SAAgB,CACd,KAAK,OAAO,EACZ,KAAK,cAAc,QAAQ,EAC3B,MAAM,QAAQ,CAChB,CACF,EC7UO,IAAMY,EAAN,KAAkB,CAAlB,cACL,KAAQ,OAAS,IAAI,QACrB,KAAQ,OAAS,IAAI,QACrB,KAAQ,eAAiB,GAKzB,IAAIC,EAA2B,CAC7B,GAAI,KAAK,gBAAkB,KAAK,OAAO,IAAIA,CAAO,EAChD,OAAO,KAAK,QAAQA,CAAO,EAG7B,IAAMC,EAAS,KAAK,OAAO,IAAID,CAAO,EACtC,OAAIC,GAIG,KAAK,QAAQD,CAAO,CAC7B,CAKA,WAAWA,EAAwB,CACjC,KAAK,OAAO,IAAIA,CAAO,CACzB,CAKA,eAAsB,CACpB,KAAK,eAAiB,EACxB,CAKA,OAAOA,EAA2B,CAChC,OAAO,KAAK,QAAQA,CAAO,CAC7B,CAKA,OAAOA,EAAwB,CAC7B,KAAK,OAAO,OAAOA,CAAO,CAC5B,CAKA,YAAmB,CACjB,KAAK,eAAiB,EAGxB,CAEQ,QAAQA,EAA2B,CACzC,IAAME,EAAOF,EAAQ,sBAAsB,EAC3C,YAAK,OAAO,IAAIA,EAASE,CAAI,EAC7B,KAAK,OAAO,OAAOF,CAAO,EACnBE,CACT,CACF,EAGaC,EAAc,IAAIJ,EAKxB,SAASK,EAAYC,EAAWC,EAAWJ,EAAwB,CACxE,OACEG,GAAKH,EAAK,MAAQG,GAAKH,EAAK,OAASI,GAAKJ,EAAK,KAAOI,GAAKJ,EAAK,MAEpE,CAiBO,SAASK,EAAWC,EAAyC,CAClE,MAAO,CACL,EAAGA,EAAK,KAAOA,EAAK,MAAQ,EAC5B,EAAGA,EAAK,IAAMA,EAAK,OAAS,CAC9B,CACF,CC9EO,IAAMC,EAAN,KAAiB,CAgBtB,YAAYC,EAAkC,CAP9C,KAAQ,SAAW,GACnB,KAAQ,uBAAyC,CAAC,EAGlD,KAAQ,OAA6B,KACrC,KAAQ,aAAsB,CAAE,EAAG,EAAG,EAAG,CAAE,EAiE3C,KAAQ,eAAkBC,GAAmC,CAC3D,GAAM,CAAE,QAAAC,EAAS,SAAAC,CAAS,EAAIF,EAGxBG,EAAO,KAAK,aAAaF,CAAO,GAAK,KAAK,uBAAuBA,CAAO,EAGxEG,EAAU,KAAK,OAAO,UAAUH,EAASC,EAAUC,CAAI,EAGvDE,EAAa,CACjB,QAAAJ,EACA,SAAU,CAAE,EAAGC,EAAS,EAAG,EAAGA,EAAS,CAAE,EACzC,KAAME,EAAQ,KACd,OAAQ,IAAM,CACZ,KAAK,OAAO,WAAW,CACzB,CACF,EAGA,GADe,KAAK,SAAS,cAAcC,CAAU,IACtC,GAAO,CACpB,KAAK,OAAO,WAAW,EACvB,MACF,CAGA,KAAK,aAAaJ,EAASC,CAAQ,EAGnCD,EAAQ,UAAU,IAAI,eAAe,EACjC,KAAK,SAAS,YAChBA,EAAQ,UAAU,IAAI,KAAK,SAAS,UAAU,EAIhDK,EAAY,cAAc,CAC5B,EAEA,KAAQ,eAAkBN,GAAkC,CAC1D,IAAMI,EAAU,KAAK,OAAO,QAC5B,GAAI,CAACA,EAAS,OAEd,GAAI,CAAE,SAAAF,CAAS,EAAIF,EAGbO,EAAO,KAAK,aAAaH,EAAQ,OAAO,GAAK,KAAK,SAAS,MAAQ,OACrEG,IAAS,SACXL,EAAW,KAAK,qBAAqBA,EAAUE,EAAQ,OAAQG,CAAI,GAIjE,KAAK,SAAS,OAChBL,EAAW,KAAK,eAAeA,EAAU,KAAK,SAAS,IAAI,GAI7D,KAAK,OAAO,eAAeA,CAAQ,EAGnC,KAAK,aAAaA,CAAQ,EAG1B,KAAK,gBAAgBA,CAAQ,EAG7B,KAAK,SAAS,aAAa,CACzB,QAASE,EAAQ,QACjB,SAAU,CAAE,EAAGA,EAAQ,QAAQ,EAAG,EAAGA,EAAQ,QAAQ,CAAE,EACvD,MAAO,CAAE,EAAGA,EAAQ,MAAM,EAAG,EAAGA,EAAQ,MAAM,CAAE,EAChD,SAAUA,EAAQ,QACpB,CAAC,CACH,EAEA,KAAQ,aAAgBJ,GAAiC,CAEvD,GAAI,CADY,KAAK,OAAO,QACd,OAGd,IAAMQ,EAAe,KAAK,OAAO,QAAQ,EACpCA,IAGL,KAAK,SAASA,EAAa,OAAO,EAG9BA,EAAa,UACf,KAAK,SAAS,SAAS,CACrB,QAASA,EAAa,QACtB,SAAUA,EAAa,SACvB,SAAU,CAAE,EAAGA,EAAa,QAAQ,EAAG,EAAGA,EAAa,QAAQ,CAAE,EACjE,KAAMA,EAAa,IACrB,CAAC,EAIH,KAAK,SAAS,YAAY,CACxB,QAASA,EAAa,QACtB,SAAU,CAAE,EAAGA,EAAa,QAAQ,EAAG,EAAGA,EAAa,QAAQ,CAAE,EACjE,MAAO,CAAE,EAAGA,EAAa,MAAM,EAAG,EAAGA,EAAa,MAAM,CAAE,EAC1D,UAAW,EACb,CAAC,EACH,EAEA,KAAQ,iBAAoBR,GAAiC,CAC3D,IAAMI,EAAU,KAAK,OAAO,QAC5B,GAAI,CAACA,EAAS,OAEd,IAAMH,EAAUG,EAAQ,QACxB,KAAK,OAAO,WAAW,EACvB,KAAK,SAASH,CAAO,EAErB,KAAK,SAAS,YAAY,CACxB,QAAAA,EACA,SAAUD,EAAM,SAChB,MAAO,CAAE,EAAG,EAAG,EAAG,CAAE,EACpB,UAAW,EACb,CAAC,CACH,EAnLE,KAAK,WAAaD,EAAc,UAChC,KAAK,OAASA,EAAc,MAC5B,KAAK,SAAWA,EAAc,QAC9B,KAAK,cAAgBA,EAAc,aACnC,KAAK,aAAeA,EAAc,YAClC,KAAK,aAAeA,EAAc,YAGlC,KAAK,eAAiB,IAAIU,EAAc,CACtC,UAAW,KAAK,WAChB,kBAAmB,KAAK,SAAS,mBAAqB,mBACtD,eAAgB,KAAK,SAAS,eAC9B,MAAO,KAAK,SAAS,MACrB,SAAU,KAAK,SAAS,QAC1B,CAAC,EAED,KAAK,gBAAgB,CACvB,CAKA,QAAe,CACT,KAAK,WACT,KAAK,eAAe,OAAO,EAC3B,KAAK,SAAW,GAClB,CAKA,SAAgB,CACT,KAAK,WACV,KAAK,eAAe,OAAO,EAC3B,KAAK,OAAO,MAAM,EAClB,KAAK,aAAa,EAClB,KAAK,SAAW,GAClB,CAKA,IAAI,WAAqB,CACvB,OAAO,KAAK,QACd,CAKA,cAAcC,EAAqC,CACjD,OAAO,OAAO,KAAK,SAAUA,CAAO,CACtC,CAEQ,iBAAwB,CAC9B,KAAK,uBAAuB,KAC1B,KAAK,eAAe,GAAG,cAAe,KAAK,cAAc,EACzD,KAAK,eAAe,GAAG,cAAe,KAAK,cAAc,EACzD,KAAK,eAAe,GAAG,YAAa,KAAK,YAAY,EACrD,KAAK,eAAe,GAAG,gBAAiB,KAAK,gBAAgB,CAC/D,CACF,CAyHQ,qBAAqBR,EAAiBS,EAAeJ,EAAmB,CAC9E,OAAIA,IAAS,IACJ,CAAE,EAAGL,EAAS,EAAG,EAAGS,EAAO,CAAE,EAElCJ,IAAS,IACJ,CAAE,EAAGI,EAAO,EAAG,EAAGT,EAAS,CAAE,EAE/BA,CACT,CAEQ,eAAeA,EAAiBU,EAAuC,CAC7E,MAAO,CACL,EAAG,KAAK,MAAMV,EAAS,EAAIU,EAAK,CAAC,EAAIA,EAAK,EAC1C,EAAG,KAAK,MAAMV,EAAS,EAAIU,EAAK,CAAC,EAAIA,EAAK,CAC5C,CACF,CAEQ,gBAAgBV,EAAuB,CAC7C,IAAMW,EAAY,KAAK,cAAc,EACjCC,EAAgC,KAEpC,QAAWC,KAAQF,EAAW,CAC5B,IAAMG,EAAOV,EAAY,IAAIS,CAAI,EACjC,GAAIE,EAAYf,EAAS,EAAGA,EAAS,EAAGc,CAAI,EAAG,CAC7CF,EAAYC,EACZ,KACF,CACF,CAEA,IAAMX,EAAU,KAAK,OAAO,QACvBA,GAGDU,IAAcV,EAAQ,WACpBA,EAAQ,UACV,KAAK,SAAS,kBAAkB,CAC9B,QAASA,EAAQ,QACjB,SAAUA,EAAQ,QACpB,CAAC,EAGH,KAAK,OAAO,cAAcU,CAAS,EAE/BA,GACF,KAAK,SAAS,kBAAkB,CAC9B,QAASV,EAAQ,QACjB,SAAUU,EACV,SAAAZ,CACF,CAAC,EAGP,CAEQ,aAAaD,EAAsBC,EAAuB,CAChE,IAAMc,EAAOf,EAAQ,sBAAsB,EAG3C,KAAK,aAAe,CAClB,EAAGC,EAAS,EAAIc,EAAK,KACrB,EAAGd,EAAS,EAAIc,EAAK,GACvB,EAGA,KAAK,OAASf,EAAQ,UAAU,EAAI,EACpC,KAAK,OAAO,MAAM,QAAU;AAAA;AAAA,cAElBe,EAAK,IAAI;AAAA,aACVA,EAAK,GAAG;AAAA,eACNA,EAAK,KAAK;AAAA,gBACTA,EAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOvB,KAAK,OAAO,UAAU,IAAI,YAAY,EAGtC,SAAS,KAAK,YAAY,KAAK,MAAM,CACvC,CAEQ,aAAad,EAAuB,CAC1C,GAAI,CAAC,KAAK,OAAQ,OAElB,IAAMgB,EAAIhB,EAAS,EAAI,KAAK,aAAa,EACnCiB,EAAIjB,EAAS,EAAI,KAAK,aAAa,EAGzC,KAAK,OAAO,MAAM,UAAY,aAAagB,EAAI,WAAW,KAAK,OAAO,MAAM,IAAI,CAAC,OAAOC,EAAI,WAAW,KAAK,OAAO,MAAM,GAAG,CAAC,KAC/H,CAEQ,cAAqB,CACvB,KAAK,SACP,KAAK,OAAO,OAAO,EACnB,KAAK,OAAS,KAElB,CAEQ,SAASlB,EAA4B,CAC3CA,EAAQ,UAAU,OAAO,eAAe,EACpC,KAAK,SAAS,YAChBA,EAAQ,UAAU,OAAO,KAAK,SAAS,UAAU,EAEnD,KAAK,aAAa,CACpB,CAEQ,uBAAuBA,EAA+C,CAC5E,IAAME,EAAgC,CAAC,EAGvC,QAAWiB,KAAQnB,EAAQ,WACzB,GAAImB,EAAK,KAAK,WAAW,YAAY,EAAG,CACtC,IAAMC,EAAMD,EAAK,KAAK,MAAM,EAAE,EAC9BjB,EAAKkB,CAAG,EAAID,EAAK,KACnB,CAIF,IAAME,EAAiBrB,EAAQ,QAAQ,UACvC,OAAIqB,GAAkBA,IAAmB,KACvCnB,EAAK,KAAOmB,GAGPnB,CACT,CAKA,SAAgB,CACd,KAAK,QAAQ,EAGb,QAAWoB,KAAS,KAAK,uBACvBA,EAAM,EAER,KAAK,uBAAyB,CAAC,EAE/B,KAAK,eAAe,QAAQ,CAC9B,CACF,ECpWO,IAAMC,EAAN,KAAe,CAKpB,YAAYC,EAAsBC,EAA2B,CAAC,EAAG,CAFjE,KAAQ,UAAY,GAGlB,KAAK,SAAWD,EAChB,KAAK,SAAWC,CAClB,CAKA,IAAI,SAAuB,CACzB,OAAO,KAAK,QACd,CAKA,IAAI,UAAoB,CACtB,OAAO,KAAK,SACd,CAKA,WAAWA,EAAyC,CAClD,OAAO,OAAO,KAAK,SAAUA,CAAO,CACtC,CAKA,cAAcC,EAAWC,EAAoB,CAC3C,IAAMC,EAAOC,EAAY,IAAI,KAAK,QAAQ,EAC1C,OAAOC,EAAYJ,EAAGC,EAAGC,CAAI,CAC/B,CAKA,QAAQG,EAA6B,CACnC,GAAM,CAAE,QAAAC,CAAQ,EAAI,KAAK,SAEzB,GAAI,CAACA,EAAS,MAAO,GAErB,GAAI,OAAOA,GAAY,WACrB,OAAOA,EAAQD,CAAI,EAIrB,QAAWE,KAAQD,EACjB,GAAID,EAAK,QAAQE,CAAI,GAAKF,EAAK,QAAQ,MAAM,IAAME,EACjD,MAAO,GAKX,IAAMC,EAAiB,KAAK,SAAS,QAAQ,QAC7C,GAAIA,EAAgB,CAClB,IAAMC,EAAgBD,EAAe,MAAM,GAAG,EAAE,IAAKE,GAAMA,EAAE,KAAK,CAAC,EACnE,QAAWH,KAAQE,EACjB,GAAIJ,EAAK,QAAQE,CAAI,GAAKF,EAAK,QAAQ,MAAM,IAAME,EACjD,MAAO,EAGb,CAEA,MAAO,EACT,CAKA,UAAUI,EAAuB,CAC3B,KAAK,YAAcA,IAEvB,KAAK,UAAYA,EAEbA,EACF,KAAK,SAAS,UAAU,IAAI,kBAAkB,EAE9C,KAAK,SAAS,UAAU,OAAO,kBAAkB,EAErD,CAMA,kBACEX,EACAC,EACAW,EACAC,EACQ,CACR,IAAMC,EAAQ,MAAM,KAClB,KAAK,SAAS,iBAA8BF,CAAY,CAC1D,EAAE,OAAQG,GAAOA,IAAOF,CAAc,EAEtC,GAAIC,EAAM,SAAW,EAAG,MAAO,GAG/B,IAAME,EAAYb,EAAY,IAAIW,EAAM,CAAC,CAAC,EACpCG,EAAWd,EAAY,IAAIW,EAAMA,EAAM,OAAS,CAAC,CAAC,EAClDI,EAAa,KAAK,IAAID,EAAS,IAAMD,EAAU,GAAG,EAAI,KAAK,IAAIC,EAAS,KAAOD,EAAU,IAAI,EAEnG,QAASG,EAAI,EAAGA,EAAIL,EAAM,OAAQK,IAAK,CACrC,IAAMjB,EAAOC,EAAY,IAAIW,EAAMK,CAAC,CAAC,EAC/BC,EAASC,EAAWnB,CAAI,EAE9B,GAAIgB,GACF,GAAIjB,EAAImB,EAAO,EAAG,OAAOD,UAErBnB,EAAIoB,EAAO,EAAG,OAAOD,CAE7B,CAEA,OAAOL,EAAM,MACf,CAKA,eACEd,EACAC,EACAW,EACAC,EAC+D,CAC/D,IAAMC,EAAQ,MAAM,KAClB,KAAK,SAAS,iBAA8BF,CAAY,CAC1D,EAAE,OAAQG,GAAOA,IAAOF,CAAc,EAEtC,GAAIC,EAAM,SAAW,EAAG,OAAO,KAE/B,IAAIQ,EAAkC,KAClCC,EAAkB,IAClBC,EAA+B,QAG7BR,EAAYb,EAAY,IAAIW,EAAM,CAAC,CAAC,EACpCG,EAAWd,EAAY,IAAIW,EAAMA,EAAM,OAAS,CAAC,CAAC,EAClDI,EAAa,KAAK,IAAID,EAAS,IAAMD,EAAU,GAAG,EAAI,KAAK,IAAIC,EAAS,KAAOD,EAAU,IAAI,EAEnG,QAAWS,KAAQX,EAAO,CACxB,IAAMZ,EAAOC,EAAY,IAAIsB,CAAI,EAC3BL,EAASC,EAAWnB,CAAI,EAExBwB,EAAK1B,EAAIoB,EAAO,EAChBO,EAAK1B,EAAImB,EAAO,EAChBQ,EAAW,KAAK,KAAKF,EAAKA,EAAKC,EAAKA,CAAE,EAExCC,EAAWL,IACbA,EAAkBK,EAClBN,EAAcG,EACdD,EAAWN,EAAcjB,EAAImB,EAAO,EAAI,SAAW,QAAYpB,EAAIoB,EAAO,EAAI,SAAW,QAE7F,CAEA,OAAKE,EAEE,CAAE,QAASA,EAAa,SAAAE,CAAS,EAFf,IAG3B,CAKA,cAAqB,CACnBrB,EAAY,OAAO,KAAK,QAAQ,CAClC,CAKA,SAAgB,CACd,KAAK,UAAU,EAAK,EACpBA,EAAY,OAAO,KAAK,QAAQ,CAClC,CACF,EAKa0B,EAAN,KAAsB,CAAtB,cACL,KAAQ,OAAS,IAAI,IAKrB,SAAS/B,EAAsBC,EAAqC,CAClE,IAAI+B,EAAO,KAAK,OAAO,IAAIhC,CAAO,EAClC,OAAIgC,GACE/B,GAAS+B,EAAK,WAAW/B,CAAO,EAC7B+B,IAGTA,EAAO,IAAIjC,EAASC,EAASC,CAAO,EACpC,KAAK,OAAO,IAAID,EAASgC,CAAI,EACtBA,EACT,CAKA,WAAWhC,EAA4B,CACrC,IAAMgC,EAAO,KAAK,OAAO,IAAIhC,CAAO,EAChCgC,IACFA,EAAK,QAAQ,EACb,KAAK,OAAO,OAAOhC,CAAO,EAE9B,CAKA,IAAIA,EAA4C,CAC9C,OAAO,KAAK,OAAO,IAAIA,CAAO,CAChC,CAKA,aAA6B,CAC3B,MAAO,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,CAC/B,CAKA,QAAqB,CACnB,MAAO,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,CACjC,CAKA,YAAYE,EAAWC,EAA4B,CACjD,QAAW6B,KAAQ,KAAK,OAAO,OAAO,EACpC,GAAIA,EAAK,cAAc9B,EAAGC,CAAC,EACzB,OAAO6B,EAGX,OAAO,IACT,CAKA,OAAc,CACZ,QAAWA,KAAQ,KAAK,OAAO,OAAO,EACpCA,EAAK,QAAQ,EAEf,KAAK,OAAO,MAAM,CACpB,CAKA,iBAAwB,CACtB3B,EAAY,cAAc,CAC5B,CAKA,SAAgB,CACd,KAAK,MAAM,CACb,CACF,EClQA,IAAM4B,EAA8B,CAClC,kBAAmB,mBACnB,iBAAkB,mBAClB,KAAM,OACN,YAAa,EACf,EAEaC,EAAN,KAAmC,CA2BxC,YACEC,EACAC,EAAuB,CAAC,EACxB,CAtBF,KAAQ,sBAAwB,IAAI,IACpC,KAAQ,qBAAuB,IAAI,IAGnC,KAAQ,SAAqB,CAAC,EAC9B,KAAQ,WAAyB,CAAC,EAGlC,KAAQ,oBAAsC,CAAC,EAG/C,KAAQ,UAAqC,KAC7C,KAAQ,kBAAoB,GAC5B,KAAQ,WAAa,GAGrB,KAAQ,eAAsC,KAC9C,KAAQ,eAAsC,KAM5C,KAAK,WAAaD,EAClB,KAAK,SAAW,CAAE,GAAGF,EAAgB,GAAGG,CAAQ,EAGhD,KAAK,OAAS,IAAIC,EAClB,KAAK,iBAAmB,IAAIC,EAE5B,KAAK,QAAU,IAAIC,EAAW,CAC5B,UAAW,KAAK,WAChB,MAAO,KAAK,OACZ,QAAS,KAAK,SACd,aAAc,IAAM,KAAK,cAAc,EACvC,YAAcC,GAAO,KAAK,aAAaA,CAAE,EACzC,YAAcA,GAAO,KAAK,aAAaA,CAAE,CAC3C,CAAC,EAGD,KAAK,qBAAqB,EAG1B,KAAK,yBAAyB,EAG1B,KAAK,SAAS,aAChB,KAAK,kBAAkB,EAIzB,KAAK,mBAAmB,EAGxB,KAAK,OAAO,CACd,CAKA,IAAI,SAAuB,CACzB,OAAO,KAAK,QACd,CAKA,QAAe,CACb,KAAK,QAAQ,OAAO,CACtB,CAKA,SAAgB,CACd,KAAK,QAAQ,QAAQ,CACvB,CAKA,SAAgB,CACd,KAAK,WAAa,GAClB,KAAK,QAAQ,EAGb,QAAWC,KAAS,KAAK,oBACvBA,EAAM,EAER,KAAK,oBAAsB,CAAC,EAG5B,QAAWC,KAAU,KAAK,SACxBA,EAAO,QAAQ,EAEjB,KAAK,SAAW,CAAC,EAGjB,QAAWC,KAAY,KAAK,WAC1BA,EAAS,QAAQ,EAEnB,KAAK,WAAa,CAAC,EAGnB,KAAK,QAAQ,QAAQ,EACrB,KAAK,OAAO,QAAQ,EACpB,KAAK,iBAAiB,QAAQ,EAG9B,KAAK,WAAW,WAAW,EAC3B,KAAK,UAAY,KAGb,KAAK,iBACP,OAAO,oBAAoB,SAAU,KAAK,eAAgB,EAAI,EAC9D,KAAK,eAAiB,MAEpB,KAAK,iBACP,OAAO,oBAAoB,SAAU,KAAK,cAAc,EACxD,KAAK,eAAiB,MAIxB,KAAK,sBAAsB,MAAM,EACjC,KAAK,qBAAqB,MAAM,CAClC,CAKA,SAAgB,CACd,KAAK,yBAAyB,EAC9BC,EAAY,cAAc,CAC5B,CAKA,aAAaC,EAAsBT,EAA6B,CAC9D,KAAK,sBAAsB,IAAIS,EAAST,GAAW,CAAC,CAAC,CACvD,CAKA,gBAAgBS,EAA4B,CAC1C,KAAK,sBAAsB,OAAOA,CAAO,CAC3C,CAKA,YAAYA,EAAsBT,EAAiC,CACjE,KAAK,qBAAqB,IAAIS,EAAST,GAAW,CAAC,CAAC,EACpD,KAAK,iBAAiB,SAASS,EAAST,CAAO,CACjD,CAKA,eAAeS,EAA4B,CACzC,KAAK,qBAAqB,OAAOA,CAAO,EACxC,KAAK,iBAAiB,WAAWA,CAAO,CAC1C,CAKA,YAAsB,CACpB,OAAO,KAAK,OAAO,WAAW,CAChC,CAKA,kBAAuC,CACrC,OAAO,KAAK,OAAO,iBAAiB,CACtC,CAKA,IAAIH,EAAsB,CACxB,YAAK,SAAS,KAAKA,CAAM,EACzBA,EAAO,KAAK,IAAI,EACT,IACT,CAKA,YAAYC,EAA0B,CACpC,YAAK,WAAW,KAAKA,CAAQ,EACtB,IACT,CAKA,WAAWP,EAAqC,CAC9C,OAAO,OAAO,KAAK,SAAUA,CAAO,EACpC,KAAK,QAAQ,cAAc,KAAK,QAAQ,CAC1C,CAIQ,eAA+B,CAErC,IAAMU,EAAW,KAAK,SAAS,kBAAoB,mBAC7CC,EAAc,KAAK,sBAAsB,WAC3C,KAAK,WACL,KAAK,WAEHC,EAAc,MAAM,KACxBD,EAAY,iBAA8BD,CAAQ,CACpD,EAEMG,EAAa,CAAC,GAAG,KAAK,qBAAqB,KAAK,CAAC,EAGvD,MAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGD,EAAa,GAAGC,CAAU,CAAC,CAAC,CACrD,CAEQ,aAAaJ,EAA2D,CAC9E,OAAO,KAAK,sBAAsB,IAAIA,CAAO,GAAG,IAClD,CAEQ,aAAaA,EAAwC,CAE3D,IAAMI,EAAa,KAAK,sBAAsB,IAAIJ,CAAO,EACzD,GAAII,GAAY,KAAM,OAAOA,EAAW,KAGxC,IAAMC,EAAOL,EAAQ,QAAQ,SAC7B,GAAIK,IAAS,KAAOA,IAAS,KAAOA,IAAS,OAC3C,OAAOA,CAIX,CAEQ,0BAAiC,CACvC,IAAMC,EAAmB,KAAK,SAAS,kBAAoB,mBAMrDC,GALc,KAAK,sBAAsB,WAC3C,KAAK,WACL,KAAK,YAGqB,iBAA8BD,CAAgB,EAC5E,QAAWE,KAAQD,EACZ,KAAK,qBAAqB,IAAIC,CAAI,GACrC,KAAK,iBAAiB,SAASA,CAAI,CAGzC,CAEQ,sBAA6B,CAEnC,KAAK,oBAAoB,KACvB,KAAK,OAAO,UAAU,YAAcC,GAAY,CAC9C,QAAWX,KAAY,KAAK,WAC1BA,EAAS,cAAcW,CAAO,CAElC,CAAC,CACH,EAEA,KAAK,oBAAoB,KACvB,KAAK,OAAO,UAAU,WAAaA,GAAY,CAC7C,QAAWX,KAAY,KAAK,WAC1BA,EAAS,aAAaW,CAAO,CAEjC,CAAC,CACH,EAEA,KAAK,oBAAoB,KACvB,KAAK,OAAO,UAAU,UAAYA,GAAY,CAC5C,QAAWX,KAAY,KAAK,WAC1BA,EAAS,YAAYW,CAAO,CAEhC,CAAC,CACH,CACF,CAEQ,mBAA0B,CAChC,KAAK,UAAY,IAAI,iBAAkBC,GAAc,CAEnD,GAAI,KAAK,WAAY,OAErB,IAAIC,EAAe,GAEnB,QAAWC,KAAYF,EACrB,GAAIE,EAAS,OAAS,YAAa,CACjCD,EAAe,GACf,KACF,CAGEA,GAAgB,CAAC,KAAK,oBACxB,KAAK,kBAAoB,GAEzB,sBAAsB,IAAM,CAEtB,KAAK,aACT,KAAK,kBAAoB,GACzB,KAAK,QAAQ,EACf,CAAC,EAEL,CAAC,EAED,IAAME,EAAS,KAAK,sBAAsB,WACtC,KAAK,WACL,KAAK,WAET,KAAK,UAAU,QAAQA,EAAQ,CAC7B,UAAW,GACX,QAAS,EACX,CAAC,CACH,CAEQ,oBAA2B,CAEjC,KAAK,eAAiB,IAAM,CACtB,KAAK,OAAO,WAAW,GACzBd,EAAY,cAAc,CAE9B,EACA,OAAO,iBAAiB,SAAU,KAAK,eAAgB,EAAI,EAG3D,KAAK,eAAiB,IAAM,CAC1BA,EAAY,cAAc,CAC5B,EACA,OAAO,iBAAiB,SAAU,KAAK,cAAc,CACvD,CACF,EAGOe,EAAQzB,ECxWf,IAAM0B,EAAkC,CACtC,UAAW,IACX,WAAY,sBACZ,iBAAkB,2BACpB,EAEaC,EAAN,KAAiC,CAYtC,YAAYC,EAA2B,CAAC,EAAG,CAX3C,UAAO,WAEP,KAAQ,MAA6B,KAErC,KAAQ,aAAmC,KAC3C,KAAQ,eAAyB,GACjC,KAAQ,cAAwB,GAChC,KAAQ,WAAiC,KACzC,KAAQ,OAAwB,CAAC,EACjC,KAAQ,eAAiC,CAAC,EAGxC,KAAK,SAAW,CAAE,GAAGF,EAAgB,GAAGE,CAAQ,CAClD,CAEA,KAAKC,EAA0B,CAC7B,KAAK,MAAQA,EAIb,IAAMC,EAAsBD,EAAK,QAAQ,YACnCE,EAAqBF,EAAK,QAAQ,WAClCG,EAAiBH,EAAK,QAAQ,OAC9BI,EAAoBJ,EAAK,QAAQ,UAEvCA,EAAK,WAAW,CACd,YAAcK,IACZ,KAAK,aAAaA,EAAE,OAAO,EACpBJ,IAAsBI,CAAC,GAEhC,WAAaA,GAAM,CACjB,KAAK,YAAYA,EAAE,SAAS,EAAGA,EAAE,SAAS,CAAC,EAC3CH,IAAqBG,CAAC,CACxB,EACA,OAASA,GAAM,CAEb,IAAMC,EAAgB,CACpB,GAAGD,EACH,eAAgB,KAAK,cACrB,gBAAiB,KAAK,YAAc,MACtC,EACAF,IAAiBG,CAAa,CAChC,EACA,UAAYD,GAAM,CAChB,KAAK,WAAW,EAChBD,IAAoBC,CAAC,CACvB,CACF,CAAC,CACH,CAEA,SAAgB,CACd,KAAK,SAAS,EACd,QAAWE,KAAS,KAAK,eACvBA,EAAM,EAER,KAAK,eAAiB,CAAC,EACvB,KAAK,MAAQ,IACf,CAEQ,aAAaC,EAA4B,CAG/C,GADA,KAAK,WAAaA,EAAQ,cACtB,CAAC,KAAK,WAAY,OAEtB,IAAMC,EAAW,KAAK,OAAO,QAAQ,mBAAqB,mBAC1D,KAAK,OAAS,MAAM,KAClB,KAAK,WAAW,iBAA8BA,CAAQ,CACxD,EAEA,KAAK,eAAiB,KAAK,OAAO,QAAQD,CAAO,EACjD,KAAK,cAAgB,KAAK,eAEtB,KAAK,iBAAmB,KAG5B,KAAK,mBAAmBA,CAAO,EAG3B,KAAK,SAAS,YAChBA,EAAQ,UAAU,IAAI,KAAK,SAAS,UAAU,EAElD,CAEQ,YAAYE,EAAWC,EAAiB,CAC9C,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,WAAY,OAE5C,IAAMF,EAAW,KAAK,OAAO,QAAQ,mBAAqB,mBACpDG,EAAgB,KAAK,OAAO,iBAAiB,EAG7CC,EAAQ,MAAM,KAClB,KAAK,WAAW,iBAA8BJ,CAAQ,CACxD,EAAE,OAAQK,GAAOA,IAAOF,GAAiBE,IAAO,KAAK,YAAY,EAEjE,GAAID,EAAM,SAAW,EAAG,CACtB,KAAK,cAAgB,EACrB,MACF,CAGA,IAAME,EAAYC,EAAY,IAAIH,EAAM,CAAC,CAAC,EACpCI,EAAWD,EAAY,IAAIH,EAAMA,EAAM,OAAS,CAAC,CAAC,EAClDK,EACJ,KAAK,IAAID,EAAS,IAAMF,EAAU,GAAG,EACrC,KAAK,IAAIE,EAAS,KAAOF,EAAU,IAAI,EAGrCI,EAAWN,EAAM,OACrB,QAASO,EAAI,EAAGA,EAAIP,EAAM,OAAQO,IAAK,CACrC,IAAMC,EAAOL,EAAY,IAAIH,EAAMO,CAAC,CAAC,EAC/BE,EAASC,EAAWF,CAAI,EAE9B,GAAIH,GACF,GAAIP,EAAIW,EAAO,EAAG,CAChBH,EAAWC,EACX,KACF,UAEIV,EAAIY,EAAO,EAAG,CAChBH,EAAWC,EACX,KACF,CAEJ,CAGID,EAAW,KAAK,gBAClBA,IAGEA,IAAa,KAAK,gBACpB,KAAK,cAAgBA,EACrB,KAAK,iBAAiBA,CAAQ,EAElC,CAEQ,YAAmB,CACzB,KAAK,SAAS,CAChB,CAEQ,mBAAmBX,EAA4B,CACrD,IAAMa,EAAOb,EAAQ,sBAAsB,EAE3C,KAAK,aAAe,SAAS,cAAc,KAAK,EAChD,KAAK,aAAa,UAAY,KAAK,SAAS,kBAAoB,GAChE,KAAK,aAAa,MAAM,QAAU;AAAA,eACvBa,EAAK,KAAK;AAAA,gBACTA,EAAK,MAAM;AAAA;AAAA;AAAA,MAMvBb,EAAQ,YAAY,aAAa,KAAK,aAAcA,CAAO,CAC7D,CAEQ,iBAAiBgB,EAAqB,CAC5C,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,WAAY,OAE5C,IAAMf,EAAW,KAAK,OAAO,QAAQ,mBAAqB,mBACpDG,EAAgB,KAAK,OAAO,iBAAiB,EAE7CC,EAAQ,MAAM,KAClB,KAAK,WAAW,iBAA8BJ,CAAQ,CACxD,EAAE,OAAQK,GAAOA,IAAOF,CAAa,EAMrC,GAHA,KAAK,aAAa,OAAO,EAGrBY,GAASX,EAAM,OACjB,KAAK,WAAW,YAAY,KAAK,YAAY,MACxC,CAEL,IAAIY,EAAeZ,EAAMW,CAAK,EAC1BC,IAAiB,KAAK,eACxBA,EAAeZ,EAAMW,EAAQ,CAAC,GAE5BC,EACF,KAAK,WAAW,aAAa,KAAK,aAAcA,CAAY,EAE5D,KAAK,WAAW,YAAY,KAAK,YAAY,CAEjD,CAGI,KAAK,SAAS,WAAa,KAAK,SAAS,UAAY,GACvD,KAAK,cAAc,CAEvB,CAEQ,eAAsB,CAC5B,GAAI,CAAC,KAAK,WAAY,OAEtB,IAAMhB,EAAW,KAAK,OAAO,QAAQ,mBAAqB,mBACpDG,EAAgB,KAAK,OAAO,iBAAiB,EAE7CC,EAAQ,MAAM,KAClB,KAAK,WAAW,iBAA8BJ,CAAQ,CACxD,EAAE,OAAQK,GAAOA,IAAOF,GAAiBE,IAAO,KAAK,YAAY,EAG3DY,EAAY,IAAI,IACtB,QAAWC,KAAQd,EACjBa,EAAU,IAAIC,EAAMA,EAAK,sBAAsB,CAAC,EAI7C,KAAK,WAAW,aAGrB,QAAWA,KAAQd,EAAO,CACxB,IAAMe,EAAUF,EAAU,IAAIC,CAAI,EAC5BE,EAAUF,EAAK,sBAAsB,EAE3C,GAAI,CAACC,EAAS,SAEd,IAAME,EAAKF,EAAQ,KAAOC,EAAQ,KAC5BE,EAAKH,EAAQ,IAAMC,EAAQ,KAE7BC,IAAO,GAAKC,IAAO,KACrBJ,EAAK,MAAM,UAAY,aAAaG,CAAE,OAAOC,CAAE,MAC/CJ,EAAK,MAAM,WAAa,OAExB,sBAAsB,IAAM,CAC1BA,EAAK,MAAM,WAAa,aAAa,KAAK,SAAS,SAAS,UAC5DA,EAAK,MAAM,UAAY,EACzB,CAAC,EAEL,CACF,CAEQ,UAAiB,CAEvB,KAAK,cAAc,OAAO,EAC1B,KAAK,aAAe,KAGpB,IAAMf,EAAgB,KAAK,OAAO,iBAAiB,EAC/CA,GAAiB,KAAK,SAAS,YACjCA,EAAc,UAAU,OAAO,KAAK,SAAS,UAAU,EAIzD,KAAK,WAAa,KAClB,KAAK,OAAS,CAAC,EACf,KAAK,eAAiB,GACtB,KAAK,cAAgB,GAGrBI,EAAY,cAAc,CAC5B,CAKA,iBAA0B,CACxB,OAAO,KAAK,aACd,CAKA,kBAA2B,CACzB,OAAO,KAAK,cACd,CACF,ECjRA,IAAMgB,EAA0C,CAC9C,WAAY,mBACZ,MAAO,mBACP,UAAW,GACb,EAEaC,EAAN,KAA+B,CAWpC,YAAYC,EAAyB,CAAC,EAAG,CAVzC,UAAO,SAEP,KAAQ,MAA6B,KAErC,KAAQ,iBAAuC,KAC/C,KAAQ,iBAAuC,KAC/C,KAAQ,aAAmC,KAC3C,KAAQ,eAAyB,GACjC,KAAQ,cAAwB,GAG9B,KAAK,SAAW,CAAE,GAAGF,EAAgB,GAAGE,CAAQ,CAClD,CAEA,KAAKC,EAA0B,CAC7B,KAAK,MAAQA,EAGb,IAAMC,EAAsBD,EAAK,QAAQ,YACnCE,EAAqBF,EAAK,QAAQ,WAClCG,EAA0BH,EAAK,QAAQ,gBACvCI,EAA0BJ,EAAK,QAAQ,gBACvCK,EAAiBL,EAAK,QAAQ,OAC9BM,EAAoBN,EAAK,QAAQ,UAEvCA,EAAK,WAAW,CACd,YAAcO,IACZ,KAAK,aAAaA,EAAE,OAAO,EACpBN,IAAsBM,CAAC,GAEhC,WAAaA,GAAM,CACjB,KAAK,YAAYA,EAAE,QAAQ,EAC3BL,IAAqBK,CAAC,CACxB,EACA,gBAAkBA,GAAM,CACtB,KAAK,iBAAiBA,EAAE,QAAQ,EAChCJ,IAA0BI,CAAC,CAC7B,EACA,gBAAkBA,GAAM,CACtB,KAAK,iBAAiBA,EAAE,QAAQ,EAChCH,IAA0BG,CAAC,CAC7B,EACA,OAASA,GAAM,CACb,IAAMC,EAAgB,CACpB,GAAGD,EACH,eAAgB,KAAK,cACrB,gBAAiB,KAAK,kBAAoB,MAC5C,EACAF,IAAiBG,CAAa,CAChC,EACA,UAAYD,GAAM,CAChB,KAAK,WAAW,EAChBD,IAAoBC,CAAC,CACvB,CACF,CAAC,CACH,CAEA,SAAgB,CACd,KAAK,SAAS,EACd,KAAK,MAAQ,IACf,CAEQ,aAAaE,EAA4B,CAG/C,GADA,KAAK,iBAAmBA,EAAQ,QAAQ,KAAK,SAAS,UAAU,EAC5D,CAAC,KAAK,iBAAkB,OAG5B,IAAMC,EAAQ,MAAM,KAClB,KAAK,iBAAiB,iBAA8B,KAAK,SAAS,KAAK,CACzE,EACA,KAAK,eAAiBA,EAAM,QAAQD,CAAO,EAG3C,KAAK,mBAAmBA,CAAO,CACjC,CAEQ,YAAYE,EAAuB,CACzC,GAAI,CAAC,KAAK,kBAAoB,CAAC,KAAK,aAAc,OAGlD,IAAMC,EAAW,KAAK,yBACpB,KAAK,iBACLD,EAAS,EACTA,EAAS,CACX,EAEIC,IAAa,KAAK,gBACpB,KAAK,cAAgBA,EACrB,KAAK,iBAAiBA,CAAQ,EAElC,CAEQ,iBAAiBC,EAA6B,CAE/CA,EAAS,QAAQ,KAAK,SAAS,UAAU,IAE9C,KAAK,iBAAmBA,EACxB,KAAK,iBAAiB,UAAU,IAAI,oBAAoB,EAGpD,KAAK,eACP,KAAK,iBAAiB,YAAY,KAAK,YAAY,EACnD,KAAK,cAAgB,KAAK,cAAc,KAAK,gBAAgB,GAEjE,CAEQ,iBAAiBA,EAA6B,CAChDA,IAAa,KAAK,mBAEtBA,EAAS,UAAU,OAAO,oBAAoB,EAG9C,KAAK,cAAc,OAAO,EAE1B,KAAK,iBAAmB,KACxB,KAAK,cAAgB,GACvB,CAEQ,YAAmB,CACzB,KAAK,SAAS,CAChB,CAEQ,mBAAmBJ,EAA4B,CACrD,IAAMK,EAAOL,EAAQ,sBAAsB,EAE3C,KAAK,aAAe,SAAS,cAAc,KAAK,EAChD,KAAK,aAAa,UAAY,0BAC9B,KAAK,aAAa,MAAM,QAAU;AAAA,eACvBK,EAAK,KAAK;AAAA,gBACTA,EAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUvBL,EAAQ,YAAY,aAAa,KAAK,aAAcA,CAAO,CAC7D,CAEQ,iBAAiBM,EAAqB,CAC5C,GAAI,CAAC,KAAK,cAAgB,CAAC,KAAK,iBAAkB,OAElD,IAAMC,EAAgB,KAAK,OAAO,iBAAiB,EAC7CN,EAAQ,MAAM,KAClB,KAAK,iBAAiB,iBAA8B,KAAK,SAAS,KAAK,CACzE,EAAE,OAAQO,GAAOA,IAAOD,GAAiBC,IAAO,KAAK,YAAY,EAMjE,GAHA,KAAK,aAAa,OAAO,EAGrBF,GAASL,EAAM,OACjB,KAAK,iBAAiB,YAAY,KAAK,YAAY,MAC9C,CACL,IAAMQ,EAAeR,EAAMK,CAAK,EAC5BG,EACF,KAAK,iBAAiB,aAAa,KAAK,aAAcA,CAAY,EAElE,KAAK,iBAAiB,YAAY,KAAK,YAAY,CAEvD,CAGI,KAAK,SAAS,UAAY,GAC5B,KAAK,cAAc,KAAK,gBAAgB,CAE5C,CAEQ,yBACNC,EACAC,EACAC,EACQ,CACR,IAAML,EAAgB,KAAK,OAAO,iBAAiB,EAC7CN,EAAQ,MAAM,KAClBS,EAAU,iBAA8B,KAAK,SAAS,KAAK,CAC7D,EAAE,OAAQF,GAAOA,IAAOD,GAAiBC,IAAO,KAAK,YAAY,EAEjE,GAAIP,EAAM,SAAW,EAAG,MAAO,GAG/B,IAAMY,EAAYC,EAAY,IAAIb,EAAM,CAAC,CAAC,EACpCc,EAAWD,EAAY,IAAIb,EAAMA,EAAM,OAAS,CAAC,CAAC,EAClDe,EACJ,KAAK,IAAID,EAAS,IAAMF,EAAU,GAAG,EACrC,KAAK,IAAIE,EAAS,KAAOF,EAAU,IAAI,EAGzC,QAASI,EAAI,EAAGA,EAAIhB,EAAM,OAAQgB,IAAK,CACrC,IAAMZ,EAAOS,EAAY,IAAIb,EAAMgB,CAAC,CAAC,EAC/BC,EAASC,EAAWd,CAAI,EAE9B,GAAIW,GACF,GAAIJ,EAAIM,EAAO,EAAG,OAAOD,UAErBN,EAAIO,EAAO,EAAG,OAAOD,CAE7B,CAEA,OAAOhB,EAAM,MACf,CAEQ,cAAcS,EAAgC,CACpD,IAAMH,EAAgB,KAAK,OAAO,iBAAiB,EACnD,OAAO,MAAM,KACXG,EAAU,iBAA8B,KAAK,SAAS,KAAK,CAC7D,EAAE,OAAQF,GAAOA,IAAOD,GAAiBC,IAAO,KAAK,YAAY,EAAE,MACrE,CAEQ,cAAcE,EAA8B,CAClD,IAAMH,EAAgB,KAAK,OAAO,iBAAiB,EAC7CN,EAAQ,MAAM,KAClBS,EAAU,iBAA8B,KAAK,SAAS,KAAK,CAC7D,EAAE,OAAQF,GAAOA,IAAOD,GAAiBC,IAAO,KAAK,YAAY,EAG3DY,EAAY,IAAI,IACtB,QAAWC,KAAQpB,EACjBmB,EAAU,IAAIC,EAAMA,EAAK,sBAAsB,CAAC,EAI7CX,EAAU,aAGf,QAAWW,KAAQpB,EAAO,CACxB,IAAMqB,EAAUF,EAAU,IAAIC,CAAI,EAC5BE,EAAUF,EAAK,sBAAsB,EAE3C,GAAI,CAACC,EAAS,SAEd,IAAME,EAAKF,EAAQ,KAAOC,EAAQ,KAC5BE,EAAKH,EAAQ,IAAMC,EAAQ,KAE7BC,IAAO,GAAKC,IAAO,KACrBJ,EAAK,MAAM,UAAY,aAAaG,CAAE,OAAOC,CAAE,MAC/CJ,EAAK,MAAM,WAAa,OAExB,sBAAsB,IAAM,CAC1BA,EAAK,MAAM,WAAa,aAAa,KAAK,SAAS,SAAS,UAC5DA,EAAK,MAAM,UAAY,EACzB,CAAC,EAEL,CACF,CAEQ,UAAiB,CAEvB,KAAK,cAAc,OAAO,EAC1B,KAAK,aAAe,KAGpB,KAAK,kBAAkB,UAAU,OAAO,oBAAoB,EAC5D,KAAK,kBAAkB,UAAU,OAAO,oBAAoB,EAG5D,KAAK,iBAAmB,KACxB,KAAK,iBAAmB,KACxB,KAAK,eAAiB,GACtB,KAAK,cAAgB,GAErBP,EAAY,cAAc,CAC5B,CAKA,oBAAyC,CACvC,OAAO,KAAK,gBACd,CAKA,oBAAyC,CACvC,OAAO,KAAK,gBACd,CAKA,iBAA0B,CACxB,OAAO,KAAK,aACd,CACF,EC9QO,IAAMY,EAAN,cACGC,CAEV,CAOE,YAAYC,EAA4B,CACtC,MAAM,EALR,KAAQ,UAAY,GACpB,KAAQ,WAAa,EACrB,KAAQ,iBAAuC,KAyC/C,KAAQ,aAAgBC,GAAuB,CAE7C,GAAI,CAAC,KAAK,UAAUA,CAAC,EAAG,OAExB,KAAK,aAEL,IAAMC,EAAW,KAAK,cAAcD,CAAC,EAChCC,IAELD,EAAE,eAAe,EAEbC,IAAa,KAAK,mBAChB,KAAK,kBACP,KAAK,KAAK,YAAa,CACrB,SAAU,CAAE,EAAGD,EAAE,QAAS,EAAGA,EAAE,OAAQ,EACvC,SAAU,KAAK,iBACf,cAAeA,CACjB,CAAC,EAGH,KAAK,iBAAmBC,EACxB,KAAK,KAAK,YAAa,CACrB,SAAU,CAAE,EAAGD,EAAE,QAAS,EAAGA,EAAE,OAAQ,EACvC,SAAAC,EACA,cAAeD,CACjB,CAAC,GAEL,EAEA,KAAQ,YAAeA,GAAuB,CAC5C,GAAI,CAAC,KAAK,UAAUA,CAAC,EAAG,OAExB,IAAMC,EAAW,KAAK,cAAcD,CAAC,EAChCC,IAGLD,EAAE,eAAe,EAGbA,EAAE,eACJA,EAAE,aAAa,WAAa,QAG9B,KAAK,KAAK,WAAY,CACpB,SAAU,CAAE,EAAGA,EAAE,QAAS,EAAGA,EAAE,OAAQ,EACvC,SAAAC,EACA,cAAeD,CACjB,CAAC,EACH,EAEA,KAAQ,aAAgBA,GAAuB,CACxC,KAAK,UAAUA,CAAC,IAErB,KAAK,aAGD,KAAK,aAAe,GAAK,KAAK,mBAChC,KAAK,KAAK,YAAa,CACrB,SAAU,CAAE,EAAGA,EAAE,QAAS,EAAGA,EAAE,OAAQ,EACvC,SAAU,KAAK,iBACf,cAAeA,CACjB,CAAC,EACD,KAAK,iBAAmB,MAE5B,EAEA,KAAQ,QAAWA,GAAuB,CACxCA,EAAE,eAAe,EACjB,KAAK,WAAa,EAElB,IAAMC,EAAW,KAAK,cAAcD,CAAC,EACrC,GAAI,CAACC,EAAU,OAEf,IAAMC,EAAQ,KAAK,UAAUF,CAAC,EAC1BE,EAAM,SAAW,IAErB,KAAK,KAAK,OAAQ,CAChB,MAAAA,EACA,SAAU,CAAE,EAAGF,EAAE,QAAS,EAAGA,EAAE,OAAQ,EACvC,SAAAC,EACA,cAAeD,CACjB,CAAC,EAED,KAAK,iBAAmB,KAC1B,EAzHE,KAAK,WAAaD,EAAQ,UAC1B,KAAK,SAAWA,CAClB,CAEA,QAAe,CACb,GAAI,KAAK,UAAW,OAEpB,IAAMI,EAAS,KAAK,gBAAgB,EACpCA,EAAO,iBAAiB,YAAa,KAAK,aAAc,CAAE,QAAS,EAAM,CAAC,EAC1EA,EAAO,iBAAiB,WAAY,KAAK,YAAa,CAAE,QAAS,EAAM,CAAC,EACxEA,EAAO,iBAAiB,YAAa,KAAK,aAAc,CAAE,QAAS,EAAM,CAAC,EAC1EA,EAAO,iBAAiB,OAAQ,KAAK,QAAS,CAAE,QAAS,EAAM,CAAC,EAEhE,KAAK,UAAY,EACnB,CAEA,QAAe,CACb,GAAI,CAAC,KAAK,UAAW,OAErB,IAAMA,EAAS,KAAK,gBAAgB,EACpCA,EAAO,oBAAoB,YAAa,KAAK,YAAY,EACzDA,EAAO,oBAAoB,WAAY,KAAK,WAAW,EACvDA,EAAO,oBAAoB,YAAa,KAAK,YAAY,EACzDA,EAAO,oBAAoB,OAAQ,KAAK,OAAO,EAE/C,KAAK,WAAa,EAClB,KAAK,iBAAmB,KACxB,KAAK,UAAY,EACnB,CAEQ,iBAA0C,CAChD,OAAI,KAAK,sBAAsB,WACtB,KAAK,WAAW,KAElB,KAAK,UACd,CAwFQ,cAAcH,EAAkC,CACtD,IAAMG,EAASH,EAAE,OAGXI,EAAOJ,EAAE,aAAa,EAC5B,QAAWK,KAAMD,EACf,GAAMC,aAAc,YAEpB,IAAIA,EAAG,QAAQ,KAAK,SAAS,gBAAgB,EAC3C,OAAOA,EAGT,GAAIA,IAAO,KAAK,YAAcA,IAAQ,KAAK,WAA0B,KACnE,MAIJ,OAAOF,EAAO,UAAU,KAAK,SAAS,gBAAgB,CACxD,CAEQ,UAAUH,EAAuB,CACvC,GAAI,CAACA,EAAE,aAAc,MAAO,GAG5B,IAAMM,EAAQN,EAAE,aAAa,MAC7B,OAAOM,EAAM,SAAS,OAAO,GAAKA,EAAM,SAAS,wBAAwB,CAC3E,CAEQ,UAAUN,EAAsB,CACtC,GAAI,CAACA,EAAE,cAAc,MAAO,MAAO,CAAC,EAEpC,IAAIE,EAAQ,MAAM,KAAKF,EAAE,aAAa,KAAK,EAGrCO,EAAS,KAAK,SAAS,OACzBA,GAAUA,EAAO,OAAS,IAC5BL,EAAQA,EAAM,OAAQM,GAAS,KAAK,eAAeA,EAAMD,CAAM,CAAC,GAIlE,IAAME,EAAU,KAAK,SAAS,QAC9B,OAAIA,GAAWA,EAAU,IACvBP,EAAQA,EAAM,OAAQM,GAASA,EAAK,MAAQC,CAAO,GAIjD,CAAC,KAAK,SAAS,UAAYP,EAAM,OAAS,IAC5CA,EAAQ,CAACA,EAAM,CAAC,CAAC,GAGZA,CACT,CAEQ,eAAeM,EAAYD,EAA2B,CAC5D,QAAWG,KAAWH,EAAQ,CAE5B,GAAIG,EAAQ,WAAW,GAAG,EAAG,CAC3B,GAAIF,EAAK,KAAK,YAAY,EAAE,SAASE,EAAQ,YAAY,CAAC,EACxD,MAAO,GAET,QACF,CAGA,GAAIA,EAAQ,SAAS,IAAI,EAAG,CAC1B,IAAMC,EAASD,EAAQ,MAAM,EAAG,EAAE,EAClC,GAAIF,EAAK,KAAK,WAAWG,CAAM,EAC7B,MAAO,GAET,QACF,CAGA,GAAIH,EAAK,OAASE,EAChB,MAAO,EAEX,CAEA,MAAO,EACT,CAEA,SAAgB,CACd,KAAK,OAAO,EACZ,MAAM,QAAQ,CAChB,CACF,EClPA,IAAME,EAAkC,CACtC,SAAU,EACZ,EAEaC,EAAN,KAAiC,CAQtC,YAAYC,EAA2B,CAAC,EAAG,CAP3C,UAAO,YAEP,KAAQ,MAA6B,KAErC,KAAQ,QAA6B,KACrC,KAAQ,YAAuD,KAG7D,KAAK,SAAW,CAAE,GAAGF,EAAgB,GAAGE,CAAQ,CAClD,CAEA,KAAKC,EAA0B,CAC7B,KAAK,MAAQA,EAGb,IAAMC,EAAY,KAAK,cAAc,EAChCA,IAGL,KAAK,QAAU,IAAIC,EAAW,CAC5B,UAAAD,EACA,iBAAkBD,EAAK,QAAQ,kBAAoB,mBACnD,OAAQ,KAAK,SAAS,OACtB,SAAU,KAAK,SAAS,SACxB,QAAS,KAAK,SAAS,OACzB,CAAC,EAGD,KAAK,oBAAoB,EAGzB,KAAK,QAAQ,OAAO,EACtB,CAEA,SAAgB,CACd,KAAK,SAAS,QAAQ,EACtB,KAAK,QAAU,KACf,KAAK,MAAQ,KACb,KAAK,YAAc,IACrB,CAKA,WAAWG,EAAgD,CACzD,YAAK,YAAcA,EACZ,IACT,CAKA,WAAWJ,EAAyC,CAClD,OAAO,OAAO,KAAK,SAAUA,CAAO,CACtC,CAEQ,eAAiD,CACvD,OAAK,KAAK,MAIF,KAAK,MAA8D,WAJnD,IAK1B,CAEQ,qBAA4B,CAC7B,KAAK,UAGV,KAAK,QAAQ,GAAG,YAAc,GAAM,CAClC,EAAE,SAAS,UAAU,IAAI,qBAAqB,CAChD,CAAC,EAGD,KAAK,QAAQ,GAAG,YAAc,GAAM,CAClC,EAAE,SAAS,UAAU,OAAO,qBAAqB,CACnD,CAAC,EAGD,KAAK,QAAQ,GAAG,OAAS,GAAuB,CAC9C,EAAE,SAAS,UAAU,OAAO,qBAAqB,EAEjD,IAAMK,EAAuB,CAC3B,MAAO,EAAE,MACT,SAAU,EAAE,SACZ,SAAU,EAAE,QACd,EAGA,KAAK,cAAcA,CAAK,EAGJ,KAAK,OAAO,SAGnB,aAAaA,CAAK,CACjC,CAAC,EACH,CACF,EAMO,SAASC,EACdC,EACAP,EAKY,CACZ,GAAM,CAAE,OAAAQ,EAAQ,YAAAC,EAAa,YAAAC,EAAa,GAAGC,CAAY,EAAIX,EAEzDY,EAAY,EAEVC,EAAmBC,GAAiB,CACnCC,EAASD,CAAC,IACfA,EAAE,eAAe,EACjBF,IACIA,IAAc,IAChBL,EAAQ,UAAU,IAAI,qBAAqB,EAC3CE,IAAc,GAElB,EAEMO,EAAkBF,GAAiB,CAClCC,EAASD,CAAC,IACfA,EAAE,eAAe,EACbA,EAAE,eACJA,EAAE,aAAa,WAAa,QAEhC,EAEMG,EAAmBH,GAAiB,CACnCC,EAASD,CAAC,IACfF,IACIA,IAAc,IAChBL,EAAQ,UAAU,OAAO,qBAAqB,EAC9CG,IAAc,GAElB,EAEMQ,EAAcJ,GAAiB,CACnCA,EAAE,eAAe,EACjBF,EAAY,EACZL,EAAQ,UAAU,OAAO,qBAAqB,EAE9C,IAAIY,EAAQ,MAAM,KAAKL,EAAE,cAAc,OAAS,CAAC,CAAC,EAG9CH,EAAY,QAAQ,SACtBQ,EAAQA,EAAM,OAAQC,GAASC,EAAcD,EAAMT,EAAY,MAAO,CAAC,GAIrEA,EAAY,UACdQ,EAAQA,EAAM,OAAQC,GAASA,EAAK,MAAQT,EAAY,OAAQ,GAI9D,CAACA,EAAY,UAAYQ,EAAM,OAAS,IAC1CA,EAAQ,CAACA,EAAM,CAAC,CAAC,GAGfA,EAAM,OAAS,GACjBX,EAAOW,CAAK,CAEhB,EAGA,OAAAZ,EAAQ,iBAAiB,YAAaM,CAAe,EACrDN,EAAQ,iBAAiB,WAAYS,CAAc,EACnDT,EAAQ,iBAAiB,YAAaU,CAAe,EACrDV,EAAQ,iBAAiB,OAAQW,CAAU,EAGpC,IAAM,CACXX,EAAQ,oBAAoB,YAAaM,CAAe,EACxDN,EAAQ,oBAAoB,WAAYS,CAAc,EACtDT,EAAQ,oBAAoB,YAAaU,CAAe,EACxDV,EAAQ,oBAAoB,OAAQW,CAAU,EAC9CX,EAAQ,UAAU,OAAO,qBAAqB,CAChD,CACF,CAEA,SAASQ,EAASD,EAAuB,CACvC,GAAI,CAACA,EAAE,aAAc,MAAO,GAC5B,IAAMQ,EAAQR,EAAE,aAAa,MAC7B,OAAOQ,EAAM,SAAS,OAAO,GAAKA,EAAM,SAAS,wBAAwB,CAC3E,CAEA,SAASD,EAAcD,EAAYG,EAA2B,CAC5D,QAAWC,KAAWD,EAAQ,CAC5B,GAAIC,EAAQ,WAAW,GAAG,EAAG,CAC3B,GAAIJ,EAAK,KAAK,YAAY,EAAE,SAASI,EAAQ,YAAY,CAAC,EACxD,MAAO,GAET,QACF,CACA,GAAIA,EAAQ,SAAS,IAAI,EAAG,CAC1B,IAAMC,EAASD,EAAQ,MAAM,EAAG,EAAE,EAClC,GAAIJ,EAAK,KAAK,WAAWK,CAAM,EAC7B,MAAO,GAET,QACF,CACA,GAAIL,EAAK,OAASI,EAChB,MAAO,EAEX,CACA,MAAO,EACT,CCjOA,IAAME,EAA8C,CAClD,UAAW,GACX,SAAU,GACV,aAAc,CAChB,EAEaC,EAAN,KAAqC,CAQ1C,YAAYC,EAA6B,CAAC,EAAG,CAP7C,UAAO,cAGP,KAAQ,qBAAkC,CAAC,EAC3C,KAAQ,OAAwB,KAChC,KAAQ,QAAU,GAGhB,KAAK,SAAW,CAAE,GAAGF,EAAgB,GAAGE,CAAQ,CAClD,CAEA,YAAYC,EAA4B,CACtC,KAAK,qBAAuB,KAAK,yBAAyBA,EAAQ,OAAO,EACzE,KAAK,QAAU,EACjB,CAEA,WAAWA,EAA4B,CACjC,CAAC,KAAK,SAAW,KAAK,SAAW,OAErC,KAAK,OAAS,sBAAsB,IAAM,CACxC,KAAK,OAAS,KACd,KAAK,eAAeA,EAAQ,QAAQ,EAAGA,EAAQ,QAAQ,CAAC,CAC1D,CAAC,EACH,CAEA,WAAkB,CAChB,KAAK,QAAU,GACf,KAAK,qBAAuB,CAAC,EACzB,KAAK,SAAW,OAClB,qBAAqB,KAAK,MAAM,EAChC,KAAK,OAAS,KAElB,CAEA,SAAgB,CACd,KAAK,UAAU,CACjB,CAEQ,eAAeC,EAAWC,EAAiB,CACjD,QAAWC,KAAY,KAAK,qBAAsB,CAChD,IAAMC,EAAOD,EAAS,sBAAsB,EACtCE,EAAQ,KAAK,sBAAsBJ,EAAGC,EAAGE,CAAI,GAE/CC,EAAM,IAAM,GAAKA,EAAM,IAAM,IAC/BF,EAAS,SAAS,CAChB,KAAME,EAAM,EACZ,IAAKA,EAAM,EACX,SAAU,SACZ,CAAC,CAEL,CACF,CAEQ,sBACNJ,EACAC,EACAE,EAC0B,CAC1B,GAAM,CAAE,UAAAE,EAAW,SAAAC,CAAS,EAAI,KAAK,SACjCC,EAAU,EACVC,EAAU,EAGd,OAAIR,EAAIG,EAAK,KAAOE,EAClBE,EAAU,CAAC,KAAK,UAAUJ,EAAK,KAAOE,EAAYL,CAAC,EAG5CA,EAAIG,EAAK,MAAQE,IACxBE,EAAU,KAAK,UAAUP,GAAKG,EAAK,MAAQE,EAAU,GAInDJ,EAAIE,EAAK,IAAME,EACjBG,EAAU,CAAC,KAAK,UAAUL,EAAK,IAAME,EAAYJ,CAAC,EAG3CA,EAAIE,EAAK,OAASE,IACzBG,EAAU,KAAK,UAAUP,GAAKE,EAAK,OAASE,EAAU,GAGjD,CAAE,EAAGE,EAAS,EAAGC,CAAQ,CAClC,CAEQ,UAAUC,EAA0B,CAC1C,GAAM,CAAE,UAAAJ,EAAW,SAAAC,EAAU,aAAAI,CAAa,EAAI,KAAK,SAC7CC,EAAQ,KAAK,IAAIF,EAAWJ,EAAW,CAAC,EAC9C,OAAO,KAAK,IAAIM,EAAOD,CAAY,EAAIJ,CACzC,CAEQ,yBAAyBM,EAAiC,CAChE,IAAMC,EAAuB,CAAC,EAC1BC,EAA0BF,EAAQ,cAEtC,KAAOE,GAAWA,IAAY,SAAS,MAAM,CAC3C,IAAMC,EAAQ,iBAAiBD,CAAO,EAChCE,EAAYD,EAAM,UAClBE,EAAYF,EAAM,UAElBG,GACHF,IAAc,QAAUA,IAAc,WACvCF,EAAQ,YAAcA,EAAQ,YAE1BK,GACHF,IAAc,QAAUA,IAAc,WACvCH,EAAQ,aAAeA,EAAQ,cAE7BI,GAAiBC,IACnBN,EAAU,KAAKC,CAAO,EAGxBA,EAAUA,EAAQ,aACpB,CAGA,OACE,SAAS,gBAAgB,aAAe,OAAO,aAC/C,SAAS,gBAAgB,YAAc,OAAO,aAE9CD,EAAU,KAAK,SAAS,eAAe,EAGlCA,CACT,CACF,ECzHO,IAAMO,EAAN,KAAmC,CAMxC,YAAYC,EAA0B,CALtC,UAAO,YAGP,KAAQ,gBAAsC,KAG5C,KAAK,SAAWA,CAClB,CAEA,YAAYC,EAA4B,CAClC,KAAK,SAAS,YAChB,KAAK,cAAcA,EAAQ,OAAO,CAEtC,CAEA,WAAWC,EAA6B,CAGxC,CAEA,WAAkB,CAChB,KAAK,cAAc,CACrB,CAEA,SAAgB,CACd,KAAK,cAAc,CACrB,CAKA,KAAKC,EAAWC,EAAqC,CACnD,MAAO,CACL,EAAG,KAAK,MAAMD,EAAI,KAAK,SAAS,CAAC,EAAI,KAAK,SAAS,EACnD,EAAG,KAAK,MAAMC,EAAI,KAAK,SAAS,CAAC,EAAI,KAAK,SAAS,CACrD,CACF,CAKA,kBACED,EACAC,EACAC,EAC0B,CAC1B,IAAMC,EAAID,GAAa,KAAK,SAAS,WAAa,EAC5CE,EAAU,KAAK,KAAKJ,EAAGC,CAAC,EAE9B,MAAO,CACL,EAAG,KAAK,IAAID,EAAII,EAAQ,CAAC,EAAID,EAAIC,EAAQ,EAAIJ,EAC7C,EAAG,KAAK,IAAIC,EAAIG,EAAQ,CAAC,EAAID,EAAIC,EAAQ,EAAIH,CAC/C,CACF,CAEQ,cAAcI,EAA4B,CAChD,IAAMC,EAAYD,EAAQ,cAAgB,SAAS,KAC7CE,EAAOD,EAAU,sBAAsB,EAE7C,KAAK,gBAAkB,SAAS,cAAc,KAAK,EACnD,KAAK,gBAAgB,MAAM,QAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWrC,IAAME,EAAO,KAAK,KAAKD,EAAK,MAAQ,KAAK,SAAS,CAAC,EACnD,QAASE,EAAI,EAAGA,EAAID,EAAMC,IAAK,CAC7B,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,MAAM,QAAU;AAAA;AAAA,gBAEXD,EAAI,KAAK,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAM7B,KAAK,gBAAgB,YAAYC,CAAI,CACvC,CAGA,IAAMC,EAAO,KAAK,KAAKJ,EAAK,OAAS,KAAK,SAAS,CAAC,EACpD,QAASE,EAAI,EAAGA,EAAIE,EAAMF,IAAK,CAC7B,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,MAAM,QAAU;AAAA;AAAA,eAEZD,EAAI,KAAK,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAM5B,KAAK,gBAAgB,YAAYC,CAAI,CACvC,CAEAJ,EAAU,YAAY,KAAK,eAAe,CAC5C,CAEQ,eAAsB,CAC5B,KAAK,iBAAiB,OAAO,EAC7B,KAAK,gBAAkB,IACzB,CACF,ECtGO,IAAMM,EAAN,KAAyC,CAW9C,YAAYC,EAA6B,CAAC,EAAG,CAV7C,UAAO,kBAGP,KAAQ,QAKG,KAGT,KAAK,SAAWA,CAClB,CAEA,YAAYC,EAA4B,CAClC,KAAK,SAAS,oBAChB,KAAK,uBAAuBA,EAAQ,OAAO,EAClC,KAAK,SAAS,SACvB,KAAK,QAAU,CACb,KAAM,KAAK,SAAS,OAAO,MAAQ,KACnC,KAAM,KAAK,SAAS,OAAO,MAAQ,IACnC,KAAM,KAAK,SAAS,OAAO,MAAQ,KACnC,KAAM,KAAK,SAAS,OAAO,MAAQ,GACrC,EAEJ,CAEA,WAAWC,EAA6B,CAGxC,CAEA,WAAkB,CAChB,KAAK,QAAU,IACjB,CAEA,SAAgB,CACd,KAAK,QAAU,IACjB,CAKA,UAAUC,EAAcC,EAAsB,CAC5C,GAAI,CAAE,EAAAC,EAAG,EAAAC,CAAE,EAAIH,EAGTI,EAAO,KAAK,SAAS,MAAQ,OACnC,OAAIA,IAAS,IACXD,EAAIF,EAAO,EACFG,IAAS,MAClBF,EAAID,EAAO,GAIT,KAAK,UACPC,EAAI,KAAK,IAAI,KAAK,QAAQ,KAAM,KAAK,IAAI,KAAK,QAAQ,KAAMA,CAAC,CAAC,EAC9DC,EAAI,KAAK,IAAI,KAAK,QAAQ,KAAM,KAAK,IAAI,KAAK,QAAQ,KAAMA,CAAC,CAAC,GAGzD,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAChB,CAKA,WAAiC,CAC/B,OAAO,KAAK,OACd,CAEQ,uBAAuBE,EAA4B,CACzD,IAAMC,EAASD,EAAQ,cACvB,GAAI,CAACC,EAAQ,OAEb,IAAMC,EAAaD,EAAO,sBAAsB,EAC1CE,EAAcH,EAAQ,sBAAsB,EAGlD,KAAK,QAAU,CACb,KAAME,EAAW,KACjB,KAAMA,EAAW,MAAQC,EAAY,MACrC,KAAMD,EAAW,IACjB,KAAMA,EAAW,OAASC,EAAY,MACxC,CACF,CACF",
6
- "names": ["EventEmitter", "event", "callback", "listeners", "unsubscribe", "data", "SnapDataTransfer", "_SnapDataTransfer", "type", "value", "copy", "key", "DragState", "EventEmitter", "element", "origin", "initialData", "data", "SnapDataTransfer", "key", "value", "point", "zone", "previous", "session", "event", "callback", "RAFThrottle", "callback", "data", "rafThrottle", "fn", "rafId", "lastArgs", "throttled", "args", "ObjectPool", "factory", "reset", "initialSize", "maxSize", "obj", "pointPool", "p", "rectPool", "acquirePoint", "x", "y", "PointerSensor", "EventEmitter", "options", "e", "draggable", "acquirePoint", "target", "delay", "position", "distance", "dx", "dy", "pointPool", "delta", "RAFThrottle", "path", "el", "handle", "BoundsCache", "element", "cached", "rect", "boundsCache", "pointInRect", "x", "y", "rectCenter", "rect", "DragEngine", "engineOptions", "event", "element", "position", "data", "session", "startEvent", "boundsCache", "axis", "finalSession", "PointerSensor", "options", "origin", "grid", "dropZones", "foundZone", "zone", "rect", "pointInRect", "x", "y", "attr", "key", "draggableValue", "unsub", "DropZone", "element", "options", "x", "y", "rect", "boundsCache", "pointInRect", "data", "accepts", "type", "elementAccepts", "acceptedTypes", "s", "active", "itemSelector", "excludeElement", "items", "el", "firstRect", "lastRect", "isVertical", "i", "center", "rectCenter", "closestItem", "closestDistance", "position", "item", "dx", "dy", "distance", "DropZoneManager", "zone", "defaultOptions", "Snap", "container", "options", "DragState", "DropZoneManager", "DragEngine", "el", "unsub", "plugin", "behavior", "boundsCache", "element", "selector", "containerEl", "declarative", "imperative", "axis", "dropZoneSelector", "dropZones", "zone", "session", "mutations", "needsRefresh", "mutation", "target", "Snap_default", "defaultOptions", "Sortable", "options", "snap", "originalOnDragStart", "originalOnDragMove", "originalOnDrop", "originalOnDragEnd", "e", "enhancedEvent", "unsub", "element", "selector", "x", "y", "activeElement", "items", "el", "firstRect", "boundsCache", "lastRect", "isVertical", "newIndex", "i", "rect", "center", "rectCenter", "index", "insertBefore", "positions", "item", "oldRect", "newRect", "dx", "dy", "defaultOptions", "Kanban", "options", "snap", "originalOnDragStart", "originalOnDragMove", "originalOnDropZoneEnter", "originalOnDropZoneLeave", "originalOnDrop", "originalOnDragEnd", "e", "enhancedEvent", "element", "items", "position", "newIndex", "dropZone", "rect", "index", "activeElement", "el", "insertBefore", "container", "x", "y", "firstRect", "boundsCache", "lastRect", "isVertical", "i", "center", "rectCenter", "positions", "item", "oldRect", "newRect", "dx", "dy", "FileSensor", "EventEmitter", "options", "e", "dropZone", "files", "target", "path", "el", "types", "accept", "file", "maxSize", "pattern", "prefix", "defaultOptions", "FileDrop", "options", "snap", "container", "FileSensor", "callback", "event", "createFileDropZone", "element", "onDrop", "onDragEnter", "onDragLeave", "fileOptions", "dragCount", "handleDragEnter", "e", "hasFiles", "handleDragOver", "handleDragLeave", "handleDrop", "files", "file", "matchesAccept", "types", "accept", "pattern", "prefix", "defaultOptions", "AutoScroll", "options", "session", "x", "y", "ancestor", "rect", "speed", "threshold", "maxSpeed", "scrollX", "scrollY", "distance", "acceleration", "ratio", "element", "ancestors", "current", "style", "overflowX", "overflowY", "isScrollableX", "isScrollableY", "SnapGrid", "options", "session", "_session", "x", "y", "threshold", "t", "snapped", "element", "container", "rect", "cols", "i", "line", "rows", "ConstraintAxis", "options", "session", "_session", "point", "origin", "x", "y", "axis", "element", "parent", "parentRect", "elementRect"]
7
- }
package/dist/snap.umd.js DELETED
@@ -1,49 +0,0 @@
1
- "use strict";var Snap=(()=>{var k=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var N=(r,e)=>{for(var t in e)k(r,t,{get:e[t],enumerable:!0})},V=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of $(e))!W.call(r,o)&&o!==t&&k(r,o,{get:()=>e[o],enumerable:!(n=K(e,o))||n.enumerable});return r};var J=r=>V(k({},"__esModule",{value:!0}),r);var st={};N(st,{AutoScroll:()=>w,BoundsCache:()=>L,ConstraintAxis:()=>F,DragEngine:()=>y,DragState:()=>f,DropZone:()=>P,DropZoneManager:()=>S,EventEmitter:()=>_,FileDrop:()=>Z,FileSensor:()=>T,Kanban:()=>O,ObjectPool:()=>b,PointerSensor:()=>x,RAFThrottle:()=>E,Snap:()=>I,SnapDataTransfer:()=>m,SnapGrid:()=>R,Sortable:()=>A,boundsCache:()=>h,createFileDropZone:()=>U,default:()=>G,pointPool:()=>v,rafThrottle:()=>Y,rectPool:()=>j});var _=class{constructor(){this._listeners=new Map}on(e,t){let n=this._listeners.get(e);return n||(n=new Set,this._listeners.set(e,n)),n.add(t),()=>{n.delete(t),n.size===0&&this._listeners.delete(e)}}once(e,t){let n=this.on(e,o=>{n(),t(o)});return n}emit(e,t){let n=this._listeners.get(e);if(n)for(let o of[...n])o(t)}off(e){e?this._listeners.delete(e):this._listeners.clear()}hasListeners(e){let t=this._listeners.get(e);return t!==void 0&&t.size>0}listenerCount(e){return this._listeners.get(e)?.size??0}destroy(){this._listeners.clear()}};var m=class r{constructor(){this._data=new Map}setData(e,t){this._data.set(e,t)}getData(e){return this._data.get(e)}hasType(e){return this._data.has(e)}get types(){return[...this._data.keys()]}clear(){this._data.clear()}clone(){let e=new r;for(let[t,n]of this._data)e.setData(t,n);return e}};var f=class extends _{constructor(){super(...arguments);this._session=null;this._idCounter=0}get session(){return this._session}isDragging(){return this._session!==null&&this._session.phase==="dragging"}getActiveElement(){return this._session?.element??null}getCurrentDropZone(){return this._session?.dropZone??null}startDrag(t,n,o){this._session&&this.cancelDrag();let i=new m;if(o)for(let[s,a]of Object.entries(o))i.setData(s,a);return this._session={id:`drag-${++this._idCounter}`,element:t,origin:{x:n.x,y:n.y},current:{x:n.x,y:n.y},delta:{x:0,y:0},data:i,dropZone:null,phase:"dragging"},this.emit("dragstart",this._session),this._session}updatePosition(t){!this._session||this._session.phase!=="dragging"||(this._session.current.x=t.x,this._session.current.y=t.y,this._session.delta.x=t.x-this._session.origin.x,this._session.delta.y=t.y-this._session.origin.y,this.emit("dragmove",this._session))}setDropTarget(t){if(!this._session)return;let n=this._session.dropZone;n!==t&&(n&&(this._session.dropZone=null,this.emit("dropzoneleave",this._session)),t&&(this._session.dropZone=t,this.emit("dropzoneenter",this._session)))}endDrag(){if(!this._session)return null;let t=this._session;return t.phase="dropping",t.dropZone&&this.emit("drop",t),this.emit("dragend",t),this._session=null,t}cancelDrag(){if(!this._session)return null;let t=this._session;return t.phase="cancelled",t.dropZone=null,this.emit("dragend",t),this._session=null,t}subscribe(t,n){return this.on(t,n)}reset(){this._session&&this.cancelDrag()}destroy(){this.reset(),super.destroy()}};var E=class{constructor(e){this._rafId=null;this._pending=null;this._process=()=>{if(this._rafId=null,this._pending!==null){let e=this._pending;this._pending=null,this._callback(e)}};this._callback=e}queue(e){this._pending=e,this._rafId===null&&(this._rafId=requestAnimationFrame(this._process))}cancel(){this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null),this._pending=null}flush(){this._pending!==null&&(this.cancel(),this._callback(this._pending),this._pending=null)}get isPending(){return this._rafId!==null}destroy(){this.cancel()}};function Y(r){let e=null,t=null,n=(...o)=>{t=o,e===null&&(e=requestAnimationFrame(()=>{e=null,t!==null&&(r(...t),t=null)}))};return n.cancel=()=>{e!==null&&(cancelAnimationFrame(e),e=null),t=null},n.flush=()=>{e!==null&&(cancelAnimationFrame(e),e=null),t!==null&&(r(...t),t=null)},n}var b=class{constructor(e,t,n=10,o=100){this._pool=[];this._factory=e,this._reset=t,this._maxSize=o;for(let i=0;i<n;i++)this._pool.push(e())}acquire(){return this._pool.pop()??this._factory()}release(e){this._pool.length<this._maxSize&&(this._reset(e),this._pool.push(e))}clear(){this._pool.length=0}get size(){return this._pool.length}},v=new b(()=>({x:0,y:0}),r=>{r.x=0,r.y=0}),j=new b(()=>({x:0,y:0,width:0,height:0}),r=>{r.x=0,r.y=0,r.width=0,r.height=0});function D(r,e){let t=v.acquire();return t.x=r,t.y=e,t}var x=class extends _{constructor(t){super();this._attached=!1;this._activePointerId=null;this._activeElement=null;this._startPosition=null;this._isDragging=!1;this._delayTimer=null;this._onPointerDown=t=>{if(!t.isPrimary||t.button!==0||this._activePointerId!==null)return;let n=this._findDraggable(t);if(!n||this._options.handleSelector&&!this._findHandle(t,n))return;t.preventDefault(),this._activePointerId=t.pointerId,this._activeElement=n,this._startPosition=D(t.clientX,t.clientY),this._isDragging=!1,t.target.setPointerCapture(t.pointerId);let o=this._getEventTarget();o.addEventListener("pointermove",this._onPointerMove,{passive:!0}),o.addEventListener("pointerup",this._onPointerUp),o.addEventListener("pointercancel",this._onPointerCancel);let i=this._options.delay??0;i>0?this._delayTimer=window.setTimeout(()=>{this._delayTimer=null,this._startDrag(t)},i):(this._options.distance??0)===0&&this._startDrag(t)};this._onPointerMove=t=>{t.pointerId===this._activePointerId&&this._moveThrottle.queue(t)};this._processMove=t=>{if(!this._startPosition||!this._activeElement)return;let n=D(t.clientX,t.clientY);if(!this._isDragging){let o=this._options.distance??0;if(o>0){let i=n.x-this._startPosition.x,s=n.y-this._startPosition.y;if(Math.sqrt(i*i+s*s)<o){v.release(n);return}this._clearDelayTimer(),this._startDrag(t)}}if(this._isDragging){let o=D(n.x-this._startPosition.x,n.y-this._startPosition.y);this.emit("pointermove",{position:n,delta:o,pointerId:t.pointerId,originalEvent:t})}else v.release(n)};this._onPointerUp=t=>{t.pointerId===this._activePointerId&&(this._moveThrottle.flush(),this._isDragging&&this.emit("pointerup",{position:D(t.clientX,t.clientY),pointerId:t.pointerId,originalEvent:t}),this._cleanup())};this._onPointerCancel=t=>{t.pointerId===this._activePointerId&&(this._moveThrottle.cancel(),this._isDragging&&this.emit("pointercancel",{position:D(t.clientX,t.clientY),pointerId:t.pointerId,originalEvent:t}),this._cleanup())};this._container=t.container,this._options=t,this._moveThrottle=new E(n=>this._processMove(n))}attach(){if(this._attached)return;this._getEventTarget().addEventListener("pointerdown",this._onPointerDown,{passive:!1}),this._attached=!0}detach(){if(!this._attached)return;this._getEventTarget().removeEventListener("pointerdown",this._onPointerDown),this._cleanup(),this._attached=!1}get isActive(){return this._activePointerId!==null}get isDragging(){return this._isDragging}_getEventTarget(){return this._container instanceof ShadowRoot?this._container.host:this._container}_startDrag(t){this._isDragging||!this._activeElement||!this._startPosition||(this._isDragging=!0,this.emit("pointerdown",{element:this._activeElement,position:{x:this._startPosition.x,y:this._startPosition.y},pointerId:t.pointerId,originalEvent:t}))}_findDraggable(t){let n=t.target,o=t.composedPath();for(let i of o)if(i instanceof HTMLElement){if(i.matches(this._options.draggableSelector))return i;if(i===this._container||i===this._container.host)break}return n.closest?.(this._options.draggableSelector)}_findHandle(t,n){if(!this._options.handleSelector)return n;let i=t.target.closest?.(this._options.handleSelector);return i&&n.contains(i)?i:null}_clearDelayTimer(){this._delayTimer!==null&&(clearTimeout(this._delayTimer),this._delayTimer=null)}_cleanup(){this._clearDelayTimer(),this._moveThrottle.cancel(),this._startPosition&&(v.release(this._startPosition),this._startPosition=null);let t=this._getEventTarget();t.removeEventListener("pointermove",this._onPointerMove),t.removeEventListener("pointerup",this._onPointerUp),t.removeEventListener("pointercancel",this._onPointerCancel),this._activePointerId=null,this._activeElement=null,this._isDragging=!1}destroy(){this.detach(),this._moveThrottle.destroy(),super.destroy()}};var L=class{constructor(){this._cache=new WeakMap;this._dirty=new WeakSet;this._invalidateAll=!1}get(e){if(this._invalidateAll||this._dirty.has(e))return this._update(e);let t=this._cache.get(e);return t||this._update(e)}invalidate(e){this._dirty.add(e)}invalidateAll(){this._invalidateAll=!0}update(e){return this._update(e)}remove(e){this._cache.delete(e)}clearDirty(){this._invalidateAll=!1}_update(e){let t=e.getBoundingClientRect();return this._cache.set(e,t),this._dirty.delete(e),t}},h=new L;function C(r,e,t){return r>=t.left&&r<=t.right&&e>=t.top&&e<=t.bottom}function g(r){return{x:r.left+r.width/2,y:r.top+r.height/2}}var y=class{constructor(e){this._enabled=!1;this._listenerUnsubscribers=[];this._ghost=null;this._ghostOffset={x:0,y:0};this._onPointerDown=e=>{let{element:t,position:n}=e,o=this._getItemData(t)??this._extractDataAttributes(t),i=this._state.startDrag(t,n,o),s={element:t,position:{x:n.x,y:n.y},data:i.data,cancel:()=>{this._state.cancelDrag()}};if(this._options.onDragStart?.(s)===!1){this._state.cancelDrag();return}this._createGhost(t,n),t.classList.add("snap-dragging"),this._options.ghostClass&&t.classList.add(this._options.ghostClass),h.invalidateAll()};this._onPointerMove=e=>{let t=this._state.session;if(!t)return;let{position:n}=e,o=this._getItemAxis(t.element)??this._options.axis??"both";o!=="both"&&(n=this._applyAxisConstraint(n,t.origin,o)),this._options.grid&&(n=this._applyGridSnap(n,this._options.grid)),this._state.updatePosition(n),this._updateGhost(n),this._updateDropZone(n),this._options.onDragMove?.({element:t.element,position:{x:t.current.x,y:t.current.y},delta:{x:t.delta.x,y:t.delta.y},dropZone:t.dropZone})};this._onPointerUp=e=>{if(!this._state.session)return;let n=this._state.endDrag();n&&(this._cleanup(n.element),n.dropZone&&this._options.onDrop?.({element:n.element,dropZone:n.dropZone,position:{x:n.current.x,y:n.current.y},data:n.data}),this._options.onDragEnd?.({element:n.element,position:{x:n.current.x,y:n.current.y},delta:{x:n.delta.x,y:n.delta.y},cancelled:!1}))};this._onPointerCancel=e=>{let t=this._state.session;if(!t)return;let n=t.element;this._state.cancelDrag(),this._cleanup(n),this._options.onDragEnd?.({element:n,position:e.position,delta:{x:0,y:0},cancelled:!0})};this._container=e.container,this._state=e.state,this._options=e.options,this._getDropZones=e.getDropZones,this._getItemData=e.getItemData,this._getItemAxis=e.getItemAxis,this._pointerSensor=new x({container:this._container,draggableSelector:this._options.draggableSelector??"[data-draggable]",handleSelector:this._options.handleSelector,delay:this._options.delay,distance:this._options.distance}),this._setupListeners()}enable(){this._enabled||(this._pointerSensor.attach(),this._enabled=!0)}disable(){this._enabled&&(this._pointerSensor.detach(),this._state.reset(),this._removeGhost(),this._enabled=!1)}get isEnabled(){return this._enabled}updateOptions(e){Object.assign(this._options,e)}_setupListeners(){this._listenerUnsubscribers.push(this._pointerSensor.on("pointerdown",this._onPointerDown),this._pointerSensor.on("pointermove",this._onPointerMove),this._pointerSensor.on("pointerup",this._onPointerUp),this._pointerSensor.on("pointercancel",this._onPointerCancel))}_applyAxisConstraint(e,t,n){return n==="x"?{x:e.x,y:t.y}:n==="y"?{x:t.x,y:e.y}:e}_applyGridSnap(e,t){return{x:Math.round(e.x/t.x)*t.x,y:Math.round(e.y/t.y)*t.y}}_updateDropZone(e){let t=this._getDropZones(),n=null;for(let i of t){let s=h.get(i);if(C(e.x,e.y,s)){n=i;break}}let o=this._state.session;o&&n!==o.dropZone&&(o.dropZone&&this._options.onDropZoneLeave?.({element:o.element,dropZone:o.dropZone}),this._state.setDropTarget(n),n&&this._options.onDropZoneEnter?.({element:o.element,dropZone:n,position:e}))}_createGhost(e,t){let n=e.getBoundingClientRect();this._ghostOffset={x:t.x-n.left,y:t.y-n.top},this._ghost=e.cloneNode(!0),this._ghost.style.cssText=`
2
- position: fixed;
3
- left: ${n.left}px;
4
- top: ${n.top}px;
5
- width: ${n.width}px;
6
- height: ${n.height}px;
7
- margin: 0;
8
- pointer-events: none;
9
- z-index: 9999;
10
- opacity: 0.8;
11
- will-change: transform;
12
- `,this._ghost.classList.add("snap-ghost"),document.body.appendChild(this._ghost)}_updateGhost(e){if(!this._ghost)return;let t=e.x-this._ghostOffset.x,n=e.y-this._ghostOffset.y;this._ghost.style.transform=`translate(${t-parseFloat(this._ghost.style.left)}px, ${n-parseFloat(this._ghost.style.top)}px)`}_removeGhost(){this._ghost&&(this._ghost.remove(),this._ghost=null)}_cleanup(e){e.classList.remove("snap-dragging"),this._options.ghostClass&&e.classList.remove(this._options.ghostClass),this._removeGhost()}_extractDataAttributes(e){let t={};for(let o of e.attributes)if(o.name.startsWith("data-drag-")){let i=o.name.slice(10);t[i]=o.value}let n=e.dataset.draggable;return n&&n!==""&&(t.type=n),t}destroy(){this.disable();for(let e of this._listenerUnsubscribers)e();this._listenerUnsubscribers=[],this._pointerSensor.destroy()}};var P=class{constructor(e,t={}){this._isActive=!1;this._element=e,this._options=t}get element(){return this._element}get isActive(){return this._isActive}setOptions(e){Object.assign(this._options,e)}containsPoint(e,t){let n=h.get(this._element);return C(e,t,n)}accepts(e){let{accepts:t}=this._options;if(!t)return!0;if(typeof t=="function")return t(e);for(let o of t)if(e.hasType(o)||e.getData("type")===o)return!0;let n=this._element.dataset.accepts;if(n){let o=n.split(",").map(i=>i.trim());for(let i of o)if(e.hasType(i)||e.getData("type")===i)return!0}return!1}setActive(e){this._isActive!==e&&(this._isActive=e,e?this._element.classList.add("snap-drop-active"):this._element.classList.remove("snap-drop-active"))}getInsertionIndex(e,t,n,o){let i=Array.from(this._element.querySelectorAll(n)).filter(l=>l!==o);if(i.length===0)return 0;let s=h.get(i[0]),a=h.get(i[i.length-1]),p=Math.abs(a.top-s.top)>Math.abs(a.left-s.left);for(let l=0;l<i.length;l++){let d=h.get(i[l]),c=g(d);if(p){if(t<c.y)return l}else if(e<c.x)return l}return i.length}getClosestItem(e,t,n,o){let i=Array.from(this._element.querySelectorAll(n)).filter(u=>u!==o);if(i.length===0)return null;let s=null,a=1/0,p="after",l=h.get(i[0]),d=h.get(i[i.length-1]),c=Math.abs(d.top-l.top)>Math.abs(d.left-l.left);for(let u of i){let M=h.get(u),H=g(M),B=e-H.x,q=t-H.y,X=Math.sqrt(B*B+q*q);X<a&&(a=X,s=u,p=c?t<H.y?"before":"after":e<H.x?"before":"after")}return s?{element:s,position:p}:null}updateBounds(){h.update(this._element)}destroy(){this.setActive(!1),h.remove(this._element)}},S=class{constructor(){this._zones=new Map}register(e,t){let n=this._zones.get(e);return n?(t&&n.setOptions(t),n):(n=new P(e,t),this._zones.set(e,n),n)}unregister(e){let t=this._zones.get(e);t&&(t.destroy(),this._zones.delete(e))}get(e){return this._zones.get(e)}getElements(){return[...this._zones.keys()]}getAll(){return[...this._zones.values()]}findAtPoint(e,t){for(let n of this._zones.values())if(n.containsPoint(e,t))return n;return null}clear(){for(let e of this._zones.values())e.destroy();this._zones.clear()}updateAllBounds(){h.invalidateAll()}destroy(){this.clear()}};var Q={draggableSelector:"[data-draggable]",dropZoneSelector:"[data-droppable]",axis:"both",autoRefresh:!1},I=class{constructor(e,t={}){this._imperativeDraggables=new Map;this._imperativeDropZones=new Map;this._plugins=[];this._behaviors=[];this._stateUnsubscribers=[];this._observer=null;this._refreshScheduled=!1;this._destroyed=!1;this._scrollHandler=null;this._resizeHandler=null;this._container=e,this._options={...Q,...t},this._state=new f,this._dropZoneManager=new S,this._engine=new y({container:this._container,state:this._state,options:this._options,getDropZones:()=>this._getDropZones(),getItemData:n=>this._getItemData(n),getItemAxis:n=>this._getItemAxis(n)}),this._setupStateListeners(),this._scanDeclarativeElements(),this._options.autoRefresh&&this._setupAutoRefresh(),this._setupScrollResize(),this.enable()}get options(){return this._options}enable(){this._engine.enable()}disable(){this._engine.disable()}destroy(){this._destroyed=!0,this.disable();for(let e of this._stateUnsubscribers)e();this._stateUnsubscribers=[];for(let e of this._plugins)e.destroy();this._plugins=[];for(let e of this._behaviors)e.destroy();this._behaviors=[],this._engine.destroy(),this._state.destroy(),this._dropZoneManager.destroy(),this._observer?.disconnect(),this._observer=null,this._scrollHandler&&(window.removeEventListener("scroll",this._scrollHandler,!0),this._scrollHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null),this._imperativeDraggables.clear(),this._imperativeDropZones.clear()}refresh(){this._scanDeclarativeElements(),h.invalidateAll()}addDraggable(e,t){this._imperativeDraggables.set(e,t??{})}removeDraggable(e){this._imperativeDraggables.delete(e)}addDropZone(e,t){this._imperativeDropZones.set(e,t??{}),this._dropZoneManager.register(e,t)}removeDropZone(e){this._imperativeDropZones.delete(e),this._dropZoneManager.unregister(e)}isDragging(){return this._state.isDragging()}getActiveElement(){return this._state.getActiveElement()}use(e){return this._plugins.push(e),e.init(this),this}addBehavior(e){return this._behaviors.push(e),this}setOptions(e){Object.assign(this._options,e),this._engine.updateOptions(this._options)}_getDropZones(){let e=this._options.dropZoneSelector??"[data-droppable]",t=this._container instanceof ShadowRoot?this._container:this._container,n=Array.from(t.querySelectorAll(e)),o=[...this._imperativeDropZones.keys()];return[...new Set([...n,...o])]}_getItemData(e){return this._imperativeDraggables.get(e)?.data}_getItemAxis(e){let t=this._imperativeDraggables.get(e);if(t?.axis)return t.axis;let n=e.dataset.dragAxis;if(n==="x"||n==="y"||n==="both")return n}_scanDeclarativeElements(){let e=this._options.dropZoneSelector??"[data-droppable]",n=(this._container instanceof ShadowRoot?this._container:this._container).querySelectorAll(e);for(let o of n)this._imperativeDropZones.has(o)||this._dropZoneManager.register(o)}_setupStateListeners(){this._stateUnsubscribers.push(this._state.subscribe("dragstart",e=>{for(let t of this._behaviors)t.onDragStart?.(e)})),this._stateUnsubscribers.push(this._state.subscribe("dragmove",e=>{for(let t of this._behaviors)t.onDragMove?.(e)})),this._stateUnsubscribers.push(this._state.subscribe("dragend",e=>{for(let t of this._behaviors)t.onDragEnd?.(e)}))}_setupAutoRefresh(){this._observer=new MutationObserver(t=>{if(this._destroyed)return;let n=!1;for(let o of t)if(o.type==="childList"){n=!0;break}n&&!this._refreshScheduled&&(this._refreshScheduled=!0,requestAnimationFrame(()=>{this._destroyed||(this._refreshScheduled=!1,this.refresh())}))});let e=this._container instanceof ShadowRoot?this._container:this._container;this._observer.observe(e,{childList:!0,subtree:!0})}_setupScrollResize(){this._scrollHandler=()=>{this._state.isDragging()&&h.invalidateAll()},window.addEventListener("scroll",this._scrollHandler,!0),this._resizeHandler=()=>{h.invalidateAll()},window.addEventListener("resize",this._resizeHandler)}},G=I;var tt={animation:150,ghostClass:"snap-sortable-ghost",placeholderClass:"snap-sortable-placeholder"},A=class{constructor(e={}){this.name="sortable";this._snap=null;this._placeholder=null;this._originalIndex=-1;this._currentIndex=-1;this._container=null;this._items=[];this._unsubscribers=[];this._options={...tt,...e}}init(e){this._snap=e;let t=e.options.onDragStart,n=e.options.onDragMove,o=e.options.onDrop,i=e.options.onDragEnd;e.setOptions({onDragStart:s=>(this._onDragStart(s.element),t?.(s)),onDragMove:s=>{this._onDragMove(s.position.x,s.position.y),n?.(s)},onDrop:s=>{let a={...s,insertionIndex:this._currentIndex,sourceContainer:this._container??void 0};o?.(a)},onDragEnd:s=>{this._onDragEnd(),i?.(s)}})}destroy(){this._cleanup();for(let e of this._unsubscribers)e();this._unsubscribers=[],this._snap=null}_onDragStart(e){if(this._container=e.parentElement,!this._container)return;let t=this._snap?.options.draggableSelector??"[data-draggable]";this._items=Array.from(this._container.querySelectorAll(t)),this._originalIndex=this._items.indexOf(e),this._currentIndex=this._originalIndex,this._originalIndex!==-1&&(this._createPlaceholder(e),this._options.ghostClass&&e.classList.add(this._options.ghostClass))}_onDragMove(e,t){if(!this._placeholder||!this._container)return;let n=this._snap?.options.draggableSelector??"[data-draggable]",o=this._snap?.getActiveElement(),i=Array.from(this._container.querySelectorAll(n)).filter(d=>d!==o&&d!==this._placeholder);if(i.length===0){this._currentIndex=0;return}let s=h.get(i[0]),a=h.get(i[i.length-1]),p=Math.abs(a.top-s.top)>Math.abs(a.left-s.left),l=i.length;for(let d=0;d<i.length;d++){let c=h.get(i[d]),u=g(c);if(p){if(t<u.y){l=d;break}}else if(e<u.x){l=d;break}}l>this._originalIndex&&l++,l!==this._currentIndex&&(this._currentIndex=l,this._movePlaceholder(l))}_onDragEnd(){this._cleanup()}_createPlaceholder(e){let t=e.getBoundingClientRect();this._placeholder=document.createElement("div"),this._placeholder.className=this._options.placeholderClass??"",this._placeholder.style.cssText=`
13
- width: ${t.width}px;
14
- height: ${t.height}px;
15
- margin: 0;
16
- box-sizing: border-box;
17
- `,e.parentNode?.insertBefore(this._placeholder,e)}_movePlaceholder(e){if(!this._placeholder||!this._container)return;let t=this._snap?.options.draggableSelector??"[data-draggable]",n=this._snap?.getActiveElement(),o=Array.from(this._container.querySelectorAll(t)).filter(i=>i!==n);if(this._placeholder.remove(),e>=o.length)this._container.appendChild(this._placeholder);else{let i=o[e];i===this._placeholder&&(i=o[e+1]),i?this._container.insertBefore(this._placeholder,i):this._container.appendChild(this._placeholder)}this._options.animation&&this._options.animation>0&&this._animateItems()}_animateItems(){if(!this._container)return;let e=this._snap?.options.draggableSelector??"[data-draggable]",t=this._snap?.getActiveElement(),n=Array.from(this._container.querySelectorAll(e)).filter(i=>i!==t&&i!==this._placeholder),o=new Map;for(let i of n)o.set(i,i.getBoundingClientRect());this._container.offsetHeight;for(let i of n){let s=o.get(i),a=i.getBoundingClientRect();if(!s)continue;let p=s.left-a.left,l=s.top-a.top;(p!==0||l!==0)&&(i.style.transform=`translate(${p}px, ${l}px)`,i.style.transition="none",requestAnimationFrame(()=>{i.style.transition=`transform ${this._options.animation}ms ease`,i.style.transform=""}))}}_cleanup(){this._placeholder?.remove(),this._placeholder=null;let e=this._snap?.getActiveElement();e&&this._options.ghostClass&&e.classList.remove(this._options.ghostClass),this._container=null,this._items=[],this._originalIndex=-1,this._currentIndex=-1,h.invalidateAll()}getCurrentIndex(){return this._currentIndex}getOriginalIndex(){return this._originalIndex}};var et={containers:"[data-droppable]",items:"[data-draggable]",animation:150},O=class{constructor(e={}){this.name="kanban";this._snap=null;this._sourceContainer=null;this._targetContainer=null;this._placeholder=null;this._originalIndex=-1;this._currentIndex=-1;this._options={...et,...e}}init(e){this._snap=e;let t=e.options.onDragStart,n=e.options.onDragMove,o=e.options.onDropZoneEnter,i=e.options.onDropZoneLeave,s=e.options.onDrop,a=e.options.onDragEnd;e.setOptions({onDragStart:p=>(this._onDragStart(p.element),t?.(p)),onDragMove:p=>{this._onDragMove(p.position),n?.(p)},onDropZoneEnter:p=>{this._onDropZoneEnter(p.dropZone),o?.(p)},onDropZoneLeave:p=>{this._onDropZoneLeave(p.dropZone),i?.(p)},onDrop:p=>{let l={...p,insertionIndex:this._currentIndex,sourceContainer:this._sourceContainer??void 0};s?.(l)},onDragEnd:p=>{this._onDragEnd(),a?.(p)}})}destroy(){this._cleanup(),this._snap=null}_onDragStart(e){if(this._sourceContainer=e.closest(this._options.containers),!this._sourceContainer)return;let t=Array.from(this._sourceContainer.querySelectorAll(this._options.items));this._originalIndex=t.indexOf(e),this._createPlaceholder(e)}_onDragMove(e){if(!this._targetContainer||!this._placeholder)return;let t=this._calculateInsertionIndex(this._targetContainer,e.x,e.y);t!==this._currentIndex&&(this._currentIndex=t,this._movePlaceholder(t))}_onDropZoneEnter(e){e.matches(this._options.containers)&&(this._targetContainer=e,this._targetContainer.classList.add("snap-kanban-target"),this._placeholder&&(this._targetContainer.appendChild(this._placeholder),this._currentIndex=this._getItemCount(this._targetContainer)))}_onDropZoneLeave(e){e===this._targetContainer&&(e.classList.remove("snap-kanban-target"),this._placeholder?.remove(),this._targetContainer=null,this._currentIndex=-1)}_onDragEnd(){this._cleanup()}_createPlaceholder(e){let t=e.getBoundingClientRect();this._placeholder=document.createElement("div"),this._placeholder.className="snap-kanban-placeholder",this._placeholder.style.cssText=`
18
- width: ${t.width}px;
19
- height: ${t.height}px;
20
- margin: 0;
21
- box-sizing: border-box;
22
- opacity: 0.5;
23
- border: 2px dashed #ccc;
24
- border-radius: 4px;
25
- background: rgba(0, 0, 0, 0.05);
26
- `,e.parentNode?.insertBefore(this._placeholder,e)}_movePlaceholder(e){if(!this._placeholder||!this._targetContainer)return;let t=this._snap?.getActiveElement(),n=Array.from(this._targetContainer.querySelectorAll(this._options.items)).filter(o=>o!==t&&o!==this._placeholder);if(this._placeholder.remove(),e>=n.length)this._targetContainer.appendChild(this._placeholder);else{let o=n[e];o?this._targetContainer.insertBefore(this._placeholder,o):this._targetContainer.appendChild(this._placeholder)}this._options.animation>0&&this._animateItems(this._targetContainer)}_calculateInsertionIndex(e,t,n){let o=this._snap?.getActiveElement(),i=Array.from(e.querySelectorAll(this._options.items)).filter(l=>l!==o&&l!==this._placeholder);if(i.length===0)return 0;let s=h.get(i[0]),a=h.get(i[i.length-1]),p=Math.abs(a.top-s.top)>Math.abs(a.left-s.left);for(let l=0;l<i.length;l++){let d=h.get(i[l]),c=g(d);if(p){if(n<c.y)return l}else if(t<c.x)return l}return i.length}_getItemCount(e){let t=this._snap?.getActiveElement();return Array.from(e.querySelectorAll(this._options.items)).filter(n=>n!==t&&n!==this._placeholder).length}_animateItems(e){let t=this._snap?.getActiveElement(),n=Array.from(e.querySelectorAll(this._options.items)).filter(i=>i!==t&&i!==this._placeholder),o=new Map;for(let i of n)o.set(i,i.getBoundingClientRect());e.offsetHeight;for(let i of n){let s=o.get(i),a=i.getBoundingClientRect();if(!s)continue;let p=s.left-a.left,l=s.top-a.top;(p!==0||l!==0)&&(i.style.transform=`translate(${p}px, ${l}px)`,i.style.transition="none",requestAnimationFrame(()=>{i.style.transition=`transform ${this._options.animation}ms ease`,i.style.transform=""}))}}_cleanup(){this._placeholder?.remove(),this._placeholder=null,this._sourceContainer?.classList.remove("snap-kanban-source"),this._targetContainer?.classList.remove("snap-kanban-target"),this._sourceContainer=null,this._targetContainer=null,this._originalIndex=-1,this._currentIndex=-1,h.invalidateAll()}getSourceContainer(){return this._sourceContainer}getTargetContainer(){return this._targetContainer}getCurrentIndex(){return this._currentIndex}};var T=class extends _{constructor(t){super();this._attached=!1;this._dragCount=0;this._currentDropZone=null;this._onDragEnter=t=>{if(!this._hasFiles(t))return;this._dragCount++;let n=this._findDropZone(t);n&&(t.preventDefault(),n!==this._currentDropZone&&(this._currentDropZone&&this.emit("dragleave",{position:{x:t.clientX,y:t.clientY},dropZone:this._currentDropZone,originalEvent:t}),this._currentDropZone=n,this.emit("dragenter",{position:{x:t.clientX,y:t.clientY},dropZone:n,originalEvent:t})))};this._onDragOver=t=>{if(!this._hasFiles(t))return;let n=this._findDropZone(t);n&&(t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="copy"),this.emit("dragover",{position:{x:t.clientX,y:t.clientY},dropZone:n,originalEvent:t}))};this._onDragLeave=t=>{this._hasFiles(t)&&(this._dragCount--,this._dragCount===0&&this._currentDropZone&&(this.emit("dragleave",{position:{x:t.clientX,y:t.clientY},dropZone:this._currentDropZone,originalEvent:t}),this._currentDropZone=null))};this._onDrop=t=>{t.preventDefault(),this._dragCount=0;let n=this._findDropZone(t);if(!n)return;let o=this._getFiles(t);o.length!==0&&(this.emit("drop",{files:o,position:{x:t.clientX,y:t.clientY},dropZone:n,originalEvent:t}),this._currentDropZone=null)};this._container=t.container,this._options=t}attach(){if(this._attached)return;let t=this._getEventTarget();t.addEventListener("dragenter",this._onDragEnter,{passive:!1}),t.addEventListener("dragover",this._onDragOver,{passive:!1}),t.addEventListener("dragleave",this._onDragLeave,{passive:!1}),t.addEventListener("drop",this._onDrop,{passive:!1}),this._attached=!0}detach(){if(!this._attached)return;let t=this._getEventTarget();t.removeEventListener("dragenter",this._onDragEnter),t.removeEventListener("dragover",this._onDragOver),t.removeEventListener("dragleave",this._onDragLeave),t.removeEventListener("drop",this._onDrop),this._dragCount=0,this._currentDropZone=null,this._attached=!1}_getEventTarget(){return this._container instanceof ShadowRoot?this._container.host:this._container}_findDropZone(t){let n=t.target,o=t.composedPath();for(let i of o)if(i instanceof HTMLElement){if(i.matches(this._options.dropZoneSelector))return i;if(i===this._container||i===this._container.host)break}return n.closest?.(this._options.dropZoneSelector)}_hasFiles(t){if(!t.dataTransfer)return!1;let n=t.dataTransfer.types;return n.includes("Files")||n.includes("application/x-moz-file")}_getFiles(t){if(!t.dataTransfer?.files)return[];let n=Array.from(t.dataTransfer.files),o=this._options.accept;o&&o.length>0&&(n=n.filter(s=>this._matchesAccept(s,o)));let i=this._options.maxSize;return i&&i>0&&(n=n.filter(s=>s.size<=i)),!this._options.multiple&&n.length>1&&(n=[n[0]]),n}_matchesAccept(t,n){for(let o of n){if(o.startsWith(".")){if(t.name.toLowerCase().endsWith(o.toLowerCase()))return!0;continue}if(o.endsWith("/*")){let i=o.slice(0,-1);if(t.type.startsWith(i))return!0;continue}if(t.type===o)return!0}return!1}destroy(){this.detach(),super.destroy()}};var nt={multiple:!0},Z=class{constructor(e={}){this.name="file-drop";this._snap=null;this._sensor=null;this._onFileDrop=null;this._options={...nt,...e}}init(e){this._snap=e;let t=this._getContainer();t&&(this._sensor=new T({container:t,dropZoneSelector:e.options.dropZoneSelector??"[data-file-drop]",accept:this._options.accept,multiple:this._options.multiple,maxSize:this._options.maxSize}),this._setupEventHandlers(),this._sensor.attach())}destroy(){this._sensor?.destroy(),this._sensor=null,this._snap=null,this._onFileDrop=null}onFileDrop(e){return this._onFileDrop=e,this}setOptions(e){Object.assign(this._options,e)}_getContainer(){return this._snap?this._snap._container:null}_setupEventHandlers(){this._sensor&&(this._sensor.on("dragenter",e=>{e.dropZone.classList.add("snap-file-drag-over")}),this._sensor.on("dragleave",e=>{e.dropZone.classList.remove("snap-file-drag-over")}),this._sensor.on("drop",e=>{e.dropZone.classList.remove("snap-file-drag-over");let t={files:e.files,position:e.position,dropZone:e.dropZone};this._onFileDrop?.(t),this._snap?.options?.onFileDrop?.(t)}))}};function U(r,e){let{onDrop:t,onDragEnter:n,onDragLeave:o,...i}=e,s=0,a=c=>{z(c)&&(c.preventDefault(),s++,s===1&&(r.classList.add("snap-file-drag-over"),n?.()))},p=c=>{z(c)&&(c.preventDefault(),c.dataTransfer&&(c.dataTransfer.dropEffect="copy"))},l=c=>{z(c)&&(s--,s===0&&(r.classList.remove("snap-file-drag-over"),o?.()))},d=c=>{c.preventDefault(),s=0,r.classList.remove("snap-file-drag-over");let u=Array.from(c.dataTransfer?.files??[]);i.accept?.length&&(u=u.filter(M=>it(M,i.accept))),i.maxSize&&(u=u.filter(M=>M.size<=i.maxSize)),!i.multiple&&u.length>1&&(u=[u[0]]),u.length>0&&t(u)};return r.addEventListener("dragenter",a),r.addEventListener("dragover",p),r.addEventListener("dragleave",l),r.addEventListener("drop",d),()=>{r.removeEventListener("dragenter",a),r.removeEventListener("dragover",p),r.removeEventListener("dragleave",l),r.removeEventListener("drop",d),r.classList.remove("snap-file-drag-over")}}function z(r){if(!r.dataTransfer)return!1;let e=r.dataTransfer.types;return e.includes("Files")||e.includes("application/x-moz-file")}function it(r,e){for(let t of e){if(t.startsWith(".")){if(r.name.toLowerCase().endsWith(t.toLowerCase()))return!0;continue}if(t.endsWith("/*")){let n=t.slice(0,-1);if(r.type.startsWith(n))return!0;continue}if(r.type===t)return!0}return!1}var ot={threshold:40,maxSpeed:15,acceleration:2},w=class{constructor(e={}){this.name="auto-scroll";this._scrollableAncestors=[];this._rafId=null;this._active=!1;this._options={...ot,...e}}onDragStart(e){this._scrollableAncestors=this._findScrollableAncestors(e.element),this._active=!0}onDragMove(e){!this._active||this._rafId!==null||(this._rafId=requestAnimationFrame(()=>{this._rafId=null,this._performScroll(e.current.x,e.current.y)}))}onDragEnd(){this._active=!1,this._scrollableAncestors=[],this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null)}destroy(){this.onDragEnd()}_performScroll(e,t){for(let n of this._scrollableAncestors){let o=n.getBoundingClientRect(),i=this._calculateScrollSpeed(e,t,o);(i.x!==0||i.y!==0)&&n.scrollBy({left:i.x,top:i.y,behavior:"instant"})}}_calculateScrollSpeed(e,t,n){let{threshold:o,maxSpeed:i}=this._options,s=0,a=0;return e<n.left+o?s=-this._getSpeed(n.left+o-e):e>n.right-o&&(s=this._getSpeed(e-(n.right-o))),t<n.top+o?a=-this._getSpeed(n.top+o-t):t>n.bottom-o&&(a=this._getSpeed(t-(n.bottom-o))),{x:s,y:a}}_getSpeed(e){let{threshold:t,maxSpeed:n,acceleration:o}=this._options,i=Math.min(e/t,1);return Math.pow(i,o)*n}_findScrollableAncestors(e){let t=[],n=e.parentElement;for(;n&&n!==document.body;){let o=getComputedStyle(n),i=o.overflowX,s=o.overflowY,a=(i==="auto"||i==="scroll")&&n.scrollWidth>n.clientWidth,p=(s==="auto"||s==="scroll")&&n.scrollHeight>n.clientHeight;(a||p)&&t.push(n),n=n.parentElement}return(document.documentElement.scrollHeight>window.innerHeight||document.documentElement.scrollWidth>window.innerWidth)&&t.push(document.documentElement),t}};var R=class{constructor(e){this.name="snap-grid";this._guideContainer=null;this._options=e}onDragStart(e){this._options.showGuides&&this._createGuides(e.element)}onDragMove(e){}onDragEnd(){this._removeGuides()}destroy(){this._removeGuides()}snap(e,t){return{x:Math.round(e/this._options.x)*this._options.x,y:Math.round(t/this._options.y)*this._options.y}}snapWithThreshold(e,t,n){let o=n??this._options.threshold??5,i=this.snap(e,t);return{x:Math.abs(e-i.x)<o?i.x:e,y:Math.abs(t-i.y)<o?i.y:t}}_createGuides(e){let t=e.offsetParent||document.body,n=t.getBoundingClientRect();this._guideContainer=document.createElement("div"),this._guideContainer.style.cssText=`
27
- position: absolute;
28
- top: 0;
29
- left: 0;
30
- right: 0;
31
- bottom: 0;
32
- pointer-events: none;
33
- z-index: 9998;
34
- `;let o=Math.ceil(n.width/this._options.x);for(let s=1;s<o;s++){let a=document.createElement("div");a.style.cssText=`
35
- position: absolute;
36
- left: ${s*this._options.x}px;
37
- top: 0;
38
- bottom: 0;
39
- width: 1px;
40
- background: rgba(0, 120, 255, 0.2);
41
- `,this._guideContainer.appendChild(a)}let i=Math.ceil(n.height/this._options.y);for(let s=1;s<i;s++){let a=document.createElement("div");a.style.cssText=`
42
- position: absolute;
43
- top: ${s*this._options.y}px;
44
- left: 0;
45
- right: 0;
46
- height: 1px;
47
- background: rgba(0, 120, 255, 0.2);
48
- `,this._guideContainer.appendChild(a)}t.appendChild(this._guideContainer)}_removeGuides(){this._guideContainer?.remove(),this._guideContainer=null}};var F=class{constructor(e={}){this.name="constraint-axis";this._bounds=null;this._options=e}onDragStart(e){this._options.containWithinParent?this._calculateParentBounds(e.element):this._options.bounds&&(this._bounds={minX:this._options.bounds.minX??-1/0,maxX:this._options.bounds.maxX??1/0,minY:this._options.bounds.minY??-1/0,maxY:this._options.bounds.maxY??1/0})}onDragMove(e){}onDragEnd(){this._bounds=null}destroy(){this._bounds=null}constrain(e,t){let{x:n,y:o}=e,i=this._options.axis??"both";return i==="x"?o=t.y:i==="y"&&(n=t.x),this._bounds&&(n=Math.max(this._bounds.minX,Math.min(this._bounds.maxX,n)),o=Math.max(this._bounds.minY,Math.min(this._bounds.maxY,o))),{x:n,y:o}}getBounds(){return this._bounds}_calculateParentBounds(e){let t=e.parentElement;if(!t)return;let n=t.getBoundingClientRect(),o=e.getBoundingClientRect();this._bounds={minX:n.left,maxX:n.right-o.width,minY:n.top,maxY:n.bottom-o.height}}};return J(st);})();
49
- //# sourceMappingURL=snap.umd.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/index.ts", "../src/utils/EventEmitter.ts", "../src/utils/DataTransfer.ts", "../src/core/DragState.ts", "../src/utils/RAFThrottle.ts", "../src/utils/ObjectPool.ts", "../src/sensors/PointerSensor.ts", "../src/utils/BoundsCache.ts", "../src/core/DragEngine.ts", "../src/core/DropZone.ts", "../src/core/Snap.ts", "../src/plugins/Sortable.ts", "../src/plugins/Kanban.ts", "../src/sensors/FileSensor.ts", "../src/plugins/FileDrop.ts", "../src/behaviors/AutoScroll.ts", "../src/behaviors/SnapGrid.ts", "../src/behaviors/ConstraintAxis.ts"],
4
- "sourcesContent": ["/**\n * Snap - A zero-dependency, memory-optimized drag and drop library\n *\n * @example Basic usage with data attributes\n * ```html\n * <div id=\"container\">\n * <div data-draggable>Drag me</div>\n * <div data-droppable>Drop here</div>\n * </div>\n *\n * <script>\n * const snap = new Snap(document.getElementById('container'));\n * </script>\n * ```\n *\n * @example Imperative usage\n * ```javascript\n * const snap = new Snap(container, {\n * onDrop: (e) => console.log('Dropped!', e.element, e.dropZone)\n * });\n *\n * snap.addDraggable(myElement, { data: { id: 1 } });\n * snap.addDropZone(myZone, { accepts: ['item'] });\n * ```\n *\n * @example With Lit Element\n * ```javascript\n * class MyComponent extends LitElement {\n * snap;\n *\n * firstUpdated() {\n * this.snap = new Snap(this.shadowRoot, {\n * autoRefresh: true,\n * onDrop: this.handleDrop.bind(this)\n * });\n * }\n *\n * disconnectedCallback() {\n * super.disconnectedCallback();\n * this.snap?.destroy();\n * }\n * }\n * ```\n */\n\n// Main entry point\nexport { Snap, default } from './core/Snap.js';\n\n// Core classes (for advanced usage)\nexport { DragState } from './core/DragState.js';\nexport { DragEngine } from './core/DragEngine.js';\nexport { DropZone, DropZoneManager } from './core/DropZone.js';\n\n// Plugins\nexport { Sortable } from './plugins/Sortable.js';\nexport { Kanban } from './plugins/Kanban.js';\nexport { FileDrop, createFileDropZone } from './plugins/FileDrop.js';\n\n// Behaviors\nexport { AutoScroll } from './behaviors/AutoScroll.js';\nexport { SnapGrid } from './behaviors/SnapGrid.js';\nexport { ConstraintAxis } from './behaviors/ConstraintAxis.js';\n\n// Utilities (for custom implementations)\nexport { EventEmitter } from './utils/EventEmitter.js';\nexport { ObjectPool, pointPool, rectPool } from './utils/ObjectPool.js';\nexport { BoundsCache, boundsCache } from './utils/BoundsCache.js';\nexport { RAFThrottle, rafThrottle } from './utils/RAFThrottle.js';\nexport { SnapDataTransfer } from './utils/DataTransfer.js';\n\n// Sensors (for custom implementations)\nexport { PointerSensor } from './sensors/PointerSensor.js';\nexport { FileSensor } from './sensors/FileSensor.js';\n\n// Types\nexport type {\n // Core types\n Point,\n Rect,\n Axis,\n Unsubscribe,\n\n // Session types\n DragSession,\n DragPhase,\n DataTransfer,\n\n // Event types\n DragStartEvent,\n DragMoveEvent,\n DragEndEvent,\n DropEvent,\n DropZoneEnterEvent,\n DropZoneLeaveEvent,\n FileDropEvent,\n\n // Options types\n SnapOptions,\n SnapInstance,\n ItemOptions,\n DropZoneOptions,\n AutoScrollOptions,\n GridOptions,\n SortableOptions,\n KanbanOptions,\n FileDropOptions,\n\n // Plugin/Behavior types\n Plugin,\n Behavior,\n Sensor,\n} from './types/index.js';\n", "/**\n * Lightweight pub/sub event emitter\n * Optimized for minimal allocations\n */\nimport type { Unsubscribe } from '../types/index.js';\n\nexport type EventCallback<T = unknown> = (data: T) => void;\n\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private _listeners = new Map<keyof Events, Set<EventCallback>>();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n let listeners = this._listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this._listeners.set(event, listeners);\n }\n listeners.add(callback as EventCallback);\n\n return () => {\n listeners!.delete(callback as EventCallback);\n if (listeners!.size === 0) {\n this._listeners.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof Events>(\n event: K,\n callback: EventCallback<Events[K]>\n ): Unsubscribe {\n const unsubscribe = this.on(event, (data) => {\n unsubscribe();\n callback(data);\n });\n return unsubscribe;\n }\n\n /**\n * Emit an event to all subscribers\n */\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n const listeners = this._listeners.get(event);\n if (listeners) {\n // Iterate over a copy to allow unsubscribe during emit\n for (const callback of [...listeners]) {\n callback(data);\n }\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners\n */\n off<K extends keyof Events>(event?: K): void {\n if (event) {\n this._listeners.delete(event);\n } else {\n this._listeners.clear();\n }\n }\n\n /**\n * Check if there are any listeners for an event\n */\n hasListeners<K extends keyof Events>(event: K): boolean {\n const listeners = this._listeners.get(event);\n return listeners !== undefined && listeners.size > 0;\n }\n\n /**\n * Get the number of listeners for an event\n */\n listenerCount<K extends keyof Events>(event: K): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n\n /**\n * Clear all listeners\n */\n destroy(): void {\n this._listeners.clear();\n }\n}\n", "/**\n * Custom DataTransfer implementation for passing data during drag operations\n * Not the browser's native DataTransfer\n */\nimport type { DataTransfer as IDataTransfer } from '../types/index.js';\n\nexport class SnapDataTransfer implements IDataTransfer {\n private _data = new Map<string, unknown>();\n\n /**\n * Set data for a given type\n */\n setData(type: string, value: unknown): void {\n this._data.set(type, value);\n }\n\n /**\n * Get data for a given type\n */\n getData<T = unknown>(type: string): T | undefined {\n return this._data.get(type) as T | undefined;\n }\n\n /**\n * Check if a type exists\n */\n hasType(type: string): boolean {\n return this._data.has(type);\n }\n\n /**\n * Get all registered types\n */\n get types(): string[] {\n return [...this._data.keys()];\n }\n\n /**\n * Clear all data\n */\n clear(): void {\n this._data.clear();\n }\n\n /**\n * Create a copy of this transfer\n */\n clone(): SnapDataTransfer {\n const copy = new SnapDataTransfer();\n for (const [key, value] of this._data) {\n copy.setData(key, value);\n }\n return copy;\n }\n}\n", "/**\n * Centralized drag state management\n * Single source of truth for the current drag session\n */\nimport type {\n DragSession,\n DragPhase,\n Point,\n StateEvent,\n Unsubscribe,\n} from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { SnapDataTransfer } from '../utils/DataTransfer.js';\n\n// Internal events\ninterface StateEvents {\n dragstart: DragSession;\n dragmove: DragSession;\n dragend: DragSession;\n dropzoneenter: DragSession;\n dropzoneleave: DragSession;\n drop: DragSession;\n}\n\nexport class DragState extends EventEmitter<StateEvents> {\n private _session: DragSession | null = null;\n private _idCounter = 0;\n\n /**\n * Get current drag session (null if not dragging)\n */\n get session(): DragSession | null {\n return this._session;\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._session !== null && this._session.phase === 'dragging';\n }\n\n /**\n * Get the element being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._session?.element ?? null;\n }\n\n /**\n * Get current drop zone\n */\n getCurrentDropZone(): HTMLElement | null {\n return this._session?.dropZone ?? null;\n }\n\n /**\n * Start a new drag session\n */\n startDrag(\n element: HTMLElement,\n origin: Point,\n initialData?: Record<string, unknown>\n ): DragSession {\n // End any existing session\n if (this._session) {\n this.cancelDrag();\n }\n\n const data = new SnapDataTransfer();\n if (initialData) {\n for (const [key, value] of Object.entries(initialData)) {\n data.setData(key, value);\n }\n }\n\n this._session = {\n id: `drag-${++this._idCounter}`,\n element,\n origin: { x: origin.x, y: origin.y },\n current: { x: origin.x, y: origin.y },\n delta: { x: 0, y: 0 },\n data,\n dropZone: null,\n phase: 'dragging',\n };\n\n this.emit('dragstart', this._session);\n return this._session;\n }\n\n /**\n * Update position during drag\n */\n updatePosition(point: Point): void {\n if (!this._session || this._session.phase !== 'dragging') return;\n\n this._session.current.x = point.x;\n this._session.current.y = point.y;\n this._session.delta.x = point.x - this._session.origin.x;\n this._session.delta.y = point.y - this._session.origin.y;\n\n this.emit('dragmove', this._session);\n }\n\n /**\n * Set or clear drop zone target\n */\n setDropTarget(zone: HTMLElement | null): void {\n if (!this._session) return;\n\n const previous = this._session.dropZone;\n if (previous === zone) return;\n\n // Emit leave for previous zone\n if (previous) {\n this._session.dropZone = null;\n this.emit('dropzoneleave', this._session);\n }\n\n // Emit enter for new zone\n if (zone) {\n this._session.dropZone = zone;\n this.emit('dropzoneenter', this._session);\n }\n }\n\n /**\n * Complete the drag with a drop\n */\n endDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'dropping';\n\n // Emit drop if over a valid drop zone\n if (session.dropZone) {\n this.emit('drop', session);\n }\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Cancel the current drag\n */\n cancelDrag(): DragSession | null {\n if (!this._session) return null;\n\n const session = this._session;\n session.phase = 'cancelled';\n session.dropZone = null;\n\n this.emit('dragend', session);\n this._session = null;\n\n return session;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(event: StateEvent, callback: (session: DragSession) => void): Unsubscribe {\n return this.on(event, callback);\n }\n\n /**\n * Reset state\n */\n reset(): void {\n if (this._session) {\n this.cancelDrag();\n }\n }\n\n /**\n * Cleanup\n */\n override destroy(): void {\n this.reset();\n super.destroy();\n }\n}\n", "/**\n * RAF-based throttling for high-frequency events\n * Ensures only one callback per animation frame\n */\nexport class RAFThrottle<T> {\n private _rafId: number | null = null;\n private _pending: T | null = null;\n private _callback: (data: T) => void;\n\n constructor(callback: (data: T) => void) {\n this._callback = callback;\n }\n\n /**\n * Queue data to be processed on next animation frame\n * Only the most recent data will be processed\n */\n queue(data: T): void {\n this._pending = data;\n\n if (this._rafId === null) {\n this._rafId = requestAnimationFrame(this._process);\n }\n }\n\n /**\n * Cancel any pending frame\n */\n cancel(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n this._pending = null;\n }\n\n /**\n * Process immediately if there's pending data\n */\n flush(): void {\n if (this._pending !== null) {\n this.cancel();\n this._callback(this._pending);\n this._pending = null;\n }\n }\n\n /**\n * Check if there's a pending frame\n */\n get isPending(): boolean {\n return this._rafId !== null;\n }\n\n private _process = (): void => {\n this._rafId = null;\n if (this._pending !== null) {\n const data = this._pending;\n this._pending = null;\n this._callback(data);\n }\n };\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.cancel();\n }\n}\n\n/**\n * Create a throttled function using RAF\n */\nexport function rafThrottle<T extends (...args: unknown[]) => void>(\n fn: T\n): T & { cancel: () => void; flush: () => void } {\n let rafId: number | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n const throttled = ((...args: Parameters<T>) => {\n lastArgs = args;\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n rafId = null;\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n });\n }\n }) as T & { cancel: () => void; flush: () => void };\n\n throttled.cancel = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n lastArgs = null;\n };\n\n throttled.flush = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (lastArgs !== null) {\n fn(...lastArgs);\n lastArgs = null;\n }\n };\n\n return throttled;\n}\n", "/**\n * Generic object pool for reusing frequently allocated objects\n * Reduces GC pressure during drag operations\n */\nexport class ObjectPool<T> {\n private _pool: T[] = [];\n private _factory: () => T;\n private _reset: (obj: T) => void;\n private _maxSize: number;\n\n constructor(\n factory: () => T,\n reset: (obj: T) => void,\n initialSize = 10,\n maxSize = 100\n ) {\n this._factory = factory;\n this._reset = reset;\n this._maxSize = maxSize;\n\n // Pre-allocate objects\n for (let i = 0; i < initialSize; i++) {\n this._pool.push(factory());\n }\n }\n\n /**\n * Get an object from the pool or create a new one\n */\n acquire(): T {\n return this._pool.pop() ?? this._factory();\n }\n\n /**\n * Return an object to the pool for reuse\n */\n release(obj: T): void {\n if (this._pool.length < this._maxSize) {\n this._reset(obj);\n this._pool.push(obj);\n }\n }\n\n /**\n * Clear all pooled objects\n */\n clear(): void {\n this._pool.length = 0;\n }\n\n /**\n * Current pool size\n */\n get size(): number {\n return this._pool.length;\n }\n}\n\n// Pre-configured pools for common types\nimport type { Point, Rect } from '../types/index.js';\n\nexport const pointPool = new ObjectPool<Point>(\n () => ({ x: 0, y: 0 }),\n (p) => {\n p.x = 0;\n p.y = 0;\n }\n);\n\nexport const rectPool = new ObjectPool<Rect>(\n () => ({ x: 0, y: 0, width: 0, height: 0 }),\n (r) => {\n r.x = 0;\n r.y = 0;\n r.width = 0;\n r.height = 0;\n }\n);\n\n/**\n * Helper to get a point from pool with initial values\n */\nexport function acquirePoint(x: number, y: number): Point {\n const p = pointPool.acquire();\n p.x = x;\n p.y = y;\n return p;\n}\n\n/**\n * Helper to get a rect from pool with initial values\n */\nexport function acquireRect(\n x: number,\n y: number,\n width: number,\n height: number\n): Rect {\n const r = rectPool.acquire();\n r.x = x;\n r.y = y;\n r.width = width;\n r.height = height;\n return r;\n}\n", "/**\n * Unified pointer event sensor\n * Handles mouse, touch, and pointer events through event delegation\n */\nimport type { Point, Sensor } from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { RAFThrottle } from '../utils/RAFThrottle.js';\nimport { acquirePoint, pointPool } from '../utils/ObjectPool.js';\n\nexport interface PointerSensorEvents {\n pointerdown: PointerStartEvent;\n pointermove: PointerMoveEvent;\n pointerup: PointerEndEvent;\n pointercancel: PointerEndEvent;\n}\n\nexport interface PointerStartEvent {\n element: HTMLElement;\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerMoveEvent {\n position: Point;\n delta: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerEndEvent {\n position: Point;\n pointerId: number;\n originalEvent: PointerEvent;\n}\n\nexport interface PointerSensorOptions {\n container: HTMLElement | ShadowRoot;\n draggableSelector: string;\n handleSelector?: string;\n delay?: number;\n distance?: number;\n}\n\nexport class PointerSensor\n extends EventEmitter<PointerSensorEvents>\n implements Sensor\n{\n private _container: HTMLElement | ShadowRoot;\n private _options: PointerSensorOptions;\n private _attached = false;\n\n // Active drag state\n private _activePointerId: number | null = null;\n private _activeElement: HTMLElement | null = null;\n private _startPosition: Point | null = null;\n private _isDragging = false;\n private _delayTimer: number | null = null;\n\n // RAF throttle for move events\n private _moveThrottle: RAFThrottle<PointerEvent>;\n\n constructor(options: PointerSensorOptions) {\n super();\n this._container = options.container;\n this._options = options;\n\n this._moveThrottle = new RAFThrottle((e) => this._processMove(e));\n }\n\n /**\n * Attach event listeners\n */\n attach(): void {\n if (this._attached) return;\n\n const target = this._getEventTarget();\n target.addEventListener('pointerdown', this._onPointerDown, {\n passive: false,\n });\n\n this._attached = true;\n }\n\n /**\n * Detach event listeners\n */\n detach(): void {\n if (!this._attached) return;\n\n const target = this._getEventTarget();\n target.removeEventListener('pointerdown', this._onPointerDown);\n\n this._cleanup();\n this._attached = false;\n }\n\n /**\n * Check if currently tracking a drag\n */\n get isActive(): boolean {\n return this._activePointerId !== null;\n }\n\n /**\n * Check if drag has started (past delay/distance threshold)\n */\n get isDragging(): boolean {\n return this._isDragging;\n }\n\n private _getEventTarget(): HTMLElement | Document {\n // For ShadowRoot, attach to the host element\n if (this._container instanceof ShadowRoot) {\n return this._container.host as HTMLElement;\n }\n return this._container;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n // Only handle primary pointer (left mouse button, first touch)\n if (!e.isPrimary || e.button !== 0) return;\n\n // Already tracking a pointer\n if (this._activePointerId !== null) return;\n\n // Find draggable element using event delegation\n const draggable = this._findDraggable(e);\n if (!draggable) return;\n\n // Check if click was on handle (if handle selector is specified)\n if (this._options.handleSelector) {\n const handle = this._findHandle(e, draggable);\n if (!handle) return;\n }\n\n // Prevent default to avoid text selection and native drag\n e.preventDefault();\n\n // Store initial state\n this._activePointerId = e.pointerId;\n this._activeElement = draggable;\n this._startPosition = acquirePoint(e.clientX, e.clientY);\n this._isDragging = false;\n\n // Set pointer capture for reliable tracking\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n\n // Attach move/up listeners\n const target = this._getEventTarget();\n target.addEventListener('pointermove', this._onPointerMove, {\n passive: true,\n });\n target.addEventListener('pointerup', this._onPointerUp);\n target.addEventListener('pointercancel', this._onPointerCancel);\n\n // Handle delay threshold\n const delay = this._options.delay ?? 0;\n if (delay > 0) {\n this._delayTimer = window.setTimeout(() => {\n this._delayTimer = null;\n this._startDrag(e);\n }, delay);\n } else if ((this._options.distance ?? 0) === 0) {\n // No delay or distance, start immediately\n this._startDrag(e);\n }\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n // Queue for RAF processing\n this._moveThrottle.queue(e);\n };\n\n private _processMove = (e: PointerEvent): void => {\n if (!this._startPosition || !this._activeElement) return;\n\n const position = acquirePoint(e.clientX, e.clientY);\n\n // Check distance threshold if not yet dragging\n if (!this._isDragging) {\n const distance = this._options.distance ?? 0;\n if (distance > 0) {\n const dx = position.x - this._startPosition.x;\n const dy = position.y - this._startPosition.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < distance) {\n pointPool.release(position);\n return;\n }\n\n // Distance threshold reached, start drag\n this._clearDelayTimer();\n this._startDrag(e);\n }\n }\n\n if (this._isDragging) {\n const delta = acquirePoint(\n position.x - this._startPosition.x,\n position.y - this._startPosition.y\n );\n\n this.emit('pointermove', {\n position,\n delta,\n pointerId: e.pointerId,\n originalEvent: e,\n });\n\n // Note: caller is responsible for releasing position/delta\n } else {\n pointPool.release(position);\n }\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.flush();\n\n if (this._isDragging) {\n this.emit('pointerup', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _onPointerCancel = (e: PointerEvent): void => {\n if (e.pointerId !== this._activePointerId) return;\n\n this._moveThrottle.cancel();\n\n if (this._isDragging) {\n this.emit('pointercancel', {\n position: acquirePoint(e.clientX, e.clientY),\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n this._cleanup();\n };\n\n private _startDrag(e: PointerEvent): void {\n if (this._isDragging || !this._activeElement || !this._startPosition) return;\n\n this._isDragging = true;\n\n this.emit('pointerdown', {\n element: this._activeElement,\n position: { x: this._startPosition.x, y: this._startPosition.y },\n pointerId: e.pointerId,\n originalEvent: e,\n });\n }\n\n private _findDraggable(e: PointerEvent): HTMLElement | null {\n const target = e.target as Element;\n\n // Handle shadow DOM by using composedPath\n const path = e.composedPath();\n\n for (const el of path) {\n if (!(el instanceof HTMLElement)) continue;\n\n if (el.matches(this._options.draggableSelector)) {\n return el;\n }\n\n // Stop at container boundary\n if (el === this._container || el === (this._container as ShadowRoot).host) {\n break;\n }\n }\n\n // Fallback for non-composed path\n return target.closest?.(this._options.draggableSelector) as HTMLElement | null;\n }\n\n private _findHandle(e: PointerEvent, draggable: HTMLElement): HTMLElement | null {\n if (!this._options.handleSelector) return draggable;\n\n const target = e.target as Element;\n const handle = target.closest?.(this._options.handleSelector) as HTMLElement | null;\n\n // Handle must be inside the draggable\n if (handle && draggable.contains(handle)) {\n return handle;\n }\n\n return null;\n }\n\n private _clearDelayTimer(): void {\n if (this._delayTimer !== null) {\n clearTimeout(this._delayTimer);\n this._delayTimer = null;\n }\n }\n\n private _cleanup(): void {\n this._clearDelayTimer();\n this._moveThrottle.cancel();\n\n // Release pooled objects\n if (this._startPosition) {\n pointPool.release(this._startPosition);\n this._startPosition = null;\n }\n\n // Remove move/up listeners\n const target = this._getEventTarget();\n target.removeEventListener('pointermove', this._onPointerMove);\n target.removeEventListener('pointerup', this._onPointerUp);\n target.removeEventListener('pointercancel', this._onPointerCancel);\n\n this._activePointerId = null;\n this._activeElement = null;\n this._isDragging = false;\n }\n\n /**\n * Cleanup resources\n */\n destroy(): void {\n this.detach();\n this._moveThrottle.destroy();\n super.destroy();\n }\n}\n", "/**\n * Cached bounding rect manager using WeakMap\n * Automatically cleans up when elements are removed from DOM\n */\nexport class BoundsCache {\n private _cache = new WeakMap<Element, DOMRect>();\n private _dirty = new WeakSet<Element>();\n private _invalidateAll = false;\n\n /**\n * Get cached bounds for an element, or compute and cache\n */\n get(element: Element): DOMRect {\n if (this._invalidateAll || this._dirty.has(element)) {\n return this._update(element);\n }\n\n const cached = this._cache.get(element);\n if (cached) {\n return cached;\n }\n\n return this._update(element);\n }\n\n /**\n * Mark a specific element's bounds as dirty\n */\n invalidate(element: Element): void {\n this._dirty.add(element);\n }\n\n /**\n * Mark all cached bounds as dirty (e.g., on scroll/resize)\n */\n invalidateAll(): void {\n this._invalidateAll = true;\n }\n\n /**\n * Force update bounds for an element\n */\n update(element: Element): DOMRect {\n return this._update(element);\n }\n\n /**\n * Remove element from cache\n */\n remove(element: Element): void {\n this._cache.delete(element);\n }\n\n /**\n * Clear the dirty flag after a frame\n */\n clearDirty(): void {\n this._invalidateAll = false;\n // WeakSet doesn't have clear(), but dirty elements\n // will be refreshed on next get() call\n }\n\n private _update(element: Element): DOMRect {\n const rect = element.getBoundingClientRect();\n this._cache.set(element, rect);\n this._dirty.delete(element);\n return rect;\n }\n}\n\n// Singleton instance for shared use\nexport const boundsCache = new BoundsCache();\n\n/**\n * Check if a point is inside a rect\n */\nexport function pointInRect(x: number, y: number, rect: DOMRect): boolean {\n return (\n x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom\n );\n}\n\n/**\n * Check if two rects intersect\n */\nexport function rectsIntersect(a: DOMRect, b: DOMRect): boolean {\n return !(\n a.right < b.left ||\n a.left > b.right ||\n a.bottom < b.top ||\n a.top > b.bottom\n );\n}\n\n/**\n * Get the center point of a rect\n */\nexport function rectCenter(rect: DOMRect): { x: number; y: number } {\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n}\n\n/**\n * Calculate distance between two points\n */\nexport function distance(\n x1: number,\n y1: number,\n x2: number,\n y2: number\n): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return Math.sqrt(dx * dx + dy * dy);\n}\n", "/**\n * DragEngine orchestrates the drag operation\n * Coordinates between sensors, state, and drop zones\n */\nimport type { Point, SnapOptions, Axis } from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport {\n PointerSensor,\n type PointerStartEvent,\n type PointerMoveEvent,\n type PointerEndEvent,\n} from '../sensors/PointerSensor.js';\nimport { boundsCache, pointInRect } from '../utils/BoundsCache.js';\nimport { pointPool } from '../utils/ObjectPool.js';\n\nexport interface DragEngineOptions {\n container: HTMLElement | ShadowRoot;\n state: DragState;\n options: SnapOptions;\n getDropZones: () => HTMLElement[];\n getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n getItemAxis: (element: HTMLElement) => Axis | undefined;\n}\n\nexport class DragEngine {\n private _container: HTMLElement | ShadowRoot;\n private _state: DragState;\n private _options: SnapOptions;\n private _getDropZones: () => HTMLElement[];\n private _getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;\n private _getItemAxis: (element: HTMLElement) => Axis | undefined;\n\n private _pointerSensor: PointerSensor;\n private _enabled = false;\n private _listenerUnsubscribers: (() => void)[] = [];\n\n // Ghost element for visual feedback\n private _ghost: HTMLElement | null = null;\n private _ghostOffset: Point = { x: 0, y: 0 };\n\n constructor(engineOptions: DragEngineOptions) {\n this._container = engineOptions.container;\n this._state = engineOptions.state;\n this._options = engineOptions.options;\n this._getDropZones = engineOptions.getDropZones;\n this._getItemData = engineOptions.getItemData;\n this._getItemAxis = engineOptions.getItemAxis;\n\n // Initialize pointer sensor\n this._pointerSensor = new PointerSensor({\n container: this._container,\n draggableSelector: this._options.draggableSelector ?? '[data-draggable]',\n handleSelector: this._options.handleSelector,\n delay: this._options.delay,\n distance: this._options.distance,\n });\n\n this._setupListeners();\n }\n\n /**\n * Enable drag engine\n */\n enable(): void {\n if (this._enabled) return;\n this._pointerSensor.attach();\n this._enabled = true;\n }\n\n /**\n * Disable drag engine\n */\n disable(): void {\n if (!this._enabled) return;\n this._pointerSensor.detach();\n this._state.reset();\n this._removeGhost();\n this._enabled = false;\n }\n\n /**\n * Check if enabled\n */\n get isEnabled(): boolean {\n return this._enabled;\n }\n\n /**\n * Update options\n */\n updateOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n }\n\n private _setupListeners(): void {\n this._listenerUnsubscribers.push(\n this._pointerSensor.on('pointerdown', this._onPointerDown),\n this._pointerSensor.on('pointermove', this._onPointerMove),\n this._pointerSensor.on('pointerup', this._onPointerUp),\n this._pointerSensor.on('pointercancel', this._onPointerCancel)\n );\n }\n\n private _onPointerDown = (event: PointerStartEvent): void => {\n const { element, position } = event;\n\n // Get item data from data attributes or imperative registration\n const data = this._getItemData(element) ?? this._extractDataAttributes(element);\n\n // Start drag session\n const session = this._state.startDrag(element, position, data);\n\n // Call user callback\n const startEvent = {\n element,\n position: { x: position.x, y: position.y },\n data: session.data,\n cancel: () => {\n this._state.cancelDrag();\n },\n };\n\n const result = this._options.onDragStart?.(startEvent);\n if (result === false) {\n this._state.cancelDrag();\n return;\n }\n\n // Create ghost element\n this._createGhost(element, position);\n\n // Add dragging class\n element.classList.add('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.add(this._options.ghostClass);\n }\n\n // Invalidate bounds cache (positions may change)\n boundsCache.invalidateAll();\n };\n\n private _onPointerMove = (event: PointerMoveEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n let { position } = event;\n\n // Apply axis constraints\n const axis = this._getItemAxis(session.element) ?? this._options.axis ?? 'both';\n if (axis !== 'both') {\n position = this._applyAxisConstraint(position, session.origin, axis);\n }\n\n // Apply grid snapping\n if (this._options.grid) {\n position = this._applyGridSnap(position, this._options.grid);\n }\n\n // Update state\n this._state.updatePosition(position);\n\n // Update ghost position\n this._updateGhost(position);\n\n // Hit test drop zones\n this._updateDropZone(position);\n\n // Call user callback\n this._options.onDragMove?.({\n element: session.element,\n position: { x: session.current.x, y: session.current.y },\n delta: { x: session.delta.x, y: session.delta.y },\n dropZone: session.dropZone,\n });\n };\n\n private _onPointerUp = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n // End drag and get final session\n const finalSession = this._state.endDrag();\n if (!finalSession) return;\n\n // Remove visual feedback\n this._cleanup(finalSession.element);\n\n // Call drop callback if over valid zone\n if (finalSession.dropZone) {\n this._options.onDrop?.({\n element: finalSession.element,\n dropZone: finalSession.dropZone,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n data: finalSession.data,\n });\n }\n\n // Call end callback\n this._options.onDragEnd?.({\n element: finalSession.element,\n position: { x: finalSession.current.x, y: finalSession.current.y },\n delta: { x: finalSession.delta.x, y: finalSession.delta.y },\n cancelled: false,\n });\n };\n\n private _onPointerCancel = (event: PointerEndEvent): void => {\n const session = this._state.session;\n if (!session) return;\n\n const element = session.element;\n this._state.cancelDrag();\n this._cleanup(element);\n\n this._options.onDragEnd?.({\n element,\n position: event.position,\n delta: { x: 0, y: 0 },\n cancelled: true,\n });\n };\n\n private _applyAxisConstraint(position: Point, origin: Point, axis: Axis): Point {\n if (axis === 'x') {\n return { x: position.x, y: origin.y };\n }\n if (axis === 'y') {\n return { x: origin.x, y: position.y };\n }\n return position;\n }\n\n private _applyGridSnap(position: Point, grid: { x: number; y: number }): Point {\n return {\n x: Math.round(position.x / grid.x) * grid.x,\n y: Math.round(position.y / grid.y) * grid.y,\n };\n }\n\n private _updateDropZone(position: Point): void {\n const dropZones = this._getDropZones();\n let foundZone: HTMLElement | null = null;\n\n for (const zone of dropZones) {\n const rect = boundsCache.get(zone);\n if (pointInRect(position.x, position.y, rect)) {\n foundZone = zone;\n break;\n }\n }\n\n const session = this._state.session;\n if (!session) return;\n\n // Handle zone change\n if (foundZone !== session.dropZone) {\n if (session.dropZone) {\n this._options.onDropZoneLeave?.({\n element: session.element,\n dropZone: session.dropZone,\n });\n }\n\n this._state.setDropTarget(foundZone);\n\n if (foundZone) {\n this._options.onDropZoneEnter?.({\n element: session.element,\n dropZone: foundZone,\n position,\n });\n }\n }\n }\n\n private _createGhost(element: HTMLElement, position: Point): void {\n const rect = element.getBoundingClientRect();\n\n // Calculate offset from cursor to element origin\n this._ghostOffset = {\n x: position.x - rect.left,\n y: position.y - rect.top,\n };\n\n // Clone element for ghost\n this._ghost = element.cloneNode(true) as HTMLElement;\n this._ghost.style.cssText = `\n position: fixed;\n left: ${rect.left}px;\n top: ${rect.top}px;\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n pointer-events: none;\n z-index: 9999;\n opacity: 0.8;\n will-change: transform;\n `;\n this._ghost.classList.add('snap-ghost');\n\n // Append to body (not container, to avoid transform issues)\n document.body.appendChild(this._ghost);\n }\n\n private _updateGhost(position: Point): void {\n if (!this._ghost) return;\n\n const x = position.x - this._ghostOffset.x;\n const y = position.y - this._ghostOffset.y;\n\n // Use transform for better performance\n this._ghost.style.transform = `translate(${x - parseFloat(this._ghost.style.left)}px, ${y - parseFloat(this._ghost.style.top)}px)`;\n }\n\n private _removeGhost(): void {\n if (this._ghost) {\n this._ghost.remove();\n this._ghost = null;\n }\n }\n\n private _cleanup(element: HTMLElement): void {\n element.classList.remove('snap-dragging');\n if (this._options.ghostClass) {\n element.classList.remove(this._options.ghostClass);\n }\n this._removeGhost();\n }\n\n private _extractDataAttributes(element: HTMLElement): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n\n // Extract data-drag-* attributes\n for (const attr of element.attributes) {\n if (attr.name.startsWith('data-drag-')) {\n const key = attr.name.slice(10); // Remove 'data-drag-'\n data[key] = attr.value;\n }\n }\n\n // Also include data-draggable value if present\n const draggableValue = element.dataset.draggable;\n if (draggableValue && draggableValue !== '') {\n data.type = draggableValue;\n }\n\n return data;\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.disable();\n\n // Unsubscribe from pointer sensor events\n for (const unsub of this._listenerUnsubscribers) {\n unsub();\n }\n this._listenerUnsubscribers = [];\n\n this._pointerSensor.destroy();\n }\n}\n", "/**\n * DropZone manages individual drop target areas\n * Handles hit testing and insertion index calculation\n */\nimport type { DataTransfer, DropZoneOptions, Point } from '../types/index.js';\nimport { boundsCache, pointInRect, rectCenter } from '../utils/BoundsCache.js';\n\nexport class DropZone {\n private _element: HTMLElement;\n private _options: DropZoneOptions;\n private _isActive = false;\n\n constructor(element: HTMLElement, options: DropZoneOptions = {}) {\n this._element = element;\n this._options = options;\n }\n\n /**\n * The DOM element for this drop zone\n */\n get element(): HTMLElement {\n return this._element;\n }\n\n /**\n * Whether this zone is currently active (being hovered)\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<DropZoneOptions>): void {\n Object.assign(this._options, options);\n }\n\n /**\n * Check if a point is inside this drop zone\n */\n containsPoint(x: number, y: number): boolean {\n const rect = boundsCache.get(this._element);\n return pointInRect(x, y, rect);\n }\n\n /**\n * Check if this zone accepts the given data\n */\n accepts(data: DataTransfer): boolean {\n const { accepts } = this._options;\n\n if (!accepts) return true;\n\n if (typeof accepts === 'function') {\n return accepts(data);\n }\n\n // Array of type strings\n for (const type of accepts) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n\n // Check data-accepts attribute on element\n const elementAccepts = this._element.dataset.accepts;\n if (elementAccepts) {\n const acceptedTypes = elementAccepts.split(',').map((s) => s.trim());\n for (const type of acceptedTypes) {\n if (data.hasType(type) || data.getData('type') === type) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Set active state and add/remove CSS class\n */\n setActive(active: boolean): void {\n if (this._isActive === active) return;\n\n this._isActive = active;\n\n if (active) {\n this._element.classList.add('snap-drop-active');\n } else {\n this._element.classList.remove('snap-drop-active');\n }\n }\n\n /**\n * Calculate insertion index for sortable behavior\n * Returns the index where an item should be inserted based on position\n */\n getInsertionIndex(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): number {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return 0;\n\n // Determine if list is vertical or horizontal\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) return i;\n } else {\n if (x < center.x) return i;\n }\n }\n\n return items.length;\n }\n\n /**\n * Get closest item to a point (for visual feedback)\n */\n getClosestItem(\n x: number,\n y: number,\n itemSelector: string,\n excludeElement?: HTMLElement\n ): { element: HTMLElement; position: 'before' | 'after' } | null {\n const items = Array.from(\n this._element.querySelectorAll<HTMLElement>(itemSelector)\n ).filter((el) => el !== excludeElement);\n\n if (items.length === 0) return null;\n\n let closestItem: HTMLElement | null = null;\n let closestDistance = Infinity;\n let position: 'before' | 'after' = 'after';\n\n // Determine orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical = Math.abs(lastRect.top - firstRect.top) > Math.abs(lastRect.left - firstRect.left);\n\n for (const item of items) {\n const rect = boundsCache.get(item);\n const center = rectCenter(rect);\n\n const dx = x - center.x;\n const dy = y - center.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < closestDistance) {\n closestDistance = distance;\n closestItem = item;\n position = isVertical ? (y < center.y ? 'before' : 'after') : (x < center.x ? 'before' : 'after');\n }\n }\n\n if (!closestItem) return null;\n\n return { element: closestItem, position };\n }\n\n /**\n * Force update cached bounds\n */\n updateBounds(): void {\n boundsCache.update(this._element);\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.setActive(false);\n boundsCache.remove(this._element);\n }\n}\n\n/**\n * DropZoneManager handles multiple drop zones\n */\nexport class DropZoneManager {\n private _zones = new Map<HTMLElement, DropZone>();\n\n /**\n * Register a drop zone\n */\n register(element: HTMLElement, options?: DropZoneOptions): DropZone {\n let zone = this._zones.get(element);\n if (zone) {\n if (options) zone.setOptions(options);\n return zone;\n }\n\n zone = new DropZone(element, options);\n this._zones.set(element, zone);\n return zone;\n }\n\n /**\n * Unregister a drop zone\n */\n unregister(element: HTMLElement): void {\n const zone = this._zones.get(element);\n if (zone) {\n zone.destroy();\n this._zones.delete(element);\n }\n }\n\n /**\n * Get drop zone for an element\n */\n get(element: HTMLElement): DropZone | undefined {\n return this._zones.get(element);\n }\n\n /**\n * Get all drop zone elements\n */\n getElements(): HTMLElement[] {\n return [...this._zones.keys()];\n }\n\n /**\n * Get all drop zones\n */\n getAll(): DropZone[] {\n return [...this._zones.values()];\n }\n\n /**\n * Find drop zone at point\n */\n findAtPoint(x: number, y: number): DropZone | null {\n for (const zone of this._zones.values()) {\n if (zone.containsPoint(x, y)) {\n return zone;\n }\n }\n return null;\n }\n\n /**\n * Clear all drop zones\n */\n clear(): void {\n for (const zone of this._zones.values()) {\n zone.destroy();\n }\n this._zones.clear();\n }\n\n /**\n * Update all bounds (e.g., after scroll/resize)\n */\n updateAllBounds(): void {\n boundsCache.invalidateAll();\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.clear();\n }\n}\n", "/**\n * Snap - Main entry point for the drag and drop library\n * Coordinates all subsystems and provides the public API\n */\nimport type {\n SnapOptions,\n SnapInstance,\n ItemOptions,\n DropZoneOptions,\n Axis,\n Plugin,\n Behavior,\n} from '../types/index.js';\nimport { DragState } from './DragState.js';\nimport { DragEngine } from './DragEngine.js';\nimport { DropZoneManager } from './DropZone.js';\nimport { boundsCache } from '../utils/BoundsCache.js';\n\n// Default options\nconst defaultOptions: SnapOptions = {\n draggableSelector: '[data-draggable]',\n dropZoneSelector: '[data-droppable]',\n axis: 'both',\n autoRefresh: false,\n};\n\nexport class Snap implements SnapInstance {\n private _container: HTMLElement | ShadowRoot;\n private _options: SnapOptions;\n private _state: DragState;\n private _engine: DragEngine;\n private _dropZoneManager: DropZoneManager;\n\n // Imperative registrations\n private _imperativeDraggables = new Map<HTMLElement, ItemOptions>();\n private _imperativeDropZones = new Map<HTMLElement, DropZoneOptions>();\n\n // Plugins and behaviors\n private _plugins: Plugin[] = [];\n private _behaviors: Behavior[] = [];\n\n // State listener unsubscribers\n private _stateUnsubscribers: (() => void)[] = [];\n\n // MutationObserver for auto-refresh\n private _observer: MutationObserver | null = null;\n private _refreshScheduled = false;\n private _destroyed = false;\n\n // Scroll/resize handlers\n private _scrollHandler: (() => void) | null = null;\n private _resizeHandler: (() => void) | null = null;\n\n constructor(\n container: HTMLElement | ShadowRoot,\n options: SnapOptions = {}\n ) {\n this._container = container;\n this._options = { ...defaultOptions, ...options };\n\n // Initialize subsystems\n this._state = new DragState();\n this._dropZoneManager = new DropZoneManager();\n\n this._engine = new DragEngine({\n container: this._container,\n state: this._state,\n options: this._options,\n getDropZones: () => this._getDropZones(),\n getItemData: (el) => this._getItemData(el),\n getItemAxis: (el) => this._getItemAxis(el),\n });\n\n // Setup state listeners for behaviors\n this._setupStateListeners();\n\n // Initial scan for declarative elements\n this._scanDeclarativeElements();\n\n // Setup auto-refresh if enabled\n if (this._options.autoRefresh) {\n this._setupAutoRefresh();\n }\n\n // Setup scroll/resize handlers\n this._setupScrollResize();\n\n // Enable by default\n this.enable();\n }\n\n /**\n * Current options\n */\n get options(): SnapOptions {\n return this._options;\n }\n\n /**\n * Enable drag and drop\n */\n enable(): void {\n this._engine.enable();\n }\n\n /**\n * Disable drag and drop\n */\n disable(): void {\n this._engine.disable();\n }\n\n /**\n * Cleanup and destroy instance\n */\n destroy(): void {\n this._destroyed = true;\n this.disable();\n\n // Unsubscribe from state listeners\n for (const unsub of this._stateUnsubscribers) {\n unsub();\n }\n this._stateUnsubscribers = [];\n\n // Destroy plugins\n for (const plugin of this._plugins) {\n plugin.destroy();\n }\n this._plugins = [];\n\n // Destroy behaviors\n for (const behavior of this._behaviors) {\n behavior.destroy();\n }\n this._behaviors = [];\n\n // Cleanup subsystems\n this._engine.destroy();\n this._state.destroy();\n this._dropZoneManager.destroy();\n\n // Cleanup observers\n this._observer?.disconnect();\n this._observer = null;\n\n // Cleanup event handlers\n if (this._scrollHandler) {\n window.removeEventListener('scroll', this._scrollHandler, true);\n this._scrollHandler = null;\n }\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n this._resizeHandler = null;\n }\n\n // Clear registrations\n this._imperativeDraggables.clear();\n this._imperativeDropZones.clear();\n }\n\n /**\n * Re-scan for declarative elements (call after DOM changes)\n */\n refresh(): void {\n this._scanDeclarativeElements();\n boundsCache.invalidateAll();\n }\n\n /**\n * Register a draggable element imperatively\n */\n addDraggable(element: HTMLElement, options?: ItemOptions): void {\n this._imperativeDraggables.set(element, options ?? {});\n }\n\n /**\n * Unregister a draggable element\n */\n removeDraggable(element: HTMLElement): void {\n this._imperativeDraggables.delete(element);\n }\n\n /**\n * Register a drop zone imperatively\n */\n addDropZone(element: HTMLElement, options?: DropZoneOptions): void {\n this._imperativeDropZones.set(element, options ?? {});\n this._dropZoneManager.register(element, options);\n }\n\n /**\n * Unregister a drop zone\n */\n removeDropZone(element: HTMLElement): void {\n this._imperativeDropZones.delete(element);\n this._dropZoneManager.unregister(element);\n }\n\n /**\n * Check if currently dragging\n */\n isDragging(): boolean {\n return this._state.isDragging();\n }\n\n /**\n * Get the element currently being dragged\n */\n getActiveElement(): HTMLElement | null {\n return this._state.getActiveElement();\n }\n\n /**\n * Register a plugin\n */\n use(plugin: Plugin): this {\n this._plugins.push(plugin);\n plugin.init(this);\n return this;\n }\n\n /**\n * Add a behavior\n */\n addBehavior(behavior: Behavior): this {\n this._behaviors.push(behavior);\n return this;\n }\n\n /**\n * Update options dynamically\n */\n setOptions(options: Partial<SnapOptions>): void {\n Object.assign(this._options, options);\n this._engine.updateOptions(this._options);\n }\n\n // Internal methods\n\n private _getDropZones(): HTMLElement[] {\n // Combine declarative and imperative drop zones\n const selector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n const declarative = Array.from(\n containerEl.querySelectorAll<HTMLElement>(selector)\n );\n\n const imperative = [...this._imperativeDropZones.keys()];\n\n // Unique elements\n return [...new Set([...declarative, ...imperative])];\n }\n\n private _getItemData(element: HTMLElement): Record<string, unknown> | undefined {\n return this._imperativeDraggables.get(element)?.data;\n }\n\n private _getItemAxis(element: HTMLElement): Axis | undefined {\n // Check imperative first\n const imperative = this._imperativeDraggables.get(element);\n if (imperative?.axis) return imperative.axis;\n\n // Check data attribute\n const axis = element.dataset.dragAxis as Axis | undefined;\n if (axis === 'x' || axis === 'y' || axis === 'both') {\n return axis;\n }\n\n return undefined;\n }\n\n private _scanDeclarativeElements(): void {\n const dropZoneSelector = this._options.dropZoneSelector ?? '[data-droppable]';\n const containerEl = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n // Register declarative drop zones\n const dropZones = containerEl.querySelectorAll<HTMLElement>(dropZoneSelector);\n for (const zone of dropZones) {\n if (!this._imperativeDropZones.has(zone)) {\n this._dropZoneManager.register(zone);\n }\n }\n }\n\n private _setupStateListeners(): void {\n // Forward state events to behaviors, store unsubscribers for cleanup\n this._stateUnsubscribers.push(\n this._state.subscribe('dragstart', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragStart?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragmove', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragMove?.(session);\n }\n })\n );\n\n this._stateUnsubscribers.push(\n this._state.subscribe('dragend', (session) => {\n for (const behavior of this._behaviors) {\n behavior.onDragEnd?.(session);\n }\n })\n );\n }\n\n private _setupAutoRefresh(): void {\n this._observer = new MutationObserver((mutations) => {\n // Guard against destroyed instance\n if (this._destroyed) return;\n\n let needsRefresh = false;\n\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n needsRefresh = true;\n break;\n }\n }\n\n if (needsRefresh && !this._refreshScheduled) {\n this._refreshScheduled = true;\n // Debounce refresh\n requestAnimationFrame(() => {\n // Guard against destroyed instance in RAF callback\n if (this._destroyed) return;\n this._refreshScheduled = false;\n this.refresh();\n });\n }\n });\n\n const target = this._container instanceof ShadowRoot\n ? this._container\n : this._container;\n\n this._observer.observe(target, {\n childList: true,\n subtree: true,\n });\n }\n\n private _setupScrollResize(): void {\n // Invalidate bounds cache on scroll (capture phase for nested scrollers)\n this._scrollHandler = () => {\n if (this._state.isDragging()) {\n boundsCache.invalidateAll();\n }\n };\n window.addEventListener('scroll', this._scrollHandler, true);\n\n // Invalidate on resize\n this._resizeHandler = () => {\n boundsCache.invalidateAll();\n };\n window.addEventListener('resize', this._resizeHandler);\n }\n}\n\n// Export as default and named\nexport default Snap;\n", "/**\n * Sortable plugin - enables reordering items within a container\n */\nimport type {\n Plugin,\n SnapInstance,\n SortableOptions,\n DragSession,\n} from '../types/index.js';\nimport { boundsCache, rectCenter } from '../utils/BoundsCache.js';\n\nconst defaultOptions: SortableOptions = {\n animation: 150,\n ghostClass: 'snap-sortable-ghost',\n placeholderClass: 'snap-sortable-placeholder',\n};\n\nexport class Sortable implements Plugin {\n name = 'sortable';\n\n private _snap: SnapInstance | null = null;\n private _options: SortableOptions;\n private _placeholder: HTMLElement | null = null;\n private _originalIndex: number = -1;\n private _currentIndex: number = -1;\n private _container: HTMLElement | null = null;\n private _items: HTMLElement[] = [];\n private _unsubscribers: (() => void)[] = [];\n\n constructor(options: SortableOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Subscribe to state events via the snap options callbacks\n // We wrap them to add sortable behavior\n const originalOnDragStart = snap.options.onDragStart;\n const originalOnDragMove = snap.options.onDragMove;\n const originalOnDrop = snap.options.onDrop;\n const originalOnDragEnd = snap.options.onDragEnd;\n\n snap.setOptions({\n onDragStart: (e) => {\n this._onDragStart(e.element);\n return originalOnDragStart?.(e);\n },\n onDragMove: (e) => {\n this._onDragMove(e.position.x, e.position.y);\n originalOnDragMove?.(e);\n },\n onDrop: (e) => {\n // Add insertion index to event\n const enhancedEvent = {\n ...e,\n insertionIndex: this._currentIndex,\n sourceContainer: this._container ?? undefined,\n };\n originalOnDrop?.(enhancedEvent);\n },\n onDragEnd: (e) => {\n this._onDragEnd();\n originalOnDragEnd?.(e);\n },\n });\n }\n\n destroy(): void {\n this._cleanup();\n for (const unsub of this._unsubscribers) {\n unsub();\n }\n this._unsubscribers = [];\n this._snap = null;\n }\n\n private _onDragStart(element: HTMLElement): void {\n // Find container and items\n this._container = element.parentElement;\n if (!this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n this._items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n );\n\n this._originalIndex = this._items.indexOf(element);\n this._currentIndex = this._originalIndex;\n\n if (this._originalIndex === -1) return;\n\n // Create placeholder\n this._createPlaceholder(element);\n\n // Add ghost class\n if (this._options.ghostClass) {\n element.classList.add(this._options.ghostClass);\n }\n }\n\n private _onDragMove(x: number, y: number): void {\n if (!this._placeholder || !this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n // Get current items (excluding the dragged element)\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n if (items.length === 0) {\n this._currentIndex = 0;\n return;\n }\n\n // Determine list orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical =\n Math.abs(lastRect.top - firstRect.top) >\n Math.abs(lastRect.left - firstRect.left);\n\n // Find new index\n let newIndex = items.length;\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) {\n newIndex = i;\n break;\n }\n } else {\n if (x < center.x) {\n newIndex = i;\n break;\n }\n }\n }\n\n // Adjust for original position\n if (newIndex > this._originalIndex) {\n newIndex++;\n }\n\n if (newIndex !== this._currentIndex) {\n this._currentIndex = newIndex;\n this._movePlaceholder(newIndex);\n }\n }\n\n private _onDragEnd(): void {\n this._cleanup();\n }\n\n private _createPlaceholder(element: HTMLElement): void {\n const rect = element.getBoundingClientRect();\n\n this._placeholder = document.createElement('div');\n this._placeholder.className = this._options.placeholderClass ?? '';\n this._placeholder.style.cssText = `\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n box-sizing: border-box;\n `;\n\n // Insert placeholder at original position\n element.parentNode?.insertBefore(this._placeholder, element);\n }\n\n private _movePlaceholder(index: number): void {\n if (!this._placeholder || !this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement);\n\n // Remove placeholder from current position\n this._placeholder.remove();\n\n // Insert at new position\n if (index >= items.length) {\n this._container.appendChild(this._placeholder);\n } else {\n // Find the item to insert before\n let insertBefore = items[index];\n if (insertBefore === this._placeholder) {\n insertBefore = items[index + 1];\n }\n if (insertBefore) {\n this._container.insertBefore(this._placeholder, insertBefore);\n } else {\n this._container.appendChild(this._placeholder);\n }\n }\n\n // Animate other items if animation enabled\n if (this._options.animation && this._options.animation > 0) {\n this._animateItems();\n }\n }\n\n private _animateItems(): void {\n if (!this._container) return;\n\n const selector = this._snap?.options.draggableSelector ?? '[data-draggable]';\n const activeElement = this._snap?.getActiveElement();\n\n const items = Array.from(\n this._container.querySelectorAll<HTMLElement>(selector)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Get positions before\n const positions = new Map<HTMLElement, DOMRect>();\n for (const item of items) {\n positions.set(item, item.getBoundingClientRect());\n }\n\n // Force reflow\n void this._container.offsetHeight;\n\n // Animate from old to new positions\n for (const item of items) {\n const oldRect = positions.get(item);\n const newRect = item.getBoundingClientRect();\n\n if (!oldRect) continue;\n\n const dx = oldRect.left - newRect.left;\n const dy = oldRect.top - newRect.top;\n\n if (dx !== 0 || dy !== 0) {\n item.style.transform = `translate(${dx}px, ${dy}px)`;\n item.style.transition = 'none';\n\n requestAnimationFrame(() => {\n item.style.transition = `transform ${this._options.animation}ms ease`;\n item.style.transform = '';\n });\n }\n }\n }\n\n private _cleanup(): void {\n // Remove placeholder\n this._placeholder?.remove();\n this._placeholder = null;\n\n // Remove ghost class from dragged element\n const activeElement = this._snap?.getActiveElement();\n if (activeElement && this._options.ghostClass) {\n activeElement.classList.remove(this._options.ghostClass);\n }\n\n // Reset state\n this._container = null;\n this._items = [];\n this._originalIndex = -1;\n this._currentIndex = -1;\n\n // Invalidate bounds cache\n boundsCache.invalidateAll();\n }\n\n /**\n * Get the current insertion index during drag\n */\n getCurrentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Get the original index of the dragged item\n */\n getOriginalIndex(): number {\n return this._originalIndex;\n }\n}\n", "/**\n * Kanban plugin - enables moving items between multiple containers\n */\nimport type {\n Plugin,\n SnapInstance,\n KanbanOptions,\n Point,\n} from '../types/index.js';\nimport { boundsCache, pointInRect, rectCenter } from '../utils/BoundsCache.js';\n\nconst defaultOptions: Required<KanbanOptions> = {\n containers: '[data-droppable]',\n items: '[data-draggable]',\n animation: 150,\n};\n\nexport class Kanban implements Plugin {\n name = 'kanban';\n\n private _snap: SnapInstance | null = null;\n private _options: Required<KanbanOptions>;\n private _sourceContainer: HTMLElement | null = null;\n private _targetContainer: HTMLElement | null = null;\n private _placeholder: HTMLElement | null = null;\n private _originalIndex: number = -1;\n private _currentIndex: number = -1;\n\n constructor(options: KanbanOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Wrap snap callbacks\n const originalOnDragStart = snap.options.onDragStart;\n const originalOnDragMove = snap.options.onDragMove;\n const originalOnDropZoneEnter = snap.options.onDropZoneEnter;\n const originalOnDropZoneLeave = snap.options.onDropZoneLeave;\n const originalOnDrop = snap.options.onDrop;\n const originalOnDragEnd = snap.options.onDragEnd;\n\n snap.setOptions({\n onDragStart: (e) => {\n this._onDragStart(e.element);\n return originalOnDragStart?.(e);\n },\n onDragMove: (e) => {\n this._onDragMove(e.position);\n originalOnDragMove?.(e);\n },\n onDropZoneEnter: (e) => {\n this._onDropZoneEnter(e.dropZone);\n originalOnDropZoneEnter?.(e);\n },\n onDropZoneLeave: (e) => {\n this._onDropZoneLeave(e.dropZone);\n originalOnDropZoneLeave?.(e);\n },\n onDrop: (e) => {\n const enhancedEvent = {\n ...e,\n insertionIndex: this._currentIndex,\n sourceContainer: this._sourceContainer ?? undefined,\n };\n originalOnDrop?.(enhancedEvent);\n },\n onDragEnd: (e) => {\n this._onDragEnd();\n originalOnDragEnd?.(e);\n },\n });\n }\n\n destroy(): void {\n this._cleanup();\n this._snap = null;\n }\n\n private _onDragStart(element: HTMLElement): void {\n // Find source container\n this._sourceContainer = element.closest(this._options.containers);\n if (!this._sourceContainer) return;\n\n // Get original index within source container\n const items = Array.from(\n this._sourceContainer.querySelectorAll<HTMLElement>(this._options.items)\n );\n this._originalIndex = items.indexOf(element);\n\n // Create placeholder\n this._createPlaceholder(element);\n }\n\n private _onDragMove(position: Point): void {\n if (!this._targetContainer || !this._placeholder) return;\n\n // Calculate insertion index in target container\n const newIndex = this._calculateInsertionIndex(\n this._targetContainer,\n position.x,\n position.y\n );\n\n if (newIndex !== this._currentIndex) {\n this._currentIndex = newIndex;\n this._movePlaceholder(newIndex);\n }\n }\n\n private _onDropZoneEnter(dropZone: HTMLElement): void {\n // Check if it's a valid container\n if (!dropZone.matches(this._options.containers)) return;\n\n this._targetContainer = dropZone;\n this._targetContainer.classList.add('snap-kanban-target');\n\n // Insert placeholder into new container\n if (this._placeholder) {\n this._targetContainer.appendChild(this._placeholder);\n this._currentIndex = this._getItemCount(this._targetContainer);\n }\n }\n\n private _onDropZoneLeave(dropZone: HTMLElement): void {\n if (dropZone !== this._targetContainer) return;\n\n dropZone.classList.remove('snap-kanban-target');\n\n // Remove placeholder from old container\n this._placeholder?.remove();\n\n this._targetContainer = null;\n this._currentIndex = -1;\n }\n\n private _onDragEnd(): void {\n this._cleanup();\n }\n\n private _createPlaceholder(element: HTMLElement): void {\n const rect = element.getBoundingClientRect();\n\n this._placeholder = document.createElement('div');\n this._placeholder.className = 'snap-kanban-placeholder';\n this._placeholder.style.cssText = `\n width: ${rect.width}px;\n height: ${rect.height}px;\n margin: 0;\n box-sizing: border-box;\n opacity: 0.5;\n border: 2px dashed #ccc;\n border-radius: 4px;\n background: rgba(0, 0, 0, 0.05);\n `;\n\n // Insert in source container initially\n element.parentNode?.insertBefore(this._placeholder, element);\n }\n\n private _movePlaceholder(index: number): void {\n if (!this._placeholder || !this._targetContainer) return;\n\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n this._targetContainer.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Remove from current position\n this._placeholder.remove();\n\n // Insert at new position\n if (index >= items.length) {\n this._targetContainer.appendChild(this._placeholder);\n } else {\n const insertBefore = items[index];\n if (insertBefore) {\n this._targetContainer.insertBefore(this._placeholder, insertBefore);\n } else {\n this._targetContainer.appendChild(this._placeholder);\n }\n }\n\n // Animate if enabled\n if (this._options.animation > 0) {\n this._animateItems(this._targetContainer);\n }\n }\n\n private _calculateInsertionIndex(\n container: HTMLElement,\n x: number,\n y: number\n ): number {\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n if (items.length === 0) return 0;\n\n // Determine orientation\n const firstRect = boundsCache.get(items[0]);\n const lastRect = boundsCache.get(items[items.length - 1]);\n const isVertical =\n Math.abs(lastRect.top - firstRect.top) >\n Math.abs(lastRect.left - firstRect.left);\n\n // Find insertion point\n for (let i = 0; i < items.length; i++) {\n const rect = boundsCache.get(items[i]);\n const center = rectCenter(rect);\n\n if (isVertical) {\n if (y < center.y) return i;\n } else {\n if (x < center.x) return i;\n }\n }\n\n return items.length;\n }\n\n private _getItemCount(container: HTMLElement): number {\n const activeElement = this._snap?.getActiveElement();\n return Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder).length;\n }\n\n private _animateItems(container: HTMLElement): void {\n const activeElement = this._snap?.getActiveElement();\n const items = Array.from(\n container.querySelectorAll<HTMLElement>(this._options.items)\n ).filter((el) => el !== activeElement && el !== this._placeholder);\n\n // Store old positions\n const positions = new Map<HTMLElement, DOMRect>();\n for (const item of items) {\n positions.set(item, item.getBoundingClientRect());\n }\n\n // Force reflow\n void container.offsetHeight;\n\n // Animate\n for (const item of items) {\n const oldRect = positions.get(item);\n const newRect = item.getBoundingClientRect();\n\n if (!oldRect) continue;\n\n const dx = oldRect.left - newRect.left;\n const dy = oldRect.top - newRect.top;\n\n if (dx !== 0 || dy !== 0) {\n item.style.transform = `translate(${dx}px, ${dy}px)`;\n item.style.transition = 'none';\n\n requestAnimationFrame(() => {\n item.style.transition = `transform ${this._options.animation}ms ease`;\n item.style.transform = '';\n });\n }\n }\n }\n\n private _cleanup(): void {\n // Remove placeholder\n this._placeholder?.remove();\n this._placeholder = null;\n\n // Remove classes\n this._sourceContainer?.classList.remove('snap-kanban-source');\n this._targetContainer?.classList.remove('snap-kanban-target');\n\n // Reset state\n this._sourceContainer = null;\n this._targetContainer = null;\n this._originalIndex = -1;\n this._currentIndex = -1;\n\n boundsCache.invalidateAll();\n }\n\n /**\n * Get source container during drag\n */\n getSourceContainer(): HTMLElement | null {\n return this._sourceContainer;\n }\n\n /**\n * Get target container during drag\n */\n getTargetContainer(): HTMLElement | null {\n return this._targetContainer;\n }\n\n /**\n * Get current insertion index\n */\n getCurrentIndex(): number {\n return this._currentIndex;\n }\n}\n", "/**\n * File drop sensor for handling external file drags\n * Uses native HTML5 drag and drop API since pointer events\n * don't work for external drags\n */\nimport type { Point, Sensor } from '../types/index.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\n\nexport interface FileSensorEvents {\n dragenter: FileDragEvent;\n dragover: FileDragEvent;\n dragleave: FileDragEvent;\n drop: FileDropEvent;\n}\n\nexport interface FileDragEvent {\n position: Point;\n dropZone: HTMLElement;\n originalEvent: DragEvent;\n}\n\nexport interface FileDropEvent {\n files: File[];\n position: Point;\n dropZone: HTMLElement;\n originalEvent: DragEvent;\n}\n\nexport interface FileSensorOptions {\n container: HTMLElement | ShadowRoot;\n dropZoneSelector: string;\n accept?: string[];\n multiple?: boolean;\n maxSize?: number;\n}\n\nexport class FileSensor\n extends EventEmitter<FileSensorEvents>\n implements Sensor\n{\n private _container: HTMLElement | ShadowRoot;\n private _options: FileSensorOptions;\n private _attached = false;\n private _dragCount = 0;\n private _currentDropZone: HTMLElement | null = null;\n\n constructor(options: FileSensorOptions) {\n super();\n this._container = options.container;\n this._options = options;\n }\n\n attach(): void {\n if (this._attached) return;\n\n const target = this._getEventTarget();\n target.addEventListener('dragenter', this._onDragEnter, { passive: false });\n target.addEventListener('dragover', this._onDragOver, { passive: false });\n target.addEventListener('dragleave', this._onDragLeave, { passive: false });\n target.addEventListener('drop', this._onDrop, { passive: false });\n\n this._attached = true;\n }\n\n detach(): void {\n if (!this._attached) return;\n\n const target = this._getEventTarget();\n target.removeEventListener('dragenter', this._onDragEnter);\n target.removeEventListener('dragover', this._onDragOver);\n target.removeEventListener('dragleave', this._onDragLeave);\n target.removeEventListener('drop', this._onDrop);\n\n this._dragCount = 0;\n this._currentDropZone = null;\n this._attached = false;\n }\n\n private _getEventTarget(): HTMLElement | Document {\n if (this._container instanceof ShadowRoot) {\n return this._container.host as HTMLElement;\n }\n return this._container;\n }\n\n private _onDragEnter = (e: DragEvent): void => {\n // Only handle file drags\n if (!this._hasFiles(e)) return;\n\n this._dragCount++;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n e.preventDefault();\n\n if (dropZone !== this._currentDropZone) {\n if (this._currentDropZone) {\n this.emit('dragleave', {\n position: { x: e.clientX, y: e.clientY },\n dropZone: this._currentDropZone,\n originalEvent: e,\n });\n }\n\n this._currentDropZone = dropZone;\n this.emit('dragenter', {\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n }\n };\n\n private _onDragOver = (e: DragEvent): void => {\n if (!this._hasFiles(e)) return;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n // Must prevent default to allow drop\n e.preventDefault();\n\n // Set drop effect\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'copy';\n }\n\n this.emit('dragover', {\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n };\n\n private _onDragLeave = (e: DragEvent): void => {\n if (!this._hasFiles(e)) return;\n\n this._dragCount--;\n\n // Only emit leave when truly leaving the container\n if (this._dragCount === 0 && this._currentDropZone) {\n this.emit('dragleave', {\n position: { x: e.clientX, y: e.clientY },\n dropZone: this._currentDropZone,\n originalEvent: e,\n });\n this._currentDropZone = null;\n }\n };\n\n private _onDrop = (e: DragEvent): void => {\n e.preventDefault();\n this._dragCount = 0;\n\n const dropZone = this._findDropZone(e);\n if (!dropZone) return;\n\n const files = this._getFiles(e);\n if (files.length === 0) return;\n\n this.emit('drop', {\n files,\n position: { x: e.clientX, y: e.clientY },\n dropZone,\n originalEvent: e,\n });\n\n this._currentDropZone = null;\n };\n\n private _findDropZone(e: DragEvent): HTMLElement | null {\n const target = e.target as Element;\n\n // Use composedPath for shadow DOM\n const path = e.composedPath();\n for (const el of path) {\n if (!(el instanceof HTMLElement)) continue;\n\n if (el.matches(this._options.dropZoneSelector)) {\n return el;\n }\n\n if (el === this._container || el === (this._container as ShadowRoot).host) {\n break;\n }\n }\n\n return target.closest?.(this._options.dropZoneSelector) as HTMLElement | null;\n }\n\n private _hasFiles(e: DragEvent): boolean {\n if (!e.dataTransfer) return false;\n\n // Check for files in types\n const types = e.dataTransfer.types;\n return types.includes('Files') || types.includes('application/x-moz-file');\n }\n\n private _getFiles(e: DragEvent): File[] {\n if (!e.dataTransfer?.files) return [];\n\n let files = Array.from(e.dataTransfer.files);\n\n // Filter by accept\n const accept = this._options.accept;\n if (accept && accept.length > 0) {\n files = files.filter((file) => this._matchesAccept(file, accept));\n }\n\n // Filter by max size\n const maxSize = this._options.maxSize;\n if (maxSize && maxSize > 0) {\n files = files.filter((file) => file.size <= maxSize);\n }\n\n // Limit to single file if not multiple\n if (!this._options.multiple && files.length > 1) {\n files = [files[0]];\n }\n\n return files;\n }\n\n private _matchesAccept(file: File, accept: string[]): boolean {\n for (const pattern of accept) {\n // Extension match (e.g., \".pdf\")\n if (pattern.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(pattern.toLowerCase())) {\n return true;\n }\n continue;\n }\n\n // MIME type match (e.g., \"image/*\" or \"application/pdf\")\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (file.type.startsWith(prefix)) {\n return true;\n }\n continue;\n }\n\n // Exact MIME match\n if (file.type === pattern) {\n return true;\n }\n }\n\n return false;\n }\n\n destroy(): void {\n this.detach();\n super.destroy();\n }\n}\n", "/**\n * FileDrop plugin - enables file drop zones for external files\n */\nimport type {\n Plugin,\n SnapInstance,\n FileDropOptions,\n FileDropEvent,\n} from '../types/index.js';\nimport {\n FileSensor,\n type FileDropEvent as SensorDropEvent,\n} from '../sensors/FileSensor.js';\n\nconst defaultOptions: FileDropOptions = {\n multiple: true,\n};\n\nexport class FileDrop implements Plugin {\n name = 'file-drop';\n\n private _snap: SnapInstance | null = null;\n private _options: FileDropOptions;\n private _sensor: FileSensor | null = null;\n private _onFileDrop: ((event: FileDropEvent) => void) | null = null;\n\n constructor(options: FileDropOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n init(snap: SnapInstance): void {\n this._snap = snap;\n\n // Get container element\n const container = this._getContainer();\n if (!container) return;\n\n // Initialize file sensor\n this._sensor = new FileSensor({\n container,\n dropZoneSelector: snap.options.dropZoneSelector ?? '[data-file-drop]',\n accept: this._options.accept,\n multiple: this._options.multiple,\n maxSize: this._options.maxSize,\n });\n\n // Setup event handlers\n this._setupEventHandlers();\n\n // Attach sensor\n this._sensor.attach();\n }\n\n destroy(): void {\n this._sensor?.destroy();\n this._sensor = null;\n this._snap = null;\n this._onFileDrop = null;\n }\n\n /**\n * Set callback for file drop events\n */\n onFileDrop(callback: (event: FileDropEvent) => void): this {\n this._onFileDrop = callback;\n return this;\n }\n\n /**\n * Update file drop options\n */\n setOptions(options: Partial<FileDropOptions>): void {\n Object.assign(this._options, options);\n }\n\n private _getContainer(): HTMLElement | ShadowRoot | null {\n if (!this._snap) return null;\n\n // Access internal container - this is a bit of a hack\n // In a real implementation, we'd expose this properly\n return (this._snap as unknown as { _container: HTMLElement | ShadowRoot })._container;\n }\n\n private _setupEventHandlers(): void {\n if (!this._sensor) return;\n\n // Handle drag enter\n this._sensor.on('dragenter', (e) => {\n e.dropZone.classList.add('snap-file-drag-over');\n });\n\n // Handle drag leave\n this._sensor.on('dragleave', (e) => {\n e.dropZone.classList.remove('snap-file-drag-over');\n });\n\n // Handle drop\n this._sensor.on('drop', (e: SensorDropEvent) => {\n e.dropZone.classList.remove('snap-file-drag-over');\n\n const event: FileDropEvent = {\n files: e.files,\n position: e.position,\n dropZone: e.dropZone,\n };\n\n // Call plugin callback\n this._onFileDrop?.(event);\n\n // Also emit through snap options if configured\n const snapOptions = this._snap?.options as unknown as {\n onFileDrop?: (event: FileDropEvent) => void;\n };\n snapOptions?.onFileDrop?.(event);\n });\n }\n}\n\n/**\n * Simple file drop zone creation helper\n * For basic use cases without full Snap instance\n */\nexport function createFileDropZone(\n element: HTMLElement,\n options: FileDropOptions & {\n onDrop: (files: File[]) => void;\n onDragEnter?: () => void;\n onDragLeave?: () => void;\n }\n): () => void {\n const { onDrop, onDragEnter, onDragLeave, ...fileOptions } = options;\n\n let dragCount = 0;\n\n const handleDragEnter = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n dragCount++;\n if (dragCount === 1) {\n element.classList.add('snap-file-drag-over');\n onDragEnter?.();\n }\n };\n\n const handleDragOver = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n e.preventDefault();\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'copy';\n }\n };\n\n const handleDragLeave = (e: DragEvent) => {\n if (!hasFiles(e)) return;\n dragCount--;\n if (dragCount === 0) {\n element.classList.remove('snap-file-drag-over');\n onDragLeave?.();\n }\n };\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault();\n dragCount = 0;\n element.classList.remove('snap-file-drag-over');\n\n let files = Array.from(e.dataTransfer?.files ?? []);\n\n // Filter by accept\n if (fileOptions.accept?.length) {\n files = files.filter((file) => matchesAccept(file, fileOptions.accept!));\n }\n\n // Filter by max size\n if (fileOptions.maxSize) {\n files = files.filter((file) => file.size <= fileOptions.maxSize!);\n }\n\n // Limit to single file if not multiple\n if (!fileOptions.multiple && files.length > 1) {\n files = [files[0]];\n }\n\n if (files.length > 0) {\n onDrop(files);\n }\n };\n\n // Attach handlers\n element.addEventListener('dragenter', handleDragEnter);\n element.addEventListener('dragover', handleDragOver);\n element.addEventListener('dragleave', handleDragLeave);\n element.addEventListener('drop', handleDrop);\n\n // Return cleanup function\n return () => {\n element.removeEventListener('dragenter', handleDragEnter);\n element.removeEventListener('dragover', handleDragOver);\n element.removeEventListener('dragleave', handleDragLeave);\n element.removeEventListener('drop', handleDrop);\n element.classList.remove('snap-file-drag-over');\n };\n}\n\nfunction hasFiles(e: DragEvent): boolean {\n if (!e.dataTransfer) return false;\n const types = e.dataTransfer.types;\n return types.includes('Files') || types.includes('application/x-moz-file');\n}\n\nfunction matchesAccept(file: File, accept: string[]): boolean {\n for (const pattern of accept) {\n if (pattern.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(pattern.toLowerCase())) {\n return true;\n }\n continue;\n }\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (file.type.startsWith(prefix)) {\n return true;\n }\n continue;\n }\n if (file.type === pattern) {\n return true;\n }\n }\n return false;\n}\n", "/**\n * AutoScroll behavior - scrolls containers when dragging near edges\n */\nimport type { Behavior, DragSession, AutoScrollOptions } from '../types/index.js';\n\nconst defaultOptions: Required<AutoScrollOptions> = {\n threshold: 40,\n maxSpeed: 15,\n acceleration: 2,\n};\n\nexport class AutoScroll implements Behavior {\n name = 'auto-scroll';\n\n private _options: Required<AutoScrollOptions>;\n private _scrollableAncestors: Element[] = [];\n private _rafId: number | null = null;\n private _active = false;\n\n constructor(options: AutoScrollOptions = {}) {\n this._options = { ...defaultOptions, ...options };\n }\n\n onDragStart(session: DragSession): void {\n this._scrollableAncestors = this._findScrollableAncestors(session.element);\n this._active = true;\n }\n\n onDragMove(session: DragSession): void {\n if (!this._active || this._rafId !== null) return;\n\n this._rafId = requestAnimationFrame(() => {\n this._rafId = null;\n this._performScroll(session.current.x, session.current.y);\n });\n }\n\n onDragEnd(): void {\n this._active = false;\n this._scrollableAncestors = [];\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n destroy(): void {\n this.onDragEnd();\n }\n\n private _performScroll(x: number, y: number): void {\n for (const ancestor of this._scrollableAncestors) {\n const rect = ancestor.getBoundingClientRect();\n const speed = this._calculateScrollSpeed(x, y, rect);\n\n if (speed.x !== 0 || speed.y !== 0) {\n ancestor.scrollBy({\n left: speed.x,\n top: speed.y,\n behavior: 'instant',\n });\n }\n }\n }\n\n private _calculateScrollSpeed(\n x: number,\n y: number,\n rect: DOMRect\n ): { x: number; y: number } {\n const { threshold, maxSpeed } = this._options;\n let scrollX = 0;\n let scrollY = 0;\n\n // Left edge\n if (x < rect.left + threshold) {\n scrollX = -this._getSpeed(rect.left + threshold - x);\n }\n // Right edge\n else if (x > rect.right - threshold) {\n scrollX = this._getSpeed(x - (rect.right - threshold));\n }\n\n // Top edge\n if (y < rect.top + threshold) {\n scrollY = -this._getSpeed(rect.top + threshold - y);\n }\n // Bottom edge\n else if (y > rect.bottom - threshold) {\n scrollY = this._getSpeed(y - (rect.bottom - threshold));\n }\n\n return { x: scrollX, y: scrollY };\n }\n\n private _getSpeed(distance: number): number {\n const { threshold, maxSpeed, acceleration } = this._options;\n const ratio = Math.min(distance / threshold, 1);\n return Math.pow(ratio, acceleration) * maxSpeed;\n }\n\n private _findScrollableAncestors(element: HTMLElement): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = element.parentElement;\n\n while (current && current !== document.body) {\n const style = getComputedStyle(current);\n const overflowX = style.overflowX;\n const overflowY = style.overflowY;\n\n const isScrollableX =\n (overflowX === 'auto' || overflowX === 'scroll') &&\n current.scrollWidth > current.clientWidth;\n\n const isScrollableY =\n (overflowY === 'auto' || overflowY === 'scroll') &&\n current.scrollHeight > current.clientHeight;\n\n if (isScrollableX || isScrollableY) {\n ancestors.push(current);\n }\n\n current = current.parentElement;\n }\n\n // Also include document scroll\n if (\n document.documentElement.scrollHeight > window.innerHeight ||\n document.documentElement.scrollWidth > window.innerWidth\n ) {\n ancestors.push(document.documentElement);\n }\n\n return ancestors;\n }\n}\n", "/**\n * SnapGrid behavior - snaps drag position to a grid\n * Note: This is handled in DragEngine via options.grid\n * This behavior provides additional grid-related features\n */\nimport type { Behavior, DragSession, GridOptions } from '../types/index.js';\n\nexport interface SnapGridOptions extends GridOptions {\n /** Only snap when within threshold of grid line */\n threshold?: number;\n /** Show visual grid guides */\n showGuides?: boolean;\n}\n\nexport class SnapGrid implements Behavior {\n name = 'snap-grid';\n\n private _options: SnapGridOptions;\n private _guideContainer: HTMLElement | null = null;\n\n constructor(options: SnapGridOptions) {\n this._options = options;\n }\n\n onDragStart(session: DragSession): void {\n if (this._options.showGuides) {\n this._createGuides(session.element);\n }\n }\n\n onDragMove(_session: DragSession): void {\n // Grid snapping is handled by DragEngine\n // This behavior could add additional visual feedback\n }\n\n onDragEnd(): void {\n this._removeGuides();\n }\n\n destroy(): void {\n this._removeGuides();\n }\n\n /**\n * Snap a point to the grid\n */\n snap(x: number, y: number): { x: number; y: number } {\n return {\n x: Math.round(x / this._options.x) * this._options.x,\n y: Math.round(y / this._options.y) * this._options.y,\n };\n }\n\n /**\n * Snap with threshold - only snap when close to grid line\n */\n snapWithThreshold(\n x: number,\n y: number,\n threshold?: number\n ): { x: number; y: number } {\n const t = threshold ?? this._options.threshold ?? 5;\n const snapped = this.snap(x, y);\n\n return {\n x: Math.abs(x - snapped.x) < t ? snapped.x : x,\n y: Math.abs(y - snapped.y) < t ? snapped.y : y,\n };\n }\n\n private _createGuides(element: HTMLElement): void {\n const container = element.offsetParent || document.body;\n const rect = container.getBoundingClientRect();\n\n this._guideContainer = document.createElement('div');\n this._guideContainer.style.cssText = `\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 9998;\n `;\n\n // Create vertical lines\n const cols = Math.ceil(rect.width / this._options.x);\n for (let i = 1; i < cols; i++) {\n const line = document.createElement('div');\n line.style.cssText = `\n position: absolute;\n left: ${i * this._options.x}px;\n top: 0;\n bottom: 0;\n width: 1px;\n background: rgba(0, 120, 255, 0.2);\n `;\n this._guideContainer.appendChild(line);\n }\n\n // Create horizontal lines\n const rows = Math.ceil(rect.height / this._options.y);\n for (let i = 1; i < rows; i++) {\n const line = document.createElement('div');\n line.style.cssText = `\n position: absolute;\n top: ${i * this._options.y}px;\n left: 0;\n right: 0;\n height: 1px;\n background: rgba(0, 120, 255, 0.2);\n `;\n this._guideContainer.appendChild(line);\n }\n\n container.appendChild(this._guideContainer);\n }\n\n private _removeGuides(): void {\n this._guideContainer?.remove();\n this._guideContainer = null;\n }\n}\n", "/**\n * ConstraintAxis behavior - constrain movement to specific axis\n * Note: Basic axis constraint is handled in DragEngine via options.axis\n * This behavior adds additional constraint features like bounds\n */\nimport type { Behavior, DragSession, Axis, Point } from '../types/index.js';\n\nexport interface ConstraintOptions {\n axis?: Axis;\n /** Bounding rectangle to constrain within */\n bounds?: {\n minX?: number;\n maxX?: number;\n minY?: number;\n maxY?: number;\n };\n /** Constrain to parent element bounds */\n containWithinParent?: boolean;\n}\n\nexport class ConstraintAxis implements Behavior {\n name = 'constraint-axis';\n\n private _options: ConstraintOptions;\n private _bounds: {\n minX: number;\n maxX: number;\n minY: number;\n maxY: number;\n } | null = null;\n\n constructor(options: ConstraintOptions = {}) {\n this._options = options;\n }\n\n onDragStart(session: DragSession): void {\n if (this._options.containWithinParent) {\n this._calculateParentBounds(session.element);\n } else if (this._options.bounds) {\n this._bounds = {\n minX: this._options.bounds.minX ?? -Infinity,\n maxX: this._options.bounds.maxX ?? Infinity,\n minY: this._options.bounds.minY ?? -Infinity,\n maxY: this._options.bounds.maxY ?? Infinity,\n };\n }\n }\n\n onDragMove(_session: DragSession): void {\n // Constraint is applied in DragEngine\n // This behavior provides bounds calculation\n }\n\n onDragEnd(): void {\n this._bounds = null;\n }\n\n destroy(): void {\n this._bounds = null;\n }\n\n /**\n * Apply constraints to a point\n */\n constrain(point: Point, origin: Point): Point {\n let { x, y } = point;\n\n // Apply axis constraint\n const axis = this._options.axis ?? 'both';\n if (axis === 'x') {\n y = origin.y;\n } else if (axis === 'y') {\n x = origin.x;\n }\n\n // Apply bounds constraint\n if (this._bounds) {\n x = Math.max(this._bounds.minX, Math.min(this._bounds.maxX, x));\n y = Math.max(this._bounds.minY, Math.min(this._bounds.maxY, y));\n }\n\n return { x, y };\n }\n\n /**\n * Get current bounds\n */\n getBounds(): typeof this._bounds {\n return this._bounds;\n }\n\n private _calculateParentBounds(element: HTMLElement): void {\n const parent = element.parentElement;\n if (!parent) return;\n\n const parentRect = parent.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n // Calculate bounds that keep element within parent\n this._bounds = {\n minX: parentRect.left,\n maxX: parentRect.right - elementRect.width,\n minY: parentRect.top,\n maxY: parentRect.bottom - elementRect.height,\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["src_exports", "__export", "AutoScroll", "BoundsCache", "ConstraintAxis", "DragEngine", "DragState", "DropZone", "DropZoneManager", "EventEmitter", "FileDrop", "FileSensor", "Kanban", "ObjectPool", "PointerSensor", "RAFThrottle", "Snap", "SnapDataTransfer", "SnapGrid", "Sortable", "boundsCache", "createFileDropZone", "Snap_default", "pointPool", "rafThrottle", "rectPool", "EventEmitter", "event", "callback", "listeners", "unsubscribe", "data", "SnapDataTransfer", "_SnapDataTransfer", "type", "value", "copy", "key", "DragState", "EventEmitter", "element", "origin", "initialData", "data", "SnapDataTransfer", "key", "value", "point", "zone", "previous", "session", "event", "callback", "RAFThrottle", "callback", "data", "rafThrottle", "fn", "rafId", "lastArgs", "throttled", "args", "ObjectPool", "factory", "reset", "initialSize", "maxSize", "obj", "pointPool", "p", "rectPool", "acquirePoint", "x", "y", "PointerSensor", "EventEmitter", "options", "e", "draggable", "acquirePoint", "target", "delay", "position", "distance", "dx", "dy", "pointPool", "delta", "RAFThrottle", "path", "el", "handle", "BoundsCache", "element", "cached", "rect", "boundsCache", "pointInRect", "x", "y", "rectCenter", "rect", "DragEngine", "engineOptions", "event", "element", "position", "data", "session", "startEvent", "boundsCache", "axis", "finalSession", "PointerSensor", "options", "origin", "grid", "dropZones", "foundZone", "zone", "rect", "pointInRect", "x", "y", "attr", "key", "draggableValue", "unsub", "DropZone", "element", "options", "x", "y", "rect", "boundsCache", "pointInRect", "data", "accepts", "type", "elementAccepts", "acceptedTypes", "s", "active", "itemSelector", "excludeElement", "items", "el", "firstRect", "lastRect", "isVertical", "i", "center", "rectCenter", "closestItem", "closestDistance", "position", "item", "dx", "dy", "distance", "DropZoneManager", "zone", "defaultOptions", "Snap", "container", "options", "DragState", "DropZoneManager", "DragEngine", "el", "unsub", "plugin", "behavior", "boundsCache", "element", "selector", "containerEl", "declarative", "imperative", "axis", "dropZoneSelector", "dropZones", "zone", "session", "mutations", "needsRefresh", "mutation", "target", "Snap_default", "defaultOptions", "Sortable", "options", "snap", "originalOnDragStart", "originalOnDragMove", "originalOnDrop", "originalOnDragEnd", "e", "enhancedEvent", "unsub", "element", "selector", "x", "y", "activeElement", "items", "el", "firstRect", "boundsCache", "lastRect", "isVertical", "newIndex", "i", "rect", "center", "rectCenter", "index", "insertBefore", "positions", "item", "oldRect", "newRect", "dx", "dy", "defaultOptions", "Kanban", "options", "snap", "originalOnDragStart", "originalOnDragMove", "originalOnDropZoneEnter", "originalOnDropZoneLeave", "originalOnDrop", "originalOnDragEnd", "e", "enhancedEvent", "element", "items", "position", "newIndex", "dropZone", "rect", "index", "activeElement", "el", "insertBefore", "container", "x", "y", "firstRect", "boundsCache", "lastRect", "isVertical", "i", "center", "rectCenter", "positions", "item", "oldRect", "newRect", "dx", "dy", "FileSensor", "EventEmitter", "options", "e", "dropZone", "files", "target", "path", "el", "types", "accept", "file", "maxSize", "pattern", "prefix", "defaultOptions", "FileDrop", "options", "snap", "container", "FileSensor", "callback", "event", "createFileDropZone", "element", "onDrop", "onDragEnter", "onDragLeave", "fileOptions", "dragCount", "handleDragEnter", "e", "hasFiles", "handleDragOver", "handleDragLeave", "handleDrop", "files", "file", "matchesAccept", "types", "accept", "pattern", "prefix", "defaultOptions", "AutoScroll", "options", "session", "x", "y", "ancestor", "rect", "speed", "threshold", "maxSpeed", "scrollX", "scrollY", "distance", "acceleration", "ratio", "element", "ancestors", "current", "style", "overflowX", "overflowY", "isScrollableX", "isScrollableY", "SnapGrid", "options", "session", "_session", "x", "y", "threshold", "t", "snapped", "element", "container", "rect", "cols", "i", "line", "rows", "ConstraintAxis", "options", "session", "_session", "point", "origin", "x", "y", "axis", "element", "parent", "parentRect", "elementRect"]
7
- }