From 045ab982c829e4033484cc9c8e0097e97cbe95bf Mon Sep 17 00:00:00 2001 From: Michael Zinsmaier Date: Thu, 30 Oct 2014 20:54:03 +0100 Subject: [PATCH] Added new hermite spline interpolatin and docu. Changed tests to be based on the minified version of flot 8.3 --- curvedLines.js | 109 +- docu/MathStuff.pdf | Bin 0 -> 105319 bytes docu/MathStuff.tex | 105 + flot/jquery.colorhelpers.min.js | 1 + flot/jquery.flot.canvas.min.js | 7 + flot/jquery.flot.categories.min.js | 7 + flot/jquery.flot.crosshair.min.js | 7 + flot/jquery.flot.errorbars.min.js | 7 + flot/jquery.flot.fillbetween.min.js | 7 + flot/jquery.flot.image.min.js | 7 + flot/jquery.flot.js | 3061 --------------------------- flot/jquery.flot.min.js | 8 + flot/jquery.flot.navigate.js | 346 --- flot/jquery.flot.navigate.min.js | 7 + flot/jquery.flot.pie.min.js | 7 + flot/jquery.flot.resize.min.js | 7 + flot/jquery.flot.selection.min.js | 7 + flot/jquery.flot.stack.js | 188 -- flot/jquery.flot.stack.min.js | 7 + flot/jquery.flot.symbol.min.js | 7 + flot/jquery.flot.threshold.js | 142 -- flot/jquery.flot.threshold.min.js | 7 + flot/jquery.flot.time.js | 431 ---- flot/jquery.flot.time.min.js | 7 + flot/jquery.min.js | 5 + tests/Issue18.htm | 8 +- tests/Issue19.htm | 8 +- tests/testDate.htm | 6 +- tests/testExample.htm | 4 +- tests/testExampleFillMultiAxis.htm | 4 +- tests/testExampleFit.htm | 4 +- tests/testSaddlePoint.htm | 4 +- tests/testSinglePoint.htm | 4 +- tests/testThreshold.htm | 6 +- tests/testTooltip.htm | 4 +- tests/testZeroDrop.htm | 4 +- 36 files changed, 305 insertions(+), 4245 deletions(-) create mode 100644 docu/MathStuff.pdf create mode 100644 docu/MathStuff.tex create mode 100644 flot/jquery.colorhelpers.min.js create mode 100644 flot/jquery.flot.canvas.min.js create mode 100644 flot/jquery.flot.categories.min.js create mode 100644 flot/jquery.flot.crosshair.min.js create mode 100644 flot/jquery.flot.errorbars.min.js create mode 100644 flot/jquery.flot.fillbetween.min.js create mode 100644 flot/jquery.flot.image.min.js delete mode 100644 flot/jquery.flot.js create mode 100644 flot/jquery.flot.min.js delete mode 100644 flot/jquery.flot.navigate.js create mode 100644 flot/jquery.flot.navigate.min.js create mode 100644 flot/jquery.flot.pie.min.js create mode 100644 flot/jquery.flot.resize.min.js create mode 100644 flot/jquery.flot.selection.min.js delete mode 100644 flot/jquery.flot.stack.js create mode 100644 flot/jquery.flot.stack.min.js create mode 100644 flot/jquery.flot.symbol.min.js delete mode 100644 flot/jquery.flot.threshold.js create mode 100644 flot/jquery.flot.threshold.min.js delete mode 100644 flot/jquery.flot.time.js create mode 100644 flot/jquery.flot.time.min.js create mode 100644 flot/jquery.min.js diff --git a/curvedLines.js b/curvedLines.js index 07475fe..671dff7 100644 --- a/curvedLines.js +++ b/curvedLines.js @@ -20,11 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ /* - - ____________________________________________________ +____________________________________________________ what it is: ____________________________________________________ @@ -35,7 +34,7 @@ => 1) with large data sets you may get trouble => 2) if you want to display the points too, you have to plot them as 2nd data series over the lines - && 3) consecutive x data points are not allowed to have the same value + => 3) consecutive x data points are not allowed to have the same value Feel free to further improve the code @@ -48,7 +47,7 @@ var options = { series: { curvedLines: { active: true }}}; - $.plot($("#placeholder"), [{data = d1, lines: { show: true}, curvedLines: {apply: true}}], options); + $.plot($("#placeholder"), [{data: d1, lines: { show: true}, curvedLines: {apply: true}}], options); _____________________________________________________ @@ -57,17 +56,21 @@ active: bool true => plugin can be used apply: bool true => series will be drawn as curved line + monotonicFit: bool true => uses monotone cubic interpolation (preserve monotonicity) + tension: int defines the tension parameter of the hermite spline interpolation (no effect if monotonicFit is set) + nrSplinePoints: int defines the number of sample points (of the spline) in between two consecutive points deprecated options from flot prior to 1.0.0: ------------------------------------------------ - legacyOverride bool true => use old default OR + legacyOverride bool true => use old default + OR legacyOverride optionArray { - fit: bool true => forces the max,mins of the curve to be on the datapoints - curvePointFactor int defines how many "virtual" points are used per "real" data point to - emulate the curvedLines (points total = real points * curvePointFactor) - fitPointDist: int defines the x axis distance of the additional two points that are used - } to enforce the min max condition. + fit: bool true => forces the max,mins of the curve to be on the datapoints + curvePointFactor int defines how many "virtual" points are used per "real" data point to + emulate the curvedLines (points total = real points * curvePointFactor) + fitPointDist: int defines the x axis distance of the additional two points that are used + } to enforce the min max condition. */ /* @@ -83,6 +86,7 @@ * v0.6.x changed versioning schema * * v1.0.0 API Break marked existing implementation/options as deprecated + * v1.1.0 added the new curved line calculations based on hermite splines */ (function($) { @@ -93,7 +97,7 @@ active : false, apply : false, monotonicFit : false, - tension : 0.0, + tension : 0.5, nrSplinePoints : 20, legacyOverride : undefined } @@ -214,14 +218,19 @@ + // Creates an array of splines, one for each segment of the original curve. Algorithm based on the wikipedia articles: + // + // http://de.wikipedia.org/w/index.php?title=Kubisch_Hermitescher_Spline&oldid=130168003 and + // http://en.wikipedia.org/w/index.php?title=Monotone_cubic_interpolation&oldid=622341725 and the description of Fritsch-Carlson from + // http://math.stackexchange.com/questions/45218/implementation-of-monotone-cubic-interpolation + // for a detailed description see https://github.com/MichaelZinsmaier/CurvedLines/docu function createHermiteSplines(datapoints, curvedLinesOptions, yPos) { var points = datapoints.points; var ps = datapoints.pointsize; - // Get consecutive differences and slopes - var dxs = []; - var dys = []; - var ms = []; + // preparation get length (x_{k+1} - x_k) and slope s=(p_{k+1} - p_k) / (x_{k+1} - x_k) of the segments + var segmentLengths = []; + var segmentSlopes = []; for (var i = 0; i < points.length - ps; i += ps) { var curX = i; @@ -229,25 +238,26 @@ var dx = points[curX + ps] - points[curX]; var dy = points[curY + ps] - points[curY]; - dxs.push(dx); - dys.push(dy); - ms.push(dy / dx); + segmentLengths.push(dx); + segmentSlopes.push(dy / dx); } - // Get degree-1 coefficients - var c1s = [ms[0]]; + //get the values for the desired gradients m_k for all points k + //depending on the used method the formula is different + var gradients = [segmentSlopes[0]]; if (curvedLinesOptions.monotonicFit) { // Fritsch Carlson - for (var i = 0; i < dxs.length - 1; i++) { - var m = ms[i]; - var mNext = ms[i + 1]; - if (m * mNext <= 0) { - c1s.push(0); + for (var i = 1; i < segmentLengths.length; i++) { + var slope = segmentSlopes[i]; + var prev_slope = segmentSlopes[i - 1]; + if (slope * prev_slope <= 0) { // sign(prev_slope) != sign(slpe) + gradients.push(0); } else { - var dx = dxs[i]; - var dxNext = dxs[i + 1]; - var common = dx + dxNext; - c1s.push(3 * common / ((common + dxNext) / m + (common + dx) / mNext)); + var length = segmentLengths[i]; + var prev_length = segmentLengths[i - 1]; + var common = length + prev_length; + //m = 3 (prev_length + length) / ((2 length + prev_length) / prev_slope + (length + 2 prev_length) / slope) + gradients.push(3 * common / ((common + length) / prev_slope + (common + prev_length) / slope)); } } } else { @@ -256,35 +266,38 @@ for (var i = ps; i < points.length - ps; i += ps) { var curX = i; var curY = i + yPos; - c1s.push(Number(curvedLinesOptions.tension) * (points[curY + ps] - points[curY - ps]) / (points[curX + ps] - points[curX - ps])); + gradients.push(Number(curvedLinesOptions.tension) * (points[curY + ps] - points[curY - ps]) / (points[curX + ps] - points[curX - ps])); } } - c1s.push(ms[ms.length - 1]); - - // Get degree-2 and degree-3 coefficients - var c2s = [], c3s = []; - for ( i = 0; i < c1s.length - 1; i++) { - var c1 = c1s[i]; - var m = ms[i]; - var invDx = 1 / dxs[i]; - var common = c1 + c1s[i + 1] - m - m; - c2s.push((m - c1 - common) * invDx); - c3s.push(common * invDx * invDx); + gradients.push(segmentSlopes[segmentSlopes.length - 1]); + + //get the two major coefficients (c'_{oef1} and c'_{oef2}) for each segment spline + var coefs1 = []; + var coefs2 = []; + for (i = 0; i < segmentLengths.length; i++) { + var m_k = gradients[i]; + var m_k_plus = gradients[i + 1]; + var slope = segmentSlopes[i]; + var invLength = 1 / segmentLengths[i]; + var common = m_k + m_k_plus - slope - slope; + + coefs1.push(common * invLength * invLength); + coefs2.push((slope - common - m_k) * invLength); } - //create functions with captured parameters + //create functions with from the coefficients and capture the parameters var ret = []; - for (var i = 0; i < c1s.length - 1; i ++) { - var spline = function (x0, a, b, c, d) { + for (var i = 0; i < segmentLengths.length; i ++) { + var spline = function (x_k, coef1, coef2, coef3, coef4) { // spline for a segment return function (x) { - var diff = x - x0; + var diff = x - x_k; var diffSq = diff * diff; - return a * diff + b * diffSq + c * diff * diffSq + d; + return coef1 * diff * diffSq + coef2 * diffSq + coef3 * diff + coef4; }; }; - ret.push(spline(points[i * ps], c1s[i], c2s[i], c3s[i], points[i * ps + yPos])); + ret.push(spline(points[i * ps], coefs1[i], coefs2[i], gradients[i], points[i * ps + yPos])); } return ret; diff --git a/docu/MathStuff.pdf b/docu/MathStuff.pdf new file mode 100644 index 0000000000000000000000000000000000000000..daedd2f7f08e9be68fc0d559de23789d6519457d GIT binary patch literal 105319 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 XTG}S$8 z%`)~W7Sn1F1z<c{YcWXs1dTs`g$ipvmfT*bMMU`cAhRM2tAaOL{XwviVcSgIlZdC$@TfRdI4IXy;MMw!*-o9=* zme3x7=xZ|BDZ86&pyBY1*e2SMK2%xra^~-_+*&5O@H&$oFoxvudsoAT@ND_^FL_*{ zC`;Dt!btMJEN#*o)7XSt`;FQnn%SfR(H0K|F2SdV!r@d!3|fR~`>swHU~~hjzXH$% zn0T%IiTi`w>l{B{a|ajHWq~ z$N^HuJ0v!Q0V62^NIHoK{n(iaSnc52btzvrrd{N@EAqghgrLkg9&IV;pAQNwO6pZh zTJ*awJqaa|H8W$?@BXT}0!y*E;HzIOy|GBNBkgm7G+OL%(+O>he{Y{*vcVXAAFs>v z5w!wSV;8A8_Z&~7Z$GX2ujrJDY`o8#zfbl zB97CZx2Y{)>mE_* zLFZXgofZ`)?2Mqf#oKeJwy!vPQhRg-$XzusG%Q4a{;tAS{FWAPwu}Z0QXsw4W;@svdl)Zf|@9x z!6k~*c%?eXlO9H6Bi;px?dZ%B4hzkEXR(8WwZ9F7(|R=?6ojZ^0#vF(KBmj9Fl4Ac zp>w+WNdH=P{I-Lb0QHRKn%LLt6Ys5hyCTCBlL+>t|=h6T$m07rOq z)@4TFl#DOkdV9+JHm6l0sGJlr)pZ8wN@q)-BTGX5bnSm9#^WvlS_oUlpD(lzM@aBc z^o1wFK@r|t3jMJvtMQHqj7iwQju~i);?Xg%oVXEsU+Wfn;fgVYMJ2h5Oo?od8c=^z z^2=|V$LMSlDbY!RX606XGq&wTcm^$f^Gjns3&xk>0}F&oH24FoH)B2lMhcDID3&gO za)|MJflyRw+`KNct36tdq-%>z8ew0&PQjkhyzz;8F)~J0o=wPESkALcTnarN>fH!c zNLWYID<6V!00~HB+n`i>?S3sLk0&Vw1sKOBuCJfkTr98U_GLAz<%Pgoh6W?4WpRD& z!=Tb7fc@REuX}f8{F{wZTLR}FyV6#Y58vLgP5k4-*&w~!!RW#FL7f)x*BMJ>=)jzD zU_0ej@%n1`qob+SN@w)-N;eEhwAyYVjYVCr*@QFg4`(Z?o0oI;n@>%RO*uI+wgx$d52&|0XV?v*f_ zji4)rV9&ILFl-j|y2JKvcFJdZ@;(}fm-@|_>5!&!lCX_em~*Hrlo->nIQfa=O*4hUPdcm?yA^a$W@(7(uNce|dPM+3<(i0%tXDBEJ zNUC>l+(_SF>)r3h|$@%t*cH9QCSBY1+ra~6;+(t zvf5?-sAs8bDZ%*TseOye^y{khMx0N`tKby!+a}HQ_hzSi%j!Wi&QIN~B;%yCtt*0( zo8K_&s2oidoBbF`gJbvkV(0W3Yx4bQ^ryD8kd0`8^%gjfD_c09%?G&rzZA)<>oduo* zQk`14#nVn5#Ob5-g?u6+*;+fBBu5kGLwlKkr)*6T&1&WXg&>vCPM}vZo0pTVFtFSk zcdG5|W2z*peB*$kI83u9FJ9&iawb3xTgVuy6K1oB_aIqtghU~PCIuiq7UB07bo}%* zYf9hW$%>F4*JoLYp<#^uIdY93u|!domrYt8^(agS$XJq=YZ~qdDTN6F`MQcDVkOvbQRb^^NvyJ5L#J#JnIh`uTKh7Ozb;8@8uK4WwVCL% z2UhXiV;JFc?%ek{oVEV0!fhMku7|^1vZI@6I`ld{7 z?RC4%in4K~*XEoqkGx*4Xv6g6MaCs(rYIM$kFO(~t}Ww_y?Af9rT2SC)Ke~R$mdKQ zQw7u|1HvgF!|V=;dVc(a2pZqloK^c5xM?^;eFYbG7p=}d&-NxS?WIL!5J)xlSh~Z_ zwiaG?xA8fUz4p0&WD2Zw1(Jgt+mNFF@Ea4*Q*f?0+cP)I9GknM6el87G>m0Jojfb1 z!%LZXiAPoD-#9O>x_(+K`s-Ojw!d_tVlTzoZTcm}9mZ3wcZ09vih*zkju~~F$qy|j zS7JD=Bx~>&;wQI4V5;;}dGczYSx%fmCDgxoQEV1z|Dk1p{XeuUFfeiaUohdHs7}wq z{-5{+HhOxF|1qE70;+^;u}ZtWkPsjkxHR`iVSxZ=frVah3V?}OOhUXAAAfqBT5Xr0f@&>WnZ~z1u8Xk7@ z2?ajV;=4i6v?S+S!~_Iu&!gPX-~xWqYe7I5IMtiy)EYg4dEC?b~xkx>>4@;40PrB_|Ci_lx2U@ zLAc=7e1XY@WrB+-@6*92MeOl%f+GOo1Azbysl!N z0{Ya@tNL+60g(e3zzcjMy!BUe^8*BRf|K{%`eOaiAVNR@T;aDs_`!|=0+GDQx+Gy5 z{fdf6@8BH3(t{R+{V!DgYS7Ot7!F@hkAx_NupeVg5#Gs)er^v^EAFWb!T#KUjix9@A=(f-xf=EVEtm#X^qFrbrvDFhJ?R+S!T!UpigFN(1=CR;+{~{QAxI6#J=nUr zAVSL?FUW@{SlQDI0=XC#Sm>9B2|!sr;O}I}28$-yk|L0(^hGOVkVdg@s#4I#z?IK+ zR$dr+-^TX#MkoM_TM{wQ9TFc+DbCm@TkStaT@D=x1&FU78ena33({v=Q4PB<)}zXY z;&)5{z(>^-{>^r{mvY^st+TM@mJLbH`itgQ#~EP^%Sf`09=b6Z#<2?4vb!v$@bzFD z)AuRfdh(0}t#&uSGZQ=koh`YNlFDfLTZ-1XEYrzdG5%4><^HF6S7(uHE9}H5JB8{u zHzm9yQIiJb5wGln?BDF|#RvM`?fu21&wa1UBO8p%fR(_loZ+PNqnlV&wy6F7a^;ow zs%i@}CQoPaW3hx%_MPcEvTYTAl)BwL^Cnj26$YjWHV7T?4)6os4)J2CDc-oQ?ADH| zfmj zuXiY!cY11)t>&FFiqI=)Q-0})qf@^2o};J>Vy?!O?F!UMG~_T$ z0y2a_m(K1l!sPTDY9!qSbD4decR4OlQY`)e8(jeyU#-4Z5VW7WRd)x;xHiW8bdn71 z-wA_Mfm^FxsX(#qbyw!_ykUoe9p}(@S(Ca?7eDK(*vy<;s)MHS<0Kh6kM%f`w_;E= zEWFs*+7WK=SUa*2eK84w3XmO@gX!D;gZxwyrxzUMM-Nbsw2G+Q=-KhU0S!5-;_kUF zSb1NK>f|8~FnM``4jmyQ>-0NH;DFZk{ljEVd-aT1=l>Pw{!pV^H?SEX8=(S+Ogw zcP2n^B-`4k0=BUt01ov&xCSG*EtFq+-SxotxV*N}5xnspwvI-Z`oAl6qci=xQZ8CX zs3L6A5sT#0BQ3Y}TF>&SKB7lSGk#CW6zb(C&(EC)DMfP6j$NxFP4I`?^+-AENvIbO z+!(O*2q=Uz*wA98^2EOEviVhKzam}{@9R5Nz5q|mq?)UQUiCJ*l>*I?- zh@gjS;Ff5KV;k?&gp8)C`o()dw-;~8LmyJIFI51IOX3;p3KZ-3f5_ltX#ep5)DmNw zTix9UZaH$jba< z(4^{9d$bhUY8IxT+FZ*#obq2EM7tw}2I9|0--fa>01wh&g14Wqu`}~75a5${!OpR8 zn-eBQ2fD(N16^695xwN&K&#B{A{qx4G*v-sALRlHR#iEBweuID&Q1{=3gqCrQ)gxy z+RKsuMl)sc9(}IJ==X6F48nMoCmE%(DkU-hvNDGxW7BGSWx9|P-Me4Q1*gYwA%3Uv z>{u1jDw#262pL`_dBVEpWCA-DNx#R~&3~(Q3A5cB<5X|M8-{DOp*gj1&VKMV&!41j z;d(*FUFB$g3;l>IcUU~{&%adItG;BrM*^&XIo{Wrbb;^H%zMnz1%nUnl8=a*7`gy> zYqW@Kdb`DHDX7iFV|G+6VWL}5tRQdnn9S4glEiH_x|*>yDdszgj~(R3dHKdNAkHxO zPC6+3hMafmWh9VB^~(wqM(j^z?Yf<$KO-L|95jIW2eBvL&h@w{3FZIlEn-&G(ErvY zFHdyMeWUweC|X|>bk+Y&kYPOra*$@cLhFb1$`uxTcnRZBbvl!|bJ4z5H2TH!_Y779dBf7V>1Wp;{^>VO$ChThwxv&9*<| zM4$l=-&Akf>PLcM+k&$P{jw)7E9tyv4G>!$Z}!c1wbI{R``4i2BkcwLtV;co1TbRJC?}ug9go_W3f9XhzZ#`L>~{JNq}(IyXd^Xfujri*ZFf zZ4ScZ0>?y(@FFck_`QpyA6F)y+TV#)RE9behKtd5chl!rgM7+wylg$db)gH z3p*-x$~KCfS2r{>olUWbuOstMBu$Z@?y84oVB}zq~n$(pf75Z)b$gqCZg*QfFpq$6; zNn+I^)br>~ZPWt@aQ)zQQsx%hNC492q5o)#P)J2h?k!i14CH<9M7n}pGoLOmszh(At{SYW4@oKaYEYNMQD1>@8SVs4lkJOhGe0GK_P1()8XzN*yxoF!j4hV z?K9RN4q-+Q=90n4Dn!y!aXP#eRW^N@*$5Hafb?$wAw`Aoty=4{#MhwO_8#}MvQEUm zolV#VJneIOkz|KoPq-2_HHx1S7%oqXIub_^K{jgo!+FbJi1DrE%fmX_7(d7F(U&FT zqhaZt&-+6q@~CGf!?d9(sb}~f&ZXl|G*Av+f7ddfo>5AkneFU^40JA0XuQ|y&nxDr za1F$NhHZ1_#7Nb;QXXD!v=lOu5pQeYAYRE79nP*|A=_ZQdJiv-NMrHc4ETBD1PVrYJ`b#6)_d#z=FZ|73Bt zF~u*w-TZ)<4L7}~8F_iK4?Witle58%YU^@2%XT9BqGD1PP2Q#Hu`Q8Lr~(VLNhNFh zbBV#OpXs$F`z-axzm#g+Tg1S-aW5BU*D3h!%6H*tMp zAkai8H2hkF+E;D%ukYlW)OHNhijfi>Ei4XABkGI;R|YQUF-IbP*OnR!uO#y5y(ls| zoB~kRv*Q+bYoQI-jP%$f7yW2x?LpQX3Fl+qE6)e%w&mCHC(z=T!uuJjdJ=jkRpE5g z^ZsC@N>Y_wevy)uiGXerQjmh5S(us{t=Wb_o|+%5?UruEQ9FeP`XJ6{FRUX=XoC~p z&8OG9m$_L$yCm(_`IOn6^MivkGXGFUj^y&yAANaWDQciE7UT=a;m}A6EuogYx3fD{ z&yIl1N&BGDx54FY$A9Yy(vo z!2G3V%aHVjYSS9yR>nKLlz?A;6KGK3y<;r6F9P^rKjLrd!h#WGQGbO#l(1)o3$%X^ zJO+-%;rsL)_v+ZNIu9as*k(jDI;TU6iowS^KK@1KIu0LS>>kNe-dsh9egs zf$7*q?V{Temv;=xQRSm5E~Hp>ck6ncN(2XGadnnu2Cso$BR0~)n6MZDA64=wB&SPU zJEcA~O0&y>tJF7{1;HY1!1~rQP5Hi;^7DnpG91>**NEfuzc55Iw%T+~ZHx9p?9Pwj zeJ!qnq2sJJUiB!Ui4Ek1K0lAwdWx2V+oFsZTA4lOL6JPKA2;%>>0G4c7({NW_O2M1 zdxWD>qFE!2=>IlNd|>iIJvA{uL;HTP*G+47Ke<2+;ci=`pzMHN;G zY_sT=$C~4)+>YkR9_PP<{e?{Ir<5I#`yLxsgs=zROzkK@Ma=kpHzb3X+hbb3Y@%IN z_C0NxuVVuZ?vp;=Q2cNMG2WWDxg*icGy}u!i<d2deyLi5V?`Fz9elC}sCmYKdweO0pI{=#6N&f3nxkRG%QOhVD-optW zfQoT}w6cis^P>(gk7(mZ(|aJLNrJlb&NW(uTY6P0A9@ts9{}fD!}*^dqr=m$7}y6G z3A#HT{#Nj~i%g#W^-W#7^l#~wX%Uk{4^EfQDC34#nNuo%9xJsS4J2T%t}B=Kg)yYB zMNqn`v!O z&l<$Sas?8DS9)3~=NPs6Kxk(EBZMfa<~`eekM>r~dwMldtLF`!l6T*(!;_{o_&wQ_X=Hd&+|jW}qLRNUCFJ zoMxY+BdEXFj&5737%7QE!5aTTgA*&a*C?ZDo$h#Av~L{DCgcq?f_)U^VN2H%ZmN6w zUab<#fh!boUc@}jF1VYx;p9_aB~L2sWW!PTy4imCG{^i;Cr=D`a8Pom0K1W|*eX^W zx6ob-4)iW_E}6AnXmvb%rAqGdc;HhV*#xKt4H^3=ir*gYcF0vrI1Pq$nB|-~5vLOX zjuFa*sgaXU8o99O?t@4m+8TRpu4tlM21xJ8P6e>oAT~7GP1tKGFJbNu_3;(aYU!Y7 zDWl2$`tcKue7P93;7+~(2)(qYb+%6x&Y&JMG&Q0&ym*ERQppKLbz2yba$WrW>ZXd- zhB#?hsPu=3vc-zZDN(H5gdpVbDKTMPQ`0h5s!VxMX_a{RlbyYZUEKgKGFF-G{8!Ht z9ZR0+Pj_8i`6?@zFBx^9>W0**4Ta4G*(t> zjzKTt$2#3IV~p?W3PXs_HGsH5Zxe=xV+uJZ%|& zrN&6Sro=WdAciu5UED#WrQjoJS@>J4Wgo@4xhd^iQ-?t6kDlg39q6mDLRMc#l!-0c ztp}HSQ`v#6*?+5D5~uuG(H7g3{`-kWl~~Qn9rpBEt)`c6kK~`zPlJ@1?67&Ii~IdV z7v&RCc#GrI=zWs5EBFFqfhmR6!W|#U>hBA-zjsNu6&TQ~_=oYvZ>%>?)pFL;CN5sk zE={WfN(gsB`g09(T;CuBtiGxVNAg>&_aW1pph*3zJ@5)MY&I}!oT{;h z(BzydomyE|i;d0I@!fLS5c;pAhl7`A2MHOBq#bXM3(y&)oQ%qaabUkZostr-n74C^ zmqjZv%&aUuIUGB$Yqk)d>nz!t4;DTPVg>3Aq&*?@oW6&I)7Poitzichl?tZ(J@9{Ac$sSY5(+Z~pt zq_`%)TQgt%J2X!>;@jT#W?usL53&Z$LRVud6aYJ%eKOnmnTzMCAaPb;FILn)uZ*f-5X)T@i>)c|**b8RTLOtb6IiVZy z4-0|qsLkj3ATn6nP|3$YvWh+e{vN*vyo!R-A517+NT$ zLG`o2yWNp}k?!GxNXA+2kN&?0N&haf;4;R=!5{D?Q)-Fe6#NXO~|qL#3YR&a;9( zVn{c6w;pbL#9#>*#>(ZSa5I1HYsQWVCbPQ*{E`7C5jkbMr(`RPknSpYg|OLnc`4PP z^Jv&^8>O6aSt#~9j5KmAl!)O_Wo@s%3bwz**Z1r23t&f~*j@u${B}e2pg1MWY?QX7 zVipQ=qkT5bD!FCeMq0P%97HE_WCBOhKP2te>113>xAB8jj>%ZQJaAvEW#PXl*jKY6 zVvJoW*jVl@*%Y`rlSwNfZ|~*j<%dlVbh9CzfJwIEyps{e%rt0G+FbmY6&x6rIo$2E*_XRYpWGP_Sf(dyP4kkVRH7H$SY~6YlYEyB-X7rsQ&w{l!RJd1c7F=9#biL5P*t z7kk)w@RJy64XMam3>KC*J+Q>EbZfD&cG6n*9PZxCqv%iI@*eQu@G1o*247x0oab+i;6d$1Zv;+f?u5b_u$-Yt^R;iZWxR>VgA10Ma;u=oGx zdaU&SDc56WW&ZCZ?_aLR%FglMU;l4;IvXn+)BiZvQvp>%y6G$-771OTr#QD}7IT$^ z3|K-32D1ue=-{W2=aT>tHx~vmH%Ev|iId}tlT(n$;QC(v{=Vft-Dz}ex%J$6+d1{j zedRjrwlShCI0$p`vn-HTLkuHVgDW%9BZLJB92Wk!6adiGVgOyj{Q`sDWehUtKrl=E z14WkU?Z{C>%LVJ%*?^g$$}X?rg2I3a6dVxDIq1>J!N4Yej>AUA0GIQ5AVl;0$>q?Z z13UrUmgjJP(1RMGQC%l=CGmNs03hO%lTm+g;FS0W7$DG*L7DvwwD-ie!s*Mn=8$0p z`|5vwCHm=Z1BN}u{P}u%dJ5! zAP|GUvTtV3bi)zKcKhYfVWOY>3ce7@P4kcjaNxR%%jqJX2cdxT$wzf#{=wzUw73_* z!fk>$c5uDWp+GFkQT}q+y}ax0{qzv`<4WZ_2rx zK)|8~rZvCT+8$7fHG0fnvLXRJ{B=di2tzl*@&fIt0N`)YZ_=rAcM zpuqb%d~JABpiflo>Am1zt%wiMBg=T$XZ|k$ocrW`frv78Tk!aE&=)_SvKOUw*Fr?ECzFd%C&3s;unR90l?>Kfi6i zHnd`rvYLvUT4!wgz0wsGX1scNVQI{ALQ;QVg7}7p{1)1T@BW2))4y~#z4Aol2eTV} zzeY>^9QpnYzH)ur+q%qNKT9CLxrc-RU$2lMW?3=&d_TTMwy-H6gLb-czpZb+pN7Mzp`91!#iqQLg;z+j{YCAs?cwEf>r>oLT*IA zixq*v2c&|a$5%hEB!peeh(30rL?Eaq521cP7l5?gTtJ{~0-gju+)R9k5a?fctXoz6 zTXwSHXf=wx(soERxEV!+SAYcM^gXa*hpVgN5V#vWG z2LgWV9{qe|%wTtwxd{e*aY!3jkI>(+Vq-x3ZL62L-RuZQ`#0CmY<`#c5SIb|zlQ;p zutCqlzet3@AfSB=z5u@!s3+0=d!%oz8ForP8^1oZdv?6+F!bEvA=_Q28qT-Z^2Jb< zwPO!)1L(I6!$^Sfedbb)uaGF>6@8UeVeV7;5*E7P)1@S^KfuQrGmm}GA#B9+(c>f1 zrTnHY;-rO>(thRfmbW3fwUtV)jfwT)X%w{}*`8qOp`D1Vd#x7_CmtS?au~;pc<(Oe z@5-*J({Mu4v{+c9|0Z~gn|+B0_~ zr8Wr&_-=>!Zu)u40c(Ya;eNApQ$t-FY3^y&X={-1XJ8`lK+3BNP8hsk|N0G3qBK3x zh9i6}1{>$0(zS>aQ(i@h$GcQ6NV<9szK%~tsNB7ICDf=&3`novC)(}Y&4R)Gk0vfK z-tbG=l1!-V61t;mS|Tc+uiBe7<};%zBNgiPJGNHUk&)qSitKLmaHrnvC}->}u9-@e zwPJzf9WWIw6fn9V&s~5BIMhHN5#Zk%+iQptX7VP~*9sE~PZXC7XA>%$^%)i;dQgCFQD&Q{SAaky(7w@mT(* z^p1sxO4a+QO?5sF(oiw{2QTH$YVaDjD@?MD?S}CB*M9| zKm_hM+Gla(Z6&CH>%D`p*#%*3p+N`Xh)idOXP`m zgwb=0eC9aiao!>I5!GSiVsE#-o&cOWOSa(CW0UMb${F~QuO=eC`82IAWdq_Oz}rm1 z30)HWy4BNASf;X3CrL4T3Wp=}QBadTIc=sf2MbScU1ow>YOVYG`IFyyO7;6SL+a2O zzg`}neguV+IZnhtpZKk1m7UJxfEVQZww(48|8w|ig_s2Bp$K+0wwe_fTnpXkGE*`Z zWYxPY`%$LU3!2CBLD%%fKIyf_%6hwW{#K6gbgkYs?k=<7$(Vn}R=6U+(m~51ft=pZ z>%GlpJN2T;ILt7pq`IFZ3&p$tQx;Sw#t+hUIJ#M10;E6^Cw{dc(y>7FY$4lb>Zt*K z-57doRkTd#-cC~FgPEzxmlG%}i>o6!g@!EJ`>k+KJm8=OflY2i?%|+=v{KEEjpQgu zz}8hGD*BpKjkIUPgit+leC!`lHiZ)D7Y7=VOKz4m-KJ87B!(TOiP3`wyw}Y+2aWgy zYpc}Jx7+*TWgW?NEp3AwZ-p^A?cIk(m`nvE8~s&2R%{r+yS{?ot!75?6S3Ayh3l5h*_k?0J@p`*>;lt`sb&iTc^SOx?eP14C zn~YD<#QValfHDX}RXV78#^f|&*Y*|AsDw_- z_fY^2`)s-je(!7wPktXi-5D0{3AwdSd6=sE{)*|BgFDffK&KWO>aY2{aYKsUhcM)9 z<_)@SN#sG69?^D1W@7^@3n^fHkVhl)y^elIyANsWX?UN9gI@G1RWM7DvyhvRMI~Ex zXLU-XKHVvD{lobO5U-|30a`Jh{9^dh@{xJVst_C**!(`*8Axy9$__p?)kTVi%11|6 zjD_;JHN@0J&D0*U&4k|&h=~REh*g+O#v1`FNgCGniRv51o!2=N*4A)8*eJ7cP&G#* zm2MTw-9cIe9G98ye=&9rL7Fhpwk>wq zwr$&8wr$(>m2KO$x~j{zZQHhedvfEw!9TdeoM%Ly$aVH!8{5EX5`-_utK8uh!$u+-Z`7>nw*ljmJEKOdT%V>`8D%$aieoz0u9-o_8T zgjO(&V;bpIlDO|UDBWusDQ8BBL`91PbI&?W@vjA!7!heonig72?R7E5Jy}xprthbf z(~`sZec2@fQ6(d%RE6j#mld^itv_Y0Gi)Vq;{P0VIAsfKSs6NgsAdZ5gtGc4Fs05u zSyWL-9J`=Z*Pl7e4(~a@JE=(&)K7Ls>1C}FuUMD}d2^g56Rv<}03TaX+q7L#c4>Xo zg|xlYyyaY8sm%R*AZVsu==#zlw0?d~#BT<2$jGsdfp8*RTVv5;hDFox zGN13L5x9+fwAad8AI}-TO^X1|;sd#c;n~eUW$di+XV~60l*T$Y2caCwd3iWe&Hn6Y zDak!gUn%BW;|53`ce1ohu?K{h%Pu#o`bf?zDX%U(`!23()L`#5G}-#qTx!feQLEb( z*60p=3hbJPANv;9R}`5YiKcl`2cEi7G{-Bj}#E}cc$|4LDZ}NL=hl)z9W`I zS*fko?I=o4EWq-66IvFW+e-_g;Mx~(@{^-G&@4HJl(%v&HZa!{=BCi#xc`6@Env*Q zL?o4I%vp#0+r7>Ae}!(HS86+Kt!w#xU+fZ7O0Q7%HisHO{N?|XvJ_7J7`~o0gOiX= zZ3JywIU=PEZokncV`M=Cd^PRn(@)e?Ccr1k7U)m;*z3@qu_zlnpTijj95Fic(YKm+ zd)W*lOdfcbF~R+1C^5>dU*BD{WN_Q9kvybF{^zv)_g#_1+#ho7ZK1w?q~~+%uk!_= z4K=Byte4^&zIy-5-JW8^VwE%wt-!~Qb=(p9c!<;HS%Q*dU-Iv7jf5|VAa3c{#DuLQ zb~msbj@B}aw9Ik>0H_)|Kw%^nz$pG4Vaw0`0-PApm#mRcpnItKi3(7dCyC4|5QzfF z5(ZDOydfxEy#TX~kDsm+EhfNhOl!~G**%QSWD0+E??2`_&-Xy5Zx$Sz)iQ8Tr_nt^ z$GU%hpMkb+wS#Gk;5BBU;X*NpnpGD~MO|Pb)!=Pl?_kMsn$}-Avll?QZVW z7&5NiZF^XC%o#k0X+`s#n_53k!}#a14mjmh3^$RFjR!7juPKvkwCqe!73g~^sVrz{ zDC>9jyc=h*jIhM!hbPQg;NS46eeYJnd@IR{&+KBL80M+ZBb2k@-V(Q~WB(z=Le+pr z8g>J27Z%d!gC|9wkjC7qs5>MRDRB$RgzRx}=!&m+BrJ;WB-MI2s z=%-J2Zl=iUNCv5$-TupV3}&Mthb**UQr7%wq^0VsSg`4#dxMS!<^p2d-R;5W$(ymG z*Ya~DZl*bRik}qtjqC>*K_fYb08nZ7eUkq`DLdG+HZ(<&VW1HCHPM;1@1o!FUWvdW zWCHN~H%ApeG2Fdb^Eb9z){Yspi(qjq3f`@FhF?kCr1|0Kw#&)Sc{4!oZ=Ts8RDbN= z9!UKGU~68T6}FMASNGNE1W{CSLUT%$*_SlqU*G0f1(;D1B}nF{Z+w90{eAWbFp*W@ z&-*30i8m?bJ%)t)A;`aYE{hj@KJ=|v8RKI6j%;=H?Qt$elL8W>a=FJ%8yvLpO@_4I z+pTB5cVYZ5t7fM05;!fA1n*0s^~r&XX!WnZ+dfj5G}V)|+DZ-f#bZLL6BCS=AND8v zVS}r4v3sc8?tbnl_nS({#`}@>%E+<;Sy1`)qu|~~cYh&Q4v-+KCqVs<9R+@~1b7Ft zH9KpwWSXDd6q4+{r*ys%tq$rZez$m>YkEgs9jMkg1vdaUHaXMO9+BJG8}wu|m-=My zq}1J#heu2pw{T_Sp#42I5IzoE0Z%mUYnZKI$lE>gV zpBd4jYnjK|D5kKn4=VEV#awNX*+I&^=J|~RhRR1)l+M-|LEZN1A|+E|)}C~;$G9f2 zyzXVW#e<9Kyg5Zm4x7Qic(A~>ruJ}5!UItua99)E0!s$*l=sW|GnUg%wcQ_f# z!FqI_R(8q^oM{`B+vDX6wS2@zTN%|>2KGwzK=2TJ7-eVh=e{#J_AuAS@$p#J->E5N z{p35(uFfcR9fp-ELW}pJeL)xEVC<~L3iTp?XkXZV|qbp<{P`Y zp=${763(!hOp+hB;eB`krQ^~i7iq^a*KNZ-yBXa*Ba1By{degxWZ1IFT^!B{-KCT2 zRtb2lI!Db`1il#fSts9LELy7D2e3cPLJ~zY*j8#4bE347aU*{^aD@d<*xnu3xXz>UdQl<%K#0(}?6*Ie;hcm^!}tz-8?;k} z2HZZVvXWu_8`-OcU=rfAQgpw;M`@w?oMZ=ud2hE(*VE>;Lav`BcSPnA+-tAllNg9C zFPXmMn-j*{X5{X_K#=)|V#%^2oc~;94&E)C;qU-B09u!2z%ctL{I=qE93-F%>>3%u zt<1|v2Lfe=&KE&4>vq%nxu5B(Ku>;(WxsjA_U~>z)}Yt=j@i}BPeS6zxg&~cZ z9~oiFIVBahr+&mlrY2V^(U}7f!mp9-ymA6+!*6Z$DVJ+pj5%|xv`VmgbUVs@CTNpA zF(ejBG;Mou=F+wHfV1!N%l6$VwZqUt|4C$`z9dWW%Vax8^BkXaL9!jg=X2!{q-x?3 z40;YpAk5h}Kh(SI(|Z5HI_41PU;C;`GB~k2?ll&yX#K57aa4QUkh^3%E_aqpQRHn7 z1|lzzDqv8EsY2}9W`t5LJSoH2eM~byUe$klaNH+v`$sFdtihwonO#=R2&jo=bdU!{!!F z`&GYDRAUmd{`#d`0!79Bjx?NPj_{xZwk!-67Aj>{OP6v+l^A6GSJX{9IqxI0NfdaeYCUG2o zF#ZzCAw|{_W&;<|$0y8~9pNHn-S8fC5kARi1Ui@0Bq^+%0=IMG6Q$5NX`}@B>?Z!X zsT29D+{14d)d?oQm~$aaim1rzb5%Vk=C`$kc;uHlNl%`-?C?#3Aaki@HNxN9`}YJ-lV=6Hcq%UGZiyLr@oEzyhBb_biIjN=^AZxiM`|xyKoH& z>C!}}MMIv!y*UK@4S&W`{kvKEw=4^q53?w{sy)^`zi!>$U!jFUoj$}8!Vn`F3s!=! zI?ggSWYB81NI)CbJG{^}E?)DrZ^Yc1)?G+)HZwR z!8egopJ#FofyymedgFc$CYxs|B>qDb{Q#3IAB=V3z2V(#ICHBNU+>Dou*Z`~*_yc( zYDB>|lLLyCes1>#S0)(QkE;^PB%YG8#{-)o=?X$!M!8zdg~Tjgh%MN5PZu<2M@sX3 zu&@-XigeDT6cY%_v68a)BrlPSvtqm)mpD`tMp*Y6k0A|@fDF${eLZnKyTqqgnpKw}sd@L!i8n_cG?(patUKWbI_O+)R$U7Mu53{$v@6yutcmj6k#TcB z#6uzYPs)e9kYt)A>F()lUTae&GS(B$WAjj1Px+9H#kp*EJ9=B|MJB-LX%GCb&2%#X zMH-LoaO0_%4EvMx?vOBn0ztvZ?o4^>POc-hHDC@Ev#&aY2t!GVk|E{%qq6lBt#v?M zU9nQegTg;`|H2aOMO}c~)|SY1+nt~aF-jXDWm0meV+aavjO`{a#C$AvH|Y@M+DXxY zZOI^>VONvs>_Yw>v}~AR@QF*a7)33oA@@n8tVfrFsGegv$z#gWr?G)83Hun#jce2g z4mPQ_HQ8{qL;j3_>j|C^XTkn!+2Y$>gs-yi*%aZoA3U?e%sW2+l5%Gcu3|J@2T1ZR(h|1I?0Sc2<+O!rkbd$&FuPl(` zkIHy_y7tL^MKYh%mzjb$J=8pB?r7m$;7Q+`vr^C0F7bChn+~mHmewvG@k6pyT#MjZ zLhzsoUOl%>4jE`0r}dd7$S6fO=1ELVwMPJvzD{Y5(Oo~Qlmzog zR;0_e*=dnsAwJRpE`3xPlp5(cB_?FtpM=+`P-gLqBY6}Jrr)%F zB3HVwA!-^6IW6ozca)P}i(XNGq!AT(nlV^$25#4iAs-{0A7XXV%^l0;sFbd;qLusRuvUV+TO4Ccj-I@~Vp$xiX(j0C|XBfK;_ zFcDCM^Pi{6K0;bFC(ffMCr_Eedz(`BUeXsX?uPE5ANORpSqail>of$|H=Rdh0vvOW z#xqdka}}5;5VI>hn+1@VcsewsmQM8{j{|u+8HUUO4%tezTt)T z^@m@z5-Et{D26jtENUO=hHeuWmKGBC7J^4Y7HV@&FiR6E%y6=J*&0+Y2VOBEc52h2 z#&l#b9de3T$5=hERrKQ7D$M%|3xfQ4k@O~LCy;{xgl)@bz|aFPzip|@?-h*Dt(Mwh zxo1AO@}}*6ziI(naneTVFN%1K=~Ss^6vS|p&C_t6tP^%TGkdMR#4mQd?%LI`bxNLoU4eu$w9 zMC$m?L%_s4wJdiNvNWQROj1Fmz9Z=u0m*=ww&sweR1y?7luMM9*xdVENZvIMX#XLuU6* z(rl|FiSa=^-=~w6Hol7%cz_V;dyyJyZ~4nuSJ|b)itWn{syw%IZ!ybLdGLWeL`>LA zhFNkaAIPg0rga;`gyBx6eb9ZUb^~T^3oiLv)9<_Yrov+{0Doe(zObcmbpw%q_tX;+ z>Hvj;glJe>=4pz+)`?|r_B~#XXSUba3F2mUZqYxlBL*%@tg->$3tb2+NEjltLYzy729b=S%FkJe60z1sbC zhPl~u!%0R?wL?7?CJePuJiLM{DF_`UF6W>NFZRr{B%S_N~ysyOAwKP0>6z2 z&Z&HSN=#&;F9Jw31WL%5x{APA%zS!e;MN-`i12XW-=xK&q$L4@{*;K6PaKG6L~sh= z9({yBxmaKegYuwy`4ZvR8*1yJ9|K69OV$Ou);ttLKf!b zIHkmxU=WxjeT7--v-}poK#;(1 z;9z}<5;DA_FknGJxQzZg+7Q5tDX_qVumb|03I+)2JlJHxfqj0CsNX5SoF}ay!=dM= z;35T!!hNsg(T;(^ji{3hRj636288xF;|oq_h0h|Vnl%JrN00an0; z9PW(x%nREEjQ+@f^wfXW-v8X-Re1I9^?dRA0e=$+jKckT`3mYiT|C&=5G!sikl*7z{iQGg3+5Vb<7pWNV&PN2r#J>DYOZ~R{Rr(7z z)E}Er@vr_1JUKMvCj)`mV{c7*2Y86(nmq<8i{?*tRVWY%QID8{iVg_S{VmWNvLUL! zW(4S`C}RV3!24$^r=SL8z;9z=Ak5eRAn{^|x!U1K;9wz2SaZyAv;~M0{plSyLcvwI z(A(c%?4L!%s|y35EXh430c+Dc7dsq4sOO;IC{wZ|eauMowZ!Yw*2$P%;45Kwsi{0h z$aG#sLvuPTGoLxGw+*c1_|zLBm8YS(*psQEvGNd%_g6V_ue|PADDCMr8F9l(7rLta zh_slmzMsob;~+xJoH0`TF`6Z-^2{dW4K2e>$8t=0-QJ{YWX*T?6H!(0i=iot@V#&f z-cr-4)8W2_$t!h1U#p2R##nq7Z~nZw^8?%i3%@5^9-%*&XuoCJ=wiP+ZYo{9k9W)D zZ=Bve^CI!ktN`lLDxykrJI@{eG+)V^^71*!&OdC>QPP^9DkZdZ2|3-PbcxnTBYIAE zBPNFW)=E9;=0QohQm1rZ`7bfKt`c{aZJjkkB;*}UHc2=Aq%N{!Ow%B2@?6PWRYV$P zL0BJ4Mz^1KI@stydb%V1@>`N7l4ltu@Xy}HxV{Rl=~rn??am(*nv%qY?3PZqUSD~6 zG}4&8nww#`Qzs0j3qUHc*($%ZI6ZCXCvrsqV8PvdHzBGTe@hAF*t52q;M_#<2>+SM zDky|e=++zDJe!mBtRwP#^BE76lLS|+W(aw%+)?h4$%A6+U+FJeA+K7U05rHZ(oP+B#CK$a*{(_T?5MTng7GEf7>;T5vwm$Tru^a? z1$f_+d~Xa(4)}J5DE-?~<|S`(CU#%Ce)BqZtLk61j^O1GP^_o%ddDEc53>klU6*77Sna1`kKR8zo93Z){T+# zN027*@bj@>CoW};Qkw3m+?}I=%MkhF5JLUj>Q}bv7sXVN0UopsiFraA?YReh*pO;b zz^9@Ea*8vKpyQk{27(Y+QrZD3bM}s7GQBv!JgtfT7Ph7r>{vV6Y^SOoj=l2JNckGQ zP3#+34Y@$KMt~7%rqq?@dg-u=0LNt~nzH6$5<0>FpJhkeYTCwT#7Vt+s-=dk`d_Dl#-YgjJeuj#AUPSe&cvM`k6-EV}+FCKXrm zLW&%fMwHQuGOTeTYd}e{$Nnzlj>0@Q$KN6P+KI>9i9+g73pk7SwtN4X!G0fK()vO8 zU|%+TR<_wn=f@R%DjYE;UgB+>=4v~dRkZK(Cw9Zd_WZXITInSCGT(rGxl%KC6X=r5 zLSVq>*NF&BpPr;Lh!5`5<#Z`oJ2ZtW5A+1pwf6#2qFymeqZ7<8;__ZqxO&tf49~Is zW(XroCh`l{7hG*(VA$@^A;rC^_fDiI(iFk5F$R?E;y6eW)^L3tQk*xwGH!mi&HFg) zh7twWZ+GGjwbQ(ew!&=oMm{|EyHb041hVtdKTek&txCo#KTh{0g>dOddQx^F?$eP4pq2);Ocr>ogkTRO4>sN^4#Tpi)yQx3kR*lFJ=~aYCiLa$a{p=c z^7s(c#5(;7cEq}-_33~FC(`S-F}P`^+^i-%yrn;ahNihw(}w(lkBBhQ`0{AHtF5lx zG;`L?_!%T4c&hQ=Y8CAPCNbGvkqne6S7eAV!=P~K7`2e9nedeb&PUN*12Z*_VW(l= zuHetRxVJdV1l!E88>k%3{8@BKrvA6JB)CgyTC3&pwD+p-WoP?d+7 z<_);)>bhsi+UL52pF2f4?ZmN(vZ0herq|0Tur84Nm;-s5#Crw7)sm@tpn2m{w;c5x zra_eP-wCr*U$IyAguCiBk^SncKQf9rs_$mzJDDrAQOPuQ45GZUL1y)}9k4;?y_3|0 zLm|HEq~_sY#dd7+UYJmwlekID%g8)mlee+QEah)IHEV;O3*O8lDrcJVCY z)H_%@G{N?2F7<9qP;Kl;eJLWzCRbs0d7}}cGcQb{v%VyxFWDc<*Uu9R$`ryLw@33F~WXd=?#?K%6&O=suVuWh)s%SFVS#4Hu|{b z3!U%&%I(P4;_ruZ+P|r>aTXl)!DZgHY)R~T;RDLA+B*9oYxb-;64D}8v8!($pdNqu z!K`4r(#4e8H~w09rcvR?RhdZGe!a!~Ws@|oW%aP(#@bor_WPl-7kh$q5rVByd-QXZ zFtqj?3soys;ZkEW;OL5*Ky<{ZhN_=NQXvz_*pGR+i(nYoB)1FxPwgqYvcId6((o&u z{pQ65+$n8h*r&@K+n6Wv`j)}*^3Ty3^VdM)iyU>(qvVL>M}xgqy`99{mW?h)gqkKS z`n3>56X}!L?`>Kk=7%f(l*o$*%$#{o9eushZv>R!+`GNYP!84Kv_hcdmuZx2>ydl5wx&?>J zJ~qmeC!BQ-%2D3A>S9D6_{5tHWVc-+z6i@-NL&D|7Ol`8E(`_g8ymA{3n(wR{7Bl= z^Na;&tEZa@H91;Fcn#_KNdN(cnJo#s0U;7n_Ux7(=sJuIissa{E>>?iV`wuCXFun4 zoEhfuxHzd{^cS>xNcmpFOibS~uh)=@*j%i(ov3jJ7@WGW|i)tuOVd26P5Y=#Ifzt?u63*c0K_B!H3UALZ*#19g?LgyQ+}KmRPvA?`B%d?mbaF zGx5tkip4FZF`ax93@l$WzjHMMRHB>JPNjNfKn(kiTX~2Z#&e)1Ny|?5(w!ICv4@`U z;P%<+pLVLGW|he6$wBa(1hV-Lo)2;D=E}eGG#C4zmdQ5PBjj`R%>x@zrHUB9YZ_;O z+wQ0=(M!(QtYJF=R!BJBj%>*I53ID1H@*e38Ulman3jm~L~dHc2m~E%`8^V&V}O%7 zG*UT|I}OIJ5)rjr0W%_b#+Pj*r-wjS``#HXipSsC)W4ooBnN^Ih<_RJY?B){|Hb47 zrw`%C+|2TCNZBAge(7epISZ_J5QJ2#S6AptB79i_{{CS_qE)LmlIU8hm^5-j9&{uu zQCk&GIwcl=TonUWsLQyx@o89(mC?DZmhhRetZ%rst8qF$)_PVinTH-fdJd}};B2P2pYKh$1~ojY>uq$j?;aep+K??Z$7hhLPU7!+s{fJMTvqrv zfVz@2|2vcMYh=cIIK1#mv7k5bI6?bHSwC&w7xzkmU|I%zWzmc*WNc2g%hjZ)t8biR zQI9^DqH`~11;yB!j_4zja=YY%BSRZ)Wa+6u4yH9wVjs1sd(;%DCw1Jj%0hudsGBODCn#rqJEe zb!IFOCkCeHvr#5bgq1OvuWw*NCVij!s3FGuT7JJ9jK(P8&#bOf7d~XXF7}zv-D7o- zX|`cY=>5sF4woNwdLwnQVl&}r+Qt=)6#Ie;jmmh=R1Ijy;9uMC4QxQ2UbEQO_x%*C zhtlQt{2m8A`%`kbF%!(&2e>b^b7cpSljljCT_X>nM0(z?`lf{{ofu)pz<7+uKwrk+kx{BSx%uZGC6<*yti__OIjq5XIfLg2JQv>P% zLk3eT{6xuO|Mdt5c5EI~MltWD0zprhHGr?=cfw}GY60`7|4+lLEYEh{guIwrB?|(> z;+4e`Hu;-xa;Y!H$r}*|!PJsS6k-xiI7uVzflBs80%L%1MmY|j{q}76fu!@3-TJ-M zUfT^`?vj<)w8xK=*gbMHyGSaoAt8p2N_NIqpmAm|1jq{~O10}SFb(wo6Lwyvs z-Pw6FBHN;9Jn!YhzEw3oud=2V#=?NrVx91kM;500JH=f7x|W#rG~7M@1I)2n3R*h9 zuU6If)Z?aqm#P;jb7D`SZGSx|wPXoU^{yljnZFPwR)fpAX|~Q?$+ptHh7}a~aNm`_ z??zHxUg7p@A*)zEmF~~|T73z5Ly&~jfK-)Pk6#kNy(i(%kvlqH1<)J|{L?(bS!SiP zxEU<;wfJlIfqa%d4y{w=L{q5i(+idOUe0t5x`o9IHs=cX*^)NLo)z4>t$0{DB5wNZ zE1euCvK`{MTxr>`Zs_*ko~So9HI$6*nJu@b&xis3*>J=-T3A2+S0PKtp~&3wDr2Hk z%rg&tC0dSj?~dDW`%))#}=Xw}CeNP405|zs~f<2m?nt2){ zS|#wf{jOo&t=}Shb~Mm@1A?4d^u$##eql2@V8AE-#WvM^d~Mt7UntHG8QMD=BXAoF z8oi8@l2sdvy6T{|n9@^M^XWKIleu{s6)pA2sl9pzVC?gk0(^&5Ku+{iX<)!|2(>m$ z=aWxdcyWQV#y>MSbXp@Yzfm6h$hzU>KG!Y@RpsE!^AE#a>ujNPzj_)FX;@K6_`sG; z7E+d;$mPqiOWdP*5@z9+M96;bh&mo3wkBXU)|BwcMEBa8sP!0rWwYgC;p&@O|LBeGB^5 z#R$=cfKSZ+vtR{j9}%qrm>lk`aC4hV0g!7FS0q)(2KslM0tPCAb1UCHEftOBSUwZQ zDZFp1xVCiiu;_N_<;KIM=%*nJw_kgDcgi!1*!Y$N!5I_ z+5;q`!Gl{5H%(lT&eqdtv4uTL0EyfcZWMW4FvHtIKbr`=2=feI&#Chmmoo0Pagzy^ z3#QQ&6?MV+nCDi^c*#Gws&(c)u2PDzQ!zMaIV`JD0tt%EY%;S9(nufMV`bjb)%2Sv zbCCmgo|08@E+6LIIsEvK>))VA*1txw$UgoG3Q<{!?By1^ZgE>kj`b8~w2xa?i#uBto!wyQq@B@p?=H&D zLu+pm3t@0fdhUgY%kddlpu1_{-SE$|DVO1cMgHLK0hY8d*wPXKG6=L@aD)UrH&oU+L~0tT{t6(|?kad`HUlDZ>2QK)GyC3@|0Z39@* zwHcp4()sh|q`P3MG52e9^OH%cE2SE`QJGy_ofkSzRclg4(bq_+S-tzM4R!f#Xr>@k z)1yAz*DGx1K~5#s1YJ+d&KH8WPG^|0&OUc!K~0c1b{%z?YzDMh&xIP3tB4&}@2`Ne zuob0VE%7FPd@O)l+l7$$ZL~sj)h{c6l&J-U3tOtf&&OUY-w~lugqKsO--1#_D%c;X z_U9Dn*uMbTnho2}$he?k0!}^bZv!m#IW8(*Ijh3Ev0L)bO~uJii7rc~4{{7iM6bb2 zt;kOY6TzZrK6*`tx)p?J=jAsmlndQk*4!yyOjMp!-Gd6Mpoyds=uXI;RnW$?ndC-_ zLB@#Th4Gc^XBrepFR3?Yi0_z|_XPHaTdTa8P2_FyDrEFpl~EqmCe6pYvmG%mvjd{!Y#m`n_ja-lAqMuN#q!gZiqH;=!Y( zO{5pwc2(M8|Ia0BYU8|{srOQ5+7!Ps{EQnX=Tnkp&D89Dj%Pl*^TXAwTXctbMHT&> zwJ7fpJ>^Q4xsfH-?R6h!szTEMw?zXHUpy>NysEy<3(xnhC_cxZ+tjV48cWxWD zO2iTp2Wa2b`f;K?Rvrg#A)G!_Htr(k0M&!8r#x`PBdqVM-lN806cLS3wy?^&FT$f8 z#-NyuPEGDyx$OZ=weZw$3d%zl%LJ9q7I2Z9ppPm3p7>k?#vBwp`$Pi7h+L1fez|2! zi|u<_ouBg!_jz4@pB@4_;oVYW3GL|velF;=8)KFr%ttS%P2R^eRo%!m6{Zs}Gp(7D95gJ1VcH8~m zZB@!6E7y$jQuZ=+-uUu4lXkW}Q<-Nt%V?A>n#5^43?c$dA?v&1W zay_w;_w8;@5jr2Z7OIbI7bqJ-4UTp92aO?}p5uB0kc~CbeqTHqk{jELsw4<|zh zlt6|jH97a)aNrAylh?7ekQ$w@kkDgFli`9~406U@rQycV){DL6ON)E+RSHTu%((E7 zfIyr9!Hg_b4c*^&VrL7o#pK_xILcH!kP{O)qOPi)JS9lBHdtIQJ}t%f)V`gj30_%U z1N%!rvG!91dcm?lA1-7b?)uAX^P@(N?<5M7yS+{Mr!Ph}WeKGx7d8_uc@gx!is4t9x1 zmXd%X-r9nkr`jS4g#Ib_^847?;j+$YF#7}8K54&byZ&g`|JO3Di*IQijHUt%EPm(j z{x%3yf8H)e48+e5tjEvqOU%yBhdGY)jv+HxiXhtFkLXbMb3_;w9H?j^10OB?Q9-f` zgvKEbBmo43j1C$Res>4_`u2+dbrmic34GXl&1mh<%^(O49M+CpH%6S@70;;6gW5j1 zQwszSNdfeDnlL)>4+&aQP$K^V9soW!NXA=)(nSJs13M)qWTYIw_*XGIc%?vT&O|sn zFc5@sc{m;=xGv?y59Z#h;0A^Cm8}0 z3OpZJ91{#0AS&M4_oqMtsGU<#T@x<<3^wG)QSIa47V%cy9*9tH)^Gj`?TZEp_L~P2 zHh?fYyU&3Ea}(VF)HxW06>ZU7F}FMnh;j2hjbwEWEg%-6Bgin;fTnTaCMyUSdVU>< zF>_b{QHMw(on<^_1?~7XiuhI?+a>L2Z@C_lf`StFNb2#z*NKr7HPEi(A22h)+l54E zozaKD!Q5Ow#(=WsFyB??oE(CyqL`<*>EAl}alOzv%Q6#(SjmA~G?74GegEANhLm4j5jy@?^%|^uzoa zAtwpC1$({q4+i3m3l;=I6nG~h9!I$S0A&8K?%Ln?DAF-r)=u1gB`IRr1p)EC4*+j< z_IR}Zkio?EsD+~3-aunRHl`K;#rhT7k5ddn2nh)O?7-ae9R8Gk=xcuK&;Q)OP_=S# zf3rJ(HvbTq{Y9CayI_E5Ox{vBZBh`=PXqnlsrfZ4P*n}z6xzo1)uM_8E>;`Hx`|Hb zh#ybLkhe>Kdt3?h5Uge0r-0ZYApGuydWs#($f*Le2mSFhBqV-!_mu|M<%$ULs6K?o z_jiY!(zD`QR~;W-NaJUn-=w9SWfA-QO?wB3kO4P9I1FeO z_X~&}l60=N?jG1*jsGH`5_Ze#_c@t$U|nw)@n2^6(Pni=Kj8A|B9>E8P0FsL(ljaj6zo*4n~Uj*a<)92`=E0W(0;M94qIgt_a=~!g@P)g#v zYqpg!iBRz*MGp~PFSTfou^Q?)>;oIf$ zcR;{*idL!sNI1cFdLHn-BC}F3z*v8{Qj_9W)x7!L#D<{9B(;%lrQCL=cq1n;>K9C} zhIbqS1#Cj3@&4nBb&InPR}lJmmoy#xgwE%<+QzP3MD78~I?P z)WKU#!DDtHdqn9^JctghDE)*grff5!|DEwU8*G&s_1oT4P!4oUW6~r}g;DI*zi`8N zFv5~FN}8bBN!MSSl^Tyji9=o8HEFO9i1Uc+0%)uQ;Nxq~&T`X~VYXji{SO=2Qa(#N z)4IK5u$D@HR`1`_{Tjx+w%N2!}PPrGiXuS$yj~W4@j?aaf_~cOnNZ z?6d+SoRw0oI-1Is6=-NY_6{s*qyUBQc^UL4k=*FKop@7_7l?Tq&&}Ri>q8Ci7%TO7 zb;P_G078i6(ekq zlLyY-Lbtv2D<40d#Z!7jWnubL~Unv$H0zAkIPr7AtPUAqiyb&f(^c_$V?S; z4=e(Oe0R#6nS1QuO0&3xs}hN#iJxT#;hToZOoyX`s=`J=NfT>Hw3u5wr+&UMTvods)+WO{Qz) zK|m$w`T8UaZSwnYTxUspdk`TtnSLz6R^6o?cUv=3W!2d>W6+xBM?Bd}iy_1wLR(yu z&q~VHY*(UrGOWa%;=_&n_#TY!QRd^J{f)iRG`AoD$UGw_6 zq5EsIHmkK9CN%3QKewgB8O(4ahc3vARyi~-_=q6fo`vG3kq7CoGyY%&YZBa<=PYDB zB<#xNRay3A8rttxkaIxc;a z${e7|a0%tjMgG-@M#;0HM}KB|ZU5t0jZ#JH{ExRIr%b7LZhu}XU+x+s-Ugndikras zHKDWHPIH-RnrXP=EJ}Z3H!f#Cg}GB;sTZF2-uD(Fx<1x%Z|0V?BJjXSO0OT`htUyF zZ0cwC#g&a4$k+!C)_G89zv+Dt?IDzuxiHwqB{Sl+eP?t{zDR6b#A8YVcbr6HwEhJ> z)kw6YIPw82r6Pfo*sD7qu6FHsD~q3X$FriAhX}Fp@!$o=fi^?XLUSx5`98=Kx&`Hg zjk0+Rqi3Kr+nsGyUrnCC~H9 zJX9)p4VJ?^@D@jLIgV}5yS~g^j#Pw#Ge=StwI2^7*{kFUPIwM9CImUakCq-ma-Xu&~nshS4r+ci^_`W>eJH=IotwK$kw zpqBNV`FxeNV%u=vGB`$3Ouz45&l>EY7Ari^CfCt@G8rd(2JJHQ(RI?Xg{bY)f6w68 z(booT8XPUi)y{Uc=r$ z8)C4*gcF_2t#+y{AvT#=fA>2Key(}uen9I5sA%WQ*ghU zH;g5bhx-sDk{7uLsy6cX5BGPc@jTO$(Q5XJu>!{LtTwn0!`kJ@XP!m6IiS-VXvxoM zqanof(fEelw&1yMXqZe|pO-C0sRC~{o&W(=Dd?H3W`&!US;c?3}&!7)ju~Sj;P1o2+ zbvYiEZUFC*an`Em;LJy9t$01ETJzVqiHuVE_lGv;)1k1$I>Oy|H4Wdo1s?2cQbEzF zv2)rZCZ6`Y32bFL^rWAGa8{QQzTjuV??L`~)f)MB-IENFt?84C=EohwNmK|c){$NN zTlCl{fLvd?>}1t=nonfMD&YO_Gn|S&+4LgzrV(7*nMvg>rlUFHwhBv+8zJ>WzLS5x zwSA58rYBDZ`_wcPk95*Ryl8F6uv&Oeg)<`M+@OInRL4elV4p?6=BR1NLUm%*x%xFe zH+=Ipu)e{*7^h#cm-u>pw$$XHk}0}tt{T)Qa1~(H(b6x|bD&3$GqL5Tpk(1lghBMM z!(wQq?<{gk*rauT{^_J+VVn$GF6#T2s&!wjjL0>i>ot?)Ns7LGdcu5i=C?ls>#fL` z=Bm7B3nekYI&71G#~Isbm#JuH_x)fWHF8TVW9lZ=~|j(6!OhM_au?? zS)FQ0 zG00#dzi#$YXOm->?Ap_q3emkkjh|d@PF*)pY_uBmSK1rE@Hb5Miw$CJN3vE=eGh1iLG_qL0PR8P?xjxU{1$0{xmlV? zOYJ@&8?{C^Nd1*K(p5tqs}VhyIUq|76|2_Y==muaezq|8))9x2{EL?S%jnGez;2#J^U8eqcXGntHuY%qv{(fjO*`RNx_hOJ@rvt zrLgQtv~a;P@2&N`Lxyhi^-P?e-wekFlbL4mH}41L?l;S>DLj{)XuMS;VNNPa_Y&ta zCESLNVj2QI1xkUn?0Kbh*L+mH^W|yh2+=dc=E(Kq8?MeJ-P@$?-EU3@8p}kyeKp!I zR!r*l2<|ytROQ1muE)p(S^(8iudW8K=WmAaFrMkbz1e6QXHPU!y|7uVpY|S33y{ZJ zlVrGEeZmUvwf=2$XF`=)IL+sXDp&ZoXvZ+7#z*De(pi*pab4J=MKa|B(c|dSo3P4} z3!y2hKYV)=deF{ZJo!Z}#p2k#mZ2ye#3CQNy5c->q@H|F>r3r!&Q_(DkG>DN3n&zn zsq+)dtkrZf4yz{=vGO-De=+^8T~8rX4hs?tdi^Rk#VhLjib$qPo{Im6t#jBCMO&h5 z+O}=mwr$(CZQHha(zb2ewlnKiwW{&{V7FqA5o^VqaU-=S8;Uo4=6^b4Dco_GER=sg zbNMy9d$fa#T8C5k*xwW)X=b|OD$)MMcnRc$*GS6A4#k`a#M=sbTxZsDbugcewBBvp z);r#<<)+mpQYObF1ZJ(lbH1|SyTeVrVVtL9BR1&fH15F}cPmfq4xGgbl%#y_N%P(=)+N7<~ zs}7`+b1UGU5EsWUB${5tVD@9sX>HAcF1CSthNUz@+ZU`k=6%uzoGQ{3>7Hlk-0i;# zo6Lt-&RR-_&1V>Kvcjcn)*TlQ!l;70vc)p(?;4+&!Wb|=d|U;?w%B{HlXH9GP3#Nx zdsJ~=6=55zbtdO2%JW>oN|fIiPCf)eIy~T%@8i^Mwb{Uf3C;KV$;{{|SZ5M4*2h!` z#Da34ogf+Yn988tUW7T&teQxlH&}R%TO?F$oS)%$qqjt-b1+zT(J~F)d)p*??W)ke z4pJ+`;I;y(`pWec+8 z;Q&>|Gt;JEfr4u3j;dC{@lW$M^a(ixLQ^w=yV9tqGcQLc(1@TdxP%2?6C1v~HZ5c| zv=S>Abg<*vdw;3^JL$Mqy>;#C432#z=4$ey=4W-A2r|&=%NQb%Z9M0C!thS*Zly>?+AXznKKK_w5Q3=AO9x zEE6{6@}-X_=JUH7r123<6WRRl=9Lb$vzVz*b51t9N17Z7`x?VOr~JR5nM0eFh<3d! zy(INSCo#2{@B6e;&RSH8+^=9pkK`A}UD!#;8RlHtNg7@~c+5faK47huFy1ozi(^D} z=pcuh#Lw&g-y@D1>re|`Ex@!{G08Q~LKmTroLMoCB7=>bmPH7iKTHuv^X~YAYFT#V z9W5V@_tL57L(}lxM&covYCFb-x4Z z=u77=SgZd{Vt_F)jx~jW#sQHbh zpfNc1!Ywn#l-HGNuUbT}dKDuo>IYlh6^dyQcE_xgb;{n{&=e+|6q(AmcxNtAWr{?` z$SO}p-Dj@7iUsBad6(8^184rm=c99~cDX7~e)StoG7t63iC;>Saj7;JJ`%H2K9HQf zt6JUSmi40rM5^AQ(WN>S1zWu-J89dsE;_lmBWT5}@7;7f!;PcHS?xMMxvrrT4MWXp zXw3&veSUUEB5WzH&zf00MXXsSXx}9(jd-eQE<0{E0kaCGYtSVvh_!jA%V?zUW3t9= zToa@M&HVjh*gGwv?9=$Ob2ywEP1#;e&-*TH_7CPT&iuh2Wr?1S?y>K_j7R-Z^y|+A zq9)*)D~x)hU>{CjnOvZt96iUbb5C1Q5NyhN>D4cguGgSReRQ-vx8F=w`$&96t@*@> zpZK!v0n(7%u41{QSvKeL3R`O}s-m#R%(#F+(iBaxe%8vX#RgyE>8h#{flSEnOfN#S z1%WD=l35S)hKJmCby=AqH&Lb#)5oSA1cF0>SJTAHJ@tHDr`D8T@rLosu0pe8^Sh{|k|-_{r;x0QSQ-_MY;5wpz{liP4EahxD{Aeki3eTlI#j2+g~ zZX08y`9KwitcY|!a3FchVsY<^M$~q+7t_Ml1{b#Y5@88Ymh#x5H4{G0)|d~Q4(^>I z9DXpJ2!Qnv+|SW78sz*7BVJUt$Bjd*66nozzr0IErU*TpQk+qT!AvgFma7Kg6I7A6 zj;g21lnv6QDU6)PK`q&cu&0>@k*m}IVgF5}UN@51c{G!O6D|p%q#tagDOE&LdQO?z zsXc;j#VT>j2ahXOp_mV0wu}EXUGTW@Y0AEvdZa6t({b}%8&5dI$?V&8W#j%COEDrr#zr+PP^H|kwT5mGbLO1pR42)Hk^@Aa5jV|8EVdE_ME(q;d z>=1CN_}OV7gv4y}ih&42$AhG->>5{?Ez%KlNFyRR^Br3b8_K@d@v9Sk-|6rU8XtEI*O{4p|e@?6fF0&kG$0<3;B* zyd%zO^YoHupJ(0Or$w}9@&FW}c;%Qa-)9l98VQZE69N1%^EJ+{6-C`$~cj zp3+mY=rt<-*7UO(c$zA@yl=Djz+2OcfZB>GqSO&UeOBptl*8$+ae`y;^ny%t?j^mm zE!pW-tHB*i!15!q19fzO<1}BrABD}b>@RIeaaQ1XAu(Fm^lSR4=tjG5^N=-qIJ+Et z`eASPBntH{R5Xce%C;&MWM)L#oXhWVtC>xP;nI^j(}ICC$JGh5pvtw6UI!Y5Qw){z@l>QOW<^QJ04niEgX=1d!w1-=Z>xlts1j7y{IRe^chZ{d&pgg zX@8vY=B-HG=TS4ZSPZ`HB9@Fn08U2XP2jpARz1FSEoCD&_ZWttt+EK*bZmsKonj3a z1MYJELezBSUV|3ix0`1nOvWxTtZ{A%^Qw6&Gh{dz3U6HTH5>xS+EULwi8c7~01I$) zIH}KT9O_u$Q~5?3-Xcb4bkgaWUZBiZH;u(80G?AqhpoJ}C3Aw?5KB^xd8IgOPtDj;?pwd-P%Kj4g?K(GIi&awTEbdHIU z`TtAj7+ILv{-^(uk(G^|_5bB_Q1oJ!HZG=41oUDyhAyTerpERrrciu*P|hw+riQjq z9-FbRpb9w`tDsOvw^-eT?Ok16+yj;cj_%?6w;=A&at`k9@MsWr1FR02oX%#aK7abI z_O7Tq)?3YMUax-o6cVW`7$VcxvH?l2Zgem-G1J`ujG(TrXl4M+%-F=t%+x@jpnFSl1G{hpS609VhQJLDk4+8_Ow7OcQVLGnTpS(uO^uw~-OX8AUCsWvHzAZ1g0~0j z&;V8mm=`2t&%@kcp$_ey$4S<3KodjbpZ-Pt6)!~4#h)B2D|=&$8*{@W=!OR1 zoB)eZKtefpes~}R&(O;JMLfSgy79}qw?2bmVr=t>cW-_*3LuGy8t}k9)c4Mr%@v5F zlY^Nn$mZ{0@>x9HHI3wEX7t+HD!`3y9>V{L49*ECyXX35@_FS{dvm>W)BP7cE$C); z>Oarm>}s&s0LB>Z0f z*@bEGi~sHSCr1DufcNzE-UyKK_x}AO{pUM4eSKrY^9T9&6qT7WQgR}ya{gQN-KMOv zybHWP(+_80U}_BP(BKHj;mHBm`=@iGK73i`dxQ z@S!b{&`dH8Y*7Z|#MtufZ1n35d$(dM;3i<|Z9b1bhYbJ>&HVKD&{LmN`SQg)^6}I3 z>jJpPe(5it(!kup{$>24!N~zQDknFZ2Qhv3G%`5=cyH#pr^s9|mR}5OVDzuq-BTX0 zyZH$;V~d;c+p$!q27v5>U*=B`2Y{@@9|1i;^1yz02FyU|3;Ut_E9OtkX8Ue@^}v_z zSL374c(<19j{pxK`C>2PXvf^j{z>kuFO7elIr9g)2_PfjZ`irFm_PNeKJ*E`ulVX~ z{5$zkZuC1pkx-OjC=#`tJGZ2c9@T<`nw2N!+> z!CfPnX(g{{yt2tdI`8yU5qn6QGlnIGAX{0Or1u#2FJCJ>zn`HEXf*~WH}c`{-FXB5he16leAh`wF%WnzV8$?UpqBg z9<92MC_YMr*ZaL|4Mcw%Fh9khx<5;i0#Akek|fJPc5WGs{?g7_Xoe++v}z?R;c!cv zbbWR|3JZpce(MHE9B_fdCXKuAD5iQbFh=-a2ZuknPS5fgD$DR`aI2>?2T@+CnkXDa z^u@;NtVzB?XjPa_C$OK0$q(OFPm_YQy!I82`q7|v)NapY5MRk^FV_5@rSj*qZ;3YQt@(h-Q1`T(MR|_Aj`YikI+C*F3dS4>p zIW@l2g1I)^kf!QVNpM4PhHl{Yjzmqlr2LM>s{kGJCZF1IRJe@SGi3)#nbFWT{5vjl ziMp;_Ud#O^Hm1yO=AAP$v2mq!sblP>k(#Kxm^wzkUF%<@vakCH3r}wc8v{X3Mqc z>hDJN#+qqD#90t$Vzw~*>VS($c!FFiHpQrJ<2eUOWq&}gYdSUDxzG*MWE$a)b~F== z^zg{wHh^TDOrM9Eh`f2VFFlRP{fM&ZPtxo0#Yt~)_0xFLGqrP+T)2<k8X!E@&u&LKYr zJ{e{j9gKMGDO=E1_;^h))~nA8R6vpNf|UrpMS*c{FscIX!rOk6IAY?`E`H|UxIjA8=hy^CQB7}=tD{!1 z;F3$lR8`rz^-(-74g9c-CbXtA+mmlg2xVP3;6dUl=SYK9Bi{tFKw=-QIFl~Fg2Ntn zwvuCZ;i4xC4T>vYKVw>HVGTYLmRF8UsBTJ#1K9Ypq2{^Ck?W1_zMf(j*lyF@fR})8 z)7Sx2Oo!nPv?-Q>6jHfpYQNl55k0YXn)RnL8xJ{`7todmoHb#-Jgml8So+5DI6-_Ts@Pi`Ocj|}7eeI|Dj>EYkS4S#=dEH0} zt=Nv@U`m4BjSo^KzN++k!Jfdsp-V9=I-p0HbYLu$%5LD-=)Nv;*SA(u z*gyR4Xu;b$i-zNrRcNRGOk{R8MYmq_b;_c2wR0P?RbBWsO01aJ^^ZXHXNWa0*Id?N zYaDN`(K?B;;yip0F=|ZCDreI?pT-$4>7-tWcQZYvj<^W#REZ3UKIT@-XD*-l`oeqP zFPGK6ne~Lq*9A0c6@&KoNtnj8=!BFPh-e?W=v4#ACA5(aP(X ze`60s8&YfqCJ@zZttf&knQ;W^=cGWy+PUHpwbkZD))}{wM|S}=Ebhz}HZ>QTcTyQD z)vNW+)f&2k2BD*#JgH{V+6H_?uX2uI}kYv70GTm(JM04q8JwC)Cwkk)PBNv1B;Leh8O&YZqJy%W z0dpi)aVGd)DOuuSD`U9-*GbT7O+P;dXypvd?aD-x=&WSi&h-~g#Yo?XQ49Fy!6DDP z?CyvjI7q#%4FFEc)ZIdt>`8T370zbcqn!?<&L@&@vIP!(@vbU1cD{+3%zvaX(~S~A z7VptWs9z6WGGOM3HN1kF_~-@B&zmMxan$ZF){_&4QdzJhzDyet3TAG~d%HCe7I!bJ zW7Etn^PjF|m)X}>*fa4#eWb)74{cXD%0B8JW?-94V8>@Ny5Y-W~CRpn-w)h zBQ$=75y28o3^sNji6w~pQx^;-ricGzwGSSaRQ4^O#+CcJJe{|%ZTle3*4HgbUS1pV zlcxt(N_jWKaR++oz@KR3(asVbx;e>B0PY5z_Ri`}QU)Z!2lKVG52nPkELLF1qsr5n z&VhDd8tF&vk;&fdOW^}|l=zVStbcAf1^^tZQ51nTOAW!;Pwe_6o7Gd~!6Hakxw}Tu}4t7qz__i2rv>wRGeD$j|h7h^&@Ccf6^vr%z z_2ZOv!|bP{NPV%8IMBn(R44uZ4Mu!Re#=O_8qLOY;{cp!Tf~kkR%_k8Z%?1o@y$oe zy$%vWHI?ke?GuyLH~pSXu4($!ieCrtT`4tL$z6@q?`dh3UxTOy9oElrq*K>emWeK^ z^pKG6x!nn?P3T!(=*F2lw&S@my!e4NepOV<0~Lo*E_4)uNVZ{EDsd4iMGw6%s$SXt z=V`{bR@vALmbf=KN`Fd38z@{ZW~W7B)Wm;fCvdo^fGS zPHQ!&mFzI&x_4Oa|9JOZQR>X1Pvw@Kl6lN~FqUN}OqyA%M%O)UNp|M}OhGRX##}xD zk2ih_@{x;7B9Ecdq}?o?4o^7s#QPR&wQ{-yZ;>qG@yo% z@pSe1i7!Rg1L0G-@zzgSr3KMFOiF-I@waj&isI+a`7Z_jFRuksASTK^f%CF^RwDn)P9$Y2fFaiO4 zmSOip3Lp_+Bw@EER<3L*S0+1SMDyzWjHL1fx11majz>4A%%z~6La6C|8mMxZxVK;J z;q}IRH(2$2YUny=nv? z3-(pQ8XNvdaxALhD@ZIbV-DAPdNNw*1Kvz0)uLB2{I(TG0~SHtRuf0SI`H9XmCH;S z&?G?w``P5(CgiqAy*`?mjcqYdug_U>MO7j{-uztBYo(I(WpypIHJDE~?nT%Q-Omey z+_FZeyTaBIUx=2WbAXe!{C!3vG)4z~7nI_W$be_e_8%w>*WC@7DKLBh@`_@cfOL3} zW^m=xh~k_&yIejLJk(rmP8h@3tWLu?t);%lPpPhv#97jG(wr1=Q^;YD>Z?PeHCFe3 z06GQD(^8pgCcV6})|yUpF=;1*Vvn#cB=aCkRxGtR(1YCzD-I2)kH7@aD`4$L!#3MK z0FtGHw7$s`+2HDr89Bf~(o~pkA{D`}xOs}QV$~5-FxWwj>xuLaug;t@AH*j9`F{ z+!;`w?Ooek^4z(@BS{l@+KFQgq0epBFWL>X7# zEU(6bi4n19vq-_jseb)|2xpTwgSnS2U16Vh8$KdPy(E5@^}Bxt>dO$NV~eK#DW^CK z?>&Z!CaGEHuEo@lFZytghG$is;kGSs(khN9P>ClNHy?>YKVo7W9htZfh)UlBVdgkV%0_sf)(amP9z!c2w%B8q>uQGd~Xg1nGx@P zaMLsW^l58)3Wq!%WBqJs`vJrO_rPem4%x#sxV4)qd~YoB?ooD5cie`f63GwPVUbnd1#Ci7^?c z6el*ysrHxEGs#F;&7Tz&F<(y4M?l-CV^sGK+I)~aR@|)Fv7Pd%=6@)gi-+pvKv3Zu zG|9hoFUV8x!(iC!r-G*k_VxSkSEOG#ikl7~4LT-#y|NWb$y8$-$LMX0O87SMlR55( zKK5_?6rsG0jMzaDS0>t~olWHQA##|@mxrs~2thtidBzg*UeNN;VcsP%r8LH^IggXs zQRf#-F+lVk(UMJP2Q&t!`OFN*A9Iw=#)k#{el@@|@cu>YSTU8_qKkr;Q&$h_r7t%z zL#y8Bs;xNAFerxEz*RYYIT=uySQHw}6k78e^aZ{oH_)^Zdd%|Bqb$O^U&&O-I~NS@;0VNKo* zxUYlH*O)-d=xszkyDfU9b&61f<`oIoP$9v{K$_JJnY0XvQ``tltSPjZVQVzK2s%1J zBx6US+@m;Jd1eq~zY%Eb9{gE5hz^!XzCA_)MEuRQSM)qyzdkx7Kuv?6=?t5s8j2wBQER5|)eE2$wVTpivfN-G?!6cvc$9Nd^ z@>0UEkGJV8eoozMbDp7l_*0nv-=sa)#BbgE{f}GuA5$Q4_7S2SR>J+yE1iUYwfgJ~g z7JKBd6;zhywQ2CWEOg0HrgV$x(?Jxpj~3>jhUvv@>8NcoTy@l~DW)YXO0?AG0*>uB zsCL9jNva?{KzO)SYV2^EWZ*iCdLQ7%*(x(X;!nN1mW-g>G4)1B9DKK6ysVvAiW6wr z!RkRJlbO+F+KR@Dq_jvMCN-oM4puzF<|=Ukn(5Dn-Crg{rGEQhVOf$g@P1EvbW=hB zMavAE%xygtAx_y?MZ?Jmd$tu zNl3nJQcKbo$g21tQ$brQjiys{y2Z|RfjVaNv)McB}!3)JU z&Gh}g8>sjK0&NTjT_>K(dr2eWOx4RU(1c2ne>hSwoi?p!{ULKt(&69BRmE^js`R;F zdFb#MqiVk10z=&Br@c&)*sF9d`DiDKz_A1}W|!1Zx=#JMbV=n8N|$9KnVf?igX0dm zU4y_;L7l4A_|7mOmyif6&PRKGBnOc%Rbd>h^dZD@D1ZEqM+C7!6uFWA?Sp~~W@CkZ zlfPEWc=R-syWL-D{2h+U>Gpqd@|I7HotCc7xYmr?DDT2IA_usq^s*IXa} zf0DKTD7>~jIueyUI=%}IETFxQ?#stwpY8wJ-ko-6nOi&?*Cn<#)+_ShsSbU!-W{RJ z6TBRCZ@c+1N>$p}{fEIhIjfPnNsGA*M|Vo3m14xy5GU}e^-0p9@r?hQZ%43;{Hfh| z*Eh@xTiGmhyweq@@ml@z{24e_3S;G2A{QgXesb&oDZIrT;O8QWr{&scm;vi%BMutJ z=D|}Tve)vtZljin18hk`+ewLbJOd`#?VuOO{3iDq&*)h)T@v8ndOWZZx<@XOaLaHl z^;~0XIt<8OBL%z*&Fx%Y&#-q8Qaq^#V{cACgyDb=%Kcu;=k3MhiednmOYlPu>|{(* zMYPx+8L=>{e*9C+h50I6zz@~KMMgfl=m#(H9Ubnp|20zOtcJxo%f(R|kJeO<*NkqZ zZy6p~tVKj~i#c)V=RCPM%s8!CnLt~GKiKPP(oH&fbkm_A)w0Owza2U`eBVRDb72o> zw*J9-3w*37;~5%C5bhzo%wI;+-no_31He!x+DbnQnLMipDP_g2Yr160<<&QluC5>D z3G9WCf+JiQV~)A!g&zYhLh?XqkP1)hpm`MyvEGFi-MR8b;w|0d&~3xiWGU^(lNk+$ z=GT?3qQ!LW#QN03`E^D?jFX81G|ZrfTegeH^1Oto&3VGF>Cb`>Fsa&GpBC|Hc0REM!Nx@Uc2@JRamMG`@f zA{xP+qh6sS5*@&{O5LGV>-Hpm{rm4oycca7zD1eDCy#JZV~n*o-!*bE#Y>cCe`1fL z^&RW?H1M!1{2P0IT4mY<|uNqsjsuon&NZl_-0& zZL@H9VNPJZKlK|5xwy)SCv|AjTjAiY%?&80`E_kwrNuK3Kka$&SK;BC^Pqxa^9!?r zzE0v?!8sUNJzD+pH_Xw&fKx?6fhK7p@(_w!-8Kh)Zn6BPkO;)ooyv3KQAzYA)eBUz z?^tQ&XlV=vyq)<_0<%fyB`-@0mh-YTxPME%;}9IjW2B&P&cH+JE!liLMqxoKOTwYh zu_C2rIyGK%_%*>oG;FJK&Msw+uE!A}(n#7pu;o8#yJAM~z48R#V(+POZT21euHrY@XHwgX6wgo|eEx-KSn2*~X>e>LbCNC*2 zwEU3tZ{^Ja)X%vxgss%}G@+HRXoSVC3tr-G$J17%UQjC*oyb4}7_i&(?2Pj)8XQi0 zDp>-+R}?^|mWud3U5N(k($uo=nTWdagt>x54ss}x-g!sO zEYt3-L>mDa$M+`N7Go%5d$l{-)@v*zgW63|Fa-m+J#Y2!Yl*F1VBy<>&pE}+ujzd0 zrs6*NGQGCyv={Em*|rF;OFV9M`tKulb!@`d#G=A9Y~b&spzbmc5d4l211p9t(#P<@ z7m31F2W~zFFXSK^Lv4X!(nbNR&fJB{S?l^fdyJb=QyLRH7VdXCt&~e}wsIL8D@Uo* zzq7iYljz>|FS81nHfTSdCdaa~2mYmjQ1)_C1=4n}=#18#t^)dh0>NdzCu|ZGnFkpr zY#(*m>n^E+5Z*|Nka&B}#=|D%0vH#kd`U~?Q<}t)y+jAY_3n8>ju~n~yco=EI7keA zP~oy(u5Lpv{MzkSntE!NL$l^(q0zOa9plO(`#5_wi*#!OFVY5=Y?JkuV(LVcO^Dg( zLE6Pz#KpHZ%kF6uu|xFpux71L;fKyjy!b>PlPrBBzvTm8LAk{L+PbXIK7`b+noAc| zSwwIi_ItqH-9i(WwV*-m6ZJHQqX*EGWlVb~xUiK;5vz<(jff-Yv0$ZYYfU)w5AT66 z+?hq*3`hUn)V3mL1Dv-leEg>4>7+pPV0i^AKZTuakbM(V;w)T%#gEpGmA|foudyo< zF_f{?81OL?Gxpp!Z#{@USKYWiUbB}YYyZ<$&@s7$K^vK%;Eyx^n%6b!v{?tD8HH;Z z*A{Cqij`?5TK}(S=shF1FZ#-p;Noj?mC_qv#Ok>|V=Q=YVN< zei+a~OSpViJ_^XUNx!u4rbuXY_G!XKLh7DS^}OZARmfMa>$l0o9j?2Twa1INH6?OT z*`2VBJYm9*qfDJLOzD>{JwOzs6e28ot8-<-Z29ooi4-rvMQP?(Up71eHr$|yEgl& zGxu}-F(%mxc4?m*3}L7KQ;3do z>M#@cd*OCTE6OTqBvTMRdd!aW%olsMA3N|@xWuCBU)8AaY3{8vg^db5Ej4nmXr+w>g67$_MV3`@tz9Wx;cMPK*`9t1jVdTL6a-0gZy_ReE+5!orQXiG>R6U z#5Mh7eh9fegZGS1#7cvCgIR*Ep9zLEVRY9CP}N4s)?~3Ix^3luwl?Wk!v+ef$vHDg z*WiAwC1d!xJ=teethyhtB@7+t@ViiiI(E`cFqu=Ys2PM#9*rbkb_5XaALc-FR$ zZ;=0dRnYxOQWi=^+IN@Yg&wIJww4pTR3St%?My;55z)Wwri2}rixtD#EwS7tIN&3WDk9}_=menEVMdpqeu%NUMMMOE{7^m@Pu=DKG>D(fN}P$3CfSS)Kx z0MF|*D+Lb5P?QJht*}f4@;#5`JlSkOe=sTGvll#v&Hy}8|jU) z(AMMu(@H-D&G4Yf^+>AK3$-W{!NFP#Tj9(c{sd`NB1bWn3PvljUKb=lob+HIk5EFT zi8btV9*R>JOugf0yz+n;m940n7~3b@(m1Q22gi6TZ@~pkd+>o+EPEYYouaPDQ>IUq z=oZgR|3yFlx2~Z&-EKj8B9ti>LA;!FV-IIX=SZ@*sDvC6m2u)x-P-RvEU;_rJPA>9 z#-o2!?V%!RpYm zziSP`q9IL@3~UdL6Pr_X;f8S}G_Z?_-c&6KU55E+5A8E}?CE3ICV`2X7fqO*bC@;Z zri8}w0*vW=H(d=MZfDB?_3!4^jk1wpd1K4CJT_lo$_m#wRdw;gi>THY+na{5(afg| z&KyFU3>Ro@$J^XbM(yLUJZg!9Rd#cHZU%Nfazc(S&;%y*O8i&31hYYpI3+%9s*jTc zucE&pKNdG`sohSMDv#|r+4xP(-TAM-Qt!3MUKXWgHsdrW9>@esHyf_$zV_*Wj9r$0 zj4Ms|2^~30cZ@3Iv4yidj$#>W2WOv%i8Ju~?O0m*2 zT&yF^n#rCQc&@Cz(Q3CixjJPLu@KwDh_waLz)W7+vqG_YKLWUwHX)fQb4+U-6$?Hv zw*ykNc8sw)x{KmxmIj;_gS8L&&3#TH4)VljH5fxBK7;|Sa5ayJ%5*g~`Cr`F;Ce7-n=N#qvuMgz23m^#6OT=;X3Q~x#t>IHQsC%6diB2BNvON zPF|f)|H6(YCYPYbzy^T_k!RKW4QYtd`RH~VFKREce}Jn=w9ZQ(G1@N_ywFqWyxfs} zHlM9{1X4lJ<6PSrVARn)hr}EAIXTR+8p9fe`Q92oHGRC9+^U=GGK{Ua7u9;Ko4&HV zhq(p9K3$qQ%Qw* z6L~RkGK6UNB5hX+fw^WS0L>0^`Q;ovb(KLDJ@Y*v|B9eu%KfCwsrJ0Blc+#n65no7 z3_c1;5abN(pxPgFrnl_qij)bKZTAqJ?Jn=C8#~-Z&uCe7xNU)M5l6daUob283*%VDcFf6V#xaka9pPxM4*h@jx=$ z7hKC6*C8kQ`OMs`@Ut)RrL=|3PZ=zH@E-ZL4;+ABF#jEze=Z6?P~9!J#9dNoDHHZ} zplnz7&33j;zIc1+TH7#1?}}h2@OZw|bojEF=a$J{c&V^y_==4l*>xk-ZoIHaYT6Gv zJNg-#2l2TLi;w5P*YQBTRsGa3ZS_)Z#`?PYBdjfX!T!Js5}#~?O=o`B@Mm^r--fk< z;EtK@Fl2RfAr!SyiFmANJ!uG4@C-=4&A{h#^4)-1bQ*O9ink%5E+In%$~-(3yscb8 zo3~PsU*9VeoHvJ~T#Jn`piQkB**H}hxuc>=vCHX5h<#Mg&MjWh(#tyY`aCWeLJbo^ z;bTH7k9rLnhZ3wwJjO}?eg%@{-h<(lNQyu{3Hz&AR8_)r z!=i8d1>LwN@;s0#yCs=i?S8vz5mVyj_n}*l|;jsC5Ik@`j3p1)3_0d9Z;^^S%g@ZgJ)ACtAtT^r<1=t+zd+xksBPX;ECrAYLx_`t9N(%NwIWREXV z(8ZUly)&xHWe?OIW%JfA*Z+w8biocvkff4bqQ$>h`(tXtDJK1H#P%MspsnbdRcZe_ zie4F>)D7j)0-tLCW(mngiQ7CiYJ|a?N6h~h&>RLHcvnNJ+U3#`(}7L24-Mt#lOdd< zKRo5m?Va*Y&a0#n zGDT}+ZmU?}y?j5ZCpU~;Ww&ENux*C$)=5(RdSRy5$C_=t!`@}Gv~nJLISUi@p8ymDsk8hkLW%hSvq4v`3I%RO1=IFcu~1Sax10Cmx836RXguzJY+C2 zsj*5%I5AhQW?oh74E(&yfPAelCl+`(z$Jt``=h%1W(8%^ zTqp;TdMvWBNl5q2&%O^%$H*?3t-)oV>`!jVPc{2;@-lw6{~0yQ*fxYeM4o7a6vEYA z0UJmq31p;z`JIHUzhS3KY_|>vJ+0AJQw%TJFgVeXUaRymgnQmO_|eynHUT_cs5O12 zyo3lo*`oY=09Miy#OFSWAml@_Jzr-eqKTMM}wBIGR zP+T3Q;Q+qOkg)ve*q3;z`bzKBS$jjLrNXnOkDnPzoDQ3LA;&n4#GFJ& zD}pKlAE6e6zNx?!IB_@57o4~pI<$^oX@Lj#) zAGRaatu*O*xPi9b!MGD~E<Aa72O0X2|^w()Z_Z-Zdc z-KnyNThdDvDiUEW|8Hfmoo#G~8&sM1gk)-`03e$040L-R&w-q>5x6m1!qY z|B-W{xpD5Mf-l2zu@I>h2~L^2R0^Y&lozdjkPWfzp4#i@WvLJpkPx2w80UT^PbXG` zh;1m$-t0uP2W>Xj8whPQ$Uq!{&&RouPAfXNj0qRlq^T|#>`VqbvJRe6RiO5A`#kc; zqz^Hj8t!OP&{jsUIVpma;y^C;U?}2Q1(tv@96dTpMJTz#chrjwija_$8Q{A@zKoq1YASF@~klsT=?;uE*PC^e5I)oB> zktS87LjXmj7wOV_2}qZY0#X&}9YH`|?)%=Ixij~@xo_so?6&sV>#Y6HT6>@0Zz;*E zR92BjYEHxZgz7_TCPo_rIWH6E3dLdFo0|b~RauLN@@Qu1QedaViQlin1ifOX!xu&d z8mIP-P+y#REns+oryc@z?t(l zJ0^vPvC%D#R@@)Mp}5;++mctdBVY9yydn}`@KqMN_1j)WzPiiC*sfC^NmUqotY@1p zMy^g=8+(2-(D6es_-T>|Ja1(uDP4!0LPiP6&hx{CMmEsnO%IRu&HjlFr+CT7ILR5?A-~;rH zOdvl0d&gDD4%iBZh#Hs3ZFCMWw5#I-Gw|k9_13ORKnCRmpS_#@L<;bG#W%Qx;kGAD zoV83hvz17$Bls}pv07}<9CLt!Zb)+MDCZ;c*WKC|scEfO21AlT&6tScv%o)cXWLl? z<_v+81s@?XoOjPb!wdS}f41(l^}O_;Lp`^D$@c}{Vw364m^(eQ^qYp|fyurcbq7`9 z;^nOUCmAiYMw130yZPwyXw!IweAWX6>oXgf)`k3-`HcQK#SbsdzJnvIUOjZKoysm_4D2%(kKT{-b2{$gBDEj} z=+)#+Yg)c_`C^kXsM!WE6Cdm3sQ7&Q%>+W{82Z6>-3WIZ8M<#lHGC4_gU~l22V1hmpv2Ne;T=pOO1RGo`Wl}NXZltug*x9KOD0|_=~TO|J5HXUEkQ+ z(YNT{7zSDRG+bmw!f5h9&5`2-hR(W+S0yj-ta`mx0OP%^#PDf#e$yYV8c}IX{*z!p zP_KHlGyRVSH1XQ~VFfKk*xPr}H1C=1XsNHl=ku##?B8<6e+Nv!8Z;V!OH?0G+LOlfM{-`*9EslXzo-esyLmQDSWABnS=c=J>D8z- z0z3cfC=JUVrE>sNqdqe*a?=CmPWm7;bam+t#6HE%|E1XA%HepZ+M~j`w9XI(9-jY} z06DT-A(YSg)$p!`HsOA*(G4CBzp}wp7anuHhMsNP;JLh*8+2t%$GSjeUJh{jkrSDj z)*S*a{oi56eJN>m55m84wP>1RJ*xmJ9al?@1)dfr>bB)_)0N|;&#L2`b#lAWS6+;z zSTXId$+V^jH9az*c*gBMj}vgF^&Fz1mLJPQ$4hKv;#49zgZQ4k@r;SLaAlChc;w#zMbNuk@^%)HU;OOaNMD%)Wk>KYuDH#QuyZBO+Q7vhR2=L^4#+LR& zO~?A@F4DSw9h%2;tJ0Qwnj%Uf1NCfCKr)BCXw}XUiHfh z^&o;+Qc;Hs(MASmxmoSUr*G7(@7gW(0)%S|y?iqLKYP))eh2X<^HTq5AOadUxg;2N zf50RM=DV{%$}y7+I}Q`+7Zl+sm8v;ZT2Er4du*(YyQ_Mlgj@Qx=&)W#H@@5xwx(&T zJUK646Of(O;hC>=TTyQnMzz8(HI zVH2jVqB)Pgl&w`sPvz8pjM(n%i?c*73&qRLK-b3n+$pnS?uA{;S#0mo&x{U;QuB@_ zPEIOIaQggIIKSHYtAoO?*VP6&`if{;BrG^uhR_fWsl1cB!Ku;nJEa$b*X~Uz3&;Zxjgz zxo)@o(*1q=*H(RaQ^Y~9(YP@U zggz1m@^L`hgY5m>kRBdLTaX*V+6iHYsPWQg?e#4QJc;4}dXiwlYH3Goa6 zQ#G78?sGI8ypbTB9uR@2NGk_~D;LPg4S}}zL?S@m|1(>JAIuNt!lBSXNLL$_l_T-L z+D#v436Q{ZD@Q%F3$cI}NEnB3S9b95M1!CZ(SLGLgM>tJ#{PdI-1m%~P&oSgn|%v; z%TT58m)Kv5abvv6r%A3US_=hJ&l)&QO;jT;4Al40=W_?m1qK(fA%II-U)2~`~|pwxI=WHVNP9CC=1U7Z;Fn8wJLIVk-#vyO?6 z*H`n2DQ`AMz;IKYg7b-8S#!%s$3 zOuN5X7LZ2%C`%(6p)+Ny?8;RfBaQS=@ga@;DJFldn4We)D1zgQamSG zMm$sf(a4rmuH_gPiOtB}bqP!uEhzc5U%2XESDO+C%r|45DT_oqnZQgdMTD1#a7jKx zNbG0g-S|s?jCEq9f42u7nSTt==cUf^3$FD9 z4m+xTV0D1OMAh)1SW3X|<~zw>TK;F$<=dB7>^DQ*G!+X2EH?1d>)|6WukZ^78PL3X zKQQeqfTiGT#aj>MHC5&YXjU0jg@rV*8@4pYvK13VKDbb@523~Cf5Iu=Yl5_y4d866r(`LWf+IiirQeB1oCj8ulvDlI6|*MxLbOiuaSn{l|-vA;rfUmR_b31r*i!R{~vB z@<(e^fidNTa&_ZMziO{dU$wSKzWvL1W-p#_>6@iCB^))sXYIU1Keq(vPp>P<+7?hI z_9UD~<~V#c2W0rc3@=AM-STa~FlYTeyC>CN-E)n+Yii72tWYg36sW4%ibCJvp(PyQ zN}R6~PYB|7K>EICobdT=r{rz>!5eivi-B(zoZRh0`g#Kj8O`4Jtx$@Q)nX5thb$%H za}lMk;qCQ*qzh9ec%$|tE?Qxt8GF($Uv{LO6z3MCX7QF%EdUX1$pGCP4yAHfQ44ig zYD|8dGE)y1FGl6Lmpc4nhpm5&A<`N%Zo|9PMx6&H%cSVYdEaRWSDR;g8QQ zHM~@ZL_ikCF|RO!-ZHumY+sg49FHiG+T?{0j2Ho`%YG)B1RZY8?H7j~{40hiU%Fm_ zk5~%Iz8n5T(J2cPs`07u-f4HD5nJc5bUKIuU--yP_Lf97I?!^Q=J0#ePhA zD3aVRNh;AMp_y1-3V*dROpsnt0&1um0Hp@p>klt=R@^FNi<8^5S;_U9rc6`aH2y4= zS0ox-;7R2^AgNT-R;$jGFVP}5_O+uVomF+DY_`a;+!=XTR3+TLz}~P|>^j2Y?lPHZ zffv1>+QZi!JGQ{eq23j!%OuUH%I&gR5cSXx>bjBgb!|Sf)f*h9QbYD4d-{vb0Jb8f z&;KsEZdO;`W)_xjfPxD&RDRK~@P!st?@Y%iY*K2YnJ(GFKl)RJ=qIqXeS#m)T<}Kf zzYl8QtY;mciaZYU;x0;GP>)s5{;@`;gk(@1Ptlc?iVM?J%g;W)i;9(`w|N5ADgGTh z)E6+7XYUT1?U3m`;G%zBk*P$G#Uhl3epl`PCa)KtLwN_&Ny;!m#mGROv}G-m==YRv zMW5MLbBO2lu?GuLq)@95Gk5Yf9@leaPhVDcR#FB+vnMdM;w(pQGuW5djgR#c$~H+B z$DdMnA5|q^m$+Csn$`JhAstl>W7g9@mM+7xqPn9$!v-hL5%u4TT-NR|WZ8ZHm@_ij za0Ew1rLZ7FE&H6Rb;zwb&UmdZco)wXM`VD zi%N434f8DCi&}C@`rVQ&@ou^u@nsokK~BP6ZCw>NQFVIpv3D67{?Kp5eI|S2$1#)a z4~}clJA~ z7VMsHJxg1vxyHpk^BdtdGY6XJc1OHf4@S3l>kLBMNAd(g0B`~k_#M8x@UDST*A0MU zSHNY_a5wB~Pu4#Zh+coWI~CX48+B#Zb?T9=_qfJQ?I>!bj#ME7^%5OjcLA1NucC+o zUJd{lGj|Z~Is)5}$J968(JALc0b7SsuR=|fWjlTc`5U~-eyGK-iIDoP=PyDp-fz4n z%4hrCrmMKu4=Z~Fk3BDk>l9!TC=Rc(UN7-W1P8gD9ttb{QE$b%&~VT81S(?JTJ;$k z%Eij?GYG(Sl^{Wi2ftpfT}0~1}SGps6G&7TpLR$I&WXmgcq)O#H8Ywcop z1y0b&7Z110_sXEL*j3!eU+|_<77LW%d4_#l^7eTCq&I&(XlT^V&V&lkmTYch)$V?D z`Mrm$(6skyqq>G#>C)6Z#f#X{KCWaKDq>Ohtp83yoziUVCHIfF$XRY#+QAgmsM-4E z&nHc(8T1a$e11X3GS6S#|G+I1{>&g4&cD7FAp(5RRV|xI?cmi3;5VUMJf7f)iyX1Uv%yHW0KKNg$i-d$KX^r7T*X?x#D@Ct zm_BT8jv%`_nb#+yE%U4B(`7dymqxLs4rI3C!8MQnmTa-;Ipd#?4En>*0h7at@r{R_ zBToLmOoUnBv00o+Yc*fUpEAcmD+21D0ZFk}vyJ@pe4t}h+Uq8Uw6n+% znx$$B0fBLSx+oMHBnrmO*ZqgMEeiDCam+s&PeCS95Cy0*R7pq#q9iV_EGnb~ z0YgNTgds{oqEI2Iu%L(x=s%0#R?$GZ+Tr3HusHN@w;lAKnW-2*Yf6OS(Y;*tl#x|E zetAJ0b8YmLOT+nnQuBN1R5n2$Geb)f4L-#yd)9Hu<|@16oNgY~7cr@yf&*yk3GN88 zR^tU>!u?<&ZH3S=8fL;xH#|*yMZ(IJ$Hs2=r8(s&bUEb#=@pAUBUOsDhL+T`mQ)R( zaAJJ~y|*Q;W3^qOMU7G8z5J4(ol=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return valuemax?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.canvas.min.js b/flot/jquery.flot.canvas.min.js new file mode 100644 index 0000000..40c1051 --- /dev/null +++ b/flot/jquery.flot.canvas.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){var options={canvas:true};var render,getTextInfo,addText;var hasOwnProperty=Object.prototype.hasOwnProperty;function init(plot,classes){var Canvas=classes.Canvas;if(render==null){getTextInfo=Canvas.prototype.getTextInfo,addText=Canvas.prototype.addText,render=Canvas.prototype.render}Canvas.prototype.render=function(){if(!plot.getOptions().canvas){return render.call(this)}var context=this.context,cache=this._textCache;context.save();context.textBaseline="middle";for(var layerKey in cache){if(hasOwnProperty.call(cache,layerKey)){var layerCache=cache[layerKey];for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey],updateStyles=true;for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var info=styleCache[key],positions=info.positions,lines=info.lines;if(updateStyles){context.fillStyle=info.font.color;context.font=info.font.definition;updateStyles=false}for(var i=0,position;position=positions[i];i++){if(position.active){for(var j=0,line;line=position.lines[j];j++){context.fillText(lines[j].text,line[0],line[1])}}else{positions.splice(i--,1)}}if(positions.length==0){delete styleCache[key]}}}}}}}context.restore()};Canvas.prototype.getTextInfo=function(layer,text,font,angle,width){if(!plot.getOptions().canvas){return getTextInfo.call(this,layer,text,font,angle,width)}var textStyle,layerCache,styleCache,info;text=""+text;if(typeof font==="object"){textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px "+font.family}else{textStyle=font}layerCache=this._textCache[layer];if(layerCache==null){layerCache=this._textCache[layer]={}}styleCache=layerCache[textStyle];if(styleCache==null){styleCache=layerCache[textStyle]={}}info=styleCache[text];if(info==null){var context=this.context;if(typeof font!=="object"){var element=$("
 
").css("position","absolute").addClass(typeof font==="string"?font:null).appendTo(this.getTextLayer(layer));font={lineHeight:element.height(),style:element.css("font-style"),variant:element.css("font-variant"),weight:element.css("font-weight"),family:element.css("font-family"),color:element.css("color")};font.size=element.css("line-height",1).height();element.remove()}textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px "+font.family;info=styleCache[text]={width:0,height:0,positions:[],lines:[],font:{definition:textStyle,color:font.color}};context.save();context.font=textStyle;var lines=(text+"").replace(/
|\r\n|\r/g,"\n").split("\n");for(var i=0;iindex)index=categories[v];return index+1}function categoriesTickGenerator(axis){var res=[];for(var label in axis.categories){var v=axis.categories[label];if(v>=axis.min&&v<=axis.max)res.push([v,label])}res.sort(function(a,b){return a[0]-b[0]});return res}function setupCategoriesForAxis(series,axis,datapoints){if(series[axis].options.mode!="categories")return;if(!series[axis].categories){var c={},o=series[axis].options.categories||{};if($.isArray(o)){for(var i=0;iax[1].max||yax[0].max)continue;if(err[e].err=="y")if(x>ax[0].max||xax[1].max)continue;var drawUpper=true,drawLower=true;if(upper>minmax[1]){drawUpper=false;upper=minmax[1]}if(lower0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,w+w/2,minmax);ctx.strokeStyle="rgba(0,0,0,0.2)";drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,w/2,minmax)}ctx.strokeStyle=err[e].color?err[e].color:s.color;ctx.lineWidth=lw;drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,0,minmax)}}}}function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){y+=offset;upper+=offset;lower+=offset;if(err.err=="x"){if(upper>x+radius)drawPath(ctx,[[upper,y],[Math.max(x+radius,minmax[0]),y]]);else drawUpper=false;if(lowery+radius)drawPath(ctx,[[x,Math.max(y+radius,minmax[1])],[x,lower]]);else drawLower=false}radius=err.radius!=null?err.radius:radius;if(drawUpper){if(err.upperCap=="-"){if(err.err=="x")drawPath(ctx,[[upper,y-radius],[upper,y+radius]]);else drawPath(ctx,[[x-radius,upper],[x+radius,upper]])}else if($.isFunction(err.upperCap)){if(err.err=="x")err.upperCap(ctx,upper,y,radius);else err.upperCap(ctx,x,upper,radius)}}if(drawLower){if(err.lowerCap=="-"){if(err.err=="x")drawPath(ctx,[[lower,y-radius],[lower,y+radius]]);else drawPath(ctx,[[x-radius,lower],[x+radius,lower]])}else if($.isFunction(err.lowerCap)){if(err.err=="x")err.lowerCap(ctx,lower,y,radius);else err.lowerCap(ctx,x,lower,radius)}}}function drawPath(ctx,pts){ctx.beginPath();ctx.moveTo(pts[0][0],pts[0][1]);for(var p=1;p=allseries.length){return null}return allseries[s.fillBetween]}return null}function computeFillBottoms(plot,s,datapoints){if(s.fillBetween==null){return}var other=findBottomSeries(s,plot.getData());if(!other){return}var ps=datapoints.pointsize,points=datapoints.points,otherps=other.datapoints.pointsize,otherpoints=other.datapoints.points,newpoints=[],px,py,intery,qx,qy,bottom,withlines=s.lines.show,withbottom=ps>2&&datapoints.format[2].y,withsteps=withlines&&s.lines.steps,fromgap=true,i=0,j=0,l,m;while(true){if(i>=points.length){break}l=newpoints.length;if(points[i]==null){for(m=0;m=otherpoints.length){if(!withlines){for(m=0;mqx){if(withlines&&i>0&&points[i-ps]!=null){intery=py+(points[i-ps+1]-py)*(qx-px)/(points[i-ps]-px);newpoints.push(qx);newpoints.push(intery);for(m=2;m0&&otherpoints[j-otherps]!=null){bottom=qy+(otherpoints[j-otherps+1]-qy)*(px-qx)/(otherpoints[j-otherps]-qx)}i+=ps}fromgap=false;if(l!==newpoints.length&&withbottom){newpoints[l+2]=bottom}}if(withsteps&&l!==newpoints.length&&l>0&&newpoints[l]!==null&&newpoints[l]!==newpoints[l-ps]&&newpoints[l+1]!==newpoints[l-ps+1]){for(m=0;m").load(handler).error(handler).attr("src",url)})};function drawSeries(plot,ctx,series){var plotOffset=plot.getPlotOffset();if(!series.images||!series.images.show)return;var points=series.datapoints.points,ps=series.datapoints.pointsize;for(var i=0;ix2){tmp=x2;x2=x1;x1=tmp}if(y1>y2){tmp=y2;y2=y1;y1=tmp}if(series.images.anchor=="center"){tmp=.5*(x2-x1)/(img.width-1);x1-=tmp;x2+=tmp;tmp=.5*(y2-y1)/(img.height-1);y1-=tmp;y2+=tmp}if(x1==x2||y1==y2||x1>=xaxis.max||x2<=xaxis.min||y1>=yaxis.max||y2<=yaxis.min)continue;var sx1=0,sy1=0,sx2=img.width,sy2=img.height;if(x1xaxis.max){sx2+=(sx2-sx1)*(xaxis.max-x2)/(x2-x1);x2=xaxis.max}if(y1yaxis.max){sy1+=(sy1-sy2)*(yaxis.max-y2)/(y2-y1);y2=yaxis.max}x1=xaxis.p2c(x1);x2=xaxis.p2c(x2);y1=yaxis.p2c(y1);y2=yaxis.p2c(y2);if(x1>x2){tmp=x2;x2=x1;x1=tmp}if(y1>y2){tmp=y2;y2=y1;y1=tmp}tmp=ctx.globalAlpha;ctx.globalAlpha*=series.images.alpha;ctx.drawImage(img,sx1,sy1,sx2-sx1,sy2-sy1,x1+plotOffset.left,y1+plotOffset.top,x2-x1,y2-y1);ctx.globalAlpha=tmp}}function processRawData(plot,series,data,datapoints){if(!series.images.show)return;datapoints.format=[{required:true},{x:true,number:true,required:true},{y:true,number:true,required:true},{x:true,number:true,required:true},{y:true,number:true,required:true}]}function init(plot){plot.hooks.processRawData.push(processRawData);plot.hooks.drawSeries.push(drawSeries)}$.plot.plugins.push({init:init,options:options,name:"image",version:"1.1"})})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.js b/flot/jquery.flot.js deleted file mode 100644 index aa7e362..0000000 --- a/flot/jquery.flot.js +++ /dev/null @@ -1,3061 +0,0 @@ -/* Javascript plotting library for jQuery, version 0.8.1. - -Copyright (c) 2007-2013 IOLA and Ole Laursen. -Licensed under the MIT license. - -*/ - -// first an inline dependency, jquery.colorhelpers.js, we inline it here -// for convenience - -/* Plugin for jQuery for working with colors. - * - * Version 1.1. - * - * Inspiration from jQuery color animation plugin by John Resig. - * - * Released under the MIT license by Ole Laursen, October 2009. - * - * Examples: - * - * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() - * var c = $.color.extract($("#mydiv"), 'background-color'); - * console.log(c.r, c.g, c.b, c.a); - * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" - * - * Note that .scale() and .add() return the same modified object - * instead of making a new one. - * - * V. 1.1: Fix error handling so e.g. parsing an empty string does - * produce a color rather than just crashing. - */ -(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return KI?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); - -// the actual Flot code -(function($) { - - // Cache the prototype hasOwnProperty for faster access - - var hasOwnProperty = Object.prototype.hasOwnProperty; - - /////////////////////////////////////////////////////////////////////////// - // The Canvas object is a wrapper around an HTML5 tag. - // - // @constructor - // @param {string} cls List of classes to apply to the canvas. - // @param {element} container Element onto which to append the canvas. - // - // Requiring a container is a little iffy, but unfortunately canvas - // operations don't work unless the canvas is attached to the DOM. - - function Canvas(cls, container) { - - var element = container.children("." + cls)[0]; - - if (element == null) { - - element = document.createElement("canvas"); - element.className = cls; - - $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) - .appendTo(container); - - // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas - - if (!element.getContext) { - if (window.G_vmlCanvasManager) { - element = window.G_vmlCanvasManager.initElement(element); - } else { - throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); - } - } - } - - this.element = element; - - var context = this.context = element.getContext("2d"); - - // Determine the screen's ratio of physical to device-independent - // pixels. This is the ratio between the canvas width that the browser - // advertises and the number of pixels actually present in that space. - - // The iPhone 4, for example, has a device-independent width of 320px, - // but its screen is actually 640px wide. It therefore has a pixel - // ratio of 2, while most normal devices have a ratio of 1. - - var devicePixelRatio = window.devicePixelRatio || 1, - backingStoreRatio = - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || 1; - - this.pixelRatio = devicePixelRatio / backingStoreRatio; - - // Size the canvas to match the internal dimensions of its container - - this.resize(container.width(), container.height()); - - // Collection of HTML div layers for text overlaid onto the canvas - - this.textContainer = null; - this.text = {}; - - // Cache of text fragments and metrics, so we can avoid expensively - // re-calculating them when the plot is re-rendered in a loop. - - this._textCache = {}; - } - - // Resizes the canvas to the given dimensions. - // - // @param {number} width New width of the canvas, in pixels. - // @param {number} width New height of the canvas, in pixels. - - Canvas.prototype.resize = function(width, height) { - - if (width <= 0 || height <= 0) { - throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); - } - - var element = this.element, - context = this.context, - pixelRatio = this.pixelRatio; - - // Resize the canvas, increasing its density based on the display's - // pixel ratio; basically giving it more pixels without increasing the - // size of its element, to take advantage of the fact that retina - // displays have that many more pixels in the same advertised space. - - // Resizing should reset the state (excanvas seems to be buggy though) - - if (this.width != width) { - element.width = width * pixelRatio; - element.style.width = width + "px"; - this.width = width; - } - - if (this.height != height) { - element.height = height * pixelRatio; - element.style.height = height + "px"; - this.height = height; - } - - // Save the context, so we can reset in case we get replotted. The - // restore ensure that we're really back at the initial state, and - // should be safe even if we haven't saved the initial state yet. - - context.restore(); - context.save(); - - // Scale the coordinate space to match the display density; so even though we - // may have twice as many pixels, we still want lines and other drawing to - // appear at the same size; the extra pixels will just make them crisper. - - context.scale(pixelRatio, pixelRatio); - }; - - // Clears the entire canvas area, not including any overlaid HTML text - - Canvas.prototype.clear = function() { - this.context.clearRect(0, 0, this.width, this.height); - }; - - // Finishes rendering the canvas, including managing the text overlay. - - Canvas.prototype.render = function() { - - var cache = this._textCache; - - // For each text layer, add elements marked as active that haven't - // already been rendered, and remove those that are no longer active. - - for (var layerKey in cache) { - if (hasOwnProperty.call(cache, layerKey)) { - - var layer = this.getTextLayer(layerKey), - layerCache = cache[layerKey]; - - layer.hide(); - - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - - var positions = styleCache[key].positions; - - for (var i = 0, position; position = positions[i]; i++) { - if (position.active) { - if (!position.rendered) { - layer.append(position.element); - position.rendered = true; - } - } else { - positions.splice(i--, 1); - if (position.rendered) { - position.element.detach(); - } - } - } - - if (positions.length == 0) { - delete styleCache[key]; - } - } - } - } - } - - layer.show(); - } - } - }; - - // Creates (if necessary) and returns the text overlay container. - // - // @param {string} classes String of space-separated CSS classes used to - // uniquely identify the text layer. - // @return {object} The jQuery-wrapped text-layer div. - - Canvas.prototype.getTextLayer = function(classes) { - - var layer = this.text[classes]; - - // Create the text layer if it doesn't exist - - if (layer == null) { - - // Create the text layer container, if it doesn't exist - - if (this.textContainer == null) { - this.textContainer = $("
") - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0, - 'font-size': "smaller", - color: "#545454" - }) - .insertAfter(this.element); - } - - layer = this.text[classes] = $("
") - .addClass(classes) - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0 - }) - .appendTo(this.textContainer); - } - - return layer; - }; - - // Creates (if necessary) and returns a text info object. - // - // The object looks like this: - // - // { - // width: Width of the text's wrapper div. - // height: Height of the text's wrapper div. - // element: The jQuery-wrapped HTML div containing the text. - // positions: Array of positions at which this text is drawn. - // } - // - // The positions array contains objects that look like this: - // - // { - // active: Flag indicating whether the text should be visible. - // rendered: Flag indicating whether the text is currently visible. - // element: The jQuery-wrapped HTML div containing the text. - // x: X coordinate at which to draw the text. - // y: Y coordinate at which to draw the text. - // } - // - // Each position after the first receives a clone of the original element. - // - // The idea is that that the width, height, and general 'identity' of the - // text is constant no matter where it is placed; the placements are a - // secondary property. - // - // Canvas maintains a cache of recently-used text info objects; getTextInfo - // either returns the cached element or creates a new entry. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {string} text Text string to retrieve info for. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @return {object} a text info object. - - Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { - - var textStyle, layerCache, styleCache, info; - - // Cast the value to a string, in case we were given a number or such - - text = "" + text; - - // If the font is a font-spec object, generate a CSS font definition - - if (typeof font === "object") { - textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; - } else { - textStyle = font; - } - - // Retrieve (or create) the cache for the text's layer and styles - - layerCache = this._textCache[layer]; - - if (layerCache == null) { - layerCache = this._textCache[layer] = {}; - } - - styleCache = layerCache[textStyle]; - - if (styleCache == null) { - styleCache = layerCache[textStyle] = {}; - } - - info = styleCache[text]; - - // If we can't find a matching element in our cache, create a new one - - if (info == null) { - - var element = $("
").html(text) - .css({ - position: "absolute", - 'max-width': width, - top: -9999 - }) - .appendTo(this.getTextLayer(layer)); - - if (typeof font === "object") { - element.css({ - font: textStyle, - color: font.color - }); - } else if (typeof font === "string") { - element.addClass(font); - } - - info = styleCache[text] = { - width: element.outerWidth(true), - height: element.outerHeight(true), - element: element, - positions: [] - }; - - element.detach(); - } - - return info; - }; - - // Adds a text string to the canvas text overlay. - // - // The text isn't drawn immediately; it is marked as rendering, which will - // result in its addition to the canvas on the next render pass. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number} x X coordinate at which to draw the text. - // @param {number} y Y coordinate at which to draw the text. - // @param {string} text Text string to draw. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @param {string=} halign Horizontal alignment of the text; either "left", - // "center" or "right". - // @param {string=} valign Vertical alignment of the text; either "top", - // "middle" or "bottom". - - Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { - - var info = this.getTextInfo(layer, text, font, angle, width), - positions = info.positions; - - // Tweak the div's position to match the text's alignment - - if (halign == "center") { - x -= info.width / 2; - } else if (halign == "right") { - x -= info.width; - } - - if (valign == "middle") { - y -= info.height / 2; - } else if (valign == "bottom") { - y -= info.height; - } - - // Determine whether this text already exists at this position. - // If so, mark it for inclusion in the next render pass. - - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = true; - return; - } - } - - // If the text doesn't exist at this position, create a new entry - - // For the very first position we'll re-use the original element, - // while for subsequent ones we'll clone it. - - position = { - active: true, - rendered: false, - element: positions.length ? info.element.clone() : info.element, - x: x, - y: y - } - - positions.push(position); - - // Move the element to its final position within the container - - position.element.css({ - top: Math.round(y), - left: Math.round(x), - 'text-align': halign // In case the text wraps - }); - }; - - // Removes one or more text strings from the canvas text overlay. - // - // If no parameters are given, all text within the layer is removed. - // - // Note that the text is not immediately removed; it is simply marked as - // inactive, which will result in its removal on the next render pass. - // This avoids the performance penalty for 'clear and redraw' behavior, - // where we potentially get rid of all text on a layer, but will likely - // add back most or all of it later, as when redrawing axes, for example. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number=} x X coordinate of the text. - // @param {number=} y Y coordinate of the text. - // @param {string=} text Text string to remove. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which the text is rotated, in degrees. - // Angle is currently unused, it will be implemented in the future. - - Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { - if (text == null) { - var layerCache = this._textCache[layer]; - if (layerCache != null) { - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - var positions = styleCache[key].positions; - for (var i = 0, position; position = positions[i]; i++) { - position.active = false; - } - } - } - } - } - } - } else { - var positions = this.getTextInfo(layer, text, font, angle).positions; - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = false; - } - } - } - }; - - /////////////////////////////////////////////////////////////////////////// - // The top-level container for the entire plot. - - function Plot(placeholder, data_, options_, plugins) { - // data is on the form: - // [ series1, series2 ... ] - // where series is either just the data as [ [x1, y1], [x2, y2], ... ] - // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } - - var series = [], - options = { - // the color theme used for graphs - colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], - legend: { - show: true, - noColumns: 1, // number of colums in legend table - labelFormatter: null, // fn: string -> string - labelBoxBorderColor: "#ccc", // border color for the little label boxes - container: null, // container (as jQuery object) to put legend in, null means default on top of graph - position: "ne", // position of default legend container within plot - margin: 5, // distance from grid edge to default legend container within plot - backgroundColor: null, // null means auto-detect - backgroundOpacity: 0.85, // set to 0 to avoid background - sorted: null // default to no legend sorting - }, - xaxis: { - show: null, // null = auto-detect, true = always, false = never - position: "bottom", // or "top" - mode: null, // null or "time" - font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } - color: null, // base color, labels, ticks - tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" - transform: null, // null or f: number -> number to transform axis - inverseTransform: null, // if transform is set, this should be the inverse function - min: null, // min. value to show, null means set automatically - max: null, // max. value to show, null means set automatically - autoscaleMargin: null, // margin in % to add if auto-setting min/max - ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks - tickFormatter: null, // fn: number -> string - labelWidth: null, // size of tick labels in pixels - labelHeight: null, - reserveSpace: null, // whether to reserve space even if axis isn't shown - tickLength: null, // size in pixels of ticks, or "full" for whole line - alignTicksWithAxis: null, // axis number or null for no sync - tickDecimals: null, // no. of decimals, null means auto - tickSize: null, // number or [number, "unit"] - minTickSize: null // number or [number, "unit"] - }, - yaxis: { - autoscaleMargin: 0.02, - position: "left" // or "right" - }, - xaxes: [], - yaxes: [], - series: { - points: { - show: false, - radius: 3, - lineWidth: 2, // in pixels - fill: true, - fillColor: "#ffffff", - symbol: "circle" // or callback - }, - lines: { - // we don't put in show: false so we can see - // whether lines were actively disabled - lineWidth: 2, // in pixels - fill: false, - fillColor: null, - steps: false - // Omit 'zero', so we can later default its value to - // match that of the 'fill' option. - }, - bars: { - show: false, - lineWidth: 2, // in pixels - barWidth: 1, // in units of the x axis - fill: true, - fillColor: null, - align: "left", // "left", "right", or "center" - horizontal: false, - zero: true - }, - shadowSize: 3, - highlightColor: null - }, - grid: { - show: true, - aboveData: false, - color: "#545454", // primary color used for outline and labels - backgroundColor: null, // null for transparent, else color - borderColor: null, // set if different from the grid color - tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" - margin: 0, // distance from the canvas edge to the grid - labelMargin: 5, // in pixels - axisMargin: 8, // in pixels - borderWidth: 2, // in pixels - minBorderMargin: null, // in pixels, null means taken from points radius - markings: null, // array of ranges or fn: axes -> array of ranges - markingsColor: "#f4f4f4", - markingsLineWidth: 2, - // interactive stuff - clickable: false, - hoverable: false, - autoHighlight: true, // highlight in case mouse is near - mouseActiveRadius: 10 // how far the mouse can be away to activate an item - }, - interaction: { - redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow - }, - hooks: {} - }, - surface = null, // the canvas for the plot itself - overlay = null, // canvas for interactive stuff on top of plot - eventHolder = null, // jQuery object that events should be bound to - ctx = null, octx = null, - xaxes = [], yaxes = [], - plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, - plotWidth = 0, plotHeight = 0, - hooks = { - processOptions: [], - processRawData: [], - processDatapoints: [], - processOffset: [], - drawBackground: [], - drawSeries: [], - draw: [], - bindEvents: [], - drawOverlay: [], - shutdown: [] - }, - plot = this; - - // public functions - plot.setData = setData; - plot.setupGrid = setupGrid; - plot.draw = draw; - plot.getPlaceholder = function() { return placeholder; }; - plot.getCanvas = function() { return surface.element; }; - plot.getPlotOffset = function() { return plotOffset; }; - plot.width = function () { return plotWidth; }; - plot.height = function () { return plotHeight; }; - plot.offset = function () { - var o = eventHolder.offset(); - o.left += plotOffset.left; - o.top += plotOffset.top; - return o; - }; - plot.getData = function () { return series; }; - plot.getAxes = function () { - var res = {}, i; - $.each(xaxes.concat(yaxes), function (_, axis) { - if (axis) - res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; - }); - return res; - }; - plot.getXAxes = function () { return xaxes; }; - plot.getYAxes = function () { return yaxes; }; - plot.c2p = canvasToAxisCoords; - plot.p2c = axisToCanvasCoords; - plot.getOptions = function () { return options; }; - plot.highlight = highlight; - plot.unhighlight = unhighlight; - plot.triggerRedrawOverlay = triggerRedrawOverlay; - plot.pointOffset = function(point) { - return { - left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), - top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) - }; - }; - plot.shutdown = shutdown; - plot.resize = function () { - var width = placeholder.width(), - height = placeholder.height(); - surface.resize(width, height); - overlay.resize(width, height); - }; - - // public attributes - plot.hooks = hooks; - - // initialize - initPlugins(plot); - parseOptions(options_); - setupCanvases(); - setData(data_); - setupGrid(); - draw(); - bindEvents(); - - - function executeHooks(hook, args) { - args = [plot].concat(args); - for (var i = 0; i < hook.length; ++i) - hook[i].apply(this, args); - } - - function initPlugins() { - - // References to key classes, allowing plugins to modify them - - var classes = { - Canvas: Canvas - }; - - for (var i = 0; i < plugins.length; ++i) { - var p = plugins[i]; - p.init(plot, classes); - if (p.options) - $.extend(true, options, p.options); - } - } - - function parseOptions(opts) { - - $.extend(true, options, opts); - - // $.extend merges arrays, rather than replacing them. When less - // colors are provided than the size of the default palette, we - // end up with those colors plus the remaining defaults, which is - // not expected behavior; avoid it by replacing them here. - - if (opts && opts.colors) { - options.colors = opts.colors; - } - - if (options.xaxis.color == null) - options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - if (options.yaxis.color == null) - options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility - options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; - if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility - options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; - - if (options.grid.borderColor == null) - options.grid.borderColor = options.grid.color; - if (options.grid.tickColor == null) - options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - // Fill in defaults for axis options, including any unspecified - // font-spec fields, if a font-spec was provided. - - // If no x/y axis options were provided, create one of each anyway, - // since the rest of the code assumes that they exist. - - var i, axisOptions, axisCount, - fontDefaults = { - style: placeholder.css("font-style"), - size: Math.round(0.8 * (+placeholder.css("font-size").replace("px", "") || 13)), - variant: placeholder.css("font-variant"), - weight: placeholder.css("font-weight"), - family: placeholder.css("font-family") - }; - - fontDefaults.lineHeight = fontDefaults.size * 1.15; - - axisCount = options.xaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.xaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.xaxis, axisOptions); - options.xaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - } - } - - axisCount = options.yaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.yaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.yaxis, axisOptions); - options.yaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - } - } - - // backwards compatibility, to be removed in future - if (options.xaxis.noTicks && options.xaxis.ticks == null) - options.xaxis.ticks = options.xaxis.noTicks; - if (options.yaxis.noTicks && options.yaxis.ticks == null) - options.yaxis.ticks = options.yaxis.noTicks; - if (options.x2axis) { - options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); - options.xaxes[1].position = "top"; - } - if (options.y2axis) { - options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); - options.yaxes[1].position = "right"; - } - if (options.grid.coloredAreas) - options.grid.markings = options.grid.coloredAreas; - if (options.grid.coloredAreasColor) - options.grid.markingsColor = options.grid.coloredAreasColor; - if (options.lines) - $.extend(true, options.series.lines, options.lines); - if (options.points) - $.extend(true, options.series.points, options.points); - if (options.bars) - $.extend(true, options.series.bars, options.bars); - if (options.shadowSize != null) - options.series.shadowSize = options.shadowSize; - if (options.highlightColor != null) - options.series.highlightColor = options.highlightColor; - - // save options on axes for future reference - for (i = 0; i < options.xaxes.length; ++i) - getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; - for (i = 0; i < options.yaxes.length; ++i) - getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; - - // add hooks from options - for (var n in hooks) - if (options.hooks[n] && options.hooks[n].length) - hooks[n] = hooks[n].concat(options.hooks[n]); - - executeHooks(hooks.processOptions, [options]); - } - - function setData(d) { - series = parseData(d); - fillInSeriesOptions(); - processData(); - } - - function parseData(d) { - var res = []; - for (var i = 0; i < d.length; ++i) { - var s = $.extend(true, {}, options.series); - - if (d[i].data != null) { - s.data = d[i].data; // move the data instead of deep-copy - delete d[i].data; - - $.extend(true, s, d[i]); - - d[i].data = s.data; - } - else - s.data = d[i]; - res.push(s); - } - - return res; - } - - function axisNumber(obj, coord) { - var a = obj[coord + "axis"]; - if (typeof a == "object") // if we got a real axis, extract number - a = a.n; - if (typeof a != "number") - a = 1; // default to first axis - return a; - } - - function allAxes() { - // return flat array without annoying null entries - return $.grep(xaxes.concat(yaxes), function (a) { return a; }); - } - - function canvasToAxisCoords(pos) { - // return an object with x/y corresponding to all used axes - var res = {}, i, axis; - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) - res["x" + axis.n] = axis.c2p(pos.left); - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) - res["y" + axis.n] = axis.c2p(pos.top); - } - - if (res.x1 !== undefined) - res.x = res.x1; - if (res.y1 !== undefined) - res.y = res.y1; - - return res; - } - - function axisToCanvasCoords(pos) { - // get canvas coords from the first pair of x/y found in pos - var res = {}, i, axis, key; - - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) { - key = "x" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "x"; - - if (pos[key] != null) { - res.left = axis.p2c(pos[key]); - break; - } - } - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) { - key = "y" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "y"; - - if (pos[key] != null) { - res.top = axis.p2c(pos[key]); - break; - } - } - } - - return res; - } - - function getOrCreateAxis(axes, number) { - if (!axes[number - 1]) - axes[number - 1] = { - n: number, // save the number for future reference - direction: axes == xaxes ? "x" : "y", - options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) - }; - - return axes[number - 1]; - } - - function fillInSeriesOptions() { - - var neededColors = series.length, maxIndex = -1, i; - - // Subtract the number of series that already have fixed colors or - // color indexes from the number that we still need to generate. - - for (i = 0; i < series.length; ++i) { - var sc = series[i].color; - if (sc != null) { - neededColors--; - if (typeof sc == "number" && sc > maxIndex) { - maxIndex = sc; - } - } - } - - // If any of the series have fixed color indexes, then we need to - // generate at least as many colors as the highest index. - - if (neededColors <= maxIndex) { - neededColors = maxIndex + 1; - } - - // Generate all the colors, using first the option colors and then - // variations on those colors once they're exhausted. - - var c, colors = [], colorPool = options.colors, - colorPoolSize = colorPool.length, variation = 0; - - for (i = 0; i < neededColors; i++) { - - c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); - - // Each time we exhaust the colors in the pool we adjust - // a scaling factor used to produce more variations on - // those colors. The factor alternates negative/positive - // to produce lighter/darker colors. - - // Reset the variation after every few cycles, or else - // it will end up producing only white or black colors. - - if (i % colorPoolSize == 0 && i) { - if (variation >= 0) { - if (variation < 0.5) { - variation = -variation - 0.2; - } else variation = 0; - } else variation = -variation; - } - - colors[i] = c.scale('rgb', 1 + variation); - } - - // Finalize the series options, filling in their colors - - var colori = 0, s; - for (i = 0; i < series.length; ++i) { - s = series[i]; - - // assign colors - if (s.color == null) { - s.color = colors[colori].toString(); - ++colori; - } - else if (typeof s.color == "number") - s.color = colors[s.color].toString(); - - // turn on lines automatically in case nothing is set - if (s.lines.show == null) { - var v, show = true; - for (v in s) - if (s[v] && s[v].show) { - show = false; - break; - } - if (show) - s.lines.show = true; - } - - // If nothing was provided for lines.zero, default it to match - // lines.fill, since areas by default should extend to zero. - - if (s.lines.zero == null) { - s.lines.zero = !!s.lines.fill; - } - - // setup axes - s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); - s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); - } - } - - function processData() { - var topSentry = Number.POSITIVE_INFINITY, - bottomSentry = Number.NEGATIVE_INFINITY, - fakeInfinity = Number.MAX_VALUE, - i, j, k, m, length, - s, points, ps, x, y, axis, val, f, p, - data, format; - - function updateAxis(axis, min, max) { - if (min < axis.datamin && min != -fakeInfinity) - axis.datamin = min; - if (max > axis.datamax && max != fakeInfinity) - axis.datamax = max; - } - - $.each(allAxes(), function (_, axis) { - // init axis - axis.datamin = topSentry; - axis.datamax = bottomSentry; - axis.used = false; - }); - - for (i = 0; i < series.length; ++i) { - s = series[i]; - s.datapoints = { points: [] }; - - executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); - } - - // first pass: clean and copy data - for (i = 0; i < series.length; ++i) { - s = series[i]; - - data = s.data; - format = s.datapoints.format; - - if (!format) { - format = []; - // find out how to copy - format.push({ x: true, number: true, required: true }); - format.push({ y: true, number: true, required: true }); - - if (s.bars.show || (s.lines.show && s.lines.fill)) { - var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); - format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); - if (s.bars.horizontal) { - delete format[format.length - 1].y; - format[format.length - 1].x = true; - } - } - - s.datapoints.format = format; - } - - if (s.datapoints.pointsize != null) - continue; // already filled in - - s.datapoints.pointsize = format.length; - - ps = s.datapoints.pointsize; - points = s.datapoints.points; - - var insertSteps = s.lines.show && s.lines.steps; - s.xaxis.used = s.yaxis.used = true; - - for (j = k = 0; j < data.length; ++j, k += ps) { - p = data[j]; - - var nullify = p == null; - if (!nullify) { - for (m = 0; m < ps; ++m) { - val = p[m]; - f = format[m]; - - if (f) { - if (f.number && val != null) { - val = +val; // convert to number - if (isNaN(val)) - val = null; - else if (val == Infinity) - val = fakeInfinity; - else if (val == -Infinity) - val = -fakeInfinity; - } - - if (val == null) { - if (f.required) - nullify = true; - - if (f.defaultValue != null) - val = f.defaultValue; - } - } - - points[k + m] = val; - } - } - - if (nullify) { - for (m = 0; m < ps; ++m) { - val = points[k + m]; - if (val != null) { - f = format[m]; - // extract min/max info - if (f.autoscale) { - if (f.x) { - updateAxis(s.xaxis, val, val); - } - if (f.y) { - updateAxis(s.yaxis, val, val); - } - } - } - points[k + m] = null; - } - } - else { - // a little bit of line specific stuff that - // perhaps shouldn't be here, but lacking - // better means... - if (insertSteps && k > 0 - && points[k - ps] != null - && points[k - ps] != points[k] - && points[k - ps + 1] != points[k + 1]) { - // copy the point to make room for a middle point - for (m = 0; m < ps; ++m) - points[k + ps + m] = points[k + m]; - - // middle point has same y - points[k + 1] = points[k - ps + 1]; - - // we've added a point, better reflect that - k += ps; - } - } - } - } - - // give the hooks a chance to run - for (i = 0; i < series.length; ++i) { - s = series[i]; - - executeHooks(hooks.processDatapoints, [ s, s.datapoints]); - } - - // second pass: find datamax/datamin for auto-scaling - for (i = 0; i < series.length; ++i) { - s = series[i]; - points = s.datapoints.points; - ps = s.datapoints.pointsize; - format = s.datapoints.format; - - var xmin = topSentry, ymin = topSentry, - xmax = bottomSentry, ymax = bottomSentry; - - for (j = 0; j < points.length; j += ps) { - if (points[j] == null) - continue; - - for (m = 0; m < ps; ++m) { - val = points[j + m]; - f = format[m]; - if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) - continue; - - if (f.x) { - if (val < xmin) - xmin = val; - if (val > xmax) - xmax = val; - } - if (f.y) { - if (val < ymin) - ymin = val; - if (val > ymax) - ymax = val; - } - } - } - - if (s.bars.show) { - // make sure we got room for the bar on the dancing floor - var delta; - - switch (s.bars.align) { - case "left": - delta = 0; - break; - case "right": - delta = -s.bars.barWidth; - break; - case "center": - delta = -s.bars.barWidth / 2; - break; - default: - throw new Error("Invalid bar alignment: " + s.bars.align); - } - - if (s.bars.horizontal) { - ymin += delta; - ymax += delta + s.bars.barWidth; - } - else { - xmin += delta; - xmax += delta + s.bars.barWidth; - } - } - - updateAxis(s.xaxis, xmin, xmax); - updateAxis(s.yaxis, ymin, ymax); - } - - $.each(allAxes(), function (_, axis) { - if (axis.datamin == topSentry) - axis.datamin = null; - if (axis.datamax == bottomSentry) - axis.datamax = null; - }); - } - - function setupCanvases() { - - // Make sure the placeholder is clear of everything except canvases - // from a previous plot in this container that we'll try to re-use. - - placeholder.css("padding", 0) // padding messes up the positioning - .children(":not(.flot-base,.flot-overlay)").remove(); - - if (placeholder.css("position") == 'static') - placeholder.css("position", "relative"); // for positioning labels and overlay - - surface = new Canvas("flot-base", placeholder); - overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features - - ctx = surface.context; - octx = overlay.context; - - // define which element we're listening for events on - eventHolder = $(overlay.element).unbind(); - - // If we're re-using a plot object, shut down the old one - - var existing = placeholder.data("plot"); - - if (existing) { - existing.shutdown(); - overlay.clear(); - } - - // save in case we get replotted - placeholder.data("plot", plot); - } - - function bindEvents() { - // bind events - if (options.grid.hoverable) { - eventHolder.mousemove(onMouseMove); - - // Use bind, rather than .mouseleave, because we officially - // still support jQuery 1.2.6, which doesn't define a shortcut - // for mouseenter or mouseleave. This was a bug/oversight that - // was fixed somewhere around 1.3.x. We can return to using - // .mouseleave when we drop support for 1.2.6. - - eventHolder.bind("mouseleave", onMouseLeave); - } - - if (options.grid.clickable) - eventHolder.click(onClick); - - executeHooks(hooks.bindEvents, [eventHolder]); - } - - function shutdown() { - if (redrawTimeout) - clearTimeout(redrawTimeout); - - eventHolder.unbind("mousemove", onMouseMove); - eventHolder.unbind("mouseleave", onMouseLeave); - eventHolder.unbind("click", onClick); - - executeHooks(hooks.shutdown, [eventHolder]); - } - - function setTransformationHelpers(axis) { - // set helper functions on the axis, assumes plot area - // has been computed already - - function identity(x) { return x; } - - var s, m, t = axis.options.transform || identity, - it = axis.options.inverseTransform; - - // precompute how much the axis is scaling a point - // in canvas space - if (axis.direction == "x") { - s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); - m = Math.min(t(axis.max), t(axis.min)); - } - else { - s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); - s = -s; - m = Math.max(t(axis.max), t(axis.min)); - } - - // data point to canvas coordinate - if (t == identity) // slight optimization - axis.p2c = function (p) { return (p - m) * s; }; - else - axis.p2c = function (p) { return (t(p) - m) * s; }; - // canvas coordinate to data point - if (!it) - axis.c2p = function (c) { return m + c / s; }; - else - axis.c2p = function (c) { return it(m + c / s); }; - } - - function measureTickLabels(axis) { - - var opts = axis.options, - ticks = axis.ticks || [], - labelWidth = opts.labelWidth || 0, - labelHeight = opts.labelHeight || 0, - maxWidth = labelWidth || axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null; - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = opts.font || "flot-tick-label tickLabel"; - - for (var i = 0; i < ticks.length; ++i) { - - var t = ticks[i]; - - if (!t.label) - continue; - - var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); - - labelWidth = Math.max(labelWidth, info.width); - labelHeight = Math.max(labelHeight, info.height); - } - - axis.labelWidth = opts.labelWidth || labelWidth; - axis.labelHeight = opts.labelHeight || labelHeight; - } - - function allocateAxisBoxFirstPhase(axis) { - // find the bounding box of the axis by looking at label - // widths/heights and ticks, make room by diminishing the - // plotOffset; this first phase only looks at one - // dimension per axis, the other dimension depends on the - // other axes so will have to wait - - var lw = axis.labelWidth, - lh = axis.labelHeight, - pos = axis.options.position, - tickLength = axis.options.tickLength, - axisMargin = options.grid.axisMargin, - padding = options.grid.labelMargin, - all = axis.direction == "x" ? xaxes : yaxes, - index, innermost; - - // determine axis margin - var samePosition = $.grep(all, function (a) { - return a && a.options.position == pos && a.reserveSpace; - }); - if ($.inArray(axis, samePosition) == samePosition.length - 1) - axisMargin = 0; // outermost - - // determine tick length - if we're innermost, we can use "full" - if (tickLength == null) { - var sameDirection = $.grep(all, function (a) { - return a && a.reserveSpace; - }); - - innermost = $.inArray(axis, sameDirection) == 0; - if (innermost) - tickLength = "full"; - else - tickLength = 5; - } - - if (!isNaN(+tickLength)) - padding += +tickLength; - - // compute box - if (axis.direction == "x") { - lh += padding; - - if (pos == "bottom") { - plotOffset.bottom += lh + axisMargin; - axis.box = { top: surface.height - plotOffset.bottom, height: lh }; - } - else { - axis.box = { top: plotOffset.top + axisMargin, height: lh }; - plotOffset.top += lh + axisMargin; - } - } - else { - lw += padding; - - if (pos == "left") { - axis.box = { left: plotOffset.left + axisMargin, width: lw }; - plotOffset.left += lw + axisMargin; - } - else { - plotOffset.right += lw + axisMargin; - axis.box = { left: surface.width - plotOffset.right, width: lw }; - } - } - - // save for future reference - axis.position = pos; - axis.tickLength = tickLength; - axis.box.padding = padding; - axis.innermost = innermost; - } - - function allocateAxisBoxSecondPhase(axis) { - // now that all axis boxes have been placed in one - // dimension, we can set the remaining dimension coordinates - if (axis.direction == "x") { - axis.box.left = plotOffset.left - axis.labelWidth / 2; - axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; - } - else { - axis.box.top = plotOffset.top - axis.labelHeight / 2; - axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; - } - } - - function adjustLayoutForThingsStickingOut() { - // possibly adjust plot offset to ensure everything stays - // inside the canvas and isn't clipped off - - var minMargin = options.grid.minBorderMargin, - margins = { x: 0, y: 0 }, i, axis; - - // check stuff from the plot (FIXME: this should just read - // a value from the series, otherwise it's impossible to - // customize) - if (minMargin == null) { - minMargin = 0; - for (i = 0; i < series.length; ++i) - minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); - } - - margins.x = margins.y = Math.ceil(minMargin); - - // check axis labels, note we don't check the actual - // labels but instead use the overall width/height to not - // jump as much around with replots - $.each(allAxes(), function (_, axis) { - var dir = axis.direction; - if (axis.reserveSpace) - margins[dir] = Math.ceil(Math.max(margins[dir], (dir == "x" ? axis.labelWidth : axis.labelHeight) / 2)); - }); - - plotOffset.left = Math.max(margins.x, plotOffset.left); - plotOffset.right = Math.max(margins.x, plotOffset.right); - plotOffset.top = Math.max(margins.y, plotOffset.top); - plotOffset.bottom = Math.max(margins.y, plotOffset.bottom); - } - - function setupGrid() { - var i, axes = allAxes(), showGrid = options.grid.show; - - // Initialize the plot's offset from the edge of the canvas - - for (var a in plotOffset) { - var margin = options.grid.margin || 0; - plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; - } - - executeHooks(hooks.processOffset, [plotOffset]); - - // If the grid is visible, add its border width to the offset - - for (var a in plotOffset) { - if(typeof(options.grid.borderWidth) == "object") { - plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; - } - else { - plotOffset[a] += showGrid ? options.grid.borderWidth : 0; - } - } - - // init axes - $.each(axes, function (_, axis) { - axis.show = axis.options.show; - if (axis.show == null) - axis.show = axis.used; // by default an axis is visible if it's got data - - axis.reserveSpace = axis.show || axis.options.reserveSpace; - - setRange(axis); - }); - - if (showGrid) { - - var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; }); - - $.each(allocatedAxes, function (_, axis) { - // make the ticks - setupTickGeneration(axis); - setTicks(axis); - snapRangeToTicks(axis, axis.ticks); - // find labelWidth/Height for axis - measureTickLabels(axis); - }); - - // with all dimensions calculated, we can compute the - // axis bounding boxes, start from the outside - // (reverse order) - for (i = allocatedAxes.length - 1; i >= 0; --i) - allocateAxisBoxFirstPhase(allocatedAxes[i]); - - // make sure we've got enough space for things that - // might stick out - adjustLayoutForThingsStickingOut(); - - $.each(allocatedAxes, function (_, axis) { - allocateAxisBoxSecondPhase(axis); - }); - } - - plotWidth = surface.width - plotOffset.left - plotOffset.right; - plotHeight = surface.height - plotOffset.bottom - plotOffset.top; - - // now we got the proper plot dimensions, we can compute the scaling - $.each(axes, function (_, axis) { - setTransformationHelpers(axis); - }); - - if (showGrid) { - drawAxisLabels(); - } - - insertLegend(); - } - - function setRange(axis) { - var opts = axis.options, - min = +(opts.min != null ? opts.min : axis.datamin), - max = +(opts.max != null ? opts.max : axis.datamax), - delta = max - min; - - if (delta == 0.0) { - // degenerate case - var widen = max == 0 ? 1 : 0.01; - - if (opts.min == null) - min -= widen; - // always widen max if we couldn't widen min to ensure we - // don't fall into min == max which doesn't work - if (opts.max == null || opts.min != null) - max += widen; - } - else { - // consider autoscaling - var margin = opts.autoscaleMargin; - if (margin != null) { - if (opts.min == null) { - min -= delta * margin; - // make sure we don't go below zero if all values - // are positive - if (min < 0 && axis.datamin != null && axis.datamin >= 0) - min = 0; - } - if (opts.max == null) { - max += delta * margin; - if (max > 0 && axis.datamax != null && axis.datamax <= 0) - max = 0; - } - } - } - axis.min = min; - axis.max = max; - } - - function setupTickGeneration(axis) { - var opts = axis.options; - - // estimate number of ticks - var noTicks; - if (typeof opts.ticks == "number" && opts.ticks > 0) - noTicks = opts.ticks; - else - // heuristic based on the model a*sqrt(x) fitted to - // some data points that seemed reasonable - noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); - - var delta = (axis.max - axis.min) / noTicks, - dec = -Math.floor(Math.log(delta) / Math.LN10), - maxDec = opts.tickDecimals; - - if (maxDec != null && dec > maxDec) { - dec = maxDec; - } - - var magn = Math.pow(10, -dec), - norm = delta / magn, // norm is between 1.0 and 10.0 - size; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - // special case for 2.5, requires an extra decimal - if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { - size = 2.5; - ++dec; - } - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - - if (opts.minTickSize != null && size < opts.minTickSize) { - size = opts.minTickSize; - } - - axis.delta = delta; - axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); - axis.tickSize = opts.tickSize || size; - - // Time mode was moved to a plug-in in 0.8, but since so many people use this - // we'll add an especially friendly make sure they remembered to include it. - - if (opts.mode == "time" && !axis.tickGenerator) { - throw new Error("Time mode requires the flot.time plugin."); - } - - // Flot supports base-10 axes; any other mode else is handled by a plug-in, - // like flot.time.js. - - if (!axis.tickGenerator) { - - axis.tickGenerator = function (axis) { - - var ticks = [], - start = floorInBase(axis.min, axis.tickSize), - i = 0, - v = Number.NaN, - prev; - - do { - prev = v; - v = start + i * axis.tickSize; - ticks.push(v); - ++i; - } while (v < axis.max && v != prev); - return ticks; - }; - - axis.tickFormatter = function (value, axis) { - - var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; - var formatted = "" + Math.round(value * factor) / factor; - - // If tickDecimals was specified, ensure that we have exactly that - // much precision; otherwise default to the value's own precision. - - if (axis.tickDecimals != null) { - var decimal = formatted.indexOf("."); - var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; - if (precision < axis.tickDecimals) { - return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); - } - } - - return formatted; - }; - } - - if ($.isFunction(opts.tickFormatter)) - axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; - - if (opts.alignTicksWithAxis != null) { - var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; - if (otherAxis && otherAxis.used && otherAxis != axis) { - // consider snapping min/max to outermost nice ticks - var niceTicks = axis.tickGenerator(axis); - if (niceTicks.length > 0) { - if (opts.min == null) - axis.min = Math.min(axis.min, niceTicks[0]); - if (opts.max == null && niceTicks.length > 1) - axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); - } - - axis.tickGenerator = function (axis) { - // copy ticks, scaled to this axis - var ticks = [], v, i; - for (i = 0; i < otherAxis.ticks.length; ++i) { - v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); - v = axis.min + v * (axis.max - axis.min); - ticks.push(v); - } - return ticks; - }; - - // we might need an extra decimal since forced - // ticks don't necessarily fit naturally - if (!axis.mode && opts.tickDecimals == null) { - var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), - ts = axis.tickGenerator(axis); - - // only proceed if the tick interval rounded - // with an extra decimal doesn't give us a - // zero at end - if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) - axis.tickDecimals = extraDec; - } - } - } - } - - function setTicks(axis) { - var oticks = axis.options.ticks, ticks = []; - if (oticks == null || (typeof oticks == "number" && oticks > 0)) - ticks = axis.tickGenerator(axis); - else if (oticks) { - if ($.isFunction(oticks)) - // generate the ticks - ticks = oticks(axis); - else - ticks = oticks; - } - - // clean up/labelify the supplied ticks, copy them over - var i, v; - axis.ticks = []; - for (i = 0; i < ticks.length; ++i) { - var label = null; - var t = ticks[i]; - if (typeof t == "object") { - v = +t[0]; - if (t.length > 1) - label = t[1]; - } - else - v = +t; - if (label == null) - label = axis.tickFormatter(v, axis); - if (!isNaN(v)) - axis.ticks.push({ v: v, label: label }); - } - } - - function snapRangeToTicks(axis, ticks) { - if (axis.options.autoscaleMargin && ticks.length > 0) { - // snap to ticks - if (axis.options.min == null) - axis.min = Math.min(axis.min, ticks[0].v); - if (axis.options.max == null && ticks.length > 1) - axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); - } - } - - function draw() { - - surface.clear(); - - executeHooks(hooks.drawBackground, [ctx]); - - var grid = options.grid; - - // draw background, if any - if (grid.show && grid.backgroundColor) - drawBackground(); - - if (grid.show && !grid.aboveData) { - drawGrid(); - } - - for (var i = 0; i < series.length; ++i) { - executeHooks(hooks.drawSeries, [ctx, series[i]]); - drawSeries(series[i]); - } - - executeHooks(hooks.draw, [ctx]); - - if (grid.show && grid.aboveData) { - drawGrid(); - } - - surface.render(); - - // A draw implies that either the axes or data have changed, so we - // should probably update the overlay highlights as well. - - triggerRedrawOverlay(); - } - - function extractRange(ranges, coord) { - var axis, from, to, key, axes = allAxes(); - - for (var i = 0; i < axes.length; ++i) { - axis = axes[i]; - if (axis.direction == coord) { - key = coord + axis.n + "axis"; - if (!ranges[key] && axis.n == 1) - key = coord + "axis"; // support x1axis as xaxis - if (ranges[key]) { - from = ranges[key].from; - to = ranges[key].to; - break; - } - } - } - - // backwards-compat stuff - to be removed in future - if (!ranges[key]) { - axis = coord == "x" ? xaxes[0] : yaxes[0]; - from = ranges[coord + "1"]; - to = ranges[coord + "2"]; - } - - // auto-reverse as an added bonus - if (from != null && to != null && from > to) { - var tmp = from; - from = to; - to = tmp; - } - - return { from: from, to: to, axis: axis }; - } - - function drawBackground() { - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); - ctx.fillRect(0, 0, plotWidth, plotHeight); - ctx.restore(); - } - - function drawGrid() { - var i, axes, bw, bc; - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // draw markings - var markings = options.grid.markings; - if (markings) { - if ($.isFunction(markings)) { - axes = plot.getAxes(); - // xmin etc. is backwards compatibility, to be - // removed in the future - axes.xmin = axes.xaxis.min; - axes.xmax = axes.xaxis.max; - axes.ymin = axes.yaxis.min; - axes.ymax = axes.yaxis.max; - - markings = markings(axes); - } - - for (i = 0; i < markings.length; ++i) { - var m = markings[i], - xrange = extractRange(m, "x"), - yrange = extractRange(m, "y"); - - // fill in missing - if (xrange.from == null) - xrange.from = xrange.axis.min; - if (xrange.to == null) - xrange.to = xrange.axis.max; - if (yrange.from == null) - yrange.from = yrange.axis.min; - if (yrange.to == null) - yrange.to = yrange.axis.max; - - // clip - if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || - yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) - continue; - - xrange.from = Math.max(xrange.from, xrange.axis.min); - xrange.to = Math.min(xrange.to, xrange.axis.max); - yrange.from = Math.max(yrange.from, yrange.axis.min); - yrange.to = Math.min(yrange.to, yrange.axis.max); - - if (xrange.from == xrange.to && yrange.from == yrange.to) - continue; - - // then draw - xrange.from = xrange.axis.p2c(xrange.from); - xrange.to = xrange.axis.p2c(xrange.to); - yrange.from = yrange.axis.p2c(yrange.from); - yrange.to = yrange.axis.p2c(yrange.to); - - if (xrange.from == xrange.to || yrange.from == yrange.to) { - // draw line - ctx.beginPath(); - ctx.strokeStyle = m.color || options.grid.markingsColor; - ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; - ctx.moveTo(xrange.from, yrange.from); - ctx.lineTo(xrange.to, yrange.to); - ctx.stroke(); - } - else { - // fill area - ctx.fillStyle = m.color || options.grid.markingsColor; - ctx.fillRect(xrange.from, yrange.to, - xrange.to - xrange.from, - yrange.from - yrange.to); - } - } - } - - // draw the ticks - axes = allAxes(); - bw = options.grid.borderWidth; - - for (var j = 0; j < axes.length; ++j) { - var axis = axes[j], box = axis.box, - t = axis.tickLength, x, y, xoff, yoff; - if (!axis.show || axis.ticks.length == 0) - continue; - - ctx.lineWidth = 1; - - // find the edges - if (axis.direction == "x") { - x = 0; - if (t == "full") - y = (axis.position == "top" ? 0 : plotHeight); - else - y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); - } - else { - y = 0; - if (t == "full") - x = (axis.position == "left" ? 0 : plotWidth); - else - x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); - } - - // draw tick bar - if (!axis.innermost) { - ctx.strokeStyle = axis.options.color; - ctx.beginPath(); - xoff = yoff = 0; - if (axis.direction == "x") - xoff = plotWidth + 1; - else - yoff = plotHeight + 1; - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") { - y = Math.floor(y) + 0.5; - } else { - x = Math.floor(x) + 0.5; - } - } - - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - ctx.stroke(); - } - - // draw ticks - - ctx.strokeStyle = axis.options.tickColor; - - ctx.beginPath(); - for (i = 0; i < axis.ticks.length; ++i) { - var v = axis.ticks[i].v; - - xoff = yoff = 0; - - if (isNaN(v) || v < axis.min || v > axis.max - // skip those lying on the axes if we got a border - || (t == "full" - && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) - && (v == axis.min || v == axis.max))) - continue; - - if (axis.direction == "x") { - x = axis.p2c(v); - yoff = t == "full" ? -plotHeight : t; - - if (axis.position == "top") - yoff = -yoff; - } - else { - y = axis.p2c(v); - xoff = t == "full" ? -plotWidth : t; - - if (axis.position == "left") - xoff = -xoff; - } - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") - x = Math.floor(x) + 0.5; - else - y = Math.floor(y) + 0.5; - } - - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - } - - ctx.stroke(); - } - - - // draw border - if (bw) { - // If either borderWidth or borderColor is an object, then draw the border - // line by line instead of as one rectangle - bc = options.grid.borderColor; - if(typeof bw == "object" || typeof bc == "object") { - if (typeof bw !== "object") { - bw = {top: bw, right: bw, bottom: bw, left: bw}; - } - if (typeof bc !== "object") { - bc = {top: bc, right: bc, bottom: bc, left: bc}; - } - - if (bw.top > 0) { - ctx.strokeStyle = bc.top; - ctx.lineWidth = bw.top; - ctx.beginPath(); - ctx.moveTo(0 - bw.left, 0 - bw.top/2); - ctx.lineTo(plotWidth, 0 - bw.top/2); - ctx.stroke(); - } - - if (bw.right > 0) { - ctx.strokeStyle = bc.right; - ctx.lineWidth = bw.right; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); - ctx.lineTo(plotWidth + bw.right / 2, plotHeight); - ctx.stroke(); - } - - if (bw.bottom > 0) { - ctx.strokeStyle = bc.bottom; - ctx.lineWidth = bw.bottom; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); - ctx.lineTo(0, plotHeight + bw.bottom / 2); - ctx.stroke(); - } - - if (bw.left > 0) { - ctx.strokeStyle = bc.left; - ctx.lineWidth = bw.left; - ctx.beginPath(); - ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); - ctx.lineTo(0- bw.left/2, 0); - ctx.stroke(); - } - } - else { - ctx.lineWidth = bw; - ctx.strokeStyle = options.grid.borderColor; - ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); - } - } - - ctx.restore(); - } - - function drawAxisLabels() { - - $.each(allAxes(), function (_, axis) { - if (!axis.show || axis.ticks.length == 0) - return; - - var box = axis.box, - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = axis.options.font || "flot-tick-label tickLabel", - tick, x, y, halign, valign; - - surface.removeText(layer); - - for (var i = 0; i < axis.ticks.length; ++i) { - - tick = axis.ticks[i]; - if (!tick.label || tick.v < axis.min || tick.v > axis.max) - continue; - - if (axis.direction == "x") { - halign = "center"; - x = plotOffset.left + axis.p2c(tick.v); - if (axis.position == "bottom") { - y = box.top + box.padding; - } else { - y = box.top + box.height - box.padding; - valign = "bottom"; - } - } else { - valign = "middle"; - y = plotOffset.top + axis.p2c(tick.v); - if (axis.position == "left") { - x = box.left + box.width - box.padding; - halign = "right"; - } else { - x = box.left + box.padding; - } - } - - surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); - } - }); - } - - function drawSeries(series) { - if (series.lines.show) - drawSeriesLines(series); - if (series.bars.show) - drawSeriesBars(series); - if (series.points.show) - drawSeriesPoints(series); - } - - function drawSeriesLines(series) { - function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { - var points = datapoints.points, - ps = datapoints.pointsize, - prevx = null, prevy = null; - - ctx.beginPath(); - for (var i = ps; i < points.length; i += ps) { - var x1 = points[i - ps], y1 = points[i - ps + 1], - x2 = points[i], y2 = points[i + 1]; - - if (x1 == null || x2 == null) - continue; - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min) { - if (y2 < axisy.min) - continue; // line segment is outside - // compute new intersection point - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min) { - if (y1 < axisy.min) - continue; - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max) { - if (y2 > axisy.max) - continue; - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max) { - if (y1 > axisy.max) - continue; - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (x1 != prevx || y1 != prevy) - ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); - - prevx = x2; - prevy = y2; - ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); - } - ctx.stroke(); - } - - function plotLineArea(datapoints, axisx, axisy) { - var points = datapoints.points, - ps = datapoints.pointsize, - bottom = Math.min(Math.max(0, axisy.min), axisy.max), - i = 0, top, areaOpen = false, - ypos = 1, segmentStart = 0, segmentEnd = 0; - - // we process each segment in two turns, first forward - // direction to sketch out top, then once we hit the - // end we go backwards to sketch the bottom - while (true) { - if (ps > 0 && i > points.length + ps) - break; - - i += ps; // ps is negative if going backwards - - var x1 = points[i - ps], - y1 = points[i - ps + ypos], - x2 = points[i], y2 = points[i + ypos]; - - if (areaOpen) { - if (ps > 0 && x1 != null && x2 == null) { - // at turning point - segmentEnd = i; - ps = -ps; - ypos = 2; - continue; - } - - if (ps < 0 && i == segmentStart + ps) { - // done with the reverse sweep - ctx.fill(); - areaOpen = false; - ps = -ps; - ypos = 1; - i = segmentStart = segmentEnd + ps; - continue; - } - } - - if (x1 == null || x2 == null) - continue; - - // clip x values - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (!areaOpen) { - // open area - ctx.beginPath(); - ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); - areaOpen = true; - } - - // now first check the case where both is outside - if (y1 >= axisy.max && y2 >= axisy.max) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); - continue; - } - else if (y1 <= axisy.min && y2 <= axisy.min) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); - continue; - } - - // else it's a bit more complicated, there might - // be a flat maxed out rectangle first, then a - // triangular cutout or reverse; to find these - // keep track of the current x values - var x1old = x1, x2old = x2; - - // clip the y values, without shortcutting, we - // go through all cases in turn - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // if the x value was changed we got a rectangle - // to fill - if (x1 != x1old) { - ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); - // it goes to (x1, y1), but we fill that below - } - - // fill triangular section, this sometimes result - // in redundant points if (x1, y1) hasn't changed - // from previous line to, but we just ignore that - ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - - // fill the other rectangle if it's there - if (x2 != x2old) { - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); - } - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - ctx.lineJoin = "round"; - - var lw = series.lines.lineWidth, - sw = series.shadowSize; - // FIXME: consider another form of shadow when filling is turned on - if (lw > 0 && sw > 0) { - // draw shadow as a thick and thin line with transparency - ctx.lineWidth = sw; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - // position shadow at angle from the mid of line - var angle = Math.PI/18; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); - ctx.lineWidth = sw/2; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); - if (fillStyle) { - ctx.fillStyle = fillStyle; - plotLineArea(series.datapoints, series.xaxis, series.yaxis); - } - - if (lw > 0) - plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); - ctx.restore(); - } - - function drawSeriesPoints(series) { - function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - var x = points[i], y = points[i + 1]; - if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - continue; - - ctx.beginPath(); - x = axisx.p2c(x); - y = axisy.p2c(y) + offset; - if (symbol == "circle") - ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); - else - symbol(ctx, x, y, radius, shadow); - ctx.closePath(); - - if (fillStyle) { - ctx.fillStyle = fillStyle; - ctx.fill(); - } - ctx.stroke(); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - var lw = series.points.lineWidth, - sw = series.shadowSize, - radius = series.points.radius, - symbol = series.points.symbol; - - // If the user sets the line width to 0, we change it to a very - // small value. A line width of 0 seems to force the default of 1. - // Doing the conditional here allows the shadow setting to still be - // optional even with a lineWidth of 0. - - if( lw == 0 ) - lw = 0.0001; - - if (lw > 0 && sw > 0) { - // draw shadow in two steps - var w = sw / 2; - ctx.lineWidth = w; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - plotPoints(series.datapoints, radius, null, w + w/2, true, - series.xaxis, series.yaxis, symbol); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - plotPoints(series.datapoints, radius, null, w/2, true, - series.xaxis, series.yaxis, symbol); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - plotPoints(series.datapoints, radius, - getFillStyle(series.points, series.color), 0, false, - series.xaxis, series.yaxis, symbol); - ctx.restore(); - } - - function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { - var left, right, bottom, top, - drawLeft, drawRight, drawTop, drawBottom, - tmp; - - // in horizontal mode, we start the bar from the left - // instead of from the bottom so it appears to be - // horizontal rather than vertical - if (horizontal) { - drawBottom = drawRight = drawTop = true; - drawLeft = false; - left = b; - right = x; - top = y + barLeft; - bottom = y + barRight; - - // account for negative bars - if (right < left) { - tmp = right; - right = left; - left = tmp; - drawLeft = true; - drawRight = false; - } - } - else { - drawLeft = drawRight = drawTop = true; - drawBottom = false; - left = x + barLeft; - right = x + barRight; - bottom = b; - top = y; - - // account for negative bars - if (top < bottom) { - tmp = top; - top = bottom; - bottom = tmp; - drawBottom = true; - drawTop = false; - } - } - - // clip - if (right < axisx.min || left > axisx.max || - top < axisy.min || bottom > axisy.max) - return; - - if (left < axisx.min) { - left = axisx.min; - drawLeft = false; - } - - if (right > axisx.max) { - right = axisx.max; - drawRight = false; - } - - if (bottom < axisy.min) { - bottom = axisy.min; - drawBottom = false; - } - - if (top > axisy.max) { - top = axisy.max; - drawTop = false; - } - - left = axisx.p2c(left); - bottom = axisy.p2c(bottom); - right = axisx.p2c(right); - top = axisy.p2c(top); - - // fill the bar - if (fillStyleCallback) { - c.beginPath(); - c.moveTo(left, bottom); - c.lineTo(left, top); - c.lineTo(right, top); - c.lineTo(right, bottom); - c.fillStyle = fillStyleCallback(bottom, top); - c.fill(); - } - - // draw outline - if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { - c.beginPath(); - - // FIXME: inline moveTo is buggy with excanvas - c.moveTo(left, bottom + offset); - if (drawLeft) - c.lineTo(left, top + offset); - else - c.moveTo(left, top + offset); - if (drawTop) - c.lineTo(right, top + offset); - else - c.moveTo(right, top + offset); - if (drawRight) - c.lineTo(right, bottom + offset); - else - c.moveTo(right, bottom + offset); - if (drawBottom) - c.lineTo(left, bottom + offset); - else - c.moveTo(left, bottom + offset); - c.stroke(); - } - } - - function drawSeriesBars(series) { - function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - if (points[i] == null) - continue; - drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // FIXME: figure out a way to add shadows (for instance along the right edge) - ctx.lineWidth = series.bars.lineWidth; - ctx.strokeStyle = series.color; - - var barLeft; - - switch (series.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -series.bars.barWidth; - break; - case "center": - barLeft = -series.bars.barWidth / 2; - break; - default: - throw new Error("Invalid bar alignment: " + series.bars.align); - } - - var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; - plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis); - ctx.restore(); - } - - function getFillStyle(filloptions, seriesColor, bottom, top) { - var fill = filloptions.fill; - if (!fill) - return null; - - if (filloptions.fillColor) - return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); - - var c = $.color.parse(seriesColor); - c.a = typeof fill == "number" ? fill : 0.4; - c.normalize(); - return c.toString(); - } - - function insertLegend() { - - placeholder.find(".legend").remove(); - - if (!options.legend.show) - return; - - var fragments = [], entries = [], rowStarted = false, - lf = options.legend.labelFormatter, s, label; - - // Build a list of legend entries, with each having a label and a color - - for (var i = 0; i < series.length; ++i) { - s = series[i]; - if (s.label) { - label = lf ? lf(s.label, s) : s.label; - if (label) { - entries.push({ - label: label, - color: s.color - }); - } - } - } - - // Sort the legend using either the default or a custom comparator - - if (options.legend.sorted) { - if ($.isFunction(options.legend.sorted)) { - entries.sort(options.legend.sorted); - } else if (options.legend.sorted == "reverse") { - entries.reverse(); - } else { - var ascending = options.legend.sorted != "descending"; - entries.sort(function(a, b) { - return a.label == b.label ? 0 : ( - (a.label < b.label) != ascending ? 1 : -1 // Logical XOR - ); - }); - } - } - - // Generate markup for the list of entries, in their final order - - for (var i = 0; i < entries.length; ++i) { - - var entry = entries[i]; - - if (i % options.legend.noColumns == 0) { - if (rowStarted) - fragments.push(''); - fragments.push(''); - rowStarted = true; - } - - fragments.push( - '
' + - '' + entry.label + '' - ); - } - - if (rowStarted) - fragments.push(''); - - if (fragments.length == 0) - return; - - var table = '' + fragments.join("") + '
'; - if (options.legend.container != null) - $(options.legend.container).html(table); - else { - var pos = "", - p = options.legend.position, - m = options.legend.margin; - if (m[0] == null) - m = [m, m]; - if (p.charAt(0) == "n") - pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; - else if (p.charAt(0) == "s") - pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; - if (p.charAt(1) == "e") - pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; - else if (p.charAt(1) == "w") - pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; - var legend = $('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(placeholder); - if (options.legend.backgroundOpacity != 0.0) { - // put in the transparent background - // separately to avoid blended labels and - // label boxes - var c = options.legend.backgroundColor; - if (c == null) { - c = options.grid.backgroundColor; - if (c && typeof c == "string") - c = $.color.parse(c); - else - c = $.color.extract(legend, 'background-color'); - c.a = 1; - c = c.toString(); - } - var div = legend.children(); - $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity); - } - } - } - - - // interactive features - - var highlights = [], - redrawTimeout = null; - - // returns the data item the mouse is over, or null if none is found - function findNearbyItem(mouseX, mouseY, seriesFilter) { - var maxDistance = options.grid.mouseActiveRadius, - smallestDistance = maxDistance * maxDistance + 1, - item = null, foundPoint = false, i, j, ps; - - for (i = series.length - 1; i >= 0; --i) { - if (!seriesFilter(series[i])) - continue; - - var s = series[i], - axisx = s.xaxis, - axisy = s.yaxis, - points = s.datapoints.points, - mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster - my = axisy.c2p(mouseY), - maxx = maxDistance / axisx.scale, - maxy = maxDistance / axisy.scale; - - ps = s.datapoints.pointsize; - // with inverse transforms, we can't use the maxx/maxy - // optimization, sadly - if (axisx.options.inverseTransform) - maxx = Number.MAX_VALUE; - if (axisy.options.inverseTransform) - maxy = Number.MAX_VALUE; - - if (s.lines.show || s.points.show) { - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1]; - if (x == null) - continue; - - // For points and lines, the cursor must be within a - // certain distance to the data point - if (x - mx > maxx || x - mx < -maxx || - y - my > maxy || y - my < -maxy) - continue; - - // We have to calculate distances in pixels, not in - // data units, because the scales of the axes may be different - var dx = Math.abs(axisx.p2c(x) - mouseX), - dy = Math.abs(axisy.p2c(y) - mouseY), - dist = dx * dx + dy * dy; // we save the sqrt - - // use <= to ensure last point takes precedence - // (last generally means on top of) - if (dist < smallestDistance) { - smallestDistance = dist; - item = [i, j / ps]; - } - } - } - - if (s.bars.show && !item) { // no other point can be nearby - var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2, - barRight = barLeft + s.bars.barWidth; - - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1], b = points[j + 2]; - if (x == null) - continue; - - // for a bar graph, the cursor must be inside the bar - if (series[i].bars.horizontal ? - (mx <= Math.max(b, x) && mx >= Math.min(b, x) && - my >= y + barLeft && my <= y + barRight) : - (mx >= x + barLeft && mx <= x + barRight && - my >= Math.min(b, y) && my <= Math.max(b, y))) - item = [i, j / ps]; - } - } - } - - if (item) { - i = item[0]; - j = item[1]; - ps = series[i].datapoints.pointsize; - - return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), - dataIndex: j, - series: series[i], - seriesIndex: i }; - } - - return null; - } - - function onMouseMove(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return s["hoverable"] != false; }); - } - - function onMouseLeave(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return false; }); - } - - function onClick(e) { - triggerClickHoverEvent("plotclick", e, - function (s) { return s["clickable"] != false; }); - } - - // trigger click or hover event (they send the same parameters - // so we share their code) - function triggerClickHoverEvent(eventname, event, seriesFilter) { - var offset = eventHolder.offset(), - canvasX = event.pageX - offset.left - plotOffset.left, - canvasY = event.pageY - offset.top - plotOffset.top, - pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); - - pos.pageX = event.pageX; - pos.pageY = event.pageY; - - var item = findNearbyItem(canvasX, canvasY, seriesFilter); - - if (item) { - // fill in mouse pos for any listeners out there - item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); - item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); - } - - if (options.grid.autoHighlight) { - // clear auto-highlights - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.auto == eventname && - !(item && h.series == item.series && - h.point[0] == item.datapoint[0] && - h.point[1] == item.datapoint[1])) - unhighlight(h.series, h.point); - } - - if (item) - highlight(item.series, item.datapoint, eventname); - } - - placeholder.trigger(eventname, [ pos, item ]); - } - - function triggerRedrawOverlay() { - var t = options.interaction.redrawOverlayInterval; - if (t == -1) { // skip event queue - drawOverlay(); - return; - } - - if (!redrawTimeout) - redrawTimeout = setTimeout(drawOverlay, t); - } - - function drawOverlay() { - redrawTimeout = null; - - // draw highlights - octx.save(); - overlay.clear(); - octx.translate(plotOffset.left, plotOffset.top); - - var i, hi; - for (i = 0; i < highlights.length; ++i) { - hi = highlights[i]; - - if (hi.series.bars.show) - drawBarHighlight(hi.series, hi.point); - else - drawPointHighlight(hi.series, hi.point); - } - octx.restore(); - - executeHooks(hooks.drawOverlay, [octx]); - } - - function highlight(s, point, auto) { - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i == -1) { - highlights.push({ series: s, point: point, auto: auto }); - - triggerRedrawOverlay(); - } - else if (!auto) - highlights[i].auto = false; - } - - function unhighlight(s, point) { - if (s == null && point == null) { - highlights = []; - triggerRedrawOverlay(); - return; - } - - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i != -1) { - highlights.splice(i, 1); - - triggerRedrawOverlay(); - } - } - - function indexOfHighlight(s, p) { - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.series == s && h.point[0] == p[0] - && h.point[1] == p[1]) - return i; - } - return -1; - } - - function drawPointHighlight(series, point) { - var x = point[0], y = point[1], - axisx = series.xaxis, axisy = series.yaxis, - highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); - - if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - return; - - var pointRadius = series.points.radius + series.points.lineWidth / 2; - octx.lineWidth = pointRadius; - octx.strokeStyle = highlightColor; - var radius = 1.5 * pointRadius; - x = axisx.p2c(x); - y = axisy.p2c(y); - - octx.beginPath(); - if (series.points.symbol == "circle") - octx.arc(x, y, radius, 0, 2 * Math.PI, false); - else - series.points.symbol(octx, x, y, radius, false); - octx.closePath(); - octx.stroke(); - } - - function drawBarHighlight(series, point) { - var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), - fillStyle = highlightColor, - barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; - - octx.lineWidth = series.bars.lineWidth; - octx.strokeStyle = highlightColor; - - drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, - 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); - } - - function getColorOrGradient(spec, bottom, top, defaultColor) { - if (typeof spec == "string") - return spec; - else { - // assume this is a gradient spec; IE currently only - // supports a simple vertical gradient properly, so that's - // what we support too - var gradient = ctx.createLinearGradient(0, top, 0, bottom); - - for (var i = 0, l = spec.colors.length; i < l; ++i) { - var c = spec.colors[i]; - if (typeof c != "string") { - var co = $.color.parse(defaultColor); - if (c.brightness != null) - co = co.scale('rgb', c.brightness); - if (c.opacity != null) - co.a *= c.opacity; - c = co.toString(); - } - gradient.addColorStop(i / (l - 1), c); - } - - return gradient; - } - } - } - - // Add the plot function to the top level of the jQuery object - - $.plot = function(placeholder, data, options) { - //var t0 = new Date(); - var plot = new Plot($(placeholder), data, options, $.plot.plugins); - //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); - return plot; - }; - - $.plot.version = "0.8.1"; - - $.plot.plugins = []; - - // Also add the plot function as a chainable property - - $.fn.plot = function(data, options) { - return this.each(function() { - $.plot(this, data, options); - }); - }; - - // round to nearby lower multiple of base - function floorInBase(n, base) { - return base * Math.floor(n / base); - } - -})(jQuery); diff --git a/flot/jquery.flot.min.js b/flot/jquery.flot.min.js new file mode 100644 index 0000000..968d3eb --- /dev/null +++ b/flot/jquery.flot.min.js @@ -0,0 +1,8 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return valuemax?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function($){var hasOwnProperty=Object.prototype.hasOwnProperty;if(!$.fn.detach){$.fn.detach=function(){return this.each(function(){if(this.parentNode){this.parentNode.removeChild(this)}})}}function Canvas(cls,container){var element=container.children("."+cls)[0];if(element==null){element=document.createElement("canvas");element.className=cls;$(element).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(container);if(!element.getContext){if(window.G_vmlCanvasManager){element=window.G_vmlCanvasManager.initElement(element)}else{throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.")}}}this.element=element;var context=this.context=element.getContext("2d");var devicePixelRatio=window.devicePixelRatio||1,backingStoreRatio=context.webkitBackingStorePixelRatio||context.mozBackingStorePixelRatio||context.msBackingStorePixelRatio||context.oBackingStorePixelRatio||context.backingStorePixelRatio||1;this.pixelRatio=devicePixelRatio/backingStoreRatio;this.resize(container.width(),container.height());this.textContainer=null;this.text={};this._textCache={}}Canvas.prototype.resize=function(width,height){if(width<=0||height<=0){throw new Error("Invalid dimensions for plot, width = "+width+", height = "+height)}var element=this.element,context=this.context,pixelRatio=this.pixelRatio;if(this.width!=width){element.width=width*pixelRatio;element.style.width=width+"px";this.width=width}if(this.height!=height){element.height=height*pixelRatio;element.style.height=height+"px";this.height=height}context.restore();context.save();context.scale(pixelRatio,pixelRatio)};Canvas.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)};Canvas.prototype.render=function(){var cache=this._textCache;for(var layerKey in cache){if(hasOwnProperty.call(cache,layerKey)){var layer=this.getTextLayer(layerKey),layerCache=cache[layerKey];layer.hide();for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){if(position.active){if(!position.rendered){layer.append(position.element);position.rendered=true}}else{positions.splice(i--,1);if(position.rendered){position.element.detach()}}}if(positions.length==0){delete styleCache[key]}}}}}layer.show()}}};Canvas.prototype.getTextLayer=function(classes){var layer=this.text[classes];if(layer==null){if(this.textContainer==null){this.textContainer=$("
").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)}layer=this.text[classes]=$("
").addClass(classes).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)}return layer};Canvas.prototype.getTextInfo=function(layer,text,font,angle,width){var textStyle,layerCache,styleCache,info;text=""+text;if(typeof font==="object"){textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px/"+font.lineHeight+"px "+font.family}else{textStyle=font}layerCache=this._textCache[layer];if(layerCache==null){layerCache=this._textCache[layer]={}}styleCache=layerCache[textStyle];if(styleCache==null){styleCache=layerCache[textStyle]={}}info=styleCache[text];if(info==null){var element=$("
").html(text).css({position:"absolute","max-width":width,top:-9999}).appendTo(this.getTextLayer(layer));if(typeof font==="object"){element.css({font:textStyle,color:font.color})}else if(typeof font==="string"){element.addClass(font)}info=styleCache[text]={width:element.outerWidth(true),height:element.outerHeight(true),element:element,positions:[]};element.detach()}return info};Canvas.prototype.addText=function(layer,x,y,text,font,angle,width,halign,valign){var info=this.getTextInfo(layer,text,font,angle,width),positions=info.positions;if(halign=="center"){x-=info.width/2}else if(halign=="right"){x-=info.width}if(valign=="middle"){y-=info.height/2}else if(valign=="bottom"){y-=info.height}for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=true;return}}position={active:true,rendered:false,element:positions.length?info.element.clone():info.element,x:x,y:y};positions.push(position);position.element.css({top:Math.round(y),left:Math.round(x),"text-align":halign})};Canvas.prototype.removeText=function(layer,x,y,text,font,angle){if(text==null){var layerCache=this._textCache[layer];if(layerCache!=null){for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){position.active=false}}}}}}}else{var positions=this.getTextInfo(layer,text,font,angle).positions;for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=false}}}};function Plot(placeholder,data_,options_,plugins){var series=[],options={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:.85,sorted:null},xaxis:{show:null,position:"bottom",mode:null,font:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null},yaxis:{autoscaleMargin:.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false,zero:true},shadowSize:3,highlightColor:null},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,margin:0,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},interaction:{redrawOverlayInterval:1e3/60},hooks:{}},surface=null,overlay=null,eventHolder=null,ctx=null,octx=null,xaxes=[],yaxes=[],plotOffset={left:0,right:0,top:0,bottom:0},plotWidth=0,plotHeight=0,hooks={processOptions:[],processRawData:[],processDatapoints:[],processOffset:[],drawBackground:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},plot=this;plot.setData=setData;plot.setupGrid=setupGrid;plot.draw=draw;plot.getPlaceholder=function(){return placeholder};plot.getCanvas=function(){return surface.element};plot.getPlotOffset=function(){return plotOffset};plot.width=function(){return plotWidth};plot.height=function(){return plotHeight};plot.offset=function(){var o=eventHolder.offset();o.left+=plotOffset.left;o.top+=plotOffset.top;return o};plot.getData=function(){return series};plot.getAxes=function(){var res={},i;$.each(xaxes.concat(yaxes),function(_,axis){if(axis)res[axis.direction+(axis.n!=1?axis.n:"")+"axis"]=axis});return res};plot.getXAxes=function(){return xaxes};plot.getYAxes=function(){return yaxes};plot.c2p=canvasToAxisCoords;plot.p2c=axisToCanvasCoords;plot.getOptions=function(){return options};plot.highlight=highlight;plot.unhighlight=unhighlight;plot.triggerRedrawOverlay=triggerRedrawOverlay;plot.pointOffset=function(point){return{left:parseInt(xaxes[axisNumber(point,"x")-1].p2c(+point.x)+plotOffset.left,10),top:parseInt(yaxes[axisNumber(point,"y")-1].p2c(+point.y)+plotOffset.top,10)}};plot.shutdown=shutdown;plot.destroy=function(){shutdown();placeholder.removeData("plot").empty();series=[];options=null;surface=null;overlay=null;eventHolder=null;ctx=null;octx=null;xaxes=[];yaxes=[];hooks=null;highlights=[];plot=null};plot.resize=function(){var width=placeholder.width(),height=placeholder.height();surface.resize(width,height);overlay.resize(width,height)};plot.hooks=hooks;initPlugins(plot);parseOptions(options_);setupCanvases();setData(data_);setupGrid();draw();bindEvents();function executeHooks(hook,args){args=[plot].concat(args);for(var i=0;imaxIndex){maxIndex=sc}}}if(neededColors<=maxIndex){neededColors=maxIndex+1}var c,colors=[],colorPool=options.colors,colorPoolSize=colorPool.length,variation=0;for(i=0;i=0){if(variation<.5){variation=-variation-.2}else variation=0}else variation=-variation}colors[i]=c.scale("rgb",1+variation)}var colori=0,s;for(i=0;iaxis.datamax&&max!=fakeInfinity)axis.datamax=max}$.each(allAxes(),function(_,axis){axis.datamin=topSentry;axis.datamax=bottomSentry;axis.used=false});for(i=0;i0&&points[k-ps]!=null&&points[k-ps]!=points[k]&&points[k-ps+1]!=points[k+1]){for(m=0;mxmax)xmax=val}if(f.y){if(valymax)ymax=val}}}if(s.bars.show){var delta;switch(s.bars.align){case"left":delta=0;break;case"right":delta=-s.bars.barWidth;break;default:delta=-s.bars.barWidth/2}if(s.bars.horizontal){ymin+=delta;ymax+=delta+s.bars.barWidth}else{xmin+=delta;xmax+=delta+s.bars.barWidth}}updateAxis(s.xaxis,xmin,xmax);updateAxis(s.yaxis,ymin,ymax)}$.each(allAxes(),function(_,axis){if(axis.datamin==topSentry)axis.datamin=null;if(axis.datamax==bottomSentry)axis.datamax=null})}function setupCanvases(){placeholder.css("padding",0).children().filter(function(){return!$(this).hasClass("flot-overlay")&&!$(this).hasClass("flot-base")}).remove();if(placeholder.css("position")=="static")placeholder.css("position","relative");surface=new Canvas("flot-base",placeholder);overlay=new Canvas("flot-overlay",placeholder);ctx=surface.context;octx=overlay.context;eventHolder=$(overlay.element).unbind();var existing=placeholder.data("plot");if(existing){existing.shutdown();overlay.clear()}placeholder.data("plot",plot)}function bindEvents(){if(options.grid.hoverable){eventHolder.mousemove(onMouseMove);eventHolder.bind("mouseleave",onMouseLeave)}if(options.grid.clickable)eventHolder.click(onClick);executeHooks(hooks.bindEvents,[eventHolder])}function shutdown(){if(redrawTimeout)clearTimeout(redrawTimeout);eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mouseleave",onMouseLeave);eventHolder.unbind("click",onClick);executeHooks(hooks.shutdown,[eventHolder])}function setTransformationHelpers(axis){function identity(x){return x}var s,m,t=axis.options.transform||identity,it=axis.options.inverseTransform;if(axis.direction=="x"){s=axis.scale=plotWidth/Math.abs(t(axis.max)-t(axis.min));m=Math.min(t(axis.max),t(axis.min))}else{s=axis.scale=plotHeight/Math.abs(t(axis.max)-t(axis.min));s=-s;m=Math.max(t(axis.max),t(axis.min))}if(t==identity)axis.p2c=function(p){return(p-m)*s};else axis.p2c=function(p){return(t(p)-m)*s};if(!it)axis.c2p=function(c){return m+c/s};else axis.c2p=function(c){return it(m+c/s)}}function measureTickLabels(axis){var opts=axis.options,ticks=axis.ticks||[],labelWidth=opts.labelWidth||0,labelHeight=opts.labelHeight||0,maxWidth=labelWidth||(axis.direction=="x"?Math.floor(surface.width/(ticks.length||1)):null),legacyStyles=axis.direction+"Axis "+axis.direction+axis.n+"Axis",layer="flot-"+axis.direction+"-axis flot-"+axis.direction+axis.n+"-axis "+legacyStyles,font=opts.font||"flot-tick-label tickLabel";for(var i=0;i=0;--i)allocateAxisBoxFirstPhase(allocatedAxes[i]);adjustLayoutForThingsStickingOut();$.each(allocatedAxes,function(_,axis){allocateAxisBoxSecondPhase(axis)})}plotWidth=surface.width-plotOffset.left-plotOffset.right;plotHeight=surface.height-plotOffset.bottom-plotOffset.top;$.each(axes,function(_,axis){setTransformationHelpers(axis)});if(showGrid){drawAxisLabels()}insertLegend()}function setRange(axis){var opts=axis.options,min=+(opts.min!=null?opts.min:axis.datamin),max=+(opts.max!=null?opts.max:axis.datamax),delta=max-min;if(delta==0){var widen=max==0?1:.01;if(opts.min==null)min-=widen;if(opts.max==null||opts.min!=null)max+=widen}else{var margin=opts.autoscaleMargin;if(margin!=null){if(opts.min==null){min-=delta*margin;if(min<0&&axis.datamin!=null&&axis.datamin>=0)min=0}if(opts.max==null){max+=delta*margin;if(max>0&&axis.datamax!=null&&axis.datamax<=0)max=0}}}axis.min=min;axis.max=max}function setupTickGeneration(axis){var opts=axis.options;var noTicks;if(typeof opts.ticks=="number"&&opts.ticks>0)noTicks=opts.ticks;else noTicks=.3*Math.sqrt(axis.direction=="x"?surface.width:surface.height);var delta=(axis.max-axis.min)/noTicks,dec=-Math.floor(Math.log(delta)/Math.LN10),maxDec=opts.tickDecimals;if(maxDec!=null&&dec>maxDec){dec=maxDec}var magn=Math.pow(10,-dec),norm=delta/magn,size;if(norm<1.5){size=1}else if(norm<3){size=2;if(norm>2.25&&(maxDec==null||dec+1<=maxDec)){size=2.5;++dec}}else if(norm<7.5){size=5}else{size=10}size*=magn;if(opts.minTickSize!=null&&size0){if(opts.min==null)axis.min=Math.min(axis.min,niceTicks[0]);if(opts.max==null&&niceTicks.length>1)axis.max=Math.max(axis.max,niceTicks[niceTicks.length-1])}axis.tickGenerator=function(axis){var ticks=[],v,i;for(i=0;i1&&/\..*0$/.test((ts[1]-ts[0]).toFixed(extraDec))))axis.tickDecimals=extraDec}}}}function setTicks(axis){var oticks=axis.options.ticks,ticks=[];if(oticks==null||typeof oticks=="number"&&oticks>0)ticks=axis.tickGenerator(axis);else if(oticks){if($.isFunction(oticks))ticks=oticks(axis);else ticks=oticks}var i,v;axis.ticks=[];for(i=0;i1)label=t[1]}else v=+t;if(label==null)label=axis.tickFormatter(v,axis);if(!isNaN(v))axis.ticks.push({v:v,label:label})}}function snapRangeToTicks(axis,ticks){if(axis.options.autoscaleMargin&&ticks.length>0){if(axis.options.min==null)axis.min=Math.min(axis.min,ticks[0].v);if(axis.options.max==null&&ticks.length>1)axis.max=Math.max(axis.max,ticks[ticks.length-1].v)}}function draw(){surface.clear();executeHooks(hooks.drawBackground,[ctx]);var grid=options.grid;if(grid.show&&grid.backgroundColor)drawBackground();if(grid.show&&!grid.aboveData){drawGrid()}for(var i=0;ito){var tmp=from;from=to;to=tmp}return{from:from,to:to,axis:axis}}function drawBackground(){ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.fillStyle=getColorOrGradient(options.grid.backgroundColor,plotHeight,0,"rgba(255, 255, 255, 0)");ctx.fillRect(0,0,plotWidth,plotHeight);ctx.restore()}function drawGrid(){var i,axes,bw,bc;ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var markings=options.grid.markings;if(markings){if($.isFunction(markings)){axes=plot.getAxes();axes.xmin=axes.xaxis.min;axes.xmax=axes.xaxis.max;axes.ymin=axes.yaxis.min;axes.ymax=axes.yaxis.max;markings=markings(axes)}for(i=0;ixrange.axis.max||yrange.toyrange.axis.max)continue;xrange.from=Math.max(xrange.from,xrange.axis.min);xrange.to=Math.min(xrange.to,xrange.axis.max);yrange.from=Math.max(yrange.from,yrange.axis.min);yrange.to=Math.min(yrange.to,yrange.axis.max);var xequal=xrange.from===xrange.to,yequal=yrange.from===yrange.to;if(xequal&&yequal){continue}xrange.from=Math.floor(xrange.axis.p2c(xrange.from));xrange.to=Math.floor(xrange.axis.p2c(xrange.to));yrange.from=Math.floor(yrange.axis.p2c(yrange.from));yrange.to=Math.floor(yrange.axis.p2c(yrange.to));if(xequal||yequal){var lineWidth=m.lineWidth||options.grid.markingsLineWidth,subPixel=lineWidth%2?.5:0;ctx.beginPath();ctx.strokeStyle=m.color||options.grid.markingsColor;ctx.lineWidth=lineWidth;if(xequal){ctx.moveTo(xrange.to+subPixel,yrange.from);ctx.lineTo(xrange.to+subPixel,yrange.to)}else{ctx.moveTo(xrange.from,yrange.to+subPixel);ctx.lineTo(xrange.to,yrange.to+subPixel)}ctx.stroke()}else{ctx.fillStyle=m.color||options.grid.markingsColor;ctx.fillRect(xrange.from,yrange.to,xrange.to-xrange.from,yrange.from-yrange.to)}}}axes=allAxes();bw=options.grid.borderWidth;for(var j=0;jaxis.max||t=="full"&&(typeof bw=="object"&&bw[axis.position]>0||bw>0)&&(v==axis.min||v==axis.max))continue;if(axis.direction=="x"){x=axis.p2c(v);yoff=t=="full"?-plotHeight:t;if(axis.position=="top")yoff=-yoff}else{y=axis.p2c(v);xoff=t=="full"?-plotWidth:t;if(axis.position=="left")xoff=-xoff}if(ctx.lineWidth==1){if(axis.direction=="x")x=Math.floor(x)+.5;else y=Math.floor(y)+.5}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff)}ctx.stroke()}if(bw){bc=options.grid.borderColor;if(typeof bw=="object"||typeof bc=="object"){if(typeof bw!=="object"){bw={top:bw,right:bw,bottom:bw,left:bw}}if(typeof bc!=="object"){bc={top:bc,right:bc,bottom:bc,left:bc}}if(bw.top>0){ctx.strokeStyle=bc.top;ctx.lineWidth=bw.top;ctx.beginPath();ctx.moveTo(0-bw.left,0-bw.top/2);ctx.lineTo(plotWidth,0-bw.top/2);ctx.stroke()}if(bw.right>0){ctx.strokeStyle=bc.right;ctx.lineWidth=bw.right;ctx.beginPath();ctx.moveTo(plotWidth+bw.right/2,0-bw.top);ctx.lineTo(plotWidth+bw.right/2,plotHeight);ctx.stroke()}if(bw.bottom>0){ctx.strokeStyle=bc.bottom;ctx.lineWidth=bw.bottom;ctx.beginPath();ctx.moveTo(plotWidth+bw.right,plotHeight+bw.bottom/2);ctx.lineTo(0,plotHeight+bw.bottom/2);ctx.stroke()}if(bw.left>0){ctx.strokeStyle=bc.left;ctx.lineWidth=bw.left;ctx.beginPath();ctx.moveTo(0-bw.left/2,plotHeight+bw.bottom);ctx.lineTo(0-bw.left/2,0);ctx.stroke()}}else{ctx.lineWidth=bw;ctx.strokeStyle=options.grid.borderColor;ctx.strokeRect(-bw/2,-bw/2,plotWidth+bw,plotHeight+bw)}}ctx.restore()}function drawAxisLabels(){$.each(allAxes(),function(_,axis){var box=axis.box,legacyStyles=axis.direction+"Axis "+axis.direction+axis.n+"Axis",layer="flot-"+axis.direction+"-axis flot-"+axis.direction+axis.n+"-axis "+legacyStyles,font=axis.options.font||"flot-tick-label tickLabel",tick,x,y,halign,valign;surface.removeText(layer);if(!axis.show||axis.ticks.length==0)return;for(var i=0;iaxis.max)continue;if(axis.direction=="x"){halign="center";x=plotOffset.left+axis.p2c(tick.v);if(axis.position=="bottom"){y=box.top+box.padding}else{y=box.top+box.height-box.padding;valign="bottom"}}else{valign="middle";y=plotOffset.top+axis.p2c(tick.v);if(axis.position=="left"){x=box.left+box.width-box.padding;halign="right"}else{x=box.left+box.padding}}surface.addText(layer,x,y,tick.label,font,null,null,halign,valign)}})}function drawSeries(series){if(series.lines.show)drawSeriesLines(series);if(series.bars.show)drawSeriesBars(series);if(series.points.show)drawSeriesPoints(series)}function drawSeriesLines(series){function plotLine(datapoints,xoffset,yoffset,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null;ctx.beginPath();for(var i=ps;i=y2&&y1>axisy.max){if(y2>axisy.max)continue;x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max){if(y1>axisy.max)continue;x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(x1!=prevx||y1!=prevy)ctx.moveTo(axisx.p2c(x1)+xoffset,axisy.p2c(y1)+yoffset);prevx=x2;prevy=y2;ctx.lineTo(axisx.p2c(x2)+xoffset,axisy.p2c(y2)+yoffset)}ctx.stroke()}function plotLineArea(datapoints,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,bottom=Math.min(Math.max(0,axisy.min),axisy.max),i=0,top,areaOpen=false,ypos=1,segmentStart=0,segmentEnd=0;while(true){if(ps>0&&i>points.length+ps)break;i+=ps;var x1=points[i-ps],y1=points[i-ps+ypos],x2=points[i],y2=points[i+ypos];if(areaOpen){if(ps>0&&x1!=null&&x2==null){segmentEnd=i;ps=-ps;ypos=2;continue}if(ps<0&&i==segmentStart+ps){ctx.fill();areaOpen=false;ps=-ps;ypos=1;i=segmentStart=segmentEnd+ps;continue}}if(x1==null||x2==null)continue;if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(!areaOpen){ctx.beginPath();ctx.moveTo(axisx.p2c(x1),axisy.p2c(bottom));areaOpen=true}if(y1>=axisy.max&&y2>=axisy.max){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.max));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.max));continue}else if(y1<=axisy.min&&y2<=axisy.min){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.min));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.min));continue}var x1old=x1,x2old=x2;if(y1<=y2&&y1=axisy.min){x1=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.min}else if(y2<=y1&&y2=axisy.min){x2=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.min}if(y1>=y2&&y1>axisy.max&&y2<=axisy.max){x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max&&y1<=axisy.max){x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1!=x1old){ctx.lineTo(axisx.p2c(x1old),axisy.p2c(y1))}ctx.lineTo(axisx.p2c(x1),axisy.p2c(y1));ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));if(x2!=x2old){ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));ctx.lineTo(axisx.p2c(x2old),axisy.p2c(y2))}}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineJoin="round";var lw=series.lines.lineWidth,sw=series.shadowSize;if(lw>0&&sw>0){ctx.lineWidth=sw;ctx.strokeStyle="rgba(0,0,0,0.1)";var angle=Math.PI/18;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/2),Math.cos(angle)*(lw/2+sw/2),series.xaxis,series.yaxis);ctx.lineWidth=sw/2;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/4),Math.cos(angle)*(lw/2+sw/4),series.xaxis,series.yaxis)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;var fillStyle=getFillStyle(series.lines,series.color,0,plotHeight);if(fillStyle){ctx.fillStyle=fillStyle;plotLineArea(series.datapoints,series.xaxis,series.yaxis)}if(lw>0)plotLine(series.datapoints,0,0,series.xaxis,series.yaxis);ctx.restore()}function drawSeriesPoints(series){function plotPoints(datapoints,radius,fillStyle,offset,shadow,axisx,axisy,symbol){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;iaxisx.max||yaxisy.max)continue;ctx.beginPath();x=axisx.p2c(x);y=axisy.p2c(y)+offset;if(symbol=="circle")ctx.arc(x,y,radius,0,shadow?Math.PI:Math.PI*2,false);else symbol(ctx,x,y,radius,shadow);ctx.closePath();if(fillStyle){ctx.fillStyle=fillStyle;ctx.fill()}ctx.stroke()}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var lw=series.points.lineWidth,sw=series.shadowSize,radius=series.points.radius,symbol=series.points.symbol;if(lw==0)lw=1e-4;if(lw>0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";plotPoints(series.datapoints,radius,null,w+w/2,true,series.xaxis,series.yaxis,symbol);ctx.strokeStyle="rgba(0,0,0,0.2)";plotPoints(series.datapoints,radius,null,w/2,true,series.xaxis,series.yaxis,symbol)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;plotPoints(series.datapoints,radius,getFillStyle(series.points,series.color),0,false,series.xaxis,series.yaxis,symbol);ctx.restore()}function drawBar(x,y,b,barLeft,barRight,fillStyleCallback,axisx,axisy,c,horizontal,lineWidth){var left,right,bottom,top,drawLeft,drawRight,drawTop,drawBottom,tmp;if(horizontal){drawBottom=drawRight=drawTop=true;drawLeft=false;left=b;right=x;top=y+barLeft;bottom=y+barRight;if(rightaxisx.max||topaxisy.max)return;if(leftaxisx.max){right=axisx.max;drawRight=false}if(bottomaxisy.max){top=axisy.max;drawTop=false}left=axisx.p2c(left);bottom=axisy.p2c(bottom);right=axisx.p2c(right);top=axisy.p2c(top);if(fillStyleCallback){c.fillStyle=fillStyleCallback(bottom,top);c.fillRect(left,top,right-left,bottom-top)}if(lineWidth>0&&(drawLeft||drawRight||drawTop||drawBottom)){c.beginPath();c.moveTo(left,bottom);if(drawLeft)c.lineTo(left,top);else c.moveTo(left,top);if(drawTop)c.lineTo(right,top);else c.moveTo(right,top);if(drawRight)c.lineTo(right,bottom);else c.moveTo(right,bottom);if(drawBottom)c.lineTo(left,bottom);else c.moveTo(left,bottom);c.stroke()}}function drawSeriesBars(series){function plotBars(datapoints,barLeft,barRight,fillStyleCallback,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;i");fragments.push("");rowStarted=true}fragments.push('
'+''+entry.label+"")}if(rowStarted)fragments.push("");if(fragments.length==0)return;var table=''+fragments.join("")+"
";if(options.legend.container!=null)$(options.legend.container).html(table);else{var pos="",p=options.legend.position,m=options.legend.margin;if(m[0]==null)m=[m,m];if(p.charAt(0)=="n")pos+="top:"+(m[1]+plotOffset.top)+"px;";else if(p.charAt(0)=="s")pos+="bottom:"+(m[1]+plotOffset.bottom)+"px;";if(p.charAt(1)=="e")pos+="right:"+(m[0]+plotOffset.right)+"px;";else if(p.charAt(1)=="w")pos+="left:"+(m[0]+plotOffset.left)+"px;";var legend=$('
'+table.replace('style="','style="position:absolute;'+pos+";")+"
").appendTo(placeholder);if(options.legend.backgroundOpacity!=0){var c=options.legend.backgroundColor;if(c==null){c=options.grid.backgroundColor;if(c&&typeof c=="string")c=$.color.parse(c);else c=$.color.extract(legend,"background-color");c.a=1;c=c.toString()}var div=legend.children();$('
').prependTo(legend).css("opacity",options.legend.backgroundOpacity)}}}var highlights=[],redrawTimeout=null;function findNearbyItem(mouseX,mouseY,seriesFilter){var maxDistance=options.grid.mouseActiveRadius,smallestDistance=maxDistance*maxDistance+1,item=null,foundPoint=false,i,j,ps;for(i=series.length-1;i>=0;--i){if(!seriesFilter(series[i]))continue;var s=series[i],axisx=s.xaxis,axisy=s.yaxis,points=s.datapoints.points,mx=axisx.c2p(mouseX),my=axisy.c2p(mouseY),maxx=maxDistance/axisx.scale,maxy=maxDistance/axisy.scale;ps=s.datapoints.pointsize;if(axisx.options.inverseTransform)maxx=Number.MAX_VALUE;if(axisy.options.inverseTransform)maxy=Number.MAX_VALUE;if(s.lines.show||s.points.show){for(j=0;jmaxx||x-mx<-maxx||y-my>maxy||y-my<-maxy)continue;var dx=Math.abs(axisx.p2c(x)-mouseX),dy=Math.abs(axisy.p2c(y)-mouseY),dist=dx*dx+dy*dy;if(dist=Math.min(b,x)&&my>=y+barLeft&&my<=y+barRight:mx>=x+barLeft&&mx<=x+barRight&&my>=Math.min(b,y)&&my<=Math.max(b,y))item=[i,j/ps]}}}if(item){i=item[0];j=item[1];ps=series[i].datapoints.pointsize;return{datapoint:series[i].datapoints.points.slice(j*ps,(j+1)*ps),dataIndex:j,series:series[i],seriesIndex:i}}return null}function onMouseMove(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return s["hoverable"]!=false})}function onMouseLeave(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return false})}function onClick(e){triggerClickHoverEvent("plotclick",e,function(s){return s["clickable"]!=false})}function triggerClickHoverEvent(eventname,event,seriesFilter){var offset=eventHolder.offset(),canvasX=event.pageX-offset.left-plotOffset.left,canvasY=event.pageY-offset.top-plotOffset.top,pos=canvasToAxisCoords({left:canvasX,top:canvasY});pos.pageX=event.pageX;pos.pageY=event.pageY;var item=findNearbyItem(canvasX,canvasY,seriesFilter);if(item){item.pageX=parseInt(item.series.xaxis.p2c(item.datapoint[0])+offset.left+plotOffset.left,10);item.pageY=parseInt(item.series.yaxis.p2c(item.datapoint[1])+offset.top+plotOffset.top,10)}if(options.grid.autoHighlight){for(var i=0;iaxisx.max||yaxisy.max)return;var pointRadius=series.points.radius+series.points.lineWidth/2;octx.lineWidth=pointRadius;octx.strokeStyle=highlightColor;var radius=1.5*pointRadius;x=axisx.p2c(x);y=axisy.p2c(y);octx.beginPath();if(series.points.symbol=="circle")octx.arc(x,y,radius,0,2*Math.PI,false);else series.points.symbol(octx,x,y,radius,false);octx.closePath();octx.stroke()}function drawBarHighlight(series,point){var highlightColor=typeof series.highlightColor==="string"?series.highlightColor:$.color.parse(series.color).scale("a",.5).toString(),fillStyle=highlightColor,barLeft;switch(series.bars.align){case"left":barLeft=0;break;case"right":barLeft=-series.bars.barWidth;break;default:barLeft=-series.bars.barWidth/2}octx.lineWidth=series.bars.lineWidth;octx.strokeStyle=highlightColor;drawBar(point[0],point[1],point[2]||0,barLeft,barLeft+series.bars.barWidth,function(){return fillStyle},series.xaxis,series.yaxis,octx,series.bars.horizontal,series.bars.lineWidth)}function getColorOrGradient(spec,bottom,top,defaultColor){if(typeof spec=="string")return spec;else{var gradient=ctx.createLinearGradient(0,top,0,bottom);for(var i=0,l=spec.colors.length;i0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY) max) { - // make sure min < max - var tmp = min; - min = max; - max = tmp; - } - - //Check that we are in panRange - if (pr) { - if (pr[0] != null && min < pr[0]) { - min = pr[0]; - } - if (pr[1] != null && max > pr[1]) { - max = pr[1]; - } - } - - var range = max - min; - if (zr && - ((zr[0] != null && range < zr[0] && amount >1) || - (zr[1] != null && range > zr[1] && amount <1))) - return; - - opts.min = min; - opts.max = max; - }); - - plot.setupGrid(); - plot.draw(); - - if (!args.preventEvent) - plot.getPlaceholder().trigger("plotzoom", [ plot, args ]); - }; - - plot.pan = function (args) { - var delta = { - x: +args.left, - y: +args.top - }; - - if (isNaN(delta.x)) - delta.x = 0; - if (isNaN(delta.y)) - delta.y = 0; - - $.each(plot.getAxes(), function (_, axis) { - var opts = axis.options, - min, max, d = delta[axis.direction]; - - min = axis.c2p(axis.p2c(axis.min) + d), - max = axis.c2p(axis.p2c(axis.max) + d); - - var pr = opts.panRange; - if (pr === false) // no panning on this axis - return; - - if (pr) { - // check whether we hit the wall - if (pr[0] != null && pr[0] > min) { - d = pr[0] - min; - min += d; - max += d; - } - - if (pr[1] != null && pr[1] < max) { - d = pr[1] - max; - min += d; - max += d; - } - } - - opts.min = min; - opts.max = max; - }); - - plot.setupGrid(); - plot.draw(); - - if (!args.preventEvent) - plot.getPlaceholder().trigger("plotpan", [ plot, args ]); - }; - - function shutdown(plot, eventHolder) { - eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick); - eventHolder.unbind("mousewheel", onMouseWheel); - eventHolder.unbind("dragstart", onDragStart); - eventHolder.unbind("drag", onDrag); - eventHolder.unbind("dragend", onDragEnd); - if (panTimeout) - clearTimeout(panTimeout); - } - - plot.hooks.bindEvents.push(bindEvents); - plot.hooks.shutdown.push(shutdown); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'navigate', - version: '1.3' - }); -})(jQuery); diff --git a/flot/jquery.flot.navigate.min.js b/flot/jquery.flot.navigate.min.js new file mode 100644 index 0000000..7288a23 --- /dev/null +++ b/flot/jquery.flot.navigate.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)max){var tmp=min;min=max;max=tmp}if(pr){if(pr[0]!=null&&minpr[1]){max=pr[1]}}var range=max-min;if(zr&&(zr[0]!=null&&range1||zr[1]!=null&&range>zr[1]&&amount<1))return;opts.min=min;opts.max=max});plot.setupGrid();plot.draw();if(!args.preventEvent)plot.getPlaceholder().trigger("plotzoom",[plot,args])};plot.pan=function(args){var delta={x:+args.left,y:+args.top};if(isNaN(delta.x))delta.x=0;if(isNaN(delta.y))delta.y=0;$.each(plot.getAxes(),function(_,axis){var opts=axis.options,min,max,d=delta[axis.direction];min=axis.c2p(axis.p2c(axis.min)+d),max=axis.c2p(axis.p2c(axis.max)+d);var pr=opts.panRange;if(pr===false)return;if(pr){if(pr[0]!=null&&pr[0]>min){d=pr[0]-min;min+=d;max+=d}if(pr[1]!=null&&pr[1]1){options.series.pie.tilt=1}else if(options.series.pie.tilt<0){options.series.pie.tilt=0}}});plot.hooks.bindEvents.push(function(plot,eventHolder){var options=plot.getOptions();if(options.series.pie.show){if(options.grid.hoverable){eventHolder.unbind("mousemove").mousemove(onMouseMove)}if(options.grid.clickable){eventHolder.unbind("click").click(onClick)}}});plot.hooks.processDatapoints.push(function(plot,series,data,datapoints){var options=plot.getOptions();if(options.series.pie.show){processDatapoints(plot,series,data,datapoints)}});plot.hooks.drawOverlay.push(function(plot,octx){var options=plot.getOptions();if(options.series.pie.show){drawOverlay(plot,octx)}});plot.hooks.draw.push(function(plot,newCtx){var options=plot.getOptions();if(options.series.pie.show){draw(plot,newCtx)}});function processDatapoints(plot,series,datapoints){if(!processed){processed=true;canvas=plot.getCanvas();target=$(canvas).parent();options=plot.getOptions();plot.setData(combine(plot.getData()))}}function combine(data){var total=0,combined=0,numCombined=0,color=options.series.pie.combine.color,newdata=[];for(var i=0;ioptions.series.pie.combine.threshold){newdata.push($.extend(data[i],{data:[[1,value]],color:data[i].color,label:data[i].label,angle:value*Math.PI*2/total,percent:value/(total/100)}))}}if(numCombined>1){newdata.push({data:[[1,combined]],color:color,label:options.series.pie.combine.label,angle:combined*Math.PI*2/total,percent:combined/(total/100)})}return newdata}function draw(plot,newCtx){if(!target){return}var canvasWidth=plot.getPlaceholder().width(),canvasHeight=plot.getPlaceholder().height(),legendWidth=target.children().filter(".legend").children().width()||0;ctx=newCtx;processed=false;maxRadius=Math.min(canvasWidth,canvasHeight/options.series.pie.tilt)/2;centerTop=canvasHeight/2+options.series.pie.offset.top;centerLeft=canvasWidth/2;if(options.series.pie.offset.left=="auto"){if(options.legend.position.match("w")){centerLeft+=legendWidth/2}else{centerLeft-=legendWidth/2}if(centerLeftcanvasWidth-maxRadius){centerLeft=canvasWidth-maxRadius}}else{centerLeft+=options.series.pie.offset.left}var slices=plot.getData(),attempts=0;do{if(attempts>0){maxRadius*=REDRAW_SHRINK}attempts+=1;clear();if(options.series.pie.tilt<=.8){drawShadow()}}while(!drawPie()&&attempts=REDRAW_ATTEMPTS){clear();target.prepend("
Could not draw pie with labels contained inside canvas
")}if(plot.setSeries&&plot.insertLegend){plot.setSeries(slices);plot.insertLegend()}function clear(){ctx.clearRect(0,0,canvasWidth,canvasHeight);target.children().filter(".pieLabel, .pieLabelBackground").remove()}function drawShadow(){var shadowLeft=options.series.pie.shadow.left;var shadowTop=options.series.pie.shadow.top;var edge=10;var alpha=options.series.pie.shadow.alpha;var radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius;if(radius>=canvasWidth/2-shadowLeft||radius*options.series.pie.tilt>=canvasHeight/2-shadowTop||radius<=edge){return}ctx.save();ctx.translate(shadowLeft,shadowTop);ctx.globalAlpha=alpha;ctx.fillStyle="#000";ctx.translate(centerLeft,centerTop);ctx.scale(1,options.series.pie.tilt);for(var i=1;i<=edge;i++){ctx.beginPath();ctx.arc(0,0,radius,0,Math.PI*2,false);ctx.fill();radius-=i}ctx.restore()}function drawPie(){var startAngle=Math.PI*options.series.pie.startAngle;var radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius;ctx.save();ctx.translate(centerLeft,centerTop);ctx.scale(1,options.series.pie.tilt);ctx.save();var currentAngle=startAngle;for(var i=0;i0){ctx.save();ctx.lineWidth=options.series.pie.stroke.width;currentAngle=startAngle;for(var i=0;i1e-9){ctx.moveTo(0,0)}ctx.arc(0,0,radius,currentAngle,currentAngle+angle/2,false);ctx.arc(0,0,radius,currentAngle+angle/2,currentAngle+angle,false);ctx.closePath();currentAngle+=angle;if(fill){ctx.fill()}else{ctx.stroke()}}function drawLabels(){var currentAngle=startAngle;var radius=options.series.pie.label.radius>1?options.series.pie.label.radius:maxRadius*options.series.pie.label.radius;for(var i=0;i=options.series.pie.label.threshold*100){if(!drawLabel(slices[i],currentAngle,i)){return false}}currentAngle+=slices[i].angle}return true;function drawLabel(slice,startAngle,index){if(slice.data[0][1]==0){return true}var lf=options.legend.labelFormatter,text,plf=options.series.pie.label.formatter;if(lf){text=lf(slice.label,slice)}else{text=slice.label}if(plf){text=plf(text,slice)}var halfAngle=(startAngle+slice.angle+startAngle)/2;var x=centerLeft+Math.round(Math.cos(halfAngle)*radius);var y=centerTop+Math.round(Math.sin(halfAngle)*radius)*options.series.pie.tilt;var html=""+text+"";target.append(html);var label=target.children("#pieLabel"+index);var labelTop=y-label.height()/2;var labelLeft=x-label.width()/2;label.css("top",labelTop);label.css("left",labelLeft);if(0-labelTop>0||0-labelLeft>0||canvasHeight-(labelTop+label.height())<0||canvasWidth-(labelLeft+label.width())<0){return false}if(options.series.pie.label.background.opacity!=0){var c=options.series.pie.label.background.color;if(c==null){c=slice.color}var pos="top:"+labelTop+"px;left:"+labelLeft+"px;";$("
").css("opacity",options.series.pie.label.background.opacity).insertBefore(label)}return true}}}}function drawDonutHole(layer){if(options.series.pie.innerRadius>0){layer.save();var innerRadius=options.series.pie.innerRadius>1?options.series.pie.innerRadius:maxRadius*options.series.pie.innerRadius;layer.globalCompositeOperation="destination-out";layer.beginPath();layer.fillStyle=options.series.pie.stroke.color;layer.arc(0,0,innerRadius,0,Math.PI*2,false);layer.fill();layer.closePath();layer.restore();layer.save();layer.beginPath();layer.strokeStyle=options.series.pie.stroke.color;layer.arc(0,0,innerRadius,0,Math.PI*2,false);layer.stroke();layer.closePath();layer.restore()}}function isPointInPoly(poly,pt){for(var c=false,i=-1,l=poly.length,j=l-1;++i1?options.series.pie.radius:maxRadius*options.series.pie.radius,x,y;for(var i=0;i1?options.series.pie.radius:maxRadius*options.series.pie.radius;octx.save();octx.translate(centerLeft,centerTop);octx.scale(1,options.series.pie.tilt);for(var i=0;i1e-9){octx.moveTo(0,0)}octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle/2,false);octx.arc(0,0,radius,series.startAngle+series.angle/2,series.startAngle+series.angle,false);octx.closePath();octx.fill()}}}var options={series:{pie:{show:false,radius:"auto",innerRadius:0,startAngle:3/2,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(label,slice){return"
"+label+"
"+Math.round(slice.percent)+"%
"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};$.plot.plugins.push({init:init,options:options,name:"pie",version:"1.1"})})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.resize.min.js b/flot/jquery.flot.resize.min.js new file mode 100644 index 0000000..7e92aa6 --- /dev/null +++ b/flot/jquery.flot.resize.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);(function($){var options={};function init(plot){function onResize(){var placeholder=plot.getPlaceholder();if(placeholder.width()==0||placeholder.height()==0)return;plot.resize();plot.setupGrid();plot.draw()}function bindEvents(plot,eventHolder){plot.getPlaceholder().resize(onResize)}function shutdown(plot,eventHolder){plot.getPlaceholder().unbind("resize",onResize)}plot.hooks.bindEvents.push(bindEvents);plot.hooks.shutdown.push(shutdown)}$.plot.plugins.push({init:init,options:options,name:"resize",version:"1.0"})})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.selection.min.js b/flot/jquery.flot.selection.min.js new file mode 100644 index 0000000..a0154fb --- /dev/null +++ b/flot/jquery.flot.selection.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){function init(plot){var selection={first:{x:-1,y:-1},second:{x:-1,y:-1},show:false,active:false};var savedhandlers={};var mouseUpHandler=null;function onMouseMove(e){if(selection.active){updateSelection(e);plot.getPlaceholder().trigger("plotselecting",[getSelection()])}}function onMouseDown(e){if(e.which!=1)return;document.body.focus();if(document.onselectstart!==undefined&&savedhandlers.onselectstart==null){savedhandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!==undefined&&savedhandlers.ondrag==null){savedhandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}setSelectionPos(selection.first,e);selection.active=true;mouseUpHandler=function(e){onMouseUp(e)};$(document).one("mouseup",mouseUpHandler)}function onMouseUp(e){mouseUpHandler=null;if(document.onselectstart!==undefined)document.onselectstart=savedhandlers.onselectstart;if(document.ondrag!==undefined)document.ondrag=savedhandlers.ondrag;selection.active=false;updateSelection(e);if(selectionIsSane())triggerSelectedEvent();else{plot.getPlaceholder().trigger("plotunselected",[]);plot.getPlaceholder().trigger("plotselecting",[null])}return false}function getSelection(){if(!selectionIsSane())return null;if(!selection.show)return null;var r={},c1=selection.first,c2=selection.second;$.each(plot.getAxes(),function(name,axis){if(axis.used){var p1=axis.c2p(c1[axis.direction]),p2=axis.c2p(c2[axis.direction]);r[name]={from:Math.min(p1,p2),to:Math.max(p1,p2)}}});return r}function triggerSelectedEvent(){var r=getSelection();plot.getPlaceholder().trigger("plotselected",[r]);if(r.xaxis&&r.yaxis)plot.getPlaceholder().trigger("selected",[{x1:r.xaxis.from,y1:r.yaxis.from,x2:r.xaxis.to,y2:r.yaxis.to}])}function clamp(min,value,max){return valuemax?max:value}function setSelectionPos(pos,e){var o=plot.getOptions();var offset=plot.getPlaceholder().offset();var plotOffset=plot.getPlotOffset();pos.x=clamp(0,e.pageX-offset.left-plotOffset.left,plot.width());pos.y=clamp(0,e.pageY-offset.top-plotOffset.top,plot.height());if(o.selection.mode=="y")pos.x=pos==selection.first?0:plot.width();if(o.selection.mode=="x")pos.y=pos==selection.first?0:plot.height()}function updateSelection(pos){if(pos.pageX==null)return;setSelectionPos(selection.second,pos);if(selectionIsSane()){selection.show=true;plot.triggerRedrawOverlay()}else clearSelection(true)}function clearSelection(preventEvent){if(selection.show){selection.show=false;plot.triggerRedrawOverlay();if(!preventEvent)plot.getPlaceholder().trigger("plotunselected",[])}}function extractRange(ranges,coord){var axis,from,to,key,axes=plot.getAxes();for(var k in axes){axis=axes[k];if(axis.direction==coord){key=coord+axis.n+"axis";if(!ranges[key]&&axis.n==1)key=coord+"axis";if(ranges[key]){from=ranges[key].from;to=ranges[key].to;break}}}if(!ranges[key]){axis=coord=="x"?plot.getXAxes()[0]:plot.getYAxes()[0];from=ranges[coord+"1"];to=ranges[coord+"2"]}if(from!=null&&to!=null&&from>to){var tmp=from;from=to;to=tmp}return{from:from,to:to,axis:axis}}function setSelection(ranges,preventEvent){var axis,range,o=plot.getOptions();if(o.selection.mode=="y"){selection.first.x=0;selection.second.x=plot.width()}else{range=extractRange(ranges,"x");selection.first.x=range.axis.p2c(range.from);selection.second.x=range.axis.p2c(range.to)}if(o.selection.mode=="x"){selection.first.y=0;selection.second.y=plot.height()}else{range=extractRange(ranges,"y");selection.first.y=range.axis.p2c(range.from);selection.second.y=range.axis.p2c(range.to)}selection.show=true;plot.triggerRedrawOverlay();if(!preventEvent&&selectionIsSane())triggerSelectedEvent()}function selectionIsSane(){var minSize=plot.getOptions().selection.minSize;return Math.abs(selection.second.x-selection.first.x)>=minSize&&Math.abs(selection.second.y-selection.first.y)>=minSize}plot.clearSelection=clearSelection;plot.setSelection=setSelection;plot.getSelection=getSelection;plot.hooks.bindEvents.push(function(plot,eventHolder){var o=plot.getOptions();if(o.selection.mode!=null){eventHolder.mousemove(onMouseMove);eventHolder.mousedown(onMouseDown)}});plot.hooks.drawOverlay.push(function(plot,ctx){if(selection.show&&selectionIsSane()){var plotOffset=plot.getPlotOffset();var o=plot.getOptions();ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var c=$.color.parse(o.selection.color);ctx.strokeStyle=c.scale("a",.8).toString();ctx.lineWidth=1;ctx.lineJoin=o.selection.shape;ctx.fillStyle=c.scale("a",.4).toString();var x=Math.min(selection.first.x,selection.second.x)+.5,y=Math.min(selection.first.y,selection.second.y)+.5,w=Math.abs(selection.second.x-selection.first.x)-1,h=Math.abs(selection.second.y-selection.first.y)-1;ctx.fillRect(x,y,w,h);ctx.strokeRect(x,y,w,h);ctx.restore()}});plot.hooks.shutdown.push(function(plot,eventHolder){eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mousedown",onMouseDown);if(mouseUpHandler)$(document).unbind("mouseup",mouseUpHandler)})}$.plot.plugins.push({init:init,options:{selection:{mode:null,color:"#e8cfac",shape:"round",minSize:5}},name:"selection",version:"1.1"})})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.stack.js b/flot/jquery.flot.stack.js deleted file mode 100644 index e75a7df..0000000 --- a/flot/jquery.flot.stack.js +++ /dev/null @@ -1,188 +0,0 @@ -/* Flot plugin for stacking data sets rather than overlyaing them. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin assumes the data is sorted on x (or y if stacking horizontally). -For line charts, it is assumed that if a line has an undefined gap (from a -null point), then the line above it should have the same gap - insert zeros -instead of "null" if you want another behaviour. This also holds for the start -and end of the chart. Note that stacking a mix of positive and negative values -in most instances doesn't make sense (so it looks weird). - -Two or more series are stacked when their "stack" attribute is set to the same -key (which can be any number or string or just "true"). To specify the default -stack, you can set the stack option like this: - - series: { - stack: null/false, true, or a key (number/string) - } - -You can also specify it for a single series, like this: - - $.plot( $("#placeholder"), [{ - data: [ ... ], - stack: true - }]) - -The stacking order is determined by the order of the data series in the array -(later series end up on top of the previous). - -Internally, the plugin modifies the datapoints in each series, adding an -offset to the y value. For line series, extra data points are inserted through -interpolation. If there's a second y value, it's also adjusted (e.g for bar -charts or filled areas). - -*/ - -(function ($) { - var options = { - series: { stack: null } // or number/string - }; - - function init(plot) { - function findMatchingSeries(s, allseries) { - var res = null; - for (var i = 0; i < allseries.length; ++i) { - if (s == allseries[i]) - break; - - if (allseries[i].stack == s.stack) - res = allseries[i]; - } - - return res; - } - - function stackData(plot, s, datapoints) { - if (s.stack == null || s.stack === false) - return; - - var other = findMatchingSeries(s, plot.getData()); - if (!other) - return; - - var ps = datapoints.pointsize, - points = datapoints.points, - otherps = other.datapoints.pointsize, - otherpoints = other.datapoints.points, - newpoints = [], - px, py, intery, qx, qy, bottom, - withlines = s.lines.show, - horizontal = s.bars.horizontal, - withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y), - withsteps = withlines && s.lines.steps, - fromgap = true, - keyOffset = horizontal ? 1 : 0, - accumulateOffset = horizontal ? 0 : 1, - i = 0, j = 0, l, m; - - while (true) { - if (i >= points.length) - break; - - l = newpoints.length; - - if (points[i] == null) { - // copy gaps - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - i += ps; - } - else if (j >= otherpoints.length) { - // for lines, we can't use the rest of the points - if (!withlines) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - } - i += ps; - } - else if (otherpoints[j] == null) { - // oops, got a gap - for (m = 0; m < ps; ++m) - newpoints.push(null); - fromgap = true; - j += otherps; - } - else { - // cases where we actually got two points - px = points[i + keyOffset]; - py = points[i + accumulateOffset]; - qx = otherpoints[j + keyOffset]; - qy = otherpoints[j + accumulateOffset]; - bottom = 0; - - if (px == qx) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - newpoints[l + accumulateOffset] += qy; - bottom = qy; - - i += ps; - j += otherps; - } - else if (px > qx) { - // we got past point below, might need to - // insert interpolated extra point - if (withlines && i > 0 && points[i - ps] != null) { - intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px); - newpoints.push(qx); - newpoints.push(intery + qy); - for (m = 2; m < ps; ++m) - newpoints.push(points[i + m]); - bottom = qy; - } - - j += otherps; - } - else { // px < qx - if (fromgap && withlines) { - // if we come from a gap, we just skip this point - i += ps; - continue; - } - - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - // we might be able to interpolate a point below, - // this can give us a better y - if (withlines && j > 0 && otherpoints[j - otherps] != null) - bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx); - - newpoints[l + accumulateOffset] += bottom; - - i += ps; - } - - fromgap = false; - - if (l != newpoints.length && withbottom) - newpoints[l + 2] += bottom; - } - - // maintain the line steps invariant - if (withsteps && l != newpoints.length && l > 0 - && newpoints[l] != null - && newpoints[l] != newpoints[l - ps] - && newpoints[l + 1] != newpoints[l - ps + 1]) { - for (m = 0; m < ps; ++m) - newpoints[l + ps + m] = newpoints[l + m]; - newpoints[l + 1] = newpoints[l - ps + 1]; - } - } - - datapoints.points = newpoints; - } - - plot.hooks.processDatapoints.push(stackData); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'stack', - version: '1.2' - }); -})(jQuery); diff --git a/flot/jquery.flot.stack.min.js b/flot/jquery.flot.stack.min.js new file mode 100644 index 0000000..920764f --- /dev/null +++ b/flot/jquery.flot.stack.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){var options={series:{stack:null}};function init(plot){function findMatchingSeries(s,allseries){var res=null;for(var i=0;i2&&(horizontal?datapoints.format[2].x:datapoints.format[2].y),withsteps=withlines&&s.lines.steps,fromgap=true,keyOffset=horizontal?1:0,accumulateOffset=horizontal?0:1,i=0,j=0,l,m;while(true){if(i>=points.length)break;l=newpoints.length;if(points[i]==null){for(m=0;m=otherpoints.length){if(!withlines){for(m=0;mqx){if(withlines&&i>0&&points[i-ps]!=null){intery=py+(points[i-ps+accumulateOffset]-py)*(qx-px)/(points[i-ps+keyOffset]-px);newpoints.push(qx);newpoints.push(intery+qy);for(m=2;m0&&otherpoints[j-otherps]!=null)bottom=qy+(otherpoints[j-otherps+accumulateOffset]-qy)*(px-qx)/(otherpoints[j-otherps+keyOffset]-qx);newpoints[l+accumulateOffset]+=bottom;i+=ps}fromgap=false;if(l!=newpoints.length&&withbottom)newpoints[l+2]+=bottom}if(withsteps&&l!=newpoints.length&&l>0&&newpoints[l]!=null&&newpoints[l]!=newpoints[l-ps]&&newpoints[l+1]!=newpoints[l-ps+1]){for(m=0;m 0 && origpoints[i - ps] != null) { - var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]); - prevp.push(interx); - prevp.push(below); - for (m = 2; m < ps; ++m) - prevp.push(origpoints[i + m]); - - p.push(null); // start new segment - p.push(null); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - p.push(interx); - p.push(below); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - } - - p.push(x); - p.push(y); - for (m = 2; m < ps; ++m) - p.push(origpoints[i + m]); - } - - datapoints.points = newpoints; - thresholded.datapoints.points = threspoints; - - if (thresholded.datapoints.points.length > 0) { - var origIndex = $.inArray(s, plot.getData()); - // Insert newly-generated series right after original one (to prevent it from becoming top-most) - plot.getData().splice(origIndex + 1, 0, thresholded); - } - - // FIXME: there are probably some edge cases left in bars - } - - function processThresholds(plot, s, datapoints) { - if (!s.threshold) - return; - - if (s.threshold instanceof Array) { - s.threshold.sort(function(a, b) { - return a.below - b.below; - }); - - $(s.threshold).each(function(i, th) { - thresholdData(plot, s, datapoints, th.below, th.color); - }); - } - else { - thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color); - } - } - - plot.hooks.processDatapoints.push(processThresholds); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'threshold', - version: '1.2' - }); -})(jQuery); diff --git a/flot/jquery.flot.threshold.min.js b/flot/jquery.flot.threshold.min.js new file mode 100644 index 0000000..ce93e0f --- /dev/null +++ b/flot/jquery.flot.threshold.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){var options={series:{threshold:null}};function init(plot){function thresholdData(plot,s,datapoints,below,color){var ps=datapoints.pointsize,i,x,y,p,prevp,thresholded=$.extend({},s);thresholded.datapoints={points:[],pointsize:ps,format:datapoints.format};thresholded.label=null;thresholded.color=color;thresholded.threshold=null;thresholded.originSeries=s;thresholded.data=[];var origpoints=datapoints.points,addCrossingPoints=s.lines.show;var threspoints=[];var newpoints=[];var m;for(i=0;i0&&origpoints[i-ps]!=null){var interx=x+(below-y)*(x-origpoints[i-ps])/(y-origpoints[i-ps+1]);prevp.push(interx);prevp.push(below);for(m=2;m0){var origIndex=$.inArray(s,plot.getData());plot.getData().splice(origIndex+1,0,thresholded)}}function processThresholds(plot,s,datapoints){if(!s.threshold)return;if(s.threshold instanceof Array){s.threshold.sort(function(a,b){return a.below-b.below});$(s.threshold).each(function(i,th){thresholdData(plot,s,datapoints,th.below,th.color)})}else{thresholdData(plot,s,datapoints,s.threshold.below,s.threshold.color)}}plot.hooks.processDatapoints.push(processThresholds)}$.plot.plugins.push({init:init,options:options,name:"threshold",version:"1.2"})})(jQuery); \ No newline at end of file diff --git a/flot/jquery.flot.time.js b/flot/jquery.flot.time.js deleted file mode 100644 index 15f5281..0000000 --- a/flot/jquery.flot.time.js +++ /dev/null @@ -1,431 +0,0 @@ -/* Pretty handling of time axes. - -Copyright (c) 2007-2013 IOLA and Ole Laursen. -Licensed under the MIT license. - -Set axis.mode to "time" to enable. See the section "Time series data" in -API.txt for details. - -*/ - -(function($) { - - var options = { - xaxis: { - timezone: null, // "browser" for local to the client or timezone for timezone-js - timeformat: null, // format string to use - twelveHourClock: false, // 12 or 24 time in time mode - monthNames: null // list of names of months - } - }; - - // round to nearby lower multiple of base - - function floorInBase(n, base) { - return base * Math.floor(n / base); - } - - // Returns a string with the date d formatted according to fmt. - // A subset of the Open Group's strftime format is supported. - - function formatDate(d, fmt, monthNames, dayNames) { - - if (typeof d.strftime == "function") { - return d.strftime(fmt); - } - - var leftPad = function(n, pad) { - n = "" + n; - pad = "" + (pad == null ? "0" : pad); - return n.length == 1 ? pad + n : n; - }; - - var r = []; - var escape = false; - var hours = d.getHours(); - var isAM = hours < 12; - - if (monthNames == null) { - monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - } - - if (dayNames == null) { - dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - } - - var hours12; - - if (hours > 12) { - hours12 = hours - 12; - } else if (hours == 0) { - hours12 = 12; - } else { - hours12 = hours; - } - - for (var i = 0; i < fmt.length; ++i) { - - var c = fmt.charAt(i); - - if (escape) { - switch (c) { - case 'a': c = "" + dayNames[d.getDay()]; break; - case 'b': c = "" + monthNames[d.getMonth()]; break; - case 'd': c = leftPad(d.getDate()); break; - case 'e': c = leftPad(d.getDate(), " "); break; - case 'h': // For back-compat with 0.7; remove in 1.0 - case 'H': c = leftPad(hours); break; - case 'I': c = leftPad(hours12); break; - case 'l': c = leftPad(hours12, " "); break; - case 'm': c = leftPad(d.getMonth() + 1); break; - case 'M': c = leftPad(d.getMinutes()); break; - // quarters not in Open Group's strftime specification - case 'q': - c = "" + (Math.floor(d.getMonth() / 3) + 1); break; - case 'S': c = leftPad(d.getSeconds()); break; - case 'y': c = leftPad(d.getFullYear() % 100); break; - case 'Y': c = "" + d.getFullYear(); break; - case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; - case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; - case 'w': c = "" + d.getDay(); break; - } - r.push(c); - escape = false; - } else { - if (c == "%") { - escape = true; - } else { - r.push(c); - } - } - } - - return r.join(""); - } - - // To have a consistent view of time-based data independent of which time - // zone the client happens to be in we need a date-like object independent - // of time zones. This is done through a wrapper that only calls the UTC - // versions of the accessor methods. - - function makeUtcWrapper(d) { - - function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { - sourceObj[sourceMethod] = function() { - return targetObj[targetMethod].apply(targetObj, arguments); - }; - }; - - var utc = { - date: d - }; - - // support strftime, if found - - if (d.strftime != undefined) { - addProxyMethod(utc, "strftime", d, "strftime"); - } - - addProxyMethod(utc, "getTime", d, "getTime"); - addProxyMethod(utc, "setTime", d, "setTime"); - - var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; - - for (var p = 0; p < props.length; p++) { - addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); - addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); - } - - return utc; - }; - - // select time zone strategy. This returns a date-like object tied to the - // desired timezone - - function dateGenerator(ts, opts) { - if (opts.timezone == "browser") { - return new Date(ts); - } else if (!opts.timezone || opts.timezone == "utc") { - return makeUtcWrapper(new Date(ts)); - } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { - var d = new timezoneJS.Date(); - // timezone-js is fickle, so be sure to set the time zone before - // setting the time. - d.setTimezone(opts.timezone); - d.setTime(ts); - return d; - } else { - return makeUtcWrapper(new Date(ts)); - } - } - - // map of app. size of time units in milliseconds - - var timeUnitSize = { - "second": 1000, - "minute": 60 * 1000, - "hour": 60 * 60 * 1000, - "day": 24 * 60 * 60 * 1000, - "month": 30 * 24 * 60 * 60 * 1000, - "quarter": 3 * 30 * 24 * 60 * 60 * 1000, - "year": 365.2425 * 24 * 60 * 60 * 1000 - }; - - // the allowed tick sizes, after 1 year we use - // an integer algorithm - - var baseSpec = [ - [1, "second"], [2, "second"], [5, "second"], [10, "second"], - [30, "second"], - [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], - [30, "minute"], - [1, "hour"], [2, "hour"], [4, "hour"], - [8, "hour"], [12, "hour"], - [1, "day"], [2, "day"], [3, "day"], - [0.25, "month"], [0.5, "month"], [1, "month"], - [2, "month"] - ]; - - // we don't know which variant(s) we'll need yet, but generating both is - // cheap - - var specMonths = baseSpec.concat([[3, "month"], [6, "month"], - [1, "year"]]); - var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], - [1, "year"]]); - - function init(plot) { - plot.hooks.processOptions.push(function (plot, options) { - $.each(plot.getAxes(), function(axisName, axis) { - - var opts = axis.options; - - if (opts.mode == "time") { - axis.tickGenerator = function(axis) { - - var ticks = []; - var d = dateGenerator(axis.min, opts); - var minSize = 0; - - // make quarter use a possibility if quarters are - // mentioned in either of these options - - var spec = (opts.tickSize && opts.tickSize[1] === - "quarter") || - (opts.minTickSize && opts.minTickSize[1] === - "quarter") ? specQuarters : specMonths; - - if (opts.minTickSize != null) { - if (typeof opts.tickSize == "number") { - minSize = opts.tickSize; - } else { - minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; - } - } - - for (var i = 0; i < spec.length - 1; ++i) { - if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] - + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 - && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { - break; - } - } - - var size = spec[i][0]; - var unit = spec[i][1]; - - // special-case the possibility of several years - - if (unit == "year") { - - // if given a minTickSize in years, just use it, - // ensuring that it's an integer - - if (opts.minTickSize != null && opts.minTickSize[1] == "year") { - size = Math.floor(opts.minTickSize[0]); - } else { - - var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); - var norm = (axis.delta / timeUnitSize.year) / magn; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - } - - // minimum size for years is 1 - - if (size < 1) { - size = 1; - } - } - - axis.tickSize = opts.tickSize || [size, unit]; - var tickSize = axis.tickSize[0]; - unit = axis.tickSize[1]; - - var step = tickSize * timeUnitSize[unit]; - - if (unit == "second") { - d.setSeconds(floorInBase(d.getSeconds(), tickSize)); - } else if (unit == "minute") { - d.setMinutes(floorInBase(d.getMinutes(), tickSize)); - } else if (unit == "hour") { - d.setHours(floorInBase(d.getHours(), tickSize)); - } else if (unit == "month") { - d.setMonth(floorInBase(d.getMonth(), tickSize)); - } else if (unit == "quarter") { - d.setMonth(3 * floorInBase(d.getMonth() / 3, - tickSize)); - } else if (unit == "year") { - d.setFullYear(floorInBase(d.getFullYear(), tickSize)); - } - - // reset smaller components - - d.setMilliseconds(0); - - if (step >= timeUnitSize.minute) { - d.setSeconds(0); - } - if (step >= timeUnitSize.hour) { - d.setMinutes(0); - } - if (step >= timeUnitSize.day) { - d.setHours(0); - } - if (step >= timeUnitSize.day * 4) { - d.setDate(1); - } - if (step >= timeUnitSize.month * 2) { - d.setMonth(floorInBase(d.getMonth(), 3)); - } - if (step >= timeUnitSize.quarter * 2) { - d.setMonth(floorInBase(d.getMonth(), 6)); - } - if (step >= timeUnitSize.year) { - d.setMonth(0); - } - - var carry = 0; - var v = Number.NaN; - var prev; - - do { - - prev = v; - v = d.getTime(); - ticks.push(v); - - if (unit == "month" || unit == "quarter") { - if (tickSize < 1) { - - // a bit complicated - we'll divide the - // month/quarter up but we need to take - // care of fractions so we don't end up in - // the middle of a day - - d.setDate(1); - var start = d.getTime(); - d.setMonth(d.getMonth() + - (unit == "quarter" ? 3 : 1)); - var end = d.getTime(); - d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); - carry = d.getHours(); - d.setHours(0); - } else { - d.setMonth(d.getMonth() + - tickSize * (unit == "quarter" ? 3 : 1)); - } - } else if (unit == "year") { - d.setFullYear(d.getFullYear() + tickSize); - } else { - d.setTime(v + step); - } - } while (v < axis.max && v != prev); - - return ticks; - }; - - axis.tickFormatter = function (v, axis) { - - var d = dateGenerator(v, axis.options); - - // first check global format - - if (opts.timeformat != null) { - return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); - } - - // possibly use quarters if quarters are mentioned in - // any of these places - - var useQuarters = (axis.options.tickSize && - axis.options.tickSize[1] == "quarter") || - (axis.options.minTickSize && - axis.options.minTickSize[1] == "quarter"); - - var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; - var span = axis.max - axis.min; - var suffix = (opts.twelveHourClock) ? " %p" : ""; - var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; - var fmt; - - if (t < timeUnitSize.minute) { - fmt = hourCode + ":%M:%S" + suffix; - } else if (t < timeUnitSize.day) { - if (span < 2 * timeUnitSize.day) { - fmt = hourCode + ":%M" + suffix; - } else { - fmt = "%b %d " + hourCode + ":%M" + suffix; - } - } else if (t < timeUnitSize.month) { - fmt = "%b %d"; - } else if ((useQuarters && t < timeUnitSize.quarter) || - (!useQuarters && t < timeUnitSize.year)) { - if (span < timeUnitSize.year) { - fmt = "%b"; - } else { - fmt = "%b %Y"; - } - } else if (useQuarters && t < timeUnitSize.year) { - if (span < timeUnitSize.year) { - fmt = "Q%q"; - } else { - fmt = "Q%q %Y"; - } - } else { - fmt = "%Y"; - } - - var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); - - return rt; - }; - } - }); - }); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'time', - version: '1.0' - }); - - // Time-axis support used to be in Flot core, which exposed the - // formatDate function on the plot object. Various plugins depend - // on the function, so we need to re-expose it here. - - $.plot.formatDate = formatDate; - -})(jQuery); diff --git a/flot/jquery.flot.time.min.js b/flot/jquery.flot.time.min.js new file mode 100644 index 0000000..690eb68 --- /dev/null +++ b/flot/jquery.flot.time.min.js @@ -0,0 +1,7 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ +(function($){var options={xaxis:{timezone:null,timeformat:null,twelveHourClock:false,monthNames:null}};function floorInBase(n,base){return base*Math.floor(n/base)}function formatDate(d,fmt,monthNames,dayNames){if(typeof d.strftime=="function"){return d.strftime(fmt)}var leftPad=function(n,pad){n=""+n;pad=""+(pad==null?"0":pad);return n.length==1?pad+n:n};var r=[];var escape=false;var hours=d.getHours();var isAM=hours<12;if(monthNames==null){monthNames=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}if(dayNames==null){dayNames=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]}var hours12;if(hours>12){hours12=hours-12}else if(hours==0){hours12=12}else{hours12=hours}for(var i=0;i=minSize){break}}var size=spec[i][0];var unit=spec[i][1];if(unit=="year"){if(opts.minTickSize!=null&&opts.minTickSize[1]=="year"){size=Math.floor(opts.minTickSize[0])}else{var magn=Math.pow(10,Math.floor(Math.log(axis.delta/timeUnitSize.year)/Math.LN10));var norm=axis.delta/timeUnitSize.year/magn;if(norm<1.5){size=1}else if(norm<3){size=2}else if(norm<7.5){size=5}else{size=10}size*=magn}if(size<1){size=1}}axis.tickSize=opts.tickSize||[size,unit];var tickSize=axis.tickSize[0];unit=axis.tickSize[1];var step=tickSize*timeUnitSize[unit];if(unit=="second"){d.setSeconds(floorInBase(d.getSeconds(),tickSize))}else if(unit=="minute"){d.setMinutes(floorInBase(d.getMinutes(),tickSize))}else if(unit=="hour"){d.setHours(floorInBase(d.getHours(),tickSize))}else if(unit=="month"){d.setMonth(floorInBase(d.getMonth(),tickSize))}else if(unit=="quarter"){d.setMonth(3*floorInBase(d.getMonth()/3,tickSize))}else if(unit=="year"){d.setFullYear(floorInBase(d.getFullYear(),tickSize))}d.setMilliseconds(0);if(step>=timeUnitSize.minute){d.setSeconds(0)}if(step>=timeUnitSize.hour){d.setMinutes(0)}if(step>=timeUnitSize.day){d.setHours(0)}if(step>=timeUnitSize.day*4){d.setDate(1)}if(step>=timeUnitSize.month*2){d.setMonth(floorInBase(d.getMonth(),3))}if(step>=timeUnitSize.quarter*2){d.setMonth(floorInBase(d.getMonth(),6))}if(step>=timeUnitSize.year){d.setMonth(0)}var carry=0;var v=Number.NaN;var prev;do{prev=v;v=d.getTime();ticks.push(v);if(unit=="month"||unit=="quarter"){if(tickSize<1){d.setDate(1);var start=d.getTime();d.setMonth(d.getMonth()+(unit=="quarter"?3:1));var end=d.getTime();d.setTime(v+carry*timeUnitSize.hour+(end-start)*tickSize);carry=d.getHours();d.setHours(0)}else{d.setMonth(d.getMonth()+tickSize*(unit=="quarter"?3:1))}}else if(unit=="year"){d.setFullYear(d.getFullYear()+tickSize)}else{d.setTime(v+step)}}while(v)[^>]*$|#([\w\-]*)$)/,rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,rvalidchars=/^[\],:{}\s]*$/,rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g,rvalidescape=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,rvalidtokens=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,rmsPrefix=/^-ms-/,rdashAlpha=/-([\da-z])/gi,fcamelCase=function(all,letter){return(letter+"").toUpperCase()},DOMContentLoaded=function(){if(document.addEventListener){document.removeEventListener("DOMContentLoaded",DOMContentLoaded,false);jQuery.ready()}else if(document.readyState==="complete"){document.detachEvent("onreadystatechange",DOMContentLoaded);jQuery.ready()}},class2type={};jQuery.fn=jQuery.prototype={constructor:jQuery,init:function(selector,context,rootjQuery){var match,elem,ret,doc;if(!selector){return this}if(selector.nodeType){this.context=this[0]=selector;this.length=1;return this}if(typeof selector==="string"){if(selector.charAt(0)==="<"&&selector.charAt(selector.length-1)===">"&&selector.length>=3){match=[null,selector,null]}else{match=rquickExpr.exec(selector)}if(match&&(match[1]||!context)){if(match[1]){context=context instanceof jQuery?context[0]:context;doc=context&&context.nodeType?context.ownerDocument||context:document;selector=jQuery.parseHTML(match[1],doc,true);if(rsingleTag.test(match[1])&&jQuery.isPlainObject(context)){this.attr.call(selector,context,true)}return jQuery.merge(this,selector)}else{elem=document.getElementById(match[2]);if(elem&&elem.parentNode){if(elem.id!==match[2]){return rootjQuery.find(selector)}this.length=1;this[0]=elem}this.context=document;this.selector=selector;return this}}else if(!context||context.jquery){return(context||rootjQuery).find(selector)}else{return this.constructor(context).find(selector)}}else if(jQuery.isFunction(selector)){return rootjQuery.ready(selector)}if(selector.selector!==undefined){this.selector=selector.selector;this.context=selector.context}return jQuery.makeArray(selector,this)},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return core_slice.call(this)},get:function(num){return num==null?this.toArray():num<0?this[this.length+num]:this[num]},pushStack:function(elems,name,selector){var ret=jQuery.merge(this.constructor(),elems);ret.prevObject=this;ret.context=this.context;if(name==="find"){ret.selector=this.selector+(this.selector?" ":"")+selector}else if(name){ret.selector=this.selector+"."+name+"("+selector+")"}return ret},each:function(callback,args){return jQuery.each(this,callback,args)},ready:function(fn){jQuery.ready.promise().done(fn);return this},eq:function(i){i=+i;return i===-1?this.slice(i):this.slice(i,i+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(core_slice.apply(this,arguments),"slice",core_slice.call(arguments).join(","))},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem)}))},end:function(){return this.prevObject||this.constructor(null)},push:core_push,sort:[].sort,splice:[].splice};jQuery.fn.init.prototype=jQuery.fn;jQuery.extend=jQuery.fn.extend=function(){var options,name,src,copy,copyIsArray,clone,target=arguments[0]||{},i=1,length=arguments.length,deep=false;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2}if(typeof target!=="object"&&!jQuery.isFunction(target)){target={}}if(length===i){target=this;--i}for(;i0){return}readyList.resolveWith(document,[jQuery]);if(jQuery.fn.trigger){jQuery(document).trigger("ready").off("ready")}},isFunction:function(obj){return jQuery.type(obj)==="function"},isArray:Array.isArray||function(obj){return jQuery.type(obj)==="array"},isWindow:function(obj){return obj!=null&&obj==obj.window},isNumeric:function(obj){return!isNaN(parseFloat(obj))&&isFinite(obj)},type:function(obj){return obj==null?String(obj):class2type[core_toString.call(obj)]||"object"},isPlainObject:function(obj){if(!obj||jQuery.type(obj)!=="object"||obj.nodeType||jQuery.isWindow(obj)){return false}try{if(obj.constructor&&!core_hasOwn.call(obj,"constructor")&&!core_hasOwn.call(obj.constructor.prototype,"isPrototypeOf")){return false}}catch(e){return false}var key;for(key in obj){}return key===undefined||core_hasOwn.call(obj,key)},isEmptyObject:function(obj){var name;for(name in obj){return false}return true},error:function(msg){throw new Error(msg)},parseHTML:function(data,context,scripts){var parsed;if(!data||typeof data!=="string"){return null}if(typeof context==="boolean"){scripts=context;context=0}context=context||document;if(parsed=rsingleTag.exec(data)){return[context.createElement(parsed[1])]}parsed=jQuery.buildFragment([data],context,scripts?null:[]);return jQuery.merge([],(parsed.cacheable?jQuery.clone(parsed.fragment):parsed.fragment).childNodes)},parseJSON:function(data){if(!data||typeof data!=="string"){return null}data=jQuery.trim(data);if(window.JSON&&window.JSON.parse){return window.JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}jQuery.error("Invalid JSON: "+data)},parseXML:function(data){var xml,tmp;if(!data||typeof data!=="string"){return null}try{if(window.DOMParser){tmp=new DOMParser;xml=tmp.parseFromString(data,"text/xml")}else{xml=new ActiveXObject("Microsoft.XMLDOM");xml.async="false";xml.loadXML(data)}}catch(e){xml=undefined}if(!xml||!xml.documentElement||xml.getElementsByTagName("parsererror").length){jQuery.error("Invalid XML: "+data)}return xml},noop:function(){},globalEval:function(data){if(data&&core_rnotwhite.test(data)){(window.execScript||function(data){window["eval"].call(window,data)})(data)}},camelCase:function(string){return string.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase)},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toLowerCase()===name.toLowerCase()},each:function(obj,callback,args){var name,i=0,length=obj.length,isObj=length===undefined||jQuery.isFunction(obj);if(args){if(isObj){for(name in obj){if(callback.apply(obj[name],args)===false){break}}}else{for(;i0&&elems[0]&&elems[length-1]||length===0||jQuery.isArray(elems));if(isArray){for(;i-1){list.splice(index,1);if(firing){if(index<=firingLength){firingLength--}if(index<=firingIndex){firingIndex--}}}})}return this},has:function(fn){return jQuery.inArray(fn,list)>-1},empty:function(){list=[];return this},disable:function(){list=stack=memory=undefined;return this},disabled:function(){return!list},lock:function(){stack=undefined;if(!memory){self.disable()}return this},locked:function(){return!stack},fireWith:function(context,args){args=args||[];args=[context,args.slice?args.slice():args];if(list&&(!fired||stack)){if(firing){stack.push(args)}else{fire(args)}}return this},fire:function(){self.fireWith(this,arguments);return this},fired:function(){return!!fired}};return self};jQuery.extend({Deferred:function(func){var tuples=[["resolve","done",jQuery.Callbacks("once memory"),"resolved"],["reject","fail",jQuery.Callbacks("once memory"),"rejected"],["notify","progress",jQuery.Callbacks("memory")]],state="pending",promise={state:function(){return state},always:function(){deferred.done(arguments).fail(arguments);return this},then:function(){var fns=arguments;return jQuery.Deferred(function(newDefer){jQuery.each(tuples,function(i,tuple){var action=tuple[0],fn=fns[i];deferred[tuple[1]](jQuery.isFunction(fn)?function(){var returned=fn.apply(this,arguments);if(returned&&jQuery.isFunction(returned.promise)){returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify)}else{newDefer[action+"With"](this===deferred?newDefer:this,[returned])}}:newDefer[action])});fns=null}).promise()},promise:function(obj){return obj!=null?jQuery.extend(obj,promise):promise}},deferred={};promise.pipe=promise.then;jQuery.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[3];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString},tuples[i^1][2].disable,tuples[2][2].lock)}deferred[tuple[0]]=list.fire;deferred[tuple[0]+"With"]=list.fireWith});promise.promise(deferred);if(func){func.call(deferred,deferred)}return deferred},when:function(subordinate){var i=0,resolveValues=core_slice.call(arguments),length=resolveValues.length,remaining=length!==1||subordinate&&jQuery.isFunction(subordinate.promise)?length:0,deferred=remaining===1?subordinate:jQuery.Deferred(),updateFunc=function(i,contexts,values){return function(value){contexts[i]=this;values[i]=arguments.length>1?core_slice.call(arguments):value;if(values===progressValues){deferred.notifyWith(contexts,values)}else if(!--remaining){deferred.resolveWith(contexts,values)}}},progressValues,progressContexts,resolveContexts;if(length>1){progressValues=new Array(length);progressContexts=new Array(length);resolveContexts=new Array(length);for(;i
a";all=div.getElementsByTagName("*");a=div.getElementsByTagName("a")[0];if(!all||!a||!all.length){return{}}select=document.createElement("select");opt=select.appendChild(document.createElement("option"));input=div.getElementsByTagName("input")[0];a.style.cssText="top:1px;float:left;opacity:.5";support={leadingWhitespace:div.firstChild.nodeType===3,tbody:!div.getElementsByTagName("tbody").length,htmlSerialize:!!div.getElementsByTagName("link").length,style:/top/.test(a.getAttribute("style")),hrefNormalized:a.getAttribute("href")==="/a",opacity:/^0.5/.test(a.style.opacity),cssFloat:!!a.style.cssFloat,checkOn:input.value==="on",optSelected:opt.selected,getSetAttribute:div.className!=="t",enctype:!!document.createElement("form").enctype,html5Clone:document.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",boxModel:document.compatMode==="CSS1Compat",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,boxSizingReliable:true,pixelPosition:false};input.checked=true;support.noCloneChecked=input.cloneNode(true).checked;select.disabled=true;support.optDisabled=!opt.disabled;try{delete div.test}catch(e){support.deleteExpando=false}if(!div.addEventListener&&div.attachEvent&&div.fireEvent){div.attachEvent("onclick",clickFn=function(){support.noCloneEvent=false});div.cloneNode(true).fireEvent("onclick");div.detachEvent("onclick",clickFn)}input=document.createElement("input");input.value="t";input.setAttribute("type","radio");support.radioValue=input.value==="t";input.setAttribute("checked","checked");input.setAttribute("name","t");div.appendChild(input);fragment=document.createDocumentFragment();fragment.appendChild(div.lastChild);support.checkClone=fragment.cloneNode(true).cloneNode(true).lastChild.checked;support.appendChecked=input.checked;fragment.removeChild(input);fragment.appendChild(div);if(div.attachEvent){for(i in{submit:true,change:true,focusin:true}){eventName="on"+i;isSupported=eventName in div;if(!isSupported){div.setAttribute(eventName,"return;");isSupported=typeof div[eventName]==="function"}support[i+"Bubbles"]=isSupported}}jQuery(function(){var container,div,tds,marginDiv,divReset="padding:0;margin:0;border:0;display:block;overflow:hidden;",body=document.getElementsByTagName("body")[0];if(!body){return}container=document.createElement("div");container.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";body.insertBefore(container,body.firstChild);div=document.createElement("div");container.appendChild(div);div.innerHTML="
t
";tds=div.getElementsByTagName("td");tds[0].style.cssText="padding:0;margin:0;border:0;display:none";isSupported=tds[0].offsetHeight===0;tds[0].style.display="";tds[1].style.display="none";support.reliableHiddenOffsets=isSupported&&tds[0].offsetHeight===0;div.innerHTML="";div.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";support.boxSizing=div.offsetWidth===4;support.doesNotIncludeMarginInBodyOffset=body.offsetTop!==1;if(window.getComputedStyle){support.pixelPosition=(window.getComputedStyle(div,null)||{}).top!=="1%";support.boxSizingReliable=(window.getComputedStyle(div,null)||{width:"4px"}).width==="4px";marginDiv=document.createElement("div");marginDiv.style.cssText=div.style.cssText=divReset;marginDiv.style.marginRight=marginDiv.style.width="0";div.style.width="1px";div.appendChild(marginDiv);support.reliableMarginRight=!parseFloat((window.getComputedStyle(marginDiv,null)||{}).marginRight)}if(typeof div.style.zoom!=="undefined"){div.innerHTML="";div.style.cssText=divReset+"width:1px;padding:1px;display:inline;zoom:1";support.inlineBlockNeedsLayout=div.offsetWidth===3;div.style.display="block";div.style.overflow="visible";div.innerHTML="
";div.firstChild.style.width="5px";support.shrinkWrapBlocks=div.offsetWidth!==3;container.style.zoom=1}body.removeChild(container);container=div=tds=marginDiv=null});fragment.removeChild(div);all=a=select=opt=input=fragment=div=null;return support}();var rbrace=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,rmultiDash=/([A-Z])/g;jQuery.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(jQuery.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(elem){elem=elem.nodeType?jQuery.cache[elem[jQuery.expando]]:elem[jQuery.expando];return!!elem&&!isEmptyDataObject(elem)},data:function(elem,name,data,pvt){if(!jQuery.acceptData(elem)){return}var thisCache,ret,internalKey=jQuery.expando,getByName=typeof name==="string",isNode=elem.nodeType,cache=isNode?jQuery.cache:elem,id=isNode?elem[internalKey]:elem[internalKey]&&internalKey;if((!id||!cache[id]||!pvt&&!cache[id].data)&&getByName&&data===undefined){return}if(!id){if(isNode){elem[internalKey]=id=jQuery.deletedIds.pop()||jQuery.guid++}else{id=internalKey}}if(!cache[id]){cache[id]={};if(!isNode){cache[id].toJSON=jQuery.noop}}if(typeof name==="object"||typeof name==="function"){if(pvt){cache[id]=jQuery.extend(cache[id],name)}else{cache[id].data=jQuery.extend(cache[id].data,name)}}thisCache=cache[id];if(!pvt){if(!thisCache.data){thisCache.data={}}thisCache=thisCache.data}if(data!==undefined){thisCache[jQuery.camelCase(name)]=data}if(getByName){ret=thisCache[name];if(ret==null){ret=thisCache[jQuery.camelCase(name)]}}else{ret=thisCache}return ret},removeData:function(elem,name,pvt){if(!jQuery.acceptData(elem)){return}var thisCache,i,l,isNode=elem.nodeType,cache=isNode?jQuery.cache:elem,id=isNode?elem[jQuery.expando]:jQuery.expando;if(!cache[id]){return}if(name){thisCache=pvt?cache[id]:cache[id].data;if(thisCache){if(!jQuery.isArray(name)){if(name in thisCache){name=[name]}else{name=jQuery.camelCase(name);if(name in thisCache){name=[name]}else{name=name.split(" ")}}}for(i=0,l=name.length;i1,null,false)},removeData:function(key){return this.each(function(){jQuery.removeData(this,key)})}});function dataAttr(elem,key,data){if(data===undefined&&elem.nodeType===1){var name="data-"+key.replace(rmultiDash,"-$1").toLowerCase();data=elem.getAttribute(name);if(typeof data==="string"){try{data=data==="true"?true:data==="false"?false:data==="null"?null:+data+""===data?+data:rbrace.test(data)?jQuery.parseJSON(data):data}catch(e){}jQuery.data(elem,key,data)}else{data=undefined}}return data}function isEmptyDataObject(obj){var name;for(name in obj){if(name==="data"&&jQuery.isEmptyObject(obj[name])){continue}if(name!=="toJSON"){return false}}return true}jQuery.extend({queue:function(elem,type,data){var queue;if(elem){type=(type||"fx")+"queue";queue=jQuery._data(elem,type);if(data){if(!queue||jQuery.isArray(data)){queue=jQuery._data(elem,type,jQuery.makeArray(data))}else{queue.push(data)}}return queue||[]}},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),startLength=queue.length,fn=queue.shift(),hooks=jQuery._queueHooks(elem,type),next=function(){jQuery.dequeue(elem,type)};if(fn==="inprogress"){fn=queue.shift();startLength--}if(fn){if(type==="fx"){queue.unshift("inprogress")}delete hooks.stop;fn.call(elem,next,hooks)}if(!startLength&&hooks){hooks.empty.fire()}},_queueHooks:function(elem,type){var key=type+"queueHooks";return jQuery._data(elem,key)||jQuery._data(elem,key,{empty:jQuery.Callbacks("once memory").add(function(){jQuery.removeData(elem,type+"queue",true);jQuery.removeData(elem,key,true)})})}});jQuery.fn.extend({queue:function(type,data){var setter=2;if(typeof type!=="string"){data=type;type="fx";setter--}if(arguments.length1)},removeAttr:function(name){return this.each(function(){jQuery.removeAttr(this,name)})},prop:function(name,value){return jQuery.access(this,jQuery.prop,name,value,arguments.length>1)},removeProp:function(name){name=jQuery.propFix[name]||name;return this.each(function(){try{this[name]=undefined;delete this[name]}catch(e){}})},addClass:function(value){var classNames,i,l,elem,setClass,c,cl;if(jQuery.isFunction(value)){return this.each(function(j){jQuery(this).addClass(value.call(this,j,this.className))})}if(value&&typeof value==="string"){classNames=value.split(core_rspace);for(i=0,l=this.length;i=0){className=className.replace(" "+removes[c]+" "," ")}}elem.className=value?jQuery.trim(className):""}}}return this},toggleClass:function(value,stateVal){var type=typeof value,isBool=typeof stateVal==="boolean";if(jQuery.isFunction(value)){return this.each(function(i){jQuery(this).toggleClass(value.call(this,i,this.className,stateVal),stateVal)})}return this.each(function(){if(type==="string"){var className,i=0,self=jQuery(this),state=stateVal,classNames=value.split(core_rspace);while(className=classNames[i++]){state=isBool?state:!self.hasClass(className);self[state?"addClass":"removeClass"](className)}}else if(type==="undefined"||type==="boolean"){if(this.className){jQuery._data(this,"__className__",this.className)}this.className=this.className||value===false?"":jQuery._data(this,"__className__")||""}})},hasClass:function(selector){var className=" "+selector+" ",i=0,l=this.length;for(;i=0){return true}}return false},val:function(value){var hooks,ret,isFunction,elem=this[0];if(!arguments.length){if(elem){hooks=jQuery.valHooks[elem.type]||jQuery.valHooks[elem.nodeName.toLowerCase()];if(hooks&&"get"in hooks&&(ret=hooks.get(elem,"value"))!==undefined){return ret}ret=elem.value;return typeof ret==="string"?ret.replace(rreturn,""):ret==null?"":ret}return}isFunction=jQuery.isFunction(value);return this.each(function(i){var val,self=jQuery(this);if(this.nodeType!==1){return}if(isFunction){val=value.call(this,i,self.val())}else{val=value}if(val==null){val=""}else if(typeof val==="number"){val+=""}else if(jQuery.isArray(val)){val=jQuery.map(val,function(value){return value==null?"":value+""})}hooks=jQuery.valHooks[this.type]||jQuery.valHooks[this.nodeName.toLowerCase()];if(!hooks||!("set"in hooks)||hooks.set(this,val,"value")===undefined){this.value=val}})}});jQuery.extend({valHooks:{option:{get:function(elem){var val=elem.attributes.value;return!val||val.specified?elem.value:elem.text}},select:{get:function(elem){var value,option,options=elem.options,index=elem.selectedIndex,one=elem.type==="select-one"||index<0,values=one?null:[],max=one?index+1:options.length,i=index<0?max:one?index:0;for(;i=0});if(!values.length){elem.selectedIndex=-1}return values}}},attrFn:{},attr:function(elem,name,value,pass){var ret,hooks,notxml,nType=elem.nodeType;if(!elem||nType===3||nType===8||nType===2){return}if(pass&&jQuery.isFunction(jQuery.fn[name])){return jQuery(elem)[name](value)}if(typeof elem.getAttribute==="undefined"){return jQuery.prop(elem,name,value)}notxml=nType!==1||!jQuery.isXMLDoc(elem);if(notxml){name=name.toLowerCase();hooks=jQuery.attrHooks[name]||(rboolean.test(name)?boolHook:nodeHook)}if(value!==undefined){if(value===null){jQuery.removeAttr(elem,name);return}else if(hooks&&"set"in hooks&¬xml&&(ret=hooks.set(elem,value,name))!==undefined){return ret}else{elem.setAttribute(name,value+"");return value}}else if(hooks&&"get"in hooks&¬xml&&(ret=hooks.get(elem,name))!==null){return ret}else{ret=elem.getAttribute(name);return ret===null?undefined:ret}},removeAttr:function(elem,value){var propName,attrNames,name,isBool,i=0;if(value&&elem.nodeType===1){attrNames=value.split(core_rspace);for(;i=0}}})});var rformElems=/^(?:textarea|input|select)$/i,rtypenamespace=/^([^\.]*|)(?:\.(.+)|)$/,rhoverHack=/(?:^|\s)hover(\.\S+|)\b/,rkeyEvent=/^key/,rmouseEvent=/^(?:mouse|contextmenu)|click/,rfocusMorph=/^(?:focusinfocus|focusoutblur)$/,hoverHack=function(events){return jQuery.event.special.hover?events:events.replace(rhoverHack,"mouseenter$1 mouseleave$1")};jQuery.event={add:function(elem,types,handler,data,selector){var elemData,eventHandle,events,t,tns,type,namespaces,handleObj,handleObjIn,handlers,special;if(elem.nodeType===3||elem.nodeType===8||!types||!handler||!(elemData=jQuery._data(elem))){return}if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;selector=handleObjIn.selector}if(!handler.guid){handler.guid=jQuery.guid++}events=elemData.events;if(!events){elemData.events=events={}}eventHandle=elemData.handle;if(!eventHandle){elemData.handle=eventHandle=function(e){return typeof jQuery!=="undefined"&&(!e||jQuery.event.triggered!==e.type)?jQuery.event.dispatch.apply(eventHandle.elem,arguments):undefined};eventHandle.elem=elem}types=jQuery.trim(hoverHack(types)).split(" ");for(t=0;t=0){type=type.slice(0,-1);exclusive=true}if(type.indexOf(".")>=0){namespaces=type.split(".");type=namespaces.shift();namespaces.sort()}if((!elem||jQuery.event.customEvent[type])&&!jQuery.event.global[type]){return}event=typeof event==="object"?event[jQuery.expando]?event:new jQuery.Event(type,event):new jQuery.Event(type);event.type=type;event.isTrigger=true;event.exclusive=exclusive;event.namespace=namespaces.join(".");event.namespace_re=event.namespace?new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;ontype=type.indexOf(":")<0?"on"+type:"";if(!elem){cache=jQuery.cache;for(i in cache){if(cache[i].events&&cache[i].events[type]){jQuery.event.trigger(event,data,cache[i].handle.elem,true)}}return}event.result=undefined;if(!event.target){event.target=elem}data=data!=null?jQuery.makeArray(data):[];data.unshift(event);special=jQuery.event.special[type]||{};if(special.trigger&&special.trigger.apply(elem,data)===false){return}eventPath=[[elem,special.bindType||type]];if(!onlyHandlers&&!special.noBubble&&!jQuery.isWindow(elem)){bubbleType=special.delegateType||type;cur=rfocusMorph.test(bubbleType+type)?elem:elem.parentNode;for(old=elem;cur;cur=cur.parentNode){eventPath.push([cur,bubbleType]);old=cur}if(old===(elem.ownerDocument||document)){eventPath.push([old.defaultView||old.parentWindow||window,bubbleType])}}for(i=0;i=0:jQuery.find(sel,this,null,[cur]).length}if(selMatch[sel]){matches.push(handleObj)}}if(matches.length){handlerQueue.push({elem:cur,matches:matches})}}}}if(handlers.length>delegateCount){handlerQueue.push({elem:this,matches:handlers.slice(delegateCount)})}for(i=0;i0?this.on(name,null,data,fn):this.trigger(name)};if(rkeyEvent.test(name)){jQuery.event.fixHooks[name]=jQuery.event.keyHooks}if(rmouseEvent.test(name)){jQuery.event.fixHooks[name]=jQuery.event.mouseHooks}});(function(window,undefined){var cachedruns,assertGetIdNotName,Expr,getText,isXML,contains,compile,sortOrder,hasDuplicate,outermostContext,baseHasDuplicate=true,strundefined="undefined",expando=("sizcache"+Math.random()).replace(".",""),Token=String,document=window.document,docElem=document.documentElement,dirruns=0,done=0,pop=[].pop,push=[].push,slice=[].slice,indexOf=[].indexOf||function(elem){var i=0,len=this.length;for(;iExpr.cacheLength){delete cache[keys.shift()]}return cache[key+" "]=value},cache)},classCache=createCache(),tokenCache=createCache(),compilerCache=createCache(),whitespace="[\\x20\\t\\r\\n\\f]",characterEncoding="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",identifier=characterEncoding.replace("w","w#"),operators="([*^$|!~]?=)",attributes="\\["+whitespace+"*("+characterEncoding+")"+whitespace+"*(?:"+operators+whitespace+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+identifier+")|)|)"+whitespace+"*\\]",pseudos=":("+characterEncoding+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+attributes+")|[^:]|\\\\.)*|.*))\\)|)",pos=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+whitespace+"*((?:-\\d)?\\d*)"+whitespace+"*\\)|)(?=[^-]|$)",rtrim=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+whitespace+"+$","g"),rcomma=new RegExp("^"+whitespace+"*,"+whitespace+"*"),rcombinators=new RegExp("^"+whitespace+"*([\\x20\\t\\r\\n\\f>+~])"+whitespace+"*"),rpseudo=new RegExp(pseudos),rquickExpr=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,rnot=/^:not/,rsibling=/[\x20\t\r\n\f]*[+~]/,rendsWithNot=/:not\($/,rheader=/h\d/i,rinputs=/input|select|textarea|button/i,rbackslash=/\\(?!\\)/g,matchExpr={ID:new RegExp("^#("+characterEncoding+")"),CLASS:new RegExp("^\\.("+characterEncoding+")"),NAME:new RegExp("^\\[name=['\"]?("+characterEncoding+")['\"]?\\]"),TAG:new RegExp("^("+characterEncoding.replace("w","w*")+")"),ATTR:new RegExp("^"+attributes),PSEUDO:new RegExp("^"+pseudos),POS:new RegExp(pos,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+whitespace+"*(even|odd|(([+-]|)(\\d*)n|)"+whitespace+"*(?:([+-]|)"+whitespace+"*(\\d+)|))"+whitespace+"*\\)|)","i"),needsContext:new RegExp("^"+whitespace+"*[>+~]|"+pos,"i")},assert=function(fn){var div=document.createElement("div");try{return fn(div)}catch(e){return false}finally{div=null}},assertTagNameNoComments=assert(function(div){div.appendChild(document.createComment(""));return!div.getElementsByTagName("*").length}),assertHrefNotNormalized=assert(function(div){div.innerHTML="";return div.firstChild&&typeof div.firstChild.getAttribute!==strundefined&&div.firstChild.getAttribute("href")==="#"}),assertAttributes=assert(function(div){div.innerHTML="";var type=typeof div.lastChild.getAttribute("multiple");return type!=="boolean"&&type!=="string"}),assertUsableClassName=assert(function(div){div.innerHTML="";if(!div.getElementsByClassName||!div.getElementsByClassName("e").length){return false}div.lastChild.className="e";return div.getElementsByClassName("e").length===2}),assertUsableName=assert(function(div){div.id=expando+0;div.innerHTML="
";docElem.insertBefore(div,docElem.firstChild);var pass=document.getElementsByName&&document.getElementsByName(expando).length===2+document.getElementsByName(expando+0).length;assertGetIdNotName=!document.getElementById(expando);docElem.removeChild(div);return pass});try{slice.call(docElem.childNodes,0)[0].nodeType}catch(e){slice=function(i){var elem,results=[];for(;elem=this[i];i++){results.push(elem)}return results}}function Sizzle(selector,context,results,seed){results=results||[];context=context||document;var match,elem,xml,m,nodeType=context.nodeType;if(!selector||typeof selector!=="string"){return results}if(nodeType!==1&&nodeType!==9){return[]}xml=isXML(context);if(!xml&&!seed){if(match=rquickExpr.exec(selector)){if(m=match[1]){if(nodeType===9){elem=context.getElementById(m);if(elem&&elem.parentNode){if(elem.id===m){results.push(elem);return results}}else{return results}}else{if(context.ownerDocument&&(elem=context.ownerDocument.getElementById(m))&&contains(context,elem)&&elem.id===m){results.push(elem);return results}}}else if(match[2]){push.apply(results,slice.call(context.getElementsByTagName(selector),0));return results}else if((m=match[3])&&assertUsableClassName&&context.getElementsByClassName){push.apply(results,slice.call(context.getElementsByClassName(m),0));return results}}}return select(selector.replace(rtrim,"$1"),context,results,seed,xml)}Sizzle.matches=function(expr,elements){return Sizzle(expr,null,null,elements)};Sizzle.matchesSelector=function(elem,expr){return Sizzle(expr,null,null,[elem]).length>0};function createInputPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type===type}}function createButtonPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return(name==="input"||name==="button")&&elem.type===type}}function createPositionalPseudo(fn){return markFunction(function(argument){argument=+argument;return markFunction(function(seed,matches){var j,matchIndexes=fn([],seed.length,argument),i=matchIndexes.length;while(i--){if(seed[j=matchIndexes[i]]){seed[j]=!(matches[j]=seed[j])}}})})}getText=Sizzle.getText=function(elem){var node,ret="",i=0,nodeType=elem.nodeType;if(nodeType){if(nodeType===1||nodeType===9||nodeType===11){if(typeof elem.textContent==="string"){return elem.textContent}else{for(elem=elem.firstChild;elem;elem=elem.nextSibling){ret+=getText(elem)}}}else if(nodeType===3||nodeType===4){return elem.nodeValue}}else{for(;node=elem[i];i++){ret+=getText(node)}}return ret};isXML=Sizzle.isXML=function(elem){var documentElement=elem&&(elem.ownerDocument||elem).documentElement;return documentElement?documentElement.nodeName!=="HTML":false};contains=Sizzle.contains=docElem.contains?function(a,b){var adown=a.nodeType===9?a.documentElement:a,bup=b&&b.parentNode;return a===bup||!!(bup&&bup.nodeType===1&&adown.contains&&adown.contains(bup))}:docElem.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode){if(b===a){return true}}return false};Sizzle.attr=function(elem,name){var val,xml=isXML(elem);if(!xml){name=name.toLowerCase()}if(val=Expr.attrHandle[name]){return val(elem)}if(xml||assertAttributes){return elem.getAttribute(name)}val=elem.getAttributeNode(name);return val?typeof elem[name]==="boolean"?elem[name]?name:null:val.specified?val.value:null:null};Expr=Sizzle.selectors={cacheLength:50,createPseudo:markFunction,match:matchExpr,attrHandle:assertHrefNotNormalized?{}:{href:function(elem){return elem.getAttribute("href",2)},type:function(elem){return elem.getAttribute("type")}},find:{ID:assertGetIdNotName?function(id,context,xml){if(typeof context.getElementById!==strundefined&&!xml){var m=context.getElementById(id);return m&&m.parentNode?[m]:[]}}:function(id,context,xml){if(typeof context.getElementById!==strundefined&&!xml){var m=context.getElementById(id);return m?m.id===id||typeof m.getAttributeNode!==strundefined&&m.getAttributeNode("id").value===id?[m]:undefined:[]}},TAG:assertTagNameNoComments?function(tag,context){if(typeof context.getElementsByTagName!==strundefined){return context.getElementsByTagName(tag)}}:function(tag,context){var results=context.getElementsByTagName(tag);if(tag==="*"){var elem,tmp=[],i=0;for(;elem=results[i];i++){if(elem.nodeType===1){tmp.push(elem)}}return tmp}return results},NAME:assertUsableName&&function(tag,context){if(typeof context.getElementsByName!==strundefined){return context.getElementsByName(name)}},CLASS:assertUsableClassName&&function(className,context,xml){if(typeof context.getElementsByClassName!==strundefined&&!xml){return context.getElementsByClassName(className)}}},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(match){match[1]=match[1].replace(rbackslash,"");match[3]=(match[4]||match[5]||"").replace(rbackslash,"");if(match[2]==="~="){match[3]=" "+match[3]+" "}return match.slice(0,4)},CHILD:function(match){match[1]=match[1].toLowerCase();if(match[1]==="nth"){if(!match[2]){Sizzle.error(match[0])}match[3]=+(match[3]?match[4]+(match[5]||1):2*(match[2]==="even"||match[2]==="odd"));match[4]=+(match[6]+match[7]||match[2]==="odd")}else if(match[2]){Sizzle.error(match[0])}return match},PSEUDO:function(match){var unquoted,excess;if(matchExpr["CHILD"].test(match[0])){return null}if(match[3]){match[2]=match[3]}else if(unquoted=match[4]){if(rpseudo.test(unquoted)&&(excess=tokenize(unquoted,true))&&(excess=unquoted.indexOf(")",unquoted.length-excess)-unquoted.length)){unquoted=unquoted.slice(0,excess);match[0]=match[0].slice(0,excess)}match[2]=unquoted}return match.slice(0,3)}},filter:{ID:assertGetIdNotName?function(id){id=id.replace(rbackslash,"");return function(elem){return elem.getAttribute("id")===id}}:function(id){id=id.replace(rbackslash,"");return function(elem){var node=typeof elem.getAttributeNode!==strundefined&&elem.getAttributeNode("id");return node&&node.value===id}},TAG:function(nodeName){if(nodeName==="*"){return function(){return true}}nodeName=nodeName.replace(rbackslash,"").toLowerCase();return function(elem){return elem.nodeName&&elem.nodeName.toLowerCase()===nodeName}},CLASS:function(className){var pattern=classCache[expando][className+" "];return pattern||(pattern=new RegExp("(^|"+whitespace+")"+className+"("+whitespace+"|$)"))&&classCache(className,function(elem){return pattern.test(elem.className||typeof elem.getAttribute!==strundefined&&elem.getAttribute("class")||"")})},ATTR:function(name,operator,check){return function(elem,context){var result=Sizzle.attr(elem,name);if(result==null){return operator==="!="}if(!operator){return true}result+="";return operator==="="?result===check:operator==="!="?result!==check:operator==="^="?check&&result.indexOf(check)===0:operator==="*="?check&&result.indexOf(check)>-1:operator==="$="?check&&result.substr(result.length-check.length)===check:operator==="~="?(" "+result+" ").indexOf(check)>-1:operator==="|="?result===check||result.substr(0,check.length+1)===check+"-":false}},CHILD:function(type,argument,first,last){if(type==="nth"){return function(elem){var node,diff,parent=elem.parentNode;if(first===1&&last===0){return true}if(parent){diff=0;for(node=parent.firstChild;node;node=node.nextSibling){if(node.nodeType===1){diff++; +if(elem===node){break}}}}diff-=last;return diff===first||diff%first===0&&diff/first>=0}}return function(elem){var node=elem;switch(type){case"only":case"first":while(node=node.previousSibling){if(node.nodeType===1){return false}}if(type==="first"){return true}node=elem;case"last":while(node=node.nextSibling){if(node.nodeType===1){return false}}return true}}},PSEUDO:function(pseudo,argument){var args,fn=Expr.pseudos[pseudo]||Expr.setFilters[pseudo.toLowerCase()]||Sizzle.error("unsupported pseudo: "+pseudo);if(fn[expando]){return fn(argument)}if(fn.length>1){args=[pseudo,pseudo,"",argument];return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase())?markFunction(function(seed,matches){var idx,matched=fn(seed,argument),i=matched.length;while(i--){idx=indexOf.call(seed,matched[i]);seed[idx]=!(matches[idx]=matched[i])}}):function(elem){return fn(elem,0,args)}}return fn}},pseudos:{not:markFunction(function(selector){var input=[],results=[],matcher=compile(selector.replace(rtrim,"$1"));return matcher[expando]?markFunction(function(seed,matches,context,xml){var elem,unmatched=matcher(seed,null,xml,[]),i=seed.length;while(i--){if(elem=unmatched[i]){seed[i]=!(matches[i]=elem)}}}):function(elem,context,xml){input[0]=elem;matcher(input,null,xml,results);return!results.pop()}}),has:markFunction(function(selector){return function(elem){return Sizzle(selector,elem).length>0}}),contains:markFunction(function(text){return function(elem){return(elem.textContent||elem.innerText||getText(elem)).indexOf(text)>-1}}),enabled:function(elem){return elem.disabled===false},disabled:function(elem){return elem.disabled===true},checked:function(elem){var nodeName=elem.nodeName.toLowerCase();return nodeName==="input"&&!!elem.checked||nodeName==="option"&&!!elem.selected},selected:function(elem){if(elem.parentNode){elem.parentNode.selectedIndex}return elem.selected===true},parent:function(elem){return!Expr.pseudos["empty"](elem)},empty:function(elem){var nodeType;elem=elem.firstChild;while(elem){if(elem.nodeName>"@"||(nodeType=elem.nodeType)===3||nodeType===4){return false}elem=elem.nextSibling}return true},header:function(elem){return rheader.test(elem.nodeName)},text:function(elem){var type,attr;return elem.nodeName.toLowerCase()==="input"&&(type=elem.type)==="text"&&((attr=elem.getAttribute("type"))==null||attr.toLowerCase()===type)},radio:createInputPseudo("radio"),checkbox:createInputPseudo("checkbox"),file:createInputPseudo("file"),password:createInputPseudo("password"),image:createInputPseudo("image"),submit:createButtonPseudo("submit"),reset:createButtonPseudo("reset"),button:function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type==="button"||name==="button"},input:function(elem){return rinputs.test(elem.nodeName)},focus:function(elem){var doc=elem.ownerDocument;return elem===doc.activeElement&&(!doc.hasFocus||doc.hasFocus())&&!!(elem.type||elem.href||~elem.tabIndex)},active:function(elem){return elem===elem.ownerDocument.activeElement},first:createPositionalPseudo(function(){return[0]}),last:createPositionalPseudo(function(matchIndexes,length){return[length-1]}),eq:createPositionalPseudo(function(matchIndexes,length,argument){return[argument<0?argument+length:argument]}),even:createPositionalPseudo(function(matchIndexes,length){for(var i=0;i=0;){matchIndexes.push(i)}return matchIndexes}),gt:createPositionalPseudo(function(matchIndexes,length,argument){for(var i=argument<0?argument+length:argument;++i1?function(elem,context,xml){var i=matchers.length;while(i--){if(!matchers[i](elem,context,xml)){return false}}return true}:matchers[0]}function condense(unmatched,map,filter,context,xml){var elem,newUnmatched=[],i=0,len=unmatched.length,mapped=map!=null;for(;i-1){seed[temp]=!(results[temp]=elem)}}}}else{matcherOut=condense(matcherOut===results?matcherOut.splice(preexisting,matcherOut.length):matcherOut);if(postFinder){postFinder(null,results,matcherOut,xml)}else{push.apply(results,matcherOut)}}})}function matcherFromTokens(tokens){var checkContext,matcher,j,len=tokens.length,leadingRelative=Expr.relative[tokens[0].type],implicitRelative=leadingRelative||Expr.relative[" "],i=leadingRelative?1:0,matchContext=addCombinator(function(elem){return elem===checkContext},implicitRelative,true),matchAnyContext=addCombinator(function(elem){return indexOf.call(checkContext,elem)>-1},implicitRelative,true),matchers=[function(elem,context,xml){return!leadingRelative&&(xml||context!==outermostContext)||((checkContext=context).nodeType?matchContext(elem,context,xml):matchAnyContext(elem,context,xml))}];for(;i1&&elementMatcher(matchers),i>1&&tokens.slice(0,i-1).join("").replace(rtrim,"$1"),matcher,i0,byElement=elementMatchers.length>0,superMatcher=function(seed,context,xml,results,expandContext){var elem,j,matcher,setMatched=[],matchedCount=0,i="0",unmatched=seed&&[],outermost=expandContext!=null,contextBackup=outermostContext,elems=seed||byElement&&Expr.find["TAG"]("*",expandContext&&context.parentNode||context),dirrunsUnique=dirruns+=contextBackup==null?1:Math.E;if(outermost){outermostContext=context!==document&&context;cachedruns=superMatcher.el}for(;(elem=elems[i])!=null;i++){if(byElement&&elem){for(j=0;matcher=elementMatchers[j];j++){if(matcher(elem,context,xml)){results.push(elem);break}}if(outermost){dirruns=dirrunsUnique;cachedruns=++superMatcher.el}}if(bySet){if(elem=!matcher&&elem){matchedCount--}if(seed){unmatched.push(elem)}}}matchedCount+=i;if(bySet&&i!==matchedCount){for(j=0;matcher=setMatchers[j];j++){matcher(unmatched,setMatched,context,xml)}if(seed){if(matchedCount>0){while(i--){if(!(unmatched[i]||setMatched[i])){setMatched[i]=pop.call(results)}}}setMatched=condense(setMatched)}push.apply(results,setMatched);if(outermost&&!seed&&setMatched.length>0&&matchedCount+setMatchers.length>1){Sizzle.uniqueSort(results)}}if(outermost){dirruns=dirrunsUnique;outermostContext=contextBackup}return unmatched};superMatcher.el=0;return bySet?markFunction(superMatcher):superMatcher}compile=Sizzle.compile=function(selector,group){var i,setMatchers=[],elementMatchers=[],cached=compilerCache[expando][selector+" "];if(!cached){if(!group){group=tokenize(selector)}i=group.length;while(i--){cached=matcherFromTokens(group[i]);if(cached[expando]){setMatchers.push(cached)}else{elementMatchers.push(cached)}}cached=compilerCache(selector,matcherFromGroupMatchers(elementMatchers,setMatchers))}return cached};function multipleContexts(selector,contexts,results){var i=0,len=contexts.length;for(;i2&&(token=tokens[0]).type==="ID"&&context.nodeType===9&&!xml&&Expr.relative[tokens[1].type]){context=Expr.find["ID"](token.matches[0].replace(rbackslash,""),context,xml)[0];if(!context){return results}selector=selector.slice(tokens.shift().length)}for(i=matchExpr["POS"].test(selector)?-1:tokens.length-1;i>=0;i--){token=tokens[i];if(Expr.relative[type=token.type]){break}if(find=Expr.find[type]){if(seed=find(token.matches[0].replace(rbackslash,""),rsibling.test(tokens[0].type)&&context.parentNode||context,xml)){tokens.splice(i,1);selector=seed.length&&tokens.join("");if(!selector){push.apply(results,slice.call(seed,0));return results}break}}}}}compile(selector,match)(seed,context,xml,results,rsibling.test(selector));return results}if(document.querySelectorAll){(function(){var disconnectedMatch,oldSelect=select,rescape=/'|\\/g,rattributeQuotes=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,rbuggyQSA=[":focus"],rbuggyMatches=[":active"],matches=docElem.matchesSelector||docElem.mozMatchesSelector||docElem.webkitMatchesSelector||docElem.oMatchesSelector||docElem.msMatchesSelector;assert(function(div){div.innerHTML="";if(!div.querySelectorAll("[selected]").length){rbuggyQSA.push("\\["+whitespace+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)")}if(!div.querySelectorAll(":checked").length){rbuggyQSA.push(":checked")}});assert(function(div){div.innerHTML="

";if(div.querySelectorAll("[test^='']").length){rbuggyQSA.push("[*^$]="+whitespace+"*(?:\"\"|'')")}div.innerHTML="";if(!div.querySelectorAll(":enabled").length){rbuggyQSA.push(":enabled",":disabled")}});rbuggyQSA=new RegExp(rbuggyQSA.join("|"));select=function(selector,context,results,seed,xml){if(!seed&&!xml&&!rbuggyQSA.test(selector)){var groups,i,old=true,nid=expando,newContext=context,newSelector=context.nodeType===9&&selector;if(context.nodeType===1&&context.nodeName.toLowerCase()!=="object"){groups=tokenize(selector);if(old=context.getAttribute("id")){nid=old.replace(rescape,"\\$&")}else{context.setAttribute("id",nid)}nid="[id='"+nid+"'] ";i=groups.length;while(i--){groups[i]=nid+groups[i].join("")}newContext=rsibling.test(selector)&&context.parentNode||context;newSelector=groups.join(",")}if(newSelector){try{push.apply(results,slice.call(newContext.querySelectorAll(newSelector),0));return results}catch(qsaError){}finally{if(!old){context.removeAttribute("id")}}}}return oldSelect(selector,context,results,seed,xml)};if(matches){assert(function(div){disconnectedMatch=matches.call(div,"div");try{matches.call(div,"[test!='']:sizzle");rbuggyMatches.push("!=",pseudos)}catch(e){}});rbuggyMatches=new RegExp(rbuggyMatches.join("|"));Sizzle.matchesSelector=function(elem,expr){expr=expr.replace(rattributeQuotes,"='$1']");if(!isXML(elem)&&!rbuggyMatches.test(expr)&&!rbuggyQSA.test(expr)){try{var ret=matches.call(elem,expr);if(ret||disconnectedMatch||elem.document&&elem.document.nodeType!==11){return ret}}catch(e){}}return Sizzle(expr,null,null,[elem]).length>0}}})()}Expr.pseudos["nth"]=Expr.pseudos["eq"];function setFilters(){}Expr.filters=setFilters.prototype=Expr.pseudos;Expr.setFilters=new setFilters;Sizzle.attr=jQuery.attr;jQuery.find=Sizzle;jQuery.expr=Sizzle.selectors;jQuery.expr[":"]=jQuery.expr.pseudos;jQuery.unique=Sizzle.uniqueSort;jQuery.text=Sizzle.getText;jQuery.isXMLDoc=Sizzle.isXML;jQuery.contains=Sizzle.contains})(window);var runtil=/Until$/,rparentsprev=/^(?:parents|prev(?:Until|All))/,isSimple=/^.[^:#\[\.,]*$/,rneedsContext=jQuery.expr.match.needsContext,guaranteedUnique={children:true,contents:true,next:true,prev:true};jQuery.fn.extend({find:function(selector){var i,l,length,n,r,ret,self=this;if(typeof selector!=="string"){return jQuery(selector).filter(function(){for(i=0,l=self.length;i0){for(n=length;n=0:jQuery.filter(selector,this).length>0:this.filter(selector).length>0)},closest:function(selectors,context){var cur,i=0,l=this.length,ret=[],pos=rneedsContext.test(selectors)||typeof selectors!=="string"?jQuery(selectors,context||this.context):0;for(;i-1:jQuery.find.matchesSelector(cur,selectors)){ret.push(cur);break}cur=cur.parentNode}}ret=ret.length>1?jQuery.unique(ret):ret;return this.pushStack(ret,"closest",selectors)},index:function(elem){if(!elem){return this[0]&&this[0].parentNode?this.prevAll().length:-1}if(typeof elem==="string"){return jQuery.inArray(this[0],jQuery(elem))}return jQuery.inArray(elem.jquery?elem[0]:elem,this)},add:function(selector,context){var set=typeof selector==="string"?jQuery(selector,context):jQuery.makeArray(selector&&selector.nodeType?[selector]:selector),all=jQuery.merge(this.get(),set);return this.pushStack(isDisconnected(set[0])||isDisconnected(all[0])?all:jQuery.unique(all))},addBack:function(selector){return this.add(selector==null?this.prevObject:this.prevObject.filter(selector))}});jQuery.fn.andSelf=jQuery.fn.addBack;function isDisconnected(node){return!node||!node.parentNode||node.parentNode.nodeType===11}function sibling(cur,dir){do{cur=cur[dir]}while(cur&&cur.nodeType!==1);return cur}jQuery.each({parent:function(elem){var parent=elem.parentNode;return parent&&parent.nodeType!==11?parent:null},parents:function(elem){return jQuery.dir(elem,"parentNode")},parentsUntil:function(elem,i,until){return jQuery.dir(elem,"parentNode",until)},next:function(elem){return sibling(elem,"nextSibling")},prev:function(elem){return sibling(elem,"previousSibling")},nextAll:function(elem){return jQuery.dir(elem,"nextSibling")},prevAll:function(elem){return jQuery.dir(elem,"previousSibling")},nextUntil:function(elem,i,until){return jQuery.dir(elem,"nextSibling",until)},prevUntil:function(elem,i,until){return jQuery.dir(elem,"previousSibling",until)},siblings:function(elem){return jQuery.sibling((elem.parentNode||{}).firstChild,elem)},children:function(elem){return jQuery.sibling(elem.firstChild)},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.merge([],elem.childNodes)}},function(name,fn){jQuery.fn[name]=function(until,selector){var ret=jQuery.map(this,fn,until);if(!runtil.test(name)){selector=until}if(selector&&typeof selector==="string"){ret=jQuery.filter(selector,ret)}ret=this.length>1&&!guaranteedUnique[name]?jQuery.unique(ret):ret;if(this.length>1&&rparentsprev.test(name)){ret=ret.reverse()}return this.pushStack(ret,name,core_slice.call(arguments).join(","))}});jQuery.extend({filter:function(expr,elems,not){if(not){expr=":not("+expr+")"}return elems.length===1?jQuery.find.matchesSelector(elems[0],expr)?[elems[0]]:[]:jQuery.find.matches(expr,elems)},dir:function(elem,dir,until){var matched=[],cur=elem[dir];while(cur&&cur.nodeType!==9&&(until===undefined||cur.nodeType!==1||!jQuery(cur).is(until))){if(cur.nodeType===1){matched.push(cur)}cur=cur[dir]}return matched},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){r.push(n)}}return r}});function winnow(elements,qualifier,keep){qualifier=qualifier||0;if(jQuery.isFunction(qualifier)){return jQuery.grep(elements,function(elem,i){var retVal=!!qualifier.call(elem,i,elem);return retVal===keep})}else if(qualifier.nodeType){return jQuery.grep(elements,function(elem,i){return elem===qualifier===keep})}else if(typeof qualifier==="string"){var filtered=jQuery.grep(elements,function(elem){return elem.nodeType===1});if(isSimple.test(qualifier)){return jQuery.filter(qualifier,filtered,!keep)}else{qualifier=jQuery.filter(qualifier,filtered)}}return jQuery.grep(elements,function(elem,i){return jQuery.inArray(elem,qualifier)>=0===keep})}function createSafeFragment(document){var list=nodeNames.split("|"),safeFrag=document.createDocumentFragment();if(safeFrag.createElement){while(list.length){safeFrag.createElement(list.pop())}}return safeFrag}var nodeNames="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|"+"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",rinlinejQuery=/ jQuery\d+="(?:null|\d+)"/g,rleadingWhitespace=/^\s+/,rxhtmlTag=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,rtagName=/<([\w:]+)/,rtbody=/]","i"),rcheckableType=/^(?:checkbox|radio)$/,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rscriptType=/\/(java|ecma)script/i,rcleanScript=/^\s*\s*$/g,wrapMap={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},safeFragment=createSafeFragment(document),fragmentDiv=safeFragment.appendChild(document.createElement("div"));wrapMap.optgroup=wrapMap.option;wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!jQuery.support.htmlSerialize){wrapMap._default=[1,"X
","
"]}jQuery.fn.extend({text:function(value){return jQuery.access(this,function(value){return value===undefined?jQuery.text(this):this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(value))},null,value,arguments.length)},wrapAll:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapAll(html.call(this,i))})}if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){wrap.insertBefore(this[0])}wrap.map(function(){var elem=this;while(elem.firstChild&&elem.firstChild.nodeType===1){elem=elem.firstChild}return elem}).append(this)}return this},wrapInner:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapInner(html.call(this,i))})}return this.each(function(){var self=jQuery(this),contents=self.contents();if(contents.length){contents.wrapAll(html)}else{self.append(html)}})},wrap:function(html){var isFunction=jQuery.isFunction(html);return this.each(function(i){jQuery(this).wrapAll(isFunction?html.call(this,i):html)})},unwrap:function(){return this.parent().each(function(){if(!jQuery.nodeName(this,"body")){jQuery(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1||this.nodeType===11){this.appendChild(elem)}})},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1||this.nodeType===11){this.insertBefore(elem,this.firstChild)}})},before:function(){if(!isDisconnected(this[0])){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this)})}if(arguments.length){var set=jQuery.clean(arguments);return this.pushStack(jQuery.merge(set,this),"before",this.selector)}},after:function(){if(!isDisconnected(this[0])){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling)})}if(arguments.length){var set=jQuery.clean(arguments);return this.pushStack(jQuery.merge(this,set),"after",this.selector)}},remove:function(selector,keepData){var elem,i=0;for(;(elem=this[i])!=null;i++){if(!selector||jQuery.filter(selector,[elem]).length){if(!keepData&&elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"));jQuery.cleanData([elem])}if(elem.parentNode){elem.parentNode.removeChild(elem)}}}return this},empty:function(){var elem,i=0;for(;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"))}while(elem.firstChild){elem.removeChild(elem.firstChild)}}return this},clone:function(dataAndEvents,deepDataAndEvents){dataAndEvents=dataAndEvents==null?false:dataAndEvents;deepDataAndEvents=deepDataAndEvents==null?dataAndEvents:deepDataAndEvents;return this.map(function(){return jQuery.clone(this,dataAndEvents,deepDataAndEvents)})},html:function(value){return jQuery.access(this,function(value){var elem=this[0]||{},i=0,l=this.length;if(value===undefined){return elem.nodeType===1?elem.innerHTML.replace(rinlinejQuery,""):undefined}if(typeof value==="string"&&!rnoInnerhtml.test(value)&&(jQuery.support.htmlSerialize||!rnoshimcache.test(value))&&(jQuery.support.leadingWhitespace||!rleadingWhitespace.test(value))&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=value.replace(rxhtmlTag,"<$1>");try{for(;i1&&typeof value==="string"&&rchecked.test(value)){return this.each(function(){jQuery(this).domManip(args,table,callback)})}if(jQuery.isFunction(value)){return this.each(function(i){var self=jQuery(this);args[0]=value.call(this,i,table?self.html():undefined);self.domManip(args,table,callback)})}if(this[0]){results=jQuery.buildFragment(args,this,scripts);fragment=results.fragment;first=fragment.firstChild;if(fragment.childNodes.length===1){fragment=first}if(first){table=table&&jQuery.nodeName(first,"tr");for(iNoClone=results.cacheable||l-1;i0?this.clone(true):this).get();jQuery(insert[i])[original](elems);ret=ret.concat(elems)}return this.pushStack(ret,name,insert.selector)}}});function getAll(elem){if(typeof elem.getElementsByTagName!=="undefined"){return elem.getElementsByTagName("*")}else if(typeof elem.querySelectorAll!=="undefined"){return elem.querySelectorAll("*")}else{return[]}}function fixDefaultChecked(elem){if(rcheckableType.test(elem.type)){elem.defaultChecked=elem.checked}}jQuery.extend({clone:function(elem,dataAndEvents,deepDataAndEvents){var srcElements,destElements,i,clone;if(jQuery.support.html5Clone||jQuery.isXMLDoc(elem)||!rnoshimcache.test("<"+elem.nodeName+">")){clone=elem.cloneNode(true)}else{fragmentDiv.innerHTML=elem.outerHTML;fragmentDiv.removeChild(clone=fragmentDiv.firstChild)}if((!jQuery.support.noCloneEvent||!jQuery.support.noCloneChecked)&&(elem.nodeType===1||elem.nodeType===11)&&!jQuery.isXMLDoc(elem)){cloneFixAttributes(elem,clone);srcElements=getAll(elem);destElements=getAll(clone);for(i=0;srcElements[i];++i){if(destElements[i]){cloneFixAttributes(srcElements[i],destElements[i])}}}if(dataAndEvents){cloneCopyEvent(elem,clone);if(deepDataAndEvents){srcElements=getAll(elem);destElements=getAll(clone);for(i=0;srcElements[i];++i){cloneCopyEvent(srcElements[i],destElements[i])}}}srcElements=destElements=null;return clone},clean:function(elems,context,fragment,scripts){var i,j,elem,tag,wrap,depth,div,hasBody,tbody,len,handleScript,jsTags,safe=context===document&&safeFragment,ret=[];if(!context||typeof context.createDocumentFragment==="undefined"){context=document}for(i=0;(elem=elems[i])!=null;i++){if(typeof elem==="number"){elem+=""}if(!elem){continue}if(typeof elem==="string"){if(!rhtml.test(elem)){elem=context.createTextNode(elem)}else{safe=safe||createSafeFragment(context);div=context.createElement("div");safe.appendChild(div);elem=elem.replace(rxhtmlTag,"<$1>");tag=(rtagName.exec(elem)||["",""])[1].toLowerCase();wrap=wrapMap[tag]||wrapMap._default;depth=wrap[0];div.innerHTML=wrap[1]+elem+wrap[2];while(depth--){div=div.lastChild +}if(!jQuery.support.tbody){hasBody=rtbody.test(elem);tbody=tag==="table"&&!hasBody?div.firstChild&&div.firstChild.childNodes:wrap[1]===""&&!hasBody?div.childNodes:[];for(j=tbody.length-1;j>=0;--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j])}}}if(!jQuery.support.leadingWhitespace&&rleadingWhitespace.test(elem)){div.insertBefore(context.createTextNode(rleadingWhitespace.exec(elem)[0]),div.firstChild)}elem=div.childNodes;div.parentNode.removeChild(div)}}if(elem.nodeType){ret.push(elem)}else{jQuery.merge(ret,elem)}}if(div){elem=div=safe=null}if(!jQuery.support.appendChecked){for(i=0;(elem=ret[i])!=null;i++){if(jQuery.nodeName(elem,"input")){fixDefaultChecked(elem)}else if(typeof elem.getElementsByTagName!=="undefined"){jQuery.grep(elem.getElementsByTagName("input"),fixDefaultChecked)}}}if(fragment){handleScript=function(elem){if(!elem.type||rscriptType.test(elem.type)){return scripts?scripts.push(elem.parentNode?elem.parentNode.removeChild(elem):elem):fragment.appendChild(elem)}};for(i=0;(elem=ret[i])!=null;i++){if(!(jQuery.nodeName(elem,"script")&&handleScript(elem))){fragment.appendChild(elem);if(typeof elem.getElementsByTagName!=="undefined"){jsTags=jQuery.grep(jQuery.merge([],elem.getElementsByTagName("script")),handleScript);ret.splice.apply(ret,[i+1,0].concat(jsTags));i+=jsTags.length}}}}return ret},cleanData:function(elems,acceptData){var data,id,elem,type,i=0,internalKey=jQuery.expando,cache=jQuery.cache,deleteExpando=jQuery.support.deleteExpando,special=jQuery.event.special;for(;(elem=elems[i])!=null;i++){if(acceptData||jQuery.acceptData(elem)){id=elem[internalKey];data=id&&cache[id];if(data){if(data.events){for(type in data.events){if(special[type]){jQuery.event.remove(elem,type)}else{jQuery.removeEvent(elem,type,data.handle)}}}if(cache[id]){delete cache[id];if(deleteExpando){delete elem[internalKey]}else if(elem.removeAttribute){elem.removeAttribute(internalKey)}else{elem[internalKey]=null}jQuery.deletedIds.push(id)}}}}}});(function(){var matched,browser;jQuery.uaMatch=function(ua){ua=ua.toLowerCase();var match=/(chrome)[ \/]([\w.]+)/.exec(ua)||/(webkit)[ \/]([\w.]+)/.exec(ua)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua)||/(msie) ([\w.]+)/.exec(ua)||ua.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)||[];return{browser:match[1]||"",version:match[2]||"0"}};matched=jQuery.uaMatch(navigator.userAgent);browser={};if(matched.browser){browser[matched.browser]=true;browser.version=matched.version}if(browser.chrome){browser.webkit=true}else if(browser.webkit){browser.safari=true}jQuery.browser=browser;jQuery.sub=function(){function jQuerySub(selector,context){return new jQuerySub.fn.init(selector,context)}jQuery.extend(true,jQuerySub,this);jQuerySub.superclass=this;jQuerySub.fn=jQuerySub.prototype=this();jQuerySub.fn.constructor=jQuerySub;jQuerySub.sub=this.sub;jQuerySub.fn.init=function init(selector,context){if(context&&context instanceof jQuery&&!(context instanceof jQuerySub)){context=jQuerySub(context)}return jQuery.fn.init.call(this,selector,context,rootjQuerySub)};jQuerySub.fn.init.prototype=jQuerySub.fn;var rootjQuerySub=jQuerySub(document);return jQuerySub}})();var curCSS,iframe,iframeDoc,ralpha=/alpha\([^)]*\)/i,ropacity=/opacity=([^)]*)/,rposition=/^(top|right|bottom|left)$/,rdisplayswap=/^(none|table(?!-c[ea]).+)/,rmargin=/^margin/,rnumsplit=new RegExp("^("+core_pnum+")(.*)$","i"),rnumnonpx=new RegExp("^("+core_pnum+")(?!px)[a-z%]+$","i"),rrelNum=new RegExp("^([-+])=("+core_pnum+")","i"),elemdisplay={BODY:"block"},cssShow={position:"absolute",visibility:"hidden",display:"block"},cssNormalTransform={letterSpacing:0,fontWeight:400},cssExpand=["Top","Right","Bottom","Left"],cssPrefixes=["Webkit","O","Moz","ms"],eventsToggle=jQuery.fn.toggle;function vendorPropName(style,name){if(name in style){return name}var capName=name.charAt(0).toUpperCase()+name.slice(1),origName=name,i=cssPrefixes.length;while(i--){name=cssPrefixes[i]+capName;if(name in style){return name}}return origName}function isHidden(elem,el){elem=el||elem;return jQuery.css(elem,"display")==="none"||!jQuery.contains(elem.ownerDocument,elem)}function showHide(elements,show){var elem,display,values=[],index=0,length=elements.length;for(;index1)},show:function(){return showHide(this,true)},hide:function(){return showHide(this)},toggle:function(state,fn2){var bool=typeof state==="boolean";if(jQuery.isFunction(state)&&jQuery.isFunction(fn2)){return eventsToggle.apply(this,arguments)}return this.each(function(){if(bool?state:isHidden(this)){jQuery(this).show()}else{jQuery(this).hide()}})}});jQuery.extend({cssHooks:{opacity:{get:function(elem,computed){if(computed){var ret=curCSS(elem,"opacity");return ret===""?"1":ret}}}},cssNumber:{fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":jQuery.support.cssFloat?"cssFloat":"styleFloat"},style:function(elem,name,value,extra){if(!elem||elem.nodeType===3||elem.nodeType===8||!elem.style){return}var ret,type,hooks,origName=jQuery.camelCase(name),style=elem.style;name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(value!==undefined){type=typeof value;if(type==="string"&&(ret=rrelNum.exec(value))){value=(ret[1]+1)*ret[2]+parseFloat(jQuery.css(elem,name));type="number"}if(value==null||type==="number"&&isNaN(value)){return}if(type==="number"&&!jQuery.cssNumber[origName]){value+="px"}if(!hooks||!("set"in hooks)||(value=hooks.set(elem,value,extra))!==undefined){try{style[name]=value}catch(e){}}}else{if(hooks&&"get"in hooks&&(ret=hooks.get(elem,false,extra))!==undefined){return ret}return style[name]}},css:function(elem,name,numeric,extra){var val,num,hooks,origName=jQuery.camelCase(name);name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(elem.style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(hooks&&"get"in hooks){val=hooks.get(elem,true,extra)}if(val===undefined){val=curCSS(elem,name)}if(val==="normal"&&name in cssNormalTransform){val=cssNormalTransform[name]}if(numeric||extra!==undefined){num=parseFloat(val);return numeric||jQuery.isNumeric(num)?num||0:val}return val},swap:function(elem,options,callback){var ret,name,old={};for(name in options){old[name]=elem.style[name];elem.style[name]=options[name]}ret=callback.call(elem);for(name in options){elem.style[name]=old[name]}return ret}});if(window.getComputedStyle){curCSS=function(elem,name){var ret,width,minWidth,maxWidth,computed=window.getComputedStyle(elem,null),style=elem.style;if(computed){ret=computed.getPropertyValue(name)||computed[name];if(ret===""&&!jQuery.contains(elem.ownerDocument,elem)){ret=jQuery.style(elem,name)}if(rnumnonpx.test(ret)&&rmargin.test(name)){width=style.width;minWidth=style.minWidth;maxWidth=style.maxWidth;style.minWidth=style.maxWidth=style.width=ret;ret=computed.width;style.width=width;style.minWidth=minWidth;style.maxWidth=maxWidth}}return ret}}else if(document.documentElement.currentStyle){curCSS=function(elem,name){var left,rsLeft,ret=elem.currentStyle&&elem.currentStyle[name],style=elem.style;if(ret==null&&style&&style[name]){ret=style[name]}if(rnumnonpx.test(ret)&&!rposition.test(name)){left=style.left;rsLeft=elem.runtimeStyle&&elem.runtimeStyle.left;if(rsLeft){elem.runtimeStyle.left=elem.currentStyle.left}style.left=name==="fontSize"?"1em":ret;ret=style.pixelLeft+"px";style.left=left;if(rsLeft){elem.runtimeStyle.left=rsLeft}}return ret===""?"auto":ret}}function setPositiveNumber(elem,value,subtract){var matches=rnumsplit.exec(value);return matches?Math.max(0,matches[1]-(subtract||0))+(matches[2]||"px"):value}function augmentWidthOrHeight(elem,name,extra,isBorderBox){var i=extra===(isBorderBox?"border":"content")?4:name==="width"?1:0,val=0;for(;i<4;i+=2){if(extra==="margin"){val+=jQuery.css(elem,extra+cssExpand[i],true)}if(isBorderBox){if(extra==="content"){val-=parseFloat(curCSS(elem,"padding"+cssExpand[i]))||0}if(extra!=="margin"){val-=parseFloat(curCSS(elem,"border"+cssExpand[i]+"Width"))||0}}else{val+=parseFloat(curCSS(elem,"padding"+cssExpand[i]))||0;if(extra!=="padding"){val+=parseFloat(curCSS(elem,"border"+cssExpand[i]+"Width"))||0}}}return val}function getWidthOrHeight(elem,name,extra){var val=name==="width"?elem.offsetWidth:elem.offsetHeight,valueIsBorderBox=true,isBorderBox=jQuery.support.boxSizing&&jQuery.css(elem,"boxSizing")==="border-box";if(val<=0||val==null){val=curCSS(elem,name);if(val<0||val==null){val=elem.style[name]}if(rnumnonpx.test(val)){return val}valueIsBorderBox=isBorderBox&&(jQuery.support.boxSizingReliable||val===elem.style[name]);val=parseFloat(val)||0}return val+augmentWidthOrHeight(elem,name,extra||(isBorderBox?"border":"content"),valueIsBorderBox)+"px"}function css_defaultDisplay(nodeName){if(elemdisplay[nodeName]){return elemdisplay[nodeName]}var elem=jQuery("<"+nodeName+">").appendTo(document.body),display=elem.css("display");elem.remove();if(display==="none"||display===""){iframe=document.body.appendChild(iframe||jQuery.extend(document.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!iframeDoc||!iframe.createElement){iframeDoc=(iframe.contentWindow||iframe.contentDocument).document;iframeDoc.write("");iframeDoc.close()}elem=iframeDoc.body.appendChild(iframeDoc.createElement(nodeName));display=curCSS(elem,"display");document.body.removeChild(iframe)}elemdisplay[nodeName]=display;return display}jQuery.each(["height","width"],function(i,name){jQuery.cssHooks[name]={get:function(elem,computed,extra){if(computed){if(elem.offsetWidth===0&&rdisplayswap.test(curCSS(elem,"display"))){return jQuery.swap(elem,cssShow,function(){return getWidthOrHeight(elem,name,extra)})}else{return getWidthOrHeight(elem,name,extra)}}},set:function(elem,value,extra){return setPositiveNumber(elem,value,extra?augmentWidthOrHeight(elem,name,extra,jQuery.support.boxSizing&&jQuery.css(elem,"boxSizing")==="border-box"):0)}}});if(!jQuery.support.opacity){jQuery.cssHooks.opacity={get:function(elem,computed){return ropacity.test((computed&&elem.currentStyle?elem.currentStyle.filter:elem.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":computed?"1":""},set:function(elem,value){var style=elem.style,currentStyle=elem.currentStyle,opacity=jQuery.isNumeric(value)?"alpha(opacity="+value*100+")":"",filter=currentStyle&¤tStyle.filter||style.filter||"";style.zoom=1;if(value>=1&&jQuery.trim(filter.replace(ralpha,""))===""&&style.removeAttribute){style.removeAttribute("filter");if(currentStyle&&!currentStyle.filter){return}}style.filter=ralpha.test(filter)?filter.replace(ralpha,opacity):filter+" "+opacity}}}jQuery(function(){if(!jQuery.support.reliableMarginRight){jQuery.cssHooks.marginRight={get:function(elem,computed){return jQuery.swap(elem,{display:"inline-block"},function(){if(computed){return curCSS(elem,"marginRight")}})}}}if(!jQuery.support.pixelPosition&&jQuery.fn.position){jQuery.each(["top","left"],function(i,prop){jQuery.cssHooks[prop]={get:function(elem,computed){if(computed){var ret=curCSS(elem,prop);return rnumnonpx.test(ret)?jQuery(elem).position()[prop]+"px":ret}}}})}});if(jQuery.expr&&jQuery.expr.filters){jQuery.expr.filters.hidden=function(elem){return elem.offsetWidth===0&&elem.offsetHeight===0||!jQuery.support.reliableHiddenOffsets&&(elem.style&&elem.style.display||curCSS(elem,"display"))==="none"};jQuery.expr.filters.visible=function(elem){return!jQuery.expr.filters.hidden(elem)}}jQuery.each({margin:"",padding:"",border:"Width"},function(prefix,suffix){jQuery.cssHooks[prefix+suffix]={expand:function(value){var i,parts=typeof value==="string"?value.split(" "):[value],expanded={};for(i=0;i<4;i++){expanded[prefix+cssExpand[i]+suffix]=parts[i]||parts[i-2]||parts[0]}return expanded}};if(!rmargin.test(prefix)){jQuery.cssHooks[prefix+suffix].set=setPositiveNumber}});var r20=/%20/g,rbracket=/\[\]$/,rCRLF=/\r?\n/g,rinput=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,rselectTextarea=/^(?:select|textarea)/i;jQuery.fn.extend({serialize:function(){return jQuery.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||rselectTextarea.test(this.nodeName)||rinput.test(this.type))}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val.replace(rCRLF,"\r\n")}}):{name:elem.name,value:val.replace(rCRLF,"\r\n")}}).get()}});jQuery.param=function(a,traditional){var prefix,s=[],add=function(key,value){value=jQuery.isFunction(value)?value():value==null?"":value;s[s.length]=encodeURIComponent(key)+"="+encodeURIComponent(value)};if(traditional===undefined){traditional=jQuery.ajaxSettings&&jQuery.ajaxSettings.traditional}if(jQuery.isArray(a)||a.jquery&&!jQuery.isPlainObject(a)){jQuery.each(a,function(){add(this.name,this.value)})}else{for(prefix in a){buildParams(prefix,a[prefix],traditional,add)}}return s.join("&").replace(r20,"+")};function buildParams(prefix,obj,traditional,add){var name;if(jQuery.isArray(obj)){jQuery.each(obj,function(i,v){if(traditional||rbracket.test(prefix)){add(prefix,v)}else{buildParams(prefix+"["+(typeof v==="object"?i:"")+"]",v,traditional,add)}})}else if(!traditional&&jQuery.type(obj)==="object"){for(name in obj){buildParams(prefix+"["+name+"]",obj[name],traditional,add)}}else{add(prefix,obj)}}var ajaxLocParts,ajaxLocation,rhash=/#.*$/,rheaders=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,rlocalProtocol=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,rnoContent=/^(?:GET|HEAD)$/,rprotocol=/^\/\//,rquery=/\?/,rscript=/)<[^<]*)*<\/script>/gi,rts=/([?&])_=[^&]*/,rurl=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,_load=jQuery.fn.load,prefilters={},transports={},allTypes=["*/"]+["*"];try{ajaxLocation=location.href}catch(e){ajaxLocation=document.createElement("a");ajaxLocation.href="";ajaxLocation=ajaxLocation.href}ajaxLocParts=rurl.exec(ajaxLocation.toLowerCase())||[];function addToPrefiltersOrTransports(structure){return function(dataTypeExpression,func){if(typeof dataTypeExpression!=="string"){func=dataTypeExpression;dataTypeExpression="*"}var dataType,list,placeBefore,dataTypes=dataTypeExpression.toLowerCase().split(core_rspace),i=0,length=dataTypes.length;if(jQuery.isFunction(func)){for(;i=0){selector=url.slice(off,url.length);url=url.slice(0,off)}if(jQuery.isFunction(params)){callback=params;params=undefined}else if(params&&typeof params==="object"){type="POST"}jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(jqXHR,status){if(callback){self.each(callback,response||[jqXHR.responseText,status,jqXHR])}}}).done(function(responseText){response=arguments;self.html(selector?jQuery("
").append(responseText.replace(rscript,"")).find(selector):responseText)});return this};jQuery.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(i,o){jQuery.fn[o]=function(f){return this.on(o,f)}});jQuery.each(["get","post"],function(i,method){jQuery[method]=function(url,data,callback,type){if(jQuery.isFunction(data)){type=type||callback;callback=data;data=undefined}return jQuery.ajax({type:method,url:url,data:data,success:callback,dataType:type})}});jQuery.extend({getScript:function(url,callback){return jQuery.get(url,undefined,callback,"script")},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json")},ajaxSetup:function(target,settings){if(settings){ajaxExtend(target,jQuery.ajaxSettings)}else{settings=target;target=jQuery.ajaxSettings}ajaxExtend(target,settings);return target},ajaxSettings:{url:ajaxLocation,isLocal:rlocalProtocol.test(ajaxLocParts[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":allTypes},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":window.String,"text html":true,"text json":jQuery.parseJSON,"text xml":jQuery.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:addToPrefiltersOrTransports(prefilters),ajaxTransport:addToPrefiltersOrTransports(transports),ajax:function(url,options){if(typeof url==="object"){options=url;url=undefined}options=options||{};var ifModifiedKey,responseHeadersString,responseHeaders,transport,timeoutTimer,parts,fireGlobals,i,s=jQuery.ajaxSetup({},options),callbackContext=s.context||s,globalEventContext=callbackContext!==s&&(callbackContext.nodeType||callbackContext instanceof jQuery)?jQuery(callbackContext):jQuery.event,deferred=jQuery.Deferred(),completeDeferred=jQuery.Callbacks("once memory"),statusCode=s.statusCode||{},requestHeaders={},requestHeadersNames={},state=0,strAbort="canceled",jqXHR={readyState:0,setRequestHeader:function(name,value){if(!state){var lname=name.toLowerCase();name=requestHeadersNames[lname]=requestHeadersNames[lname]||name;requestHeaders[name]=value}return this},getAllResponseHeaders:function(){return state===2?responseHeadersString:null},getResponseHeader:function(key){var match;if(state===2){if(!responseHeaders){responseHeaders={};while(match=rheaders.exec(responseHeadersString)){responseHeaders[match[1].toLowerCase()]=match[2]}}match=responseHeaders[key.toLowerCase()]}return match===undefined?null:match},overrideMimeType:function(type){if(!state){s.mimeType=type}return this},abort:function(statusText){statusText=statusText||strAbort;if(transport){transport.abort(statusText)}done(0,statusText);return this}};function done(status,nativeStatusText,responses,headers){var isSuccess,success,error,response,modified,statusText=nativeStatusText;if(state===2){return}state=2;if(timeoutTimer){clearTimeout(timeoutTimer)}transport=undefined;responseHeadersString=headers||"";jqXHR.readyState=status>0?4:0;if(responses){response=ajaxHandleResponses(s,jqXHR,responses)}if(status>=200&&status<300||status===304){if(s.ifModified){modified=jqXHR.getResponseHeader("Last-Modified");if(modified){jQuery.lastModified[ifModifiedKey]=modified}modified=jqXHR.getResponseHeader("Etag");if(modified){jQuery.etag[ifModifiedKey]=modified}}if(status===304){statusText="notmodified";isSuccess=true}else{isSuccess=ajaxConvert(s,response);statusText=isSuccess.state;success=isSuccess.data;error=isSuccess.error;isSuccess=!error}}else{error=statusText;if(!statusText||status){statusText="error";if(status<0){status=0}}}jqXHR.status=status;jqXHR.statusText=(nativeStatusText||statusText)+"";if(isSuccess){deferred.resolveWith(callbackContext,[success,statusText,jqXHR])}else{deferred.rejectWith(callbackContext,[jqXHR,statusText,error])}jqXHR.statusCode(statusCode);statusCode=undefined;if(fireGlobals){globalEventContext.trigger("ajax"+(isSuccess?"Success":"Error"),[jqXHR,s,isSuccess?success:error])}completeDeferred.fireWith(callbackContext,[jqXHR,statusText]);if(fireGlobals){globalEventContext.trigger("ajaxComplete",[jqXHR,s]);if(!--jQuery.active){jQuery.event.trigger("ajaxStop")}}}deferred.promise(jqXHR);jqXHR.success=jqXHR.done;jqXHR.error=jqXHR.fail;jqXHR.complete=completeDeferred.add;jqXHR.statusCode=function(map){if(map){var tmp;if(state<2){for(tmp in map){statusCode[tmp]=[statusCode[tmp],map[tmp]]}}else{tmp=map[jqXHR.status];jqXHR.always(tmp)}}return this};s.url=((url||s.url)+"").replace(rhash,"").replace(rprotocol,ajaxLocParts[1]+"//");s.dataTypes=jQuery.trim(s.dataType||"*").toLowerCase().split(core_rspace);if(s.crossDomain==null){parts=rurl.exec(s.url.toLowerCase());s.crossDomain=!!(parts&&(parts[1]!==ajaxLocParts[1]||parts[2]!==ajaxLocParts[2]||(parts[3]||(parts[1]==="http:"?80:443))!=(ajaxLocParts[3]||(ajaxLocParts[1]==="http:"?80:443))))}if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data,s.traditional)}inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);if(state===2){return jqXHR}fireGlobals=s.global;s.type=s.type.toUpperCase();s.hasContent=!rnoContent.test(s.type);if(fireGlobals&&jQuery.active++===0){jQuery.event.trigger("ajaxStart")}if(!s.hasContent){if(s.data){s.url+=(rquery.test(s.url)?"&":"?")+s.data;delete s.data}ifModifiedKey=s.url;if(s.cache===false){var ts=jQuery.now(),ret=s.url.replace(rts,"$1_="+ts);s.url=ret+(ret===s.url?(rquery.test(s.url)?"&":"?")+"_="+ts:"")}}if(s.data&&s.hasContent&&s.contentType!==false||options.contentType){jqXHR.setRequestHeader("Content-Type",s.contentType)}if(s.ifModified){ifModifiedKey=ifModifiedKey||s.url;if(jQuery.lastModified[ifModifiedKey]){jqXHR.setRequestHeader("If-Modified-Since",jQuery.lastModified[ifModifiedKey])}if(jQuery.etag[ifModifiedKey]){jqXHR.setRequestHeader("If-None-Match",jQuery.etag[ifModifiedKey])}}jqXHR.setRequestHeader("Accept",s.dataTypes[0]&&s.accepts[s.dataTypes[0]]?s.accepts[s.dataTypes[0]]+(s.dataTypes[0]!=="*"?", "+allTypes+"; q=0.01":""):s.accepts["*"]);for(i in s.headers){jqXHR.setRequestHeader(i,s.headers[i])}if(s.beforeSend&&(s.beforeSend.call(callbackContext,jqXHR,s)===false||state===2)){return jqXHR.abort()}strAbort="abort";for(i in{success:1,error:1,complete:1}){jqXHR[i](s[i])}transport=inspectPrefiltersOrTransports(transports,s,options,jqXHR);if(!transport){done(-1,"No Transport")}else{jqXHR.readyState=1;if(fireGlobals){globalEventContext.trigger("ajaxSend",[jqXHR,s])}if(s.async&&s.timeout>0){timeoutTimer=setTimeout(function(){jqXHR.abort("timeout")},s.timeout)}try{state=1;transport.send(requestHeaders,done)}catch(e){if(state<2){done(-1,e)}else{throw e}}}return jqXHR},active:0,lastModified:{},etag:{}});function ajaxHandleResponses(s,jqXHR,responses){var ct,type,finalDataType,firstDataType,contents=s.contents,dataTypes=s.dataTypes,responseFields=s.responseFields;for(type in responseFields){if(type in responses){jqXHR[responseFields[type]]=responses[type]}}while(dataTypes[0]==="*"){dataTypes.shift();if(ct===undefined){ct=s.mimeType||jqXHR.getResponseHeader("content-type")}}if(ct){for(type in contents){if(contents[type]&&contents[type].test(ct)){dataTypes.unshift(type);break}}}if(dataTypes[0]in responses){finalDataType=dataTypes[0]}else{for(type in responses){if(!dataTypes[0]||s.converters[type+" "+dataTypes[0]]){finalDataType=type;break}if(!firstDataType){firstDataType=type}}finalDataType=finalDataType||firstDataType}if(finalDataType){if(finalDataType!==dataTypes[0]){dataTypes.unshift(finalDataType)}return responses[finalDataType]}}function ajaxConvert(s,response){var conv,conv2,current,tmp,dataTypes=s.dataTypes.slice(),prev=dataTypes[0],converters={},i=0;if(s.dataFilter){response=s.dataFilter(response,s.dataType)}if(dataTypes[1]){for(conv in s.converters){converters[conv.toLowerCase()]=s.converters[conv]}}for(;current=dataTypes[++i];){if(current!=="*"){if(prev!=="*"&&prev!==current){conv=converters[prev+" "+current]||converters["* "+current];if(!conv){for(conv2 in converters){tmp=conv2.split(" ");if(tmp[1]===current){conv=converters[prev+" "+tmp[0]]||converters["* "+tmp[0]];if(conv){if(conv===true){conv=converters[conv2]}else if(converters[conv2]!==true){current=tmp[0];dataTypes.splice(i--,0,current)}break}}}}if(conv!==true){if(conv&&s["throws"]){response=conv(response)}else{try{response=conv(response)}catch(e){return{state:"parsererror",error:conv?e:"No conversion from "+prev+" to "+current}}}}}prev=current}}return{state:"success",data:response}}var oldCallbacks=[],rquestion=/\?/,rjsonp=/(=)\?(?=&|$)|\?\?/,nonce=jQuery.now();jQuery.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var callback=oldCallbacks.pop()||jQuery.expando+"_"+nonce++;this[callback]=true;return callback}});jQuery.ajaxPrefilter("json jsonp",function(s,originalSettings,jqXHR){var callbackName,overwritten,responseContainer,data=s.data,url=s.url,hasCallback=s.jsonp!==false,replaceInUrl=hasCallback&&rjsonp.test(url),replaceInData=hasCallback&&!replaceInUrl&&typeof data==="string"&&!(s.contentType||"").indexOf("application/x-www-form-urlencoded")&&rjsonp.test(data);if(s.dataTypes[0]==="jsonp"||replaceInUrl||replaceInData){callbackName=s.jsonpCallback=jQuery.isFunction(s.jsonpCallback)?s.jsonpCallback():s.jsonpCallback;overwritten=window[callbackName];if(replaceInUrl){s.url=url.replace(rjsonp,"$1"+callbackName)}else if(replaceInData){s.data=data.replace(rjsonp,"$1"+callbackName)}else if(hasCallback){s.url+=(rquestion.test(url)?"&":"?")+s.jsonp+"="+callbackName}s.converters["script json"]=function(){if(!responseContainer){jQuery.error(callbackName+" was not called")}return responseContainer[0]};s.dataTypes[0]="json";window[callbackName]=function(){responseContainer=arguments};jqXHR.always(function(){window[callbackName]=overwritten;if(s[callbackName]){s.jsonpCallback=originalSettings.jsonpCallback;oldCallbacks.push(callbackName)}if(responseContainer&&jQuery.isFunction(overwritten)){overwritten(responseContainer[0])}responseContainer=overwritten=undefined});return"script"}});jQuery.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(text){jQuery.globalEval(text);return text}}});jQuery.ajaxPrefilter("script",function(s){if(s.cache===undefined){s.cache=false}if(s.crossDomain){s.type="GET";s.global=false}});jQuery.ajaxTransport("script",function(s){if(s.crossDomain){var script,head=document.head||document.getElementsByTagName("head")[0]||document.documentElement;return{send:function(_,callback){script=document.createElement("script");script.async="async";if(s.scriptCharset){script.charset=s.scriptCharset}script.src=s.url;script.onload=script.onreadystatechange=function(_,isAbort){if(isAbort||!script.readyState||/loaded|complete/.test(script.readyState)){script.onload=script.onreadystatechange=null;if(head&&script.parentNode){head.removeChild(script)}script=undefined;if(!isAbort){callback(200,"success")}}};head.insertBefore(script,head.firstChild)},abort:function(){if(script){script.onload(0,1)}}}}});var xhrCallbacks,xhrOnUnloadAbort=window.ActiveXObject?function(){for(var key in xhrCallbacks){xhrCallbacks[key](0,1)}}:false,xhrId=0;function createStandardXHR(){try{return new window.XMLHttpRequest}catch(e){}}function createActiveXHR(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}jQuery.ajaxSettings.xhr=window.ActiveXObject?function(){return!this.isLocal&&createStandardXHR()||createActiveXHR()}:createStandardXHR;(function(xhr){jQuery.extend(jQuery.support,{ajax:!!xhr,cors:!!xhr&&"withCredentials"in xhr})})(jQuery.ajaxSettings.xhr());if(jQuery.support.ajax){jQuery.ajaxTransport(function(s){if(!s.crossDomain||jQuery.support.cors){var callback;return{send:function(headers,complete){var handle,i,xhr=s.xhr();if(s.username){xhr.open(s.type,s.url,s.async,s.username,s.password)}else{xhr.open(s.type,s.url,s.async)}if(s.xhrFields){for(i in s.xhrFields){xhr[i]=s.xhrFields[i]}}if(s.mimeType&&xhr.overrideMimeType){xhr.overrideMimeType(s.mimeType)}if(!s.crossDomain&&!headers["X-Requested-With"]){headers["X-Requested-With"]="XMLHttpRequest"}try{for(i in headers){xhr.setRequestHeader(i,headers[i])}}catch(_){}xhr.send(s.hasContent&&s.data||null);callback=function(_,isAbort){var status,statusText,responseHeaders,responses,xml;try{if(callback&&(isAbort||xhr.readyState===4)){callback=undefined;if(handle){xhr.onreadystatechange=jQuery.noop;if(xhrOnUnloadAbort){delete xhrCallbacks[handle]}}if(isAbort){if(xhr.readyState!==4){xhr.abort()}}else{status=xhr.status;responseHeaders=xhr.getAllResponseHeaders();responses={};xml=xhr.responseXML;if(xml&&xml.documentElement){responses.xml=xml}try{responses.text=xhr.responseText}catch(e){}try{statusText=xhr.statusText}catch(e){statusText=""}if(!status&&s.isLocal&&!s.crossDomain){status=responses.text?200:404}else if(status===1223){status=204}}}}catch(firefoxAccessException){if(!isAbort){complete(-1,firefoxAccessException)}}if(responses){complete(status,statusText,responses,responseHeaders)}};if(!s.async){callback()}else if(xhr.readyState===4){setTimeout(callback,0)}else{handle=++xhrId;if(xhrOnUnloadAbort){if(!xhrCallbacks){xhrCallbacks={};jQuery(window).unload(xhrOnUnloadAbort)}xhrCallbacks[handle]=callback}xhr.onreadystatechange=callback}},abort:function(){if(callback){callback(0,1)}}}}})}var fxNow,timerId,rfxtypes=/^(?:toggle|show|hide)$/,rfxnum=new RegExp("^(?:([-+])=|)("+core_pnum+")([a-z%]*)$","i"),rrun=/queueHooks$/,animationPrefilters=[defaultPrefilter],tweeners={"*":[function(prop,value){var end,unit,tween=this.createTween(prop,value),parts=rfxnum.exec(value),target=tween.cur(),start=+target||0,scale=1,maxIterations=20;if(parts){end=+parts[2];unit=parts[3]||(jQuery.cssNumber[prop]?"":"px");if(unit!=="px"&&start){start=jQuery.css(tween.elem,prop,true)||end||1;do{scale=scale||".5";start=start/scale;jQuery.style(tween.elem,prop,start+unit)}while(scale!==(scale=tween.cur()/target)&&scale!==1&&--maxIterations)}tween.unit=unit;tween.start=start;tween.end=parts[1]?start+(parts[1]+1)*end:end}return tween}]};function createFxNow(){setTimeout(function(){fxNow=undefined},0);return fxNow=jQuery.now()}function createTweens(animation,props){jQuery.each(props,function(prop,value){var collection=(tweeners[prop]||[]).concat(tweeners["*"]),index=0,length=collection.length;for(;index-1,props={},curPosition={},curTop,curLeft;if(calculatePosition){curPosition=curElem.position();curTop=curPosition.top;curLeft=curPosition.left}else{curTop=parseFloat(curCSSTop)||0;curLeft=parseFloat(curCSSLeft)||0}if(jQuery.isFunction(options)){options=options.call(elem,i,curOffset)}if(options.top!=null){props.top=options.top-curOffset.top+curTop}if(options.left!=null){props.left=options.left-curOffset.left+curLeft}if("using"in options){options.using.call(elem,props)}else{curElem.css(props)}}};jQuery.fn.extend({position:function(){if(!this[0]){return}var elem=this[0],offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=rroot.test(offsetParent[0].nodeName)?{top:0,left:0}:offsetParent.offset();offset.top-=parseFloat(jQuery.css(elem,"marginTop"))||0;offset.left-=parseFloat(jQuery.css(elem,"marginLeft"))||0;parentOffset.top+=parseFloat(jQuery.css(offsetParent[0],"borderTopWidth"))||0;parentOffset.left+=parseFloat(jQuery.css(offsetParent[0],"borderLeftWidth"))||0;return{top:offset.top-parentOffset.top,left:offset.left-parentOffset.left}},offsetParent:function(){return this.map(function(){var offsetParent=this.offsetParent||document.body;while(offsetParent&&(!rroot.test(offsetParent.nodeName)&&jQuery.css(offsetParent,"position")==="static")){offsetParent=offsetParent.offsetParent}return offsetParent||document.body})}});jQuery.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(method,prop){var top=/Y/.test(prop);jQuery.fn[method]=function(val){return jQuery.access(this,function(elem,method,val){var win=getWindow(elem);if(val===undefined){return win?prop in win?win[prop]:win.document.documentElement[method]:elem[method]}if(win){win.scrollTo(!top?val:jQuery(win).scrollLeft(),top?val:jQuery(win).scrollTop())}else{elem[method]=val}},method,val,arguments.length,null)}});function getWindow(elem){return jQuery.isWindow(elem)?elem:elem.nodeType===9?elem.defaultView||elem.parentWindow:false}jQuery.each({Height:"height",Width:"width"},function(name,type){jQuery.each({padding:"inner"+name,content:type,"":"outer"+name},function(defaultExtra,funcName){jQuery.fn[funcName]=function(margin,value){var chainable=arguments.length&&(defaultExtra||typeof margin!=="boolean"),extra=defaultExtra||(margin===true||value===true?"margin":"border");return jQuery.access(this,function(elem,type,value){var doc;if(jQuery.isWindow(elem)){return elem.document.documentElement["client"+name]}if(elem.nodeType===9){doc=elem.documentElement;return Math.max(elem.body["scroll"+name],doc["scroll"+name],elem.body["offset"+name],doc["offset"+name],doc["client"+name])}return value===undefined?jQuery.css(elem,type,value,extra):jQuery.style(elem,type,value,extra)},type,chainable?margin:undefined,chainable,null)}})});window.jQuery=window.$=jQuery;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return jQuery})}})(window); \ No newline at end of file diff --git a/tests/Issue18.htm b/tests/Issue18.htm index 0667a07..63a011b 100644 --- a/tests/Issue18.htm +++ b/tests/Issue18.htm @@ -2,11 +2,11 @@ CurvedLines Plugin for flot - + - - - + + + diff --git a/tests/Issue19.htm b/tests/Issue19.htm index ec10281..55ba737 100644 --- a/tests/Issue19.htm +++ b/tests/Issue19.htm @@ -2,12 +2,10 @@ CurvedLines Plugin for flot - + - - - - + + diff --git a/tests/testDate.htm b/tests/testDate.htm index 2b599e0..f4f734f 100644 --- a/tests/testDate.htm +++ b/tests/testDate.htm @@ -2,10 +2,10 @@ CurvedLines Plugin for flot - + - - + + diff --git a/tests/testExample.htm b/tests/testExample.htm index 242516d..668b4ad 100644 --- a/tests/testExample.htm +++ b/tests/testExample.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testExampleFillMultiAxis.htm b/tests/testExampleFillMultiAxis.htm index 9ce7a0c..af19bc2 100644 --- a/tests/testExampleFillMultiAxis.htm +++ b/tests/testExampleFillMultiAxis.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testExampleFit.htm b/tests/testExampleFit.htm index d0aef5e..a640659 100644 --- a/tests/testExampleFit.htm +++ b/tests/testExampleFit.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testSaddlePoint.htm b/tests/testSaddlePoint.htm index d70c30e..8520dde 100644 --- a/tests/testSaddlePoint.htm +++ b/tests/testSaddlePoint.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testSinglePoint.htm b/tests/testSinglePoint.htm index 936a086..b2b2a98 100644 --- a/tests/testSinglePoint.htm +++ b/tests/testSinglePoint.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testThreshold.htm b/tests/testThreshold.htm index 128331c..35bdaa1 100644 --- a/tests/testThreshold.htm +++ b/tests/testThreshold.htm @@ -2,10 +2,10 @@ CurvedLines Plugin for flot - + - - + + diff --git a/tests/testTooltip.htm b/tests/testTooltip.htm index feeecc2..a8dfc74 100644 --- a/tests/testTooltip.htm +++ b/tests/testTooltip.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - + diff --git a/tests/testZeroDrop.htm b/tests/testZeroDrop.htm index 75ffc88..64e76f6 100644 --- a/tests/testZeroDrop.htm +++ b/tests/testZeroDrop.htm @@ -2,9 +2,9 @@ CurvedLines Plugin for flot - + - +