var DragDrift=new JS.Class({include:[Ojay.Observable,JS.State],extend:{TICK_INTERVAL:0.05,_instances:[],updatePosition:function(A){this._instances.forEach({updatePosition:A})}},initialize:function(A,B){this.klass._instances.push(this);this._handle=Ojay(A);B=B||{};this._others=Ojay(B.controls||"");[this._handle,this._others].forEach({setStyle:{position:"relative"}});this.setState("FREE");this._handle.on("mousedown")._(this)._startDragging();this._handle.on("mouseup")._(this)._stopDragging()},states:{DRAGGING:{updatePosition:function(A){this._x=A.left-this._base.x;this._y=A.top-this._base.y;this._elements=Ojay(this._handle,this._others);this._elements.setStyle({left:this._x+"px",top:this._y+"px"})},_stopDragging:function(){this.notifyObservers("dragend");this.setState("RETURNING");var A=(this._x.pow(2)+this._y.pow(2)).sqrt();this._elements.animate({left:{to:0},top:{to:0}},A/45,{easing:"easeNone"})._(function(B){B.setState("FREE");B.notifyObservers("settled")},this)}},FREE:{_startDragging:function(){var A=Ojay.Mouse.position;this._base={x:A.left,y:A.top};this.setState("DRAGGING");this.notifyObservers("dragstart")}},RETURNING:{}}});Ojay.Mouse.subscribe(DragDrift.method("updatePosition"))