var dragMaster = (function() {    var dragObject    var mouseDownAt	var currentDropTarget		function mouseDown(e) {		e = fixEvent(e)		if (e.which!=1) return 		mouseDownAt = { x: e.pageX, y: e.pageY, element: this }		addDocumentEventHandlers()		return false	}	function mouseMove(e){		e = fixEvent(e)		// (1)		if (mouseDownAt) {			if (Math.abs(mouseDownAt.x-e.pageX)<5 && Math.abs(mouseDownAt.y-e.pageY)<5) {				return false			}			// Начать перенос			var elem  = mouseDownAt.element			// текущий объект для переноса			dragObject = elem.dragObject						// запомнить, с каких относительных координат начался перенос			var mouseOffset = getMouseOffset(elem, mouseDownAt.x, mouseDownAt.y)			mouseDownAt = null // запомненное значение больше не нужно, сдвиг уже вычислен						dragObject.onDragStart(mouseOffset) // начали					}		// (2)		dragObject.onDragMove(e.pageX, e.pageY)				// (3)		var newTarget = getCurrentTarget(e)				// (4)		if (currentDropTarget != newTarget) {			if (currentDropTarget) {				currentDropTarget.onLeave()			}			if (newTarget) {				newTarget.onEnter()			}			currentDropTarget = newTarget		}				// (5)		return false    }		    function mouseUp(){		if (!dragObject) { // (1)			mouseDownAt = null		} else {			// (2)			if (currentDropTarget) {				currentDropTarget.accept(dragObject)				dragObject.onDragSuccess(currentDropTarget)			} else {				dragObject.onDragFail()			}			dragObject = null		}		// (3)		removeDocumentEventHandlers()    }	function getMouseOffset(target, x, y) {		var docPos	= getOffset(target)		return {x:x - docPos.left, y:y - docPos.top}	}		function getCurrentTarget(e) {		// спрятать объект, получить элемент под ним - и тут же показать опять				if (navigator.userAgent.match('MSIE') || navigator.userAgent.match('Gecko')) {			var x=e.clientX, y=e.clientY		} else {			var x=e.pageX, y=e.pageY		}		// чтобы не было заметно мигание - максимально снизим время от hide до show		dragObject.hide()		var elem = document.elementFromPoint(x,y)		dragObject.show()				// найти самую вложенную dropTarget		while (elem) {			// которая может принять dragObject 			if (elem.dropTarget && elem.dropTarget.canAccept(dragObject)) {				return elem.dropTarget			}			elem = elem.parentNode		}				// dropTarget не нашли		return null	}	function addDocumentEventHandlers() {		document.onmousemove = mouseMove		document.onmouseup = mouseUp		document.ondragstart = document.body.onselectstart = function() {return false}	}	function removeDocumentEventHandlers() {		document.onmousemove = document.onmouseup = document.ondragstart = document.body.onselectstart = null	}    return {		makeDraggable: function(element){			element.onmousedown = mouseDown		}    }}())
