// Crosshair
(function(h){h.plot.plugins.push({init:function(a){function e(){!c.locked&&-1!=c.x&&(c.x=-1,a.triggerRedrawOverlay())}function g(d){if(!c.locked)if(a.getSelection&&a.getSelection())c.x=-1;else{var b=a.offset();c.x=Math.max(0,Math.min(d.pageX-b.left,a.width()));c.y=Math.max(0,Math.min(d.pageY-b.top,a.height()));a.triggerRedrawOverlay()}}var c={x:-1,y:-1,locked:!1};a.setCrosshair=function(d){d?(d=a.p2c(d),c.x=Math.max(0,Math.min(d.left,a.width())),c.y=Math.max(0,Math.min(d.top,a.height()))):c.x=-1;
a.triggerRedrawOverlay()};a.clearCrosshair=a.setCrosshair;a.lockCrosshair=function(d){d&&a.setCrosshair(d);c.locked=!0};a.unlockCrosshair=function(){c.locked=!1};a.hooks.bindEvents.push(function(a,b){a.getOptions().crosshair.mode&&(b.mouseout(e),b.mousemove(g))});a.hooks.drawOverlay.push(function(a,b){var f=a.getOptions().crosshair;if(f.mode){var e=a.getPlotOffset();b.save();b.translate(e.left,e.top);-1!=c.x&&(b.strokeStyle=f.color,b.lineWidth=f.lineWidth,b.lineJoin="round",b.beginPath(),-1!=f.mode.indexOf("x")&&
(b.moveTo(c.x,0),b.lineTo(c.x,a.height())),-1!=f.mode.indexOf("y")&&(b.moveTo(0,c.y),b.lineTo(a.width(),c.y)),b.stroke());b.restore()}});a.hooks.shutdown.push(function(a,b){b.unbind("mouseout",e);b.unbind("mousemove",g)})},options:{crosshair:{mode:null,color:"rgba(170, 0, 0, 0.80)",lineWidth:1}},name:"crosshair",version:"1.0"})})(jQuery);

// Resize
(function(a,f,i){function d(){k=f[g](function(){b.each(function(){var c=a(this),d=c.width(),f=c.height(),b=a.data(this,j);if(d!==b.w||f!==b.h)c.trigger(h,[b.w=d,b.h=f])});d()},e[l])}var b=a([]),e=a.resize=a.extend(a.resize,{}),k,g="setTimeout",h="resize",j=h+"-special-event",l="delay";e[l]=250;e.throttleWindow=!0;a.event.special[h]={setup:function(){if(!e.throttleWindow&&this[g])return!1;var c=a(this);b=b.add(c);a.data(this,j,{w:c.width(),h:c.height()});1===b.length&&d()},teardown:function(){if(!e.throttleWindow&&
this[g])return!1;var c=a(this);b=b.not(c);c.removeData(j);b.length||clearTimeout(k)},add:function(c){function d(c,f,e){var g=a(this),h=a.data(this,j);h.w=f!==i?f:g.width();h.h=e!==i?e:g.height();b.apply(this,arguments)}if(!e.throttleWindow&&this[g])return!1;var b;if(a.isFunction(c))return b=c,d;b=c.handler;c.handler=d}}})(jQuery,this);
(function(a){a.plot.plugins.push({init:function(a){function i(){var d=a.getPlaceholder();0==d.width()||0==d.height()||(a.resize(),a.setupGrid(),a.draw())}a.hooks.bindEvents.push(function(a){a.getPlaceholder().resize(i)});a.hooks.shutdown.push(function(a){a.getPlaceholder().unbind("resize",i)})},options:{},name:"resize",version:"1.0"})})(jQuery);

// Selection
(function(k){k.plot.plugins.push({init:function(a){function p(c){b.active&&(q(c),a.getPlaceholder().trigger("plotselecting",[n()]))}function r(c){1==c.which&&(document.body.focus(),void 0!==document.onselectstart&&null==h.onselectstart&&(h.onselectstart=document.onselectstart,document.onselectstart=function(){return!1}),void 0!==document.ondrag&&null==h.ondrag&&(h.ondrag=document.ondrag,document.ondrag=function(){return!1}),s(b.first,c),b.active=!0,l=function(c){l=null;void 0!==document.onselectstart&&
(document.onselectstart=h.onselectstart);void 0!==document.ondrag&&(document.ondrag=h.ondrag);b.active=!1;q(c);m()?t():(a.getPlaceholder().trigger("plotunselected",[]),a.getPlaceholder().trigger("plotselecting",[null]))},k(document).one("mouseup",l))}function n(){if(!m())return null;var c={},j=b.first,d=b.second;k.each(a.getAxes(),function(b,a){if(a.used){var f=a.c2p(j[a.direction]),i=a.c2p(d[a.direction]);c[b]={from:Math.min(f,i),to:Math.max(f,i)}}});return c}function t(){var c=n();a.getPlaceholder().trigger("plotselected",
[c]);c.xaxis&&c.yaxis&&a.getPlaceholder().trigger("selected",[{x1:c.xaxis.from,y1:c.yaxis.from,x2:c.xaxis.to,y2:c.yaxis.to}])}function s(c,j){var d=a.getOptions(),e=a.getPlaceholder().offset(),g=a.getPlotOffset(),f=j.pageX-e.left-g.left,i=a.width();c.x=0>f?0:f>i?i:f;e=j.pageY-e.top-g.top;g=a.height();c.y=0>e?0:e>g?g:e;"y"==d.selection.mode&&(c.x=c==b.first?0:a.width());"x"==d.selection.mode&&(c.y=c==b.first?0:a.height())}function q(c){null!=c.pageX&&(s(b.second,c),m()?(b.show=!0,a.triggerRedrawOverlay()):
u(!0))}function u(c){b.show&&(b.show=!1,a.triggerRedrawOverlay(),c||a.getPlaceholder().trigger("plotunselected",[]))}function v(c,b){var d,e,g,f,i=a.getAxes(),h;for(h in i)if(d=i[h],d.direction==b&&(f=b+d.n+"axis",!c[f]&&1==d.n&&(f=b+"axis"),c[f])){e=c[f].from;g=c[f].to;break}c[f]||(d="x"==b?a.getXAxes()[0]:a.getYAxes()[0],e=c[b+"1"],g=c[b+"2"]);null!=e&&(null!=g&&e>g)&&(f=e,e=g,g=f);return{from:e,to:g,axis:d}}function m(){return 0.1<=Math.abs(b.second.x-b.first.x)&&0.1<=Math.abs(b.second.y-b.first.y)}
var b={first:{x:-1,y:-1},second:{x:-1,y:-1},show:!1,active:!1},h={},l=null;a.clearSelection=u;a.setSelection=function(c,j){var d,e=a.getOptions();"y"==e.selection.mode?(b.first.x=0,b.second.x=a.width()):(d=v(c,"x"),b.first.x=d.axis.p2c(d.from),b.second.x=d.axis.p2c(d.to));"x"==e.selection.mode?(b.first.y=0,b.second.y=a.height()):(d=v(c,"y"),b.first.y=d.axis.p2c(d.from),b.second.y=d.axis.p2c(d.to));b.show=!0;a.triggerRedrawOverlay();!j&&m()&&t()};a.getSelection=n;a.hooks.bindEvents.push(function(c,
b){null!=c.getOptions().selection.mode&&(b.mousemove(p),b.mousedown(r))});a.hooks.drawOverlay.push(function(c,a){if(b.show&&m()){var d=c.getPlotOffset(),e=c.getOptions();a.save();a.translate(d.left,d.top);d=k.color.parse(e.selection.color);a.strokeStyle=d.scale("a",0.8).toString();a.lineWidth=1;a.lineJoin="round";a.fillStyle=d.scale("a",0.4).toString();var d=Math.min(b.first.x,b.second.x),e=Math.min(b.first.y,b.second.y),g=Math.abs(b.second.x-b.first.x),f=Math.abs(b.second.y-b.first.y);a.fillRect(d,
e,g,f);a.strokeRect(d,e,g,f);a.restore()}});a.hooks.shutdown.push(function(b,a){a.unbind("mousemove",p);a.unbind("mousedown",r);l&&k(document).unbind("mouseup",l)})},options:{selection:{mode:null,color:"#e8cfac"}},name:"selection",version:"1.1"})})(jQuery);

// Fillbetween
(function(j){j.plot.plugins.push({init:function(j){j.hooks.processDatapoints.push(function(a,h,q){if(null!=h.fillBetween){var e;a:{var a=a.getData(),c;for(c=0;c<a.length;++c)if(a[c].id==h.fillBetween){e=a[c];break a}"number"==typeof h.fillBetween?(c=h.fillBetween,e=0>c||c>=a.length?null:a[c]):e=null}if(e){a=q.pointsize;c=q.points;var k=e.datapoints.pointsize;e=e.datapoints.points;for(var d=[],i,j,l,n,p=h.lines.show,s=2<a&&q.format[2].y,t=p&&h.lines.steps,r=!0,b=0,f=0,g;!(b>=c.length);){g=d.length;
if(null==c[b]){for(m=0;m<a;++m)d.push(c[b+m]);b+=a}else if(f>=e.length){if(!p)for(m=0;m<a;++m)d.push(c[b+m]);b+=a}else if(null==e[f]){for(m=0;m<a;++m)d.push(null);r=!0;f+=k}else{i=c[b];j=c[b+1];h=e[f];l=e[f+1];n=0;if(i==h){for(m=0;m<a;++m)d.push(c[b+m]);n=l;b+=a;f+=k}else if(i>h){if(p&&0<b&&null!=c[b-a]){i=j+(c[b-a+1]-j)*(h-i)/(c[b-a]-i);d.push(h);d.push(i);for(m=2;m<a;++m)d.push(c[b+m]);n=l}f+=k}else{if(r&&p){b+=a;continue}for(m=0;m<a;++m)d.push(c[b+m]);p&&(0<f&&null!=e[f-k])&&(n=l+(e[f-k+1]-l)*
(i-h)/(e[f-k]-h));b+=a}r=!1;g!=d.length&&s&&(d[g+2]=n)}if(t&&g!=d.length&&0<g&&null!=d[g]&&d[g]!=d[g-a]&&d[g+1]!=d[g-a+1]){for(m=0;m<a;++m)d[g+a+m]=d[g+m];d[g+1]=d[g-a+1]}}q.points=d}}})},options:{series:{fillBetween:null}},name:"fillbetween",version:"1.0"})})(jQuery);
