aboutsummaryrefslogtreecommitdiffstats
path: root/web/js
diff options
context:
space:
mode:
authorOle Mathias Aa. Heggem <olemathias.aa.heggem@gmail.com>2025-04-13 07:18:45 +0200
committerGitHub <noreply@github.com>2025-04-13 07:18:45 +0200
commit4ea3a099b05fa910498bfbf1b2d7387118355472 (patch)
treec248cf6764412471ee3e0d1218761bee19fb396a /web/js
parent09710c061d5b8ae86b3dfe49f4b8936c13a10535 (diff)
Upgrade bootstrap and rewrite API (#230)HEADmaster
Diffstat (limited to 'web/js')
-rw-r--r--web/js/Chart.min.js10
-rw-r--r--web/js/bootstrap.js2317
-rw-r--r--web/js/bootstrap.min.js7
-rw-r--r--web/js/jquery.datetimepicker.full.js3073
-rw-r--r--web/js/jquery.min.js4
-rw-r--r--web/js/moment.min.js7
-rw-r--r--web/js/nms-admin-pane.js99
-rw-r--r--web/js/nms-color-util.js127
-rw-r--r--web/js/nms-data.js429
-rw-r--r--web/js/nms-dhcp.js45
-rw-r--r--web/js/nms-draw-chart.js350
-rw-r--r--web/js/nms-fetch.js38
-rw-r--r--web/js/nms-info-box.js1851
-rw-r--r--web/js/nms-map-handlers.js2137
-rw-r--r--web/js/nms-map.js1189
-rw-r--r--web/js/nms-nightmode.js32
-rw-r--r--web/js/nms-oplog.js527
-rw-r--r--web/js/nms-search.js393
-rw-r--r--web/js/nms-template.js103
-rw-r--r--web/js/nms-time.js231
-rw-r--r--web/js/nms-types.js417
-rw-r--r--web/js/nms-ui-boxes.js512
-rw-r--r--web/js/nms-ui-switch-summary.js107
-rw-r--r--web/js/nms-ui-switch.js616
-rw-r--r--web/js/nms-ui.js33
-rw-r--r--web/js/nms.js1011
-rw-r--r--web/js/npm.js13
27 files changed, 5247 insertions, 10431 deletions
diff --git a/web/js/Chart.min.js b/web/js/Chart.min.js
deleted file mode 100644
index dbf22c4..0000000
--- a/web/js/Chart.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.7.2
- *
- * Copyright 2018 Chart.js Contributors
- * Released under the MIT license
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
- */
-!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,i,n){function a(r,s){if(!i[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[r]={exports:{}};e[r][0].call(d.exports,function(t){var i=e[r][1][t];return a(i||t)},d,d.exports,t,e,i,n)}return i[r].exports}for(var o="function"==typeof require&&require,r=0;r<n.length;r++)a(n[r]);return a}({1:[function(t,e,i){},{}],2:[function(t,e,i){var n=t(6);function a(t){if(t){var e=[0,0,0],i=1,a=t.match(/^#([a-fA-F0-9]{3})$/i);if(a){a=a[1];for(var o=0;o<e.length;o++)e[o]=parseInt(a[o]+a[o],16)}else if(a=t.match(/^#([a-fA-F0-9]{6})$/i)){a=a[1];for(o=0;o<e.length;o++)e[o]=parseInt(a.slice(2*o,2*o+2),16)}else if(a=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=parseInt(a[o+1]);i=parseFloat(a[4])}else if(a=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=Math.round(2.55*parseFloat(a[o+1]));i=parseFloat(a[4])}else if(a=t.match(/(\w+)/)){if("transparent"==a[1])return[0,0,0,0];if(!(e=n[a[1]]))return}for(o=0;o<e.length;o++)e[o]=d(e[o],0,255);return i=i||0==i?d(i,0,1):1,e[3]=i,e}}function o(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function r(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function s(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function l(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function u(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function d(t,e,i){return Math.min(Math.max(e,t),i)}function c(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}e.exports={getRgba:a,getHsla:o,getRgb:function(t){var e=a(t);return e&&e.slice(0,3)},getHsl:function(t){var e=o(t);return e&&e.slice(0,3)},getHwb:r,getAlpha:function(t){var e=a(t);{if(e)return e[3];if(e=o(t))return e[3];if(e=r(t))return e[3]}},hexString:function(t){return"#"+c(t[0])+c(t[1])+c(t[2])},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return s(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:s,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return l(t,e);var i=Math.round(t[0]/255*100),n=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+i+"%, "+n+"%, "+a+"%)"},percentaString:l,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return u(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:u,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return h[t.slice(0,3)]}};var h={};for(var f in n)h[n[f]]=f},{6:6}],3:[function(t,e,i){var n=t(5),a=t(2),o=function(t){return t instanceof o?t:this instanceof o?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=a.getRgba(t))?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new o(t);var e};o.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],i=0;i<t.length;i++){var n=t[i]/255;e[i]=n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),i=t.luminosity();return e>i?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=this,n=t,a=void 0===e?.5:e,o=2*a-1,r=i.alpha()-n.alpha(),s=((o*r==-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*i.red()+l*n.red(),s*i.green()+l*n.green(),s*i.blue()+l*n.blue()).alpha(i.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new o,n=this.values,a=i.values;for(var r in n)n.hasOwnProperty(r)&&(t=n[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return i}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n<t.length;n++)i[t.charAt(n)]=e[t][n];return 1!==e.alpha&&(i.a=e.alpha),i},o.prototype.setValues=function(t,e){var i,a,o=this.values,r=this.spaces,s=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)o[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(i=0;i<t.length;i++)o[t][i]=e[t.charAt(i)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(i=0;i<t.length;i++)o[t][i]=e[u[i]];l=e.alpha}if(o.alpha=Math.max(0,Math.min(1,void 0===l?o.alpha:l)),"alpha"===t)return!1;for(i=0;i<t.length;i++)a=Math.max(0,Math.min(s[t][i],o[t][i])),o[t][i]=Math.round(a);for(var d in r)d!==t&&(o[d]=n[t][d](o[t]));return!0},o.prototype.setSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i),this)},o.prototype.setChannel=function(t,e,i){var n=this.values[t];return void 0===i?n[e]:i===n[e]?this:(n[e]=i,this.setValues(t,n),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,i){function n(t){var e,i,n=t[0]/255,a=t[1]/255,o=t[2]/255,r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),i=(r+s)/2,[e,100*(s==r?0:i<=.5?l/(s+r):l/(2-s-r)),100*i]}function a(t){var e,i,n=t[0],a=t[1],o=t[2],r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return i=0==s?0:l/s*1e3/10,s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),[e,i,s/255*1e3/10]}function o(t){var e=t[0],i=t[1],a=t[2];return[n(t)[0],100*(1/255*Math.min(e,Math.min(i,a))),100*(a=1-1/255*Math.max(e,Math.max(i,a)))]}function s(t){var e,i=t[0]/255,n=t[1]/255,a=t[2]/255;return[100*((1-i-(e=Math.min(1-i,1-n,1-a)))/(1-e)||0),100*((1-n-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]}function l(t){return C[JSON.stringify(t)]}function u(t){var e=t[0]/255,i=t[1]/255,n=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=u(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function c(t){var e,i,n,a,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[o=255*l,o,o];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(n=r+1/3*-(u-1))<0&&n++,n>1&&n--,o=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[u]=255*o;return a}function h(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*n*(1-i),s=255*n*(1-i*o),l=255*n*(1-i*(1-o));n*=255;switch(a){case 0:return[n,l,r];case 1:return[s,n,r];case 2:return[r,n,l];case 3:return[r,s,n];case 4:return[l,r,n];case 5:return[n,r,s]}}function f(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function p(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function m(t){var e,i,n,a=t[0]/100,o=t[1]/100,r=t[2]/100;return i=-.9689*a+1.8758*o+.0415*r,n=.0557*a+-.204*o+1.057*r,e=(e=3.2406*a+-1.5372*o+-.4986*r)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function v(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function x(t){var e,i,n,a,o=t[0],r=t[1],s=t[2];return o<=8?a=(i=100*o/903.3)/100*7.787+16/116:(i=100*Math.pow((o+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function y(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function k(t){return m(x(t))}function M(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return S[t]}e.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return y(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,o=t[2]/100;return e=a*o,[n,100*(e=(e/=(i=(2-a)*o)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:p,cmyk2hsl:function(t){return n(p(t))},cmyk2hsv:function(t){return a(p(t))},cmyk2hwb:function(t){return o(p(t))},cmyk2keyword:function(t){return l(p(t))},keyword2rgb:w,keyword2hsl:function(t){return n(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:m,xyz2lab:v,xyz2lch:function(t){return y(v(t))},lab2xyz:x,lab2rgb:k,lab2lch:y,lch2lab:M,lch2xyz:function(t){return x(M(t))},lch2rgb:function(t){return k(M(t))}};var S={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],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],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},C={};for(var _ in S)C[JSON.stringify(S[_])]=_},{}],5:[function(t,e,i){var n=t(4),a=function(){return new u};for(var o in n){a[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),n[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];(a[s]=a[s]||{})[l]=a[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=n[t](e);if("string"==typeof i||void 0===i)return i;for(var a=0;a<i.length;a++)i[a]=Math.round(i[a]);return i}}(o)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var i=this.space,n=this.convs[i];e=a[i][t](n),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{4:4}],6:[function(t,e,i){"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],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],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,i){var n=t(29)();n.helpers=t(45),t(27)(n),n.defaults=t(25),n.Element=t(26),n.elements=t(40),n.Interaction=t(28),n.layouts=t(30),n.platform=t(48),n.plugins=t(31),n.Ticks=t(34),t(22)(n),t(23)(n),t(24)(n),t(33)(n),t(32)(n),t(35)(n),t(55)(n),t(53)(n),t(54)(n),t(56)(n),t(57)(n),t(58)(n),t(15)(n),t(16)(n),t(17)(n),t(18)(n),t(19)(n),t(20)(n),t(21)(n),t(8)(n),t(9)(n),t(10)(n),t(11)(n),t(12)(n),t(13)(n),t(14)(n);var a=t(49);for(var o in a)a.hasOwnProperty(o)&&n.plugins.register(a[o]);n.platform.initialize(),e.exports=n,"undefined"!=typeof window&&(window.Chart=n),n.Legend=a.legend._element,n.Title=a.title._element,n.pluginService=n.plugins,n.PluginBase=n.Element.extend({}),n.canvasHelpers=n.helpers.canvas,n.layoutService=n.layouts},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,40:40,45:45,48:48,49:49,53:53,54:54,55:55,56:56,57:57,58:58,8:8,9:9}],8:[function(t,e,i){"use strict";e.exports=function(t){t.Bar=function(e,i){return i.type="bar",new t(e,i)}}},{}],9:[function(t,e,i){"use strict";e.exports=function(t){t.Bubble=function(e,i){return i.type="bubble",new t(e,i)}}},{}],10:[function(t,e,i){"use strict";e.exports=function(t){t.Doughnut=function(e,i){return i.type="doughnut",new t(e,i)}}},{}],11:[function(t,e,i){"use strict";e.exports=function(t){t.Line=function(e,i){return i.type="line",new t(e,i)}}},{}],12:[function(t,e,i){"use strict";e.exports=function(t){t.PolarArea=function(e,i){return i.type="polarArea",new t(e,i)}}},{}],13:[function(t,e,i){"use strict";e.exports=function(t){t.Radar=function(e,i){return i.type="radar",new t(e,i)}}},{}],14:[function(t,e,i){"use strict";e.exports=function(t){t.Scatter=function(e,i){return i.type="scatter",new t(e,i)}}},{}],15:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),n._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var i="";return t.length>0&&(t[0].yLabel?i=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(i=e.labels[t[0].index])),i},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": "+t.xLabel}},mode:"index",axis:"y"}}),e.exports=function(t){t.controllers.bar=t.DatasetController.extend({dataElementType:a.Rectangle,initialize:function(){var e;t.DatasetController.prototype.initialize.apply(this,arguments),(e=this.getMeta()).stack=this.getDataset().stack,e.bar=!0},update:function(t){var e,i,n=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,i=n.length;e<i;++e)this.updateElement(n[e],e,t)},updateElement:function(t,e,i){var n=this,a=n.chart,r=n.getMeta(),s=n.getDataset(),l=t.custom||{},u=a.options.elements.rectangle;t._xScale=n.getScaleForId(r.xAxisID),t._yScale=n.getScaleForId(r.yAxisID),t._datasetIndex=n.index,t._index=e,t._model={datasetLabel:s.label,label:a.data.labels[e],borderSkipped:l.borderSkipped?l.borderSkipped:u.borderSkipped,backgroundColor:l.backgroundColor?l.backgroundColor:o.valueAtIndexOrDefault(s.backgroundColor,e,u.backgroundColor),borderColor:l.borderColor?l.borderColor:o.valueAtIndexOrDefault(s.borderColor,e,u.borderColor),borderWidth:l.borderWidth?l.borderWidth:o.valueAtIndexOrDefault(s.borderWidth,e,u.borderWidth)},n.updateElementGeometry(t,e,i),t.pivot()},updateElementGeometry:function(t,e,i){var n=this,a=t._model,o=n.getValueScale(),r=o.getBasePixel(),s=o.isHorizontal(),l=n._ruler||n.getRuler(),u=n.calculateBarValuePixels(n.index,e),d=n.calculateBarIndexPixels(n.index,e,l);a.horizontal=s,a.base=i?r:u.base,a.x=s?i?r:u.head:d.center,a.y=s?d.center:i?r:u.head,a.height=s?d.size:void 0,a.width=s?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},_getStacks:function(t){var e,i,n=this.chart,a=this.getIndexScale().options.stacked,o=void 0===t?n.data.datasets.length:t+1,r=[];for(e=0;e<o;++e)(i=n.getDatasetMeta(e)).bar&&n.isDatasetVisible(e)&&(!1===a||!0===a&&-1===r.indexOf(i.stack)||void 0===a&&(void 0===i.stack||-1===r.indexOf(i.stack)))&&r.push(i.stack);return r},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var i=this._getStacks(t),n=void 0!==e?i.indexOf(e):-1;return-1===n?i.length-1:n},getRuler:function(){var t,e,i=this.getIndexScale(),n=this.getStackCount(),a=this.index,r=i.isHorizontal(),s=r?i.left:i.top,l=s+(r?i.width:i.height),u=[];for(t=0,e=this.getMeta().data.length;t<e;++t)u.push(i.getPixelForValue(null,t,a));return{min:o.isNullOrUndef(i.options.barThickness)?function(t,e){var i,n,a,o,r=t.isHorizontal()?t.width:t.height,s=t.getTicks();for(a=1,o=e.length;a<o;++a)r=Math.min(r,e[a]-e[a-1]);for(a=0,o=s.length;a<o;++a)n=t.getPixelForTick(a),r=a>0?Math.min(r,n-i):r,i=n;return r}(i,u):-1,pixels:u,start:s,end:l,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,o,r,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),c=l.data.datasets,h=d.getRightValue(c[t].data[e]),f=d.options.stacked,g=u.stack,p=0;if(f||void 0===f&&void 0!==g)for(i=0;i<t;++i)(n=l.getDatasetMeta(i)).bar&&n.stack===g&&n.controller.getValueScaleId()===d.id&&l.isDatasetVisible(i)&&(a=d.getRightValue(c[i].data[e]),(h<0&&a<0||h>=0&&a>0)&&(p+=a));return o=d.getPixelForValue(p),{size:s=((r=d.getPixelForValue(p+h))-o)/2,base:o,head:r,center:r+s/2}},calculateBarIndexPixels:function(t,e,i){var n,a,r,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k=i.scale.options,M="flex"===k.barThickness?(h=e,g=k,m=(f=i).pixels,v=m[h],b=h>0?m[h-1]:null,x=h<m.length-1?m[h+1]:null,y=g.categoryPercentage,null===b&&(b=v-(null===x?f.end-v:x-v)),null===x&&(x=v+v-b),p=v-(v-b)/2*y,{chunk:(x-b)/2*y/f.stackCount,ratio:g.barPercentage,start:p}):(n=e,a=i,u=(r=k).barThickness,d=a.stackCount,c=a.pixels[n],o.isNullOrUndef(u)?(s=a.min*r.categoryPercentage,l=r.barPercentage):(s=u*d,l=1),{chunk:s/d,ratio:l,start:c-s/2}),w=this.getStackIndex(t,this.getMeta().stack),S=M.start+M.chunk*w+M.chunk/2,C=Math.min(o.valueOrDefault(k.maxBarThickness,1/0),M.chunk*M.ratio);return{base:S-C/2,head:S+C/2,center:S,size:C}},draw:function(){var t=this.chart,e=this.getValueScale(),i=this.getMeta().data,n=this.getDataset(),a=i.length,r=0;for(o.canvas.clipArea(t.ctx,t.chartArea);r<a;++r)isNaN(e.getRightValue(n.data[r]))||i[r].draw();o.canvas.unclipArea(t.ctx)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o.valueAtIndexOrDefault(e.hoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor?n.hoverBorderColor:o.valueAtIndexOrDefault(e.hoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o.valueAtIndexOrDefault(e.hoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model,r=this.chart.options.elements.rectangle;a.backgroundColor=n.backgroundColor?n.backgroundColor:o.valueAtIndexOrDefault(e.backgroundColor,i,r.backgroundColor),a.borderColor=n.borderColor?n.borderColor:o.valueAtIndexOrDefault(e.borderColor,i,r.borderColor),a.borderWidth=n.borderWidth?n.borderWidth:o.valueAtIndexOrDefault(e.borderWidth,i,r.borderWidth)}}),t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{25:25,40:40,45:45}],16:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var i=e.datasets[t.datasetIndex].label||"",n=e.datasets[t.datasetIndex].data[t.index];return i+": ("+t.xLabel+", "+t.yLabel+", "+n.r+")"}}}}),e.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:a.Point,update:function(t){var e=this,i=e.getMeta().data;o.each(i,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.getMeta(),o=t.custom||{},r=n.getScaleForId(a.xAxisID),s=n.getScaleForId(a.yAxisID),l=n._resolveElementOptions(t,e),u=n.getDataset().data[e],d=n.index,c=i?r.getPixelForDecimal(.5):r.getPixelForValue("object"==typeof u?u:NaN,e,d),h=i?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=r,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,radius:i?0:l.radius,skip:o.skip||isNaN(c)||isNaN(h),x:c,y:h},t.pivot()},setHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=o.valueOrDefault(i.hoverBackgroundColor,o.getHoverColor(i.backgroundColor)),e.borderColor=o.valueOrDefault(i.hoverBorderColor,o.getHoverColor(i.borderColor)),e.borderWidth=o.valueOrDefault(i.hoverBorderWidth,i.borderWidth),e.radius=i.radius+i.hoverRadius},removeHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=i.backgroundColor,e.borderColor=i.borderColor,e.borderWidth=i.borderWidth,e.radius=i.radius},_resolveElementOptions:function(t,e){var i,n,a,r=this.chart,s=r.data.datasets[this.index],l=t.custom||{},u=r.options.elements.point,d=o.options.resolve,c=s.data[e],h={},f={chart:r,dataIndex:e,dataset:s,datasetIndex:this.index},g=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle"];for(i=0,n=g.length;i<n;++i)h[a=g[i]]=d([l[a],s[a],u[a]],f,e);return h.radius=d([l.radius,c?c.r:void 0,s.radius,u.radius],f,e),h}})}},{25:25,40:40,45:45}],17:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n],l=s&&s.custom||{},u=o.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:i,fillStyle:l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o]&&(a.data[o].hidden=!a.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:-.5*Math.PI,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var i=e.labels[t.index],n=": "+e.datasets[t.datasetIndex].data[t.index];return o.isArray(i)?(i=i.slice())[0]+=n:i+=n,i}}}}),n._set("pie",o.clone(n.doughnut)),n._set("pie",{cutoutPercentage:0}),e.exports=function(t){t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,getRingIndex:function(t){for(var e=0,i=0;i<t;++i)this.chart.isDatasetVisible(i)&&++e;return e},update:function(t){var e=this,i=e.chart,n=i.chartArea,a=i.options,r=a.elements.arc,s=n.right-n.left-r.borderWidth,l=n.bottom-n.top-r.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=e.getMeta(),h=a.cutoutPercentage,f=a.circumference;if(f<2*Math.PI){var g=a.rotation%(2*Math.PI),p=(g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0))+f,m=Math.cos(g),v=Math.sin(g),b=Math.cos(p),x=Math.sin(p),y=g<=0&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,k=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,M=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,w=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,C=M?-1:Math.min(m*(m<0?1:S),b*(b<0?1:S)),_=w?-1:Math.min(v*(v<0?1:S),x*(x<0?1:S)),D=y?1:Math.max(m*(m>0?1:S),b*(b>0?1:S)),I=k?1:Math.max(v*(v>0?1:S),x*(x>0?1:S)),P=.5*(D-C),A=.5*(I-_);u=Math.min(s/P,l/A),d={x:-.5*(D+C),y:-.5*(I+_)}}i.borderWidth=e.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=e.calculateTotal(),e.outerRadius=i.outerRadius-i.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-i.radiusLength,0),o.each(c.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.chart,r=a.chartArea,s=a.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=o.valueAtIndexOrDefault;o.extend(t,{_datasetIndex:n.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,e,a.data.labels[e])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(b.startAngle=0===e?s.rotation:n.getMeta().data[e-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),i=this.getMeta(),n=0;return o.each(i.data,function(i,a){t=e.data[a],isNaN(t)||i.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,i,n=0,a=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,n=(i=t[r]._chart?t[r]._chart.config.data.datasets[a].hoverBorderWidth:0)>(n=e>n?e:n)?i:n;return n}})}},{25:25,40:40,45:45}],18:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return o.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var i,n,a,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:o.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:o.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:o.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),i=0,n=u.length;i<n;++i)r.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&r.updateBezierControlPoints(),i=0,n=u.length;i<n;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),a=t.custom||{};return a.backgroundColor?i=a.backgroundColor:n.pointBackgroundColor?i=o.valueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),a=t.custom||{};return a.borderColor?i=a.borderColor:n.pointBorderColor?i=o.valueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),a=t.custom||{};return isNaN(a.borderWidth)?!isNaN(n.pointBorderWidth)||o.isArray(n.pointBorderWidth)?i=o.valueAtIndexOrDefault(n.pointBorderWidth,e,i):isNaN(n.borderWidth)||(i=n.borderWidth):i=a.borderWidth,i},updateElement:function(t,e,i){var n,a,r=this,s=r.getMeta(),l=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(s.yAxisID),f=r.getScaleForId(s.xAxisID),g=r.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,d),a=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:n,y:a,skip:l.skip||isNaN(n)||isNaN(a),radius:l.radius||o.valueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||o.valueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||o.valueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,i){var n,a,o,r=this.chart,s=this.getMeta(),l=this.getScaleForId(s.yAxisID),u=0,d=0;if(l.options.stacked){for(n=0;n<i;n++)if(a=r.data.datasets[n],"line"===(o=r.getDatasetMeta(n)).type&&o.yAxisID===l.id&&r.isDatasetVisible(n)){var c=Number(l.getRightValue(a.data[e]));c<0?d+=c||0:u+=c||0}var h=Number(l.getRightValue(t));return h<0?l.getPixelForValue(d+h):l.getPixelForValue(u+h)}return l.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,i,n,a=this.getMeta(),r=this.chart.chartArea,s=a.data||[];function l(t,e,i){return Math.max(Math.min(t,i),e)}if(a.dataset._model.spanGaps&&(s=s.filter(function(t){return!t._model.skip})),"monotone"===a.dataset._model.cubicInterpolationMode)o.splineCurveMonotone(s);else for(t=0,e=s.length;t<e;++t)i=s[t]._model,n=o.splineCurve(o.previousItem(s,t)._model,i,o.nextItem(s,t)._model,a.dataset._model.tension),i.controlPointPreviousX=n.previous.x,i.controlPointPreviousY=n.previous.y,i.controlPointNextX=n.next.x,i.controlPointNextY=n.next.y;if(this.chart.options.elements.line.capBezierPoints)for(t=0,e=s.length;t<e;++t)(i=s[t]._model).controlPointPreviousX=l(i.controlPointPreviousX,r.left,r.right),i.controlPointPreviousY=l(i.controlPointPreviousY,r.top,r.bottom),i.controlPointNextX=l(i.controlPointNextX,r.left,r.right),i.controlPointNextY=l(i.controlPointNextY,r.top,r.bottom)},draw:function(){var t=this.chart,i=this.getMeta(),n=i.data||[],a=t.chartArea,r=n.length,s=0;for(o.canvas.clipArea(t.ctx,a),e(this.getDataset(),t.options)&&i.dataset.draw(),o.canvas.unclipArea(t.ctx);s<r;++s)n[s].draw(a)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.radius=n.hoverRadius||o.valueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),a.backgroundColor=n.hoverBackgroundColor||o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor||o.valueAtIndexOrDefault(e.pointHoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth||o.valueAtIndexOrDefault(e.pointHoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=a.radius||o.valueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{25:25,40:40,45:45}],19:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n].custom||{},l=o.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:i,fillStyle:s.backgroundColor?s.backgroundColor:l(r.backgroundColor,n,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(r.borderColor,n,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(r.borderWidth,n,u.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o].hidden=!a.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}}),e.exports=function(t){t.controllers.polarArea=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,update:function(t){var e=this,i=e.chart,n=i.chartArea,a=e.getMeta(),r=i.options,s=r.elements.arc,l=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),e.outerRadius=i.outerRadius-i.radiusLength*e.index,e.innerRadius=e.outerRadius-i.radiusLength,a.count=e.countVisibleElements(),o.each(a.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){for(var n=this,a=n.chart,r=n.getDataset(),s=a.options,l=s.animation,u=a.scale,d=a.data.labels,c=n.calculateCircumference(r.data[e]),h=u.xCenter,f=u.yCenter,g=0,p=n.getMeta(),m=0;m<e;++m)isNaN(r.data[m])||p.data[m].hidden||++g;var v=s.startAngle,b=t.hidden?0:u.getDistanceFromCenterForValue(r.data[e]),x=v+c*g,y=x+(t.hidden?0:c),k=l.animateScale?0:u.getDistanceFromCenterForValue(r.data[e]);o.extend(t,{_datasetIndex:n.index,_index:e,_scale:u,_model:{x:h,y:f,innerRadius:0,outerRadius:i?k:b,startAngle:i&&l.animateRotate?v:x,endAngle:i&&l.animateRotate?v:y,label:o.valueAtIndexOrDefault(d,e,d[e])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),i=0;return o.each(e.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:o.noop,update:function(t){var e=this,i=e.getMeta(),n=i.dataset,a=i.data,r=n.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),o.extend(i.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:r.tension?r.tension:o.valueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),i.dataset.pivot(),o.each(a,function(i,n){e.updateElement(i,n,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,i){var n=this,a=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(e,r.data[e]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),o.extend(t,{_datasetIndex:n.index,_index:e,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:a.tension?a.tension:o.valueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:a.radius?a.radius:o.valueAtIndexOrDefault(r.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:o.valueAtIndexOrDefault(r.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:o.valueAtIndexOrDefault(r.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:o.valueAtIndexOrDefault(r.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:o.valueAtIndexOrDefault(r.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:o.valueAtIndexOrDefault(r.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();o.each(e.data,function(i,n){var a=i._model,r=o.splineCurve(o.previousItem(e.data,n,!0)._model,a,o.nextItem(e.data,n,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model;a.radius=i.hoverRadius?i.hoverRadius:o.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,o.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:o.valueAtIndexOrDefault(e.pointHoverBorderColor,n,o.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:o.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model,r=this.chart.options.elements.point;a.radius=i.radius?i.radius:o.valueAtIndexOrDefault(e.pointRadius,n,r.radius),a.backgroundColor=i.backgroundColor?i.backgroundColor:o.valueAtIndexOrDefault(e.pointBackgroundColor,n,r.backgroundColor),a.borderColor=i.borderColor?i.borderColor:o.valueAtIndexOrDefault(e.pointBorderColor,n,r.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:o.valueAtIndexOrDefault(e.pointBorderWidth,n,r.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,i){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:o.noop,onComplete:o.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,n){var a,o,r=this.animations;for(e.chart=t,n||(t.animating=!0),a=0,o=r.length;a<o;++a)if(r[a].chart===t)return void(r[a]=e);r.push(e),1===r.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=o.findIndex(this.animations,function(e){return e.chart===t});-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=o.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),i=0;t.dropFrames>1&&(i=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+i);var n=Date.now();t.dropFrames+=(n-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,i,n=this.animations,a=0;a<n.length;)i=(e=n[a]).chart,e.currentStep=(e.currentStep||0)+t,e.currentStep=Math.min(e.currentStep,e.numSteps),o.callback(e.render,[i,e],i),o.callback(e.onAnimationProgress,[e],i),e.currentStep>=e.numSteps?(o.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(28),r=t(30),s=t(48),l=t(31);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(e,i){var o,r,l=this;(r=(o=(o=i)||{}).data=o.data||{}).datasets=r.datasets||[],r.labels=r.labels||[],o.options=a.configMerge(n.global,n[o.type],o.options||{}),i=o;var u=s.acquireContext(e,i),d=u&&u.canvas,c=d&&d.height,h=d&&d.width;l.id=a.uid(),l.ctx=u,l.canvas=d,l.config=i,l.width=h,l.height=c,l.aspectRatio=c?h/c:null,l.options=i.options,l._bufferedRender=!1,l.chart=l,l.controller=l,t.instances[l.id]=l,Object.defineProperty(l,"data",{get:function(){return l.config.data},set:function(t){l.config.data=t}}),u&&d?(l.initialize(),l.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,o=i.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(a.getMaximumWidth(n))),s=Math.max(0,Math.floor(o?r/o:a.getMaximumHeight(n)));if((e.width!==r||e.height!==s)&&(n.width=e.width=r,n.height=e.height=s,n.style.width=r+"px",n.style.height=s+"px",a.retinaScale(e,i.devicePixelRatio),!t)){var u={width:r,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var i=this,n=i.options,o=i.scales||{},r=[],s=Object.keys(o).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=r.id,u=a.valueOrDefault(r.type,n.dtype);e(r.position)!==e(n.dposition)&&(r.position=n.dposition),s[l]=!0;var d=null;if(l in o&&o[l].type===u)(d=o[l]).options=r,d.ctx=i.ctx,d.chart=i;else{var c=t.scaleService.getScaleConstructor(u);if(!c)return;d=new c({id:l,type:u,options:r,ctx:i.ctx,chart:i}),o[d.id]=d}d.mergeTicksOptions(),n.isDefault&&(i.scale=d)}),a.each(s,function(t,e){t||delete o[e]}),i.scales=o,t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,i=[],n=[];return a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o),s=a.type||e.config.type;if(r.type&&r.type!==s&&(e.destroyDatasetMeta(o),r=e.getDatasetMeta(o)),r.type=s,i.push(r.type),r.controller)r.controller.updateIndex(o),r.controller.linkScales();else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),n.push(r.controller)}},e),n},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var i,n,o=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),n=(i=o).options,a.each(i.scales,function(t){r.removeBox(i,t)}),n=a.configMerge(t.defaults.global,t.defaults[i.config.type],n),i.options=i.config.options=n,i.ensureScalesHaveIDs(),i.buildOrUpdateScales(),i.tooltip._options=n.tooltips,i.tooltip.initialize(),l._invalidate(o),!1!==l.notify(o,"beforeUpdate")){o.tooltip._data=o.data;var s=o.buildOrUpdateControllers();a.each(o.data.datasets,function(t,e){o.getDatasetMeta(e).controller.buildOrUpdateElements()},o),o.updateLayout(),o.options.animation&&o.options.animation.duration&&a.each(s,function(t){t.reset()}),o.updateDatasets(),o.tooltip.initialize(),o.lastActive=[],l.notify(o,"afterUpdate"),o._bufferedRender?o._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:o.render(e)}},updateLayout:function(){!1!==l.notify(this,"beforeLayout")&&(r.update(this,this.width,this.height),l.notify(this,"afterScaleUpdate"),l.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==l.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);l.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),i={meta:e,index:t};!1!==l.notify(this,"beforeDatasetUpdate",[i])&&(e.controller.update(),l.notify(this,"afterDatasetUpdate",[i]))},render:function(e){var i=this;e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]});var n=e.duration,o=e.lazy;if(!1!==l.notify(i,"beforeRender")){var r=i.options.animation,s=function(t){l.notify(i,"afterRender"),a.callback(r&&r.onComplete,[t],i)};if(r&&(void 0!==n&&0!==n||void 0===n&&0!==r.duration)){var u=new t.Animation({numSteps:(n||r.duration)/16.66,easing:e.easing||r.easing,render:function(t,e){var i=a.easing.effects[e.easing],n=e.currentStep,o=n/e.numSteps;t.draw(i(o),o,n)},onAnimationProgress:r.onProgress,onAnimationComplete:s});t.animationService.addAnimation(i,u,n,o)}else i.draw(),s(new t.Animation({numSteps:0,chart:i}));return i}},draw:function(t){var e=this;e.clear(),a.isNullOrUndef(t)&&(t=1),e.transition(t),!1!==l.notify(e,"beforeDraw",[t])&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e._drawTooltip(t),l.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=0,i=(this.data.datasets||[]).length;e<i;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(!1!==l.notify(e,"beforeDatasetsDraw",[t])){for(var i=(e.data.datasets||[]).length-1;i>=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),l.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),l.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return o.modes.single(this,t)},getElementsAtEvent:function(t){return o.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return o.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=o.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return o.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e<i;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,i=this.data.datasets[t],n=i._meta&&i._meta[e];n&&(n.controller.destroy(),delete i._meta[e])},destroy:function(){var e,i,n=this,o=n.canvas;for(n.stop(),e=0,i=n.data.datasets.length;e<i;++e)n.destroyDatasetMeta(e);o&&(n.unbindEvents(),a.canvas.clear(n),s.releaseContext(n.ctx),n.canvas=null,n.ctx=null),l.notify(n,"destroy"),delete t.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this,e=t._listeners={},i=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(n){s.addEventListener(t,n,i),e[n]=i}),t.options.responsive&&(i=function(){t.resize()},s.addEventListener(t,"resize",i),e.resize=i)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,i){s.removeEventListener(t,i,e)}))},updateHoverStyle:function(t,e,i){var n,a,o,r=i?"setHoverStyle":"removeHoverStyle";for(a=0,o=t.length;a<o;++a)(n=t[a])&&this.getDatasetMeta(n._datasetIndex).controller[r](n)},eventHandler:function(t){var e=this,i=e.tooltip;if(!1!==l.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var n=e.handleEvent(t);i&&(n=i._start?i.handleEvent(t):n|i.handleEvent(t)),l.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):n&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,i=this,n=i.options||{},o=n.hover;return i.lastActive=i.lastActive||[],"mouseout"===t.type?i.active=[]:i.active=i.getElementsAtEventForMode(t,o.mode,o),a.callback(n.onHover||n.hover.onHover,[t.native,i.active],i),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(i,t.native,i.active),i.lastActive.length&&i.updateHoverStyle(i.lastActive,o.mode,!1),i.active.length&&o.mode&&i.updateHoverStyle(i.active,o.mode,!0),e=!a.arrayEquals(i.active,i.lastActive),i.lastActive=i.active,e}}),t.Controller=t}},{25:25,28:28,30:30,31:31,45:45,48:48}],24:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=["push","pop","shift","splice","unshift"];function i(t,i){var n=t._chartjs;if(n){var a=n.listeners,o=a.indexOf(i);-1!==o&&a.splice(o,1),a.length>0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},n.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&i(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);i.dataset=i.dataset||this.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,a,o=this,r=o.getDataset(),s=r.data||(r.data=[]);o._data!==s&&(o._data&&i(o._data,o),a=o,(t=s)._chartjs?t._chartjs.listeners.push(a):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[a]}}),e.forEach(function(e){var i="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),o=a.apply(this,e);return n.each(t._chartjs.listeners,function(t){"function"==typeof t[i]&&t[i].apply(t,e)}),o}})})),o._data=s),o.resyncElements()},update:n.noop,transition:function(t){for(var e=this.getMeta(),i=e.data||[],n=i.length,a=0;a<n;++a)i[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],i=e.length,n=0;for(t.dataset&&t.dataset.draw();n<i;++n)e[n].draw()},removeHoverStyle:function(t,e){var i=this.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=n.valueAtIndexOrDefault,s=t._model;s.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,a,e.backgroundColor),s.borderColor=o.borderColor?o.borderColor:r(i.borderColor,a,e.borderColor),s.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=n.valueAtIndexOrDefault,r=n.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:o(e.hoverBackgroundColor,i,r(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:o(e.hoverBorderColor,i,r(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:o(e.hoverBorderWidth,i,s.borderWidth)},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,i=t.data.length,n=e.length;n<i?t.data.splice(n,i-n):n>i&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;i<e;++i)this.addElementAndReset(t+i)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=n.inherits}},{45:45}],25:[function(t,e,i){"use strict";var n=t(45);e.exports={_set:function(t,e){return n.merge(this[t]||(this[t]={}),e)}}},{45:45}],26:[function(t,e,i){"use strict";var n=t(3),a=t(45);var o=function(t){a.extend(this,t),this.initialize.apply(this,arguments)};a.extend(o.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=a.clone(t._model)),t._start={},t},transition:function(t){var e=this,i=e._model,a=e._start,o=e._view;return i&&1!==t?(o||(o=e._view={}),a||(a=e._start={}),function(t,e,i,a){var o,r,s,l,u,d,c,h,f,g=Object.keys(i);for(o=0,r=g.length;o<r;++o)if(d=i[s=g[o]],e.hasOwnProperty(s)||(e[s]=d),(l=e[s])!==d&&"_"!==s[0]){if(t.hasOwnProperty(s)||(t[s]=l),(c=typeof d)==typeof(u=t[s]))if("string"===c){if((h=n(u)).valid&&(f=n(d)).valid){e[s]=f.mix(h,a).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[s]=u+(d-u)*a;continue}e[s]=d}}(a,o,i,t),e):(e._view=i,e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return a.isNumber(this._model.x)&&a.isNumber(this._model.y)}}),o.extend=a.inherits,e.exports=o},{3:3,45:45}],27:[function(t,e,i){"use strict";var n=t(3),a=t(25),o=t(45);e.exports=function(t){function e(t,e,i){var n;return"string"==typeof t?(n=parseInt(t,10),-1!==t.indexOf("%")&&(n=n/100*e.parentNode[i])):n=t,n}function i(t){return null!=t&&"none"!==t}function r(t,n,a){var o=document.defaultView,r=t.parentNode,s=o.getComputedStyle(t)[n],l=o.getComputedStyle(r)[n],u=i(s),d=i(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,r,a):c):"none"}o.configMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){var r=i[e]||{},s=n[e];"scales"===e?i[e]=o.scaleMerge(r,s):"scale"===e?i[e]=o.merge(r,[t.scaleService.getScaleDefaults(s.type),s]):o._merger(e,i,n,a)}})},o.scaleMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){if("xAxes"===e||"yAxes"===e){var r,s,l,u=n[e].length;for(i[e]||(i[e]=[]),r=0;r<u;++r)l=n[e][r],s=o.valueOrDefault(l.type,"xAxes"===e?"category":"linear"),r>=i[e].length&&i[e].push({}),!i[e][r].type||l.type&&l.type!==i[e][r].type?o.merge(i[e][r],[t.scaleService.getScaleDefaults(s),l]):o.merge(i[e][r],l)}else o._merger(e,i,n,a)}})},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return o.each(t,function(t){e(t)&&i.push(t)}),i},o.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n<a;++n)if(e.call(i,t[n],n,t))return n;return-1},o.findNextWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=-1);for(var n=i+1;n<t.length;n++){var a=t[n];if(e(a))return a}},o.findPreviousWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=t.length);for(var n=i-1;n>=0;n--){var a=t[n];if(e(a))return a}},o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,i){return Math.abs(t-e)<i},o.almostWhole=function(t,e){var i=Math.round(t);return i-e<t&&i+e>t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),o=Math.atan2(n,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2==0?0:.5},o.splineCurve=function(t,e,i,n){var a=t.skip?e:t,o=e,r=i.skip?e:i,s=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l),c=n*(u=isNaN(u)?0:u),h=n*(d=isNaN(d)?0:d);return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,i,n,a,r,s,l,u,d,c=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=c.length;for(e=0;e<h;++e)if(!(n=c[e]).model.skip){if(i=e>0?c[e-1]:null,(a=e<h-1?c[e+1]:null)&&!a.model.skip){var f=a.model.x-n.model.x;n.deltaK=0!==f?(a.model.y-n.model.y)/f:0}!i||i.model.skip?n.mK=n.deltaK:!a||a.model.skip?n.mK=i.deltaK:this.sign(i.deltaK)!==this.sign(n.deltaK)?n.mK=0:n.mK=(i.deltaK+n.deltaK)/2}for(e=0;e<h-1;++e)n=c[e],a=c[e+1],n.model.skip||a.model.skip||(o.almostEquals(n.deltaK,0,this.EPSILON)?n.mK=a.mK=0:(r=n.mK/n.deltaK,s=a.mK/n.deltaK,(u=Math.pow(r,2)+Math.pow(s,2))<=9||(l=3/Math.sqrt(u),n.mK=r*l*n.deltaK,a.mK=s*l*n.deltaK)));for(e=0;e<h;++e)(n=c[e]).model.skip||(i=e>0?c[e-1]:null,a=e<h-1?c[e+1]:null,i&&!i.model.skip&&(d=(n.model.x-i.model.x)/3,n.model.controlPointPreviousX=n.model.x-d,n.model.controlPointPreviousY=n.model.y-d*n.mK),a&&!a.model.skip&&(d=(a.model.x-n.model.x)/3,n.model.controlPointNextX=n.model.x+d,n.model.controlPointNextY=n.model.y+d*n.mK))},o.nextItem=function(t,e,i){return i?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},o.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},o.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,s=r.getBoundingClientRect(),l=a.touches;l&&l.length>0?(i=l[0].clientX,n=l[0].clientY):(i=a.clientX,n=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return{x:i=Math.round((i-s.left-u)/f*r.width/e.currentDevicePixelRatio),y:n=Math.round((n-s.top-d)/g*r.height/e.currentDevicePixelRatio)}},o.getConstraintWidth=function(t){return r(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return r(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var i=parseInt(o.getStyle(e,"padding-left"),10),n=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-i-n,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var i=parseInt(o.getStyle(e,"padding-top"),10),n=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-i-n,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,o=t.width;n.height=a*i,n.width=o*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=o+"px")}},o.fontString=function(t,e,i){return e+" "+t+"px "+i},o.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},r=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},r=n.garbageCollect=[],n.font=e),t.font=e;var s=0;o.each(i,function(e){null!=e&&!0!==o.isArray(e)?s=o.measureText(t,a,r,s,e):o.isArray(e)&&o.each(e,function(e){null==e||o.isArray(e)||(s=o.measureText(t,a,r,s,e))})});var l=r.length/2;if(l>i.length){for(var u=0;u<l;u++)delete a[r[u]];r.splice(0,l)}return s},o.measureText=function(t,e,i,n,a){var o=e[a];return o||(o=e[a]=t.measureText(a).width,i.push(a)),o>n&&(n=o),n},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{25:25,3:3,45:45}],28:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function o(t,e){var i,n,a,o,r;for(n=0,o=t.data.datasets.length;n<o;++n)if(t.isDatasetVisible(n))for(a=0,r=(i=t.getDatasetMeta(n)).data.length;a<r;++a){var s=i.data[a];s._view.skip||e(s)}}function r(t,e){var i=[];return o(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function s(t,e,i,n){var a=Number.POSITIVE_INFINITY,r=[];return o(t,function(t){if(!i||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=n(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}}),r}function l(t){var e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,n){var a=e?Math.abs(t.x-n.x):0,o=i?Math.abs(t.y-n.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(o,2))}}function u(t,e,i){var n=a(e,t);i.axis=i.axis||"x";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o),d=[];return u.length?(t.data.datasets.forEach(function(e,i){if(t.isDatasetVisible(i)){var n=t.getDatasetMeta(i).data[u[0]._index];n&&!n._view.skip&&d.push(n)}}),d):[]}e.exports={modes:{single:function(t,e){var i=a(e,t),n=[];return o(t,function(t){if(t.inRange(i.x,i.y))return n.push(t),n}),n.slice(0,1)},label:u,index:u,dataset:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o);return u.length>0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return r(t,a(e,t))},nearest:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),r=s(t,n,i.intersect,o);return r.length>1&&r.sort(function(t,e){var i=t.getArea()-e.getArea();return 0===i&&(i=t._datasetIndex-e._datasetIndex),i}),r.slice(0,1)},x:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inXRange(n.x)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r},y:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inYRange(n.y)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r}}}},{45:45}],29:[function(t,e,i){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return n.where(t,function(t){return t.position===e})}function o(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],o=a.length,r=0;r<o;++r)n=a[r],i.hasOwnProperty(n)&&(e[n]=i[n])},update:function(t,e,i){if(t){var r=t.options.layout||{},s=n.options.toPadding(r.padding),l=s.left,u=s.right,d=s.top,c=s.bottom,h=a(t.boxes,"left"),f=a(t.boxes,"right"),g=a(t.boxes,"top"),p=a(t.boxes,"bottom"),m=a(t.boxes,"chartArea");o(h,!0),o(f,!1),o(g,!0),o(p,!1);var v=e-l-u,b=i-d-c,x=b/2,y=(e-v/2)/(h.length+f.length),k=(i-x)/(g.length+p.length),M=v,w=b,S=[];n.each(h.concat(f,g,p),function(t){var e,i=t.isHorizontal();i?(e=t.update(t.fullWidth?v:M,k),w-=e.height):(e=t.update(y,w),M-=e.width),S.push({horizontal:i,minSize:e,box:t})});var C=0,_=0,D=0,I=0;n.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();C=Math.max(C,e.left),_=Math.max(_,e.right)}}),n.each(h.concat(f),function(t){if(t.getPadding){var e=t.getPadding();D=Math.max(D,e.top),I=Math.max(I,e.bottom)}});var P=l,A=u,T=d,F=c;n.each(h.concat(f),N),n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g.concat(p),N),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height}),n.each(h.concat(f),function(t){var e=n.findNextWhere(S,function(e){return e.box===t}),i={left:0,right:0,top:T,bottom:F};e&&t.update(e.minSize.width,w,i)}),P=l,A=u,T=d,F=c,n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height});var O=Math.max(C-P,0);P+=O,A+=Math.max(_-A,0);var R=Math.max(D-T,0);T+=R,F+=Math.max(I-F,0);var L=i-T-F,z=e-P-A;z===M&&L===w||(n.each(h,function(t){t.height=L}),n.each(f,function(t){t.height=L}),n.each(g,function(t){t.fullWidth||(t.width=z)}),n.each(p,function(t){t.fullWidth||(t.width=z)}),w=L,M=z);var B=l+O,W=d+R;n.each(h.concat(g),V),B+=M,W+=w,n.each(f,V),n.each(p,V),t.chartArea={left:P,top:T,right:P+M,bottom:T+w},n.each(m,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,w)})}function N(t){var e=n.findNextWhere(S,function(e){return e.box===t});if(e)if(t.isHorizontal()){var i={left:Math.max(P,C),right:Math.max(A,_),top:0,bottom:0};t.update(t.fullWidth?v:M,b/2,i)}else t.update(e.minSize.width,w)}function V(t){t.isHorizontal()?(t.left=t.fullWidth?l:P,t.right=t.fullWidth?e-u:P+M,t.top=W,t.bottom=W+t.height,W=t.bottom):(t.left=B,t.right=B+t.width,t.top=T,t.bottom=T+w,B=t.right)}}}},{45:45}],31:[function(t,e,i){"use strict";var n=t(25),a=t(45);n._set("global",{plugins:{}}),e.exports={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var i=e.indexOf(t);-1!==i&&e.splice(i,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,i){var n,a,o,r,s,l=this.descriptors(t),u=l.length;for(n=0;n<u;++n)if("function"==typeof(s=(o=(a=l[n]).plugin)[e])&&((r=[t].concat(i||[])).push(a.options),!1===s.apply(o,r)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var i=[],o=[],r=t&&t.config||{},s=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){if(-1===i.indexOf(t)){var e=t.id,r=s[e];!1!==r&&(!0===r&&(r=a.clone(n.global.plugins[e])),i.push(t),o.push({plugin:t,options:r||{}}))}}),e.descriptors=o,e.id=this._cacheId,o},_invalidate:function(t){delete t.$plugins}}},{25:25,45:45}],32:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(34);function s(t){var e,i,n=[];for(e=0,i=t.length;e<i;++e)n.push(t[e].label);return n}function l(t,e,i){var n=t.getPixelForTick(e);return i&&(n-=0===e?(t.getPixelForTick(1)-n)/2:(n-t.getPixelForTick(e-1))/2),n}n._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",lineHeight:1.2,padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:r.formatters.values,minor:{},major:{}}}),e.exports=function(t){function e(t,e,i){return o.isArray(e)?o.longestText(t,i,e):t.measureText(e).width}function i(t){var e=o.valueOrDefault,i=n.global,a=e(t.fontSize,i.defaultFontSize),r=e(t.fontStyle,i.defaultFontStyle),s=e(t.fontFamily,i.defaultFontFamily);return{size:a,style:r,family:s,font:o.fontString(a,r,s)}}function r(t){return o.options.toLineHeight(o.valueOrDefault(t.lineHeight,1.2),o.valueOrDefault(t.fontSize,n.global.defaultFontSize))}t.Scale=a.extend({getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},mergeTicksOptions:function(){var t=this.options.ticks;for(var e in!1===t.minor&&(t.minor={display:!1}),!1===t.major&&(t.major={display:!1}),t)"major"!==e&&"minor"!==e&&(void 0===t.minor[e]&&(t.minor[e]=t[e]),void 0===t.major[e]&&(t.major[e]=t[e]))},beforeUpdate:function(){o.callback(this.options.beforeUpdate,[this])},update:function(t,e,i){var n,a,r,s,l,u,d=this;for(d.beforeUpdate(),d.maxWidth=t,d.maxHeight=e,d.margins=o.extend({left:0,right:0,top:0,bottom:0},i),d.longestTextCache=d.longestTextCache||{},d.beforeSetDimensions(),d.setDimensions(),d.afterSetDimensions(),d.beforeDataLimits(),d.determineDataLimits(),d.afterDataLimits(),d.beforeBuildTicks(),l=d.buildTicks()||[],d.afterBuildTicks(),d.beforeTickToLabelConversion(),r=d.convertTicksToLabels(l)||d.ticks,d.afterTickToLabelConversion(),d.ticks=r,n=0,a=r.length;n<a;++n)s=r[n],(u=l[n])?u.label=s:l.push(u={label:s,major:!1});return d._ticks=l,d.beforeCalculateTickRotation(),d.calculateTickRotation(),d.afterCalculateTickRotation(),d.beforeFit(),d.fit(),d.afterFit(),d.afterUpdate(),d.minSize},afterUpdate:function(){o.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){o.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){o.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){o.callback(this.options.beforeDataLimits,[this])},determineDataLimits:o.noop,afterDataLimits:function(){o.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){o.callback(this.options.beforeBuildTicks,[this])},buildTicks:o.noop,afterBuildTicks:function(){o.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){o.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){o.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){o.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,n=t.options.ticks,a=s(t._ticks),r=i(n);e.font=r.font;var l=n.minRotation||0;if(a.length&&t.options.display&&t.isHorizontal())for(var u,d=o.longestText(e,r.font,a,t.longestTextCache),c=d,h=t.getPixelForTick(1)-t.getPixelForTick(0)-6;c>h&&l<n.maxRotation;){var f=o.toRadians(l);if(u=Math.cos(f),Math.sin(f)*d>t.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){o.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){o.callback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},a=s(t._ticks),l=t.options,u=l.ticks,d=l.scaleLabel,c=l.gridLines,h=l.display,f=t.isHorizontal(),g=i(u),p=l.gridLines.tickMarkLength;if(n.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?p:0,n.height=f?h&&c.drawTicks?p:0:t.maxHeight,d.display&&h){var m=r(d)+o.options.toPadding(d.padding).height;f?n.height+=m:n.width+=m}if(u.display&&h){var v=o.longestText(t.ctx,g.font,a,t.longestTextCache),b=o.numberOfLabelLines(a),x=.5*g.size,y=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var k=o.toRadians(t.labelRotation),M=Math.cos(k),w=Math.sin(k)*v+g.size*b+x*(b-1)+x;n.height=Math.min(t.maxHeight,n.height+w+y),t.ctx.font=g.font;var S=e(t.ctx,a[0],g.font),C=e(t.ctx,a[a.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===l.position?M*S+3:M*x+3,t.paddingRight="bottom"===l.position?M*x+3:M*C+3):(t.paddingLeft=S/2+3,t.paddingRight=C/2+3)}else u.mirror?v=0:v+=y+x,n.width=Math.min(t.maxWidth,n.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){o.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(o.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:o.noop,getPixelForValue:o.noop,getValueForPixel:o.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+Math.round(a);return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n,a,r=this,s=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=o.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),i=0;i<u;i++)n=t[i],(e>1&&i%e>0||i%e==0&&i+e>=u)&&i!==u-1&&delete n.label,f.push(n);return f},draw:function(t){var e=this,a=e.options;if(a.display){var s=e.ctx,u=n.global,d=a.ticks.minor,c=a.ticks.major||d,h=a.gridLines,f=a.scaleLabel,g=0!==e.labelRotation,p=e.isHorizontal(),m=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=o.valueOrDefault(d.fontColor,u.defaultFontColor),b=i(d),x=o.valueOrDefault(c.fontColor,u.defaultFontColor),y=i(c),k=h.drawTicks?h.tickMarkLength:0,M=o.valueOrDefault(f.fontColor,u.defaultFontColor),w=i(f),S=o.options.toPadding(f.padding),C=o.toRadians(e.labelRotation),_=[],D=e.options.gridLines.lineWidth,I="right"===a.position?e.right:e.right-D-k,P="right"===a.position?e.right+k:e.right,A="bottom"===a.position?e.top+D:e.bottom-k-D,T="bottom"===a.position?e.top+D+k:e.bottom+D;if(o.each(m,function(i,n){if(!o.isNullOrUndef(i.label)){var r,s,c,f,v,b,x,y,M,w,S,F,O,R,L=i.label;n===e.zeroLineIndex&&a.offset===h.offsetGridLines?(r=h.zeroLineWidth,s=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(r=o.valueAtIndexOrDefault(h.lineWidth,n),s=o.valueAtIndexOrDefault(h.color,n),c=o.valueOrDefault(h.borderDash,u.borderDash),f=o.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var z="middle",B="middle",W=d.padding;if(p){var N=k+W;"bottom"===a.position?(B=g?"middle":"top",z=g?"right":"center",R=e.top+N):(B=g?"middle":"bottom",z=g?"left":"center",R=e.bottom-N);var V=l(e,n,h.offsetGridLines&&m.length>1);V<e.left&&(s="rgba(0,0,0,0)"),V+=o.aliasPixel(r),O=e.getPixelForTick(n)+d.labelOffset,v=x=M=S=V,b=A,y=T,w=t.top,F=t.bottom+D}else{var E,H="left"===a.position;d.mirror?(z=H?"left":"right",E=W):(z=H?"right":"left",E=k+W),O=H?e.right-E:e.left+E;var j=l(e,n,h.offsetGridLines&&m.length>1);j<e.top&&(s="rgba(0,0,0,0)"),j+=o.aliasPixel(r),R=e.getPixelForTick(n)+d.labelOffset,v=I,x=P,M=t.left,S=t.right+D,b=y=w=F=j}_.push({tx1:v,ty1:b,tx2:x,ty2:y,x1:M,y1:w,x2:S,y2:F,labelX:O,labelY:R,glWidth:r,glColor:s,glBorderDash:c,glBorderDashOffset:f,rotation:-1*C,label:L,major:i.major,textBaseline:B,textAlign:z})}}),o.each(_,function(t){if(h.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),h.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),h.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),d.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=t.major?y.font:b.font,s.fillStyle=t.major?x:v,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var i=t.label;if(o.isArray(i))for(var n=i.length,a=1.5*b.size,r=e.isHorizontal()?0:-a*(n-1)/2,l=0;l<n;++l)s.fillText(""+i[l],0,r),r+=a;else s.fillText(i,0,0);s.restore()}}),f.display){var F,O,R=0,L=r(f)/2;if(p)F=e.left+(e.right-e.left)/2,O="bottom"===a.position?e.bottom-L-S.bottom:e.top+L+S.top;else{var z="left"===a.position;F=z?e.left+L+S.top:e.right-L-S.top,O=e.top+(e.bottom-e.top)/2,R=z?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(F,O),s.rotate(R),s.textAlign="center",s.textBaseline="middle",s.fillStyle=M,s.font=w.font,s.fillText(f.labelString,0,0),s.restore()}if(h.drawBorder){s.lineWidth=o.valueAtIndexOrDefault(h.lineWidth,0),s.strokeStyle=o.valueAtIndexOrDefault(h.color,0);var B=e.left,W=e.right+D,N=e.top,V=e.bottom+D,E=o.aliasPixel(s.lineWidth);p?(N=V="top"===a.position?e.bottom:e.top,N+=E,V+=E):(B=W="left"===a.position?e.right:e.left,B+=E,W+=E),s.beginPath(),s.moveTo(B,N),s.lineTo(W,V),s.stroke()}}}})}},{25:25,26:26,34:34,45:45}],33:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(30);e.exports=function(t){t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,e,i){this.constructors[t]=e,this.defaults[t]=a.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?a.merge({},[n.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=a.extend(this.defaults[t],e))},addScalesToLayout:function(t){a.each(t.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,o.addBox(t,e)})}}}},{25:25,30:30,45:45}],34:[function(t,e,i){"use strict";var n=t(45);e.exports={formatters:{values:function(t){return n.isArray(t)?t:""+t},linear:function(t,e,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var o=n.log10(Math.abs(a)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,e,i){var a=t/Math.pow(10,Math.floor(n.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===i.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:o.noop,title:function(t,e){var i="",n=e.labels,a=n?n.length:0;if(t.length>0){var o=t[0];o.xLabel?i=o.xLabel:a>0&&o.index<a&&(i=n[o.index])}return i},afterTitle:o.noop,beforeBody:o.noop,beforeLabel:o.noop,label:function(t,e){var i=e.datasets[t.datasetIndex].label||"";return i&&(i+=": "),i+=t.yLabel},labelColor:function(t,e){var i=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:i.borderColor,backgroundColor:i.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:o.noop,afterBody:o.noop,beforeFooter:o.noop,footer:o.noop,afterFooter:o.noop}}}),e.exports=function(t){function e(t,e){var i=o.color(t);return i.alpha(e*i.alpha()).rgbaString()}function i(t,e){return e&&(o.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function r(t){var e=n.global,i=o.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:i(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:i(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:i(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:i(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:i(t.titleFontStyle,e.defaultFontStyle),titleFontSize:i(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:i(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:i(t.footerFontStyle,e.defaultFontStyle),footerFontSize:i(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}t.Tooltip=a.extend({initialize:function(){this._model=r(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),a=t.afterTitle.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var n=this,a=n._options.callbacks,r=[];return o.each(t,function(t){var o={before:[],lines:[],after:[]};i(o.before,a.beforeLabel.call(n,t,e)),i(o.lines,a.label.call(n,t,e)),i(o.after,a.afterLabel.call(n,t,e)),r.push(o)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),a=t.afterFooter.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},update:function(e){var i,n,a,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k,M,w,S=this,C=S._options,_=S._model,D=S._model=r(C),I=S._active,P=S._data,A={xAlign:_.xAlign,yAlign:_.yAlign},T={x:_.x,y:_.y},F={width:_.width,height:_.height},O={x:_.caretX,y:_.caretY};if(I.length){D.opacity=1;var R=[],L=[];O=t.Tooltip.positioners[C.position].call(S,I,S._eventPosition);var z=[];for(i=0,n=I.length;i<n;++i)z.push((x=I[i],y=void 0,k=void 0,void 0,void 0,y=x._xScale,k=x._yScale||x._scale,M=x._index,w=x._datasetIndex,{xLabel:y?y.getLabelForIndex(M,w):"",yLabel:k?k.getLabelForIndex(M,w):"",index:M,datasetIndex:w,x:x._model.x,y:x._model.y}));C.filter&&(z=z.filter(function(t){return C.filter(t,P)})),C.itemSort&&(z=z.sort(function(t,e){return C.itemSort(t,e,P)})),o.each(z,function(t){R.push(C.callbacks.labelColor.call(S,t,S._chart)),L.push(C.callbacks.labelTextColor.call(S,t,S._chart))}),D.title=S.getTitle(z,P),D.beforeBody=S.getBeforeBody(z,P),D.body=S.getBody(z,P),D.afterBody=S.getAfterBody(z,P),D.footer=S.getFooter(z,P),D.x=Math.round(O.x),D.y=Math.round(O.y),D.caretPadding=C.caretPadding,D.labelColors=R,D.labelTextColors=L,D.dataPoints=z,A=function(t,e){var i,n,a,o,r,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",c="center";s.y<e.height?c="top":s.y>l.height-e.height&&(c="bottom");var h=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===c?(i=function(t){return t<=h},n=function(t){return t>h}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",c=r(s.y))):n(s.x)&&(d="right",o(s.x)&&(d="center",c=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:c}}(this,F=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,r=e.body,s=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;n+=l*d,n+=l?(l-1)*e.titleSpacing:0,n+=l?e.titleMarginBottom:0,n+=s*c,n+=s?(s-1)*e.bodySpacing:0,n+=u?e.footerMarginTop:0,n+=u*h,n+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,i.measureText(t).width+f)};return i.font=o.fontString(d,e._titleFontStyle,e._titleFontFamily),o.each(e.title,g),i.font=o.fontString(c,e._bodyFontStyle,e._bodyFontFamily),o.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,o.each(r,function(t){o.each(t.before,g),o.each(t.lines,g),o.each(t.after,g)}),f=0,i.font=o.fontString(h,e._footerFontStyle,e._footerFontFamily),o.each(e.footer,g),{width:a+=2*e.xPadding,height:n}}(this,D)),a=D,s=F,l=A,u=S._chart,d=a.x,c=a.y,h=a.caretSize,f=a.caretPadding,g=a.cornerRadius,p=l.xAlign,m=l.yAlign,v=h+f,b=g+f,"right"===p?d-=s.width:"center"===p&&((d-=s.width/2)+s.width>u.width&&(d=u.width-s.width),d<0&&(d=0)),"top"===m?c+=v:c-="bottom"===m?s.height+v:s.height/2,"center"===m?"left"===p?d+=v:"right"===p&&(d-=v):"left"===p?d-=b:"right"===p&&(d+=b),T={x:d,y:c}}else D.opacity=0;return D.xAlign=A.xAlign,D.yAlign=A.yAlign,D.x=T.x,D.y=T.y,D.width=F.width,D.height=F.height,D.caretX=O.x,D.caretY=O.y,S._model=D,e&&C.custom&&C.custom.call(S,D),S},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,u=i.caretSize,d=i.cornerRadius,c=i.xAlign,h=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)s=g+m/2,"left"===c?(a=(n=f)-u,o=n,r=s+u,l=s-u):(a=(n=f+p)+u,o=n,r=s-u,l=s+u);else if("left"===c?(n=(a=f+d+u)-u,o=a+u):"right"===c?(n=(a=f+p-d-u)-u,o=a+u):(n=(a=i.caretX)-u,o=a+u),"top"===h)s=(r=g)-u,l=r;else{s=(r=g+m)+u,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,i,n,a){var r=i.title;if(r.length){n.textAlign=i._titleAlign,n.textBaseline="top";var s,l,u=i.titleFontSize,d=i.titleSpacing;for(n.fillStyle=e(i.titleFontColor,a),n.font=o.fontString(u,i._titleFontStyle,i._titleFontFamily),s=0,l=r.length;s<l;++s)n.fillText(r[s],t.x,t.y),t.y+=u+d,s+1===r.length&&(t.y+=i.titleMarginBottom-d)}},drawBody:function(t,i,n,a){var r=i.bodyFontSize,s=i.bodySpacing,l=i.body;n.textAlign=i._bodyAlign,n.textBaseline="top",n.font=o.fontString(r,i._bodyFontStyle,i._bodyFontFamily);var u=0,d=function(e){n.fillText(e,t.x+u,t.y),t.y+=r+s};n.fillStyle=e(i.bodyFontColor,a),o.each(i.beforeBody,d);var c=i.displayColors;u=c?r+2:0,o.each(l,function(s,l){var u=e(i.labelTextColors[l],a);n.fillStyle=u,o.each(s.before,d),o.each(s.lines,function(o){c&&(n.fillStyle=e(i.legendColorBackground,a),n.fillRect(t.x,t.y,r,r),n.lineWidth=1,n.strokeStyle=e(i.labelColors[l].borderColor,a),n.strokeRect(t.x,t.y,r,r),n.fillStyle=e(i.labelColors[l].backgroundColor,a),n.fillRect(t.x+1,t.y+1,r-2,r-2),n.fillStyle=u),d(o)}),o.each(s.after,d)}),u=0,o.each(i.afterBody,d),t.y-=s},drawFooter:function(t,i,n,a){var r=i.footer;r.length&&(t.y+=i.footerMarginTop,n.textAlign=i._footerAlign,n.textBaseline="top",n.fillStyle=e(i.footerFontColor,a),n.font=o.fontString(i.footerFontSize,i._footerFontStyle,i._footerFontFamily),o.each(r,function(e){n.fillText(e,t.x,t.y),t.y+=i.footerFontSize+i.footerSpacing}))},drawBackground:function(t,i,n,a,o){n.fillStyle=e(i.backgroundColor,o),n.strokeStyle=e(i.borderColor,o),n.lineWidth=i.borderWidth;var r=i.xAlign,s=i.yAlign,l=t.x,u=t.y,d=a.width,c=a.height,h=i.cornerRadius;n.beginPath(),n.moveTo(l+h,u),"top"===s&&this.drawCaret(t,a),n.lineTo(l+d-h,u),n.quadraticCurveTo(l+d,u,l+d,u+h),"center"===s&&"right"===r&&this.drawCaret(t,a),n.lineTo(l+d,u+c-h),n.quadraticCurveTo(l+d,u+c,l+d-h,u+c),"bottom"===s&&this.drawCaret(t,a),n.lineTo(l+h,u+c),n.quadraticCurveTo(l,u+c,l,u+c-h),"center"===s&&"left"===r&&this.drawCaret(t,a),n.lineTo(l,u+h),n.quadraticCurveTo(l,u,l+h,u),n.closePath(),n.fill(),i.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(n,e,t,i,a),n.x+=e.xPadding,n.y+=e.yPadding,this.drawTitle(n,e,t,a),this.drawBody(n,e,t,a),this.drawFooter(n,e,t,a))}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!o.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,i,n=0,a=0,o=0;for(e=0,i=t.length;e<i;++e){var r=t[e];if(r&&r.hasValue()){var s=r.tooltipPosition();n+=s.x,a+=s.y,++o}}return{x:Math.round(n/o),y:Math.round(a/o)}},nearest:function(t,e){var i,n,a,r=e.x,s=e.y,l=Number.POSITIVE_INFINITY;for(i=0,n=t.length;i<n;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=o.distanceBetweenPoints(e,d);c<l&&(l=c,a=u)}}if(a){var h=a.tooltipPosition();r=h.x,s=h.y}return{x:r,y:s}}}}},{25:25,26:26,45:45}],36:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{elements:{arc:{backgroundColor:n.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var i=this._view;if(i){for(var n=o.getAngleFromPoint(i,{x:t,y:e}),a=n.angle,r=n.distance,s=i.startAngle,l=i.endAngle;l<s;)l+=2*Math.PI;for(;a>l;)a-=2*Math.PI;for(;a<s;)a+=2*Math.PI;var u=a>=s&&a<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:r.defaultColor,borderWidth:3,borderColor:r.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=r.elements.line,c=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||r.defaultColor,s.beginPath(),c=-1,t=0;t<u.length;++t)e=u[t],i=o.previousItem(u,t),n=e._view,0===t?n.skip||(s.moveTo(n.x,n.y),c=t):(i=-1===c?i:u[c],n.skip||(c!==t-1&&!l||-1===c?s.moveTo(n.x,n.y):o.canvas.lineTo(s,i._view,e._view),c=t));s.stroke(),s.restore()}})},{25:25,26:26,45:45}],38:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global.defaultColor;function s(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}n._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:r,borderColor:r,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}}),e.exports=a.extend({inRange:function(t,e){var i=this._view;return!!i&&Math.pow(t-i.x,2)+Math.pow(e-i.y,2)<Math.pow(i.hitRadius+i.radius,2)},inLabelRange:s,inXRange:s,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,i=this._model,a=this._chart.ctx,s=e.pointStyle,l=e.radius,u=e.x,d=e.y,c=o.color,h=0;e.skip||(a.strokeStyle=e.borderColor||r,a.lineWidth=o.valueOrDefault(e.borderWidth,n.global.elements.point.borderWidth),a.fillStyle=e.backgroundColor||r,void 0!==t&&(i.x<t.left||1.01*t.right<i.x||i.y<t.top||1.01*t.bottom<i.y)&&(i.x<t.left?h=(u-i.x)/(t.left-i.x):1.01*t.right<i.x?h=(i.x-u)/(i.x-t.right):i.y<t.top?h=(d-i.y)/(t.top-i.y):1.01*t.bottom<i.y&&(h=(i.y-d)/(i.y-t.bottom)),h=Math.round(100*h)/100,a.strokeStyle=c(a.strokeStyle).alpha(h).rgbString(),a.fillStyle=c(a.fillStyle).alpha(h).rgbString()),o.canvas.drawPoint(a,s,l,u,d))}})},{25:25,26:26,45:45}],39:[function(t,e,i){"use strict";var n=t(25),a=t(26);function o(t){return void 0!==t._view.width}function r(t){var e,i,n,a,r=t._view;if(o(t)){var s=r.width/2;e=r.x-s,i=r.x+s,n=Math.min(r.y,r.base),a=Math.max(r.y,r.base)}else{var l=r.height/2;e=Math.min(r.x,r.base),i=Math.max(r.x,r.base),n=r.y-l,a=r.y+l}return{left:e,top:n,right:i,bottom:a}}n._set("global",{elements:{rectangle:{backgroundColor:n.global.defaultColor,borderColor:n.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a,o,r,s=this._chart.ctx,l=this._view,u=l.borderWidth;if(l.horizontal?(t=l.base,e=l.x,i=l.y-l.height/2,n=l.y+l.height/2,a=e>t?1:-1,o=1,r=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,i=l.y,a=1,o=(n=l.base)>i?1:-1,r=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(i-n)),c=(u=u>d?d:u)/2,h=t+("left"!==r?c*a:0),f=e+("right"!==r?-c*a:0),g=i+("top"!==r?c*o:0),p=n+("bottom"!==r?-c*o:0);h!==f&&(i=g,n=p),g!==p&&(t=h,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var m=[[t,n],[t,i],[e,i],[e,n]],v=["bottom","left","top","right"].indexOf(r,0);function b(t){return m[(v+t)%4]}-1===v&&(v=0);var x=b(0);s.moveTo(x[0],x[1]);for(var y=1;y<4;y++)x=b(y),s.lineTo(x[0],x[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=r(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=r(this);return o(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=r(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=r(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return o(this)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,i){"use strict";var n=t(42);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,n/2),s=Math.min(o,a/2);t.moveTo(e+r,i),t.lineTo(e+n-r,i),t.quadraticCurveTo(e+n,i,e+n,i+s),t.lineTo(e+n,i+a-s),t.quadraticCurveTo(e+n,i+a,e+n-r,i+a),t.lineTo(e+r,i+a),t.quadraticCurveTo(e,i+a,e,i+a-s),t.lineTo(e,i+s),t.quadraticCurveTo(e,i,e+r,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a){var o,r,s,l,u,d;if(!e||"object"!=typeof e||"[object HTMLImageElement]"!==(o=e.toString())&&"[object HTMLCanvasElement]"!==o){if(!(isNaN(i)||i<=0)){switch(e){default:t.beginPath(),t.arc(n,a,i,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(r=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(n-r/2,a+u/3),t.lineTo(n+r/2,a+u/3),t.lineTo(n,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*i,t.beginPath(),t.fillRect(n-d,a-d,2*d,2*d),t.strokeRect(n-d,a-d,2*d,2*d);break;case"rectRounded":var c=i/Math.SQRT2,h=n-c,f=a-c,g=Math.SQRT2*i;t.beginPath(),this.roundedRect(t,h,f,g,g,i/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*i,t.beginPath(),t.moveTo(n-d,a),t.lineTo(n,a+d),t.lineTo(n+d,a),t.lineTo(n,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(n,a),t.lineTo(n+i,a),t.closePath()}t.stroke()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments),t.closePath()}},{42:42}],42:[function(t,e,i){"use strict";var n,a={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return a.valueOrDefault(a.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var o,r,s;if(a.isArray(t))if(r=t.length,n)for(o=r-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;o<r;o++)e.call(i,t[o],o);else if(a.isObject(t))for(r=(s=Object.keys(t)).length,o=0;o<r;o++)e.call(i,t[s[o]],s[o])},arrayEquals:function(t,e){var i,n,o,r;if(!t||!e||t.length!==e.length)return!1;for(i=0,n=t.length;i<n;++i)if(o=t[i],r=e[i],o instanceof Array&&r instanceof Array){if(!a.arrayEquals(o,r))return!1}else if(o!==r)return!1;return!0},clone:function(t){if(a.isArray(t))return t.map(a.clone);if(a.isObject(t)){for(var e={},i=Object.keys(t),n=i.length,o=0;o<n;++o)e[i[o]]=a.clone(t[i[o]]);return e}return t},_merger:function(t,e,i,n){var o=e[t],r=i[t];a.isObject(o)&&a.isObject(r)?a.merge(o,r,n):e[t]=a.clone(r)},_mergerIf:function(t,e,i){var n=e[t],o=i[t];a.isObject(n)&&a.isObject(o)?a.mergeIf(n,o):e.hasOwnProperty(t)||(e[t]=a.clone(o))},merge:function(t,e,i){var n,o,r,s,l,u=a.isArray(e)?e:[e],d=u.length;if(!a.isObject(t))return t;for(n=(i=i||{}).merger||a._merger,o=0;o<d;++o)if(e=u[o],a.isObject(e))for(l=0,s=(r=Object.keys(e)).length;l<s;++l)n(r[l],t,e,i);return t},mergeIf:function(t,e){return a.merge(t,e,{merger:a._mergerIf})},extend:function(t){for(var e=function(e,i){t[i]=e},i=1,n=arguments.length;i<n;++i)a.each(arguments[i],e);return t},inherits:function(t){var e=this,i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},n=function(){this.constructor=i};return n.prototype=e.prototype,i.prototype=new n,i.extend=a.inherits,t&&a.extend(i.prototype,t),i.__super__=e.prototype,i}};e.exports=a,a.callCallback=a.callback,a.indexOf=function(t,e,i){return Array.prototype.indexOf.call(t,e,i)},a.getValueOrDefault=a.valueOrDefault,a.getValueAtIndexOrDefault=a.valueAtIndexOrDefault},{}],43:[function(t,e,i){"use strict";var n=t(42),a={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},n.easingEffects=a},{42:42}],44:[function(t,e,i){"use strict";var n=t(42);e.exports={toLineHeight:function(t,e){var i=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,i,a,o;return n.isObject(t)?(e=+t.top||0,i=+t.right||0,a=+t.bottom||0,o=+t.left||0):e=i=a=o=+t||0,{top:e,right:i,bottom:a,left:o,height:e+a,width:o+i}},resolve:function(t,e,i){var a,o,r;for(a=0,o=t.length;a<o;++a)if(void 0!==(r=t[a])&&(void 0!==e&&"function"==typeof r&&(r=r(e)),void 0!==i&&n.isArray(r)&&(r=r[i]),void 0!==r))return r}}},{42:42}],45:[function(t,e,i){"use strict";e.exports=t(42),e.exports.easing=t(43),e.exports.canvas=t(41),e.exports.options=t(44)},{41:41,42:42,43:43,44:44}],46:[function(t,e,i){e.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},{}],47:[function(t,e,i){"use strict";var n=t(45),a="$chartjs",o="chartjs-",r=o+"render-monitor",s=o+"render-animation",l=["animationstart","webkitAnimationStart"],u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function d(t,e){var i=n.getStyle(t,e),a=i&&i.match(/^(\d+)(\.\d+)?px$/);return a?Number(a[1]):void 0}var c=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function h(t,e,i){t.addEventListener(e,i,c)}function f(t,e,i){t.removeEventListener(e,i,c)}function g(t,e,i,n,a){return{type:t,chart:e,native:a||null,x:void 0!==i?i:null,y:void 0!==n?n:null}}function p(t,e,i){var u,d,c,f,p,m,v,b,x=t[a]||(t[a]={}),y=x.resizer=function(t){var e=document.createElement("div"),i=o+"size-monitor",n="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;";e.style.cssText=n,e.className=i,e.innerHTML='<div class="'+i+'-expand" style="'+n+'"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="'+i+'-shrink" style="'+n+'"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div>';var a=e.childNodes[0],r=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,r.scrollLeft=1e6,r.scrollTop=1e6};var s=function(){e._reset(),t()};return h(a,"scroll",s.bind(a,"expand")),h(r,"scroll",s.bind(r,"shrink")),e}((u=function(){if(x.resizer)return e(g("resize",i))},c=!1,f=[],function(){f=Array.prototype.slice.call(arguments),d=d||this,c||(c=!0,n.requestAnimFrame.call(window,function(){c=!1,u.apply(d,f)}))}));m=function(){if(x.resizer){var e=t.parentNode;e&&e!==y.parentNode&&e.insertBefore(y,e.firstChild),y._reset()}},v=(p=t)[a]||(p[a]={}),b=v.renderProxy=function(t){t.animationName===s&&m()},n.each(l,function(t){h(p,t,b)}),v.reflow=!!p.offsetParent,p.classList.add(r)}function m(t){var e,i,o,s=t[a]||{},u=s.resizer;delete s.resizer,i=(e=t)[a]||{},(o=i.renderProxy)&&(n.each(l,function(t){f(e,t,o)}),delete i.renderProxy),e.classList.remove(r),u&&u.parentNode&&u.parentNode.removeChild(u)}e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t,e,i,n="from{opacity:0.99}to{opacity:1}";e="@-webkit-keyframes "+s+"{"+n+"}@keyframes "+s+"{"+n+"}."+r+"{-webkit-animation:"+s+" 0.001s;animation:"+s+" 0.001s;}",i=(t=this)._style||document.createElement("style"),t._style||(t._style=i,e="/* Chart.js */\n"+e,i.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(i)),i.appendChild(document.createTextNode(e))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t[a]={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=d(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=d(t,"height");void 0!==r&&(t.height=s)}}(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e[a]){var i=e[a].initial;["height","width"].forEach(function(t){var a=i[t];n.isNullOrUndef(a)?e.removeAttribute(t):e.setAttribute(t,a)}),n.each(i.style||{},function(t,i){e.style[i]=t}),e.width=e.width,delete e[a]}},addEventListener:function(t,e,i){var o=t.canvas;if("resize"!==e){var r=i[a]||(i[a]={});h(o,e,(r.proxies||(r.proxies={}))[t.id+"_"+e]=function(e){var a,o,r,s;i((o=t,r=u[(a=e).type]||a.type,s=n.getRelativePosition(a,o),g(r,o,s.x,s.y,a)))})}else p(o,i,t)},removeEventListener:function(t,e,i){var n=t.canvas;if("resize"!==e){var o=((i[a]||{}).proxies||{})[t.id+"_"+e];o&&f(n,e,o)}else m(n)}},n.addEvent=h,n.removeEvent=f},{45:45}],48:[function(t,e,i){"use strict";var n=t(45),a=t(46),o=t(47),r=o._enabled?o:a;e.exports=n.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},r)},{45:45,46:46,47:47}],49:[function(t,e,i){"use strict";e.exports={},e.exports.filler=t(50),e.exports.legend=t(51),e.exports.title=t(52)},{50:50,51:51,52:52}],50:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("global",{plugins:{filler:{propagate:!0}}});var r={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],o=a.length||0;return o?function(t,e){return e<o&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,i=e?e.x:null,n=e?e.y:null;return function(t){return{x:null===i?t.x:i,y:null===n?t.y:n}}}};function s(t,e,i){var n,a=t._model||{},o=a.fill;if(void 0===o&&(o=!!a.backgroundColor),!1===o||null===o)return!1;if(!0===o)return"origin";if(n=parseFloat(o,10),isFinite(n)&&Math.floor(n)===n)return"-"!==o[0]&&"+"!==o[0]||(n=e+n),!(n===e||n<0||n>=i)&&n;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function l(t){var e,i=t.el._model||{},n=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===i.scaleBottom?n.bottom:i.scaleBottom:"end"===a?o=void 0===i.scaleTop?n.top:i.scaleTop:void 0!==i.scaleZero?o=i.scaleZero:n.getBasePosition?o=n.getBasePosition():n.getBasePixel&&(o=n.getBasePixel()),null!=o){if(void 0!==o.x&&void 0!==o.y)return o;if("number"==typeof o&&isFinite(o))return{x:(e=n.isHorizontal())?o:null,y:e?null:o}}return null}function u(t,e,i){var n,a=t[e].fill,o=[e];if(!i)return a;for(;!1!==a&&-1===o.indexOf(a);){if(!isFinite(a))return a;if(!(n=t[a]))return!1;if(n.visible)return a;o.push(a),a=n.fill}return!1}function d(t){return t&&!t.skip}function c(t,e,i,n,a){var r;if(n&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<n;++r)o.canvas.lineTo(t,e[r-1],e[r]);for(t.lineTo(i[a-1].x,i[a-1].y),r=a-1;r>0;--r)o.canvas.lineTo(t,i[r],i[r-1],!0)}}e.exports={id:"filler",afterDatasetsUpdate:function(t,e){var i,n,o,d,c,h,f,g=(t.data.datasets||[]).length,p=e.propagate,m=[];for(n=0;n<g;++n)d=null,(o=(i=t.getDatasetMeta(n)).dataset)&&o._model&&o instanceof a.Line&&(d={visible:t.isDatasetVisible(n),fill:s(o,n,g),chart:t,el:o}),i.$filler=d,m.push(d);for(n=0;n<g;++n)(d=m[n])&&(d.fill=u(m,n,p),d.boundary=l(d),d.mapper=(void 0,f=void 0,h=(c=d).fill,f="dataset",!1===h?null:(isFinite(h)||(f="boundary"),r[f](c))))},beforeDatasetDraw:function(t,e){var i=e.meta.$filler;if(i){var a=t.ctx,r=i.el,s=r._view,l=r._children||[],u=i.mapper,h=s.backgroundColor||n.global.defaultColor;u&&h&&l.length&&(o.canvas.clipArea(a,t.chartArea),function(t,e,i,n,a,o){var r,s,l,u,h,f,g,p=e.length,m=n.spanGaps,v=[],b=[],x=0,y=0;for(t.beginPath(),r=0,s=p+!!o;r<s;++r)h=i(u=e[l=r%p]._view,l,n),f=d(u),g=d(h),f&&g?(x=v.push(u),y=b.push(h)):x&&y&&(m?(f&&v.push(u),g&&b.push(h)):(c(t,v,b,x,y),x=y=0,v=[],b=[]));c(t,v,b,x,y),t.closePath(),t.fillStyle=a,t.fill()}(a,l,u,s,h,r._loop),o.canvas.unclipArea(a))}}}},{25:25,40:40,45:45}],51:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;function l(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}n._set("global",{legend:{display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var i=e.datasetIndex,n=this.chart,a=n.getDatasetMeta(i);a.hidden=null===a.hidden?!n.data.datasets[i].hidden:null,n.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return o.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:o.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:i}},this):[]}}},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var i=0;i<t.data.datasets.length;i++)e.push('<li><span style="background-color:'+t.data.datasets[i].backgroundColor+'"></span>'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("</li>");return e.push("</ul>"),e.join("")}});var u=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},i=o.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter(function(i){return e.filter(i,t.chart.data)})),t.options.reverse&&i.reverse(),t.legendItems=i},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,i=e.labels,a=e.display,r=t.ctx,s=n.global,u=o.valueOrDefault,d=u(i.fontSize,s.defaultFontSize),c=u(i.fontStyle,s.defaultFontStyle),h=u(i.fontFamily,s.defaultFontFamily),f=o.fontString(d,c,h),g=t.legendHitBoxes=[],p=t.minSize,m=t.isHorizontal();if(m?(p.width=t.maxWidth,p.height=a?10:0):(p.width=a?10:0,p.height=t.maxHeight),a)if(r.font=f,m){var v=t.lineWidths=[0],b=t.legendItems.length?d+i.padding:0;r.textAlign="left",r.textBaseline="top",o.each(t.legendItems,function(e,n){var a=l(i,d)+d/2+r.measureText(e.text).width;v[v.length-1]+a+i.padding>=t.width&&(b+=d+i.padding,v[v.length]=t.left),g[n]={left:0,top:0,width:a,height:d},v[v.length-1]+=a+i.padding}),p.height+=b}else{var x=i.padding,y=t.columnWidths=[],k=i.padding,M=0,w=0,S=d+x;o.each(t.legendItems,function(t,e){var n=l(i,d)+d/2+r.measureText(t.text).width;w+S>p.height&&(k+=M+i.padding,y.push(M),M=0,w=0),M=Math.max(M,n),w+=S,g[e]={left:0,top:0,width:n,height:d}}),k+=M,y.push(M),p.width+=k}t.width=p.width,t.height=p.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,i=e.labels,a=n.global,r=a.elements.line,s=t.width,u=t.lineWidths;if(e.display){var d,c=t.ctx,h=o.valueOrDefault,f=h(i.fontColor,a.defaultFontColor),g=h(i.fontSize,a.defaultFontSize),p=h(i.fontStyle,a.defaultFontStyle),m=h(i.fontFamily,a.defaultFontFamily),v=o.fontString(g,p,m);c.textAlign="left",c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=l(i,g),x=t.legendHitBoxes,y=t.isHorizontal();d=y?{x:t.left+(s-u[0])/2,y:t.top+i.padding,line:0}:{x:t.left+i.padding,y:t.top+i.padding,line:0};var k=g+i.padding;o.each(t.legendItems,function(n,l){var f,p,m,v,M,w=c.measureText(n.text).width,S=b+g/2+w,C=d.x,_=d.y;y?C+S>=s&&(_=d.y+=k,d.line++,C=d.x=t.left+(s-u[d.line])/2):_+k>t.bottom&&(C=d.x=C+t.columnWidths[d.line]+i.padding,_=d.y=t.top+i.padding,d.line++),function(t,i,n){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(n.fillStyle,a.defaultColor),c.lineCap=h(n.lineCap,r.borderCapStyle),c.lineDashOffset=h(n.lineDashOffset,r.borderDashOffset),c.lineJoin=h(n.lineJoin,r.borderJoinStyle),c.lineWidth=h(n.lineWidth,r.borderWidth),c.strokeStyle=h(n.strokeStyle,a.defaultColor);var s=0===h(n.lineWidth,r.borderWidth);if(c.setLineDash&&c.setLineDash(h(n.lineDash,r.borderDash)),e.labels&&e.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=i+u;o.canvas.drawPoint(c,n.pointStyle,l,d,f)}else s||c.strokeRect(t,i,b,g),c.fillRect(t,i,b,g);c.restore()}}(C,_,n),x[l].left=C,x[l].top=_,f=n,p=w,v=b+(m=g/2)+C,M=_+m,c.fillText(f.text,v,M),f.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(v,M),c.lineTo(v+p,M),c.stroke()),y?d.x+=S+i.padding:d.y+=k})}},handleEvent:function(t){var e=this,i=e.options,n="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===n){if(!i.onHover)return}else{if("click"!==n)return;if(!i.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===n){i.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===n){i.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function d(t,e){var i=new u({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.legend=i}e.exports={id:"legend",_element:u,beforeInit:function(t){var e=t.options.legend;e&&d(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(o.mergeIf(e,n.global.legend),i?(r.configure(t,i,e),i.options=e):d(t,e)):i&&(r.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}}},{25:25,26:26,30:30,45:45}],52:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;n._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var l=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:s,afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=o.valueOrDefault,i=t.options,a=i.display,r=e(i.fontSize,n.global.defaultFontSize),s=t.minSize,l=o.isArray(i.text)?i.text.length:1,u=o.options.toLineHeight(i.lineHeight,r),d=a?l*u+2*i.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=d):(s.width=d,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:s,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,i=o.valueOrDefault,a=t.options,r=n.global;if(a.display){var s,l,u,d=i(a.fontSize,r.defaultFontSize),c=i(a.fontStyle,r.defaultFontStyle),h=i(a.fontFamily,r.defaultFontFamily),f=o.fontString(d,c,h),g=o.options.toLineHeight(a.lineHeight,d),p=g/2+a.padding,m=0,v=t.top,b=t.left,x=t.bottom,y=t.right;e.fillStyle=i(a.fontColor,r.defaultFontColor),e.font=f,t.isHorizontal()?(l=b+(y-b)/2,u=v+p,s=y-b):(l="left"===a.position?b+p:y-p,u=v+(x-v)/2,s=x-v,m=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(m),e.textAlign="center",e.textBaseline="middle";var k=a.text;if(o.isArray(k))for(var M=0,w=0;w<k.length;++w)e.fillText(k[w],0,M,s),M+=g;else e.fillText(k,0,0,s);e.restore()}}});function u(t,e){var i=new l({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.titleBlock=i}e.exports={id:"title",_element:l,beforeInit:function(t){var e=t.options.title;e&&u(t,e)},beforeUpdate:function(t){var e=t.options.title,i=t.titleBlock;e?(o.mergeIf(e,n.global.title),i?(r.configure(t,i,e),i.options=e):u(t,e)):i&&(r.removeBox(t,i),delete t.titleBlock)}}},{25:25,26:26,30:30,45:45}],53:[function(t,e,i){"use strict";e.exports=function(t){var e=t.Scale.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t,e=this,i=e.getLabels();e.minIndex=0,e.maxIndex=i.length-1,void 0!==e.options.ticks.min&&(t=i.indexOf(e.options.ticks.min),e.minIndex=-1!==t?t:e.minIndex),void 0!==e.options.ticks.max&&(t=i.indexOf(e.options.ticks.max),e.maxIndex=-1!==t?t:e.maxIndex),e.min=i[e.minIndex],e.max=i[e.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var i=this,n=i.chart.data,a=i.isHorizontal();return n.yLabels&&!a?i.getRightValue(n.datasets[e].data[t]):i.ticks[t-i.minIndex]},getPixelForValue:function(t,e){var i,n=this,a=n.options.offset,o=Math.max(n.maxIndex+1-n.minIndex-(a?0:1),1);if(null!=t&&(i=n.isHorizontal()?t.x:t.y),void 0!==i||void 0!==t&&isNaN(e)){t=i||t;var r=n.getLabels().indexOf(t);e=-1!==r?r:e}if(n.isHorizontal()){var s=n.width/o,l=s*(e-n.minIndex);return a&&(l+=s/2),n.left+Math.round(l)}var u=n.height/o,d=u*(e-n.minIndex);return a&&(d+=u/2),n.top+Math.round(d)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,i=e.options.offset,n=Math.max(e._ticks.length-(i?0:1),1),a=e.isHorizontal(),o=(a?e.width:e.height)/n;return t-=a?e.left:e.top,i&&(t-=o/2),(t<=0?0:Math.round(t/o))+e.minIndex},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",e,{position:"bottom"})}},{}],54:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:o.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,n=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null;var s=e.stacked;if(void 0===s&&a.each(n,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};a.each(n,function(n,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,c=l[u].negativeValues;i.isDatasetVisible(o)&&r(s)&&a.each(n.data,function(i,n){var a=+t.getRightValue(i);isNaN(a)||s.data[n].hidden||(d[n]=d[n]||0,c[n]=c[n]||0,e.relativePoints?d[n]=100:a<0?c[n]+=a:d[n]+=a)})}),a.each(l,function(e){var i=e.positiveValues.concat(e.negativeValues),n=a.min(i),o=a.max(i);t.min=null===t.min?n:Math.min(t.min,n),t.max=null===t.max?o:Math.max(t.max,o)})}else a.each(n,function(e,n){var o=i.getDatasetMeta(n);i.isDatasetVisible(n)&&r(o)&&a.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var i=a.valueOrDefault(e.fontSize,n.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*i)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,i=e.start,n=+e.getRightValue(t),a=e.end-i;return e.isHorizontal()?e.left+e.width/a*(n-i):e.bottom-e.height/a*(n-i)},getValueForPixel:function(t){var e=this,i=e.isHorizontal(),n=i?e.width:e.height,a=(i?t-e.left:e.bottom-t)/n;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,e)}},{25:25,34:34,45:45}],55:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=n.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var i=n.sign(t.min),a=n.sign(t.max);i<0&&a<0?t.max=0:i>0&&a>0&&(t.min=0)}var o=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),o!==r&&t.min>=t.max&&(o?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),a={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,stepSize:n.valueOrDefault(e.fixedStepSize,e.stepSize)},o=t.ticks=function(t,e){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=n.niceNum(e.max-e.min,!1);i=n.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(e.min/i)*i,s=Math.ceil(e.max/i)*i;t.min&&t.max&&t.stepSize&&n.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=n.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l);var u=1;i<1&&(u=Math.pow(10,i.toString().length-2),r=Math.round(r*u)/u,s=Math.round(s*u)/u),a.push(void 0!==t.min?t.min:r);for(var d=1;d<l;++d)a.push(Math.round((r+d*i)*u)/u);return a.push(void 0!==t.max?t.max:s),a}(a,t);t.handleDirectionalChanges(),t.max=n.max(o),t.min=n.min(o),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{45:45}],56:[function(t,e,i){"use strict";var n=t(45),a=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:a.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,a=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null,t.minNotZero=null;var s=e.stacked;if(void 0===s&&n.each(a,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};n.each(a,function(a,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");i.isDatasetVisible(o)&&r(s)&&(void 0===l[u]&&(l[u]=[]),n.each(a.data,function(e,i){var n=l[u],a=+t.getRightValue(e);isNaN(a)||s.data[i].hidden||a<0||(n[i]=n[i]||0,n[i]+=a)}))}),n.each(l,function(e){if(e.length>0){var i=n.min(e),a=n.max(e);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?a:Math.max(t.max,a)}})}else n.each(a,function(e,a){var o=i.getDatasetMeta(a);i.isDatasetVisible(a)&&r(o)&&n.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||n<0||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n),0!==n&&(null===t.minNotZero||n<t.minNotZero)&&(t.minNotZero=n))})});this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks,i=n.valueOrDefault;t.min=i(e.min,t.min),t.max=i(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(n.log10(t.min))-1),t.max=Math.pow(10,Math.floor(n.log10(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(n.log10(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(n.log10(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(n.log10(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,i=!t.isHorizontal(),a={min:e.min,max:e.max},o=t.ticks=function(t,e){var i,a,o=[],r=n.valueOrDefault,s=r(t.min,Math.pow(10,Math.floor(n.log10(e.min)))),l=Math.floor(n.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(i=Math.floor(n.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,i)),o.push(s),s=a*Math.pow(10,i)):(i=Math.floor(n.log10(s)),a=Math.floor(s/Math.pow(10,i)));for(var d=i<0?Math.pow(10,Math.abs(i)):1;o.push(s),10==++a&&(a=1,d=++i>=0?1:d),s=Math.round(a*Math.pow(10,i)*d)/d,i<l||i===l&&a<u;);var c=r(t.max,s);return o.push(c),o}(a,t);t.max=n.max(o),t.min=n.min(o),e.reverse?(i=!i,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),i&&o.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},_getFirstTickValue:function(t){var e=Math.floor(n.log10(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},getPixelForValue:function(e){var i,a,o,r,s,l=this,u=l.options.ticks.reverse,d=n.log10,c=l._getFirstTickValue(l.minNotZero),h=0;return e=+l.getRightValue(e),u?(o=l.end,r=l.start,s=-1):(o=l.start,r=l.end,s=1),l.isHorizontal()?(i=l.width,a=u?l.right:l.left):(i=l.height,s*=-1,a=u?l.top:l.bottom),e!==o&&(0===o&&(i-=h=n.getValueOrDefault(l.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=c),0!==e&&(h+=i/(d(r)-d(o))*(d(e)-d(o))),a+=s*h),a},getValueForPixel:function(e){var i,a,o,r,s=this,l=s.options.ticks.reverse,u=n.log10,d=s._getFirstTickValue(s.minNotZero);if(l?(a=s.end,o=s.start):(a=s.start,o=s.end),s.isHorizontal()?(i=s.width,r=l?s.right-e:e-s.left):(i=s.height,r=l?e-s.top:s.bottom-e),r!==a){if(0===a){var c=n.getValueOrDefault(s.options.ticks.fontSize,t.defaults.global.defaultFontSize);r-=c,i-=c,a=d}r*=u(o)-u(a),r/=i,r=Math.pow(10,u(a)+r)}return r}});t.scaleService.registerScaleType("logarithmic",i,e)}},{34:34,45:45}],57:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e=n.global,i={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:o.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function r(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function s(t){var i=t.options.pointLabels,n=a.valueOrDefault(i.fontSize,e.defaultFontSize),o=a.valueOrDefault(i.fontStyle,e.defaultFontStyle),r=a.valueOrDefault(i.fontFamily,e.defaultFontFamily);return{size:n,style:o,family:r,font:a.fontString(n,o,r)}}function l(t,e,i,n,a){return t===n||t===a?{start:e-i/2,end:e+i/2}:t<n||t>a?{start:e-i-5,end:e}:{start:e,end:e+i+5}}function u(t,e,i,n){if(a.isArray(e))for(var o=i.y,r=1.5*n,s=0;s<e.length;++s)t.fillText(e[s],i.x,o),o+=r;else t.fillText(e,i.x,i.y)}function d(t){return a.isNumber(t)?t:0}var c=t.LinearScaleBase.extend({setDimensions:function(){var t=this,i=t.options,n=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var o=a.min([t.height,t.width]),r=a.valueOrDefault(n.fontSize,e.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,e=t.chart,i=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(o,r){if(e.isDatasetVisible(r)){var s=e.getDatasetMeta(r);a.each(o.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||s.data[a].hidden||(i=Math.min(o,i),n=Math.max(o,n))})}}),t.min=i===Number.POSITIVE_INFINITY?0:i,t.max=n===Number.NEGATIVE_INFINITY?0:n,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=a.valueOrDefault(t.fontSize,e.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,e;this.options.pointLabels.display?function(t){var e,i,n,o=s(t),u=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},c={};t.ctx.font=o.font,t._pointLabelSizes=[];var h,f,g,p=r(t);for(e=0;e<p;e++){n=t.getPointPosition(e,u),h=t.ctx,f=o.size,g=t.pointLabels[e]||"",i=a.isArray(g)?{w:a.longestText(h,h.font,g),h:g.length*f+1.5*(g.length-1)*f}:{w:h.measureText(g).width,h:f},t._pointLabelSizes[e]=i;var m=t.getIndexAngle(e),v=a.toDegrees(m)%360,b=l(v,n.x,i.w,0,180),x=l(v,n.y,i.h,90,270);b.start<d.l&&(d.l=b.start,c.l=m),b.end>d.r&&(d.r=b.end,c.r=m),x.start<d.t&&(d.t=x.start,c.t=m),x.end>d.b&&(d.b=x.end,c.b=m)}t.setReductions(u,d,c)}(this):(t=this,e=Math.min(t.height/2,t.width/2),t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0))},setReductions:function(t,e,i){var n=e.l/Math.sin(i.l),a=Math.max(e.r-this.width,0)/Math.sin(i.r),o=-e.t/Math.cos(i.t),r=-Math.max(e.b-this.height,0)/Math.cos(i.b);n=d(n),a=d(a),o=d(o),r=d(r),this.drawingArea=Math.min(Math.round(t-(n+a)/2),Math.round(t-(o+r)/2)),this.setCenterPoint(n,a,o,r)},setCenterPoint:function(t,e,i,n){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,s=i+a.drawingArea,l=a.height-n-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/r(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var i=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*i:(t-e.min)*i},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+this.xCenter,y:Math.round(Math.sin(i)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,l=a.valueOrDefault;if(i.display){var d=t.ctx,c=this.getIndexAngle(0),h=l(o.fontSize,e.defaultFontSize),f=l(o.fontStyle,e.defaultFontStyle),g=l(o.fontFamily,e.defaultFontFamily),p=a.fontString(h,f,g);a.each(t.ticks,function(i,s){if(s>0||o.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]);if(n.display&&0!==s&&function(t,e,i,n){var o=t.ctx;if(o.strokeStyle=a.valueAtIndexOrDefault(e.color,n-1),o.lineWidth=a.valueAtIndexOrDefault(e.lineWidth,n-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var s=r(t);if(0===s)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var u=1;u<s;u++)l=t.getPointPosition(u,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}(t,n,u,s),o.display){var f=l(o.fontColor,e.defaultFontColor);if(d.font=p,d.save(),d.translate(t.xCenter,t.yCenter),d.rotate(c),o.showLabelBackdrop){var g=d.measureText(i).width;d.fillStyle=o.backdropColor,d.fillRect(-g/2-o.backdropPaddingX,-u-h/2-o.backdropPaddingY,g+2*o.backdropPaddingX,h+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=f,d.fillText(i,0,-u),d.restore()}}}),(i.angleLines.display||i.pointLabels.display)&&function(t){var i=t.ctx,n=t.options,o=n.angleLines,l=n.pointLabels;i.lineWidth=o.lineWidth,i.strokeStyle=o.color;var d,c,h,f,g=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),p=s(t);i.textBaseline="top";for(var m=r(t)-1;m>=0;m--){if(o.display){var v=t.getPointPosition(m,g);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(v.x,v.y),i.stroke(),i.closePath()}if(l.display){var b=t.getPointPosition(m,g+5),x=a.valueAtIndexOrDefault(l.fontColor,m,e.defaultFontColor);i.font=p.font,i.fillStyle=x;var y=t.getIndexAngle(m),k=a.toDegrees(y);i.textAlign=0===(f=k)||180===f?"center":f<180?"left":"right",d=k,c=t._pointLabelSizes[m],h=b,90===d||270===d?h.y-=c.h/2:(d>270||d<90)&&(h.y-=c.h),u(i,t.pointLabels[m]||"",b,p.size)}}}(t)}}});t.scaleService.registerScaleType("radialLinear",c,i)}},{25:25,34:34,45:45}],58:[function(t,e,i){"use strict";var n=t(1);n="function"==typeof n?n:window.moment;var a=t(25),o=t(45),r=Number.MIN_SAFE_INTEGER||-9007199254740991,s=Number.MAX_SAFE_INTEGER||9007199254740991,l={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},u=Object.keys(l);function d(t,e){return t-e}function c(t){var e,i,n,a={},o=[];for(e=0,i=t.length;e<i;++e)a[n=t[e]]||(a[n]=!0,o.push(n));return o}function h(t,e,i,n){var a=function(t,e,i){for(var n,a,o,r=0,s=t.length-1;r>=0&&r<=s;){if(a=t[(n=r+s>>1)-1]||null,o=t[n],!a)return{lo:null,hi:o};if(o[e]<i)r=n+1;else{if(!(a[e]>i))return{lo:a,hi:o};s=n-1}}return{lo:o,hi:null}}(t,e,i),o=a.lo?a.hi?a.lo:t[t.length-2]:t[0],r=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=r[e]-o[e],l=s?(i-o[e])/s:0,u=(r[n]-o[n])*l;return o[n]+u}function f(t,e){var i=e.parser,a=e.parser||e.format;return"function"==typeof i?i(t):"string"==typeof t&&"string"==typeof a?n(t,a):(t instanceof n||(t=n(t)),t.isValid()?t:"function"==typeof a?a(t):t)}function g(t,e){if(o.isNullOrUndef(t))return null;var i=e.options.time,n=f(e.getRightValue(t),i);return n.isValid()?(i.round&&n.startOf(i.round),n.valueOf()):null}function p(t){for(var e=u.indexOf(t)+1,i=u.length;e<i;++e)if(l[u[e]].common)return u[e]}function m(t,e,i,a){var r,d=a.time,c=d.unit||function(t,e,i,n){var a,o,r,d=u.length;for(a=u.indexOf(t);a<d-1;++a)if(r=(o=l[u[a]]).steps?o.steps[o.steps.length-1]:s,o.common&&Math.ceil((i-e)/(r*o.size))<=n)return u[a];return u[d-1]}(d.minUnit,t,e,i),h=p(c),f=o.valueOrDefault(d.stepSize,d.unitStepSize),g="week"===c&&d.isoWeekday,m=a.ticks.major.enabled,v=l[c],b=n(t),x=n(e),y=[];for(f||(f=function(t,e,i,n){var a,o,r,s=e-t,u=l[i],d=u.size,c=u.steps;if(!c)return Math.ceil(s/(n*d));for(a=0,o=c.length;a<o&&(r=c[a],!(Math.ceil(s/(d*r))<=n));++a);return r}(t,e,c,i)),g&&(b=b.isoWeekday(g),x=x.isoWeekday(g)),b=b.startOf(g?"day":c),(x=x.startOf(g?"day":c))<e&&x.add(1,c),r=n(b),m&&h&&!g&&!d.round&&(r.startOf(h),r.add(~~((b-r)/(v.size*f))*f,c));r<x;r.add(f,c))y.push(+r);return y.push(+r),y}e.exports=function(t){var e=t.Scale.extend({initialize:function(){if(!n)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");this.mergeTicksOptions(),t.Scale.prototype.initialize.call(this)},update:function(){var e=this.options;return e.time&&e.time.format&&console.warn("options.time.format is deprecated and replaced by options.time.parser."),t.Scale.prototype.update.apply(this,arguments)},getRightValue:function(e){return e&&void 0!==e.t&&(e=e.t),t.Scale.prototype.getRightValue.call(this,e)},determineDataLimits:function(){var t,e,i,a,l,u,h=this,f=h.chart,p=h.options.time,m=p.unit||"day",v=s,b=r,x=[],y=[],k=[];for(t=0,i=f.data.labels.length;t<i;++t)k.push(g(f.data.labels[t],h));for(t=0,i=(f.data.datasets||[]).length;t<i;++t)if(f.isDatasetVisible(t))if(l=f.data.datasets[t].data,o.isObject(l[0]))for(y[t]=[],e=0,a=l.length;e<a;++e)u=g(l[e],h),x.push(u),y[t][e]=u;else x.push.apply(x,k),y[t]=k.slice(0);else y[t]=[];k.length&&(k=c(k).sort(d),v=Math.min(v,k[0]),b=Math.max(b,k[k.length-1])),x.length&&(x=c(x).sort(d),v=Math.min(v,x[0]),b=Math.max(b,x[x.length-1])),v=g(p.min,h)||v,b=g(p.max,h)||b,v=v===s?+n().startOf(m):v,b=b===r?+n().endOf(m)+1:b,h.min=Math.min(v,b),h.max=Math.max(v+1,b),h._horizontal=h.isHorizontal(),h._table=[],h._timestamps={data:x,datasets:y,labels:k}},buildTicks:function(){var t,e,i,a,o,r,s,d,c,v,b,x,y=this,k=y.min,M=y.max,w=y.options,S=w.time,C=[],_=[];switch(w.ticks.source){case"data":C=y._timestamps.data;break;case"labels":C=y._timestamps.labels;break;case"auto":default:C=m(k,M,y.getLabelCapacity(k),w)}for("ticks"===w.bounds&&C.length&&(k=C[0],M=C[C.length-1]),k=g(S.min,y)||k,M=g(S.max,y)||M,t=0,e=C.length;t<e;++t)(i=C[t])>=k&&i<=M&&_.push(i);return y.min=k,y.max=M,y._unit=S.unit||function(t,e,i,a){var o,r,s=n.duration(n(a).diff(n(i)));for(o=u.length-1;o>=u.indexOf(e);o--)if(r=u[o],l[r].common&&s.as(r)>=t.length)return r;return u[e?u.indexOf(e):0]}(_,S.minUnit,y.min,y.max),y._majorUnit=p(y._unit),y._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,o,r,s,l,u=[],d=[e];for(a=0,o=t.length;a<o;++a)(s=t[a])>e&&s<i&&d.push(s);for(d.push(i),a=0,o=d.length;a<o;++a)l=d[a+1],r=d[a-1],s=d[a],void 0!==r&&void 0!==l&&Math.round((l+r)/2)===s||u.push({time:s,pos:a/(o-1)});return u}(y._timestamps.data,k,M,w.distribution),y._offsets=(a=y._table,o=_,r=k,s=M,b=0,x=0,(d=w).offset&&o.length&&(d.time.min||(c=o.length>1?o[1]:s,v=o[0],b=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2),d.time.max||(c=o[o.length-1],v=o.length>1?o[o.length-2]:r,x=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2)),{left:b,right:x}),y._labelFormat=function(t,e){var i,n,a,o=t.length;for(i=0;i<o;i++){if(0!==(n=f(t[i],e)).millisecond())return"MMM D, YYYY h:mm:ss.SSS a";0===n.second()&&0===n.minute()&&0===n.hour()||(a=!0)}return a?"MMM D, YYYY h:mm:ss a":"MMM D, YYYY"}(y._timestamps.data,S),function(t,e){var i,a,o,r,s=[];for(i=0,a=t.length;i<a;++i)o=t[i],r=!!e&&o===+n(o).startOf(e),s.push({value:o,major:r});return s}(_,y._majorUnit)},getLabelForIndex:function(t,e){var i=this.chart.data,n=this.options.time,a=i.labels&&t<i.labels.length?i.labels[t]:"",r=i.datasets[e].data[t];return o.isObject(r)&&(a=this.getRightValue(r)),n.tooltipFormat?f(a,n).format(n.tooltipFormat):"string"==typeof a?a:f(a,n).format(this._labelFormat)},tickFormatFunction:function(t,e,i,n){var a=this.options,r=t.valueOf(),s=a.time.displayFormats,l=s[this._unit],u=this._majorUnit,d=s[u],c=t.clone().startOf(u).valueOf(),h=a.ticks.major,f=h.enabled&&u&&d&&r===c,g=t.format(n||(f?d:l)),p=f?h:a.ticks.minor,m=o.valueOrDefault(p.callback,p.userCallback);return m?m(g,e,i):g},convertTicksToLabels:function(t){var e,i,a=[];for(e=0,i=t.length;e<i;++e)a.push(this.tickFormatFunction(n(t[e].value),e,t));return a},getPixelForOffset:function(t){var e=this,i=e._horizontal?e.width:e.height,n=e._horizontal?e.left:e.top,a=h(e._table,"time",t,"pos");return n+i*(e._offsets.left+a)/(e._offsets.left+1+e._offsets.right)},getPixelForValue:function(t,e,i){var n=null;if(void 0!==e&&void 0!==i&&(n=this._timestamps.datasets[i][e]),null===n&&(n=g(t,this)),null!==n)return this.getPixelForOffset(n)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this,i=e._horizontal?e.width:e.height,a=e._horizontal?e.left:e.top,o=(i?(t-a)/i:0)*(e._offsets.left+1+e._offsets.left)-e._offsets.right,r=h(e._table,"pos",o,"time");return n(r)},getLabelWidth:function(t){var e=this.options.ticks,i=this.ctx.measureText(t).width,n=o.toRadians(e.maxRotation),r=Math.cos(n),s=Math.sin(n);return i*r+o.valueOrDefault(e.fontSize,a.global.defaultFontSize)*s},getLabelCapacity:function(t){var e=this,i=e.options.time.displayFormats.millisecond,a=e.tickFormatFunction(n(t),0,[],i),o=e.getLabelWidth(a),r=e.isHorizontal()?e.width:e.height,s=Math.floor(r/o);return s>0?s:1}});t.scaleService.registerScaleType("time",e,{position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},{1:1,25:25,45:45}]},{},[7])(7)});
diff --git a/web/js/bootstrap.js b/web/js/bootstrap.js
deleted file mode 100644
index 1c88b71..0000000
--- a/web/js/bootstrap.js
+++ /dev/null
@@ -1,2317 +0,0 @@
-/*!
- * Bootstrap v3.3.4 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-if (typeof jQuery === 'undefined') {
- throw new Error('Bootstrap\'s JavaScript requires jQuery')
-}
-
-+function ($) {
- 'use strict';
- var version = $.fn.jquery.split(' ')[0].split('.')
- if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
- throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
- }
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: transition.js v3.3.4
- * http://getbootstrap.com/javascript/#transitions
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
- // ============================================================
-
- function transitionEnd() {
- var el = document.createElement('bootstrap')
-
- var transEndEventNames = {
- WebkitTransition : 'webkitTransitionEnd',
- MozTransition : 'transitionend',
- OTransition : 'oTransitionEnd otransitionend',
- transition : 'transitionend'
- }
-
- for (var name in transEndEventNames) {
- if (el.style[name] !== undefined) {
- return { end: transEndEventNames[name] }
- }
- }
-
- return false // explicit for ie8 ( ._.)
- }
-
- // http://blog.alexmaccaw.com/css-transitions
- $.fn.emulateTransitionEnd = function (duration) {
- var called = false
- var $el = this
- $(this).one('bsTransitionEnd', function () { called = true })
- var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
- setTimeout(callback, duration)
- return this
- }
-
- $(function () {
- $.support.transition = transitionEnd()
-
- if (!$.support.transition) return
-
- $.event.special.bsTransitionEnd = {
- bindType: $.support.transition.end,
- delegateType: $.support.transition.end,
- handle: function (e) {
- if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
- }
- }
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: alert.js v3.3.4
- * http://getbootstrap.com/javascript/#alerts
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // ALERT CLASS DEFINITION
- // ======================
-
- var dismiss = '[data-dismiss="alert"]'
- var Alert = function (el) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.VERSION = '3.3.4'
-
- Alert.TRANSITION_DURATION = 150
-
- Alert.prototype.close = function (e) {
- var $this = $(this)
- var selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- var $parent = $(selector)
-
- if (e) e.preventDefault()
-
- if (!$parent.length) {
- $parent = $this.closest('.alert')
- }
-
- $parent.trigger(e = $.Event('close.bs.alert'))
-
- if (e.isDefaultPrevented()) return
-
- $parent.removeClass('in')
-
- function removeElement() {
- // detach from parent, fire event then clean up data
- $parent.detach().trigger('closed.bs.alert').remove()
- }
-
- $.support.transition && $parent.hasClass('fade') ?
- $parent
- .one('bsTransitionEnd', removeElement)
- .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
- removeElement()
- }
-
-
- // ALERT PLUGIN DEFINITION
- // =======================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.alert')
-
- if (!data) $this.data('bs.alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- var old = $.fn.alert
-
- $.fn.alert = Plugin
- $.fn.alert.Constructor = Alert
-
-
- // ALERT NO CONFLICT
- // =================
-
- $.fn.alert.noConflict = function () {
- $.fn.alert = old
- return this
- }
-
-
- // ALERT DATA-API
- // ==============
-
- $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: button.js v3.3.4
- * http://getbootstrap.com/javascript/#buttons
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // BUTTON PUBLIC CLASS DEFINITION
- // ==============================
-
- var Button = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Button.DEFAULTS, options)
- this.isLoading = false
- }
-
- Button.VERSION = '3.3.4'
-
- Button.DEFAULTS = {
- loadingText: 'loading...'
- }
-
- Button.prototype.setState = function (state) {
- var d = 'disabled'
- var $el = this.$element
- var val = $el.is('input') ? 'val' : 'html'
- var data = $el.data()
-
- state = state + 'Text'
-
- if (data.resetText == null) $el.data('resetText', $el[val]())
-
- // push to event loop to allow forms to submit
- setTimeout($.proxy(function () {
- $el[val](data[state] == null ? this.options[state] : data[state])
-
- if (state == 'loadingText') {
- this.isLoading = true
- $el.addClass(d).attr(d, d)
- } else if (this.isLoading) {
- this.isLoading = false
- $el.removeClass(d).removeAttr(d)
- }
- }, this), 0)
- }
-
- Button.prototype.toggle = function () {
- var changed = true
- var $parent = this.$element.closest('[data-toggle="buttons"]')
-
- if ($parent.length) {
- var $input = this.$element.find('input')
- if ($input.prop('type') == 'radio') {
- if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
- else $parent.find('.active').removeClass('active')
- }
- if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
- } else {
- this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
- }
-
- if (changed) this.$element.toggleClass('active')
- }
-
-
- // BUTTON PLUGIN DEFINITION
- // ========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.button')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.button', (data = new Button(this, options)))
-
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
-
- var old = $.fn.button
-
- $.fn.button = Plugin
- $.fn.button.Constructor = Button
-
-
- // BUTTON NO CONFLICT
- // ==================
-
- $.fn.button.noConflict = function () {
- $.fn.button = old
- return this
- }
-
-
- // BUTTON DATA-API
- // ===============
-
- $(document)
- .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
- var $btn = $(e.target)
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
- Plugin.call($btn, 'toggle')
- e.preventDefault()
- })
- .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
- $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: carousel.js v3.3.4
- * http://getbootstrap.com/javascript/#carousel
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // CAROUSEL CLASS DEFINITION
- // =========================
-
- var Carousel = function (element, options) {
- this.$element = $(element)
- this.$indicators = this.$element.find('.carousel-indicators')
- this.options = options
- this.paused = null
- this.sliding = null
- this.interval = null
- this.$active = null
- this.$items = null
-
- this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
-
- this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
- .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
- .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
- }
-
- Carousel.VERSION = '3.3.4'
-
- Carousel.TRANSITION_DURATION = 600
-
- Carousel.DEFAULTS = {
- interval: 5000,
- pause: 'hover',
- wrap: true,
- keyboard: true
- }
-
- Carousel.prototype.keydown = function (e) {
- if (/input|textarea/i.test(e.target.tagName)) return
- switch (e.which) {
- case 37: this.prev(); break
- case 39: this.next(); break
- default: return
- }
-
- e.preventDefault()
- }
-
- Carousel.prototype.cycle = function (e) {
- e || (this.paused = false)
-
- this.interval && clearInterval(this.interval)
-
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
-
- return this
- }
-
- Carousel.prototype.getItemIndex = function (item) {
- this.$items = item.parent().children('.item')
- return this.$items.index(item || this.$active)
- }
-
- Carousel.prototype.getItemForDirection = function (direction, active) {
- var activeIndex = this.getItemIndex(active)
- var willWrap = (direction == 'prev' && activeIndex === 0)
- || (direction == 'next' && activeIndex == (this.$items.length - 1))
- if (willWrap && !this.options.wrap) return active
- var delta = direction == 'prev' ? -1 : 1
- var itemIndex = (activeIndex + delta) % this.$items.length
- return this.$items.eq(itemIndex)
- }
-
- Carousel.prototype.to = function (pos) {
- var that = this
- var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
-
- if (pos > (this.$items.length - 1) || pos < 0) return
-
- if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
- if (activeIndex == pos) return this.pause().cycle()
-
- return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
- }
-
- Carousel.prototype.pause = function (e) {
- e || (this.paused = true)
-
- if (this.$element.find('.next, .prev').length && $.support.transition) {
- this.$element.trigger($.support.transition.end)
- this.cycle(true)
- }
-
- this.interval = clearInterval(this.interval)
-
- return this
- }
-
- Carousel.prototype.next = function () {
- if (this.sliding) return
- return this.slide('next')
- }
-
- Carousel.prototype.prev = function () {
- if (this.sliding) return
- return this.slide('prev')
- }
-
- Carousel.prototype.slide = function (type, next) {
- var $active = this.$element.find('.item.active')
- var $next = next || this.getItemForDirection(type, $active)
- var isCycling = this.interval
- var direction = type == 'next' ? 'left' : 'right'
- var that = this
-
- if ($next.hasClass('active')) return (this.sliding = false)
-
- var relatedTarget = $next[0]
- var slideEvent = $.Event('slide.bs.carousel', {
- relatedTarget: relatedTarget,
- direction: direction
- })
- this.$element.trigger(slideEvent)
- if (slideEvent.isDefaultPrevented()) return
-
- this.sliding = true
-
- isCycling && this.pause()
-
- if (this.$indicators.length) {
- this.$indicators.find('.active').removeClass('active')
- var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
- $nextIndicator && $nextIndicator.addClass('active')
- }
-
- var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
- if ($.support.transition && this.$element.hasClass('slide')) {
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- $active
- .one('bsTransitionEnd', function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () {
- that.$element.trigger(slidEvent)
- }, 0)
- })
- .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
- } else {
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger(slidEvent)
- }
-
- isCycling && this.cycle()
-
- return this
- }
-
-
- // CAROUSEL PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.carousel')
- var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var action = typeof option == 'string' ? option : options.slide
-
- if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (action) data[action]()
- else if (options.interval) data.pause().cycle()
- })
- }
-
- var old = $.fn.carousel
-
- $.fn.carousel = Plugin
- $.fn.carousel.Constructor = Carousel
-
-
- // CAROUSEL NO CONFLICT
- // ====================
-
- $.fn.carousel.noConflict = function () {
- $.fn.carousel = old
- return this
- }
-
-
- // CAROUSEL DATA-API
- // =================
-
- var clickHandler = function (e) {
- var href
- var $this = $(this)
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
- if (!$target.hasClass('carousel')) return
- var options = $.extend({}, $target.data(), $this.data())
- var slideIndex = $this.attr('data-slide-to')
- if (slideIndex) options.interval = false
-
- Plugin.call($target, options)
-
- if (slideIndex) {
- $target.data('bs.carousel').to(slideIndex)
- }
-
- e.preventDefault()
- }
-
- $(document)
- .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
- .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
-
- $(window).on('load', function () {
- $('[data-ride="carousel"]').each(function () {
- var $carousel = $(this)
- Plugin.call($carousel, $carousel.data())
- })
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: collapse.js v3.3.4
- * http://getbootstrap.com/javascript/#collapse
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // COLLAPSE PUBLIC CLASS DEFINITION
- // ================================
-
- var Collapse = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Collapse.DEFAULTS, options)
- this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
- '[data-toggle="collapse"][data-target="#' + element.id + '"]')
- this.transitioning = null
-
- if (this.options.parent) {
- this.$parent = this.getParent()
- } else {
- this.addAriaAndCollapsedClass(this.$element, this.$trigger)
- }
-
- if (this.options.toggle) this.toggle()
- }
-
- Collapse.VERSION = '3.3.4'
-
- Collapse.TRANSITION_DURATION = 350
-
- Collapse.DEFAULTS = {
- toggle: true
- }
-
- Collapse.prototype.dimension = function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
-
- Collapse.prototype.show = function () {
- if (this.transitioning || this.$element.hasClass('in')) return
-
- var activesData
- var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
-
- if (actives && actives.length) {
- activesData = actives.data('bs.collapse')
- if (activesData && activesData.transitioning) return
- }
-
- var startEvent = $.Event('show.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
-
- if (actives && actives.length) {
- Plugin.call(actives, 'hide')
- activesData || actives.data('bs.collapse', null)
- }
-
- var dimension = this.dimension()
-
- this.$element
- .removeClass('collapse')
- .addClass('collapsing')[dimension](0)
- .attr('aria-expanded', true)
-
- this.$trigger
- .removeClass('collapsed')
- .attr('aria-expanded', true)
-
- this.transitioning = 1
-
- var complete = function () {
- this.$element
- .removeClass('collapsing')
- .addClass('collapse in')[dimension]('')
- this.transitioning = 0
- this.$element
- .trigger('shown.bs.collapse')
- }
-
- if (!$.support.transition) return complete.call(this)
-
- var scrollSize = $.camelCase(['scroll', dimension].join('-'))
-
- this.$element
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
- }
-
- Collapse.prototype.hide = function () {
- if (this.transitioning || !this.$element.hasClass('in')) return
-
- var startEvent = $.Event('hide.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
-
- var dimension = this.dimension()
-
- this.$element[dimension](this.$element[dimension]())[0].offsetHeight
-
- this.$element
- .addClass('collapsing')
- .removeClass('collapse in')
- .attr('aria-expanded', false)
-
- this.$trigger
- .addClass('collapsed')
- .attr('aria-expanded', false)
-
- this.transitioning = 1
-
- var complete = function () {
- this.transitioning = 0
- this.$element
- .removeClass('collapsing')
- .addClass('collapse')
- .trigger('hidden.bs.collapse')
- }
-
- if (!$.support.transition) return complete.call(this)
-
- this.$element
- [dimension](0)
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
- }
-
- Collapse.prototype.toggle = function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
-
- Collapse.prototype.getParent = function () {
- return $(this.options.parent)
- .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
- .each($.proxy(function (i, element) {
- var $element = $(element)
- this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
- }, this))
- .end()
- }
-
- Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
- var isOpen = $element.hasClass('in')
-
- $element.attr('aria-expanded', isOpen)
- $trigger
- .toggleClass('collapsed', !isOpen)
- .attr('aria-expanded', isOpen)
- }
-
- function getTargetFromTrigger($trigger) {
- var href
- var target = $trigger.attr('data-target')
- || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
-
- return $(target)
- }
-
-
- // COLLAPSE PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.collapse')
- var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
- if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
- if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.collapse
-
- $.fn.collapse = Plugin
- $.fn.collapse.Constructor = Collapse
-
-
- // COLLAPSE NO CONFLICT
- // ====================
-
- $.fn.collapse.noConflict = function () {
- $.fn.collapse = old
- return this
- }
-
-
- // COLLAPSE DATA-API
- // =================
-
- $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
- var $this = $(this)
-
- if (!$this.attr('data-target')) e.preventDefault()
-
- var $target = getTargetFromTrigger($this)
- var data = $target.data('bs.collapse')
- var option = data ? 'toggle' : $this.data()
-
- Plugin.call($target, option)
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: dropdown.js v3.3.4
- * http://getbootstrap.com/javascript/#dropdowns
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // DROPDOWN CLASS DEFINITION
- // =========================
-
- var backdrop = '.dropdown-backdrop'
- var toggle = '[data-toggle="dropdown"]'
- var Dropdown = function (element) {
- $(element).on('click.bs.dropdown', this.toggle)
- }
-
- Dropdown.VERSION = '3.3.4'
-
- Dropdown.prototype.toggle = function (e) {
- var $this = $(this)
-
- if ($this.is('.disabled, :disabled')) return
-
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
-
- clearMenus()
-
- if (!isActive) {
- if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
- // if mobile we use a backdrop because click events don't delegate
- $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
- }
-
- var relatedTarget = { relatedTarget: this }
- $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
-
- if (e.isDefaultPrevented()) return
-
- $this
- .trigger('focus')
- .attr('aria-expanded', 'true')
-
- $parent
- .toggleClass('open')
- .trigger('shown.bs.dropdown', relatedTarget)
- }
-
- return false
- }
-
- Dropdown.prototype.keydown = function (e) {
- if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
-
- var $this = $(this)
-
- e.preventDefault()
- e.stopPropagation()
-
- if ($this.is('.disabled, :disabled')) return
-
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
-
- if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
- if (e.which == 27) $parent.find(toggle).trigger('focus')
- return $this.trigger('click')
- }
-
- var desc = ' li:not(.disabled):visible a'
- var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
-
- if (!$items.length) return
-
- var index = $items.index(e.target)
-
- if (e.which == 38 && index > 0) index-- // up
- if (e.which == 40 && index < $items.length - 1) index++ // down
- if (!~index) index = 0
-
- $items.eq(index).trigger('focus')
- }
-
- function clearMenus(e) {
- if (e && e.which === 3) return
- $(backdrop).remove()
- $(toggle).each(function () {
- var $this = $(this)
- var $parent = getParent($this)
- var relatedTarget = { relatedTarget: this }
-
- if (!$parent.hasClass('open')) return
-
- $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
-
- if (e.isDefaultPrevented()) return
-
- $this.attr('aria-expanded', 'false')
- $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
- })
- }
-
- function getParent($this) {
- var selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- var $parent = selector && $(selector)
-
- return $parent && $parent.length ? $parent : $this.parent()
- }
-
-
- // DROPDOWN PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.dropdown')
-
- if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- var old = $.fn.dropdown
-
- $.fn.dropdown = Plugin
- $.fn.dropdown.Constructor = Dropdown
-
-
- // DROPDOWN NO CONFLICT
- // ====================
-
- $.fn.dropdown.noConflict = function () {
- $.fn.dropdown = old
- return this
- }
-
-
- // APPLY TO STANDARD DROPDOWN ELEMENTS
- // ===================================
-
- $(document)
- .on('click.bs.dropdown.data-api', clearMenus)
- .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
- .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
- .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
- .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: modal.js v3.3.4
- * http://getbootstrap.com/javascript/#modals
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // MODAL CLASS DEFINITION
- // ======================
-
- var Modal = function (element, options) {
- this.options = options
- this.$body = $(document.body)
- this.$element = $(element)
- this.$dialog = this.$element.find('.modal-dialog')
- this.$backdrop = null
- this.isShown = null
- this.originalBodyPad = null
- this.scrollbarWidth = 0
- this.ignoreBackdropClick = false
-
- if (this.options.remote) {
- this.$element
- .find('.modal-content')
- .load(this.options.remote, $.proxy(function () {
- this.$element.trigger('loaded.bs.modal')
- }, this))
- }
- }
-
- Modal.VERSION = '3.3.4'
-
- Modal.TRANSITION_DURATION = 300
- Modal.BACKDROP_TRANSITION_DURATION = 150
-
- Modal.DEFAULTS = {
- backdrop: true,
- keyboard: true,
- show: true
- }
-
- Modal.prototype.toggle = function (_relatedTarget) {
- return this.isShown ? this.hide() : this.show(_relatedTarget)
- }
-
- Modal.prototype.show = function (_relatedTarget) {
- var that = this
- var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
-
- this.$element.trigger(e)
-
- if (this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = true
-
- this.checkScrollbar()
- this.setScrollbar()
- this.$body.addClass('modal-open')
-
- this.escape()
- this.resize()
-
- this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
-
- this.$dialog.on('mousedown.dismiss.bs.modal', function () {
- that.$element.one('mouseup.dismiss.bs.modal', function (e) {
- if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
- })
- })
-
- this.backdrop(function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
-
- if (!that.$element.parent().length) {
- that.$element.appendTo(that.$body) // don't move modals dom position
- }
-
- that.$element
- .show()
- .scrollTop(0)
-
- that.adjustDialog()
-
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
-
- that.$element
- .addClass('in')
- .attr('aria-hidden', false)
-
- that.enforceFocus()
-
- var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
-
- transition ?
- that.$dialog // wait for modal to slide in
- .one('bsTransitionEnd', function () {
- that.$element.trigger('focus').trigger(e)
- })
- .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
- that.$element.trigger('focus').trigger(e)
- })
- }
-
- Modal.prototype.hide = function (e) {
- if (e) e.preventDefault()
-
- e = $.Event('hide.bs.modal')
-
- this.$element.trigger(e)
-
- if (!this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = false
-
- this.escape()
- this.resize()
-
- $(document).off('focusin.bs.modal')
-
- this.$element
- .removeClass('in')
- .attr('aria-hidden', true)
- .off('click.dismiss.bs.modal')
- .off('mouseup.dismiss.bs.modal')
-
- this.$dialog.off('mousedown.dismiss.bs.modal')
-
- $.support.transition && this.$element.hasClass('fade') ?
- this.$element
- .one('bsTransitionEnd', $.proxy(this.hideModal, this))
- .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
- this.hideModal()
- }
-
- Modal.prototype.enforceFocus = function () {
- $(document)
- .off('focusin.bs.modal') // guard against infinite focus loop
- .on('focusin.bs.modal', $.proxy(function (e) {
- if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
- this.$element.trigger('focus')
- }
- }, this))
- }
-
- Modal.prototype.escape = function () {
- if (this.isShown && this.options.keyboard) {
- this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
- e.which == 27 && this.hide()
- }, this))
- } else if (!this.isShown) {
- this.$element.off('keydown.dismiss.bs.modal')
- }
- }
-
- Modal.prototype.resize = function () {
- if (this.isShown) {
- $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
- } else {
- $(window).off('resize.bs.modal')
- }
- }
-
- Modal.prototype.hideModal = function () {
- var that = this
- this.$element.hide()
- this.backdrop(function () {
- that.$body.removeClass('modal-open')
- that.resetAdjustments()
- that.resetScrollbar()
- that.$element.trigger('hidden.bs.modal')
- })
- }
-
- Modal.prototype.removeBackdrop = function () {
- this.$backdrop && this.$backdrop.remove()
- this.$backdrop = null
- }
-
- Modal.prototype.backdrop = function (callback) {
- var that = this
- var animate = this.$element.hasClass('fade') ? 'fade' : ''
-
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
-
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(this.$body)
-
- this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
- if (this.ignoreBackdropClick) {
- this.ignoreBackdropClick = false
- return
- }
- if (e.target !== e.currentTarget) return
- this.options.backdrop == 'static'
- ? this.$element[0].focus()
- : this.hide()
- }, this))
-
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
- this.$backdrop.addClass('in')
-
- if (!callback) return
-
- doAnimate ?
- this.$backdrop
- .one('bsTransitionEnd', callback)
- .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
- callback()
-
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
-
- var callbackRemove = function () {
- that.removeBackdrop()
- callback && callback()
- }
- $.support.transition && this.$element.hasClass('fade') ?
- this.$backdrop
- .one('bsTransitionEnd', callbackRemove)
- .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
- callbackRemove()
-
- } else if (callback) {
- callback()
- }
- }
-
- // these following methods are used to handle overflowing modals
-
- Modal.prototype.handleUpdate = function () {
- this.adjustDialog()
- }
-
- Modal.prototype.adjustDialog = function () {
- var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
-
- this.$element.css({
- paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
- paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
- })
- }
-
- Modal.prototype.resetAdjustments = function () {
- this.$element.css({
- paddingLeft: '',
- paddingRight: ''
- })
- }
-
- Modal.prototype.checkScrollbar = function () {
- var fullWindowWidth = window.innerWidth
- if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
- var documentElementRect = document.documentElement.getBoundingClientRect()
- fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
- }
- this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
- this.scrollbarWidth = this.measureScrollbar()
- }
-
- Modal.prototype.setScrollbar = function () {
- var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
- this.originalBodyPad = document.body.style.paddingRight || ''
- if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
- }
-
- Modal.prototype.resetScrollbar = function () {
- this.$body.css('padding-right', this.originalBodyPad)
- }
-
- Modal.prototype.measureScrollbar = function () { // thx walsh
- var scrollDiv = document.createElement('div')
- scrollDiv.className = 'modal-scrollbar-measure'
- this.$body.append(scrollDiv)
- var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
- this.$body[0].removeChild(scrollDiv)
- return scrollbarWidth
- }
-
-
- // MODAL PLUGIN DEFINITION
- // =======================
-
- function Plugin(option, _relatedTarget) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.modal')
- var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
- if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option](_relatedTarget)
- else if (options.show) data.show(_relatedTarget)
- })
- }
-
- var old = $.fn.modal
-
- $.fn.modal = Plugin
- $.fn.modal.Constructor = Modal
-
-
- // MODAL NO CONFLICT
- // =================
-
- $.fn.modal.noConflict = function () {
- $.fn.modal = old
- return this
- }
-
-
- // MODAL DATA-API
- // ==============
-
- $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
- var $this = $(this)
- var href = $this.attr('href')
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
- var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
-
- if ($this.is('a')) e.preventDefault()
-
- $target.one('show.bs.modal', function (showEvent) {
- if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
- $target.one('hidden.bs.modal', function () {
- $this.is(':visible') && $this.trigger('focus')
- })
- })
- Plugin.call($target, option, this)
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: tooltip.js v3.3.4
- * http://getbootstrap.com/javascript/#tooltip
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // TOOLTIP PUBLIC CLASS DEFINITION
- // ===============================
-
- var Tooltip = function (element, options) {
- this.type = null
- this.options = null
- this.enabled = null
- this.timeout = null
- this.hoverState = null
- this.$element = null
-
- this.init('tooltip', element, options)
- }
-
- Tooltip.VERSION = '3.3.4'
-
- Tooltip.TRANSITION_DURATION = 150
-
- Tooltip.DEFAULTS = {
- animation: true,
- placement: 'top',
- selector: false,
- template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
- trigger: 'hover focus',
- title: '',
- delay: 0,
- html: false,
- container: false,
- viewport: {
- selector: 'body',
- padding: 0
- }
- }
-
- Tooltip.prototype.init = function (type, element, options) {
- this.enabled = true
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
-
- if (this.$element[0] instanceof document.constructor && !this.options.selector) {
- throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
- }
-
- var triggers = this.options.trigger.split(' ')
-
- for (var i = triggers.length; i--;) {
- var trigger = triggers[i]
-
- if (trigger == 'click') {
- this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
- } else if (trigger != 'manual') {
- var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
- var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
-
- this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
- }
- }
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
- }
-
- Tooltip.prototype.getDefaults = function () {
- return Tooltip.DEFAULTS
- }
-
- Tooltip.prototype.getOptions = function (options) {
- options = $.extend({}, this.getDefaults(), this.$element.data(), options)
-
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay,
- hide: options.delay
- }
- }
-
- return options
- }
-
- Tooltip.prototype.getDelegateOptions = function () {
- var options = {}
- var defaults = this.getDefaults()
-
- this._options && $.each(this._options, function (key, value) {
- if (defaults[key] != value) options[key] = value
- })
-
- return options
- }
-
- Tooltip.prototype.enter = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
-
- if (self && self.$tip && self.$tip.is(':visible')) {
- self.hoverState = 'in'
- return
- }
-
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
-
- clearTimeout(self.timeout)
-
- self.hoverState = 'in'
-
- if (!self.options.delay || !self.options.delay.show) return self.show()
-
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'in') self.show()
- }, self.options.delay.show)
- }
-
- Tooltip.prototype.leave = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
-
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
-
- clearTimeout(self.timeout)
-
- self.hoverState = 'out'
-
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'out') self.hide()
- }, self.options.delay.hide)
- }
-
- Tooltip.prototype.show = function () {
- var e = $.Event('show.bs.' + this.type)
-
- if (this.hasContent() && this.enabled) {
- this.$element.trigger(e)
-
- var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
- if (e.isDefaultPrevented() || !inDom) return
- var that = this
-
- var $tip = this.tip()
-
- var tipId = this.getUID(this.type)
-
- this.setContent()
- $tip.attr('id', tipId)
- this.$element.attr('aria-describedby', tipId)
-
- if (this.options.animation) $tip.addClass('fade')
-
- var placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
-
- var autoToken = /\s?auto?\s?/i
- var autoPlace = autoToken.test(placement)
- if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
-
- $tip
- .detach()
- .css({ top: 0, left: 0, display: 'block' })
- .addClass(placement)
- .data('bs.' + this.type, this)
-
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
-
- var pos = this.getPosition()
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
-
- if (autoPlace) {
- var orgPlacement = placement
- var $container = this.options.container ? $(this.options.container) : this.$element.parent()
- var containerDim = this.getPosition($container)
-
- placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
- placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
- placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
- placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
- placement
-
- $tip
- .removeClass(orgPlacement)
- .addClass(placement)
- }
-
- var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
-
- this.applyPlacement(calculatedOffset, placement)
-
- var complete = function () {
- var prevHoverState = that.hoverState
- that.$element.trigger('shown.bs.' + that.type)
- that.hoverState = null
-
- if (prevHoverState == 'out') that.leave(that)
- }
-
- $.support.transition && this.$tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
- complete()
- }
- }
-
- Tooltip.prototype.applyPlacement = function (offset, placement) {
- var $tip = this.tip()
- var width = $tip[0].offsetWidth
- var height = $tip[0].offsetHeight
-
- // manually read margins because getBoundingClientRect includes difference
- var marginTop = parseInt($tip.css('margin-top'), 10)
- var marginLeft = parseInt($tip.css('margin-left'), 10)
-
- // we must check for NaN for ie 8/9
- if (isNaN(marginTop)) marginTop = 0
- if (isNaN(marginLeft)) marginLeft = 0
-
- offset.top = offset.top + marginTop
- offset.left = offset.left + marginLeft
-
- // $.fn.offset doesn't round pixel values
- // so we use setOffset directly with our own function B-0
- $.offset.setOffset($tip[0], $.extend({
- using: function (props) {
- $tip.css({
- top: Math.round(props.top),
- left: Math.round(props.left)
- })
- }
- }, offset), 0)
-
- $tip.addClass('in')
-
- // check to see if placing tip in new offset caused the tip to resize itself
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
-
- if (placement == 'top' && actualHeight != height) {
- offset.top = offset.top + height - actualHeight
- }
-
- var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
-
- if (delta.left) offset.left += delta.left
- else offset.top += delta.top
-
- var isVertical = /top|bottom/.test(placement)
- var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
- var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
-
- $tip.offset(offset)
- this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
- }
-
- Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
- this.arrow()
- .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
- .css(isVertical ? 'top' : 'left', '')
- }
-
- Tooltip.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
-
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
- $tip.removeClass('fade in top bottom left right')
- }
-
- Tooltip.prototype.hide = function (callback) {
- var that = this
- var $tip = $(this.$tip)
- var e = $.Event('hide.bs.' + this.type)
-
- function complete() {
- if (that.hoverState != 'in') $tip.detach()
- that.$element
- .removeAttr('aria-describedby')
- .trigger('hidden.bs.' + that.type)
- callback && callback()
- }
-
- this.$element.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- $tip.removeClass('in')
-
- $.support.transition && $tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
- complete()
-
- this.hoverState = null
-
- return this
- }
-
- Tooltip.prototype.fixTitle = function () {
- var $e = this.$element
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
- }
- }
-
- Tooltip.prototype.hasContent = function () {
- return this.getTitle()
- }
-
- Tooltip.prototype.getPosition = function ($element) {
- $element = $element || this.$element
-
- var el = $element[0]
- var isBody = el.tagName == 'BODY'
-
- var elRect = el.getBoundingClientRect()
- if (elRect.width == null) {
- // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
- elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
- }
- var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
- var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
- var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
-
- return $.extend({}, elRect, scroll, outerDims, elOffset)
- }
-
- Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
- return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
- /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
-
- }
-
- Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
- var delta = { top: 0, left: 0 }
- if (!this.$viewport) return delta
-
- var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
- var viewportDimensions = this.getPosition(this.$viewport)
-
- if (/right|left/.test(placement)) {
- var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
- var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
- if (topEdgeOffset < viewportDimensions.top) { // top overflow
- delta.top = viewportDimensions.top - topEdgeOffset
- } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
- delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
- }
- } else {
- var leftEdgeOffset = pos.left - viewportPadding
- var rightEdgeOffset = pos.left + viewportPadding + actualWidth
- if (leftEdgeOffset < viewportDimensions.left) { // left overflow
- delta.left = viewportDimensions.left - leftEdgeOffset
- } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
- delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
- }
- }
-
- return delta
- }
-
- Tooltip.prototype.getTitle = function () {
- var title
- var $e = this.$element
- var o = this.options
-
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
-
- return title
- }
-
- Tooltip.prototype.getUID = function (prefix) {
- do prefix += ~~(Math.random() * 1000000)
- while (document.getElementById(prefix))
- return prefix
- }
-
- Tooltip.prototype.tip = function () {
- return (this.$tip = this.$tip || $(this.options.template))
- }
-
- Tooltip.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
- }
-
- Tooltip.prototype.enable = function () {
- this.enabled = true
- }
-
- Tooltip.prototype.disable = function () {
- this.enabled = false
- }
-
- Tooltip.prototype.toggleEnabled = function () {
- this.enabled = !this.enabled
- }
-
- Tooltip.prototype.toggle = function (e) {
- var self = this
- if (e) {
- self = $(e.currentTarget).data('bs.' + this.type)
- if (!self) {
- self = new this.constructor(e.currentTarget, this.getDelegateOptions())
- $(e.currentTarget).data('bs.' + this.type, self)
- }
- }
-
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
- }
-
- Tooltip.prototype.destroy = function () {
- var that = this
- clearTimeout(this.timeout)
- this.hide(function () {
- that.$element.off('.' + that.type).removeData('bs.' + that.type)
- })
- }
-
-
- // TOOLTIP PLUGIN DEFINITION
- // =========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tooltip')
- var options = typeof option == 'object' && option
-
- if (!data && /destroy|hide/.test(option)) return
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.tooltip
-
- $.fn.tooltip = Plugin
- $.fn.tooltip.Constructor = Tooltip
-
-
- // TOOLTIP NO CONFLICT
- // ===================
-
- $.fn.tooltip.noConflict = function () {
- $.fn.tooltip = old
- return this
- }
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: popover.js v3.3.4
- * http://getbootstrap.com/javascript/#popovers
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // POPOVER PUBLIC CLASS DEFINITION
- // ===============================
-
- var Popover = function (element, options) {
- this.init('popover', element, options)
- }
-
- if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
-
- Popover.VERSION = '3.3.4'
-
- Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
- placement: 'right',
- trigger: 'click',
- content: '',
- template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
- })
-
-
- // NOTE: POPOVER EXTENDS tooltip.js
- // ================================
-
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
-
- Popover.prototype.constructor = Popover
-
- Popover.prototype.getDefaults = function () {
- return Popover.DEFAULTS
- }
-
- Popover.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
- var content = this.getContent()
-
- $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
- $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
- this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
- ](content)
-
- $tip.removeClass('fade top bottom left right in')
-
- // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
- // this manually by checking the contents.
- if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
- }
-
- Popover.prototype.hasContent = function () {
- return this.getTitle() || this.getContent()
- }
-
- Popover.prototype.getContent = function () {
- var $e = this.$element
- var o = this.options
-
- return $e.attr('data-content')
- || (typeof o.content == 'function' ?
- o.content.call($e[0]) :
- o.content)
- }
-
- Popover.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
- }
-
-
- // POPOVER PLUGIN DEFINITION
- // =========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.popover')
- var options = typeof option == 'object' && option
-
- if (!data && /destroy|hide/.test(option)) return
- if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.popover
-
- $.fn.popover = Plugin
- $.fn.popover.Constructor = Popover
-
-
- // POPOVER NO CONFLICT
- // ===================
-
- $.fn.popover.noConflict = function () {
- $.fn.popover = old
- return this
- }
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: scrollspy.js v3.3.4
- * http://getbootstrap.com/javascript/#scrollspy
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // SCROLLSPY CLASS DEFINITION
- // ==========================
-
- function ScrollSpy(element, options) {
- this.$body = $(document.body)
- this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
- this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
- this.selector = (this.options.target || '') + ' .nav li > a'
- this.offsets = []
- this.targets = []
- this.activeTarget = null
- this.scrollHeight = 0
-
- this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
- this.refresh()
- this.process()
- }
-
- ScrollSpy.VERSION = '3.3.4'
-
- ScrollSpy.DEFAULTS = {
- offset: 10
- }
-
- ScrollSpy.prototype.getScrollHeight = function () {
- return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
- }
-
- ScrollSpy.prototype.refresh = function () {
- var that = this
- var offsetMethod = 'offset'
- var offsetBase = 0
-
- this.offsets = []
- this.targets = []
- this.scrollHeight = this.getScrollHeight()
-
- if (!$.isWindow(this.$scrollElement[0])) {
- offsetMethod = 'position'
- offsetBase = this.$scrollElement.scrollTop()
- }
-
- this.$body
- .find(this.selector)
- .map(function () {
- var $el = $(this)
- var href = $el.data('target') || $el.attr('href')
- var $href = /^#./.test(href) && $(href)
-
- return ($href
- && $href.length
- && $href.is(':visible')
- && [[$href[offsetMethod]().top + offsetBase, href]]) || null
- })
- .sort(function (a, b) { return a[0] - b[0] })
- .each(function () {
- that.offsets.push(this[0])
- that.targets.push(this[1])
- })
- }
-
- ScrollSpy.prototype.process = function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- var scrollHeight = this.getScrollHeight()
- var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
- var offsets = this.offsets
- var targets = this.targets
- var activeTarget = this.activeTarget
- var i
-
- if (this.scrollHeight != scrollHeight) {
- this.refresh()
- }
-
- if (scrollTop >= maxScroll) {
- return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
- }
-
- if (activeTarget && scrollTop < offsets[0]) {
- this.activeTarget = null
- return this.clear()
- }
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
- && this.activate(targets[i])
- }
- }
-
- ScrollSpy.prototype.activate = function (target) {
- this.activeTarget = target
-
- this.clear()
-
- var selector = this.selector +
- '[data-target="' + target + '"],' +
- this.selector + '[href="' + target + '"]'
-
- var active = $(selector)
- .parents('li')
- .addClass('active')
-
- if (active.parent('.dropdown-menu').length) {
- active = active
- .closest('li.dropdown')
- .addClass('active')
- }
-
- active.trigger('activate.bs.scrollspy')
- }
-
- ScrollSpy.prototype.clear = function () {
- $(this.selector)
- .parentsUntil(this.options.target, '.active')
- .removeClass('active')
- }
-
-
- // SCROLLSPY PLUGIN DEFINITION
- // ===========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.scrollspy')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.scrollspy
-
- $.fn.scrollspy = Plugin
- $.fn.scrollspy.Constructor = ScrollSpy
-
-
- // SCROLLSPY NO CONFLICT
- // =====================
-
- $.fn.scrollspy.noConflict = function () {
- $.fn.scrollspy = old
- return this
- }
-
-
- // SCROLLSPY DATA-API
- // ==================
-
- $(window).on('load.bs.scrollspy.data-api', function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- Plugin.call($spy, $spy.data())
- })
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: tab.js v3.3.4
- * http://getbootstrap.com/javascript/#tabs
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // TAB CLASS DEFINITION
- // ====================
-
- var Tab = function (element) {
- this.element = $(element)
- }
-
- Tab.VERSION = '3.3.4'
-
- Tab.TRANSITION_DURATION = 150
-
- Tab.prototype.show = function () {
- var $this = this.element
- var $ul = $this.closest('ul:not(.dropdown-menu)')
- var selector = $this.data('target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- if ($this.parent('li').hasClass('active')) return
-
- var $previous = $ul.find('.active:last a')
- var hideEvent = $.Event('hide.bs.tab', {
- relatedTarget: $this[0]
- })
- var showEvent = $.Event('show.bs.tab', {
- relatedTarget: $previous[0]
- })
-
- $previous.trigger(hideEvent)
- $this.trigger(showEvent)
-
- if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
-
- var $target = $(selector)
-
- this.activate($this.closest('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $previous.trigger({
- type: 'hidden.bs.tab',
- relatedTarget: $this[0]
- })
- $this.trigger({
- type: 'shown.bs.tab',
- relatedTarget: $previous[0]
- })
- })
- }
-
- Tab.prototype.activate = function (element, container, callback) {
- var $active = container.find('> .active')
- var transition = callback
- && $.support.transition
- && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
-
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
- .end()
- .find('[data-toggle="tab"]')
- .attr('aria-expanded', false)
-
- element
- .addClass('active')
- .find('[data-toggle="tab"]')
- .attr('aria-expanded', true)
-
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
-
- if (element.parent('.dropdown-menu').length) {
- element
- .closest('li.dropdown')
- .addClass('active')
- .end()
- .find('[data-toggle="tab"]')
- .attr('aria-expanded', true)
- }
-
- callback && callback()
- }
-
- $active.length && transition ?
- $active
- .one('bsTransitionEnd', next)
- .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
- next()
-
- $active.removeClass('in')
- }
-
-
- // TAB PLUGIN DEFINITION
- // =====================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tab')
-
- if (!data) $this.data('bs.tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.tab
-
- $.fn.tab = Plugin
- $.fn.tab.Constructor = Tab
-
-
- // TAB NO CONFLICT
- // ===============
-
- $.fn.tab.noConflict = function () {
- $.fn.tab = old
- return this
- }
-
-
- // TAB DATA-API
- // ============
-
- var clickHandler = function (e) {
- e.preventDefault()
- Plugin.call($(this), 'show')
- }
-
- $(document)
- .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
- .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: affix.js v3.3.4
- * http://getbootstrap.com/javascript/#affix
- * ========================================================================
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // AFFIX CLASS DEFINITION
- // ======================
-
- var Affix = function (element, options) {
- this.options = $.extend({}, Affix.DEFAULTS, options)
-
- this.$target = $(this.options.target)
- .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
- .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
-
- this.$element = $(element)
- this.affixed = null
- this.unpin = null
- this.pinnedOffset = null
-
- this.checkPosition()
- }
-
- Affix.VERSION = '3.3.4'
-
- Affix.RESET = 'affix affix-top affix-bottom'
-
- Affix.DEFAULTS = {
- offset: 0,
- target: window
- }
-
- Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- var targetHeight = this.$target.height()
-
- if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
-
- if (this.affixed == 'bottom') {
- if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
- return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
- }
-
- var initializing = this.affixed == null
- var colliderTop = initializing ? scrollTop : position.top
- var colliderHeight = initializing ? targetHeight : height
-
- if (offsetTop != null && scrollTop <= offsetTop) return 'top'
- if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
-
- return false
- }
-
- Affix.prototype.getPinnedOffset = function () {
- if (this.pinnedOffset) return this.pinnedOffset
- this.$element.removeClass(Affix.RESET).addClass('affix')
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- return (this.pinnedOffset = position.top - scrollTop)
- }
-
- Affix.prototype.checkPositionWithEventLoop = function () {
- setTimeout($.proxy(this.checkPosition, this), 1)
- }
-
- Affix.prototype.checkPosition = function () {
- if (!this.$element.is(':visible')) return
-
- var height = this.$element.height()
- var offset = this.options.offset
- var offsetTop = offset.top
- var offsetBottom = offset.bottom
- var scrollHeight = $(document.body).height()
-
- if (typeof offset != 'object') offsetBottom = offsetTop = offset
- if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
- if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
-
- var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
-
- if (this.affixed != affix) {
- if (this.unpin != null) this.$element.css('top', '')
-
- var affixType = 'affix' + (affix ? '-' + affix : '')
- var e = $.Event(affixType + '.bs.affix')
-
- this.$element.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- this.affixed = affix
- this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
-
- this.$element
- .removeClass(Affix.RESET)
- .addClass(affixType)
- .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
- }
-
- if (affix == 'bottom') {
- this.$element.offset({
- top: scrollHeight - height - offsetBottom
- })
- }
- }
-
-
- // AFFIX PLUGIN DEFINITION
- // =======================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.affix')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.affix
-
- $.fn.affix = Plugin
- $.fn.affix.Constructor = Affix
-
-
- // AFFIX NO CONFLICT
- // =================
-
- $.fn.affix.noConflict = function () {
- $.fn.affix = old
- return this
- }
-
-
- // AFFIX DATA-API
- // ==============
-
- $(window).on('load', function () {
- $('[data-spy="affix"]').each(function () {
- var $spy = $(this)
- var data = $spy.data()
-
- data.offset = data.offset || {}
-
- if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
- if (data.offsetTop != null) data.offset.top = data.offsetTop
-
- Plugin.call($spy, data)
- })
- })
-
-}(jQuery);
diff --git a/web/js/bootstrap.min.js b/web/js/bootstrap.min.js
deleted file mode 100644
index c8f82e5..0000000
--- a/web/js/bootstrap.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Bootstrap v3.3.4 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){
-var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file
diff --git a/web/js/jquery.datetimepicker.full.js b/web/js/jquery.datetimepicker.full.js
deleted file mode 100644
index 417037c..0000000
--- a/web/js/jquery.datetimepicker.full.js
+++ /dev/null
@@ -1,3073 +0,0 @@
-/*!
- * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014 - 2015
- * @version 1.3.3
- *
- * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format.
- * @see http://php.net/manual/en/function.date.php
- *
- * For more JQuery plugins visit http://plugins.krajee.com
- * For more Yii related demos visit http://demos.krajee.com
- */
-var DateFormatter;
-(function () {
- "use strict";
-
- var _compare, _lpad, _extend, defaultSettings, DAY, HOUR;
- DAY = 1000 * 60 * 60 * 24;
- HOUR = 3600;
-
- _compare = function (str1, str2) {
- return typeof(str1) === 'string' && typeof(str2) === 'string' && str1.toLowerCase() === str2.toLowerCase();
- };
- _lpad = function (value, length, char) {
- var chr = char || '0', val = value.toString();
- return val.length < length ? _lpad(chr + val, length) : val;
- };
- _extend = function (out) {
- var i, obj;
- out = out || {};
- for (i = 1; i < arguments.length; i++) {
- obj = arguments[i];
- if (!obj) {
- continue;
- }
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if (typeof obj[key] === 'object') {
- _extend(out[key], obj[key]);
- } else {
- out[key] = obj[key];
- }
- }
- }
- }
- return out;
- };
- defaultSettings = {
- dateSettings: {
- days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
- months: [
- 'January', 'February', 'March', 'April', 'May', 'June', 'July',
- 'August', 'September', 'October', 'November', 'December'
- ],
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- meridiem: ['AM', 'PM'],
- ordinal: function (number) {
- var n = number % 10, suffixes = {1: 'st', 2: 'nd', 3: 'rd'};
- return Math.floor(number % 100 / 10) === 1 || !suffixes[n] ? 'th' : suffixes[n];
- }
- },
- separators: /[ \-+\/\.T:@]/g,
- validParts: /[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g,
- intParts: /[djwNzmnyYhHgGis]/g,
- tzParts: /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
- tzClip: /[^-+\dA-Z]/g
- };
-
- DateFormatter = function (options) {
- var self = this, config = _extend(defaultSettings, options);
- self.dateSettings = config.dateSettings;
- self.separators = config.separators;
- self.validParts = config.validParts;
- self.intParts = config.intParts;
- self.tzParts = config.tzParts;
- self.tzClip = config.tzClip;
- };
-
- DateFormatter.prototype = {
- constructor: DateFormatter,
- parseDate: function (vDate, vFormat) {
- var self = this, vFormatParts, vDateParts, i, vDateFlag = false, vTimeFlag = false, vDatePart, iDatePart,
- vSettings = self.dateSettings, vMonth, vMeriIndex, vMeriOffset, len, mer,
- out = {date: null, year: null, month: null, day: null, hour: 0, min: 0, sec: 0};
- if (!vDate) {
- return undefined;
- }
- if (vDate instanceof Date) {
- return vDate;
- }
- if (typeof vDate === 'number') {
- return new Date(vDate);
- }
- if (vFormat === 'U') {
- i = parseInt(vDate);
- return i ? new Date(i * 1000) : vDate;
- }
- if (typeof vDate !== 'string') {
- return '';
- }
- vFormatParts = vFormat.match(self.validParts);
- if (!vFormatParts || vFormatParts.length === 0) {
- throw new Error("Invalid date format definition.");
- }
- vDateParts = vDate.replace(self.separators, '\0').split('\0');
- for (i = 0; i < vDateParts.length; i++) {
- vDatePart = vDateParts[i];
- iDatePart = parseInt(vDatePart);
- switch (vFormatParts[i]) {
- case 'y':
- case 'Y':
- len = vDatePart.length;
- if (len === 2) {
- out.year = parseInt((iDatePart < 70 ? '20' : '19') + vDatePart);
- } else if (len === 4) {
- out.year = iDatePart;
- }
- vDateFlag = true;
- break;
- case 'm':
- case 'n':
- case 'M':
- case 'F':
- if (isNaN(vDatePart)) {
- vMonth = vSettings.monthsShort.indexOf(vDatePart);
- if (vMonth > -1) {
- out.month = vMonth + 1;
- }
- vMonth = vSettings.months.indexOf(vDatePart);
- if (vMonth > -1) {
- out.month = vMonth + 1;
- }
- } else {
- if (iDatePart >= 1 && iDatePart <= 12) {
- out.month = iDatePart;
- }
- }
- vDateFlag = true;
- break;
- case 'd':
- case 'j':
- if (iDatePart >= 1 && iDatePart <= 31) {
- out.day = iDatePart;
- }
- vDateFlag = true;
- break;
- case 'g':
- case 'h':
- vMeriIndex = (vFormatParts.indexOf('a') > -1) ? vFormatParts.indexOf('a') :
- (vFormatParts.indexOf('A') > -1) ? vFormatParts.indexOf('A') : -1;
- mer = vDateParts[vMeriIndex];
- if (vMeriIndex > -1) {
- vMeriOffset = _compare(mer, vSettings.meridiem[0]) ? 0 :
- (_compare(mer, vSettings.meridiem[1]) ? 12 : -1);
- if (iDatePart >= 1 && iDatePart <= 12 && vMeriOffset > -1) {
- out.hour = iDatePart + vMeriOffset - 1;
- } else if (iDatePart >= 0 && iDatePart <= 23) {
- out.hour = iDatePart;
- }
- } else if (iDatePart >= 0 && iDatePart <= 23) {
- out.hour = iDatePart;
- }
- vTimeFlag = true;
- break;
- case 'G':
- case 'H':
- if (iDatePart >= 0 && iDatePart <= 23) {
- out.hour = iDatePart;
- }
- vTimeFlag = true;
- break;
- case 'i':
- if (iDatePart >= 0 && iDatePart <= 59) {
- out.min = iDatePart;
- }
- vTimeFlag = true;
- break;
- case 's':
- if (iDatePart >= 0 && iDatePart <= 59) {
- out.sec = iDatePart;
- }
- vTimeFlag = true;
- break;
- }
- }
- if (vDateFlag === true && out.year && out.month && out.day) {
- out.date = new Date(out.year, out.month - 1, out.day, out.hour, out.min, out.sec, 0);
- } else {
- if (vTimeFlag !== true) {
- return false;
- }
- out.date = new Date(0, 0, 0, out.hour, out.min, out.sec, 0);
- }
- return out.date;
- },
- guessDate: function (vDateStr, vFormat) {
- if (typeof vDateStr !== 'string') {
- return vDateStr;
- }
- var self = this, vParts = vDateStr.replace(self.separators, '\0').split('\0'), vPattern = /^[djmn]/g,
- vFormatParts = vFormat.match(self.validParts), vDate = new Date(), vDigit = 0, vYear, i, iPart, iSec;
-
- if (!vPattern.test(vFormatParts[0])) {
- return vDateStr;
- }
-
- for (i = 0; i < vParts.length; i++) {
- vDigit = 2;
- iPart = vParts[i];
- iSec = parseInt(iPart.substr(0, 2));
- switch (i) {
- case 0:
- if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') {
- vDate.setMonth(iSec - 1);
- } else {
- vDate.setDate(iSec);
- }
- break;
- case 1:
- if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') {
- vDate.setDate(iSec);
- } else {
- vDate.setMonth(iSec - 1);
- }
- break;
- case 2:
- vYear = vDate.getFullYear();
- if (iPart.length < 4) {
- vDate.setFullYear(parseInt(vYear.toString().substr(0, 4 - iPart.length) + iPart));
- vDigit = iPart.length;
- } else {
- vDate.setFullYear = parseInt(iPart.substr(0, 4));
- vDigit = 4;
- }
- break;
- case 3:
- vDate.setHours(iSec);
- break;
- case 4:
- vDate.setMinutes(iSec);
- break;
- case 5:
- vDate.setSeconds(iSec);
- break;
- }
- if (iPart.substr(vDigit).length > 0) {
- vParts.splice(i + 1, 0, iPart.substr(vDigit));
- }
- }
- return vDate;
- },
- parseFormat: function (vChar, vDate) {
- var self = this, vSettings = self.dateSettings, fmt, backspace = /\\?(.?)/gi, doFormat = function (t, s) {
- return fmt[t] ? fmt[t]() : s;
- };
- fmt = {
- /////////
- // DAY //
- /////////
- /**
- * Day of month with leading 0: `01..31`
- * @return {string}
- */
- d: function () {
- return _lpad(fmt.j(), 2);
- },
- /**
- * Shorthand day name: `Mon...Sun`
- * @return {string}
- */
- D: function () {
- return vSettings.daysShort[fmt.w()];
- },
- /**
- * Day of month: `1..31`
- * @return {number}
- */
- j: function () {
- return vDate.getDate();
- },
- /**
- * Full day name: `Monday...Sunday`
- * @return {number}
- */
- l: function () {
- return vSettings.days[fmt.w()];
- },
- /**
- * ISO-8601 day of week: `1[Mon]..7[Sun]`
- * @return {number}
- */
- N: function () {
- return fmt.w() || 7;
- },
- /**
- * Day of week: `0[Sun]..6[Sat]`
- * @return {number}
- */
- w: function () {
- return vDate.getDay();
- },
- /**
- * Day of year: `0..365`
- * @return {number}
- */
- z: function () {
- var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j()), b = new Date(fmt.Y(), 0, 1);
- return Math.round((a - b) / DAY);
- },
-
- //////////
- // WEEK //
- //////////
- /**
- * ISO-8601 week number
- * @return {number}
- */
- W: function () {
- var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j() - fmt.N() + 3), b = new Date(a.getFullYear(), 0, 4);
- return _lpad(1 + Math.round((a - b) / DAY / 7), 2);
- },
-
- ///////////
- // MONTH //
- ///////////
- /**
- * Full month name: `January...December`
- * @return {string}
- */
- F: function () {
- return vSettings.months[vDate.getMonth()];
- },
- /**
- * Month w/leading 0: `01..12`
- * @return {string}
- */
- m: function () {
- return _lpad(fmt.n(), 2);
- },
- /**
- * Shorthand month name; `Jan...Dec`
- * @return {string}
- */
- M: function () {
- return vSettings.monthsShort[vDate.getMonth()];
- },
- /**
- * Month: `1...12`
- * @return {number}
- */
- n: function () {
- return vDate.getMonth() + 1;
- },
- /**
- * Days in month: `28...31`
- * @return {number}
- */
- t: function () {
- return (new Date(fmt.Y(), fmt.n(), 0)).getDate();
- },
-
- //////////
- // YEAR //
- //////////
- /**
- * Is leap year? `0 or 1`
- * @return {number}
- */
- L: function () {
- var Y = fmt.Y();
- return (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) ? 1 : 0;
- },
- /**
- * ISO-8601 year
- * @return {number}
- */
- o: function () {
- var n = fmt.n(), W = fmt.W(), Y = fmt.Y();
- return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
- },
- /**
- * Full year: `e.g. 1980...2010`
- * @return {number}
- */
- Y: function () {
- return vDate.getFullYear();
- },
- /**
- * Last two digits of year: `00...99`
- * @return {string}
- */
- y: function () {
- return fmt.Y().toString().slice(-2);
- },
-
- //////////
- // TIME //
- //////////
- /**
- * Meridian lower: `am or pm`
- * @return {string}
- */
- a: function () {
- return fmt.A().toLowerCase();
- },
- /**
- * Meridian upper: `AM or PM`
- * @return {string}
- */
- A: function () {
- var n = fmt.G() < 12 ? 0 : 1;
- return vSettings.meridiem[n];
- },
- /**
- * Swatch Internet time: `000..999`
- * @return {string}
- */
- B: function () {
- var H = vDate.getUTCHours() * HOUR, i = vDate.getUTCMinutes() * 60, s = vDate.getUTCSeconds();
- return _lpad(Math.floor((H + i + s + HOUR) / 86.4) % 1000, 3);
- },
- /**
- * 12-Hours: `1..12`
- * @return {number}
- */
- g: function () {
- return fmt.G() % 12 || 12;
- },
- /**
- * 24-Hours: `0..23`
- * @return {number}
- */
- G: function () {
- return vDate.getHours();
- },
- /**
- * 12-Hours with leading 0: `01..12`
- * @return {string}
- */
- h: function () {
- return _lpad(fmt.g(), 2);
- },
- /**
- * 24-Hours w/leading 0: `00..23`
- * @return {string}
- */
- H: function () {
- return _lpad(fmt.G(), 2);
- },
- /**
- * Minutes w/leading 0: `00..59`
- * @return {string}
- */
- i: function () {
- return _lpad(vDate.getMinutes(), 2);
- },
- /**
- * Seconds w/leading 0: `00..59`
- * @return {string}
- */
- s: function () {
- return _lpad(vDate.getSeconds(), 2);
- },
- /**
- * Microseconds: `000000-999000`
- * @return {string}
- */
- u: function () {
- return _lpad(vDate.getMilliseconds() * 1000, 6);
- },
-
- //////////////
- // TIMEZONE //
- //////////////
- /**
- * Timezone identifier: `e.g. Atlantic/Azores, ...`
- * @return {string}
- */
- e: function () {
- var str = /\((.*)\)/.exec(String(vDate))[1];
- return str || 'Coordinated Universal Time';
- },
- /**
- * Timezone abbreviation: `e.g. EST, MDT, ...`
- * @return {string}
- */
- T: function () {
- var str = (String(vDate).match(self.tzParts) || [""]).pop().replace(self.tzClip, "");
- return str || 'UTC';
- },
- /**
- * DST observed? `0 or 1`
- * @return {number}
- */
- I: function () {
- var a = new Date(fmt.Y(), 0), c = Date.UTC(fmt.Y(), 0),
- b = new Date(fmt.Y(), 6), d = Date.UTC(fmt.Y(), 6);
- return ((a - c) !== (b - d)) ? 1 : 0;
- },
- /**
- * Difference to GMT in hour format: `e.g. +0200`
- * @return {string}
- */
- O: function () {
- var tzo = vDate.getTimezoneOffset(), a = Math.abs(tzo);
- return (tzo > 0 ? '-' : '+') + _lpad(Math.floor(a / 60) * 100 + a % 60, 4);
- },
- /**
- * Difference to GMT with colon: `e.g. +02:00`
- * @return {string}
- */
- P: function () {
- var O = fmt.O();
- return (O.substr(0, 3) + ':' + O.substr(3, 2));
- },
- /**
- * Timezone offset in seconds: `-43200...50400`
- * @return {number}
- */
- Z: function () {
- return -vDate.getTimezoneOffset() * 60;
- },
-
- ////////////////////
- // FULL DATE TIME //
- ////////////////////
- /**
- * ISO-8601 date
- * @return {string}
- */
- c: function () {
- return 'Y-m-d\\TH:i:s'.replace(backspace, doFormat);
- },
- /**
- * RFC 2822 date
- * @return {string}
- */
- r: function () {
- return 'D, d M Y H:i:s O'.replace(backspace, doFormat);
- },
- /**
- * Seconds since UNIX epoch
- * @return {number}
- */
- U: function () {
- return vDate.getTime() / 1000 || 0;
- }
- };
- return doFormat(vChar, vChar);
- },
- formatDate: function (vDate, vFormat) {
- var self = this, i, n, len, str, vChar, vDateStr = '';
- if (typeof vDate === 'string') {
- vDate = self.parseDate(vDate, vFormat);
- if (vDate === false) {
- return false;
- }
- }
- if (vDate instanceof Date) {
- len = vFormat.length;
- for (i = 0; i < len; i++) {
- vChar = vFormat.charAt(i);
- if (vChar === 'S') {
- continue;
- }
- str = self.parseFormat(vChar, vDate);
- if (i !== (len - 1) && self.intParts.test(vChar) && vFormat.charAt(i + 1) === 'S') {
- n = parseInt(str);
- str += self.dateSettings.ordinal(n);
- }
- vDateStr += str;
- }
- return vDateStr;
- }
- return '';
- }
- };
-})();/**
- * @preserve jQuery DateTimePicker plugin v2.5.1
- * @homepage http://xdsoft.net/jqplugins/datetimepicker/
- * @author Chupurnov Valeriy (<chupurnov@gmail.com>)
- */
-/*global DateFormatter, document,window,jQuery,setTimeout,clearTimeout,HighlightedDate,getCurrentValue*/
-;(function (factory) {
- if ( typeof define === 'function' && define.amd ) {
- // AMD. Register as an anonymous module.
- define(['jquery', 'jquery-mousewheel'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS style for Browserify
- module.exports = factory;
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function ($) {
- 'use strict';
- var default_options = {
- i18n: {
- ar: { // Arabic
- months: [
- "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
- ],
- dayOfWeekShort: [
- "ن", "ث", "ع", "خ", "ج", "س", "ح"
- ],
- dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"]
- },
- ro: { // Romanian
- months: [
- "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
- ],
- dayOfWeekShort: [
- "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"
- ],
- dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"]
- },
- id: { // Indonesian
- months: [
- "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
- ],
- dayOfWeekShort: [
- "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"
- ],
- dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]
- },
- is: { // Icelandic
- months: [
- "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"
- ],
- dayOfWeekShort: [
- "Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau"
- ],
- dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"]
- },
- bg: { // Bulgarian
- months: [
- "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
- ],
- dayOfWeekShort: [
- "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
- ],
- dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"]
- },
- fa: { // Persian/Farsi
- months: [
- 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
- ],
- dayOfWeekShort: [
- 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
- ],
- dayOfWeek: ["یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه", "یک‌شنبه"]
- },
- ru: { // Russian
- months: [
- 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
- ],
- dayOfWeekShort: [
- "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
- ],
- dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]
- },
- uk: { // Ukrainian
- months: [
- 'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
- ],
- dayOfWeekShort: [
- "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
- ],
- dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"]
- },
- en: { // English
- months: [
- "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- ],
- dayOfWeekShort: [
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- ],
- dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- },
- el: { // Ελληνικά
- months: [
- "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
- ],
- dayOfWeekShort: [
- "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
- ],
- dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"]
- },
- de: { // German
- months: [
- 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
- ],
- dayOfWeekShort: [
- "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
- ],
- dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
- },
- nl: { // Dutch
- months: [
- "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
- ],
- dayOfWeekShort: [
- "zo", "ma", "di", "wo", "do", "vr", "za"
- ],
- dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
- },
- tr: { // Turkish
- months: [
- "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
- ],
- dayOfWeekShort: [
- "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
- ],
- dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
- },
- fr: { //French
- months: [
- "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
- ],
- dayOfWeekShort: [
- "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
- ],
- dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
- },
- es: { // Spanish
- months: [
- "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
- ],
- dayOfWeekShort: [
- "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
- ],
- dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
- },
- th: { // Thai
- months: [
- 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
- ],
- dayOfWeekShort: [
- 'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
- ],
- dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"]
- },
- pl: { // Polish
- months: [
- "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
- ],
- dayOfWeekShort: [
- "nd", "pn", "wt", "śr", "cz", "pt", "sb"
- ],
- dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
- },
- pt: { // Portuguese
- months: [
- "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
- ],
- dayOfWeekShort: [
- "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
- ],
- dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
- },
- ch: { // Simplified Chinese
- months: [
- "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
- ],
- dayOfWeekShort: [
- "日", "一", "二", "三", "四", "五", "六"
- ]
- },
- se: { // Swedish
- months: [
- "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
- ],
- dayOfWeekShort: [
- "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
- ]
- },
- kr: { // Korean
- months: [
- "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
- ],
- dayOfWeekShort: [
- "일", "월", "화", "수", "목", "금", "토"
- ],
- dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
- },
- it: { // Italian
- months: [
- "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
- ],
- dayOfWeekShort: [
- "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
- ],
- dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
- },
- da: { // Dansk
- months: [
- "January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December"
- ],
- dayOfWeekShort: [
- "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
- ],
- dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"]
- },
- no: { // Norwegian
- months: [
- "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
- ],
- dayOfWeekShort: [
- "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
- ],
- dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag']
- },
- ja: { // Japanese
- months: [
- "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
- ],
- dayOfWeekShort: [
- "日", "月", "火", "水", "木", "金", "土"
- ],
- dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"]
- },
- vi: { // Vietnamese
- months: [
- "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
- ],
- dayOfWeekShort: [
- "CN", "T2", "T3", "T4", "T5", "T6", "T7"
- ],
- dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
- },
- sl: { // Slovenščina
- months: [
- "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"
- ],
- dayOfWeekShort: [
- "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
- ],
- dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"]
- },
- cs: { // Čeština
- months: [
- "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
- ],
- dayOfWeekShort: [
- "Ne", "Po", "Út", "St", "Čt", "Pá", "So"
- ]
- },
- hu: { // Hungarian
- months: [
- "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
- ],
- dayOfWeekShort: [
- "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
- ],
- dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"]
- },
- az: { //Azerbaijanian (Azeri)
- months: [
- "Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
- ],
- dayOfWeekShort: [
- "B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
- ],
- dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"]
- },
- bs: { //Bosanski
- months: [
- "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
- ],
- dayOfWeekShort: [
- "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
- ],
- dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
- },
- ca: { //Català
- months: [
- "Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
- ],
- dayOfWeekShort: [
- "Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
- ],
- dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"]
- },
- 'en-GB': { //English (British)
- months: [
- "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- ],
- dayOfWeekShort: [
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- ],
- dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- },
- et: { //"Eesti"
- months: [
- "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
- ],
- dayOfWeekShort: [
- "P", "E", "T", "K", "N", "R", "L"
- ],
- dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"]
- },
- eu: { //Euskara
- months: [
- "Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
- ],
- dayOfWeekShort: [
- "Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
- ],
- dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
- },
- fi: { //Finnish (Suomi)
- months: [
- "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
- ],
- dayOfWeekShort: [
- "Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
- ],
- dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"]
- },
- gl: { //Galego
- months: [
- "Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
- ],
- dayOfWeekShort: [
- "Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
- ],
- dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"]
- },
- hr: { //Hrvatski
- months: [
- "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
- ],
- dayOfWeekShort: [
- "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
- ],
- dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
- },
- ko: { //Korean (한국어)
- months: [
- "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
- ],
- dayOfWeekShort: [
- "일", "월", "화", "수", "목", "금", "토"
- ],
- dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
- },
- lt: { //Lithuanian (lietuvių)
- months: [
- "Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
- ],
- dayOfWeekShort: [
- "Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
- ],
- dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"]
- },
- lv: { //Latvian (Latviešu)
- months: [
- "Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
- ],
- dayOfWeekShort: [
- "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
- ],
- dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"]
- },
- mk: { //Macedonian (Македонски)
- months: [
- "јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
- ],
- dayOfWeekShort: [
- "нед", "пон", "вто", "сре", "чет", "пет", "саб"
- ],
- dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"]
- },
- mn: { //Mongolian (Монгол)
- months: [
- "1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
- ],
- dayOfWeekShort: [
- "Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
- ],
- dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"]
- },
- 'pt-BR': { //Português(Brasil)
- months: [
- "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
- ],
- dayOfWeekShort: [
- "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
- ],
- dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
- },
- sk: { //Slovenčina
- months: [
- "Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
- ],
- dayOfWeekShort: [
- "Ne", "Po", "Ut", "St", "Št", "Pi", "So"
- ],
- dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"]
- },
- sq: { //Albanian (Shqip)
- months: [
- "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"
- ],
- dayOfWeekShort: [
- "Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"
- ],
- dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"]
- },
- 'sr-YU': { //Serbian (Srpski)
- months: [
- "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
- ],
- dayOfWeekShort: [
- "Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
- ],
- dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"]
- },
- sr: { //Serbian Cyrillic (Српски)
- months: [
- "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
- ],
- dayOfWeekShort: [
- "нед", "пон", "уто", "сре", "чет", "пет", "суб"
- ],
- dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"]
- },
- sv: { //Svenska
- months: [
- "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
- ],
- dayOfWeekShort: [
- "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
- ],
- dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"]
- },
- 'zh-TW': { //Traditional Chinese (繁體中文)
- months: [
- "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
- ],
- dayOfWeekShort: [
- "日", "一", "二", "三", "四", "五", "六"
- ],
- dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
- },
- zh: { //Simplified Chinese (简体中文)
- months: [
- "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
- ],
- dayOfWeekShort: [
- "日", "一", "二", "三", "四", "五", "六"
- ],
- dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
- },
- he: { //Hebrew (עברית)
- months: [
- 'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
- ],
- dayOfWeekShort: [
- 'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
- ],
- dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
- },
- hy: { // Armenian
- months: [
- "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"
- ],
- dayOfWeekShort: [
- "Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ"
- ],
- dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"]
- },
- kg: { // Kyrgyz
- months: [
- 'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
- ],
- dayOfWeekShort: [
- "Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише"
- ],
- dayOfWeek: [
- "Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб"
- ]
- },
- rm: { // Romansh
- months: [
- "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December"
- ],
- dayOfWeekShort: [
- "Du", "Gli", "Ma", "Me", "Gie", "Ve", "So"
- ],
- dayOfWeek: [
- "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
- ]
- },
- },
- value: '',
- rtl: false,
-
- format: 'Y/m/d H:i',
- formatTime: 'H:i',
- formatDate: 'Y/m/d',
-
- startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
- step: 60,
- monthChangeSpinner: true,
-
- closeOnDateSelect: false,
- closeOnTimeSelect: true,
- closeOnWithoutClick: true,
- closeOnInputClick: true,
-
- timepicker: true,
- datepicker: true,
- weeks: false,
-
- defaultTime: false, // use formatTime format (ex. '10:00' for formatTime: 'H:i')
- defaultDate: false, // use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
-
- minDate: false,
- maxDate: false,
- minTime: false,
- maxTime: false,
- disabledMinTime: false,
- disabledMaxTime: false,
-
- allowTimes: [],
- opened: false,
- initTime: true,
- inline: false,
- theme: '',
-
- onSelectDate: function () {},
- onSelectTime: function () {},
- onChangeMonth: function () {},
- onGetWeekOfYear: function () {},
- onChangeYear: function () {},
- onChangeDateTime: function () {},
- onShow: function () {},
- onClose: function () {},
- onGenerate: function () {},
-
- withoutCopyright: true,
- inverseButton: false,
- hours12: false,
- next: 'xdsoft_next',
- prev : 'xdsoft_prev',
- dayOfWeekStart: 0,
- parentID: 'body',
- timeHeightInTimePicker: 25,
- timepickerScrollbar: true,
- todayButton: true,
- prevButton: true,
- nextButton: true,
- defaultSelect: true,
-
- scrollMonth: true,
- scrollTime: true,
- scrollInput: true,
-
- lazyInit: false,
- mask: false,
- validateOnBlur: true,
- allowBlank: true,
- yearStart: 1950,
- yearEnd: 2050,
- monthStart: 0,
- monthEnd: 11,
- style: '',
- id: '',
- fixed: false,
- roundTime: 'round', // ceil, floor
- className: '',
- weekends: [],
- highlightedDates: [],
- highlightedPeriods: [],
- allowDates : [],
- allowDateRe : null,
- disabledDates : [],
- disabledWeekDays: [],
- yearOffset: 0,
- beforeShowDay: null,
-
- enterLikeTab: true,
- showApplyButton: false
- };
-
- var dateHelper = null,
- globalLocaleDefault = 'en',
- globalLocale = 'en';
-
- var dateFormatterOptionsDefault = {
- meridiem: ['AM', 'PM']
- };
-
- var initDateFormatter = function(){
- var locale = default_options.i18n[globalLocale],
- opts = {
- days: locale.dayOfWeek,
- daysShort: locale.dayOfWeekShort,
- months: locale.months,
- monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) }),
- };
-
- dateHelper = new DateFormatter({
- dateSettings: $.extend({}, dateFormatterOptionsDefault, opts)
- });
- };
-
- // for locale settings
- $.datetimepicker = {
- setLocale: function(locale){
- var newLocale = default_options.i18n[locale]?locale:globalLocaleDefault;
- if(globalLocale != newLocale){
- globalLocale = newLocale;
- // reinit date formatter
- initDateFormatter();
- }
- },
- RFC_2822: 'D, d M Y H:i:s O',
- ATOM: 'Y-m-d\TH:i:sP',
- ISO_8601: 'Y-m-d\TH:i:sO',
- RFC_822: 'D, d M y H:i:s O',
- RFC_850: 'l, d-M-y H:i:s T',
- RFC_1036: 'D, d M y H:i:s O',
- RFC_1123: 'D, d M Y H:i:s O',
- RSS: 'D, d M Y H:i:s O',
- W3C: 'Y-m-d\TH:i:sP'
- };
-
- // first init date formatter
- initDateFormatter();
-
- // fix for ie8
- if (!window.getComputedStyle) {
- window.getComputedStyle = function (el, pseudo) {
- this.el = el;
- this.getPropertyValue = function (prop) {
- var re = /(\-([a-z]){1})/g;
- if (prop === 'float') {
- prop = 'styleFloat';
- }
- if (re.test(prop)) {
- prop = prop.replace(re, function (a, b, c) {
- return c.toUpperCase();
- });
- }
- return el.currentStyle[prop] || null;
- };
- return this;
- };
- }
- if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (obj, start) {
- var i, j;
- for (i = (start || 0), j = this.length; i < j; i += 1) {
- if (this[i] === obj) { return i; }
- }
- return -1;
- };
- }
- Date.prototype.countDaysInMonth = function () {
- return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
- };
- $.fn.xdsoftScroller = function (percent) {
- return this.each(function () {
- var timeboxparent = $(this),
- pointerEventToXY = function (e) {
- var out = {x: 0, y: 0},
- touch;
- if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
- touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
- out.x = touch.clientX;
- out.y = touch.clientY;
- } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
- out.x = e.clientX;
- out.y = e.clientY;
- }
- return out;
- },
- move = 0,
- timebox,
- parentHeight,
- height,
- scrollbar,
- scroller,
- maximumOffset = 100,
- start = false,
- startY = 0,
- startTop = 0,
- h1 = 0,
- touchStart = false,
- startTopScroll = 0,
- calcOffset = function () {};
- if (percent === 'hide') {
- timeboxparent.find('.xdsoft_scrollbar').hide();
- return;
- }
- if (!$(this).hasClass('xdsoft_scroller_box')) {
- timebox = timeboxparent.children().eq(0);
- parentHeight = timeboxparent[0].clientHeight;
- height = timebox[0].offsetHeight;
- scrollbar = $('<div class="xdsoft_scrollbar"></div>');
- scroller = $('<div class="xdsoft_scroller"></div>');
- scrollbar.append(scroller);
-
- timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
- calcOffset = function calcOffset(event) {
- var offset = pointerEventToXY(event).y - startY + startTopScroll;
- if (offset < 0) {
- offset = 0;
- }
- if (offset + scroller[0].offsetHeight > h1) {
- offset = h1 - scroller[0].offsetHeight;
- }
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
- };
-
- scroller
- .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
- if (!parentHeight) {
- timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
- }
-
- startY = pointerEventToXY(event).y;
- startTopScroll = parseInt(scroller.css('margin-top'), 10);
- h1 = scrollbar[0].offsetHeight;
-
- if (event.type === 'mousedown' || event.type === 'touchstart') {
- if (document) {
- $(document.body).addClass('xdsoft_noselect');
- }
- $([document.body, window]).on('touchend mouseup.xdsoft_scroller', function arguments_callee() {
- $([document.body, window]).off('touchend mouseup.xdsoft_scroller', arguments_callee)
- .off('mousemove.xdsoft_scroller', calcOffset)
- .removeClass('xdsoft_noselect');
- });
- $(document.body).on('mousemove.xdsoft_scroller', calcOffset);
- } else {
- touchStart = true;
- event.stopPropagation();
- event.preventDefault();
- }
- })
- .on('touchmove', function (event) {
- if (touchStart) {
- event.preventDefault();
- calcOffset(event);
- }
- })
- .on('touchend touchcancel', function (event) {
- touchStart = false;
- startTopScroll = 0;
- });
-
- timeboxparent
- .on('scroll_element.xdsoft_scroller', function (event, percentage) {
- if (!parentHeight) {
- timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
- }
- percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
-
- scroller.css('margin-top', maximumOffset * percentage);
-
- setTimeout(function () {
- timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
- }, 10);
- })
- .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
- var percent, sh;
- parentHeight = timeboxparent[0].clientHeight;
- height = timebox[0].offsetHeight;
- percent = parentHeight / height;
- sh = percent * scrollbar[0].offsetHeight;
- if (percent > 1) {
- scroller.hide();
- } else {
- scroller.show();
- scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
- maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
- if (noTriggerScroll !== true) {
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
- }
- }
- });
-
- timeboxparent.on('mousewheel', function (event) {
- var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
-
- top = top - (event.deltaY * 20);
- if (top < 0) {
- top = 0;
- }
-
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
- event.stopPropagation();
- return false;
- });
-
- timeboxparent.on('touchstart', function (event) {
- start = pointerEventToXY(event);
- startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
- });
-
- timeboxparent.on('touchmove', function (event) {
- if (start) {
- event.preventDefault();
- var coord = pointerEventToXY(event);
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
- }
- });
-
- timeboxparent.on('touchend touchcancel', function (event) {
- start = false;
- startTop = 0;
- });
- }
- timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
- });
- };
-
- $.fn.datetimepicker = function (opt, opt2) {
- var result = this,
- KEY0 = 48,
- KEY9 = 57,
- _KEY0 = 96,
- _KEY9 = 105,
- CTRLKEY = 17,
- DEL = 46,
- ENTER = 13,
- ESC = 27,
- BACKSPACE = 8,
- ARROWLEFT = 37,
- ARROWUP = 38,
- ARROWRIGHT = 39,
- ARROWDOWN = 40,
- TAB = 9,
- F5 = 116,
- AKEY = 65,
- CKEY = 67,
- VKEY = 86,
- ZKEY = 90,
- YKEY = 89,
- ctrlDown = false,
- options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
-
- lazyInitTimer = 0,
- createDateTimePicker,
- destroyDateTimePicker,
-
- lazyInit = function (input) {
- input
- .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback(event) {
- if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) {
- return;
- }
- clearTimeout(lazyInitTimer);
- lazyInitTimer = setTimeout(function () {
-
- if (!input.data('xdsoft_datetimepicker')) {
- createDateTimePicker(input);
- }
- input
- .off('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback)
- .trigger('open.xdsoft');
- }, 100);
- });
- };
-
- createDateTimePicker = function (input) {
- var datetimepicker = $('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'),
- xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
- datepicker = $('<div class="xdsoft_datepicker active"></div>'),
- mounth_picker = $('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
- '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
- '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
- '<button type="button" class="xdsoft_next"></button></div>'),
- calendar = $('<div class="xdsoft_calendar"></div>'),
- timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
- timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
- timebox = $('<div class="xdsoft_time_variant"></div>'),
- applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
-
- monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
- yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
- triggerAfterOpen = false,
- XDSoft_datetime,
-
- xchangeTimer,
- timerclick,
- current_time_index,
- setPos,
- timer = 0,
- timer1 = 0,
- _xdsoft_datetime;
-
- if (options.id) {
- datetimepicker.attr('id', options.id);
- }
- if (options.style) {
- datetimepicker.attr('style', options.style);
- }
- if (options.weeks) {
- datetimepicker.addClass('xdsoft_showweeks');
- }
- if (options.rtl) {
- datetimepicker.addClass('xdsoft_rtl');
- }
-
- datetimepicker.addClass('xdsoft_' + options.theme);
- datetimepicker.addClass(options.className);
-
- mounth_picker
- .find('.xdsoft_month span')
- .after(monthselect);
- mounth_picker
- .find('.xdsoft_year span')
- .after(yearselect);
-
- mounth_picker
- .find('.xdsoft_month,.xdsoft_year')
- .on('touchstart mousedown.xdsoft', function (event) {
- var select = $(this).find('.xdsoft_select').eq(0),
- val = 0,
- top = 0,
- visible = select.is(':visible'),
- items,
- i;
-
- mounth_picker
- .find('.xdsoft_select')
- .hide();
- if (_xdsoft_datetime.currentTime) {
- val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
- }
-
- select[visible ? 'hide' : 'show']();
- for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
- if (items.eq(i).data('value') === val) {
- break;
- } else {
- top += items[0].offsetHeight;
- }
- }
-
- select.xdsoftScroller(top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
- event.stopPropagation();
- return false;
- });
-
- mounth_picker
- .find('.xdsoft_select')
- .xdsoftScroller()
- .on('touchstart mousedown.xdsoft', function (event) {
- event.stopPropagation();
- event.preventDefault();
- })
- .on('touchstart mousedown.xdsoft', '.xdsoft_option', function (event) {
- if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
- _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
- }
-
- var year = _xdsoft_datetime.currentTime.getFullYear();
- if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
- _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
- }
-
- $(this).parent().parent().hide();
-
- datetimepicker.trigger('xchange.xdsoft');
- if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
- options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
-
- if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
- options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
- });
-
- datetimepicker.getValue = function () {
- return _xdsoft_datetime.getCurrentTime();
- };
-
- datetimepicker.setOptions = function (_options) {
- var highlightedDates = {};
-
-
- options = $.extend(true, {}, options, _options);
-
- if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
- options.allowTimes = $.extend(true, [], _options.allowTimes);
- }
-
- if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
- options.weekends = $.extend(true, [], _options.weekends);
- }
-
- if (_options.allowDates && $.isArray(_options.allowDates) && _options.allowDates.length) {
- options.allowDates = $.extend(true, [], _options.allowDates);
- }
-
- if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") {
- options.allowDateRe = new RegExp(_options.allowDateRe);
- }
-
- if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) {
- $.each(_options.highlightedDates, function (index, value) {
- var splitData = $.map(value.split(','), $.trim),
- exDesc,
- hDate = new HighlightedDate(dateHelper.parseDate(splitData[0], options.formatDate), splitData[1], splitData[2]), // date, desc, style
- keyDate = dateHelper.formatDate(hDate.date, options.formatDate);
- if (highlightedDates[keyDate] !== undefined) {
- exDesc = highlightedDates[keyDate].desc;
- if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
- highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
- }
- } else {
- highlightedDates[keyDate] = hDate;
- }
- });
-
- options.highlightedDates = $.extend(true, [], highlightedDates);
- }
-
- if (_options.highlightedPeriods && $.isArray(_options.highlightedPeriods) && _options.highlightedPeriods.length) {
- highlightedDates = $.extend(true, [], options.highlightedDates);
- $.each(_options.highlightedPeriods, function (index, value) {
- var dateTest, // start date
- dateEnd,
- desc,
- hDate,
- keyDate,
- exDesc,
- style;
- if ($.isArray(value)) {
- dateTest = value[0];
- dateEnd = value[1];
- desc = value[2];
- style = value[3];
- }
- else {
- var splitData = $.map(value.split(','), $.trim);
- dateTest = dateHelper.parseDate(splitData[0], options.formatDate);
- dateEnd = dateHelper.parseDate(splitData[1], options.formatDate);
- desc = splitData[2];
- style = splitData[3];
- }
-
- while (dateTest <= dateEnd) {
- hDate = new HighlightedDate(dateTest, desc, style);
- keyDate = dateHelper.formatDate(dateTest, options.formatDate);
- dateTest.setDate(dateTest.getDate() + 1);
- if (highlightedDates[keyDate] !== undefined) {
- exDesc = highlightedDates[keyDate].desc;
- if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
- highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
- }
- } else {
- highlightedDates[keyDate] = hDate;
- }
- }
- });
-
- options.highlightedDates = $.extend(true, [], highlightedDates);
- }
-
- if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
- options.disabledDates = $.extend(true, [], _options.disabledDates);
- }
-
- if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) {
- options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
- }
-
- if ((options.open || options.opened) && (!options.inline)) {
- input.trigger('open.xdsoft');
- }
-
- if (options.inline) {
- triggerAfterOpen = true;
- datetimepicker.addClass('xdsoft_inline');
- input.after(datetimepicker).hide();
- }
-
- if (options.inverseButton) {
- options.next = 'xdsoft_prev';
- options.prev = 'xdsoft_next';
- }
-
- if (options.datepicker) {
- datepicker.addClass('active');
- } else {
- datepicker.removeClass('active');
- }
-
- if (options.timepicker) {
- timepicker.addClass('active');
- } else {
- timepicker.removeClass('active');
- }
-
- if (options.value) {
- _xdsoft_datetime.setCurrentTime(options.value);
- if (input && input.val) {
- input.val(_xdsoft_datetime.str);
- }
- }
-
- if (isNaN(options.dayOfWeekStart)) {
- options.dayOfWeekStart = 0;
- } else {
- options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
- }
-
- if (!options.timepickerScrollbar) {
- timeboxparent.xdsoftScroller('hide');
- }
-
- if (options.minDate && /^[\+\-](.*)$/.test(options.minDate)) {
- options.minDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.minDate), options.formatDate);
- }
-
- if (options.maxDate && /^[\+\-](.*)$/.test(options.maxDate)) {
- options.maxDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.maxDate), options.formatDate);
- }
-
- applyButton.toggle(options.showApplyButton);
-
- mounth_picker
- .find('.xdsoft_today_button')
- .css('visibility', !options.todayButton ? 'hidden' : 'visible');
-
- mounth_picker
- .find('.' + options.prev)
- .css('visibility', !options.prevButton ? 'hidden' : 'visible');
-
- mounth_picker
- .find('.' + options.next)
- .css('visibility', !options.nextButton ? 'hidden' : 'visible');
-
- setMask(options);
-
- if (options.validateOnBlur) {
- input
- .off('blur.xdsoft')
- .on('blur.xdsoft', function () {
- if (options.allowBlank && (!$.trim($(this).val()).length || $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_'))) {
- $(this).val(null);
- datetimepicker.data('xdsoft_datetime').empty();
- } else if (!dateHelper.parseDate($(this).val(), options.format)) {
- var splittedHours = +([$(this).val()[0], $(this).val()[1]].join('')),
- splittedMinutes = +([$(this).val()[2], $(this).val()[3]].join(''));
-
- // parse the numbers as 0312 => 03:12
- if (!options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) {
- $(this).val([splittedHours, splittedMinutes].map(function (item) {
- return item > 9 ? item : '0' + item;
- }).join(':'));
- } else {
- $(this).val(dateHelper.formatDate(_xdsoft_datetime.now(), options.format));
- }
-
- datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
- } else {
- datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
- }
-
- datetimepicker.trigger('changedatetime.xdsoft');
- datetimepicker.trigger('close.xdsoft');
- });
- }
- options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
-
- datetimepicker
- .trigger('xchange.xdsoft')
- .trigger('afterOpen.xdsoft');
- };
-
- datetimepicker
- .data('options', options)
- .on('touchstart mousedown.xdsoft', function (event) {
- event.stopPropagation();
- event.preventDefault();
- yearselect.hide();
- monthselect.hide();
- return false;
- });
-
- //scroll_element = timepicker.find('.xdsoft_time_box');
- timeboxparent.append(timebox);
- timeboxparent.xdsoftScroller();
-
- datetimepicker.on('afterOpen.xdsoft', function () {
- timeboxparent.xdsoftScroller();
- });
-
- datetimepicker
- .append(datepicker)
- .append(timepicker);
-
- if (options.withoutCopyright !== true) {
- datetimepicker
- .append(xdsoft_copyright);
- }
-
- datepicker
- .append(mounth_picker)
- .append(calendar)
- .append(applyButton);
-
- $(options.parentID)
- .append(datetimepicker);
-
- XDSoft_datetime = function () {
- var _this = this;
- _this.now = function (norecursion) {
- var d = new Date(),
- date,
- time;
-
- if (!norecursion && options.defaultDate) {
- date = _this.strToDateTime(options.defaultDate);
- d.setFullYear(date.getFullYear());
- d.setMonth(date.getMonth());
- d.setDate(date.getDate());
- }
-
- if (options.yearOffset) {
- d.setFullYear(d.getFullYear() + options.yearOffset);
- }
-
- if (!norecursion && options.defaultTime) {
- time = _this.strtotime(options.defaultTime);
- d.setHours(time.getHours());
- d.setMinutes(time.getMinutes());
- }
- return d;
- };
-
- _this.isValidDate = function (d) {
- if (Object.prototype.toString.call(d) !== "[object Date]") {
- return false;
- }
- return !isNaN(d.getTime());
- };
-
- _this.setCurrentTime = function (dTime) {
- _this.currentTime = (typeof dTime === 'string') ? _this.strToDateTime(dTime) : _this.isValidDate(dTime) ? dTime : _this.now();
- datetimepicker.trigger('xchange.xdsoft');
- };
-
- _this.empty = function () {
- _this.currentTime = null;
- };
-
- _this.getCurrentTime = function (dTime) {
- return _this.currentTime;
- };
-
- _this.nextMonth = function () {
-
- if (_this.currentTime === undefined || _this.currentTime === null) {
- _this.currentTime = _this.now();
- }
-
- var month = _this.currentTime.getMonth() + 1,
- year;
- if (month === 12) {
- _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
- month = 0;
- }
-
- year = _this.currentTime.getFullYear();
-
- _this.currentTime.setDate(
- Math.min(
- new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
- _this.currentTime.getDate()
- )
- );
- _this.currentTime.setMonth(month);
-
- if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
- options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
-
- if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
- options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
-
- datetimepicker.trigger('xchange.xdsoft');
- return month;
- };
-
- _this.prevMonth = function () {
-
- if (_this.currentTime === undefined || _this.currentTime === null) {
- _this.currentTime = _this.now();
- }
-
- var month = _this.currentTime.getMonth() - 1;
- if (month === -1) {
- _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
- month = 11;
- }
- _this.currentTime.setDate(
- Math.min(
- new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
- _this.currentTime.getDate()
- )
- );
- _this.currentTime.setMonth(month);
- if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
- options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
- datetimepicker.trigger('xchange.xdsoft');
- return month;
- };
-
- _this.getWeekOfYear = function (datetime) {
- if (options.onGetWeekOfYear && $.isFunction(options.onGetWeekOfYear)) {
- var week = options.onGetWeekOfYear.call(datetimepicker, datetime);
- if (typeof week !== 'undefined') {
- return week;
- }
- }
- var onejan = new Date(datetime.getFullYear(), 0, 1);
- //First week of the year is th one with the first Thursday according to ISO8601
- if(onejan.getDay()!=4)
- onejan.setMonth(0, 1 + ((4 - onejan.getDay()+ 7) % 7));
- return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
- };
-
- _this.strToDateTime = function (sDateTime) {
- var tmpDate = [], timeOffset, currentTime;
-
- if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
- return sDateTime;
- }
-
- tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime);
- if (tmpDate) {
- tmpDate[2] = dateHelper.parseDate(tmpDate[2], options.formatDate);
- }
- if (tmpDate && tmpDate[2]) {
- timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
- currentTime = new Date((_this.now(true)).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
- } else {
- currentTime = sDateTime ? dateHelper.parseDate(sDateTime, options.format) : _this.now();
- }
-
- if (!_this.isValidDate(currentTime)) {
- currentTime = _this.now();
- }
-
- return currentTime;
- };
-
- _this.strToDate = function (sDate) {
- if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
- return sDate;
- }
-
- var currentTime = sDate ? dateHelper.parseDate(sDate, options.formatDate) : _this.now(true);
- if (!_this.isValidDate(currentTime)) {
- currentTime = _this.now(true);
- }
- return currentTime;
- };
-
- _this.strtotime = function (sTime) {
- if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
- return sTime;
- }
- var currentTime = sTime ? dateHelper.parseDate(sTime, options.formatTime) : _this.now(true);
- if (!_this.isValidDate(currentTime)) {
- currentTime = _this.now(true);
- }
- return currentTime;
- };
-
- _this.str = function () {
- return dateHelper.formatDate(_this.currentTime, options.format);
- };
- _this.currentTime = this.now();
- };
-
- _xdsoft_datetime = new XDSoft_datetime();
-
- applyButton.on('touchend click', function (e) {//pathbrite
- e.preventDefault();
- datetimepicker.data('changed', true);
- _xdsoft_datetime.setCurrentTime(getCurrentValue());
- input.val(_xdsoft_datetime.str());
- datetimepicker.trigger('close.xdsoft');
- });
- mounth_picker
- .find('.xdsoft_today_button')
- .on('touchend mousedown.xdsoft', function () {
- datetimepicker.data('changed', true);
- _xdsoft_datetime.setCurrentTime(0);
- datetimepicker.trigger('afterOpen.xdsoft');
- }).on('dblclick.xdsoft', function () {
- var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate;
- currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
- minDate = _xdsoft_datetime.strToDate(options.minDate);
- minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
- if (currentDate < minDate) {
- return;
- }
- maxDate = _xdsoft_datetime.strToDate(options.maxDate);
- maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
- if (currentDate > maxDate) {
- return;
- }
- input.val(_xdsoft_datetime.str());
- input.trigger('change');
- datetimepicker.trigger('close.xdsoft');
- });
- mounth_picker
- .find('.xdsoft_prev,.xdsoft_next')
- .on('touchend mousedown.xdsoft', function () {
- var $this = $(this),
- timer = 0,
- stop = false;
-
- (function arguments_callee1(v) {
- if ($this.hasClass(options.next)) {
- _xdsoft_datetime.nextMonth();
- } else if ($this.hasClass(options.prev)) {
- _xdsoft_datetime.prevMonth();
- }
- if (options.monthChangeSpinner) {
- if (!stop) {
- timer = setTimeout(arguments_callee1, v || 100);
- }
- }
- }(500));
-
- $([document.body, window]).on('touchend mouseup.xdsoft', function arguments_callee2() {
- clearTimeout(timer);
- stop = true;
- $([document.body, window]).off('touchend mouseup.xdsoft', arguments_callee2);
- });
- });
-
- timepicker
- .find('.xdsoft_prev,.xdsoft_next')
- .on('touchend mousedown.xdsoft', function () {
- var $this = $(this),
- timer = 0,
- stop = false,
- period = 110;
- (function arguments_callee4(v) {
- var pheight = timeboxparent[0].clientHeight,
- height = timebox[0].offsetHeight,
- top = Math.abs(parseInt(timebox.css('marginTop'), 10));
- if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
- timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
- } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
- timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
- }
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox.css('marginTop'), 10) / (height - pheight))]);
- period = (period > 10) ? 10 : period - 10;
- if (!stop) {
- timer = setTimeout(arguments_callee4, v || period);
- }
- }(500));
- $([document.body, window]).on('touchend mouseup.xdsoft', function arguments_callee5() {
- clearTimeout(timer);
- stop = true;
- $([document.body, window])
- .off('touchend mouseup.xdsoft', arguments_callee5);
- });
- });
-
- xchangeTimer = 0;
- // base handler - generating a calendar and timepicker
- datetimepicker
- .on('xchange.xdsoft', function (event) {
- clearTimeout(xchangeTimer);
- xchangeTimer = setTimeout(function () {
-
- if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
- _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
- }
-
- var table = '',
- start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
- i = 0,
- j,
- today = _xdsoft_datetime.now(),
- maxDate = false,
- minDate = false,
- hDate,
- day,
- d,
- y,
- m,
- w,
- classes = [],
- customDateSettings,
- newRow = true,
- time = '',
- h = '',
- line_time,
- description;
-
- while (start.getDay() !== options.dayOfWeekStart) {
- start.setDate(start.getDate() - 1);
- }
-
- table += '<table><thead><tr>';
-
- if (options.weeks) {
- table += '<th></th>';
- }
-
- for (j = 0; j < 7; j += 1) {
- table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>';
- }
-
- table += '</tr></thead>';
- table += '<tbody>';
-
- if (options.maxDate !== false) {
- maxDate = _xdsoft_datetime.strToDate(options.maxDate);
- maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
- }
-
- if (options.minDate !== false) {
- minDate = _xdsoft_datetime.strToDate(options.minDate);
- minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
- }
-
- while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
- classes = [];
- i += 1;
-
- day = start.getDay();
- d = start.getDate();
- y = start.getFullYear();
- m = start.getMonth();
- w = _xdsoft_datetime.getWeekOfYear(start);
- description = '';
-
- classes.push('xdsoft_date');
-
- if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
- customDateSettings = options.beforeShowDay.call(datetimepicker, start);
- } else {
- customDateSettings = null;
- }
-
- if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){
- if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){
- classes.push('xdsoft_disabled');
- }
- } else if(options.allowDates && options.allowDates.length>0){
- if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){
- classes.push('xdsoft_disabled');
- }
- } else if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
- classes.push('xdsoft_disabled');
- } else if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
- classes.push('xdsoft_disabled');
- } else if (options.disabledWeekDays.indexOf(day) !== -1) {
- classes.push('xdsoft_disabled');
- }
-
- if (customDateSettings && customDateSettings[1] !== "") {
- classes.push(customDateSettings[1]);
- }
-
- if (_xdsoft_datetime.currentTime.getMonth() !== m) {
- classes.push('xdsoft_other_month');
- }
-
- if ((options.defaultSelect || datetimepicker.data('changed')) && dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
- classes.push('xdsoft_current');
- }
-
- if (dateHelper.formatDate(today, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
- classes.push('xdsoft_today');
- }
-
- if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
- classes.push('xdsoft_weekend');
- }
-
- if (options.highlightedDates[dateHelper.formatDate(start, options.formatDate)] !== undefined) {
- hDate = options.highlightedDates[dateHelper.formatDate(start, options.formatDate)];
- classes.push(hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style);
- description = hDate.desc === undefined ? '' : hDate.desc;
- }
-
- if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
- classes.push(options.beforeShowDay(start));
- }
-
- if (newRow) {
- table += '<tr>';
- newRow = false;
- if (options.weeks) {
- table += '<th>' + w + '</th>';
- }
- }
-
- table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '" title="' + description + '">' +
- '<div>' + d + '</div>' +
- '</td>';
-
- if (start.getDay() === options.dayOfWeekStartPrev) {
- table += '</tr>';
- newRow = true;
- }
-
- start.setDate(d + 1);
- }
- table += '</tbody></table>';
-
- calendar.html(table);
-
- mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()]);
- mounth_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear());
-
- // generate timebox
- time = '';
- h = '';
- m = '';
-
- line_time = function line_time(h, m) {
- var now = _xdsoft_datetime.now(), optionDateTime, current_time,
- isALlowTimesInit = options.allowTimes && $.isArray(options.allowTimes) && options.allowTimes.length;
- now.setHours(h);
- h = parseInt(now.getHours(), 10);
- now.setMinutes(m);
- m = parseInt(now.getMinutes(), 10);
- optionDateTime = new Date(_xdsoft_datetime.currentTime);
- optionDateTime.setHours(h);
- optionDateTime.setMinutes(m);
- classes = [];
- if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || (options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) {
- classes.push('xdsoft_disabled');
- }
- if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime(options.disabledMinTime).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime(options.disabledMaxTime).getTime()))) {
- classes.push('xdsoft_disabled');
- }
-
- current_time = new Date(_xdsoft_datetime.currentTime);
- current_time.setHours(parseInt(_xdsoft_datetime.currentTime.getHours(), 10));
-
- if (!isALlowTimesInit) {
- current_time.setMinutes(Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step);
- }
-
- if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && current_time.getHours() === parseInt(h, 10) && ((!isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt(m, 10))) {
- if (options.defaultSelect || datetimepicker.data('changed')) {
- classes.push('xdsoft_current');
- } else if (options.initTime) {
- classes.push('xdsoft_init_time');
- }
- }
- if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
- classes.push('xdsoft_today');
- }
- time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate(now, options.formatTime) + '</div>';
- };
-
- if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
- for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
- for (j = 0; j < 60; j += options.step) {
- h = (i < 10 ? '0' : '') + i;
- m = (j < 10 ? '0' : '') + j;
- line_time(h, m);
- }
- }
- } else {
- for (i = 0; i < options.allowTimes.length; i += 1) {
- h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
- m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
- line_time(h, m);
- }
- }
-
- timebox.html(time);
-
- opt = '';
- i = 0;
-
- for (i = parseInt(options.yearStart, 10) + options.yearOffset; i <= parseInt(options.yearEnd, 10) + options.yearOffset; i += 1) {
- opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + i + '</div>';
- }
- yearselect.children().eq(0)
- .html(opt);
-
- for (i = parseInt(options.monthStart, 10), opt = ''; i <= parseInt(options.monthEnd, 10); i += 1) {
- opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>';
- }
- monthselect.children().eq(0).html(opt);
- $(datetimepicker)
- .trigger('generate.xdsoft');
- }, 10);
- event.stopPropagation();
- })
- .on('afterOpen.xdsoft', function () {
- if (options.timepicker) {
- var classType, pheight, height, top;
- if (timebox.find('.xdsoft_current').length) {
- classType = '.xdsoft_current';
- } else if (timebox.find('.xdsoft_init_time').length) {
- classType = '.xdsoft_init_time';
- }
- if (classType) {
- pheight = timeboxparent[0].clientHeight;
- height = timebox[0].offsetHeight;
- top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
- if ((height - pheight) < top) {
- top = height - pheight;
- }
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
- } else {
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
- }
- }
- });
-
- timerclick = 0;
- calendar
- .on('touchend click.xdsoft', 'td', function (xdevent) {
- xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
- timerclick += 1;
- var $this = $(this),
- currentTime = _xdsoft_datetime.currentTime;
-
- if (currentTime === undefined || currentTime === null) {
- _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
- currentTime = _xdsoft_datetime.currentTime;
- }
-
- if ($this.hasClass('xdsoft_disabled')) {
- return false;
- }
-
- currentTime.setDate(1);
- currentTime.setFullYear($this.data('year'));
- currentTime.setMonth($this.data('month'));
- currentTime.setDate($this.data('date'));
-
- datetimepicker.trigger('select.xdsoft', [currentTime]);
-
- input.val(_xdsoft_datetime.str());
-
- if (options.onSelectDate && $.isFunction(options.onSelectDate)) {
- options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
- }
-
- datetimepicker.data('changed', true);
- datetimepicker.trigger('xchange.xdsoft');
- datetimepicker.trigger('changedatetime.xdsoft');
- if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && !options.timepicker))) && !options.inline) {
- datetimepicker.trigger('close.xdsoft');
- }
- setTimeout(function () {
- timerclick = 0;
- }, 200);
- });
-
- timebox
- .on('touchend click.xdsoft', 'div', function (xdevent) {
- xdevent.stopPropagation();
- var $this = $(this),
- currentTime = _xdsoft_datetime.currentTime;
-
- if (currentTime === undefined || currentTime === null) {
- _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
- currentTime = _xdsoft_datetime.currentTime;
- }
-
- if ($this.hasClass('xdsoft_disabled')) {
- return false;
- }
- currentTime.setHours($this.data('hour'));
- currentTime.setMinutes($this.data('minute'));
- datetimepicker.trigger('select.xdsoft', [currentTime]);
-
- datetimepicker.data('input').val(_xdsoft_datetime.str());
-
- if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
- options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
- }
- datetimepicker.data('changed', true);
- datetimepicker.trigger('xchange.xdsoft');
- datetimepicker.trigger('changedatetime.xdsoft');
- if (options.inline !== true && options.closeOnTimeSelect === true) {
- datetimepicker.trigger('close.xdsoft');
- }
- });
-
-
- datepicker
- .on('mousewheel.xdsoft', function (event) {
- if (!options.scrollMonth) {
- return true;
- }
- if (event.deltaY < 0) {
- _xdsoft_datetime.nextMonth();
- } else {
- _xdsoft_datetime.prevMonth();
- }
- return false;
- });
-
- input
- .on('mousewheel.xdsoft', function (event) {
- if (!options.scrollInput) {
- return true;
- }
- if (!options.datepicker && options.timepicker) {
- current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
- if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
- current_time_index += event.deltaY;
- }
- if (timebox.children().eq(current_time_index).length) {
- timebox.children().eq(current_time_index).trigger('mousedown');
- }
- return false;
- }
- if (options.datepicker && !options.timepicker) {
- datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
- if (input.val) {
- input.val(_xdsoft_datetime.str());
- }
- datetimepicker.trigger('changedatetime.xdsoft');
- return false;
- }
- });
-
- datetimepicker
- .on('changedatetime.xdsoft', function (event) {
- if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
- var $input = datetimepicker.data('input');
- options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
- delete options.value;
- $input.trigger('change');
- }
- })
- .on('generate.xdsoft', function () {
- if (options.onGenerate && $.isFunction(options.onGenerate)) {
- options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
- }
- if (triggerAfterOpen) {
- datetimepicker.trigger('afterOpen.xdsoft');
- triggerAfterOpen = false;
- }
- })
- .on('click.xdsoft', function (xdevent) {
- xdevent.stopPropagation();
- });
-
- current_time_index = 0;
-
- setPos = function () {
- /**
- * 修复输入框在window最右边,且输入框的宽度小于日期控件宽度情况下,日期控件显示不全的bug。
- * Bug fixed - The datetimepicker will overflow-y when the width of the date input less than its, which
- * could causes part of the datetimepicker being hidden.
- * by Soon start
- */
- var offset = datetimepicker.data('input').offset(),
- datetimepickerelement = datetimepicker.data('input')[0],
- top = offset.top + datetimepickerelement.offsetHeight - 1,
- left = offset.left,
- position = "absolute",
- node;
-
- if ((document.documentElement.clientWidth - offset.left) < datepicker.parent().outerWidth(true)) {
- var diff = datepicker.parent().outerWidth(true) - datetimepickerelement.offsetWidth;
- left = left - diff;
- }
- /**
- * by Soon end
- */
- if (datetimepicker.data('input').parent().css('direction') == 'rtl')
- left -= (datetimepicker.outerWidth() - datetimepicker.data('input').outerWidth());
- if (options.fixed) {
- top -= $(window).scrollTop();
- left -= $(window).scrollLeft();
- position = "fixed";
- } else {
- if (top + datetimepickerelement.offsetHeight > $(window).height() + $(window).scrollTop()) {
- top = offset.top - datetimepickerelement.offsetHeight + 1;
- }
- if (top < 0) {
- top = 0;
- }
- if (left + datetimepickerelement.offsetWidth > $(window).width()) {
- left = $(window).width() - datetimepickerelement.offsetWidth;
- }
- }
-
- node = datetimepicker[0];
- do {
- node = node.parentNode;
- if (window.getComputedStyle(node).getPropertyValue('position') === 'relative' && $(window).width() >= node.offsetWidth) {
- left = left - (($(window).width() - node.offsetWidth) / 2);
- break;
- }
- } while (node.nodeName !== 'HTML');
- datetimepicker.css({
- left: left,
- top: top,
- position: position
- });
- };
- datetimepicker
- .on('open.xdsoft', function (event) {
- var onShow = true;
- if (options.onShow && $.isFunction(options.onShow)) {
- onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
- }
- if (onShow !== false) {
- datetimepicker.show();
- setPos();
- $(window)
- .off('resize.xdsoft', setPos)
- .on('resize.xdsoft', setPos);
-
- if (options.closeOnWithoutClick) {
- $([document.body, window]).on('touchstart mousedown.xdsoft', function arguments_callee6() {
- datetimepicker.trigger('close.xdsoft');
- $([document.body, window]).off('touchstart mousedown.xdsoft', arguments_callee6);
- });
- }
- }
- })
- .on('close.xdsoft', function (event) {
- var onClose = true;
- mounth_picker
- .find('.xdsoft_month,.xdsoft_year')
- .find('.xdsoft_select')
- .hide();
- if (options.onClose && $.isFunction(options.onClose)) {
- onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
- }
- if (onClose !== false && !options.opened && !options.inline) {
- datetimepicker.hide();
- }
- event.stopPropagation();
- })
- .on('toggle.xdsoft', function (event) {
- if (datetimepicker.is(':visible')) {
- datetimepicker.trigger('close.xdsoft');
- } else {
- datetimepicker.trigger('open.xdsoft');
- }
- })
- .data('input', input);
-
- timer = 0;
- timer1 = 0;
-
- datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
- datetimepicker.setOptions(options);
-
- function getCurrentValue() {
- var ct = false, time;
-
- if (options.startDate) {
- ct = _xdsoft_datetime.strToDate(options.startDate);
- } else {
- ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
- if (ct) {
- ct = _xdsoft_datetime.strToDateTime(ct);
- } else if (options.defaultDate) {
- ct = _xdsoft_datetime.strToDateTime(options.defaultDate);
- if (options.defaultTime) {
- time = _xdsoft_datetime.strtotime(options.defaultTime);
- ct.setHours(time.getHours());
- ct.setMinutes(time.getMinutes());
- }
- }
- }
-
- if (ct && _xdsoft_datetime.isValidDate(ct)) {
- datetimepicker.data('changed', true);
- } else {
- ct = '';
- }
-
- return ct || 0;
- }
-
- function setMask(options) {
-
- var isValidValue = function (mask, value) {
- var reg = mask
- .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
- .replace(/_/g, '{digit+}')
- .replace(/([0-9]{1})/g, '{digit$1}')
- .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
- .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
- return (new RegExp(reg)).test(value);
- },
- getCaretPos = function (input) {
- try {
- if (document.selection && document.selection.createRange) {
- var range = document.selection.createRange();
- return range.getBookmark().charCodeAt(2) - 2;
- }
- if (input.setSelectionRange) {
- return input.selectionStart;
- }
- } catch (e) {
- return 0;
- }
- },
- setCaretPos = function (node, pos) {
- node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node;
- if (!node) {
- return false;
- }
- if (node.createTextRange) {
- var textRange = node.createTextRange();
- textRange.collapse(true);
- textRange.moveEnd('character', pos);
- textRange.moveStart('character', pos);
- textRange.select();
- return true;
- }
- if (node.setSelectionRange) {
- node.setSelectionRange(pos, pos);
- return true;
- }
- return false;
- };
- if(options.mask) {
- input.off('keydown.xdsoft');
- }
- if (options.mask === true) {
- if (typeof moment != 'undefined') {
- options.mask = options.format
- .replace(/Y{4}/g, '9999')
- .replace(/Y{2}/g, '99')
- .replace(/M{2}/g, '19')
- .replace(/D{2}/g, '39')
- .replace(/H{2}/g, '29')
- .replace(/m{2}/g, '59')
- .replace(/s{2}/g, '59');
- } else {
- options.mask = options.format
- .replace(/Y/g, '9999')
- .replace(/F/g, '9999')
- .replace(/m/g, '19')
- .replace(/d/g, '39')
- .replace(/H/g, '29')
- .replace(/i/g, '59')
- .replace(/s/g, '59');
- }
- }
-
- if ($.type(options.mask) === 'string') {
- if (!isValidValue(options.mask, input.val())) {
- input.val(options.mask.replace(/[0-9]/g, '_'));
- setCaretPos(input[0], 0);
- }
-
- input.on('keydown.xdsoft', function (event) {
- var val = this.value,
- key = event.which,
- pos,
- digit;
-
- if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
- pos = getCaretPos(this);
- digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
-
- if ((key === BACKSPACE || key === DEL) && pos) {
- pos -= 1;
- digit = '_';
- }
-
- while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
- pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
- }
-
- val = val.substr(0, pos) + digit + val.substr(pos + 1);
- if ($.trim(val) === '') {
- val = options.mask.replace(/[0-9]/g, '_');
- } else {
- if (pos === options.mask.length) {
- event.preventDefault();
- return false;
- }
- }
-
- pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
- while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
- pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
- }
-
- if (isValidValue(options.mask, val)) {
- this.value = val;
- setCaretPos(this, pos);
- } else if ($.trim(val) === '') {
- this.value = options.mask.replace(/[0-9]/g, '_');
- } else {
- input.trigger('error_input.xdsoft');
- }
- } else {
- if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
- return true;
- }
- }
-
- event.preventDefault();
- return false;
- });
- }
- }
-
- _xdsoft_datetime.setCurrentTime(getCurrentValue());
-
- input
- .data('xdsoft_datetimepicker', datetimepicker)
- .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function (event) {
- if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
- return;
- }
- clearTimeout(timer);
- timer = setTimeout(function () {
- if (input.is(':disabled')) {
- return;
- }
-
- triggerAfterOpen = true;
- _xdsoft_datetime.setCurrentTime(getCurrentValue());
- if(options.mask) {
- setMask(options);
- }
- datetimepicker.trigger('open.xdsoft');
- }, 100);
- })
- .on('keydown.xdsoft', function (event) {
- var val = this.value, elementSelector,
- key = event.which;
- if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
- elementSelector = $("input:visible,textarea:visible,button:visible,a:visible");
- datetimepicker.trigger('close.xdsoft');
- elementSelector.eq(elementSelector.index(this) + 1).focus();
- return false;
- }
- if ([TAB].indexOf(key) !== -1) {
- datetimepicker.trigger('close.xdsoft');
- return true;
- }
- })
- .on('blur.xdsoft', function () {
- datetimepicker.trigger('close.xdsoft');
- });
- };
- destroyDateTimePicker = function (input) {
- var datetimepicker = input.data('xdsoft_datetimepicker');
- if (datetimepicker) {
- datetimepicker.data('xdsoft_datetime', null);
- datetimepicker.remove();
- input
- .data('xdsoft_datetimepicker', null)
- .off('.xdsoft');
- $(window).off('resize.xdsoft');
- $([window, document.body]).off('mousedown.xdsoft touchstart');
- if (input.unmousewheel) {
- input.unmousewheel();
- }
- }
- };
- $(document)
- .off('keydown.xdsoftctrl keyup.xdsoftctrl')
- .on('keydown.xdsoftctrl', function (e) {
- if (e.keyCode === CTRLKEY) {
- ctrlDown = true;
- }
- })
- .on('keyup.xdsoftctrl', function (e) {
- if (e.keyCode === CTRLKEY) {
- ctrlDown = false;
- }
- });
-
- this.each(function () {
- var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input;
- if (datetimepicker) {
- if ($.type(opt) === 'string') {
- switch (opt) {
- case 'show':
- $(this).select().focus();
- datetimepicker.trigger('open.xdsoft');
- break;
- case 'hide':
- datetimepicker.trigger('close.xdsoft');
- break;
- case 'toggle':
- datetimepicker.trigger('toggle.xdsoft');
- break;
- case 'destroy':
- destroyDateTimePicker($(this));
- break;
- case 'reset':
- this.value = this.defaultValue;
- if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(dateHelper.parseDate(this.value, options.format))) {
- datetimepicker.data('changed', false);
- }
- datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
- break;
- case 'validate':
- $input = datetimepicker.data('input');
- $input.trigger('blur.xdsoft');
- break;
- default:
- if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
- result = datetimepicker[opt](opt2);
- }
- }
- } else {
- datetimepicker
- .setOptions(opt);
- }
- return 0;
- }
- if ($.type(opt) !== 'string') {
- if (!options.lazyInit || options.open || options.inline) {
- createDateTimePicker($(this));
- } else {
- lazyInit($(this));
- }
- }
- });
-
- return result;
- };
- $.fn.datetimepicker.defaults = default_options;
-
- function HighlightedDate(date, desc, style) {
- "use strict";
- this.date = date;
- this.desc = desc;
- this.style = style;
- }
-
-}));
-/*!
- * jQuery Mousewheel 3.1.13
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- */
-
-(function (factory) {
- if ( typeof define === 'function' && define.amd ) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS style for Browserify
- module.exports = factory;
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function ($) {
-
- var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
- toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
- ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
- slice = Array.prototype.slice,
- nullLowestDeltaTimeout, lowestDelta;
-
- if ( $.event.fixHooks ) {
- for ( var i = toFix.length; i; ) {
- $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
- }
- }
-
- var special = $.event.special.mousewheel = {
- version: '3.1.12',
-
- setup: function() {
- if ( this.addEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.addEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = handler;
- }
- // Store the line height and page height for this particular element
- $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
- $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
- },
-
- teardown: function() {
- if ( this.removeEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.removeEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = null;
- }
- // Clean up the data we added to the element
- $.removeData(this, 'mousewheel-line-height');
- $.removeData(this, 'mousewheel-page-height');
- },
-
- getLineHeight: function(elem) {
- var $elem = $(elem),
- $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
- if (!$parent.length) {
- $parent = $('body');
- }
- return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
- },
-
- getPageHeight: function(elem) {
- return $(elem).height();
- },
-
- settings: {
- adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
- normalizeOffset: true // calls getBoundingClientRect for each event
- }
- };
-
- $.fn.extend({
- mousewheel: function(fn) {
- return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
- },
-
- unmousewheel: function(fn) {
- return this.unbind('mousewheel', fn);
- }
- });
-
-
- function handler(event) {
- var orgEvent = event || window.event,
- args = slice.call(arguments, 1),
- delta = 0,
- deltaX = 0,
- deltaY = 0,
- absDelta = 0,
- offsetX = 0,
- offsetY = 0;
- event = $.event.fix(orgEvent);
- event.type = 'mousewheel';
-
- // Old school scrollwheel delta
- if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
- if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
- if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
- if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
-
- // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
- if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
- deltaX = deltaY * -1;
- deltaY = 0;
- }
-
- // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
- delta = deltaY === 0 ? deltaX : deltaY;
-
- // New school wheel delta (wheel event)
- if ( 'deltaY' in orgEvent ) {
- deltaY = orgEvent.deltaY * -1;
- delta = deltaY;
- }
- if ( 'deltaX' in orgEvent ) {
- deltaX = orgEvent.deltaX;
- if ( deltaY === 0 ) { delta = deltaX * -1; }
- }
-
- // No change actually happened, no reason to go any further
- if ( deltaY === 0 && deltaX === 0 ) { return; }
-
- // Need to convert lines and pages to pixels if we aren't already in pixels
- // There are three delta modes:
- // * deltaMode 0 is by pixels, nothing to do
- // * deltaMode 1 is by lines
- // * deltaMode 2 is by pages
- if ( orgEvent.deltaMode === 1 ) {
- var lineHeight = $.data(this, 'mousewheel-line-height');
- delta *= lineHeight;
- deltaY *= lineHeight;
- deltaX *= lineHeight;
- } else if ( orgEvent.deltaMode === 2 ) {
- var pageHeight = $.data(this, 'mousewheel-page-height');
- delta *= pageHeight;
- deltaY *= pageHeight;
- deltaX *= pageHeight;
- }
-
- // Store lowest absolute delta to normalize the delta values
- absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
-
- if ( !lowestDelta || absDelta < lowestDelta ) {
- lowestDelta = absDelta;
-
- // Adjust older deltas if necessary
- if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
- lowestDelta /= 40;
- }
- }
-
- // Adjust older deltas if necessary
- if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
- // Divide all the things by 40!
- delta /= 40;
- deltaX /= 40;
- deltaY /= 40;
- }
-
- // Get a whole, normalized value for the deltas
- delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
- deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
- deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
-
- // Normalise offsetX and offsetY properties
- if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
- var boundingRect = this.getBoundingClientRect();
- offsetX = event.clientX - boundingRect.left;
- offsetY = event.clientY - boundingRect.top;
- }
-
- // Add information to the event object
- event.deltaX = deltaX;
- event.deltaY = deltaY;
- event.deltaFactor = lowestDelta;
- event.offsetX = offsetX;
- event.offsetY = offsetY;
- // Go ahead and set deltaMode to 0 since we converted to pixels
- // Although this is a little odd since we overwrite the deltaX/Y
- // properties with normalized deltas.
- event.deltaMode = 0;
-
- // Add event and delta to the front of the arguments
- args.unshift(event, delta, deltaX, deltaY);
-
- // Clearout lowestDelta after sometime to better
- // handle multiple device types that give different
- // a different lowestDelta
- // Ex: trackpad = 3 and mouse wheel = 120
- if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
- nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
-
- return ($.event.dispatch || $.event.handle).apply(this, args);
- }
-
- function nullLowestDelta() {
- lowestDelta = null;
- }
-
- function shouldAdjustOldDeltas(orgEvent, absDelta) {
- // If this is an older event and the delta is divisable by 120,
- // then we are assuming that the browser is treating this as an
- // older mouse wheel event and that we should divide the deltas
- // by 40 to try and get a more usable deltaFactor.
- // Side note, this actually impacts the reported scroll distance
- // in older browsers and can cause scrolling to be slower than native.
- // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
- return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
- }
-
-}));
-
-$(document).ready(function(){
- $.datetimepicker.setLocale('en');
-});
diff --git a/web/js/jquery.min.js b/web/js/jquery.min.js
deleted file mode 100644
index e6a051d..0000000
--- a/web/js/jquery.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=mb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=nb(b);function qb(){}qb.prototype=d.filters=d.pseudos,d.setFilters=new qb,g=gb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?gb.error(a):z(a,i).slice(0)};function rb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
-return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)
-}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/web/js/moment.min.js b/web/js/moment.min.js
deleted file mode 100644
index 25fa625..0000000
--- a/web/js/moment.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-//! moment.js
-//! version : 2.18.1
-//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
-//! license : MIT
-//! momentjs.com
-!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return sd.apply(null,arguments)}function b(a){sd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)return!1;return!0}function f(a){return void 0===a}function g(a){return"number"==typeof a||"[object Number]"===Object.prototype.toString.call(a)}function h(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function i(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function j(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function k(a,b){for(var c in b)j(b,c)&&(a[c]=b[c]);return j(b,"toString")&&(a.toString=b.toString),j(b,"valueOf")&&(a.valueOf=b.valueOf),a}function l(a,b,c,d){return sb(a,b,c,d,!0).utc()}function m(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function n(a){return null==a._pf&&(a._pf=m()),a._pf}function o(a){if(null==a._isValid){var b=n(a),c=ud.call(b.parsedDateParts,function(a){return null!=a}),d=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c);if(a._strict&&(d=d&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour),null!=Object.isFrozen&&Object.isFrozen(a))return d;a._isValid=d}return a._isValid}function p(a){var b=l(NaN);return null!=a?k(n(b),a):n(b).userInvalidated=!0,b}function q(a,b){var c,d,e;if(f(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),f(b._i)||(a._i=b._i),f(b._f)||(a._f=b._f),f(b._l)||(a._l=b._l),f(b._strict)||(a._strict=b._strict),f(b._tzm)||(a._tzm=b._tzm),f(b._isUTC)||(a._isUTC=b._isUTC),f(b._offset)||(a._offset=b._offset),f(b._pf)||(a._pf=n(b)),f(b._locale)||(a._locale=b._locale),vd.length>0)for(c=0;c<vd.length;c++)d=vd[c],e=b[d],f(e)||(a[d]=e);return a}function r(b){q(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),wd===!1&&(wd=!0,a.updateOffset(this),wd=!1)}function s(a){return a instanceof r||null!=a&&null!=a._isAMomentObject}function t(a){return a<0?Math.ceil(a)||0:Math.floor(a)}function u(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=t(b)),c}function v(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;d<e;d++)(c&&a[d]!==b[d]||!c&&u(a[d])!==u(b[d]))&&g++;return g+f}function w(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function x(b,c){var d=!0;return k(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,b),d){for(var e,f=[],g=0;g<arguments.length;g++){if(e="","object"==typeof arguments[g]){e+="\n["+g+"] ";for(var h in arguments[0])e+=h+": "+arguments[0][h]+", ";e=e.slice(0,-2)}else e=arguments[g];f.push(e)}w(b+"\nArguments: "+Array.prototype.slice.call(f).join("")+"\n"+(new Error).stack),d=!1}return c.apply(this,arguments)},c)}function y(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),xd[b]||(w(c),xd[b]=!0)}function z(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function A(a){var b,c;for(c in a)b=a[c],z(b)?this[c]=b:this["_"+c]=b;this._config=a,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function B(a,b){var c,e=k({},a);for(c in b)j(b,c)&&(d(a[c])&&d(b[c])?(e[c]={},k(e[c],a[c]),k(e[c],b[c])):null!=b[c]?e[c]=b[c]:delete e[c]);for(c in a)j(a,c)&&!j(b,c)&&d(a[c])&&(e[c]=k({},e[c]));return e}function C(a){null!=a&&this.set(a)}function D(a,b,c){var d=this._calendar[a]||this._calendar.sameElse;return z(d)?d.call(b,c):d}function E(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function F(){return this._invalidDate}function G(a){return this._ordinal.replace("%d",a)}function H(a,b,c,d){var e=this._relativeTime[c];return z(e)?e(a,b,c,d):e.replace(/%d/i,a)}function I(a,b){var c=this._relativeTime[a>0?"future":"past"];return z(c)?c(b):c.replace(/%s/i,b)}function J(a,b){var c=a.toLowerCase();Hd[c]=Hd[c+"s"]=Hd[b]=a}function K(a){return"string"==typeof a?Hd[a]||Hd[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)j(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(a,b){Id[a]=b}function N(a){var b=[];for(var c in a)b.push({unit:c,priority:Id[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function O(b,c){return function(d){return null!=d?(Q(this,b,d),a.updateOffset(this,c),this):P(this,b)}}function P(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function Q(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function R(a){return a=K(a),z(this[a])?this[a]():this}function S(a,b){if("object"==typeof a){a=L(a);for(var c=N(a),d=0;d<c.length;d++)this[c[d].unit](a[c[d].unit])}else if(a=K(a),z(this[a]))return this[a](b);return this}function T(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function U(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Md[a]=e),b&&(Md[b[0]]=function(){return T(e.apply(this,arguments),b[1],b[2])}),c&&(Md[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function V(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function W(a){var b,c,d=a.match(Jd);for(b=0,c=d.length;b<c;b++)Md[d[b]]?d[b]=Md[d[b]]:d[b]=V(d[b]);return function(b){var e,f="";for(e=0;e<c;e++)f+=z(d[e])?d[e].call(b,a):d[e];return f}}function X(a,b){return a.isValid()?(b=Y(b,a.localeData()),Ld[b]=Ld[b]||W(b),Ld[b](a)):a.localeData().invalidDate()}function Y(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Kd.lastIndex=0;d>=0&&Kd.test(a);)a=a.replace(Kd,c),Kd.lastIndex=0,d-=1;return a}function Z(a,b,c){ce[a]=z(b)?b:function(a,d){return a&&c?c:b}}function $(a,b){return j(ce,a)?ce[a](b._strict,b._locale):new RegExp(_(a))}function _(a){return aa(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function aa(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ba(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),g(b)&&(d=function(a,c){c[b]=u(a)}),c=0;c<a.length;c++)de[a[c]]=d}function ca(a,b){ba(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function da(a,b,c){null!=b&&j(de,a)&&de[a](b,c._a,c,a)}function ea(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function fa(a,b){return a?c(this._months)?this._months[a.month()]:this._months[(this._months.isFormat||oe).test(b)?"format":"standalone"][a.month()]:c(this._months)?this._months:this._months.standalone}function ga(a,b){return a?c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[oe.test(b)?"format":"standalone"][a.month()]:c(this._monthsShort)?this._monthsShort:this._monthsShort.standalone}function ha(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;d<12;++d)f=l([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null):(e=ne.call(this._longMonthsParse,g),e!==-1?e:null):"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:(e=ne.call(this._longMonthsParse,g),e!==-1?e:null)):(e=ne.call(this._longMonthsParse,g),e!==-1?e:(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null))}function ia(a,b,c){var d,e,f;if(this._monthsParseExact)return ha.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;d<12;d++){if(e=l([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ja(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=u(b);else if(b=a.localeData().monthsParse(b),!g(b))return a;return c=Math.min(a.date(),ea(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ka(b){return null!=b?(ja(this,b),a.updateOffset(this,!0),this):P(this,"Month")}function la(){return ea(this.year(),this.month())}function ma(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):(j(this,"_monthsShortRegex")||(this._monthsShortRegex=re),this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex)}function na(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsStrictRegex:this._monthsRegex):(j(this,"_monthsRegex")||(this._monthsRegex=se),this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex)}function oa(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;b<12;b++)c=l([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;b<12;b++)d[b]=aa(d[b]),e[b]=aa(e[b]);for(b=0;b<24;b++)f[b]=aa(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function pa(a){return qa(a)?366:365}function qa(a){return a%4===0&&a%100!==0||a%400===0}function ra(){return qa(this.year())}function sa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return a<100&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ta(a){var b=new Date(Date.UTC.apply(null,arguments));return a<100&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ua(a,b,c){var d=7+b-c,e=(7+ta(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return j<=0?(f=a-1,g=pa(f)+j):j>pa(a)?(f=a+1,g=j-pa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return g<1?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(pa(a)-d+e)/7}function ya(a){return wa(a,this._week.dow,this._week.doy).week}function za(){return this._week.dow}function Aa(){return this._week.doy}function Ba(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ca(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Da(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Ea(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Fa(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:c(this._weekdays)?this._weekdays:this._weekdays.standalone}function Ga(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ha(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ia(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;d<7;++d)f=l([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:null):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null):"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null)))}function Ja(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ia.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;d<7;d++){if(e=l([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function Ka(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Da(a,this.localeData()),this.add(a-b,"d")):b}function La(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Ma(a){if(!this.isValid())return null!=a?this:NaN;if(null!=a){var b=Ea(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Na(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(j(this,"_weekdaysRegex")||(this._weekdaysRegex=ye),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Oa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(j(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ze),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Pa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(j(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ae),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Qa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],j=[];for(b=0;b<7;b++)c=l([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),j.push(d),j.push(e),j.push(f);for(g.sort(a),h.sort(a),i.sort(a),j.sort(a),b=0;b<7;b++)h[b]=aa(h[b]),i[b]=aa(i[b]),j[b]=aa(j[b]);this._weekdaysRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function Ra(){return this.hours()%12||12}function Sa(){return this.hours()||24}function Ta(a,b){U(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Ua(a,b){return b._meridiemParse}function Va(a){return"p"===(a+"").toLowerCase().charAt(0)}function Wa(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Xa(a){return a?a.toLowerCase().replace("_","-"):a}function Ya(a){for(var b,c,d,e,f=0;f<a.length;){for(e=Xa(a[f]).split("-"),b=e.length,c=Xa(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=Za(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&v(e,c,!0)>=b-1)break;b--}f++}return null}function Za(a){var b=null;if(!Fe[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Be._abbr,require("./locale/"+a),$a(b)}catch(a){}return Fe[a]}function $a(a,b){var c;return a&&(c=f(b)?bb(a):_a(a,b),c&&(Be=c)),Be._abbr}function _a(a,b){if(null!==b){var c=Ee;if(b.abbr=a,null!=Fe[a])y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=Fe[a]._config;else if(null!=b.parentLocale){if(null==Fe[b.parentLocale])return Ge[b.parentLocale]||(Ge[b.parentLocale]=[]),Ge[b.parentLocale].push({name:a,config:b}),null;c=Fe[b.parentLocale]._config}return Fe[a]=new C(B(c,b)),Ge[a]&&Ge[a].forEach(function(a){_a(a.name,a.config)}),$a(a),Fe[a]}return delete Fe[a],null}function ab(a,b){if(null!=b){var c,d=Ee;null!=Fe[a]&&(d=Fe[a]._config),b=B(d,b),c=new C(b),c.parentLocale=Fe[a],Fe[a]=c,$a(a)}else null!=Fe[a]&&(null!=Fe[a].parentLocale?Fe[a]=Fe[a].parentLocale:null!=Fe[a]&&delete Fe[a]);return Fe[a]}function bb(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Be;if(!c(a)){if(b=Za(a))return b;a=[a]}return Ya(a)}function cb(){return Ad(Fe)}function db(a){var b,c=a._a;return c&&n(a).overflow===-2&&(b=c[fe]<0||c[fe]>11?fe:c[ge]<1||c[ge]>ea(c[ee],c[fe])?ge:c[he]<0||c[he]>24||24===c[he]&&(0!==c[ie]||0!==c[je]||0!==c[ke])?he:c[ie]<0||c[ie]>59?ie:c[je]<0||c[je]>59?je:c[ke]<0||c[ke]>999?ke:-1,n(a)._overflowDayOfYear&&(b<ee||b>ge)&&(b=ge),n(a)._overflowWeeks&&b===-1&&(b=le),n(a)._overflowWeekday&&b===-1&&(b=me),n(a).overflow=b),a}function eb(a){var b,c,d,e,f,g,h=a._i,i=He.exec(h)||Ie.exec(h);if(i){for(n(a).iso=!0,b=0,c=Ke.length;b<c;b++)if(Ke[b][1].exec(i[1])){e=Ke[b][0],d=Ke[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Le.length;b<c;b++)if(Le[b][1].exec(i[3])){f=(i[2]||" ")+Le[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Je.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),lb(a)}else a._isValid=!1}function fb(a){var b,c,d,e,f,g,h,i,j={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"},k="YXWVUTSRQPONZABCDEFGHIKLM";if(b=a._i.replace(/\([^\)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),c=Ne.exec(b)){if(d=c[1]?"ddd"+(5===c[1].length?", ":" "):"",e="D MMM "+(c[2].length>10?"YYYY ":"YY "),f="HH:mm"+(c[4]?":ss":""),c[1]){var l=new Date(c[2]),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][l.getDay()];if(c[1].substr(0,3)!==m)return n(a).weekdayMismatch=!0,void(a._isValid=!1)}switch(c[5].length){case 2:0===i?h=" +0000":(i=k.indexOf(c[5][1].toUpperCase())-12,h=(i<0?" -":" +")+(""+i).replace(/^-?/,"0").match(/..$/)[0]+"00");break;case 4:h=j[c[5]];break;default:h=j[" GMT"]}c[5]=h,a._i=c.splice(1).join(""),g=" ZZ",a._f=d+e+f+g,lb(a),n(a).rfc2822=!0}else a._isValid=!1}function gb(b){var c=Me.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(eb(b),void(b._isValid===!1&&(delete b._isValid,fb(b),b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b)))))}function hb(a,b,c){return null!=a?a:null!=b?b:c}function ib(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function jb(a){var b,c,d,e,f=[];if(!a._d){for(d=ib(a),a._w&&null==a._a[ge]&&null==a._a[fe]&&kb(a),null!=a._dayOfYear&&(e=hb(a._a[ee],d[ee]),(a._dayOfYear>pa(e)||0===a._dayOfYear)&&(n(a)._overflowDayOfYear=!0),c=ta(e,0,a._dayOfYear),a._a[fe]=c.getUTCMonth(),a._a[ge]=c.getUTCDate()),b=0;b<3&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;b<7;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[he]&&0===a._a[ie]&&0===a._a[je]&&0===a._a[ke]&&(a._nextDay=!0,a._a[he]=0),a._d=(a._useUTC?ta:sa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[he]=24)}}function kb(a){var b,c,d,e,f,g,h,i;if(b=a._w,null!=b.GG||null!=b.W||null!=b.E)f=1,g=4,c=hb(b.GG,a._a[ee],wa(tb(),1,4).year),d=hb(b.W,1),e=hb(b.E,1),(e<1||e>7)&&(i=!0);else{f=a._locale._week.dow,g=a._locale._week.doy;var j=wa(tb(),f,g);c=hb(b.gg,a._a[ee],j.year),d=hb(b.w,j.week),null!=b.d?(e=b.d,(e<0||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f}d<1||d>xa(c,f,g)?n(a)._overflowWeeks=!0:null!=i?n(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[ee]=h.year,a._dayOfYear=h.dayOfYear)}function lb(b){if(b._f===a.ISO_8601)return void eb(b);if(b._f===a.RFC_2822)return void fb(b);b._a=[],n(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Y(b._f,b._locale).match(Jd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match($(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&n(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Md[f]?(d?n(b).empty=!1:n(b).unusedTokens.push(f),da(f,d,b)):b._strict&&!d&&n(b).unusedTokens.push(f);n(b).charsLeftOver=i-j,h.length>0&&n(b).unusedInput.push(h),b._a[he]<=12&&n(b).bigHour===!0&&b._a[he]>0&&(n(b).bigHour=void 0),n(b).parsedDateParts=b._a.slice(0),n(b).meridiem=b._meridiem,b._a[he]=mb(b._locale,b._a[he],b._meridiem),jb(b),db(b)}function mb(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&b<12&&(b+=12),d||12!==b||(b=0),b):b}function nb(a){var b,c,d,e,f;if(0===a._f.length)return n(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=q({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],lb(b),o(b)&&(f+=n(b).charsLeftOver,f+=10*n(b).unusedTokens.length,n(b).score=f,(null==d||f<d)&&(d=f,c=b));k(a,c||b)}function ob(a){if(!a._d){var b=L(a._i);a._a=i([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),jb(a)}}function pb(a){var b=new r(db(qb(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function qb(a){var b=a._i,d=a._f;return a._locale=a._locale||bb(a._l),null===b||void 0===d&&""===b?p({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),s(b)?new r(db(b)):(h(b)?a._d=b:c(d)?nb(a):d?lb(a):rb(a),o(a)||(a._d=null),a))}function rb(b){var e=b._i;f(e)?b._d=new Date(a.now()):h(e)?b._d=new Date(e.valueOf()):"string"==typeof e?gb(b):c(e)?(b._a=i(e.slice(0),function(a){return parseInt(a,10)}),jb(b)):d(e)?ob(b):g(e)?b._d=new Date(e):a.createFromInputFallback(b)}function sb(a,b,f,g,h){var i={};return f!==!0&&f!==!1||(g=f,f=void 0),(d(a)&&e(a)||c(a)&&0===a.length)&&(a=void 0),i._isAMomentObject=!0,i._useUTC=i._isUTC=h,i._l=f,i._i=a,i._f=b,i._strict=g,pb(i)}function tb(a,b,c,d){return sb(a,b,c,d,!1)}function ub(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return tb();for(d=b[0],e=1;e<b.length;++e)b[e].isValid()&&!b[e][a](d)||(d=b[e]);return d}function vb(){var a=[].slice.call(arguments,0);return ub("isBefore",a)}function wb(){var a=[].slice.call(arguments,0);return ub("isAfter",a)}function xb(a){for(var b in a)if(Re.indexOf(b)===-1||null!=a[b]&&isNaN(a[b]))return!1;for(var c=!1,d=0;d<Re.length;++d)if(a[Re[d]]){if(c)return!1;parseFloat(a[Re[d]])!==u(a[Re[d]])&&(c=!0)}return!0}function yb(){return this._isValid}function zb(){return Sb(NaN)}function Ab(a){var b=L(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._isValid=xb(b),this._milliseconds=+k+1e3*j+6e4*i+1e3*h*60*60,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=bb(),this._bubble()}function Bb(a){return a instanceof Ab}function Cb(a){return a<0?Math.round(-1*a)*-1:Math.round(a)}function Db(a,b){U(a,0,0,function(){var a=this.utcOffset(),c="+";return a<0&&(a=-a,c="-"),c+T(~~(a/60),2)+b+T(~~a%60,2)})}function Eb(a,b){var c=(b||"").match(a);if(null===c)return null;var d=c[c.length-1]||[],e=(d+"").match(Se)||["-",0,0],f=+(60*e[1])+u(e[2]);return 0===f?0:"+"===e[0]?f:-f}function Fb(b,c){var d,e;return c._isUTC?(d=c.clone(),e=(s(b)||h(b)?b.valueOf():tb(b).valueOf())-d.valueOf(),d._d.setTime(d._d.valueOf()+e),a.updateOffset(d,!1),d):tb(b).local()}function Gb(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Hb(b,c,d){var e,f=this._offset||0;if(!this.isValid())return null!=b?this:NaN;if(null!=b){if("string"==typeof b){if(b=Eb(_d,b),null===b)return this}else Math.abs(b)<16&&!d&&(b=60*b);return!this._isUTC&&c&&(e=Gb(this)),this._offset=b,this._isUTC=!0,null!=e&&this.add(e,"m"),f!==b&&(!c||this._changeInProgress?Xb(this,Sb(b-f,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?f:Gb(this)}function Ib(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Jb(a){return this.utcOffset(0,a)}function Kb(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Gb(this),"m")),this}function Lb(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var a=Eb($d,this._i);null!=a?this.utcOffset(a):this.utcOffset(0,!0)}return this}function Mb(a){return!!this.isValid()&&(a=a?tb(a).utcOffset():0,(this.utcOffset()-a)%60===0)}function Nb(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ob(){if(!f(this._isDSTShifted))return this._isDSTShifted;var a={};if(q(a,this),a=qb(a),a._a){var b=a._isUTC?l(a._a):tb(a._a);this._isDSTShifted=this.isValid()&&v(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Pb(){return!!this.isValid()&&!this._isUTC}function Qb(){return!!this.isValid()&&this._isUTC}function Rb(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Sb(a,b){var c,d,e,f=a,h=null;return Bb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:g(a)?(f={},b?f[b]=a:f.milliseconds=a):(h=Te.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:u(h[ge])*c,h:u(h[he])*c,m:u(h[ie])*c,s:u(h[je])*c,ms:u(Cb(1e3*h[ke]))*c}):(h=Ue.exec(a))?(c="-"===h[1]?-1:1,f={y:Tb(h[2],c),M:Tb(h[3],c),w:Tb(h[4],c),d:Tb(h[5],c),h:Tb(h[6],c),m:Tb(h[7],c),s:Tb(h[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Vb(tb(f.from),tb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new Ab(f),Bb(a)&&j(a,"_locale")&&(d._locale=a._locale),d}function Tb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Ub(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Vb(a,b){var c;return a.isValid()&&b.isValid()?(b=Fb(b,a),a.isBefore(b)?c=Ub(a,b):(c=Ub(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function Wb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(y(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Sb(c,d),Xb(this,e,a),this}}function Xb(b,c,d,e){var f=c._milliseconds,g=Cb(c._days),h=Cb(c._months);b.isValid()&&(e=null==e||e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&Q(b,"Date",P(b,"Date")+g*d),h&&ja(b,P(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Yb(a,b){var c=a.diff(b,"days",!0);return c<-6?"sameElse":c<-1?"lastWeek":c<0?"lastDay":c<1?"sameDay":c<2?"nextDay":c<7?"nextWeek":"sameElse"}function Zb(b,c){var d=b||tb(),e=Fb(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(z(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,tb(d)))}function $b(){return new r(this)}function _b(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf())}function ac(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf())}function bc(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function cc(a,b){var c,d=s(a)?a:tb(a);return!(!this.isValid()||!d.isValid())&&(b=K(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf()))}function dc(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function ec(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function fc(a,b,c){var d,e,f,g;return this.isValid()?(d=Fb(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=gc(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:t(g)):NaN):NaN}function gc(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return b-f<0?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function hc(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ic(){if(!this.isValid())return null;var a=this.clone().utc();return a.year()<0||a.year()>9999?X(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):z(Date.prototype.toISOString)?this.toDate().toISOString():X(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function jc(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var a="moment",b="";this.isLocal()||(a=0===this.utcOffset()?"moment.utc":"moment.parseZone",b="Z");var c="["+a+'("]',d=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",e="-MM-DD[T]HH:mm:ss.SSS",f=b+'[")]';return this.format(c+d+e+f)}function kc(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=X(this,b);return this.localeData().postformat(c)}function lc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function mc(a){return this.from(tb(),a)}function nc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function oc(a){return this.to(tb(),a)}function pc(a){var b;return void 0===a?this._locale._abbr:(b=bb(a),null!=b&&(this._locale=b),this)}function qc(){return this._locale}function rc(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function sc(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function tc(){return this._d.valueOf()-6e4*(this._offset||0)}function uc(){return Math.floor(this.valueOf()/1e3)}function vc(){return new Date(this.valueOf())}function wc(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function xc(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function yc(){return this.isValid()?this.toISOString():null}function zc(){return o(this)}function Ac(){
-return k({},n(this))}function Bc(){return n(this).overflow}function Cc(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Dc(a,b){U(0,[a,a.length],0,b)}function Ec(a){return Ic.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Fc(a){return Ic.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Gc(){return xa(this.year(),1,4)}function Hc(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ic(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Jc.call(this,a,b,c,d,e))}function Jc(a,b,c,d,e){var f=va(a,b,c,d,e),g=ta(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Kc(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Lc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Mc(a,b){b[ke]=u(1e3*("0."+a))}function Nc(){return this._isUTC?"UTC":""}function Oc(){return this._isUTC?"Coordinated Universal Time":""}function Pc(a){return tb(1e3*a)}function Qc(){return tb.apply(null,arguments).parseZone()}function Rc(a){return a}function Sc(a,b,c,d){var e=bb(),f=l().set(d,b);return e[c](f,a)}function Tc(a,b,c){if(g(a)&&(b=a,a=void 0),a=a||"",null!=b)return Sc(a,b,c,"month");var d,e=[];for(d=0;d<12;d++)e[d]=Sc(a,d,c,"month");return e}function Uc(a,b,c,d){"boolean"==typeof a?(g(b)&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,g(b)&&(c=b,b=void 0),b=b||"");var e=bb(),f=a?e._week.dow:0;if(null!=c)return Sc(b,(c+f)%7,d,"day");var h,i=[];for(h=0;h<7;h++)i[h]=Sc(b,(h+f)%7,d,"day");return i}function Vc(a,b){return Tc(a,b,"months")}function Wc(a,b){return Tc(a,b,"monthsShort")}function Xc(a,b,c){return Uc(a,b,c,"weekdays")}function Yc(a,b,c){return Uc(a,b,c,"weekdaysShort")}function Zc(a,b,c){return Uc(a,b,c,"weekdaysMin")}function $c(){var a=this._data;return this._milliseconds=df(this._milliseconds),this._days=df(this._days),this._months=df(this._months),a.milliseconds=df(a.milliseconds),a.seconds=df(a.seconds),a.minutes=df(a.minutes),a.hours=df(a.hours),a.months=df(a.months),a.years=df(a.years),this}function _c(a,b,c,d){var e=Sb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function ad(a,b){return _c(this,a,b,1)}function bd(a,b){return _c(this,a,b,-1)}function cd(a){return a<0?Math.floor(a):Math.ceil(a)}function dd(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||f<=0&&g<=0&&h<=0||(f+=864e5*cd(fd(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=t(f/1e3),i.seconds=a%60,b=t(a/60),i.minutes=b%60,c=t(b/60),i.hours=c%24,g+=t(c/24),e=t(ed(g)),h+=e,g-=cd(fd(e)),d=t(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function ed(a){return 4800*a/146097}function fd(a){return 146097*a/4800}function gd(a){if(!this.isValid())return NaN;var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+ed(b),"month"===a?c:c/12;switch(b=this._days+Math.round(fd(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function hd(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*u(this._months/12):NaN}function id(a){return function(){return this.as(a)}}function jd(a){return a=K(a),this.isValid()?this[a+"s"]():NaN}function kd(a){return function(){return this.isValid()?this._data[a]:NaN}}function ld(){return t(this.days()/7)}function md(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function nd(a,b,c){var d=Sb(a).abs(),e=uf(d.as("s")),f=uf(d.as("m")),g=uf(d.as("h")),h=uf(d.as("d")),i=uf(d.as("M")),j=uf(d.as("y")),k=e<=vf.ss&&["s",e]||e<vf.s&&["ss",e]||f<=1&&["m"]||f<vf.m&&["mm",f]||g<=1&&["h"]||g<vf.h&&["hh",g]||h<=1&&["d"]||h<vf.d&&["dd",h]||i<=1&&["M"]||i<vf.M&&["MM",i]||j<=1&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,md.apply(null,k)}function od(a){return void 0===a?uf:"function"==typeof a&&(uf=a,!0)}function pd(a,b){return void 0!==vf[a]&&(void 0===b?vf[a]:(vf[a]=b,"s"===a&&(vf.ss=b-1),!0))}function qd(a){if(!this.isValid())return this.localeData().invalidDate();var b=this.localeData(),c=nd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function rd(){if(!this.isValid())return this.localeData().invalidDate();var a,b,c,d=wf(this._milliseconds)/1e3,e=wf(this._days),f=wf(this._months);a=t(d/60),b=t(a/60),d%=60,a%=60,c=t(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(m<0?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var sd,td;td=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;d<c;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var ud=td,vd=a.momentProperties=[],wd=!1,xd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var yd;yd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)j(a,b)&&c.push(b);return c};var zd,Ad=yd,Bd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Cd={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Dd="Invalid date",Ed="%d",Fd=/\d{1,2}/,Gd={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Hd={},Id={},Jd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Kd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ld={},Md={},Nd=/\d/,Od=/\d\d/,Pd=/\d{3}/,Qd=/\d{4}/,Rd=/[+-]?\d{6}/,Sd=/\d\d?/,Td=/\d\d\d\d?/,Ud=/\d\d\d\d\d\d?/,Vd=/\d{1,3}/,Wd=/\d{1,4}/,Xd=/[+-]?\d{1,6}/,Yd=/\d+/,Zd=/[+-]?\d+/,$d=/Z|[+-]\d\d:?\d\d/gi,_d=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[+-]?\d+(\.\d{1,3})?/,be=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,ce={},de={},ee=0,fe=1,ge=2,he=3,ie=4,je=5,ke=6,le=7,me=8;zd=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1};var ne=zd;U("M",["MM",2],"Mo",function(){return this.month()+1}),U("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),U("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),M("month",8),Z("M",Sd),Z("MM",Sd,Od),Z("MMM",function(a,b){return b.monthsShortRegex(a)}),Z("MMMM",function(a,b){return b.monthsRegex(a)}),ba(["M","MM"],function(a,b){b[fe]=u(a)-1}),ba(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[fe]=e:n(c).invalidMonth=a});var oe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,pe="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),qe="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),re=be,se=be;U("Y",0,0,function(){var a=this.year();return a<=9999?""+a:"+"+a}),U(0,["YY",2],0,function(){return this.year()%100}),U(0,["YYYY",4],0,"year"),U(0,["YYYYY",5],0,"year"),U(0,["YYYYYY",6,!0],0,"year"),J("year","y"),M("year",1),Z("Y",Zd),Z("YY",Sd,Od),Z("YYYY",Wd,Qd),Z("YYYYY",Xd,Rd),Z("YYYYYY",Xd,Rd),ba(["YYYYY","YYYYYY"],ee),ba("YYYY",function(b,c){c[ee]=2===b.length?a.parseTwoDigitYear(b):u(b)}),ba("YY",function(b,c){c[ee]=a.parseTwoDigitYear(b)}),ba("Y",function(a,b){b[ee]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return u(a)+(u(a)>68?1900:2e3)};var te=O("FullYear",!0);U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),M("week",5),M("isoWeek",5),Z("w",Sd),Z("ww",Sd,Od),Z("W",Sd),Z("WW",Sd,Od),ca(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=u(a)});var ue={dow:0,doy:6};U("d",0,"do","day"),U("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),U("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),U("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),M("day",11),M("weekday",11),M("isoWeekday",11),Z("d",Sd),Z("e",Sd),Z("E",Sd),Z("dd",function(a,b){return b.weekdaysMinRegex(a)}),Z("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Z("dddd",function(a,b){return b.weekdaysRegex(a)}),ca(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:n(c).invalidWeekday=a}),ca(["d","e","E"],function(a,b,c,d){b[d]=u(a)});var ve="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),we="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ye=be,ze=be,Ae=be;U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Ra),U("k",["kk",2],0,Sa),U("hmm",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ta("a",!0),Ta("A",!1),J("hour","h"),M("hour",13),Z("a",Ua),Z("A",Ua),Z("H",Sd),Z("h",Sd),Z("k",Sd),Z("HH",Sd,Od),Z("hh",Sd,Od),Z("kk",Sd,Od),Z("hmm",Td),Z("hmmss",Ud),Z("Hmm",Td),Z("Hmmss",Ud),ba(["H","HH"],he),ba(["k","kk"],function(a,b,c){var d=u(a);b[he]=24===d?0:d}),ba(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),ba(["h","hh"],function(a,b,c){b[he]=u(a),n(c).bigHour=!0}),ba("hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d)),n(c).bigHour=!0}),ba("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e)),n(c).bigHour=!0}),ba("Hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d))}),ba("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e))});var Be,Ce=/[ap]\.?m?\.?/i,De=O("Hours",!0),Ee={calendar:Bd,longDateFormat:Cd,invalidDate:Dd,ordinal:Ed,dayOfMonthOrdinalParse:Fd,relativeTime:Gd,months:pe,monthsShort:qe,week:ue,weekdays:ve,weekdaysMin:xe,weekdaysShort:we,meridiemParse:Ce},Fe={},Ge={},He=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ie=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Je=/Z|[+-]\d\d(?::?\d\d)?/,Ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Le=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Me=/^\/?Date\((\-?\d+)/i,Ne=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;a.createFromInputFallback=x("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),a.ISO_8601=function(){},a.RFC_2822=function(){};var Oe=x("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a<this?this:a:p()}),Pe=x("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:p()}),Qe=function(){return Date.now?Date.now():+new Date},Re=["year","quarter","month","week","day","hour","minute","second","millisecond"];Db("Z",":"),Db("ZZ",""),Z("Z",_d),Z("ZZ",_d),ba(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Eb(_d,a)});var Se=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Te=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ue=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Sb.fn=Ab.prototype,Sb.invalid=zb;var Ve=Wb(1,"add"),We=Wb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xe=x("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});U(0,["gg",2],0,function(){return this.weekYear()%100}),U(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Dc("gggg","weekYear"),Dc("ggggg","weekYear"),Dc("GGGG","isoWeekYear"),Dc("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),M("weekYear",1),M("isoWeekYear",1),Z("G",Zd),Z("g",Zd),Z("GG",Sd,Od),Z("gg",Sd,Od),Z("GGGG",Wd,Qd),Z("gggg",Wd,Qd),Z("GGGGG",Xd,Rd),Z("ggggg",Xd,Rd),ca(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=u(a)}),ca(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),U("Q",0,"Qo","quarter"),J("quarter","Q"),M("quarter",7),Z("Q",Nd),ba("Q",function(a,b){b[fe]=3*(u(a)-1)}),U("D",["DD",2],"Do","date"),J("date","D"),M("date",9),Z("D",Sd),Z("DD",Sd,Od),Z("Do",function(a,b){return a?b._dayOfMonthOrdinalParse||b._ordinalParse:b._dayOfMonthOrdinalParseLenient}),ba(["D","DD"],ge),ba("Do",function(a,b){b[ge]=u(a.match(Sd)[0],10)});var Ye=O("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),M("dayOfYear",4),Z("DDD",Vd),Z("DDDD",Pd),ba(["DDD","DDDD"],function(a,b,c){c._dayOfYear=u(a)}),U("m",["mm",2],0,"minute"),J("minute","m"),M("minute",14),Z("m",Sd),Z("mm",Sd,Od),ba(["m","mm"],ie);var Ze=O("Minutes",!1);U("s",["ss",2],0,"second"),J("second","s"),M("second",15),Z("s",Sd),Z("ss",Sd,Od),ba(["s","ss"],je);var $e=O("Seconds",!1);U("S",0,0,function(){return~~(this.millisecond()/100)}),U(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),U(0,["SSS",3],0,"millisecond"),U(0,["SSSS",4],0,function(){return 10*this.millisecond()}),U(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),U(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),U(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),U(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),U(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),M("millisecond",16),Z("S",Vd,Nd),Z("SS",Vd,Od),Z("SSS",Vd,Pd);var _e;for(_e="SSSS";_e.length<=9;_e+="S")Z(_e,Yd);for(_e="S";_e.length<=9;_e+="S")ba(_e,Mc);var af=O("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var bf=r.prototype;bf.add=Ve,bf.calendar=Zb,bf.clone=$b,bf.diff=fc,bf.endOf=sc,bf.format=kc,bf.from=lc,bf.fromNow=mc,bf.to=nc,bf.toNow=oc,bf.get=R,bf.invalidAt=Bc,bf.isAfter=_b,bf.isBefore=ac,bf.isBetween=bc,bf.isSame=cc,bf.isSameOrAfter=dc,bf.isSameOrBefore=ec,bf.isValid=zc,bf.lang=Xe,bf.locale=pc,bf.localeData=qc,bf.max=Pe,bf.min=Oe,bf.parsingFlags=Ac,bf.set=S,bf.startOf=rc,bf.subtract=We,bf.toArray=wc,bf.toObject=xc,bf.toDate=vc,bf.toISOString=ic,bf.inspect=jc,bf.toJSON=yc,bf.toString=hc,bf.unix=uc,bf.valueOf=tc,bf.creationData=Cc,bf.year=te,bf.isLeapYear=ra,bf.weekYear=Ec,bf.isoWeekYear=Fc,bf.quarter=bf.quarters=Kc,bf.month=ka,bf.daysInMonth=la,bf.week=bf.weeks=Ba,bf.isoWeek=bf.isoWeeks=Ca,bf.weeksInYear=Hc,bf.isoWeeksInYear=Gc,bf.date=Ye,bf.day=bf.days=Ka,bf.weekday=La,bf.isoWeekday=Ma,bf.dayOfYear=Lc,bf.hour=bf.hours=De,bf.minute=bf.minutes=Ze,bf.second=bf.seconds=$e,bf.millisecond=bf.milliseconds=af,bf.utcOffset=Hb,bf.utc=Jb,bf.local=Kb,bf.parseZone=Lb,bf.hasAlignedHourOffset=Mb,bf.isDST=Nb,bf.isLocal=Pb,bf.isUtcOffset=Qb,bf.isUtc=Rb,bf.isUTC=Rb,bf.zoneAbbr=Nc,bf.zoneName=Oc,bf.dates=x("dates accessor is deprecated. Use date instead.",Ye),bf.months=x("months accessor is deprecated. Use month instead",ka),bf.years=x("years accessor is deprecated. Use year instead",te),bf.zone=x("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ib),bf.isDSTShifted=x("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ob);var cf=C.prototype;cf.calendar=D,cf.longDateFormat=E,cf.invalidDate=F,cf.ordinal=G,cf.preparse=Rc,cf.postformat=Rc,cf.relativeTime=H,cf.pastFuture=I,cf.set=A,cf.months=fa,cf.monthsShort=ga,cf.monthsParse=ia,cf.monthsRegex=na,cf.monthsShortRegex=ma,cf.week=ya,cf.firstDayOfYear=Aa,cf.firstDayOfWeek=za,cf.weekdays=Fa,cf.weekdaysMin=Ha,cf.weekdaysShort=Ga,cf.weekdaysParse=Ja,cf.weekdaysRegex=Na,cf.weekdaysShortRegex=Oa,cf.weekdaysMinRegex=Pa,cf.isPM=Va,cf.meridiem=Wa,$a("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===u(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=x("moment.lang is deprecated. Use moment.locale instead.",$a),a.langData=x("moment.langData is deprecated. Use moment.localeData instead.",bb);var df=Math.abs,ef=id("ms"),ff=id("s"),gf=id("m"),hf=id("h"),jf=id("d"),kf=id("w"),lf=id("M"),mf=id("y"),nf=kd("milliseconds"),of=kd("seconds"),pf=kd("minutes"),qf=kd("hours"),rf=kd("days"),sf=kd("months"),tf=kd("years"),uf=Math.round,vf={ss:44,s:45,m:45,h:22,d:26,M:11},wf=Math.abs,xf=Ab.prototype;return xf.isValid=yb,xf.abs=$c,xf.add=ad,xf.subtract=bd,xf.as=gd,xf.asMilliseconds=ef,xf.asSeconds=ff,xf.asMinutes=gf,xf.asHours=hf,xf.asDays=jf,xf.asWeeks=kf,xf.asMonths=lf,xf.asYears=mf,xf.valueOf=hd,xf._bubble=dd,xf.get=jd,xf.milliseconds=nf,xf.seconds=of,xf.minutes=pf,xf.hours=qf,xf.days=rf,xf.weeks=ld,xf.months=sf,xf.years=tf,xf.humanize=qd,xf.toISOString=rd,xf.toString=rd,xf.toJSON=rd,xf.locale=pc,xf.localeData=qc,xf.toIsoString=x("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",rd),xf.lang=Xe,U("X",0,0,"unix"),U("x",0,0,"valueOf"),Z("x",Zd),Z("X",ae),ba("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),ba("x",function(a,b,c){c._d=new Date(u(a))}),a.version="2.18.1",b(tb),a.fn=bf,a.min=vb,a.max=wb,a.now=Qe,a.utc=l,a.unix=Pc,a.months=Vc,a.isDate=h,a.locale=$a,a.invalid=p,a.duration=Sb,a.isMoment=s,a.weekdays=Xc,a.parseZone=Qc,a.localeData=bb,a.isDuration=Bb,a.monthsShort=Wc,a.weekdaysMin=Zc,a.defineLocale=_a,a.updateLocale=ab,a.locales=cb,a.weekdaysShort=Yc,a.normalizeUnits=K,a.relativeTimeRounding=od,a.relativeTimeThreshold=pd,a.calendarFormat=Yb,a.prototype=bf,a});
diff --git a/web/js/nms-admin-pane.js b/web/js/nms-admin-pane.js
deleted file mode 100644
index 235da8d..0000000
--- a/web/js/nms-admin-pane.js
+++ /dev/null
@@ -1,99 +0,0 @@
-"use strict";
-
-
-
-var nmsAdmin = nmsAdmin || {
- _populated: false,
- _elements: {},
- _main: {
- 'shortname':"Short name",
- 'publicvhost': "Public VHOST",
- 'data': "Misc data"
- }
-};
-
-nmsAdmin._populatePane = function() {
- var form = document.createElement("div");
- form.classList.add("form-group");
- for (var v in nmsAdmin._main) {
- var x = document.createElement('label');
- var y = document.createElement('input');
- y.classList.add("form-control");
- y.id = "nmsAdmin-input-" + v;
- x.innerText = nmsAdmin._main[v];
- x.htmlFor = y.id;
- form.appendChild(x);
- form.appendChild(y);
- nmsAdmin._elements[v] = y;
- }
- var submit = document.createElement("button");
- submit.classList.add("btn");
- submit.classList.add("btn-default");
- submit.onclick = nmsAdmin._commitData;
- submit.innerHTML = "Save";
- var topel = document.getElementById("admin-row");
- topel.appendChild(form);
- topel.appendChild(submit);
- nmsAdmin._populated = true;
-}
-
-nmsAdmin._setReadOnly = function(ro) {
- for (var v in nmsAdmin._main) {
- nmsAdmin._elements[v].readOnly = ro;
- }
-}
-
-nmsAdmin._commitData = function() {
- var myData = {};
- for (var v in nmsAdmin._main) {
- if (v != "data") {
- myData[v] = nmsAdmin._elements[v].value;
- } else {
- myData[v] = JSON.parse(nmsAdmin._elements[v].value);
- }
- }
- myData = JSON.stringify(myData);
- nmsAdmin._setReadOnly(true);
- $.ajax({
- type: "POST",
- url: "/api/write/config",
- dataType: "text",
- data:myData,
- success: function (data, textStatus, jqXHR) {
- nmsData.invalidate("config");
- nmsAdmin._setReadOnly(false);
- }
- });
-}
-
-nmsAdmin.updateConfigPane = function() {
- if (nmsAdmin._populated == false) {
- nmsAdmin._populatePane();
- }
- for (var v in nmsAdmin._main) {
- if (v != "data") {
- nmsAdmin._elements[v].value = nmsData['config']['config'][v];
- } else {
- nmsAdmin._elements[v].value = JSON.stringify(nmsData['config']['config'][v]);
- }
- }
-}
-
-nmsAdmin.addLinknet = function() {
- var myData = {
- "switch1": document.getElementById("admin-input-linknet1").value,
- "switch2": document.getElementById("admin-input-linknet2").value
- };
- myData = JSON.stringify(myData);
- $.ajax({
- type: "POST",
- url: "/api/write/linknet-add",
- dataType: "text",
- data:myData,
- success: function (data, textStatus, jqXHR) {
- nmsData.invalidate("switches");
- document.getElementById("admin-input-linknet1").value = "";
- document.getElementById("admin-input-linknet2").value = "";
- }
- });
-}
diff --git a/web/js/nms-color-util.js b/web/js/nms-color-util.js
index 0f50126..d1336c3 100644
--- a/web/js/nms-color-util.js
+++ b/web/js/nms-color-util.js
@@ -7,32 +7,36 @@
*/
var nmsColor = nmsColor || {
- _cache: [],
- lightblue: "#d9edf7",
- lightgreen: "#dff0d8",
- lightred: "#f2dede",
- lightorange: "#fcf8e3",
- blue: "#337ab7",
- green: "#5cb85c",
- teal: "#5bc0de",
- orange: "#f0ad4e",
- red: "#d9534f",
- white: "#ffffff"
-}
+ _cache: [],
+ cyan: "#0dcaf0",
+ blue: "#0d6efd",
+ green: "#198754",
+ teal: "#20c997",
+ orange: "#fd7e14",
+ red: "#dc3545",
+ white: "#fff",
+};
/*
* Return a random-ish color (for testing)
*/
-nmsColor.random = function()
-{
- var colors = [ "white", nmsColor.red, nmsColor.teal, nmsColor.orange, nmsColor.green, nmsColor.blue ];
- var i = Math.round(Math.random() * (colors.length-1));
- return colors[i];
-}
+nmsColor.random = function () {
+ var colors = [
+ nmsColor.white,
+ nmsColor.red,
+ nmsColor.teal,
+ nmsColor.orange,
+ nmsColor.green,
+ nmsColor.blue,
+ nmsColor.cyan,
+ ];
+ var i = Math.round(Math.random() * (colors.length - 1));
+ return colors[i];
+};
/*
* Set up the hidden gradient canvas, using an array as input.
- *
+ *
* This gives us a flexible way to get gradients between any number of
* colors (green to red, or blue to green to orange to red to white to pink
* to black and so on).
@@ -44,57 +48,52 @@ nmsColor.random = function()
* resize for the moment, because this canvas is also re-sized (which isn't
* really necessary, but avoids special handling).
*/
-nmsColor.drawGradient = function(gradients) {
- var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away...
- var gradient = ctx.createLinearGradient(0,0,1000,0);
- var stops = gradients.length - 1;
- nmsColor._cache = [];
- nms.gradients = gradients;
- for (var color in gradients) {
- var i = color / stops;
- gradient.addColorStop(i, gradients[color]);
- }
- ctx.beginPath();
- ctx.strokeStyle = gradient;
- ctx.moveTo(0,0);
- ctx.lineTo(1000,0);
- ctx.lineWidth = 10;
- ctx.closePath();
- ctx.stroke();
- ctx.moveTo(0,0);
-}
+nmsColor.drawGradient = function (gradients) {
+ var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away...
+ var gradient = ctx.createLinearGradient(0, 0, 1000, 0);
+ var stops = gradients.length - 1;
+ nmsColor._cache = [];
+ nms.gradients = gradients;
+ for (var color in gradients) {
+ var i = color / stops;
+ gradient.addColorStop(i, gradients[color]);
+ }
+ ctx.beginPath();
+ ctx.strokeStyle = gradient;
+ ctx.moveTo(0, 0);
+ ctx.lineTo(1000, 0);
+ ctx.lineWidth = 10;
+ ctx.closePath();
+ ctx.stroke();
+ ctx.moveTo(0, 0);
+};
/*
* Get the color of a gradient, range is from 0 to 999 (inclusive).
*/
-nmsColor.getColorStop = function(x) {
- x = parseInt(x);
- if (isNaN(x))
- x = 0;
- if (x > 999)
- x = 999;
- if (x < 0)
- x = 0;
- return nmsColor._getColor(x,0);
-}
+nmsColor.getColorStop = function (x) {
+ x = parseInt(x);
+ if (isNaN(x)) x = 0;
+ if (x > 999) x = 999;
+ if (x < 0) x = 0;
+ return nmsColor._getColor(x, 0);
+};
/*
* Get the color on the hidden canvas at a specific point. Could easily be
* made generic.
*/
-nmsColor._getColor = function(x,y) {
- if (nmsColor._cache[x] != undefined)
- return nmsColor._cache[x];
- var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away...
- try {
- var imageData = ctx.getImageData(x, y, 1, 1);
- } catch(e) {
- console.log("x: " + x);
- console.log(e);
- }
- var data = imageData.data;
- if (data.length < 4)
- return false;
- nmsColor._cache[x] = 'rgb(' + data[0] + ',' + data[1] + ',' + data[2] + ')';
- return nmsColor._cache[x];
-}
+nmsColor._getColor = function (x, y) {
+ if (nmsColor._cache[x] != undefined) return nmsColor._cache[x];
+ var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away...
+ try {
+ var imageData = ctx.getImageData(x, y, 1, 1);
+ } catch (e) {
+ console.log("x: " + x);
+ console.log(e);
+ }
+ var data = imageData.data;
+ if (data.length < 4) return false;
+ nmsColor._cache[x] = "rgb(" + data[0] + "," + data[1] + "," + data[2] + ")";
+ return nmsColor._cache[x];
+};
diff --git a/web/js/nms-data.js b/web/js/nms-data.js
index c923e08..6a00fba 100644
--- a/web/js/nms-data.js
+++ b/web/js/nms-data.js
@@ -23,78 +23,82 @@
* nmsData.invalidate() - Invalidate browser-cache.
*/
-
var nmsData = nmsData || {
- old: {}, // Single copy of previous data. Automatically populated.
- stats: {
- identicalFetches:0,
- outstandingAjaxRequests:0,
- ajaxOverflow:0,
- pollClearsEmpty:0,
- pollClears:0,
- pollSets:0,
- newSource:0,
- oldSource:0
- },
- _pulseBeat: 0,
- /*
- * The last time stamp of any data received, regardless of source.
- *
- * Used as a fallback for blank now, but can also be used to check
- * "freshness", I suppose.
- */
- _last: undefined,
- _now: undefined,
+ old: {}, // Single copy of previous data. Automatically populated.
+ stats: {
+ identicalFetches: 0,
+ outstandingAjaxRequests: 0,
+ ajaxOverflow: 0,
+ pollClearsEmpty: 0,
+ pollClears: 0,
+ pollSets: 0,
+ newSource: 0,
+ oldSource: 0,
+ allFetches: 0,
+ allRequests: 0,
+ failedFetches: 0,
+ jsonParse: 0,
+ },
+ _pulseBeat: 0,
+ /*
+ * The last time stamp of any data received, regardless of source.
+ *
+ * Used as a fallback for blank now, but can also be used to check
+ * "freshness", I suppose.
+ */
+ _last: undefined,
+ _now: undefined,
- /*
- * These are provided so we can introduce error checking when we
- * have time.
- *
- * now() represents the data, not the intent. That means that if
- * you want to check if we are traveling in time you should not
- * check nmsData.now. That will always return a value as long as
- * we've had a single piece of data.
- */
- get now() { return this._now || this._last; },
- set now(val) {
- if (val == undefined || !val) {
- nmsData._now = undefined;
- } else {
- // FIXME: Check if now is valid syntax.
- nmsData._now = val;
- }
- },
- /*
- * List of sources, name, handler, etc
- */
- _sources: {},
+ /*
+ * These are provided so we can introduce error checking when we
+ * have time.
+ *
+ * now() represents the data, not the intent. That means that if
+ * you want to check if we are traveling in time you should not
+ * check nmsData.now. That will always return a value as long as
+ * we've had a single piece of data.
+ */
+ get now() {
+ return this._now || this._last;
+ },
+ set now(val) {
+ if (val == undefined || !val) {
+ nmsData._now = undefined;
+ } else {
+ // FIXME: Check if now is valid syntax.
+ nmsData._now = val;
+ }
+ },
+ /*
+ * List of sources, name, handler, etc
+ */
+ _sources: {},
- /*
- * Maximum number of AJAX requests in transit before we start
- * skipping updates.
- *
- * A problem right now is that it will typically always hit the
- * same thing since everything starts at the same time...
- */
- _ajaxThreshold: 10
+ /*
+ * Maximum number of AJAX requests in transit before we start
+ * skipping updates.
+ *
+ * A problem right now is that it will typically always hit the
+ * same thing since everything starts at the same time...
+ */
+ _ajaxThreshold: 10,
};
-
nmsData._dropData = function (name) {
- delete this[name];
- delete this.old[name];
+ delete this[name];
+ delete this.old[name];
};
nmsData.removeSource = function (name) {
- if (this._sources[name] == undefined) {
- this.stats.pollClearsEmpty++;
- return true;
- }
- if (this._sources[name]['handle']) {
- this.stats.pollClears++;
- clearInterval(this._sources[name]['handle']);
- }
- delete this._sources[name];
+ if (this._sources[name] == undefined) {
+ this.stats.pollClearsEmpty++;
+ return true;
+ }
+ if (this._sources[name]["handle"]) {
+ this.stats.pollClears++;
+ clearInterval(this._sources[name]["handle"]);
+ }
+ delete this._sources[name];
};
/*
@@ -112,15 +116,17 @@ nmsData.removeSource = function (name) {
*
* FIXME: Should be unified with nmsTimers() somehow.
*/
-nmsData.registerSource = function(name, target) {
- if (this._sources[name] == undefined) {
- this._sources[name] = { target: target, cbs: {}, fresh: true };
- this._sources[name]['handle'] = setInterval(function(){nmsData.updateSource(name)}, 1000);
- this.stats.newSource++;
- } else {
- this.stats.oldSource++;
- }
- this.stats.pollSets++;
+nmsData.registerSource = function (name, target) {
+ if (this._sources[name] == undefined) {
+ this._sources[name] = { target: target, cbs: {}, fresh: true };
+ this._sources[name]["handle"] = setInterval(function () {
+ nmsData.updateSource(name);
+ }, 1000);
+ this.stats.newSource++;
+ } else {
+ this.stats.oldSource++;
+ }
+ this.stats.pollSets++;
};
/*
@@ -132,45 +138,44 @@ nmsData.registerSource = function(name, target) {
* The actual html might not be the best choice, but I think the general
* idea of some sort of heartbeat is needed.
*/
-nmsData._pulse = function() {
- if (nmsData._pulseElement == undefined) {
- try {
- nmsData._pulseElement = document.getElementById("heartbeat");
- } catch(e) {
- nmsData._pulseElement = null;
- }
- }
- if (nmsData._pulseElement == null)
- return;
- if (nmsData._pulseBeat > 20) {
- if (nmsData._pulseElement.classList.contains("pulse-on")) {
- nmsData._pulseElement.classList.remove("pulse-on");
- } else {
- nmsData._pulseElement.classList.add("pulse-on");
- }
- nmsData._pulseBeat = 0;
- }
- nmsData._pulseBeat++;
-}
+nmsData._pulse = function () {
+ if (nmsData._pulseElement == undefined) {
+ try {
+ nmsData._pulseElement = document.getElementById("heartbeat");
+ } catch (e) {
+ nmsData._pulseElement = null;
+ }
+ }
+ if (nmsData._pulseElement == null) return;
+ if (nmsData._pulseBeat > 20) {
+ if (nmsData._pulseElement.classList.contains("pulse-on")) {
+ nmsData._pulseElement.classList.remove("pulse-on");
+ } else {
+ nmsData._pulseElement.classList.add("pulse-on");
+ }
+ nmsData._pulseBeat = 0;
+ }
+ nmsData._pulseBeat++;
+};
/*
* Add a handler (callback) for a source, using an id.
*
* This is idempotent: if the id is the same, it will just overwrite the
* old id, not add a copy.
*/
-nmsData.addHandler = function(name, id, cb, cbdata) {
- var cbob = {
- id: id,
- name: name,
- cb: cb,
- fresh: true,
- cbdata: cbdata
- };
- if (id == undefined) {
- return;
- }
- this._sources[name].cbs[id] = cbob;
- this.updateSource(name);
+nmsData.addHandler = function (name, id, cb, cbdata) {
+ var cbob = {
+ id: id,
+ name: name,
+ cb: cb,
+ fresh: true,
+ cbdata: cbdata,
+ };
+ if (id == undefined) {
+ return;
+ }
+ this._sources[name].cbs[id] = cbob;
+ this.updateSource(name);
};
/*
@@ -179,14 +184,14 @@ nmsData.addHandler = function(name, id, cb, cbdata) {
* Mainly used to avoid fini() functions in the map handlers. E.g.: just
* reuse "mapHandler" as id.
*/
-nmsData.unregisterHandlerWildcard = function(id) {
- for (var v in nmsData._sources) {
- this.unregisterHandler(v, id);
- }
+nmsData.unregisterHandlerWildcard = function (id) {
+ for (var v in nmsData._sources) {
+ this.unregisterHandler(v, id);
+ }
};
-nmsData.unregisterHandler = function(name, id) {
- delete this._sources[name].cbs[id];
+nmsData.unregisterHandler = function (name, id) {
+ delete this._sources[name].cbs[id];
};
/*
@@ -196,34 +201,34 @@ nmsData.unregisterHandler = function(name, id) {
* known action that updates the underlying data (e.g: update comments
* after a comment is posted).
*/
-nmsData.updateSource = function(name) {
- /*
- * See comment in nms.js nmsINIT();
- */
- if (name == "ticker" ) {
- for (var i in nmsData._sources[name].cbs) {
- var tmp = nmsData._sources[name].cbs[i];
- if (tmp.cb != undefined) {
- tmp.cb(tmp.cbdata);
- }
- }
- return;
- }
- this._genericUpdater(name, true);
+nmsData.updateSource = function (name) {
+ /*
+ * See comment in nms.js nmsINIT();
+ */
+ if (name == "ticker") {
+ for (var i in nmsData._sources[name].cbs) {
+ var tmp = nmsData._sources[name].cbs[i];
+ if (tmp.cb != undefined) {
+ tmp.cb(tmp.cbdata);
+ }
+ }
+ return;
+ }
+ this._genericUpdater(name, true);
};
-nmsData.invalidate = function(name) {
- this._genericUpdater(name, false);
+nmsData.invalidate = function (name) {
+ this._genericUpdater(name, false);
};
/*
* Reset a source, deleting all data, including old.
*
* Useful if traveling in time, for example.
*/
-nmsData.resetSource = function(name) {
- this[name] = {};
- this.old[name] = {};
- this.updateSource(name);
+nmsData.resetSource = function (name) {
+ this[name] = {};
+ this.old[name] = {};
+ this.updateSource(name);
};
/*
@@ -233,77 +238,95 @@ nmsData.resetSource = function(name) {
* Do not use this directly. Use updateSource().
*
*/
-nmsData._genericUpdater = function(name, cacheok) {
- if (this.stats.outstandingAjaxRequests++ > this._ajaxThreshold) {
- this.stats.outstandingAjaxRequests--;
- this.stats.ajaxOverflow++;
- return;
- }
- var now = "";
- if (this._now != undefined)
- now = "now=" + this._now;
- if (now != "") {
- if (this._sources[name].target.match("\\?"))
- now = "&" + now;
- else
- now = "?" + now;
- }
- var heads = {};
- if (cacheok == false) {
- heads['Cache-Control'] = "max-age=0, no-cache, stale-while-revalidate=0";
- }
+nmsData._genericUpdater = function (name, cacheok) {
+ if (this.stats.outstandingAjaxRequests++ > this._ajaxThreshold) {
+ this.stats.outstandingAjaxRequests--;
+ this.stats.ajaxOverflow++;
+ return;
+ }
+ var now = "";
+ if (this._now != undefined) now = "now=" + this._now;
+ if (now != "") {
+ if (this._sources[name].target.match("\\?")) now = "&" + now;
+ else now = "?" + now;
+ }
+
+ // TODO
+ var heads = {};
+ if (cacheok == false) {
+ heads["Cache-Control"] = "max-age=0, no-cache, stale-while-revalidate=0";
+ }
+
+ /*
+ *
+ * We can be smarter than fetch here. We know that the ETag can be
+ * used to evaluate against our cached copy. If the ETag is a
+ * match, we never have to do the potentially extensive JSON
+ * parsing.
+ *
+ * Also note that we accept weakened ETags too (ETags with W/
+ * prefixed). This is typically if the intermediate cache has
+ * compressed the content for us, so this is fine. DO WE?
+ *
+ * This is particularly important because we poll everything even
+ * though we _know_ it will hit both browser cache and most likely
+ * Varnish. JSON.Parse was one of the biggest CPU hogs before this.
+ */
+
+ const request = new Request(this._sources[name].target + now, {
+ method: "GET",
+ headers: { "Content-Type": "application/json", "If-None-Match": nmsData[name] != undefined ? nmsData[name]["hash"] : null },
+ signal: AbortSignal.timeout(2000), // 2s timeout
+ });
- /*
- * Note that we intentionally set dataType: "text" here.
- *
- * We can be smarter than jQuery here. We know that the ETag can be
- * used to evaluate against our cached copy. If the ETag is a
- * match, we never have to do the potentially extensive JSON
- * parsing.
- *
- * Also note that we accept weakened ETags too (ETags with W/
- * prefixed). This is typically if the intermediate cache has
- * compressed the content for us, so this is fine.
- *
- * This is particularly important because we poll everything even
- * though we _know_ it will hit both browser cache and most likely
- * Varnish. JSON.Parse was one of the biggest CPU hogs before this.
- */
- $.ajax({
- type: "GET",
- headers: heads,
- url: this._sources[name].target + now,
- dataType: "text",
- success: function (indata, textStatus, jqXHR) {
- var etag = jqXHR.getResponseHeader("ETag");
- if (nmsData[name] == undefined || (nmsData[name]['hash'] != etag && nmsData[name]['hash'] != etag.slice(2))) {
- var data = JSON.parse(indata);
- if (name == "ping") {
- nmsData._last = data['time'];
- nmsMap.drawNow();
- }
- nmsData.old[name] = nmsData[name];
- nmsData[name] = data;
- for (var i in nmsData._sources[name].cbs) {
- var tmp2 = nmsData._sources[name].cbs[i];
- if (tmp2.cb != undefined) {
- tmp2.cb(tmp2.cbdata);
- }
- }
- } else {
- for (var j in nmsData._sources[name].cbs) {
- var tmp = nmsData._sources[name].cbs[j];
- if (tmp.cb != undefined && tmp.fresh) {
- nmsData._sources[name].cbs[j].fresh = false;
- tmp.cb(tmp.cbdata);
- }
- }
- nmsData.stats.identicalFetches++;
- }
- nmsData._pulse();
- },
- complete: function(jqXHR, textStatus) {
- nmsData.stats.outstandingAjaxRequests--;
- }
- });
+ nmsData.stats.allRequests++;
+ fetch(request)
+ .then((r) => {
+ nmsData.stats.allFetches++;
+ if (!r.ok && r.status != 304) {
+ throw new Error("Fetch failed with status: " + r.status);
+ }
+ var etag = r.headers.get("etag");
+ if (
+ r.status != 304 && (
+ etag == null ||
+ nmsData[name] == undefined ||
+ (nmsData[name]["hash"] != etag &&
+ nmsData[name]["hash"] != etag.slice(2))
+ )
+ ) {
+ r.json().then((data) => {
+ nmsData.stats.jsonParse++;
+ if (name == "ping") {
+ nmsData._last = data["time"];
+ nmsMap.drawNow();
+ }
+ nmsData.old[name] = nmsData[name];
+ nmsData[name] = data;
+ for (var i in nmsData._sources[name].cbs) {
+ var tmp2 = nmsData._sources[name].cbs[i];
+ if (tmp2.cb != undefined) {
+ tmp2.cb(tmp2.cbdata);
+ }
+ }
+ });
+ } else {
+ for (var j in nmsData._sources[name].cbs) {
+ var tmp = nmsData._sources[name].cbs[j];
+ if (tmp.cb != undefined && tmp.fresh) {
+ nmsData._sources[name].cbs[j].fresh = false;
+ tmp.cb(tmp.cbdata);
+ }
+ }
+ nmsData.stats.identicalFetches++;
+ }
+ })
+ .catch((err) => {
+ nmsData.stats.failedFetches++;
+ console.log("(" + name + "): " + err);
+ })
+ .finally(() => {
+ nmsData._pulse();
+ nmsData.stats.outstandingAjaxRequests--;
+ });
};
diff --git a/web/js/nms-dhcp.js b/web/js/nms-dhcp.js
index dd2e96d..2c91a38 100644
--- a/web/js/nms-dhcp.js
+++ b/web/js/nms-dhcp.js
@@ -1,26 +1,27 @@
"use strict";
-var nmsDhcp = nmsDhcp || {
+var nmsDhcp = nmsDhcp || {};
-}
+nmsDhcp.init = function () {
+ //nmsData.addHandler("dhcpsummary", "nmsDhcpHandler", nmsDhcp.updateSummary);
+};
-nmsDhcp.init = function() {
- nmsData.addHandler("dhcpsummary", "nmsDhcpHandler", nmsDhcp.updateSummary);
-}
-
-nmsDhcp.updateSummary = function() {
- var e = document.getElementById("dhcp-summary");
- if (e == undefined) {
- return;
- }
- e.innerHTML = "";
- if(nmsData.dhcpsummary.dhcp[4] != undefined){
- e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[4] + " IPv4 clients";
- }
- if(nmsData.dhcpsummary.dhcp[4] != undefined && nmsData.dhcpsummary.dhcp[6] != undefined){
- e.innerHTML = e.innerHTML + " | ";
- }
- if(nmsData.dhcpsummary.dhcp[6] != undefined){
- e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[6] + " IPv6 clients";
- }
-}
+nmsDhcp.updateSummary = function () {
+ var e = document.getElementById("dhcp-summary");
+ if (e == undefined) {
+ return;
+ }
+ e.innerHTML = "";
+ if (nmsData.dhcpsummary.dhcp[4] != undefined) {
+ e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[4] + " IPv4 clients";
+ }
+ if (
+ nmsData.dhcpsummary.dhcp[4] != undefined &&
+ nmsData.dhcpsummary.dhcp[6] != undefined
+ ) {
+ e.innerHTML = e.innerHTML + " | ";
+ }
+ if (nmsData.dhcpsummary.dhcp[6] != undefined) {
+ e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[6] + " IPv6 clients";
+ }
+};
diff --git a/web/js/nms-draw-chart.js b/web/js/nms-draw-chart.js
index 4145a9a..2139992 100644
--- a/web/js/nms-draw-chart.js
+++ b/web/js/nms-draw-chart.js
@@ -1,81 +1,92 @@
"use strict";
function setNightModeChart(night) {
- if(night) {
+ if (night) {
Chart.defaults.global.defaultFontColor = "#fff";
- Chart.defaults.scale.gridLines.color = "#444"
- }
- else {
+ Chart.defaults.scale.gridLines.color = "#444";
+ } else {
Chart.defaults.global.defaultFontColor = "#222";
- Chart.defaults.scale.gridLines.color = "#ddd"
+ Chart.defaults.scale.gridLines.color = "#ddd";
}
}
function drawLatency(canvas, sw, chart, callback) {
- var q = encodeURIComponent('SELECT mean("latency") AS "mean_latency" FROM "ping" WHERE time > now() - 1h AND "switch"=\''+sw+'\' GROUP BY time(60s), "version" fill(null)');
+ var q = encodeURIComponent(
+ 'SELECT mean("latency") AS "mean_latency" FROM "ping" WHERE time > now() - 1h AND "switch"=\'' +
+ sw +
+ '\' GROUP BY time(60s), "version" fill(null)'
+ );
var dataset = [];
- $.getJSON( "/query?db=gondul&q="+q, function( results ) {
+ $.getJSON("/query?db=gondul&q=" + q, function (results) {
try {
- results['results'][0]['series'].forEach(function(serie) {
+ results["results"][0]["series"].forEach(function (serie) {
var data = [];
- serie['values'].forEach(function(element) {
- data.push({t: new Date(element[0]), y: element[1]});
+ serie["values"].forEach(function (element) {
+ data.push({ t: new Date(element[0]), y: element[1] });
});
var borderColor = "rgba(0,155,200,255)";
- if(serie['tags']['version'] === "v6") {
+ if (serie["tags"]["version"] === "v6") {
borderColor = "rgba(100,155,100,255)";
}
- dataset.push({data: data, fill:false, borderColor:borderColor, label:serie['tags']['version'] });
+ dataset.push({
+ data: data,
+ fill: false,
+ borderColor: borderColor,
+ label: serie["tags"]["version"],
+ });
});
- if(chart != false) {
+ if (chart != false) {
chart.data.datasets = dataset;
chart.update();
return;
}
- var ctx = document.getElementById(canvas).getContext('2d');
+ var ctx = document.getElementById(canvas).getContext("2d");
var myChart = new Chart(ctx, {
- type: 'line',
+ type: "line",
data: {
- datasets: dataset
+ datasets: dataset,
},
options: {
legend: {
- display: false
+ display: false,
},
scales: {
- xAxes:[{
- type: 'time',
- time: {
- parser: "HH:mm",
- unit: 'minute',
- tooltipFormat: 'HH:mm',
- displayFormats: {
- 'minute': 'HH:mm',
- 'hour': 'HH:mm',
- min: '00:00',
- max: '23:59'
+ xAxes: [
+ {
+ type: "time",
+ time: {
+ parser: "HH:mm",
+ unit: "minute",
+ tooltipFormat: "HH:mm",
+ displayFormats: {
+ minute: "HH:mm",
+ hour: "HH:mm",
+ min: "00:00",
+ max: "23:59",
+ },
},
- }
- }],
- yAxes: [{
- ticks: {
- beginAtZero: true
- }
- }]
+ },
+ ],
+ yAxes: [
+ {
+ ticks: {
+ beginAtZero: true,
+ },
+ },
+ ],
},
responsive: true,
animation: false,
elements: {
line: {
- tension: 0.05
- }
- }
- }
+ tension: 0.05,
+ },
+ },
+ },
});
- } catch(e) {
- }
- if(callback != undefined) {
+ } catch (e) {}
+ if (callback != undefined) {
callback(myChart);
}
});
@@ -87,29 +98,33 @@ function drawSumOfPorts(canvas, sw) {
var gigabit = megabit * 1024;
var terabit = gigabit * 1024;
- var q = encodeURIComponent('SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\''+sw+'\' GROUP BY time(90s),"interface" fill(null)');
+ var q = encodeURIComponent(
+ 'SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\'' +
+ sw +
+ '\' GROUP BY time(90s),"interface" fill(null)'
+ );
var dataset = [];
- $.getJSON( "/query?db=gondul&q="+q, function( results ) {
+ $.getJSON("/query?db=gondul&q=" + q, function (results) {
var bits_in = [];
var bits_out = [];
- results['results'][0]['series'].forEach(function(serie) {
+ results["results"][0]["series"].forEach(function (serie) {
// Bytes in
- serie['values'].forEach(function(element) {
+ serie["values"].forEach(function (element) {
bits_in.push(element[1]);
});
// Bytes out
- serie['values'].forEach(function(element) {
+ serie["values"].forEach(function (element) {
bits_out.push(element[2]);
});
});
- var bits_in_size = bitToSize(Math.max.apply( Math, bits_in ));
- var bits_out_size = bitToSize(Math.max.apply( Math, bits_out ));
+ var bits_in_size = bitToSize(Math.max.apply(Math, bits_in));
+ var bits_out_size = bitToSize(Math.max.apply(Math, bits_out));
var size = 0;
- if(bits_in_size >= bits_out_size) {
+ if (bits_in_size >= bits_out_size) {
size = bits_in_size;
} else {
size = bits_out_size;
@@ -133,107 +148,126 @@ function drawSumOfPorts(canvas, sw) {
size_divider = terabit;
break;
}
- results['results'][0]['series'].forEach(function(serie) {
+ results["results"][0]["series"].forEach(function (serie) {
// Bytes in
var data = [];
- serie['values'].forEach(function(element) {
- data.push({t: new Date(element[0]), y: element[1] / size_divider });
+ serie["values"].forEach(function (element) {
+ data.push({ t: new Date(element[0]), y: element[1] / size_divider });
+ });
+ dataset.push({
+ data: data,
+ backgroundColor: "rgba(58,125,48,200)",
+ label: "Traffic in (" + sizeToText(size) + ")",
});
- dataset.push({data: data, backgroundColor:'rgba(58,125,48,200)', label:'Traffic in (' + sizeToText(size)+')'});
// Bytes out
data = [];
- serie['values'].forEach(function(element) {
- data.push({t: new Date(element[0]), y: -Math.abs(element[2] / size_divider) });
+ serie["values"].forEach(function (element) {
+ data.push({
+ t: new Date(element[0]),
+ y: -Math.abs(element[2] / size_divider),
+ });
+ });
+ dataset.push({
+ data: data,
+ backgroundColor: "rgba(84,84,142,225)",
+ label: "Traffic out (" + sizeToText(size) + ")",
});
- dataset.push({data: data, backgroundColor:'rgba(84,84,142,225)', label:'Traffic out (' + sizeToText(size)+')'});
});
// Draw the chart
- var ctx = document.getElementById(canvas).getContext('2d');
+ var ctx = document.getElementById(canvas).getContext("2d");
var myChart = new Chart(ctx, {
- type: 'line',
+ type: "line",
data: {
- datasets: dataset
+ datasets: dataset,
},
options: {
legend: {
- display: false
+ display: false,
},
scales: {
- xAxes:[{
- type: 'time',
- time: {
- parser: "HH:mm",
- unit: 'minute',
- tooltipFormat: 'HH:mm',
- displayFormats: {
- 'minute': 'HH:mm',
- 'hour': 'HH:mm',
- min: '00:00',
- max: '23:59'
+ xAxes: [
+ {
+ type: "time",
+ time: {
+ parser: "HH:mm",
+ unit: "minute",
+ tooltipFormat: "HH:mm",
+ displayFormats: {
+ minute: "HH:mm",
+ hour: "HH:mm",
+ min: "00:00",
+ max: "23:59",
+ },
+ },
+ },
+ ],
+ yAxes: [
+ {
+ stacked: true,
+ ticks: {
+ callback: function (label, index, labels) {
+ return Math.abs(label) + " " + sizeToText(size);
+ },
+ },
+ scaleLabel: {
+ display: true,
+ labelString: sw + " - All ports",
},
- }
- }],
- yAxes: [{
- stacked: true,
- ticks: {
- callback: function(label, index, labels) {
- return Math.abs(label)+' '+sizeToText(size);
- }
},
- scaleLabel: {
- display: true,
- labelString: sw+' - All ports'
- }
- }]
+ ],
},
responsive: true,
animation: false,
elements: {
point: {
- radius: 0
+ radius: 0,
},
line: {
- tension: 0
- }
- }
- }
+ tension: 0,
+ },
+ },
+ },
});
});
}
-
function drawPort(canvas, sw, port) {
-
var kilobit = 1024;
var megabit = kilobit * 1024;
var gigabit = megabit * 1024;
var terabit = gigabit * 1024;
- var q = encodeURIComponent('SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\''+sw+'\' AND "interface"=\''+port+'\' GROUP BY time(30s) fill(null)');
+ var q = encodeURIComponent(
+ 'SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\'' +
+ sw +
+ "' AND \"interface\"='" +
+ port +
+ "' GROUP BY time(30s) fill(null)"
+ );
var dataset = [];
- $.getJSON( "/query?db=gondul&q="+q, function( results ) {
- var serie = results['results'][0]['series'][0];
+ $.getJSON("/query?db=gondul&q=" + q, function (results) {
+ var serie = results["results"][0]["series"][0];
var bits_in = [];
var bits_out = [];
// Bytes in
- serie['values'].forEach(function(element) {
+ serie["values"].forEach(function (element) {
bits_in.push(element[1]);
});
// Bytes out
- serie['values'].forEach(function(element) {
+ serie["values"].forEach(function (element) {
bits_out.push(element[2]);
});
- var bits_in_size = bitToSize(Math.max.apply( Math, bits_in ));
- var bits_out_size = bitToSize(Math.max.apply( Math, bits_out ));
+ var bits_in_size = bitToSize(Math.max.apply(Math, bits_in));
+ var bits_out_size = bitToSize(Math.max.apply(Math, bits_out));
var size = 0;
- if(bits_in_size >= bits_out_size) {
+ if (bits_in_size >= bits_out_size) {
size = bits_in_size;
} else {
size = bits_out_size;
@@ -260,107 +294,115 @@ function drawPort(canvas, sw, port) {
// Bytes in
var data = [];
- serie['values'].forEach(function(element) {
- data.push({t: new Date(element[0]), y: element[1] / size_divider });
+ serie["values"].forEach(function (element) {
+ data.push({ t: new Date(element[0]), y: element[1] / size_divider });
+ });
+ dataset.push({
+ data: data,
+ backgroundColor: "rgba(58,125,48,200)",
+ label: "Traffic in (" + sizeToText(size) + ")",
});
- dataset.push({data: data, backgroundColor:'rgba(58,125,48,200)', label:'Traffic in (' + sizeToText(size)+')'});
// Bytes out
data = [];
- serie['values'].forEach(function(element) {
- data.push({t: new Date(element[0]), y: -Math.abs(element[2] / size_divider) });
+ serie["values"].forEach(function (element) {
+ data.push({
+ t: new Date(element[0]),
+ y: -Math.abs(element[2] / size_divider),
+ });
+ });
+ dataset.push({
+ data: data,
+ backgroundColor: "rgba(84,84,142,225)",
+ label: "Traffic out (" + sizeToText(size) + ")",
});
- dataset.push({data: data, backgroundColor:'rgba(84,84,142,225)', label:'Traffic out (' + sizeToText(size)+')'});
-
// Draw the chart
- var ctx = document.getElementById(canvas).getContext('2d');
+ var ctx = document.getElementById(canvas).getContext("2d");
var myChart = new Chart(ctx, {
- type: 'line',
+ type: "line",
data: {
- datasets: dataset
+ datasets: dataset,
},
options: {
scales: {
- xAxes:[{
- type: 'time',
- time: {
- parser: "HH:mm",
- unit: 'minute',
- tooltipFormat: 'HH:mm',
- displayFormats: {
- 'minute': 'HH:mm',
- 'hour': 'HH:mm',
- min: '00:00',
- max: '23:59'
+ xAxes: [
+ {
+ type: "time",
+ time: {
+ parser: "HH:mm",
+ unit: "minute",
+ tooltipFormat: "HH:mm",
+ displayFormats: {
+ minute: "HH:mm",
+ hour: "HH:mm",
+ min: "00:00",
+ max: "23:59",
+ },
+ },
+ },
+ ],
+ yAxes: [
+ {
+ ticks: {
+ callback: function (label, index, labels) {
+ return Math.abs(label) + " " + sizeToText(size);
+ },
+ },
+ scaleLabel: {
+ display: true,
+ labelString: sw + " - " + port,
},
- }
- }],
- yAxes: [{
- ticks: {
- callback: function(label, index, labels) {
- return Math.abs(label)+' '+sizeToText(size);
- }
},
- scaleLabel: {
- display: true,
- labelString: sw+' - '+port
- }
- }]
+ ],
},
responsive: true,
animation: false,
elements: {
line: {
- tension: 0
- }
- }
-
- }
+ tension: 0,
+ },
+ },
+ },
});
});
}
-
function bitToSize(bits) {
var kilobit = 1024;
var megabit = kilobit * 1024;
var gigabit = megabit * 1024;
var terabit = gigabit * 1024;
- if(bits >= 0 && bits < kilobit) {
+ if (bits >= 0 && bits < kilobit) {
return 0;
- }
- else if(bits >= kilobit && bits < megabit){
+ } else if (bits >= kilobit && bits < megabit) {
return 1;
- }
- else if(bits >= megabit && bits < gigabit){
+ } else if (bits >= megabit && bits < gigabit) {
return 2;
- }
- else if(bits >= gigabit && bits < terabit){
+ } else if (bits >= gigabit && bits < terabit) {
return 3;
- }
- else if(bits >= terabit) {
+ } else if (bits >= terabit) {
return 4;
}
}
function sizeToText(size) {
- switch(size) {
+ switch (size) {
case 0:
- return 'bit/s';
+ return "bit/s";
break;
case 1:
- return 'Kb/s';
+ return "Kb/s";
break;
case 2:
- return 'Mb/s';
+ return "Mb/s";
break;
case 3:
- return 'Gb/s';
+ return "Gb/s";
break;
case 4:
- return 'Tb/s';
+ return "Tb/s";
break;
}
}
diff --git a/web/js/nms-fetch.js b/web/js/nms-fetch.js
new file mode 100644
index 0000000..da2162c
--- /dev/null
+++ b/web/js/nms-fetch.js
@@ -0,0 +1,38 @@
+async function getData(url) {
+ var data;
+ const request = new Request(url, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ await fetch(request)
+ .then((response) => response.json())
+ .then((json) => {
+ data = json;
+ })
+ .catch(console.error);
+
+ return data;
+}
+
+async function postData(url, data) {
+ var data;
+ const request = new Request(url, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(data)
+ });
+
+ await fetch(request)
+ .then((response) => response.json())
+ .then((json) => {
+ data = json;
+ })
+ .catch(console.error);
+
+ return data;
+}
diff --git a/web/js/nms-info-box.js b/web/js/nms-info-box.js
index 1a15e6c..f79fc7a 100644
--- a/web/js/nms-info-box.js
+++ b/web/js/nms-info-box.js
@@ -29,220 +29,224 @@
* Basic configuration
*/
var nmsInfoBox = nmsInfoBox || {
- stats: {},
- _container: false, //Container window
- _windowHandler: false, //Window handler
- _sw: false, //Name of last switch opened, used for toggle-click
- _windowTypes: [
- {
- 'id': 'switchInfo',
- 'title': 'Switch info',
- 'views': {
- 'initial': {
- 'name': 'Summary',
- 'panels': ['switchLatency','switchSummary','switchComments'],
- 'public': true
- },
- 'ports': {
- 'name': 'Ports',
- 'panels': ['switchPorts']
- },
- 'misc': {
- 'name': 'SNMP',
- 'panels': ['switchSNMP:misc']
- },
- 'links': {
- 'name': 'Links',
- 'panels': ['switchLinks']
- },
- 'edit': {
- 'name': 'Edit settings',
- 'panels': ['switchEdit']
- }
- }
- },
- {
- 'id': 'networkInfo',
- 'title': 'Network info',
- 'views': {
- 'initial': {
- 'name': 'Summary',
- 'panels': ['networkSummary']
- },
- 'edit': {
- 'name': 'Edit settings',
- 'panels': ['networkEdit']
- }
- }
- },
- {
- 'id': 'addSwitch',
- 'title': 'Add new switch(es)',
- 'views': {
- 'initial': {
- 'name': 'Add switch',
- 'panels': ['switchAdd']
- }
- }
- },
- {
- 'id': 'addNetwork',
- 'title': 'Add new network(s)',
- 'views': {
- 'initial': {
- 'name': 'Add network',
- 'panels': ['networkAdd']
- }
- }
- },
- {
- 'id': 'searchHelp',
- 'title': 'Search help',
- 'views': {
- 'initial': {
- 'name': 'Search help',
- 'panels': ['searchHelp']
- }
- }
- },
- {
- 'id': 'searchResults',
- 'title': 'Search Results',
- 'views': {
- 'initial': {
- 'name': 'Search Results',
- 'panels': ['searchResults']
- }
- }
- },
- {
- 'id': 'listNetwork',
- 'title': 'Networks',
- 'views': {
- 'initial': {
- 'name': 'List all networks',
- 'panels': ['listNetworks']
- }
- }
- },
-],
- _panelTypes: {} //Populate by using the nmsInfoBox.addPanelType method
+ stats: {},
+ _container: false, //Container window
+ _windowHandler: false, //Window handler
+ _sw: false, //Name of last switch opened, used for toggle-click
+ _windowTypes: [
+ {
+ id: "switchInfo",
+ title: "Switch info",
+ views: {
+ initial: {
+ name: "Summary",
+ panels: ["switchLatency", "switchSummary", "switchLinks", "switchComments"],
+ public: true,
+ },
+ ports: {
+ name: "Ports",
+ panels: ["switchPorts"],
+ },
+ misc: {
+ name: "SNMP",
+ panels: ["switchSNMP:misc"],
+ },
+ edit: {
+ name: "Settings",
+ panels: ["switchEdit"],
+ },
+ },
+ },
+ {
+ id: "networkInfo",
+ title: "Network info",
+ views: {
+ initial: {
+ name: "Summary",
+ panels: ["networkSummary"],
+ },
+ edit: {
+ name: "Settings",
+ panels: ["networkEdit"],
+ },
+ },
+ },
+ {
+ id: "addSwitch",
+ title: "Add new switch(es)",
+ views: {
+ initial: {
+ name: "Add switch",
+ panels: ["switchAdd"],
+ },
+ },
+ },
+ {
+ id: "addNetwork",
+ title: "Add new network(s)",
+ views: {
+ initial: {
+ name: "Add network",
+ panels: ["networkAdd"],
+ },
+ },
+ },
+ {
+ id: "searchHelp",
+ title: "Search help",
+ views: {
+ initial: {
+ name: "Search help",
+ panels: ["searchHelp"],
+ },
+ },
+ },
+ {
+ id: "searchResults",
+ title: "Search Results",
+ views: {
+ initial: {
+ name: "Search Results",
+ panels: ["searchResults"],
+ },
+ },
+ },
+ {
+ id: "listNetwork",
+ title: "Networks",
+ views: {
+ initial: {
+ name: "List all networks",
+ panels: ["listNetworks"],
+ },
+ },
+ },
+ {
+ id: "debug",
+ title: "Debug",
+ views: {
+ initial: {
+ name: "Debug",
+ panels: ["debugInfo"],
+ },
+ stats: {
+ name: "Stats",
+ panels: ["debugStats"],
+ },
+ },
+ },
+ ],
+ _panelTypes: {}, //Populate by using the nmsInfoBox.addPanelType method
};
/*
* Shows a window, and triggers initial load if needed
*/
-nmsInfoBox.showWindow = function (windowName,argument) {
- if(windowName == "switchInfo" && argument != '' && argument == this._sw) {
- nmsInfoBox.hide();
- return;
- }
-
- if(!this._container)
- this._load();
- if(!windowName)
- windowName = 'switchInfo';
-
- this._sw = argument;
-
- this._windowHandler.showWindow(windowName,argument)
-
- $(this._windowHandler.getTitleObj()).on('mousedown', function(e) {
- var cont = $(nmsInfoBox._container);
- var dimensions = nmsInfoBox._container.getBoundingClientRect();
- var startLeft = dimensions.left;
- var startTop = dimensions.top;
- nmsInfoBox.startDrag(e.screenX, e.screenY, startLeft, startTop);
- });
- $(this._windowHandler.getTitleObj()).on('mouseup',nmsInfoBox.stopDrag);
+nmsInfoBox.showWindow = function (windowName, argument) {
+ if (windowName == "switchInfo" && argument != "" && argument == this._sw) {
+ nmsInfoBox.hide();
+ return;
+ }
+
+ if (!this._container) this._load();
+ if (!windowName) windowName = "switchInfo";
+
+ this._sw = argument;
+
+ this._windowHandler.showWindow(windowName, argument);
};
/*
* Internal function to load and register the initial html objects
*/
-nmsInfoBox._load = function() {
- var infoBox = document.createElement("div");
- infoBox.classList.add("panel", "panel-default");
- var title = document.createElement("div");
- title.id = "info-box-title";
- title.classList.add("panel-heading");
- var nav = document.createElement("div");
- nav.id = "info-box-nav";
- nav.classList.add("panel-body");
- var body = document.createElement("div");
- body.id = "info-box-body";
- body.classList.add("panel-body");
-
- infoBox.appendChild(title);
- infoBox.appendChild(nav);
- infoBox.appendChild(body);
-
- this._container = document.getElementById("info-box-container");
- this._container.appendChild(infoBox);
-
- this._windowHandler = new windowHandler();
- this._windowHandler.setContainerObj(document.getElementById("info-box-container"));
- this._windowHandler.setTitleObj(document.getElementById("info-box-title"));
- this._windowHandler.setBodyObj(document.getElementById("info-box-body"));
- this._windowHandler.setNavObj(document.getElementById("info-box-nav"));
- this._windowHandler.setPanelTypes(this._panelTypes);
- this._windowHandler.setWindowTypes(this._windowTypes);
+nmsInfoBox._load = function () {
+ var modalBox = document.createElement("div");
+ modalBox.classList.add("modal", "show");
+ modalBox.style = "display: block;";
+ // did not work
+ // modalBox.setAttribute('data-bs-backdrop', "false");
+
+ var dialogBox = document.createElement("div");
+ dialogBox.classList.add(
+ "modal-dialog",
+ "modal-lg",
+ "modal-dialog-scrollable"
+ );
+
+ var dialogContentBox = document.createElement("div");
+ dialogContentBox.classList.add("modal-content");
+
+ var dialogHeader = document.createElement("div");
+ dialogHeader.classList.add("modal-header");
+
+ modalBox.appendChild(dialogBox);
+
+ dialogBox.appendChild(dialogContentBox);
+
+ var title = document.createElement("div");
+ title.id = "info-box-title";
+ title.classList.add("modal-title");
+
+ var nav = document.createElement("div");
+ nav.id = "info-box-nav";
+
+ var body = document.createElement("div");
+ body.id = "info-box-body";
+ body.classList.add("modal-body");
+
+ var closeButton = document.createElement("button");
+ // <button type="button" class="btn-close" data-bs-dismiss="modal" data-bs-target="#my-modal" aria-label="Close"></button>
+ closeButton.classList.add("btn-close");
+ closeButton.onclick = function () {
+ nmsInfoBox.hide();
+ };
+
+ dialogContentBox.appendChild(dialogHeader);
+ dialogContentBox.appendChild(body);
+ dialogHeader.appendChild(title);
+ dialogHeader.appendChild(nav);
+ dialogHeader.appendChild(closeButton);
+
+ this._container = document.getElementById("info-box-container");
+ this._container.appendChild(modalBox);
+
+ this._windowHandler = new windowHandler();
+ this._windowHandler.setContainerObj(
+ document.getElementById("info-box-container")
+ );
+ this._windowHandler.setTitleObj(document.getElementById("info-box-title"));
+ this._windowHandler.setBodyObj(document.getElementById("info-box-body"));
+ this._windowHandler.setNavObj(document.getElementById("info-box-nav"));
+ this._windowHandler.setPanelTypes(this._panelTypes);
+ this._windowHandler.setWindowTypes(this._windowTypes);
};
/*
* Adds a panel type to _panelTypes for usage in windows and views
*/
nmsInfoBox.addPanelType = function (id, obj) {
- this._panelTypes[id] = obj;
+ this._panelTypes[id] = obj;
};
-
/*
* Hide the active window and tell it to unload
*/
-nmsInfoBox.hide = function() {
- this._sw = false;
- if (this._windowHandler != undefined && this._windowHandler.hide != undefined) {
- this._windowHandler.hide();
- this._windowHandler.unloadWindow();
- }
- nmsInfoBox.resetDrag();
-};
-
-/*
- * Start window drag
- */
-nmsInfoBox.startDrag = function(mouseStartX, mouseStartY, startLeft, startTop) {
- document.onmousemove = function(e) {
- var mouseOffsetX = e.screenX - mouseStartX;
- var mouseOffsetY = e.screenY - mouseStartY;
- $(nmsInfoBox._container).css('left', startLeft + mouseOffsetX + 'px');
- $(nmsInfoBox._container).css('top', startTop + mouseOffsetY + 'px');
- };
-};
-
-/*
- * Reset drag
- */
-nmsInfoBox.resetDrag = function() {
- nmsInfoBox.stopDrag();
- $(nmsInfoBox._container).css('left','');
- $(nmsInfoBox._container).css('top','');
-};
-
-/*
- * Stop window drag
- */
-nmsInfoBox.stopDrag = function() {
- document.onmousemove = null;
+nmsInfoBox.hide = function () {
+ this._sw = false;
+ if (
+ this._windowHandler != undefined &&
+ this._windowHandler.hide != undefined
+ ) {
+ this._windowHandler.hide();
+ this._windowHandler.unloadWindow();
+ }
};
/*
* Click a switch and display it.
*/
-nmsInfoBox.click = function(sw)
-{
- this.showWindow("switchInfo",sw);
+nmsInfoBox.click = function (sw) {
+ this.showWindow("switchInfo", sw);
};
/*
@@ -262,159 +266,163 @@ nmsInfoBox.click = function(sw)
*
*/
var windowHandler = function () {
- this.containerObj = false;
- this.titleObj = false;
- this.navObj = false;
- this.bodyObj = false;
- this._panels = {};
- this._view = "";
- this._viewId = {};
- this._window = {};
- this.windowTypes = false;
- this.panelTypes = false;
- this.argument = false;
- this.show = function () {
- this.containerObj.classList.remove("hidden");
- };
- this.hide = function () {
- this.containerObj.classList.add("hidden");
- };
- this.setContainerObj = function (containerObj) {
- this.containerObj = containerObj;
- };
- this.setTitleObj = function (titleObj) {
- this.titleObj = titleObj;
- };
- this.getTitleObj = function (titleObj) {
- return this.titleObj;
- };
- this.setNavObj = function (navObj) {
- this.navObj = navObj;
- };
- this.setBodyObj = function (bodyObj) {
- this.bodyObj = bodyObj;
- };
- this.setPanelTypes = function (panelTypes) {
- this.panelTypes = panelTypes;
- };
- this.setWindowTypes = function (windowTypes) {
- this.windowTypes = {};
- for(var i in windowTypes) {
- this.windowTypes[windowTypes[i].id] = windowTypes[i];
- }
- };
- this.setArgument = function (argument) {
- if(this.argument != argument) {
- this.argument = argument;
- this.showView(this._view);
- }
- };
- this.showPanel = function (panelName) {
- var panelArray = panelName.split(":");
- var panelName = panelArray[0];
- var panelMode = panelArray[1];
- if(this.panelTypes[panelName]) {
- var id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2);
- var panel = new this.panelTypes[panelName];
- panel.setId(id);
- if(!!panelMode)
- panel.setMode(panelMode);
- panel.load(this.bodyObj,this.argument);
- this._panels[id] = panel;
- }
- };
- this.showTitle = function (title) {
- this.titleObj.innerHTML = '<button type="button" class="close" aria-label="Close" onclick="nmsInfoBox.hide();" style="float: right;"><span aria-hidden="true">&times;</span></button><h4>' + title + '</h4>';
- };
- this.showNav = function () {
- if(!this._window.views)
- this.navObj.innerHTML = '';
- var output = '<ul class="nav nav-pills small">';
- var i = 0;
- for(var view in this._window.views) {
- var viewObj = this._window.views[view];
- var active = '';
- if (viewObj.public == null || viewObj.public == false)
- active = ' class="gondul-is-private" '
- if(this._view == view)
- active = ' class="active" ';
- output += '<li' + active + '><a class="' + view + '" aria-label="' + viewObj.name + '" onclick="nmsInfoBox._windowHandler.showView(\'' + view + '\');">' + viewObj.name + '</a></li> ';
- i++;
- }
- output += '</ul>';
- if(i < 2) {
- this.navObj.innerHTML = '';
- } else {
- this.navObj.innerHTML = output;
- }
- };
- this.addWindow = function (windowObj) {
- this.windowTypes[windowObj.id] = windowObj;
- };
- this.showWindow = function (windowName,argument) {
- if(!this.windowTypes[windowName])
- return;
- this.unloadWindow();
- this.argument = argument;
- this._window = this.windowTypes[windowName];
- this.showTitle(this._window.title + " " + (argument ? argument : ""));
- this.showView();
- this.show();
- };
- this.showView = function (viewId) {
- if(!viewId || viewId == '') {
- if (this._viewId[this._window.id] == undefined)
- viewId = "initial";
- else
- viewId = this._viewId[this._window.id];
- } else {
- this._viewId[this._window.id] = viewId;
- }
- if(!this._window.views || !this._window.views[viewId])
- return;
- this.unloadView();
- for(var panel in this._window.views[viewId].panels) {
- this.showPanel(this._window.views[viewId].panels[panel]);
- }
- this._view = viewId;
- this.showNav();
- };
- this.removePanel = function (panelId) {
- if(!!panelId)
- this.unloadPanel(panelId);
- };
- this.unloadView = function () {
- this.unloadPanel();
- };
- this.unloadWindow = function() {
- this.hide();
- this.unloadPanel();
- };
- this.unloadPanel = function (panelId) {
- if(!panelId) {
- for(var i in this._panels) {
- this._panels[i].unload();
- }
- this._panels = {};
- } else {
- try {
- this._panels[panelId].unload();
- } catch (e) {}
- delete this._panels[panelId];
- }
- };
- //Method for triggering a function in an active panel
- this.doInPanel = function (panelId, action, argument) {
- if(!this._panels[panelId])
- return;
- if(typeof this._panels[panelId][action] === "function") {
- if(!argument) {
- this._panels[panelId][action]();
- } else {
- this._panels[panelId][action](argument);
- }
- }
- };
+ this.containerObj = false;
+ this.titleObj = false;
+ this.navObj = false;
+ this.bodyObj = false;
+ this._panels = {};
+ this._view = "";
+ this._viewId = {};
+ this._window = {};
+ this.windowTypes = false;
+ this.panelTypes = false;
+ this.argument = false;
+ this.show = function () {
+ this.containerObj.classList.remove("d-none");
+ };
+ this.hide = function () {
+ this.containerObj.classList.add("d-none");
+ };
+ this.setContainerObj = function (containerObj) {
+ this.containerObj = containerObj;
+ };
+ this.setTitleObj = function (titleObj) {
+ this.titleObj = titleObj;
+ };
+ this.getTitleObj = function (titleObj) {
+ return this.titleObj;
+ };
+ this.setNavObj = function (navObj) {
+ this.navObj = navObj;
+ };
+ this.setBodyObj = function (bodyObj) {
+ this.bodyObj = bodyObj;
+ };
+ this.setPanelTypes = function (panelTypes) {
+ this.panelTypes = panelTypes;
+ };
+ this.setWindowTypes = function (windowTypes) {
+ this.windowTypes = {};
+ for (var i in windowTypes) {
+ this.windowTypes[windowTypes[i].id] = windowTypes[i];
+ }
+ };
+ this.setArgument = function (argument) {
+ if (this.argument != argument) {
+ this.argument = argument;
+ this.showView(this._view);
+ }
+ };
+ this.showPanel = function (panelName) {
+ var panelArray = panelName.split(":");
+ var panelName = panelArray[0];
+ var panelMode = panelArray[1];
+ if (this.panelTypes[panelName]) {
+ var id = (Math.random().toString(36) + "00000000000000000").slice(
+ 2,
+ 10 + 2
+ );
+ var panel = new this.panelTypes[panelName]();
+ panel.setId(id);
+ if (!!panelMode) panel.setMode(panelMode);
+ panel.load(this.bodyObj, this.argument);
+ this._panels[id] = panel;
+ }
+ };
+ this.showTitle = function (title) {
+ this.titleObj.innerHTML = '<h1 class="modal-title fs-4">' + title + "</h1>";
+ };
+ this.showNav = function () {
+ if (!this._window.views) this.navObj.innerHTML = "";
+ var output = '<ul class="nav nav-tabs">';
+ var i = 0;
+ for (var view in this._window.views) {
+ var viewObj = this._window.views[view];
+ var active = '><a class="nav-link ';
+ if (this._view == view) {
+ active = '><a class="nav-link active ';
+ }
+ output +=
+ "<li" +
+ ' class="nav-item gondul-is-private" ' +
+ active +
+ view +
+ '" aria-label="' +
+ viewObj.name +
+ '" onclick="nmsInfoBox._windowHandler.showView(\'' +
+ view +
+ "');\">" +
+ viewObj.name +
+ "</a></li> ";
+ i++;
+ }
+ if (i < 2) {
+ this.navObj.innerHTML = "";
+ } else {
+ this.navObj.innerHTML = output;
+ }
+ };
+ this.addWindow = function (windowObj) {
+ this.windowTypes[windowObj.id] = windowObj;
+ };
+ this.showWindow = function (windowName, argument) {
+ if (!this.windowTypes[windowName]) return;
+ this.unloadWindow();
+ this.argument = argument;
+ this._window = this.windowTypes[windowName];
+ this.showTitle(this._window.title + " " + (argument ? argument : ""));
+ this.showView();
+ this.show();
+ };
+ this.showView = function (viewId) {
+ if (!viewId || viewId == "") {
+ if (this._viewId[this._window.id] == undefined) viewId = "initial";
+ else viewId = this._viewId[this._window.id];
+ } else {
+ this._viewId[this._window.id] = viewId;
+ }
+ if (!this._window.views || !this._window.views[viewId]) return;
+ this.unloadView();
+ for (var panel in this._window.views[viewId].panels) {
+ this.showPanel(this._window.views[viewId].panels[panel]);
+ }
+ this._view = viewId;
+ this.showNav();
+ };
+ this.removePanel = function (panelId) {
+ if (!!panelId) this.unloadPanel(panelId);
+ };
+ this.unloadView = function () {
+ this.unloadPanel();
+ };
+ this.unloadWindow = function () {
+ this.hide();
+ this.unloadPanel();
+ };
+ this.unloadPanel = function (panelId) {
+ if (!panelId) {
+ for (var i in this._panels) {
+ this._panels[i].unload();
+ }
+ this._panels = {};
+ } else {
+ try {
+ this._panels[panelId].unload();
+ } catch (e) {}
+ delete this._panels[panelId];
+ }
+ };
+ //Method for triggering a function in an active panel
+ this.doInPanel = function (panelId, action, argument) {
+ if (!this._panels[panelId]) return;
+ if (typeof this._panels[panelId][action] === "function") {
+ if (!argument) {
+ this._panels[panelId][action]();
+ } else {
+ this._panels[panelId][action](argument);
+ }
+ }
+ };
};
/*
@@ -432,122 +440,125 @@ var windowHandler = function () {
* };
*
*/
-var nmsInfoPanel = function nmsInfoPanel(name,id) {
- this.name = name;
- this.id = id;
- this.sw = false;
- this.container = false;
- this.classList = ['info-panel'];
- this.me = false;
- this.handlers = [];
- this.mode = "initial";
-
- if(!this.id)
- this.id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2);
-
- //Method for loading the general panel properties
- this.load = function (container,argument) {
- this.container = container;
- this.sw = argument;
- this.me = document.createElement("div");
- this.me.id = this.id;
- for(var i in this.classList)
- this.me.classList.add(this.classList[i]);
- this.container.appendChild(this.me);
- this.init(argument);
- };
-
- //Method for making this specific panel-instance ready for first refresh
- //Override in children when any custom init-functionality is needed
- this.init = function (argument) {
- this.refresh("init");
- };
-
- //Methods for getting and setting panel id
- this.setId = function (id) {
- this.id = id;
- };
- this.getId = function () {
- return this.id;
- };
-
- //Methods for setting and getting mode (default "initial")
- this.setMode = function (mode) {
- this.mode = mode;
- };
- this.getMode = function () {
- return this.mode;
- };
-
- //Internal method for rendering content
- this._render = function (newContent) {
- if(!newContent || !this.me)
- return;
- this.me.innerHTML = newContent.outerHTML;
- };
-
- //Helper method for rendering error messages in a unified way
- this._renderError = function (message) {
- var error = document.createElement("div");
- error.className = "alert alert-info";
- error.innerHTML = message;
- this._render(error);
- };
-
- //Method for unloading any local data
- this.unload = function () {
- if(!this.me)
- return;
- this.me.remove();
- this.removeHandlers();
- this.sw = false;
- this.container = false;
- this.me = false;
- this.id = false;
- };
-
- //Method for loading new data and triggering a _render if needed
- //Implemented in children only
- this.refresh = function (reason) {};
-
- //Methods for adding and removing classes
- this.addClass = function (className) {
- if(this.classList.indexOf(className) == -1) {
- this.classList.push(className);
- this.me.classList.add(className);
- }
- };
- this.removeClass = function (className) {
- var index = this.classList.indexOf(className);
- if(index != -1) {
- this.classList.splice(index,1);
- this.me.classList.remove(className);
- }
- };
-
- //Method for registering a data handler (lets us clean them up later)
- this.addHandler = function (dataType,targetFunction) {
- if(!targetFunction)
- targetFunction = "refresh";
- nmsData.addHandler(dataType,this.id,(this[targetFunction]).bind(this),"handler-"+dataType);
- this.handlers.push(dataType);
- };
-
- //Method for removing all handlers we have registered
- this.removeHandlers = function () {
- for(var i in this.handlers) {
- nmsData.unregisterHandler(this.handlers[i],this.id);
- }
- };
-
- //Method for checking if we have handlers registered
- this.hasHandler = function (dataType) {
- for(var i in this.handlers) {
- if(this.handlers[i] == dataType)
- return true;
- }
- return false;
- };
+var nmsInfoPanel = function nmsInfoPanel(name, id) {
+ this.name = name;
+ this.id = id;
+ this.sw = false;
+ this.container = false;
+ this.classList = ["info-panel"];
+ this.me = false;
+ this.handlers = [];
+ this.mode = "initial";
+
+ if (!this.id)
+ this.id = (Math.random().toString(36) + "00000000000000000").slice(
+ 2,
+ 10 + 2
+ );
+
+ //Method for loading the general panel properties
+ this.load = function (container, argument) {
+ this.container = container;
+ this.sw = argument;
+ this.me = document.createElement("div");
+ this.me.id = this.id;
+ for (var i in this.classList) this.me.classList.add(this.classList[i]);
+ this.container.appendChild(this.me);
+ this.init(argument);
+ };
+
+ //Method for making this specific panel-instance ready for first refresh
+ //Override in children when any custom init-functionality is needed
+ this.init = function (argument) {
+ this.refresh("init");
+ };
+
+ //Methods for getting and setting panel id
+ this.setId = function (id) {
+ this.id = id;
+ };
+ this.getId = function () {
+ return this.id;
+ };
+
+ //Methods for setting and getting mode (default "initial")
+ this.setMode = function (mode) {
+ this.mode = mode;
+ };
+ this.getMode = function () {
+ return this.mode;
+ };
+
+ //Internal method for rendering content
+ this._render = function (newContent) {
+ if (!newContent || !this.me) return;
+ this.me.innerHTML = newContent.outerHTML;
+ };
+
+ //Helper method for rendering error messages in a unified way
+ this._renderError = function (message) {
+ var error = document.createElement("div");
+ error.className = "alert alert-info";
+ error.innerHTML = message;
+ this._render(error);
+ };
+
+ //Method for unloading any local data
+ this.unload = function () {
+ if (!this.me) return;
+ this.me.remove();
+ this.removeHandlers();
+ this.sw = false;
+ this.container = false;
+ this.me = false;
+ this.id = false;
+ };
+
+ //Method for loading new data and triggering a _render if needed
+ //Implemented in children only
+ this.refresh = function (reason) {};
+
+ //Methods for adding and removing classes
+ this.addClass = function (className) {
+ if (this.classList.indexOf(className) == -1) {
+ this.classList.push(className);
+ this.me.classList.add(className);
+ }
+ };
+ this.removeClass = function (className) {
+ var index = this.classList.indexOf(className);
+ if (index != -1) {
+ this.classList.splice(index, 1);
+ this.me.classList.remove(className);
+ }
+ };
+
+ //Method for registering a data handler (lets us clean them up later)
+ this.addHandler = function (dataType, targetFunction) {
+ if (!targetFunction) targetFunction = "refresh";
+ nmsData.addHandler(
+ dataType,
+ this.id,
+ this[targetFunction].bind(this),
+ "handler-" + dataType
+ );
+ this.handlers.push(dataType);
+ };
+
+ //Method for removing all handlers we have registered
+ this.removeHandlers = function () {
+ for (var i in this.handlers) {
+ nmsData.unregisterHandler(this.handlers[i], this.id);
+ }
+ };
+
+ //Method for checking if we have handlers registered
+ this.hasHandler = function (dataType) {
+ for (var i in this.handlers) {
+ if (this.handlers[i] == dataType) return true;
+ }
+ return false;
+ };
};
/*
@@ -559,220 +570,228 @@ var nmsInfoPanel = function nmsInfoPanel(name,id) {
*
*/
var switchSNMPPanel = function () {
- nmsInfoPanel.call(this,"switchSNMP");
- this.init = function() {
- this.refresh();
- };
- this.refresh = function(reason) {
- var domObj = document.createElement("div");
- domObj.classList.add("panel-group");
-
- try {
- var snmpJson = nmsData.snmp.snmp[this.sw][this.mode];
- } catch(e) {
- this._renderError("Waiting for data.");
- return;
- }
-
- for(var obj in snmpJson) {
-
- var cleanObj = obj.replace(/\W+/g, "");
-
- var groupObj = document.createElement("div");
- groupObj.classList.add("panel","panel-default","nms-panel-small");
- groupObj.innerHTML = '<a class="panel-heading collapse-controller" style="display:block;" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + obj + '</a>';
-
- var groupObjCollapse = document.createElement("div");
- groupObjCollapse.id = cleanObj + "-group";
- groupObjCollapse.classList.add("collapse");
-
- var panelBodyObj = document.createElement("div");
- panelBodyObj.classList.add("panel-body");
-
- var tableObj = document.createElement("table");
- tableObj.classList.add("table","table-condensed");
-
- var tbody = document.createElement("tbody");
-
- for(var prop in snmpJson[obj]) {
- var propObj = document.createElement("tr");
- propObj.innerHTML = '<td>' + prop + '</td><td>' + snmpJson[obj][prop] + '</td>';
- tbody.appendChild(propObj);
- }
-
- tableObj.appendChild(tbody);
- panelBodyObj.appendChild(tableObj);
- groupObjCollapse.appendChild(panelBodyObj);
- groupObj.appendChild(groupObjCollapse);
- domObj.appendChild(groupObj);
-
- }
-
- this._render(domObj);
- };
+ nmsInfoPanel.call(this, "switchSNMP");
+ this.init = function () {
+ this.refresh();
+ };
+ this.refresh = function (reason) {
+ var domObj = document.createElement("div");
+ domObj.classList.add("panel-group");
+
+ try {
+ var snmpJson = nmsData.snmp.snmp[this.sw][this.mode];
+ } catch (e) {
+ this._renderError("Waiting for data.");
+ return;
+ }
+
+ for (var obj in snmpJson) {
+ var cleanObj = obj.replace(/\W+/g, "");
+
+ var groupObj = document.createElement("div");
+ groupObj.classList.add("panel", "panel-default", "nms-panel-small");
+ groupObj.innerHTML =
+ '<h6 class="">' + obj + '</h6>';
+
+ var groupObjCollapse = document.createElement("div");
+ groupObjCollapse.id = cleanObj + "-group";
+ //groupObjCollapse.classList.add("collapse");
+
+ var panelBodyObj = document.createElement("div");
+ panelBodyObj.classList.add("panel-body");
+
+ var tableObj = document.createElement("table");
+ tableObj.classList.add("table");
+
+ var tbody = document.createElement("tbody");
+
+ for (var prop in snmpJson[obj]) {
+ var propObj = document.createElement("tr");
+ propObj.innerHTML =
+ "<td>" + prop + "</td><td>" + snmpJson[obj][prop] + "</td>";
+ tbody.appendChild(propObj);
+ }
+
+ tableObj.appendChild(tbody);
+ panelBodyObj.appendChild(tableObj);
+ groupObjCollapse.appendChild(panelBodyObj);
+ groupObj.appendChild(groupObjCollapse);
+ domObj.appendChild(groupObj);
+ }
+
+ this._render(domObj);
+ };
};
-nmsInfoBox.addPanelType("switchSNMP",switchSNMPPanel);
+nmsInfoBox.addPanelType("switchSNMP", switchSNMPPanel);
var switchPortsPanel = function () {
- nmsInfoPanel.call(this,"switchPorts");
- this.init = function() {
- this.refresh();
- };
- this.refresh = function(reason) {
- var domObj = document.createElement("div");
- domObj.classList.add("panel-group");
-
- try {
- var snmpOldJson;
- var snmpJson = nmsData.snmp.snmp[this.sw]['ports'];
- if (nmsData.old.snmp != undefined) {
- snmpOldJson = nmsData.old.snmp.snmp[this.sw]['ports'];
- }
- } catch(e) {
- this._renderError("Waiting for data.");
- return;
- }
- var chart = document.createElement("canvas");
- chart.id = this.sw+'port-total-chart';
- drawSumOfPorts(this.sw+'port-total-chart',this.sw)
- var expanderButton = document.createElement("a");
- expanderButton.innerHTML = "Toggle all";
- expanderButton.setAttribute("onclick","$('.collapse-top').collapse('toggle');");
- expanderButton.setAttribute("role","button");
-
- var interfaceAliasButton = document.createElement("a");
- interfaceAliasButton.innerHTML = "Toggle interfaces without ifAlias";
- interfaceAliasButton.setAttribute("onclick", "$('.nms-interface-missing-alias').toggle();");
- interfaceAliasButton.setAttribute("role","button");
-
- domObj.appendChild(chart);
- domObj.appendChild(expanderButton);
- domObj.appendChild(document.createElement("br"));
- domObj.appendChild(interfaceAliasButton);
- var indicies = [];
- for (var obj in snmpJson) {
- indicies.push(obj);
- }
- indicies.sort(function(a,b) {
- var tmpx = [ snmpJson[a].ifName, snmpJson[b].ifName ];
- tmpx.sort();
- if (tmpx[0] == snmpJson[a].ifName) {
- return -1;
- } else {
- return 1;
- }
- });
- for(var obji in indicies) {
- var obj = indicies[obji];
- var cleanObj = obj.replace(/\W+/g, "");
- var groupObj = document.createElement("div");
- groupObj.classList.add("panel","panel-default","nms-panel-small");
- var glyphicon = "glyphicon-remove";
- var button = "btn-danger";
- var title = "link down";
- groupObj.classList.add("nms-interface-down");
- if (snmpJson[obj].ifOperStatus == "up") {
- glyphicon = "glyphicon-ok";
- button = "btn-success";
- title = "link up";
- groupObj.classList.remove("nms-interface-down");
- }
- if (snmpJson[obj].ifAdminStatus == "down") {
- glyphicon = "glyphicon-ban-circle";
- title = "admin down";
- button = "btn-info";
- }
- var traffic = "";
- try {
- var nowin = parseInt(snmpJson[obj].ifHCInOctets);
- var nowout = parseInt(snmpJson[obj].ifHCOutOctets);
- if (!isNaN(nowin) && !isNaN(nowout)) {
- traffic = "<small>" + byteCount(nowin) + "B in | " + byteCount(nowout) + "B out </small>";
- }
- } catch(e) {};
-
- if(snmpJson[obj].ifAlias == null || snmpJson[obj].ifAlias == '') {
- groupObj.classList.add("nms-interface-missing-alias");
- }
- groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifName + ' </a><small>' + snmpJson[obj].ifAlias + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>';
-
- var groupObjCollapse = document.createElement("div");
- groupObjCollapse.id = cleanObj + "-group";
- groupObjCollapse.classList.add("collapse");
- groupObjCollapse.classList.add("collapse-top");
-
- var panelBodyObj = document.createElement("div");
- panelBodyObj.classList.add("panel-body");
-
- var tableObj = document.createElement("table");
- tableObj.classList.add("table","table-condensed");
-
- var tbody = document.createElement("tbody");
- var props = [];
- for (var prop in snmpJson[obj]) {
- props.push(prop);
- }
- props.sort();
- for(var index in props) {
- var prop = props[index];
- var propObj = document.createElement("tr");
- var append = "";
- var value = snmpJson[obj][prop];
- if (!isNaN(parseInt(value))) {
- append = byteCount(value, 2);
- if (append != value)
- append = " (" + append + ")";
- else
- append = "";
- }
- propObj.innerHTML = '<td>' + prop + '</td><td>' + value + append + '</td>';
- tbody.appendChild(propObj);
- }
-
- tableObj.appendChild(tbody);
- if (snmpJson[obj].ifHCInOctets != 0
- || snmpJson[obj].ifHCOutOctets != 0) {
- var chart = document.createElement("canvas");
- chart.id = this.sw+'port-'+obj+'-chart';
- drawPort(this.sw+'port-'+obj+'-chart',this.sw,obj)
-
- panelBodyObj.appendChild(chart);
- }
- var tableTopObj = document.createElement("div");
- tableTopObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-table-group">Details</a></span>';
- var tableTopObjCollapse = document.createElement("div");
- tableTopObjCollapse.id = cleanObj + "-table-group";
- tableTopObjCollapse.classList.add("collapse");
- tableTopObjCollapse.classList.add("collapse-detail");
- tableTopObjCollapse.appendChild(tableObj);
- tableTopObj.appendChild(tableTopObjCollapse);
- panelBodyObj.appendChild(tableTopObj);
- //panelBodyObj.appendChild(tableObj);
- groupObjCollapse.appendChild(panelBodyObj);
- groupObj.appendChild(groupObjCollapse);
- domObj.appendChild(groupObj);
-
- }
-
- this._render(domObj);
- };
+ nmsInfoPanel.call(this, "switchPorts");
+ this.init = function () {
+ this.refresh();
+ };
+ this.refresh = function (reason) {
+ var domObj = document.createElement("div");
+ domObj.classList.add("panel-group");
+
+ try {
+ var snmpOldJson;
+ var snmpJson = nmsData.snmp.snmp[this.sw]["ports"];
+ if (nmsData.old.snmp != undefined) {
+ snmpOldJson = nmsData.old.snmp.snmp[this.sw]["ports"];
+ }
+ } catch (e) {
+ this._renderError("Waiting for data.");
+ return;
+ }
+ //var expanderButton = document.createElement("a");
+ //expanderButton.innerHTML = "Toggle all";
+ //expanderButton.setAttribute("onclick","$('.collapse-top').collapse('toggle');");
+ //expanderButton.setAttribute("role", "button");
+
+ //var interfaceAliasButton = document.createElement("a");
+ //interfaceAliasButton.innerHTML = "Toggle interfaces without ifAlias";
+ //interfaceAliasButton.setAttribute("onclick", "$('.nms-interface-missing-alias').toggle();");
+ //interfaceAliasButton.setAttribute("role", "button");
+
+ //domObj.appendChild(expanderButton);
+ //domObj.appendChild(document.createElement("br"));
+ //domObj.appendChild(interfaceAliasButton);
+ var indicies = [];
+ for (var obj in snmpJson) {
+ indicies.push(obj);
+ }
+ indicies.sort(function (a, b) {
+ var tmpx = [snmpJson[a].ifName, snmpJson[b].ifName];
+ tmpx.sort();
+ if (tmpx[0] == snmpJson[a].ifName) {
+ return -1;
+ } else {
+ return 1;
+ }
+ });
+ for (var obji in indicies) {
+ var obj = indicies[obji];
+ var cleanObj = obj.replace(/\W+/g, "");
+ var groupObj = document.createElement("div");
+ groupObj.classList.add("panel", "panel-default", "nms-panel-small");
+ var glyphicon = "glyphicon-remove";
+ var button = "btn-danger";
+ var title = "link down";
+ groupObj.classList.add("nms-interface-down");
+ if (snmpJson[obj].ifOperStatus == "up") {
+ glyphicon = "glyphicon-ok";
+ button = "btn-success";
+ title = "link up";
+ groupObj.classList.remove("nms-interface-down");
+ }
+ if (snmpJson[obj].ifAdminStatus == "down") {
+ glyphicon = "glyphicon-ban-circle";
+ title = "admin down";
+ button = "btn-info";
+ }
+ var traffic = "";
+ try {
+ var nowin = parseInt(snmpJson[obj].ifHCInOctets);
+ var nowout = parseInt(snmpJson[obj].ifHCOutOctets);
+ if (!isNaN(nowin) && !isNaN(nowout)) {
+ traffic =
+ "<small>" +
+ byteCount(nowin) +
+ "B in | " +
+ byteCount(nowout) +
+ "B out </small>";
+ }
+ } catch (e) {}
+
+ if (snmpJson[obj].ifAlias == null || snmpJson[obj].ifAlias == "") {
+ groupObj.classList.add("nms-interface-missing-alias");
+ }
+ groupObj.innerHTML =
+ '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#' +
+ cleanObj +
+ '-group">' +
+ snmpJson[obj].ifName +
+ " </a><small>" +
+ snmpJson[obj].ifAlias +
+ '</small><span class="pull-right">' +
+ traffic +
+ '<i class="btn-xs ' +
+ button +
+ '"><span class="glyphicon ' +
+ glyphicon +
+ '" title="' +
+ title +
+ '" aria-hidden="true"></span></i></span></span>';
+
+ var groupObjCollapse = document.createElement("div");
+ groupObjCollapse.id = cleanObj + "-group";
+ //groupObjCollapse.classList.add("collapse");
+ //groupObjCollapse.classList.add("collapse-top");
+
+ var panelBodyObj = document.createElement("div");
+ panelBodyObj.classList.add("panel-body");
+
+ var tableObj = document.createElement("table");
+ tableObj.classList.add("table", "table-condensed");
+
+ var tbody = document.createElement("tbody");
+ var props = [];
+ for (var prop in snmpJson[obj]) {
+ props.push(prop);
+ }
+ props.sort();
+ for (var index in props) {
+ var prop = props[index];
+ var propObj = document.createElement("tr");
+ var append = "";
+ var value = snmpJson[obj][prop];
+ if (!isNaN(parseInt(value))) {
+ append = byteCount(value, 2);
+ if (append != value) append = " (" + append + ")";
+ else append = "";
+ }
+ propObj.innerHTML =
+ "<td>" + prop + "</td><td>" + value + append + "</td>";
+ tbody.appendChild(propObj);
+ }
+
+ tableObj.appendChild(tbody);
+ var tableTopObj = document.createElement("div");
+ tableTopObj.innerHTML =
+ '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#' +
+ cleanObj;
+ //'-table-group">Details</a></span>';
+ var tableTopObjCollapse = document.createElement("div");
+ tableTopObjCollapse.id = cleanObj + "-table-group";
+ //tableTopObjCollapse.classList.add("collapse");
+ //tableTopObjCollapse.classList.add("collapse-detail");
+ tableTopObjCollapse.appendChild(tableObj);
+ tableTopObj.appendChild(tableTopObjCollapse);
+ panelBodyObj.appendChild(tableTopObj);
+ //panelBodyObj.appendChild(tableObj);
+ groupObjCollapse.appendChild(panelBodyObj);
+ groupObj.appendChild(groupObjCollapse);
+ domObj.appendChild(groupObj);
+ }
+
+ this._render(domObj);
+ };
};
-nmsInfoBox.addPanelType("switchPorts",switchPortsPanel);
-
-var searchHelpPanel = function() {
- nmsInfoPanel.call(this,"searchHelp");
- this.refresh = function(reason) {
- var x = document.createElement("div");
- var searchHelp = nmsSearch.helpText;
- for (var a in searchHelp) {
- var c = document.createElement("p");
- c.innerText = searchHelp[a];
- x.appendChild(c);
- }
- this._render(x);
- };
+nmsInfoBox.addPanelType("switchPorts", switchPortsPanel);
+
+var searchHelpPanel = function () {
+ nmsInfoPanel.call(this, "searchHelp");
+ this.refresh = function (reason) {
+ var x = document.createElement("div");
+ var searchHelp = nmsSearch.helpText;
+ for (var a in searchHelp) {
+ var c = document.createElement("p");
+ c.innerText = searchHelp[a];
+ x.appendChild(c);
+ }
+ this._render(x);
+ };
};
-nmsInfoBox.addPanelType("searchHelp",searchHelpPanel);
-
+nmsInfoBox.addPanelType("searchHelp", searchHelpPanel);
/*
* Panel type: Search Results
@@ -780,28 +799,36 @@ nmsInfoBox.addPanelType("searchHelp",searchHelpPanel);
* Show the search results
*
*/
-var searchResultsPanel = function() {
- var searchPage = 0;
- nmsInfoPanel.call(this,"searchResults");
- this.refresh = function(reason) {
- var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
- var switches = nmsSearch.matches.sort(collator.compare);
- var table = document.createElement('table');
- table.className = "table table-condensed";
- table.id = "searchResults-table"
- for (var sw in switches) {
- var row = table.insertRow(sw);
- var cell1 = row.insertCell(0);
- var cell2 = row.insertCell(1);
- var cell3 = row.insertCell(2);
- cell1.innerHTML = "<a href='#' onclick='nmsInfoBox.showWindow(\"switchInfo\",\""+switches[sw]+"\");'>"+switches[sw]+ '</a>';
- cell2.innerHTML = nmsData.switches["switches"][switches[sw]].distro_name;
- cell3.innerHTML = handlers[0].getInfo(switches[sw]).why;
- }
- this._render(table);
- }
+var searchResultsPanel = function () {
+ var searchPage = 0;
+ nmsInfoPanel.call(this, "searchResults");
+ this.refresh = function (reason) {
+ var collator = new Intl.Collator(undefined, {
+ numeric: true,
+ sensitivity: "base",
+ });
+ var switches = nmsSearch.matches.sort(collator.compare);
+ var table = document.createElement("table");
+ table.className = "table table-condensed";
+ table.id = "searchResults-table";
+ for (var sw in switches) {
+ var row = table.insertRow(sw);
+ var cell1 = row.insertCell(0);
+ var cell2 = row.insertCell(1);
+ var cell3 = row.insertCell(2);
+ cell1.innerHTML =
+ "<a href='#' onclick='nmsInfoBox.showWindow(\"switchInfo\",\"" +
+ switches[sw] +
+ "\");'>" +
+ switches[sw] +
+ "</a>";
+ cell2.innerHTML = nmsData.switches["switches"][switches[sw]].distro_name;
+ cell3.innerHTML = handlers[0].getInfo(switches[sw]).why;
+ }
+ this._render(table);
+ };
};
-nmsInfoBox.addPanelType("searchResults",searchResultsPanel);
+nmsInfoBox.addPanelType("searchResults", searchResultsPanel);
/*
* Panel type: Edit switch
@@ -810,16 +837,17 @@ nmsInfoBox.addPanelType("searchResults",searchResultsPanel);
*
*/
var switchEditPanel = function () {
- nmsInfoPanel.call(this,"switchEdit");
- this.refresh = function (reason) {
- if (this.box) { return; }
- this.box = new nmsModSwitch(this.sw);
- this.box.attach(this.me)
- this.box.show()
- };
-
+ nmsInfoPanel.call(this, "switchEdit");
+ this.refresh = function (reason) {
+ if (this.box) {
+ return;
+ }
+ this.box = new nmsModSwitch(this.sw);
+ this.box.attach(this.me);
+ this.box.show();
+ };
};
-nmsInfoBox.addPanelType("switchEdit",switchEditPanel);
+nmsInfoBox.addPanelType("switchEdit", switchEditPanel);
/*
* Panel type: Switch comments
@@ -828,80 +856,79 @@ nmsInfoBox.addPanelType("switchEdit",switchEditPanel);
*
*/
var switchCommentsPanel = function () {
- nmsInfoPanel.call(this,"switchComments");
- this.commentsHash = false;
- this.refresh = function (reason) {
- var domObj = document.createElement("div");
- domObj.className = 'gondul-is-private';
- var comments = [];
- var logs = nmsOplog.getSwitchLogs(this.sw);
- var table = document.createElement("table");
- var tr;
- var td1;
- var td2;
- var td3;
- table.className = "table";
- table.classList.add("table");
- table.classList.add("table-condensed");
- var cap = document.createElement("caption");
- cap.textContent = "Relevant log entries";
- table.appendChild(cap);
- for (var v in logs) {
- tr = table.insertRow(-1);
- tr.className =
- td1 = tr.insertCell(0);
- td2 = tr.insertCell(1);
- var date = new Date(logs[v]['timestamp']);
- var month = date.getMonth() + 1;
- var day = date.getDate();
- var tmp = (date.getYear() + 1900) + "-" + (month < 10 ? "0": "") + month + "-" + (day < 10 ? "0" : "") + day + " " + date.toTimeString().replace(/:\d\d .*$/,"");
- td1.textContent = tmp;
- td1.classList.add("left");
- td2.textContent = logs[v]['systems'] + "[" + logs[v]['username'] + "] " + logs[v]['log'];
- }
- domObj.appendChild(table);
- this._render(domObj);
- };
+ nmsInfoPanel.call(this, "switchComments");
+ this.commentsHash = false;
+ this.refresh = function (reason) {
+ var domObj = document.createElement("div");
+ domObj.className = "gondul-is-private";
+ var comments = [];
+ var logs = nmsOplog.getSwitchLogs(this.sw);
+ var table = document.createElement("table");
+ var tr;
+ var td1;
+ var td2;
+ var td3;
+ table.className = "table";
+ table.classList.add("table");
+ table.classList.add("table-condensed");
+ var cap = document.createElement("h5");
+ cap.textContent = "Relevant log entries";
+ table.appendChild(cap);
+ for (var v in logs) {
+ tr = table.insertRow(-1);
+ tr.className = td1 = tr.insertCell(0);
+ td2 = tr.insertCell(1);
+ var date = new Date(logs[v]["time"] * 1000);
+ var month = date.getMonth() + 1;
+ var day = date.getDate();
+ var tmp =
+ date.getYear() +
+ 1900 +
+ "-" +
+ (month < 10 ? "0" : "") +
+ month +
+ "-" +
+ (day < 10 ? "0" : "") +
+ day +
+ " " +
+ date.toTimeString().replace(/:\d\d .*$/, "");
+ td1.textContent = tmp;
+ td1.classList.add("left");
+ td2.textContent =
+ logs[v]["systems"] + "[" + logs[v]["username"] + "] " + logs[v]["message"];
+ }
+ domObj.appendChild(table);
+ this._render(domObj);
+ };
};
-nmsInfoBox.addPanelType("switchComments",switchCommentsPanel);
+nmsInfoBox.addPanelType("switchComments", switchCommentsPanel);
/*
- * Panel type: Switch latency
+ * Panel type: Switch links
+ *
*
- * Display a live line chart with latency
*
*/
-var switchLatencyPanel = function() {
- nmsInfoPanel.call(this,"switchLatency");
- var latencyChart;
- this.init = function() {
- if(nms._public == false) {
- this.addHandler("ticker");
- this.refresh();
- }
- };
- this.refresh = function(reason) {
- if (this.sw == false) {
- console.log("ugh, cleanup failed?");
- return;
- }
-
- if(reason == 'handler-ticker' && latencyChart != undefined) {
- drawLatency(this.sw+'latency_chart',this.sw, latencyChart);
- return;
- }
-
- var topper = document.createElement("div");
- var latency = document.createElement("canvas");
- latency.id = this.sw+'latency_chart';
- latency.width = 500;
- latency.height = 50;
- drawLatency(this.sw+'latency_chart',this.sw, false, function(chart) { latencyChart = chart; });
- topper.appendChild(latency);
- this._render(topper);
- };
+var switchLinksPanel = function () {
+ nmsInfoPanel.call(this, "switchLinks");
+ this.commentsHash = false;
+ this.refresh = function (reason) {
+ var domObj = document.createElement("div");
+ domObj.className = "gondul-is-private d-grid gap-0 row-gap-3";
+ var device = nmsData.smanagement.switches[this.sw]
+ if(["eos64"].includes(device["platform"]) && device["serial"] != null && device["serial"] != "") {
+ var cap = document.createElement("a");
+ cap.textContent = "Open in CVP";
+ cap.href = "https://www.cv-prod-euwest-2.arista.io/cv/devices/overview/" + device["serial"];
+ cap.target = "_blank";
+ cap.className = "my-4 btn btn-outline-primary";
+ cap.role = "button";
+ domObj.appendChild(cap);
+ }
+ this._render(domObj);
+ };
};
-nmsInfoBox.addPanelType("switchLatency",switchLatencyPanel);
+nmsInfoBox.addPanelType("switchLinks", switchLinksPanel);
/*
* Panel type: Switch summary
@@ -909,129 +936,83 @@ nmsInfoBox.addPanelType("switchLatency",switchLatencyPanel);
* Display a live summary of key metrics
*
*/
-var switchSummaryPanel = function() {
- nmsInfoPanel.call(this,"switchSummary");
- var latencyChart;
- this.init = function() {
- this.addHandler("ticker");
- this.refresh();
- };
- this.refresh = function(reason) {
- if (this.box) {
- this.box.refresh();
- return;
- }
- this.box = new nmsSwitchSummary(this.sw);
- this.box.attach(this.me)
- this.box.show()
- };
+var switchSummaryPanel = function () {
+ nmsInfoPanel.call(this, "switchSummary");
+ this.init = function () {
+ this.addHandler("ticker");
+ this.refresh();
+ };
+ this.refresh = function (reason) {
+ if (this.box) {
+ this.box.refresh();
+ return;
+ }
+ this.box = new nmsSwitchSummary(this.sw);
+ this.box.attach(this.me);
+ this.box.show();
+ };
};
-nmsInfoBox.setLegendPick = function(tag,id) {
- if (nms.legendPick != undefined) {
- if (nms.legendPick.handler == tag && nms.legendPick.idx == id) {
- nms.legendPick = undefined;
- return;
- }
- }
- nms.legendPick = {handler: tag, idx: id};
-}
-
-nmsInfoBox.addPanelType("switchSummary",switchSummaryPanel);
-
-var copybuttonfunc = function(text) {
- console.log('clickened', text);
- navigator.clipboard.writeText(text);
-}
-var switchLinks = function() {
- nmsInfoPanel.call(this,"switchLinks");
- var latencyChart;
- this.init = function() {
- this.refresh();
- };
- this.refresh = function(reason) {
- var content = [];
- if (this.sw == false) {
- console.log("ugh, cleanup failed?");
- return;
- }
- var sw = this.sw;
-
- var topp = document.createElement("div")
- var urls = [ "http://gondul.tg23.gathering.org/api/templates/magic.conf/switch=" + sw,
- "http://185.110.148.105/api/templates/magic.conf/switch=" + sw,
- "http://gondul.tg23.gathering.org/api/write/fap/" + sw
- ];
- if (testTree(nmsData,['smanagement','switches',sw])) {
- var mg = nmsData["smanagement"]["switches"][sw];
- urls.push("ssh://[" + mg.mgmt_v6_addr + "]");
- urls.push("ssh://" + mg.mgmt_v4_addr);
- }
- for (var x in urls) {
- console.log("create link")
- topp.appendChild(document.createElement("br"));
- var container = document.createElement("div");
- var link = document.createElement("a");
- link.href = urls[x];
- link.textContent = urls[x];
- var copybutton = document.createElement("button");
- copybutton.setAttribute("onclick", "copybuttonfunc('"+urls[x]+"')");
- copybutton.type = "button";
- var btnText = document.createTextNode("copy url");
- copybutton.className = "btn btn-primary";
- copybutton.appendChild(btnText);
- container.appendChild(link);
- container.appendChild(copybutton);
- topp.appendChild(container);
- }
- this._render(topp);
- };
+nmsInfoBox.setLegendPick = function (tag, id) {
+ if (nms.legendPick != undefined) {
+ if (nms.legendPick.handler == tag && nms.legendPick.idx == id) {
+ nms.legendPick = undefined;
+ return;
+ }
+ }
+ nms.legendPick = { handler: tag, idx: id };
};
-nmsInfoBox.addPanelType("switchLinks",switchLinks);
+
+nmsInfoBox.addPanelType("switchSummary", switchSummaryPanel);
/*
-* List networks
-*
-* Shows all networks
-*
-*/
-var networkListPanel = function() {
- nmsInfoPanel.call(this,"listNetworks");
- this.refresh = function(reason) {
- var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
- var networks = nmsData.networks.networks;
- var table = document.createElement('table');
- table.className = "table table-condensed";
- table.id = "searchResults-table"
- for (var net in networks) {
- var row = table.insertRow(net);
- var cell1 = row.insertCell(0);
- var cell2 = row.insertCell(1);
- var cell3 = row.insertCell(2);
- cell1.innerHTML = "<a href='#' onclick='nmsInfoBox.showWindow(\"networkInfo\",\""+net+"\");'>"+net+ '</a>';
- cell2.innerHTML = networks[net].vlan;
- cell3.innerHTML = networks[net].router;
- }
- this._render(table);
-
- };
+ * List networks
+ *
+ * Shows all networks
+ *
+ */
+var networkListPanel = function () {
+ nmsInfoPanel.call(this, "listNetworks");
+ this.refresh = function (reason) {
+ var collator = new Intl.Collator(undefined, {
+ numeric: true,
+ sensitivity: "base",
+ });
+ var networks = nmsData.networks.networks;
+ var table = document.createElement("table");
+ table.className = "table table-condensed";
+ table.id = "searchResults-table";
+ for (var net in networks) {
+ var row = table.insertRow(net);
+ var cell1 = row.insertCell(0);
+ var cell2 = row.insertCell(1);
+ var cell3 = row.insertCell(2);
+ cell1.innerHTML =
+ "<a href='#' onclick='nmsInfoBox.showWindow(\"networkInfo\",\"" +
+ net +
+ "\");'>" +
+ net +
+ "</a>";
+ cell2.innerHTML = networks[net].vlan;
+ cell3.innerHTML = networks[net].router;
+ }
+ this._render(table);
+ };
};
-nmsInfoBox.addPanelType("listNetworks",networkListPanel);
+nmsInfoBox.addPanelType("listNetworks", networkListPanel);
/*
-* Panel type: Network summary
-*
-* Display a summary
-*
-*/
-var networkSummaryPanel = function() {
- nmsInfoPanel.call(this,"networkSummary");
- this.refresh = function(reason) {
- var network = this.sw;
-
- };
-}
-nmsInfoBox.addPanelType("networkSummary",networkSummaryPanel);
-
+ * Panel type: Network summary
+ *
+ * Display a summary
+ *
+ */
+var networkSummaryPanel = function () {
+ nmsInfoPanel.call(this, "networkSummary");
+ this.refresh = function (reason) {
+ var network = this.sw;
+ };
+};
+nmsInfoBox.addPanelType("networkSummary", networkSummaryPanel);
/*
* Panel type: Edit network
@@ -1040,50 +1021,76 @@ nmsInfoBox.addPanelType("networkSummary",networkSummaryPanel);
*
*/
var networkEditPanel = function () {
- nmsInfoPanel.call(this,"networkEdit");
- this.refresh = function (reason) {
- if (this.box) { return; }
- this.box = new nmsModNet(this.sw);
- this.box.attach(this.me)
- this.box.show()
- };
+ nmsInfoPanel.call(this, "networkEdit");
+ this.refresh = function (reason) {
+ if (this.box) {
+ return;
+ }
+ this.box = new nmsModNet(this.sw);
+ this.box.attach(this.me);
+ this.box.show();
+ };
+};
+nmsInfoBox.addPanelType("networkEdit", networkEditPanel);
+
+/*
+ * Debug Panel
+ *
+ * Show debug information
+ *
+ */
+var debugStatsPanel = function () {
+ nmsInfoPanel.call(this, "debugStatsPanel");
+ this.init = function () {
+ this.addHandler("ticker");
+ this.refresh();
+ };
+ this.refresh = function (reason) {
+ var table = document.createElement("table");
+ table.className = "table table-condensed";
+ table.id = "searchResults-table";
+ var stats = Object.fromEntries(
+ Object.entries(nmsData.stats).sort((a, b) => a[0].localeCompare(b[0]))
+ );
+ for (var stat in stats) {
+ var row = table.insertRow(stat);
+ var cell1 = row.insertCell(0);
+ var cell2 = row.insertCell(1);
+ cell1.innerHTML = stat;
+ cell2.innerHTML = nmsData.stats[stat];
+ }
+ this._render(table);
+ };
};
-nmsInfoBox.addPanelType("networkEdit",networkEditPanel);
+nmsInfoBox.addPanelType("debugStats", debugStatsPanel);
/*
- * Provide common defaults for graph renders.
+ * Debug Panel
+ *
+ * Show debug information
*
- * Kept on the URL to avoid having to manage templates since we need to
- * manage night mode anyway for now.
*/
-nmsInfoBox._graphZoom = function() {
- if (nmsInfoBox._graphFrom == "-60min") {
- nmsInfoBox._graphFrom = "-6h";
- } else if (nmsInfoBox._graphFrom == "-6h") {
- nmsInfoBox._graphFrom = "-24h";
- } else if (nmsInfoBox._graphFrom == "-24h") {
- nmsInfoBox._graphFrom = "-7days";
- } else {
- nmsInfoBox._graphFrom = "-60min";
- }
-
-
-}
-nmsInfoBox._graphFrom = "-60min";
-nmsInfoBox._graphUntil = "now";
-nmsInfoBox._graphNormalize = function(f) {
- return f.replace(/[^a-z0-9]/gi,"_");
-}
-nmsInfoBox._graphDefaults = function(title) {
- if (title != undefined) {
- title = "From " + nmsInfoBox._graphFrom + " until " + nmsInfoBox._graphUntil + " (" + title + ")";
- } else {
- title = "From " + nmsInfoBox._graphFrom + " until " + nmsInfoBox._graphUntil;
- }
- var base = "&yMinLeft=0&yMinRight=0&yMin=0&bgcolor=%23ffffff00&fontName=courier&width=600&height=240&yUnitSystem=binary&format=svg&from=" + nmsInfoBox._graphFrom + "&until=" + nmsInfoBox._graphUntil + '&title=' + title + "&lolBuster=" + Math.floor(new Date().getTime() / 30000);
- if (nms.nightMode) {
- return "&fgcolor=%23dddddd&minorGridLineColor=%233d3d3d&majorGridLineColor=%23666666" + base;
- } else {
- return base;
- }
-}
+var debugPanel = function () {
+ nmsInfoPanel.call(this, "debugInfo");
+ this.init = function () {
+ this.addHandler("ticker");
+ this.refresh();
+ };
+ this.refresh = function (reason) {
+ var table = document.createElement("table");
+ table.className = "table table-condensed";
+ table.id = "searchResults-table";
+ var stats = Object.fromEntries(
+ Object.entries(nmsData.stats).sort((a, b) => a[0].localeCompare(b[0]))
+ );
+ for (var stat in stats) {
+ var row = table.insertRow(stat);
+ var cell1 = row.insertCell(0);
+ var cell2 = row.insertCell(1);
+ cell1.innerHTML = stat;
+ cell2.innerHTML = nmsData.stats[stat];
+ }
+ this._render(table);
+ };
+};
+nmsInfoBox.addPanelType("debugInfo", debugPanel);
diff --git a/web/js/nms-map-handlers.js b/web/js/nms-map-handlers.js
index 0097586..27139d8 100644
--- a/web/js/nms-map-handlers.js
+++ b/web/js/nms-map-handlers.js
@@ -14,335 +14,341 @@
*/
var handler_uplinks = {
- init:uplinkInit,
- getInfo:uplinkInfo,
- tag:"uplink",
- name:"Uplink"
+ init: uplinkInit,
+ getInfo: uplinkInfo,
+ tag: "uplink",
+ name: "Uplink",
};
var handler_temp = {
- init:tempInit,
- getInfo:tempInfo,
- tag:"temp",
- name:"Temperature"
+ init: tempInit,
+ getInfo: tempInfo,
+ tag: "temp",
+ name: "Temperature",
};
var handler_ping = {
- init:pingInit,
- getInfo:pingInfo,
- tag:"ping",
- name:"Ping"
+ init: pingInit,
+ getInfo: pingInfo,
+ tag: "ping",
+ name: "Ping",
};
var handler_traffic = {
- init:trafficInit,
- tag:"traffic",
- name:"Uplink traffic"
+ init: trafficInit,
+ tag: "traffic",
+ name: "Uplink traffic",
};
var handler_traffic_tot = {
- init:trafficTotInit,
- tag:"traffictot",
- name:"Switch traffic"
+ init: trafficTotInit,
+ tag: "traffictot",
+ name: "Switch traffic",
};
var handler_dhcp = {
- init:dhcpInit,
- getInfo:dhcpInfo,
- tag:"dhcp",
- name:"DHCP"
+ init: dhcpInit,
+ getInfo: dhcpInfo,
+ tag: "dhcp",
+ name: "DHCP",
};
var handler_disco = {
- init:discoInit,
- tag:"disco",
- name:"Disco fever"
+ init: discoInit,
+ tag: "disco",
+ name: "Disco fever",
};
var handler_snmp = {
- init:snmpInit,
- getInfo:snmpInfo,
- tag:"snmp",
- name:"SNMP state"
+ init: snmpInit,
+ getInfo: snmpInfo,
+ tag: "snmp",
+ name: "SNMP state",
};
var handler_cpu = {
- init:cpuInit,
- getInfo:cpuInfo,
- tag:"cpu",
- name:"CPU utilization"
+ init: cpuInit,
+ getInfo: cpuInfo,
+ tag: "cpu",
+ name: "CPU utilization",
};
var handler_memory = {
- init:memoryInit,
- getInfo:memoryInfo,
- tag:"memory",
- name:"Memory utilization"
+ init: memoryInit,
+ getInfo: memoryInfo,
+ tag: "memory",
+ name: "Memory utilization",
};
var handler_health = {
- init:healthInit,
- getInfo:healthInfo,
- tag:"health",
- name:"Health"
+ init: healthInit,
+ getInfo: healthInfo,
+ tag: "health",
+ name: "Health",
};
var handler_mgmt = {
- getInfo:mgmtInfo,
- tag:"mgmt",
- name:"Management info"
+ getInfo: mgmtInfo,
+ tag: "mgmt",
+ name: "Management info",
};
var handler_net = {
- getInfo:networkInfo,
- tag:"net",
- name:"Network info"
+ getInfo: networkInfo,
+ tag: "net",
+ name: "Network info",
};
var handler_snmpup = {
- getInfo:snmpUpInfo,
- tag:"snmpup",
- name:"SNMP Uplink state"
+ getInfo: snmpUpInfo,
+ tag: "snmpup",
+ name: "SNMP Uplink state",
};
-var handlerInfo = function(tag,desc) {
- /*
- * Short name, typically matching the url anchor.
- */
- this.tag = tag;
- this.description = desc || "Unknown";
- this.data = [
- {
- value: undefined,
- description: desc || "Generic info"
- }];
- /*
- * 0: all good.
- * 1000: messed up.
- *
- * This can be "intelligent". E.g.: pingInfo() takes latency and
- * the age of the reply into account in addition to having a
- * special handling of lack of a result.
- */
- this.score = 0;
- /*
- * Why the score is what it is. E.g.: If you have multiple
- * conditions that set the score, what is the final value based on?
- */
- this.why = "0 score is the default";
+var handlerInfo = function (tag, desc) {
+ /*
+ * Short name, typically matching the url anchor.
+ */
+ this.tag = tag;
+ this.description = desc || "Unknown";
+ this.data = [
+ {
+ value: undefined,
+ description: desc || "Generic info",
+ },
+ ];
+ /*
+ * 0: all good.
+ * 1000: messed up.
+ *
+ * This can be "intelligent". E.g.: pingInfo() takes latency and
+ * the age of the reply into account in addition to having a
+ * special handling of lack of a result.
+ */
+ this.score = 0;
+ /*
+ * Why the score is what it is. E.g.: If you have multiple
+ * conditions that set the score, what is the final value based on?
+ */
+ this.why = "0 score is the default";
};
/*
* Order matches what's seen in the infobox
*/
var handlers = [
- handler_health,
- handler_mgmt,
- handler_net,
- handler_uplinks,
- handler_temp,
- handler_ping,
- handler_traffic,
- handler_disco,
- handler_traffic_tot,
- handler_dhcp,
- handler_snmp,
- handler_cpu,
- handler_memory,
- handler_snmpup
- ];
-
-function uplinkInfo(sw)
-{
- var ret = new handlerInfo("snmpup","Uplinks");
- ret.why = "Uplinks";
- ret.score = 0;
- var u = 0;
- var t = 0;
- var known_t = 0;
- if (testTree(nmsData,['switchstate','switches',sw,'uplinks','live'])) {
- u = parseInt(nmsData.switchstate.switches[sw].uplinks.live);
- t = parseInt(nmsData.switchstate.switches[sw].uplinks.total);
- known_t = t;
- ret.data[0].value = u + " / " + t;
- ret.data[0].description = "Uplinks (live/configured)";
- if (nmsData.switches.switches[sw].subnet4 == undefined ||
- nmsData.switches.switches[sw].subnet4 == null) {
- if (tagged(sw,'3up')) {
- known_t = 3;
- } else if (tagged(sw,'2up')) {
- known_t = 2;
- } else if (tagged(sw, '1up')) {
- known_t = 1;
- } else if (tagged(sw,'4up')) {
- known_t = 4;
- }
- if (known_t != t) {
- ret.data[0].value += "(Overridden: " + known_t + ")";
- }
- if (u == known_t) {
- ret.score = 0;
- ret.why = "All uplinks up";
- } else if (u == 1) {
- ret.score = 800;
- ret.why = "Only 1 of " + known_t + " uplinks alive";
- } else if (u < known_t && !(t >= 10 && u <5)) {
- ret.score = 450;
- ret.why = u + " of " + known_t + " uplinks alive";
- } else if (u > known_t) {
- ret.score = 350;
- ret.why = u + " of " + known_t + " uplinks alive";
- } else if (u < known_t && (t >= 10 && u < 5)) {
- ret.score = 150;
- ret.why = u + " of " + known_t + " uplinks alive (huge diff suggests WIP - downgrading)";
- }
- }
- }
- if (testTree(nmsData,['switchstate','switches',sw,'clients','total'])) {
- var tu = parseInt(nmsData.switchstate.switches[sw].clients.live);
- var tt = parseInt(nmsData.switchstate.switches[sw].clients.total);
- ret.data[1] = {};
- ret.data[1].value = tt ? (tu) + " / " + (tt) : "None configured";
- ret.data[1].description = "Client ports (live/total)";
- }
- if (testTree(nmsData,['switchstate','switches',sw,'totals','live'])) {
- var tu = parseInt(nmsData.switchstate.switches[sw].totals.live);
- var tt = parseInt(nmsData.switchstate.switches[sw].totals.total);
- ret.data[2] = {};
- ret.data[2].value = (tu-u) + " / " + (tt-t);
- ret.data[2].description = "Non-uplink ports (live/total)";
- }
- return ret;
+ handler_health,
+ handler_mgmt,
+ handler_net,
+ handler_uplinks,
+ handler_temp,
+ handler_ping,
+ handler_traffic,
+ handler_disco,
+ handler_traffic_tot,
+ handler_dhcp,
+ handler_snmp,
+ handler_cpu,
+ handler_memory,
+ handler_snmpup,
+];
+
+function uplinkInfo(sw) {
+ var ret = new handlerInfo("snmpup", "Uplinks");
+ ret.why = "Uplinks";
+ ret.score = 0;
+ var u = 0;
+ var t = 0;
+ var known_t = 0;
+ if (testTree(nmsData, ["switchstate", "switches", sw, "uplinks", "live"])) {
+ u = parseInt(nmsData.switchstate.switches[sw].uplinks.live);
+ t = parseInt(nmsData.switchstate.switches[sw].uplinks.total);
+ known_t = t;
+ ret.data[0].value = u + " / " + t;
+ ret.data[0].description = "Uplinks (live/configured)";
+ if (
+ nmsData.switches.switches[sw].subnet4 == undefined ||
+ nmsData.switches.switches[sw].subnet4 == null
+ ) {
+ if (tagged(sw, "3up")) {
+ known_t = 3;
+ } else if (tagged(sw, "2up")) {
+ known_t = 2;
+ } else if (tagged(sw, "1up")) {
+ known_t = 1;
+ } else if (tagged(sw, "4up")) {
+ known_t = 4;
+ }
+ if (known_t != t) {
+ ret.data[0].value += "(Overridden: " + known_t + ")";
+ }
+ if (u == known_t) {
+ ret.score = 0;
+ ret.why = "All uplinks up";
+ } else if (u == 1) {
+ ret.score = 800;
+ ret.why = "Only 1 of " + known_t + " uplinks alive";
+ } else if (u < known_t && !(t >= 10 && u < 5)) {
+ ret.score = 450;
+ ret.why = u + " of " + known_t + " uplinks alive";
+ } else if (u > known_t) {
+ ret.score = 350;
+ ret.why = u + " of " + known_t + " uplinks alive";
+ } else if (u < known_t && t >= 10 && u < 5) {
+ ret.score = 150;
+ ret.why =
+ u +
+ " of " +
+ known_t +
+ " uplinks alive (huge diff suggests WIP - downgrading)";
+ }
+ }
+ }
+ if (testTree(nmsData, ["switchstate", "switches", sw, "clients", "total"])) {
+ var tu = parseInt(nmsData.switchstate.switches[sw].clients.live);
+ var tt = parseInt(nmsData.switchstate.switches[sw].clients.total);
+ ret.data[1] = {};
+ ret.data[1].value = tt ? tu + " / " + tt : "None configured";
+ ret.data[1].description = "Client ports (live/total)";
+ }
+ if (testTree(nmsData, ["switchstate", "switches", sw, "totals", "live"])) {
+ var tu = parseInt(nmsData.switchstate.switches[sw].totals.live);
+ var tt = parseInt(nmsData.switchstate.switches[sw].totals.total);
+ ret.data[2] = {};
+ ret.data[2].value = tu - u + " / " + (tt - t);
+ ret.data[2].description = "Non-uplink ports (live/total)";
+ }
+ return ret;
}
/*
* Update function for uplink map
*/
-function uplinkUpdater()
-{
- if (!nmsData.switches)
- return;
- if (!nmsData.switches.switches)
- return;
- if (!nmsData.switchstate)
- return;
- if (!nmsData.switchstate.switches)
- return;
- for (var sw in nmsData.switches.switches) {
- var uplinks=0;
- if (nmsData.switchstate.switches[sw] == undefined || nmsData.switchstate.switches[sw].uplinks == undefined) {
- uplinks=0;
- } else {
- uplinks = nmsData.switchstate.switches[sw].uplinks.live;
- nuplinks = nmsData.switchstate.switches[sw].uplinks.total;
- }
-
- if (uplinks == 0) {
- nmsMap.setSwitchColor(sw,"white");
- } else if (uplinks == 1) {
- nmsMap. setSwitchColor(sw, nmsColor.red);
- } else if (uplinks == 2) {
- nmsMap.setSwitchColor(sw, nmsColor.green);
- } else if (uplinks == 3) {
- nmsMap.setSwitchColor(sw, nmsColor.orange);
- } else if (uplinks > 3) {
- nmsMap.setSwitchColor(sw, nmsColor.blue);
- }
- }
+function uplinkUpdater() {
+ if (!nmsData.switches) return;
+ if (!nmsData.switches.switches) return;
+ if (!nmsData.switchstate) return;
+ if (!nmsData.switchstate.switches) return;
+ for (var sw in nmsData.switches.switches) {
+ var uplinks = 0;
+ if (
+ nmsData.switchstate.switches[sw] == undefined ||
+ nmsData.switchstate.switches[sw].uplinks == undefined
+ ) {
+ uplinks = 0;
+ } else {
+ uplinks = nmsData.switchstate.switches[sw].uplinks.live;
+ nuplinks = nmsData.switchstate.switches[sw].uplinks.total;
+ }
+
+ if (uplinks == 0) {
+ nmsMap.setSwitchColor(sw, "white");
+ } else if (uplinks == 1) {
+ nmsMap.setSwitchColor(sw, nmsColor.red);
+ } else if (uplinks == 2) {
+ nmsMap.setSwitchColor(sw, nmsColor.green);
+ } else if (uplinks == 3) {
+ nmsMap.setSwitchColor(sw, nmsColor.orange);
+ } else if (uplinks > 3) {
+ nmsMap.setSwitchColor(sw, nmsColor.blue);
+ }
+ }
}
-
/*
* Init-function for uplink map
*/
-function uplinkInit()
-{
- nmsData.addHandler("switches","mapHandler",uplinkUpdater);
- nmsData.addHandler("switchstate","mapHandler",uplinkUpdater);
- setLegend(1,"white","0 uplinks");
- setLegend(2,nmsColor.red,"1 uplink");
- setLegend(3,nmsColor.green,"2 uplinks");
- setLegend(4,nmsColor.orange,"3 uplinks");
- setLegend(5,nmsColor.blue,"4 uplinks");
+function uplinkInit() {
+ nmsData.addHandler("switches", "mapHandler", uplinkUpdater);
+ nmsData.addHandler("switchstate", "mapHandler", uplinkUpdater);
+ setLegend(1, "white", "0 uplinks");
+ setLegend(2, nmsColor.red, "1 uplink");
+ setLegend(3, nmsColor.green, "2 uplinks");
+ setLegend(4, nmsColor.orange, "3 uplinks");
+ setLegend(5, nmsColor.blue, "4 uplinks");
}
/*
* Init-function for uplink map
*/
-function trafficInit()
-{
- nmsData.addHandler("switches","mapHandler",trafficUpdater);
- nmsData.addHandler("switchstate","mapHandler",trafficUpdater);
- var m = 1024 * 1024 / 8;
- nmsColor.drawGradient([nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]);
- setLegend(1,colorFromSpeed(0),"0 (N/A)");
- setLegend(5,colorFromSpeed(1100 * m) , "1100Mb/s");
- setLegend(4,colorFromSpeed(600 * m),"600Mb/s");
- setLegend(3,colorFromSpeed(300 * m),"300Mb/s");
- setLegend(2,colorFromSpeed(10 * m),"10Mb/s");
+function trafficInit() {
+ nmsData.addHandler("switches", "mapHandler", trafficUpdater);
+ nmsData.addHandler("switchstate", "mapHandler", trafficUpdater);
+ var m = (1024 * 1024) / 8;
+ nmsColor.drawGradient([
+ nmsColor.teal,
+ nmsColor.green,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ setLegend(1, colorFromSpeed(0), "0 (N/A)");
+ setLegend(5, colorFromSpeed(1100 * m), "1100Mb/s");
+ setLegend(4, colorFromSpeed(600 * m), "600Mb/s");
+ setLegend(3, colorFromSpeed(300 * m), "300Mb/s");
+ setLegend(2, colorFromSpeed(10 * m), "10Mb/s");
}
-function trafficUpdater()
-{
- if (!nmsData.switchstate.switches || !nmsData.switchstate.then)
- return;
- for (var sw in nmsData.switchstate.switches) {
- var speed = 0;
- try {
- var t = parseInt(nmsData.switchstate.then[sw].uplinks.ifHCOutOctets);
- var n = parseInt(nmsData.switchstate.switches[sw].uplinks.ifHCOutOctets);
- var tt = parseInt(nmsData.switchstate.then[sw].time);
- var nt = parseInt(nmsData.switchstate.switches[sw].time);
- } catch (e) { continue;};
- var tdiff = nt - tt;
- var diff = n - t;
- speed = diff / tdiff;
- if(!isNaN(speed)) {
- nmsMap.setSwitchColor(sw,colorFromSpeed(speed));
- nmsMap.setSwitchInfo(sw,byteCount(speed*8,0));
- }
- }
+function trafficUpdater() {
+ if (!nmsData.switchstate.switches || !nmsData.switchstate.then) return;
+ for (var sw in nmsData.switchstate.switches) {
+ var speed = 0;
+ try {
+ var t = parseInt(nmsData.switchstate.then[sw].uplinks.ifHCOutOctets);
+ var n = parseInt(nmsData.switchstate.switches[sw].uplinks.ifHCOutOctets);
+ var tt = parseInt(nmsData.switchstate.then[sw].time);
+ var nt = parseInt(nmsData.switchstate.switches[sw].time);
+ } catch (e) {
+ continue;
+ }
+ var tdiff = nt - tt;
+ var diff = n - t;
+ speed = diff / tdiff;
+ if (!isNaN(speed)) {
+ nmsMap.setSwitchColor(sw, colorFromSpeed(speed));
+ nmsMap.setSwitchInfo(sw, byteCount(speed * 8, 0));
+ }
+ }
}
-function trafficTotInit()
-{
- nmsData.addHandler("switches","mapHandler",trafficTotUpdater);
- nmsData.addHandler("switchstate","mapHandler",trafficTotUpdater);
- var m = 1024 * 1024 / 8;
- nmsColor.drawGradient([nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]);
- setLegend(1,colorFromSpeed(0),"0 (N/A)");
- setLegend(5,colorFromSpeed(5000 * m,5) , "5000Mb/s");
- setLegend(4,colorFromSpeed(3000 * m,5),"3000Mb/s");
- setLegend(3,colorFromSpeed(1000 * m,5),"1000Mb/s");
- setLegend(2,colorFromSpeed(100 * m,5),"100Mb/s");
+function trafficTotInit() {
+ nmsData.addHandler("switches", "mapHandler", trafficTotUpdater);
+ nmsData.addHandler("switchstate", "mapHandler", trafficTotUpdater);
+ var m = (1024 * 1024) / 8;
+ nmsColor.drawGradient([
+ nmsColor.teal,
+ nmsColor.green,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ setLegend(1, colorFromSpeed(0), "0 (N/A)");
+ setLegend(5, colorFromSpeed(5000 * m, 5), "5000Mb/s");
+ setLegend(4, colorFromSpeed(3000 * m, 5), "3000Mb/s");
+ setLegend(3, colorFromSpeed(1000 * m, 5), "1000Mb/s");
+ setLegend(2, colorFromSpeed(100 * m, 5), "100Mb/s");
}
-function trafficTotUpdater()
-{
- if (!nmsData.switchstate.switches || !nmsData.switchstate.then)
- return;
- for (var sw in nmsData.switchstate.switches) {
- var speed = 0;
- try {
- var t = parseInt(nmsData.switchstate.then[sw].totals.ifHCOutOctets);
- var n = parseInt(nmsData.switchstate.switches[sw].totals.ifHCOutOctets);
- var tt = parseInt(nmsData.switchstate.then[sw].time);
- var nt = parseInt(nmsData.switchstate.switches[sw].time);
- } catch (e) { continue;};
- var tdiff = nt - tt;
- var diff = n - t;
- speed = diff / tdiff;
- if(!isNaN(speed))
- nmsMap.setSwitchColor(sw,colorFromSpeed(speed));
- }
+function trafficTotUpdater() {
+ if (!nmsData.switchstate.switches || !nmsData.switchstate.then) return;
+ for (var sw in nmsData.switchstate.switches) {
+ var speed = 0;
+ try {
+ var t = parseInt(nmsData.switchstate.then[sw].totals.ifHCOutOctets);
+ var n = parseInt(nmsData.switchstate.switches[sw].totals.ifHCOutOctets);
+ var tt = parseInt(nmsData.switchstate.then[sw].time);
+ var nt = parseInt(nmsData.switchstate.switches[sw].time);
+ } catch (e) {
+ continue;
+ }
+ var tdiff = nt - tt;
+ var diff = n - t;
+ speed = diff / tdiff;
+ if (!isNaN(speed)) nmsMap.setSwitchColor(sw, colorFromSpeed(speed));
+ }
}
-function colorFromSpeed(speed,factor)
-{
- var m = 1024 * 1024 / 8;
- if (factor == undefined)
- factor = 1.1;
- if (speed == 0)
- return nmsColor.blue;
- speed = speed < 0 ? 0 : speed;
- return nmsColor.getColorStop( 1000 * (speed / (factor * (1000 * m))));
+function colorFromSpeed(speed, factor) {
+ var m = (1024 * 1024) / 8;
+ if (factor == undefined) factor = 1.1;
+ if (speed == 0) return nmsColor.blue;
+ speed = speed < 0 ? 0 : speed;
+ return nmsColor.getColorStop(1000 * (speed / (factor * (1000 * m))));
}
/*
@@ -350,825 +356,954 @@ function colorFromSpeed(speed,factor)
* thing (e.g., "0" is 20 and "15" is 35 by the time we pass it to
* rgb_from_max());
*/
-function temp_color(t)
-{
- if (t == undefined) {
- console.log("Temp_color, but temp is undefined");
- return nmsColor.blue;
- }
- t = parseInt(t) - 12;
- t = Math.floor((t / 23) * 1000);
- return nmsColor.getColorStop(t);
+function temp_color(t) {
+ if (t == undefined) {
+ console.log("Temp_color, but temp is undefined");
+ return nmsColor.blue;
+ }
+ t = parseInt(t) - 12;
+ t = Math.floor((t / 23) * 1000);
+ return nmsColor.getColorStop(t);
}
-function tempUpdater()
-{
- if(!nmsData.switches)
- return;
-
- for ( var sw in nmsData.switches["switches"]) {
- var t = "white";
- var temp = "";
-
- if(!nmsData.switchstate || !nmsData.switchstate.switches || !nmsData.switchstate.switches[sw] || !nmsData.switchstate.switches[sw].temp)
- continue;
-
- var t = nmsData.switchstate.switches[sw].temp;
- temp = t + "°C";
- t = temp_color(temp);
- nmsMap.setSwitchColor(sw, t);
- nmsMap.setSwitchInfo(sw, temp);
-
- }
+function tempUpdater() {
+ if (!nmsData.switches) return;
+
+ for (var sw in nmsData.switches["switches"]) {
+ var t = "white";
+ var temp = "";
+
+ if (
+ !nmsData.switchstate ||
+ !nmsData.switchstate.switches ||
+ !nmsData.switchstate.switches[sw] ||
+ !nmsData.switchstate.switches[sw].temp
+ )
+ continue;
+
+ var t = nmsData.switchstate.switches[sw].temp;
+ temp = t + "°C";
+ t = temp_color(temp);
+ nmsMap.setSwitchColor(sw, t);
+ nmsMap.setSwitchInfo(sw, temp);
+ }
}
-function tempInfo(sw)
-{
- var ret = new handlerInfo("temp","Temperature");
- ret.why = "Temp";
- ret.score = 0;
- ret.data[0].value = undefined;
- if (testTree(nmsData,['switchstate','switches',sw,'temp'])) {
- var temp = nmsData.switchstate.switches[sw].temp;
- if (temp == undefined) {
- ret.data[0].value = undefined;
- } else {
- temp = parseInt(temp);
- ret.data[0].value = temp + "°C";
- }
- if (temp > 30 && temp < 50) {
- ret.score = temp;
- } else if (temp > 50 && temp < 100) {
- ret.score = temp * 5;
- ret.why = "Very high temperature";
- }
- }
- return ret;
+function tempInfo(sw) {
+ var ret = new handlerInfo("temp", "Temperature");
+ ret.why = "Temp";
+ ret.score = 0;
+ ret.data[0].value = undefined;
+ if (testTree(nmsData, ["switchstate", "switches", sw, "temp"])) {
+ var temp = nmsData.switchstate.switches[sw].temp;
+ if (temp == undefined) {
+ ret.data[0].value = undefined;
+ } else {
+ temp = parseInt(temp);
+ ret.data[0].value = temp + "°C";
+ }
+ if (temp > 30 && temp < 50) {
+ ret.score = temp;
+ } else if (temp > 50 && temp < 100) {
+ ret.score = temp * 5;
+ ret.why = "Very high temperature";
+ }
+ }
+ return ret;
}
-function tempInit()
-{
- //Padded the gradient with extra colors for the upper unused values
- nmsColor.drawGradient(["black", nmsColor.blue, nmsColor.lightblue, nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]);
- setLegend(1,temp_color(15),"15 °C");
- setLegend(2,temp_color(20),"20 °C");
- setLegend(3,temp_color(25),"25 °C");
- setLegend(4,temp_color(30),"30 °C");
- setLegend(5,temp_color(35),"35 °C");
- nmsData.addHandler("switchstate","mapHandler",tempUpdater);
- tempUpdater();
+function tempInit() {
+ //Padded the gradient with extra colors for the upper unused values
+ nmsColor.drawGradient([
+ "black",
+ nmsColor.blue,
+ nmsColor.cyan,
+ nmsColor.teal,
+ nmsColor.green,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ setLegend(1, temp_color(15), "15 °C");
+ setLegend(2, temp_color(20), "20 °C");
+ setLegend(3, temp_color(25), "25 °C");
+ setLegend(4, temp_color(30), "30 °C");
+ setLegend(5, temp_color(35), "35 °C");
+ nmsData.addHandler("switchstate", "mapHandler", tempUpdater);
+ tempUpdater();
}
-function pingUpdater()
-{
- if (nmsData.switches == undefined || nmsData.switches.switches == undefined) {
- return;
- }
- for (var sw in nmsData.switches.switches) {
- var c = nmsColor.getColorStop(pingInfo(sw).score);
- if (c == 1000) {
- nmsMap.setSwitchColor(sw, nmsColor.blue);
- } else {
- nmsMap.setSwitchColor(sw, c);
- }
- }
+function pingUpdater() {
+ if (nmsData.switches == undefined || nmsData.switches.switches == undefined) {
+ return;
+ }
+ for (var sw in nmsData.switches.switches) {
+ var c = nmsColor.getColorStop(pingInfo(sw).score);
+ if (c == 1000) {
+ nmsMap.setSwitchColor(sw, nmsColor.blue);
+ } else {
+ nmsMap.setSwitchColor(sw, c);
+ }
+ }
}
-function printDiff(t)
-{
- var str = "";
- if (t.d > 1)
- str = t.d + " days";
- else if (t.d == 1)
- str = t.d + " day";
-
- if (t.h > 1)
- str += " " + t.h + " hours";
- else if (t.h == 1)
- str += " " + t.h + " hour";
- else if (t.d > 0)
- str += " 0 hours";
-
- if (t.m > 1)
- str += " " + t.m + " minutes";
- else if (t.m == 1)
- str += " " + t.m + " minute";
- else if (t.d > 0 || t.h > 0)
- str += " 0 minutes";
-
- if (t.s > 1)
- str += " " + t.s + " seconds";
- else if (t.s == 1)
- str += " " + t.s + " second";
- else if (t.d > 0 || t.h > 0 || t.m > 0)
- str += " 0 seconds";
- return str;
+function printDiff(t) {
+ var str = "";
+ if (t.d > 1) str = t.d + " days";
+ else if (t.d == 1) str = t.d + " day";
+
+ if (t.h > 1) str += " " + t.h + " hours";
+ else if (t.h == 1) str += " " + t.h + " hour";
+ else if (t.d > 0) str += " 0 hours";
+
+ if (t.m > 1) str += " " + t.m + " minutes";
+ else if (t.m == 1) str += " " + t.m + " minute";
+ else if (t.d > 0 || t.h > 0) str += " 0 minutes";
+
+ if (t.s > 1) str += " " + t.s + " seconds";
+ else if (t.s == 1) str += " " + t.s + " second";
+ else if (t.d > 0 || t.h > 0 || t.m > 0) str += " 0 seconds";
+ return str;
}
-function pingInfo(sw)
-{
- var ret = new handlerInfo("ping","Latency(ms)");
- ret.why = "Latency (?)";
- ret.score =0;
- if (testTree(nmsData,['ping','switches',sw])) {
- var v4 = nmsData.ping.switches[sw].latency4;
- var v6 = nmsData.ping.switches[sw].latency6;
- if (v4 == undefined || v4 == null || isNaN(v4))
- v4 = undefined;
- if (v6 == undefined || v6 == null || isNaN(v6))
- v6 = undefined;
- ret.data[0].value = v6 + " (v4: " + v4 + " )";
- ret.data[0].description = "Latency(ms)";
- if (v4 == undefined && v6 == undefined) {
- ret.score = 1000;
- ret.why = "No IPv4 or IPv6 ping reply";
- } else if(v6 == undefined && !tagged(sw,'ignorev6')) {
- ret.score = 450;
- ret.why = "No IPv6 ping reply";
- } else if (v4 == undefined) {
- ret.score = 800;
- ret.why = "No IPv4 ping reply";
- }
-
- v4 = parseFloat(v4) ;
- v6 = parseFloat(v6) ;
- if (tagged(sw,'ignorev6')) {
- v6 = 0;
- }
- if (v4 > ret.score || v6 > ret.score) {
- ret.why = "Latency";
- ret.score = parseInt(v4 > v6 ? v4 : v6);
- }
- if (nmsData.ping.switches[sw].age4 > 10 || nmsData.ping.switches[sw].age6 > 10) {
- ret.why = "Old ping";
- ret.score = 900;
- }
- } else {
- ret.data[0].value = "No ping replies";
- ret.why = "No ping replies";
- ret.score = 999;
- }
-
- if (testTree(nmsData,['smanagement','switches',sw])) {
- try {
- var distro = nmsData['smanagement']['switches'][sw]['distro_name'];
- var phy = nmsData['smanagement']['switches'][sw]['distro_phy_port'];
- if (!(distro == "" || phy == "" || distro == undefined || phy == undefined)) {
- ret.data[3] = {};
- ret.data[3].description = "Distro-port";
- ret.data[3].value = distro + " " + phy;
- if (testTree(nmsData,['snmp','snmp',distro, 'ports',phy,'ifOperStatus'])) {
- var x = nmsData['snmp']['snmp'][distro]['ports'][phy]['ifOperStatus'];
- var ping = "no";
- var ping6 = "no ";
- try {
- ping = parseFloat(nmsData["ping"]["switches"][sw]["latency4"]);
- ping6 = parseFloat(nmsData["ping"]["switches"][sw]["latency6"]);
- } catch(e) {}
- if (x == "up") {
- ret.data[3].value += " (😇 up!)";
- if (isNaN(ping) && isNaN(ping6)) {
- ret.score = 700;
- ret.why = "Distro port is alive, but no IPv4/IPv6 ping.";
- if (testTree(nmsData,['snmp','snmp',distro, 'ports',phy,'ifLastChange'])) {
- if (testTree(nmsData,['snmp','snmp',distro, 'misc','sysUpTimeInstance'])) {
- ret.data[4] = {};
- ret.data[4].description = 'Distro port changed';
- diff = (parseInt(nmsData['snmp']['snmp'][distro]['misc']['sysUpTimeInstance']['']) - parseInt(nmsData['snmp']['snmp'][distro]['ports'][phy]['ifLastChange'])) / 100;
- var diff2 = {
- d:parseInt((diff/60/60/24)),
- h:parseInt((diff/60/60)%24),
- m:parseInt((diff/60)%60),
- s:parseInt(diff%60)
- }
-
-
-
- ret.data[4].value = printDiff(diff2);
- }
- }
- }
- } else {
- ret.data[3].value += " (👺down)";
- }
- }
- }
- } catch(e) {
- console.log("Lazy about errors....");
- console.log(e);
- }
- }
- return ret;
+function pingInfo(sw) {
+ var ret = new handlerInfo("ping", "Latency");
+ ret.why = "Latency (?)";
+ ret.score = 0;
+ if (testTree(nmsData, ["ping", "switches", sw])) {
+ var v4 = nmsData.ping.switches[sw].latency4;
+ var v6 = nmsData.ping.switches[sw].latency6;
+ if (v4 == undefined || v4 == null || isNaN(v4)) v4 = undefined;
+ if (v6 == undefined || v6 == null || isNaN(v6)) v6 = undefined;
+ ret.data[0].value = v6 + " ms (v4: " + v4 + " ms)";
+ ret.data[0].description = "Latency(ms)";
+ if (v4 == undefined && v6 == undefined) {
+ ret.score = 1000;
+ ret.why = "No IPv4 or IPv6 ping reply";
+ } else if (v6 == undefined && !tagged(sw, "ignorev6")) {
+ ret.score = 450;
+ ret.why = "No IPv6 ping reply";
+ } else if (v4 == undefined) {
+ ret.score = 800;
+ ret.why = "No IPv4 ping reply";
+ }
+
+ v4 = parseFloat(v4);
+ v6 = parseFloat(v6);
+ if (tagged(sw, "ignorev6")) {
+ v6 = 0;
+ }
+ if (v4 > ret.score || v6 > ret.score) {
+ ret.why = "Latency";
+ ret.score = parseInt(v4 > v6 ? v4 : v6);
+ }
+ if (
+ nmsData.ping.switches[sw].age4 > 10 ||
+ nmsData.ping.switches[sw].age6 > 10
+ ) {
+ ret.why = "Old ping";
+ ret.score = 900;
+ }
+ } else {
+ ret.data[0].value = "No ping replies";
+ ret.why = "No ping replies";
+ ret.score = 999;
+ }
+
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ try {
+ var distro = nmsData["smanagement"]["switches"][sw]["distro_name"];
+ var phy = nmsData["smanagement"]["switches"][sw]["distro_phy_port"];
+ if (
+ !(distro == "" || phy == "" || distro == undefined || phy == undefined)
+ ) {
+ ret.data[3] = {};
+ ret.data[3].description = "Distro-port";
+ ret.data[3].value = distro + " " + phy;
+ if (
+ testTree(nmsData, [
+ "snmp",
+ "snmp",
+ distro,
+ "ports",
+ phy,
+ "ifOperStatus",
+ ])
+ ) {
+ var x = nmsData["snmp"]["snmp"][distro]["ports"][phy]["ifOperStatus"];
+ var ping = "no";
+ var ping6 = "no ";
+ try {
+ ping = parseFloat(nmsData["ping"]["switches"][sw]["latency4"]);
+ ping6 = parseFloat(nmsData["ping"]["switches"][sw]["latency6"]);
+ } catch (e) {}
+ if (x == "up") {
+ ret.data[3].value += " (😇 up!)";
+ if (isNaN(ping) && isNaN(ping6)) {
+ ret.score = 700;
+ ret.why = "Distro port is alive, but no IPv4/IPv6 ping.";
+ if (
+ testTree(nmsData, [
+ "snmp",
+ "snmp",
+ distro,
+ "ports",
+ phy,
+ "ifLastChange",
+ ])
+ ) {
+ if (
+ testTree(nmsData, [
+ "snmp",
+ "snmp",
+ distro,
+ "misc",
+ "sysUpTimeInstance",
+ ])
+ ) {
+ ret.data[4] = {};
+ ret.data[4].description = "Distro port changed";
+ diff =
+ (parseInt(
+ nmsData["snmp"]["snmp"][distro]["misc"][
+ "sysUpTimeInstance"
+ ][""]
+ ) -
+ parseInt(
+ nmsData["snmp"]["snmp"][distro]["ports"][phy][
+ "ifLastChange"
+ ]
+ )) /
+ 100;
+ var diff2 = {
+ d: parseInt(diff / 60 / 60 / 24),
+ h: parseInt((diff / 60 / 60) % 24),
+ m: parseInt((diff / 60) % 60),
+ s: parseInt(diff % 60),
+ };
+
+ ret.data[4].value = printDiff(diff2);
+ }
+ }
+ }
+ } else {
+ ret.data[3].value += " (👺down)";
+ }
+ }
+ }
+ } catch (e) {
+ console.log("Lazy about errors....");
+ console.log(e);
+ }
+ }
+ return ret;
}
-function pingInit()
-{
- nmsColor.drawGradient([nmsColor.green,nmsColor.lightgreen, nmsColor.orange, nmsColor.red]);
- setLegend(1,nmsColor.getColorStop(10),"1ms");
- setLegend(2,nmsColor.getColorStop(300),"30ms");
- setLegend(3,nmsColor.getColorStop(600),"60ms");
- setLegend(4,nmsColor.getColorStop(1000),"100ms");
- setLegend(5,nmsColor.blue,"No response");
- nmsData.addHandler("ping","mapHandler",pingUpdater);
- pingUpdater();
+function pingInit() {
+ nmsColor.drawGradient([
+ nmsColor.green,
+ nmsColor.teal,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ setLegend(1, nmsColor.getColorStop(10), "1ms");
+ setLegend(2, nmsColor.getColorStop(300), "30ms");
+ setLegend(3, nmsColor.getColorStop(600), "60ms");
+ setLegend(4, nmsColor.getColorStop(1000), "100ms");
+ setLegend(5, nmsColor.blue, "No response");
+ nmsData.addHandler("ping", "mapHandler", pingUpdater);
+ pingUpdater();
}
-function getDhcpColor(stop)
-{
- stop = parseInt(stop);
- stop = stop * 0.85;
- if (stop < 0)
- stop = 1000;
- if (stop > 1000)
- stop = 1000;
- return nmsColor.getColorStop(stop);
+function getDhcpColor(stop) {
+ stop = parseInt(stop);
+ stop = stop * 0.85;
+ if (stop < 0) stop = 1000;
+ if (stop > 1000) stop = 1000;
+ return nmsColor.getColorStop(stop);
}
-function dhcpUpdater()
-{
- if (!testTree(nmsData,['dhcp','dhcp4']) || !testTree(nmsData,['dhcp','dhcp6']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) {
- return;
- }
- var now = nmsData.dhcp.time;
- for (var sw in nmsData.switches.switches) {
- var c = nmsColor.blue;
- var sv4 = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan];
- var sv6 = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan];
- if (sv4 == undefined && sv6 == undefined) {
- nmsMap.setSwitchColor(sw,c);
- continue;
- }
- var thenv4 = parseInt(sv4);
- var thenv6 = parseInt(sv6);
- var then = Math.max(thenv4, thenv6)
- c = getDhcpColor(now - then);
- nmsMap.setSwitchColor(sw, c);
- }
+function dhcpUpdater() {
+ if (
+ !testTree(nmsData, ["dhcp", "dhcp4"]) ||
+ !testTree(nmsData, ["dhcp", "dhcp6"]) ||
+ !testTree(nmsData, ["switches", "switches"]) ||
+ !testTree(nmsData, ["smanagement", "switches"])
+ ) {
+ return;
+ }
+ var now = nmsData.dhcp.time;
+ for (var sw in nmsData.switches.switches) {
+ var c = nmsColor.blue;
+ var sv4 = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan];
+ var sv6 = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan];
+ if (sv4 == undefined && sv6 == undefined) {
+ nmsMap.setSwitchColor(sw, c);
+ continue;
+ }
+ var thenv4 = parseInt(sv4);
+ var thenv6 = parseInt(sv6);
+ var then = Math.max(thenv4, thenv6);
+ c = getDhcpColor(now - then);
+ nmsMap.setSwitchColor(sw, c);
+ }
}
function dhcpInfo(sw) {
- var ret = new handlerInfo("dhcp","DHCP state");
- ret.why = "No DHCP data";
- ret.data[0].description = "DHCPv4 age";
-
- ret.data[1] = {};
- ret.data[1].description = "DHCPv6 age";
-
- if (!testTree(nmsData,['dhcp','dhcp4']) || !testTree(nmsData,['dhcp','dhcp6']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) {
- return ret.data[1] = {};
+ var ret = new handlerInfo("dhcp", "DHCP state");
+ ret.why = "No DHCP data";
+ ret.data[0].description = "DHCPv4 age";
+
+ ret.data[1] = {};
+ ret.data[1].description = "DHCPv6 age";
+
+ if (
+ !testTree(nmsData, ["dhcp", "dhcp4"]) ||
+ !testTree(nmsData, ["dhcp", "dhcp6"]) ||
+ !testTree(nmsData, ["switches", "switches"]) ||
+ !testTree(nmsData, ["smanagement", "switches"])
+ ) {
+ return (ret.data[1] = {});
+ }
+ var dhcpClients = 0;
+ var clientPortsUp = 0;
+ var clientPortsUp = setTree(
+ nmsData,
+ ["switchstate", "switches", sw, "clients", "live"],
+ 0
+ );
+ var clientPortsTotal = setTree(
+ nmsData,
+ ["switchstate", "switches", sw, "clients", "total"],
+ 0
+ );
+ if (testTree(nmsData, ["smanagement", "switches", sw, "traffic_vlan"])) {
+ if (
+ testTree(nmsData, [
+ "dhcp",
+ "networks",
+ nmsData.smanagement.switches[sw].traffic_vlan,
+ "clients",
+ ])
+ ) {
+ dhcpClients =
+ nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan]
+ .clients;
+ }
+ }
+ if (
+ testTree(nmsData, [
+ "dhcp",
+ "dhcp4",
+ nmsData.smanagement.switches[sw].traffic_vlan,
+ ])
+ ) {
+ var now = nmsData.dhcp.time;
+ var then =
+ nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan];
+ var diff = now - then;
+ var divider = 10;
+ if (dhcpClients < 10) {
+ divider = 12;
+ }
+ if (tagged(sw, "slowdhcp")) {
+ divider = 12;
+ }
+
+ ret.data[0].value = secondsToTime(diff);
+ ret.why = "DHCP freshness";
+ ret.score = diff / divider > 350 ? 350 : parseInt(diff / divider);
+ } else {
+ ret.data[0].value = "No DHCPv4 data";
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ if (
+ nmsData.smanagement.switches[sw].traffic_vlan == undefined ||
+ nmsData.smanagement.switches[sw].traffic_vlan == ""
+ ) {
+ ret.data[0].value = "No associated networks";
+ ret.score = 0;
+ ret.why = "No network associated";
+ } else {
+ if (!(clientPortsUp < 2 && clientPortsTotal > 20)) {
+ ret.score = 350;
+ ret.why = "No DHCPv4 data";
+ } else {
+ ret.data[0].value = "No DHCPv4 data, but too few clients anyway";
}
- var dhcpClients = 0;
- var clientPortsUp = 0;
- var clientPortsUp = setTree(nmsData,['switchstate','switches',sw,'clients','live'],0);
- var clientPortsTotal = setTree(nmsData,['switchstate','switches',sw,'clients','total'],0);
- if (testTree(nmsData,['smanagement','switches',sw,'traffic_vlan'])) {
- if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) {
- dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients;
- }
- }
- if (testTree(nmsData,['dhcp','dhcp4',nmsData.smanagement.switches[sw].traffic_vlan])) {
- var now = nmsData.dhcp.time;
- var then = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan];
- var diff = now - then;
- var divider = 10;
- if (dhcpClients < 10) {
- divider = 12;
- }
- if(tagged(sw,'slowdhcp')) {
- divider = 12;
- }
-
- ret.data[0].value = secondsToTime(diff);
- ret.why = "DHCP freshness";
- ret.score = diff/divider> 350 ? 350 : parseInt(diff/divider);
- } else {
- ret.data[0].value = "No DHCPv4 data";
- if (testTree(nmsData,['smanagement','switches',sw])) {
- if (nmsData.smanagement.switches[sw].traffic_vlan == undefined ||
- nmsData.smanagement.switches[sw].traffic_vlan == "") {
- ret.data[0].value = "No associated networks";
- ret.score = 0;
- ret.why = "No network associated";
- } else {
- if (!(clientPortsUp < 2 && clientPortsTotal > 20)) {
- ret.score = 350;
- ret.why = "No DHCPv4 data";
- } else {
- ret.data[0].value = "No DHCPv4 data, but too few clients anyway";
- }
- }
- } else {
- ret.score = 100;
- ret.why = "No management data for DHCP";
- }
- }
- if (testTree(nmsData,['dhcp','dhcp6',nmsData.smanagement.switches[sw].traffic_vlan])) {
- var now = nmsData.dhcp.time;
- var then = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan];
- var diff = now - then;
- var divider = 10;
- if (dhcpClients < 10) {
- divider = 12;
- }
- if(tagged(sw,'slowdhcp')) {
- divider = 12;
- }
-
- ret.data[1].value = secondsToTime(diff);
- ret.why = "DHCP freshness";
- ret.score = diff/divider> 350 ? 350 : parseInt(diff/divider);
+ }
+ } else {
+ ret.score = 100;
+ ret.why = "No management data for DHCP";
+ }
+ }
+ if (
+ testTree(nmsData, [
+ "dhcp",
+ "dhcp6",
+ nmsData.smanagement.switches[sw].traffic_vlan,
+ ])
+ ) {
+ var now = nmsData.dhcp.time;
+ var then =
+ nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan];
+ var diff = now - then;
+ var divider = 10;
+ if (dhcpClients < 10) {
+ divider = 12;
+ }
+ if (tagged(sw, "slowdhcp")) {
+ divider = 12;
+ }
+
+ ret.data[1].value = secondsToTime(diff);
+ ret.why = "DHCP freshness";
+ ret.score = diff / divider > 350 ? 350 : parseInt(diff / divider);
+ } else {
+ ret.data[1].value = "No DHCPv6 data";
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ if (
+ nmsData.smanagement.switches[sw].traffic_vlan == undefined ||
+ nmsData.smanagement.switches[sw].traffic_vlan == ""
+ ) {
+ ret.data[1].value = "No associated networks";
+ ret.score = 0;
+ ret.why = "No network associated";
+ } else {
+ if (!(clientPortsUp < 2 && clientPortsTotal > 20)) {
+ ret.score = 350;
+ ret.why = "No DHCPv6 data";
} else {
- ret.data[1].value = "No DHCPv6 data";
- if (testTree(nmsData,['smanagement','switches',sw])) {
- if (nmsData.smanagement.switches[sw].traffic_vlan == undefined ||
- nmsData.smanagement.switches[sw].traffic_vlan == "") {
- ret.data[1].value = "No associated networks";
- ret.score = 0;
- ret.why = "No network associated";
- } else {
- if (!(clientPortsUp < 2 && clientPortsTotal > 20)) {
- ret.score = 350;
- ret.why = "No DHCPv6 data";
- } else {
- ret.data[1].value = "No DHCPv6 data, but too few clients anyway";
- }
- }
- } else {
- ret.score = 100;
- ret.why = "No management data for DHCP";
- }
+ ret.data[1].value = "No DHCPv6 data, but too few clients anyway";
}
- if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) {
- var dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients;
- ret.data[2] = {};
- ret.data[2].value = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients;
- ret.data[2].description = "DHCP clients";
- if (testTree(nmsData,['switchstate','switches',sw,'clients','live'])) {
- var tu = parseInt(nmsData.switchstate.switches[sw].clients.live);
- var tt = parseInt(nmsData.switchstate.switches[sw].clients.total);
- if (tu - dhcpClients > 12) {
- if (ret.score < 450) {
- ret.score = 450;
- ret.why = "Far more client ports than dhcp clients";
- }
- }
- }
- }
- if (testTree(nmsData,['switches','switches',sw, 'tags'])) {
- if (tagged(sw,'ignoredhcp')) {
- ret.score = 0;
- ret.why += "(Ignored)";
- ret.data[0].value += "(Ignored)";
- }
- }
- return ret;
+ }
+ } else {
+ ret.score = 100;
+ ret.why = "No management data for DHCP";
+ }
+ }
+ if (
+ testTree(nmsData, [
+ "dhcp",
+ "networks",
+ nmsData.smanagement.switches[sw].traffic_vlan,
+ "clients",
+ ])
+ ) {
+ var dhcpClients =
+ nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan]
+ .clients;
+ ret.data[2] = {};
+ ret.data[2].value =
+ nmsData.dhcp.networks[
+ nmsData.smanagement.switches[sw].traffic_vlan
+ ].clients;
+ ret.data[2].description = "DHCP clients";
+ if (testTree(nmsData, ["switchstate", "switches", sw, "clients", "live"])) {
+ var tu = parseInt(nmsData.switchstate.switches[sw].clients.live);
+ var tt = parseInt(nmsData.switchstate.switches[sw].clients.total);
+ if (tu - dhcpClients > 12) {
+ if (ret.score < 450) {
+ ret.score = 450;
+ ret.why = "Far more client ports than dhcp clients";
+ }
+ }
+ }
+ }
+ if (testTree(nmsData, ["switches", "switches", sw, "tags"])) {
+ if (tagged(sw, "ignoredhcp")) {
+ ret.score = 0;
+ ret.why += "(Ignored)";
+ ret.data[0].value += "(Ignored)";
+ }
+ }
+ return ret;
}
-function dhcpInit()
-{
- nmsColor.drawGradient([nmsColor.green, nmsColor.lightgreen, nmsColor.orange, nmsColor.red]);
- nmsData.addHandler("dhcp","mapHandler",dhcpUpdater);
- setLegend(1,"white","Undefined");
- setLegend(2,getDhcpColor(1),"1 Second old");
- setLegend(3,getDhcpColor(300),"300 Seconds old");
- setLegend(4,getDhcpColor(900),"900 Seconds old");
- setLegend(5,getDhcpColor(1200),"1200 Seconds old");
- dhcpUpdater();
+function dhcpInit() {
+ nmsColor.drawGradient([
+ nmsColor.green,
+ nmsColor.teal,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ nmsData.addHandler("dhcp", "mapHandler", dhcpUpdater);
+ setLegend(1, "white", "Undefined");
+ setLegend(2, getDhcpColor(1), "1 Second old");
+ setLegend(3, getDhcpColor(300), "300 Seconds old");
+ setLegend(4, getDhcpColor(900), "900 Seconds old");
+ setLegend(5, getDhcpColor(1200), "1200 Seconds old");
+ dhcpUpdater();
}
/*
* Testing-function to randomize colors of linknets and switches
*/
-function randomizeColors()
-{
-/* for (var i in nms.switches_now.linknets) {
+function randomizeColors() {
+ /* for (var i in nms.switches_now.linknets) {
setLinknetColors(i, getRandomColor(), getRandomColor());
}
*/
- if (nmsData.switches == undefined || nmsData.switches.switches == undefined) {
- return;
- }
- for (var sw in nmsData.switches.switches) {
- nmsMap.setSwitchColor(sw, nmsColor.random());
- }
+ if (nmsData.switches == undefined || nmsData.switches.switches == undefined) {
+ return;
+ }
+ for (var sw in nmsData.switches.switches) {
+ nmsMap.setSwitchColor(sw, nmsColor.random());
+ }
}
function discoDo() {
- randomizeColors();
+ randomizeColors();
}
-function discoInit()
-{
- nmsData.addHandler("ticker", "mapHandler", discoDo);
-
- setNightMode(true);
- setLegend(1,nmsColor.blue,"Y");
- setLegend(2,nmsColor.red, "M");
- setLegend(3,nmsColor.orange,"C");
- setLegend(4,nmsColor.green, "A");
- setLegend(5,"white","!");
- discoDo();
+function discoInit() {
+ nmsData.addHandler("ticker", "mapHandler", discoDo);
+
+ setNightMode(true);
+ setLegend(1, nmsColor.blue, "Y");
+ setLegend(2, nmsColor.red, "M");
+ setLegend(3, nmsColor.orange, "C");
+ setLegend(4, nmsColor.green, "A");
+ setLegend(5, "white", "!");
+ discoDo();
}
function snmpUpdater() {
- for (var sw in nmsData.switches.switches) {
- if (nmsData.snmp.snmp[sw] == undefined || nmsData.snmp.snmp[sw].misc == undefined) {
- nmsMap.setSwitchColor(sw, nmsColor.red);
- } else if (nmsData.snmp.snmp[sw].misc.sysName[0] != sw) {
- nmsMap.setSwitchColor(sw, nmsColor.orange);
- } else {
- nmsMap.setSwitchColor(sw, nmsColor.green);
- }
- }
+ for (var sw in nmsData.switches.switches) {
+ if (
+ nmsData.snmp.snmp[sw] == undefined ||
+ nmsData.snmp.snmp[sw].misc == undefined
+ ) {
+ nmsMap.setSwitchColor(sw, nmsColor.red);
+ } else if (nmsData.snmp.snmp[sw].misc.sysName[0] != sw) {
+ nmsMap.setSwitchColor(sw, nmsColor.orange);
+ } else {
+ nmsMap.setSwitchColor(sw, nmsColor.green);
+ }
+ }
}
function secondsToTime(input) {
- var d, h, m, s;
- d = Math.floor(input / 60 / 60 / 24);
- h = Math.floor((input - (d * 24 * 3600)) / 60 / 60);
- m = Math.floor((input%3600)/60);
- s = Math.floor(input%60);
- var string = "";
- if (d > 0)
- string = d + " days ";
- if (h > 0)
- string += h + " hours ";
- if (h > 0 || m > 0)
- string += m + " minutes ";
- if (string == "")
- string += s + " seconds";
- return string;
+ var d, h, m, s;
+ d = Math.floor(input / 60 / 60 / 24);
+ h = Math.floor((input - d * 24 * 3600) / 60 / 60);
+ m = Math.floor((input % 3600) / 60);
+ s = Math.floor(input % 60);
+ var string = "";
+ if (d > 0) string = d + " days ";
+ if (h > 0) string += h + " hours ";
+ if (h > 0 || m > 0) string += m + " minutes ";
+ if (string == "") string += s + " seconds";
+ return string;
}
function snmpInfo(sw) {
- var ret = new handlerInfo("snmp","SNMP data");
- ret.why = "No SNMP data";
- if (tagged(sw,'ignore-snmp')) {
- ret.score = 0;
- ret.why += "(Ignored)";
- ret.data[0].value += "(Ignored)";
- }
- else if (!testTree(nmsData,['snmp','snmp',sw,'misc'])) {
- ret.score = 500;
- ret.why = "No SNMP data";
- ret.data[0].value = "No data";
- if (testTree(nmsData,['smanagement','switches',sw])) {
- if (nmsData.smanagement.switches[sw].community == undefined ||
- nmsData.smanagement.switches[sw].community == "disable") {
- ret.score = 0;
- ret.why = "SNMP disabled";
- ret.data[0].value = "SNMP disabled";
- }
- }
- } else if (nmsData.snmp.snmp[sw].misc.sysName[0].indexOf(sw) != 0) {
- ret.score = 200;
- ret.why = "SNMP sysName doesn't match Gondul sysname";
- ret.data[0].value = ret.why;
- ret.data[1] = { description: "SNMP sysName", value: nmsData.snmp.snmp[sw].misc.sysName[0] };
- } else {
- ret.score = 0;
- ret.data[0].value = "Available";
- ret.why = "SNMP all good";
- }
- if (testTree(nmsData,['snmp','snmp',sw,'misc','sysUpTimeInstance',''])) {
- var uptime = parseInt(nmsData.snmp.snmp[sw]["misc"]["sysUpTimeInstance"][""]) / 100;
- var upstring = secondsToTime(uptime);
- ret.data.push({value: upstring, description: "System uptime"});
- if (uptime < 60*5 && ret.score < 300) {
- ret.score = 300;
- ret.why = "System rebooted last 5 minutes";
- }
- if (uptime < 60*15 && ret.score < 250) {
- ret.score = 250;
- ret.why = "System rebooted last 15 minutes";
- }
- }
- if (testTree(nmsData,['snmp','snmp',sw,'misc','sysDescr','0'])) {
- ret.data[1].description = "Description";
- lol = nmsData['snmp']['snmp'][sw]['misc']['sysDescr']['0'];
- re1 = /Juniper Networks, Inc./
- re2 = /, Build date.*$/
- lol = lol.replace(re1,"")
- lol = lol.replace(re2,"")
- ret.data[1].value = lol
- }
- return ret;
+ var ret = new handlerInfo("snmp", "SNMP data");
+ ret.why = "No SNMP data";
+ if (tagged(sw, "ignore-snmp")) {
+ ret.score = 0;
+ ret.why += "(Ignored)";
+ ret.data[0].value += "(Ignored)";
+ } else if (!testTree(nmsData, ["snmp", "snmp", sw, "misc"])) {
+ ret.score = 500;
+ ret.why = "No SNMP data";
+ ret.data[0].value = "No data";
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ if (
+ nmsData.smanagement.switches[sw].community == undefined ||
+ nmsData.smanagement.switches[sw].community == "disable"
+ ) {
+ ret.score = 0;
+ ret.why = "SNMP disabled";
+ ret.data[0].value = "SNMP disabled";
+ }
+ }
+ } else if (nmsData.snmp.snmp[sw].misc.sysName[0].indexOf(sw) != 0) {
+ ret.score = 200;
+ ret.why = "SNMP sysName doesn't match Gondul sysname";
+ ret.data[0].value = ret.why;
+ ret.data[1] = {
+ description: "SNMP sysName",
+ value: nmsData.snmp.snmp[sw].misc.sysName[0],
+ };
+ } else {
+ ret.score = 0;
+ ret.data[0].value = "Available";
+ ret.why = "SNMP all good";
+ }
+ if (
+ testTree(nmsData, ["snmp", "snmp", sw, "misc", "sysUpTimeInstance", ""])
+ ) {
+ var uptime =
+ parseInt(nmsData.snmp.snmp[sw]["misc"]["sysUpTimeInstance"][""]) / 100;
+ var upstring = secondsToTime(uptime);
+ ret.data.push({ value: upstring, description: "System uptime" });
+ if (uptime < 60 * 5 && ret.score < 300) {
+ ret.score = 300;
+ ret.why = "System rebooted last 5 minutes";
+ }
+ if (uptime < 60 * 15 && ret.score < 250) {
+ ret.score = 250;
+ ret.why = "System rebooted last 15 minutes";
+ }
+ }
+ if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "sysDescr", "0"])) {
+ lol = nmsData["snmp"]["snmp"][sw]["misc"]["sysDescr"]["0"];
+ re1 = /Juniper Networks, Inc./;
+ re2 = /, Build date.*$/;
+ re3 = /Arista Networks./;
+ lol = lol.replace(re1, "");
+ lol = lol.replace(re2, "");
+ lol = lol.replace(re3, "");
+ ret.data.push({ value: lol, description: "Description" });
+ }
+ return ret;
}
-
function snmpInit() {
- nmsData.addHandler("snmp", "mapHandler", snmpUpdater);
-
- setLegend(1,nmsColor.green,"OK");
- setLegend(2,nmsColor.orange, "Sysname mismatch");
- setLegend(3,nmsColor.red,"No SNMP data");
- setLegend(4,nmsColor.green, "");
- setLegend(5,nmsColor.green,"");
- snmpUpdater();
+ nmsData.addHandler("snmp", "mapHandler", snmpUpdater);
+
+ setLegend(1, nmsColor.green, "OK");
+ setLegend(2, nmsColor.orange, "Sysname mismatch");
+ setLegend(3, nmsColor.red, "No SNMP data");
+ setLegend(4, nmsColor.green, "");
+ setLegend(5, nmsColor.green, "");
+ snmpUpdater();
}
function snmpUpInfo(sw) {
- var ret = new handlerInfo("uplink","SNMP uplink data");
- ret.why = "No SNMP data";
- ret.score = 0;
-
- if (testTree(nmsData,['snmp','snmp',sw, 'ports'])) {
- var total_up = 0;
- var seen_up = 0;
- for (var port in nmsData.snmp.snmp[sw].ports) {
- var x = nmsData.snmp.snmp[sw].ports[port];
- if(x["ifAlias"] != null) {
- if (x["ifAlias"].match(/B:/i) && x["ifOperStatus"] == "up") {
- total_up += parseInt(x["ifHighSpeed"]);
- }
- if (x["ifAlias"].match(/G:/i) && x["ifOperStatus"] == "up") {
- seen_up += parseInt(x["ifHighSpeed"]);
- }
- }
- }
- ret.data[0].value = "LAG member speed and total speed is " + seen_up;
- if (total_up != seen_up) {
- ret.score = 500;
- if (tagged(sw,'ignoreuplink')) {
- ret.score = 0;
- }
-
- ret.why = "LAG member (ge/mge/xe/et) speed is " + seen_up + " but logical (ae) is " + total_up;
- ret.data[0].value = ret.why;
- }
- }
- return ret;
+ var ret = new handlerInfo("uplink", "SNMP uplink data");
+ ret.why = "No SNMP uplink data";
+ ret.score = 0;
+
+ if (testTree(nmsData, ["snmp", "snmp", sw, "ports"])) {
+ var total_up = 0;
+ var seen_up = 0;
+ for (var port in nmsData.snmp.snmp[sw].ports) {
+ var x = nmsData.snmp.snmp[sw].ports[port];
+ if (x["ifAlias"] != null) {
+ if (x["ifAlias"].match(/B:/i) && x["ifOperStatus"] == "up") {
+ total_up += parseInt(x["ifHighSpeed"]);
+ }
+ if (x["ifAlias"].match(/G:/i) && x["ifOperStatus"] == "up") {
+ seen_up += parseInt(x["ifHighSpeed"]);
+ }
+ }
+ }
+ ret.data[0].value = "LAG member speed and total speed is " + seen_up;
+ if (total_up != seen_up) {
+ ret.score = 500;
+ if (tagged(sw, "ignoreuplink")) {
+ ret.score = 0;
+ }
+
+ ret.why =
+ "LAG member (ge/mge/xe/et) speed is " +
+ seen_up +
+ " but logical (ae) is " +
+ total_up;
+ ret.data[0].value = ret.why;
+ }
+ }
+ return ret;
}
function cpuInfo(sw) {
- var ret = new handlerInfo("cpu","CPU utilization");
- ret.why = "No CPU info";
- ret.score = 0;
-
- if (testTree(nmsData,['snmp','snmp',sw, 'misc','jnxOperatingCPU'])) {
- var cpu = 0;
- for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) {
- var local = nmsData.snmp.snmp[sw].misc['jnxOperatingCPU'][u];
- cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u],cpu);
- }
- if (cpu < 40) {
- ret.score = 0;
- } else if (cpu < 50) {
- ret.score = 100;
- } else if (cpu < 85 ) {
- ret.score = cpu * 3;
- } else {
- ret.score = cpu * 7;
- }
- ret.why = "CPU utilization: " + cpu + "%";
- ret.data[0].value = cpu + "%";
- }
- return ret;
+ var ret = new handlerInfo("cpu", "CPU utilization");
+ ret.why = "No CPU info";
+ ret.score = 0;
+
+ if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "jnxOperatingCPU"])) {
+ var cpu = 0;
+ for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) {
+ var local = nmsData.snmp.snmp[sw].misc["jnxOperatingCPU"][u];
+ cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u], cpu);
+ }
+ if (cpu < 40) {
+ ret.score = 0;
+ } else if (cpu < 50) {
+ ret.score = 100;
+ } else if (cpu < 85) {
+ ret.score = cpu * 3;
+ } else {
+ ret.score = cpu * 7;
+ }
+ ret.why = "CPU utilization: " + cpu + "%";
+ ret.data[0].value = cpu + "%";
+ }
+ return ret;
}
function cpuUpdater() {
- for (var sw in nmsData.switches.switches) {
- try {
- var cpu = 0;
- for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) {
- var local = nmsData.snmp.snmp[sw].misc['jnxOperatingCPU'][u];
- cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u],cpu);
- }
- nmsMap.setSwitchColor(sw, nmsColor.getColorStop(cpu * 10));
- nmsMap.setSwitchInfo(sw, cpu + " % ");
- } catch (e) {
- nmsMap.setSwitchColor(sw, "white");
- nmsMap.setSwitchInfo(sw, "N/A");
- }
- }
+ for (var sw in nmsData.switches.switches) {
+ try {
+ var cpu = 0;
+ for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) {
+ var local = nmsData.snmp.snmp[sw].misc["jnxOperatingCPU"][u];
+ cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u], cpu);
+ }
+ nmsMap.setSwitchColor(sw, nmsColor.getColorStop(cpu * 10));
+ nmsMap.setSwitchInfo(sw, cpu + " % ");
+ } catch (e) {
+ nmsMap.setSwitchColor(sw, "white");
+ nmsMap.setSwitchInfo(sw, "N/A");
+ }
+ }
}
function memoryUpdater() {
- for (var sw in nmsData.switches.switches) {
- try {
- var buffer = 0;
- for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) {
- var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u];
- buffer = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],buffer);
- }
- nmsMap.setSwitchColor(sw, nmsColor.getColorStop(buffer * 10));
- nmsMap.setSwitchInfo(sw, buffer + " % ");
- } catch (e) {
- nmsMap.setSwitchColor(sw, "white");
- nmsMap.setSwitchInfo(sw, "N/A");
- }
- }
+ for (var sw in nmsData.switches.switches) {
+ try {
+ var buffer = 0;
+ for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) {
+ var local = nmsData.snmp.snmp[sw].misc["jnxOperatingBuffer"][u];
+ buffer = Math.max(
+ nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],
+ buffer
+ );
+ }
+ nmsMap.setSwitchColor(sw, nmsColor.getColorStop(buffer * 10));
+ nmsMap.setSwitchInfo(sw, buffer + " % ");
+ } catch (e) {
+ nmsMap.setSwitchColor(sw, "white");
+ nmsMap.setSwitchInfo(sw, "N/A");
+ }
+ }
}
function memoryInfo(sw) {
- var ret = new handlerInfo("memory","Memory utilization");
- ret.why = "No Memory info";
- ret.score = 0;
-
- if (testTree(nmsData,['snmp','snmp',sw, 'misc','jnxOperatingBuffer'])) {
- var memory = 0;
- for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) {
- var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u];
- memory = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],memory);
- }
- if (memory < 70) {
- ret.score = 0;
- } else if (memory < 80) {
- ret.score = 100;
- } else if (memory < 90) {
- ret.score = memory * 2;
- } else {
- ret.score = memory * 6;
- }
- ret.why = "Memory utilization: " + memory + "%";
- ret.data[0].value = memory + "%";
- }
- return ret;
+ var ret = new handlerInfo("memory", "Memory utilization");
+ ret.why = "No Memory info";
+ ret.score = 0;
+
+ if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "jnxOperatingBuffer"])) {
+ var memory = 0;
+ for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) {
+ var local = nmsData.snmp.snmp[sw].misc["jnxOperatingBuffer"][u];
+ memory = Math.max(
+ nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],
+ memory
+ );
+ }
+ if (memory < 70) {
+ ret.score = 0;
+ } else if (memory < 80) {
+ ret.score = 100;
+ } else if (memory < 90) {
+ ret.score = memory * 2;
+ } else {
+ ret.score = memory * 6;
+ }
+ ret.why = "Memory utilization: " + memory + "%";
+ ret.data[0].value = memory + "%";
+ }
+ return ret;
}
function tagged(sw, tag) {
- try {
- if (testTree(nmsData,['switches','switches',sw, 'tags'])) {
- if (nmsData.switches.switches[sw].tags.includes(tag)) {
- return true;
- }
- }
- } catch(e) {
- console.log("Tried to find tags for " + sw + "but tags-datastructure is probably not an array?");
- }
- return false;
+ try {
+ if (testTree(nmsData, ["switches", "switches", sw, "tags"])) {
+ if (nmsData.switches.switches[sw].tags.includes(tag)) {
+ return true;
+ }
+ }
+ } catch (e) {
+ console.log(
+ "Tried to find tags for " +
+ sw +
+ "but tags-datastructure is probably not an array?"
+ );
+ }
+ return false;
}
function networkInfo(sw) {
- var ret = new handlerInfo("net","Network info");
- ret.score = 0;
- ret.why = "All good";
- if (testTree(nmsData,['smanagement','switches',sw])) {
- var i = 0;
- var mg = nmsData.smanagement.switches[sw];
- var objs = [{
- d: "Management",
- v: setTree(nmsData,['networks','networks',mg.mgmt_vlan],undefined)
- },{
- d: "Traffic",
- v: setTree(nmsData,['networks','networks',mg.traffic_vlan],undefined)
- }
- ];
- for (var x in objs) {
- a = objs[x];
- if (a.v == undefined) {
- ret.data[i++] = {
- value: 'Not set',
- description: a.d + ' network'
- };
- continue;
- }
-
- ret.data[i++] = {
- value: (a.v.name || "Not set") + " " + "vlan: " + (a.v.vlan || "Not set"),
- description: a.d + " network"
- }
- ret.data[i++] = {
- value: a.v.subnet4 || "Not set",
- description: a.d + " subnet IPv4"
- }
- ret.data[i++] = {
- value: a.v.subnet6 || "Not set",
- description: a.d + " subnet IPv6"
- }
- ret.data[i++] = {
- value: a.v.router || "Not set",
- description: a.d + " net router"
- }
- }
- }
- return ret;
+ var ret = new handlerInfo("net", "Network info");
+ ret.score = 0;
+ ret.why = "All good";
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ var i = 0;
+ var mg = nmsData.smanagement.switches[sw];
+ var objs = [
+ {
+ d: "Management",
+ v: setTree(nmsData, ["networks", "networks", mg.mgmt_vlan], undefined),
+ },
+ {
+ d: "Traffic",
+ v: setTree(
+ nmsData,
+ ["networks", "networks", mg.traffic_vlan],
+ undefined
+ ),
+ },
+ ];
+ for (var x in objs) {
+ a = objs[x];
+ if (a.v == undefined) {
+ ret.data[i++] = {
+ value: "Not set",
+ description: a.d + " network",
+ };
+ continue;
+ }
+
+ ret.data[i++] = {
+ value:
+ (a.v.name || "Not set") + " " + "vlan: " + (a.v.vlan || "Not set"),
+ description: a.d + " network",
+ };
+ ret.data[i++] = {
+ value: a.v.subnet4 || "Not set",
+ description: a.d + " subnet IPv4",
+ };
+ ret.data[i++] = {
+ value: a.v.subnet6 || "Not set",
+ description: a.d + " subnet IPv6",
+ };
+ ret.data[i++] = {
+ value: a.v.router || "Not set",
+ description: a.d + " net router",
+ };
+ }
+ }
+ return ret;
}
function mgmtInfo(sw) {
- var ret = new handlerInfo("mgmt","Management info");
- ret.score = 0;
- ret.why = "All good";
- if (testTree(nmsData,['smanagement','switches',sw])) {
- var mg = nmsData.smanagement.switches[sw];
- ret.data =
- [{
- value: (mg.mgmt_v4_addr || "N/A") + " / " + (mg.mgmt_v6_addr || "N/A"),
- description: "Management IP"
- }
- ];
- if ((mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") && (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "")) {
- ret.why = "No IPv4 or IPv6 management IP";
- ret.score = 1000;
- } else if (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") {
- ret.why = "No IPv4 management IP";
- ret.score = 550;
- } else if (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "") {
- ret.why = "No IPv6 management IP";
- ret.score = 560;
- if (tagged(sw,'ignorev6')) {
- ret.score = 0;
- }
- }
- } else {
- ret.score = 1000;
- ret.why = "No management info";
- ret.data = [{}];
- ret.data[0].value = "N/A";
- ret.data[0].description = "Management info";
- };
- if (tagged(sw,'maint')) {
- ret.score = 1337;
- ret.why = "Maintenance mode: maint tag";
- }
- return ret;
+ var ret = new handlerInfo("mgmt", "Management info");
+ ret.score = 0;
+ ret.why = "All good";
+ if (testTree(nmsData, ["smanagement", "switches", sw])) {
+ var mg = nmsData.smanagement.switches[sw];
+ ret.data = [
+ {
+ value: (mg.mgmt_v4_addr || "N/A") + " / " + (mg.mgmt_v6_addr || "N/A"),
+ description: "Management IP",
+ },
+ ];
+ if (
+ (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") &&
+ (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "")
+ ) {
+ ret.why = "No IPv4 or IPv6 management IP";
+ ret.score = 1000;
+ } else if (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") {
+ ret.why = "No IPv4 management IP";
+ ret.score = 550;
+ } else if (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "") {
+ ret.why = "No IPv6 management IP";
+ ret.score = 560;
+ if (tagged(sw, "ignorev6")) {
+ ret.score = 0;
+ }
+ }
+ } else {
+ ret.score = 1000;
+ ret.why = "No management info";
+ ret.data = [{}];
+ ret.data[0].value = "N/A";
+ ret.data[0].description = "Management info";
+ }
+ if (tagged(sw, "maint")) {
+ ret.score = 1337;
+ ret.why = "Maintenance mode: maint tag";
+ }
+ return ret;
}
function cpuInit() {
- nmsData.addHandler("snmp", "mapHandler", cpuUpdater);
- nmsColor.drawGradient([nmsColor.green,nmsColor.orange,nmsColor.red]);
- setLegend(1,getColorStop(0),"0 %");
- setLegend(2,getColorStop(250),"25 %");
- setLegend(3,getColorStop(600),"60 %");
- setLegend(4,getColorStop(1000),"100 %");
- setLegend(5,"white","N/A");
- cpuUpdater();
+ nmsData.addHandler("snmp", "mapHandler", cpuUpdater);
+ nmsColor.drawGradient([nmsColor.green, nmsColor.orange, nmsColor.red]);
+ setLegend(1, getColorStop(0), "0 %");
+ setLegend(2, getColorStop(250), "25 %");
+ setLegend(3, getColorStop(600), "60 %");
+ setLegend(4, getColorStop(1000), "100 %");
+ setLegend(5, "white", "N/A");
+ cpuUpdater();
}
function memoryInit() {
- nmsData.addHandler("snmp", "mapHandler", memoryUpdater);
- nmsColor.drawGradient([nmsColor.green,nmsColor.orange,nmsColor.red]);
- setLegend(1,getColorStop(0),"0 %");
- setLegend(2,getColorStop(250),"25 %");
- setLegend(3,getColorStop(600),"60 %");
- setLegend(4,getColorStop(1000),"100 %");
- setLegend(5,"white","N/A");
- memoryUpdater();
+ nmsData.addHandler("snmp", "mapHandler", memoryUpdater);
+ nmsColor.drawGradient([nmsColor.green, nmsColor.orange, nmsColor.red]);
+ setLegend(1, getColorStop(0), "0 %");
+ setLegend(2, getColorStop(250), "25 %");
+ setLegend(3, getColorStop(600), "60 %");
+ setLegend(4, getColorStop(1000), "100 %");
+ setLegend(5, "white", "N/A");
+ memoryUpdater();
}
function healthInfo(sw) {
- var worst = new handlerInfo("health", "Health");
- var realdata = {};
- worst.score = 0;
- worst.why = "All good";
- for (var h in handlers) {
- if (handlers[h].tag== "health")
- continue;
- if (handlers[h].getInfo == undefined)
- continue;
- var ret = handlers[h].getInfo(sw);
- realdata[handlers[h].tag] = ret.data;
- if (ret.score > worst.score) {
- worst = ret;
- }
- }
- worst.data = [{
- description: "Health (lower is better)",
- value: worst.score + " (" + worst.why + ")"
- }];
- realdata['health'] = worst.data;
- worst.realdata = realdata;
- return worst;
+ var worst = new handlerInfo("health", "Health");
+ var realdata = {};
+ worst.score = 0;
+ worst.why = "All good";
+ for (var h in handlers) {
+ if (handlers[h].tag == "health") continue;
+ if (handlers[h].getInfo == undefined) continue;
+ var ret = handlers[h].getInfo(sw);
+ realdata[handlers[h].tag] = ret.data;
+ if (ret.score > worst.score) {
+ worst = ret;
+ }
+ }
+ worst.data = [
+ {
+ description: "Health (lower is better)",
+ value: worst.score + " (" + worst.why + ")",
+ },
+ ];
+ realdata["health"] = worst.data;
+ worst.realdata = realdata;
+ return worst;
}
-var nmsBlink = []
+var nmsBlink = [];
function healthUpdater() {
- if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
- return;
- for (var sw in nmsData.switches.switches) {
- var worst = healthInfo(sw);
- color = nmsColor.getColorStop(worst.score);
- // maint
- if (worst.score == 1337) {
- nmsMap.setSwitchColor(sw, "#89cff0");
- nmsMap.setSwitchInfo(sw, "maint");
- continue;
- }
- rigge = true;
- // blinkenlights
- if (rigge == false && worst.score > 650) {
- if (nmsBlink[sw] == true) {
- nmsMap.setSwitchColor(sw, "rebeccapurple");
- nmsBlink[sw] = false;
- } else {
- nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score));
- nmsBlink[sw] = true;
- }
- } else {
- nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score));
- }
- if (worst.score > 200)
- nmsMap.setSwitchInfo(sw, worst.tag);
- else {
- if (nms.legendPick != undefined &&
- testTree(worst.realdata,[nms.legendPick.handler,nms.legendPick.idx])) {
- nmsMap.setSwitchInfo(sw,worst.realdata[nms.legendPick.handler][nms.legendPick.idx].value);
- } else {
- nmsMap.setSwitchInfo(sw, undefined);
- }
- }
- }
+ if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
+ return;
+ for (var sw in nmsData.switches.switches) {
+ var worst = healthInfo(sw);
+ color = nmsColor.getColorStop(worst.score);
+ // maint
+ if (worst.score == 1337) {
+ nmsMap.setSwitchColor(sw, "#89cff0");
+ nmsMap.setSwitchInfo(sw, "maint");
+ continue;
+ }
+ rigge = true;
+ // blinkenlights
+ if (rigge == false && worst.score > 650) {
+ if (nmsBlink[sw] == true) {
+ nmsMap.setSwitchColor(sw, "rebeccapurple");
+ nmsBlink[sw] = false;
+ } else {
+ nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score));
+ nmsBlink[sw] = true;
+ }
+ } else {
+ nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score));
+ }
+ if (worst.score > 200) nmsMap.setSwitchInfo(sw, worst.tag);
+ else {
+ if (
+ nms.legendPick != undefined &&
+ testTree(worst.realdata, [nms.legendPick.handler, nms.legendPick.idx])
+ ) {
+ nmsMap.setSwitchInfo(
+ sw,
+ worst.realdata[nms.legendPick.handler][nms.legendPick.idx].value
+ );
+ } else {
+ nmsMap.setSwitchInfo(sw, undefined);
+ }
+ }
+ }
}
function healthInit() {
- nmsData.addHandler("ticker", "mapHandler", healthUpdater);
- nmsColor.drawGradient([nmsColor.green,nmsColor.lightgreen, nmsColor.orange,nmsColor.red]);
- setLegend(1,nmsColor.getColorStop(0),"All good");
- setLegend(2,nmsColor.getColorStop(250),"Ok-ish");
- setLegend(3,nmsColor.getColorStop(600),"Ick-ish");
- setLegend(4,nmsColor.getColorStop(800),"Nasty");
- setLegend(5,nmsColor.getColorStop(1000),"WTF?");
- healthUpdater();
+ nmsData.addHandler("ticker", "mapHandler", healthUpdater);
+ nmsColor.drawGradient([
+ nmsColor.green,
+ nmsColor.teal,
+ nmsColor.orange,
+ nmsColor.red,
+ ]);
+ setLegend(1, nmsColor.getColorStop(0), "All good");
+ setLegend(2, nmsColor.getColorStop(250), "Ok-ish");
+ setLegend(3, nmsColor.getColorStop(600), "Ick-ish");
+ setLegend(4, nmsColor.getColorStop(900), "Nasty");
+ setLegend(5, nmsColor.getColorStop(1000), "WTF?");
+ healthUpdater();
}
diff --git a/web/js/nms-map.js b/web/js/nms-map.js
index bd88d1d..a658925 100644
--- a/web/js/nms-map.js
+++ b/web/js/nms-map.js
@@ -14,136 +14,149 @@
* nmsMap.disableHighlights()
*/
-
var nmsMap = nmsMap || {
- _moveInProgress: false,
- stats: {
- colorChange:0,
- colorSame:0,
- earlyDrawAll:0,
- nowDups:0,
- nows:0,
- resizeEvents:0,
- switchInfoSame:0,
- switchInfoUpdate:0,
- highlightChange:0,
- textSwitchDraws:0,
- textInfoDraws:0,
- textInfoClears:0
- },
- contexts: ["bg","link","blur","switch","text","textInfo","top","input","hidden"],
- _info: {},
- _settings: {
- fontLineFactor: 2,
- textMargin: 4,
- xMargin: 10,
- yMargin: 20,
- fontSize: 14,
- fontFace: "sans-serif"
- },
- scale: 1,
- _init: true,
- _orig: { width:1920, height:1032 },
- _canvas: {
- get width() { return nmsMap.scale * nmsMap._orig.width; },
- get height() { return nmsMap.scale * nmsMap._orig.height; }
- },
-
- _color: { },
- _linknets: {} ,
- _highlight: { },
- _highlightActive: false,
- _c: {},
- _lastName: {},
- _lastInfo: {}
-};
-
-nmsMap._loadEvent = function(e) {
- nmsMap._init = false;
- nmsMap._drawAllSwitches();
-};
-
-nmsMap.init = function() {
- this._initContexts();
- this._init = true;
- nmsData.addHandler("switches","nmsMap",function(){nmsMap._resizeEvent();});
- window.addEventListener('resize',nmsMap._resizeEvent,true);
- window.addEventListener('load',nmsMap._loadEvent,true);
-};
-
-nmsMap.setSwitchColor = function(sw, color) {
- /*
- * NEED TO LOCATE? YAS.
+ _moveInProgress: false,
+ stats: {
+ colorChange: 0,
+ colorSame: 0,
+ earlyDrawAll: 0,
+ nowDups: 0,
+ nows: 0,
+ resizeEvents: 0,
+ switchInfoSame: 0,
+ switchInfoUpdate: 0,
+ highlightChange: 0,
+ textSwitchDraws: 0,
+ textInfoDraws: 0,
+ textInfoClears: 0,
+ },
+ contexts: [
+ "bg",
+ "link",
+ "blur",
+ "switch",
+ "text",
+ "textInfo",
+ "top",
+ "input",
+ "hidden",
+ ],
+ _info: {},
+ _settings: {
+ fontLineFactor: 2,
+ textMargin: 4,
+ xMargin: 10,
+ yMargin: 20,
+ fontSize: 14,
+ fontFace: "sans-serif",
+ },
+ scale: 1,
+ _init: true,
+ _orig: { width: 1920, height: 1032 },
+ _canvas: {
+ get width() {
+ return nmsMap.scale * nmsMap._orig.width;
+ },
+ get height() {
+ return nmsMap.scale * nmsMap._orig.height;
+ },
+ },
+
+ _color: {},
+ _linknets: {},
+ _highlight: {},
+ _highlightActive: false,
+ _c: {},
+ _lastName: {},
+ _lastInfo: {},
+};
+
+nmsMap._loadEvent = function (e) {
+ nmsMap._init = false;
+ nmsMap._drawAllSwitches();
+};
+
+nmsMap.init = function () {
+ this._initContexts();
+ this._init = true;
+ nmsData.addHandler("switches", "nmsMap", function () {
+ nmsMap._resizeEvent();
+ });
+ window.addEventListener("resize", nmsMap._resizeEvent, true);
+ if (document.readyState === "complete") {
+ nmsMap._loadEvent();
+ } else {
+ window.addEventListener("load", nmsMap._loadEvent, true);
+ }
+};
+
+nmsMap.setSwitchColor = function (sw, color) {
+ /*
+ * NEED TO LOCATE? YAS.
if (nmsData.switches.switches[sw] && nmsData.switches.switches[sw].tags.includes("locating") && this._color[sw] != "purple") {
color = "purple";
}
*/
- if (this._color[sw] != color) {
- this._color[sw] = color;
- this._drawSwitch(sw);
- this.stats.colorChange++;
- } else {
- this.stats.colorSame++;
- }
-};
-
-
-nmsMap.setSwitchHighlight = function(sw, highlight) {
- if( highlight )
- highlight = true;
- if ( this._highlight[sw] != highlight ) {
- this.stats.highlightChange++;
- this._highlight[sw] = highlight;
- }
+ if (this._color[sw] != color) {
+ this._color[sw] = color;
this._drawSwitch(sw);
+ this.stats.colorChange++;
+ } else {
+ this.stats.colorSame++;
+ }
};
-
-nmsMap.enableHighlights = function() {
- this._highlightActive = true;
+nmsMap.setSwitchHighlight = function (sw, highlight) {
+ if (highlight) highlight = true;
+ if (this._highlight[sw] != highlight) {
+ this.stats.highlightChange++;
+ this._highlight[sw] = highlight;
+ }
+ this._drawSwitch(sw);
};
-
-nmsMap.disableHighlights = function() {
- this._highlightActive = false;
- this._drawAllSwitches();
+nmsMap.enableHighlights = function () {
+ this._highlightActive = true;
};
+nmsMap.disableHighlights = function () {
+ this._highlightActive = false;
+ this._drawAllSwitches();
+};
-nmsMap.reset = function() {
- for (var sw in this._color) {
- nmsMap.setSwitchColor(sw, undefined);
- }
- for (var sw in this._info) {
- nmsMap.setSwitchInfo(sw, undefined);
- }
+nmsMap.reset = function () {
+ for (var sw in this._color) {
+ nmsMap.setSwitchColor(sw, undefined);
+ }
+ for (var sw in this._info) {
+ nmsMap.setSwitchInfo(sw, undefined);
+ }
};
-nmsMap.setSwitchInfo = function(sw,info) {
- if (info != undefined) {
- var textl = info.length;
- if (textl > 15)
- info = info.slice(0,15);
- }
- if (this._info[sw] != info) {
- this._info[sw] = info;
- this._drawSwitchInfo(sw);
- this.stats.switchInfoUpdate++;
- } else {
- this.stats.switchInfoSame++;
- }
+nmsMap.setSwitchInfo = function (sw, info) {
+ if (info != undefined) {
+ var textl = info.length;
+ if (textl > 15) info = info.slice(0, 15);
+ }
+ if (this._info[sw] != info) {
+ this._info[sw] = info;
+ this._drawSwitchInfo(sw);
+ this.stats.switchInfoUpdate++;
+ } else {
+ this.stats.switchInfoSame++;
+ }
};
-nmsMap._initContext = function(name) {
- this._c[name] = {};
- this._c[name].c = document.getElementById(name + "Canvas");
- this._c[name].ctx = this._c[name].c.getContext('2d');
+nmsMap._initContext = function (name) {
+ this._c[name] = {};
+ this._c[name].c = document.getElementById(name + "Canvas");
+ this._c[name].ctx = this._c[name].c.getContext("2d");
};
-nmsMap._initContexts = function() {
- for (var context in this.contexts) {
- this._initContext(this.contexts[context]);
- }
+nmsMap._initContexts = function () {
+ for (var context in this.contexts) {
+ this._initContext(this.contexts[context]);
+ }
};
/*
@@ -152,56 +165,54 @@ nmsMap._initContexts = function() {
* changed. Example: The menu is toggled. So far this is the same as
* _resizeEvent, but there is no guarantee that will stay true.
*/
-nmsMap.forceResize = function() {
- if (this._init == true) {
- return;
- }
- nmsMap._resizeEvent();
-}
-
-
-nmsMap._resizeEvent = function() {
- var width = window.innerWidth - nmsMap._c.bg.c.offsetLeft;
- var height = window.innerHeight - nmsMap._c.bg.c.offsetTop;
-
- var xScale = (width / (nmsMap._orig.width + nmsMap._settings.xMargin));
- var yScale = (height / (nmsMap._orig.height + nmsMap._settings.yMargin));
-
- /*
- * We need to forget this. Because the rescale will blank the text
- * anyway it is safe to set it to undefined here. This is a special
- * case, if you set it to 'undefined' anywhere else to "reset" or
- * force a redraw of the text you will introduce a bug if a handler
- * then tries to _unset_ the text (which you do by setting the text
- * to undefined)
- */
- nmsMap._lastName = {};
- nmsMap._lastInfo = {};
- if (xScale > yScale) {
- nmsMap.scale = yScale;
- } else {
- nmsMap.scale = xScale;
- }
- for (var a in nmsMap._c) {
- /*
- * Resizing this to a too small size breaks gradients on smaller screens.
- */
- if (a == 'hidden' && a != 'blur')
- continue;
- nmsMap._c[a].c.height = nmsMap._canvas.height;
- nmsMap._c[a].c.width = nmsMap._canvas.width;
- if(a == 'bg') {
- nmsMap._drawBG();
- }
- }
- if (nmsMap._init != true) {
- nmsMap._blurDrawn = false;
- nmsMap._drawBG();
- nmsMap._drawAllSwitches();
- nmsMap._drawAllLinknets();
- nmsMap.drawNow();
- nmsMap.stats.resizeEvents++;
- }
+nmsMap.forceResize = function () {
+ if (this._init == true) {
+ return;
+ }
+ nmsMap._resizeEvent();
+};
+
+nmsMap._resizeEvent = function () {
+ var width = window.innerWidth - nmsMap._c.bg.c.offsetLeft;
+ var height = window.innerHeight - nmsMap._c.bg.c.offsetTop;
+
+ var xScale = width / (nmsMap._orig.width + nmsMap._settings.xMargin);
+ var yScale = height / (nmsMap._orig.height + nmsMap._settings.yMargin);
+
+ /*
+ * We need to forget this. Because the rescale will blank the text
+ * anyway it is safe to set it to undefined here. This is a special
+ * case, if you set it to 'undefined' anywhere else to "reset" or
+ * force a redraw of the text you will introduce a bug if a handler
+ * then tries to _unset_ the text (which you do by setting the text
+ * to undefined)
+ */
+ nmsMap._lastName = {};
+ nmsMap._lastInfo = {};
+ if (xScale > yScale) {
+ nmsMap.scale = yScale;
+ } else {
+ nmsMap.scale = xScale;
+ }
+ for (var a in nmsMap._c) {
+ /*
+ * Resizing this to a too small size breaks gradients on smaller screens.
+ */
+ if (a == "hidden" && a != "blur") continue;
+ nmsMap._c[a].c.height = nmsMap._canvas.height;
+ nmsMap._c[a].c.width = nmsMap._canvas.width;
+ if (a == "bg") {
+ nmsMap._drawBG();
+ }
+ }
+ if (nmsMap._init != true) {
+ nmsMap._blurDrawn = false;
+ nmsMap._drawBG();
+ nmsMap._drawAllSwitches();
+ nmsMap._drawAllLinknets();
+ nmsMap.drawNow();
+ nmsMap.stats.resizeEvents++;
+ }
};
/*
@@ -217,320 +228,341 @@ nmsMap._resizeEvent = function() {
* local time zone with js. Should find a more robust solution.
*
*/
-nmsMap.drawNow = function ()
-{
- var now = nmsData.now;
- var ctx = nmsMap._c.top.ctx;
- if (nmsTime.isRealTime()) {
- if (!nmsMap._nowCleared) {
- ctx.save();
- ctx.scale(this.scale, this.scale);
- ctx.clearRect(0,0,800,100);
- ctx.restore();
- nmsMap._nowCleared = true;
- nmsMap._lastNow = undefined;
- }
- return true;
- }
- nmsMap._nowCleared = false;
- if(String(now).indexOf('T') == -1) { //If now does not contain 'T' we assume its in epoch format
- now = new Date(nmsData.now * 1000);
- } else {
- now = new Date(nmsData.now); //Date assumes UTC
- }
- now = now.toString().split(' ').splice(0,5).join(' '); //Date returns local time
- if (nmsMap._lastNow == now) {
- nmsMap.stats.nowDups++;
- return;
- }
- nmsMap.stats.nows++;
-
- ctx.save();
- ctx.scale(this.scale, this.scale);
- ctx.font = (2 * this._settings.fontSize) + "px " + this._settings.fontFace;
- ctx.clearRect(0,0,800,100);
- ctx.fillStyle = "white";
- ctx.strokeStyle = "black";
- ctx.translate(200,0);
- ctx.lineWidth = nms.fontLineFactor;
- ctx.strokeText(now, this._settings.textMargin, 25);
- ctx.fillText(now, this._settings.textMargin, 25);
- ctx.restore();
-};
-
-nmsMap.setNightMode = function(toggle) {
- if (this._nightmode == toggle)
- return;
- this._nightmode = toggle;
- if (this._init == true) {
- return;
- }
- if (!toggle)
- this._c.blur.c.style.display = "none";
- else {
- this._drawAllBlur();
- this._c.blur.c.style.display = "";
- }
- nmsMap._drawBG();
-};
-
-nmsMap._drawBG = function() {
- var imageObj = document.getElementById('source');
- this._c.bg.ctx.drawImage(imageObj, 0, 0, nmsMap._canvas.width, nmsMap._canvas.height);
- if(this._nightmode)
- nmsMap._invertBG();
-};
-
-nmsMap._invertBG = function() {
- var imageData = this._c.bg.ctx.getImageData(0, 0, nmsMap._canvas.width, nmsMap._canvas.height);
- var data = imageData.data;
-
- for(var i = 0; i < data.length; i += 4) {
- data[i] = 255 - data[i];
- data[i + 1] = 255 - data[i + 1];
- data[i + 2] = 255 - data[i + 2];
- }
- this._c.bg.ctx.putImageData(imageData, 0, 0);
-};
-
-nmsMap._getBox = function(sw) {
- var box = nmsData.switches.switches[sw]['placement'];
- box.x = parseInt(box.x);
- box.y = parseInt(box.y);
- box.width = parseInt(box.width);
- box.height = parseInt(box.height);
- return box;
-};
-
-nmsMap._drawSwitchBlur = function(sw)
-{
- if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
- return;
- var box = this._getBox(sw);
- this._c.blur.ctx.save();
- this._c.blur.ctx.fillStyle = "red";
- this._c.blur.ctx.shadowBlur = 30;
- this._c.blur.ctx.shadowColor = "white";
- this._c.blur.ctx.scale(this.scale, this.scale); // FIXME <- fix what?!
- this._c.blur.ctx.fillRect(box['x'],box['y'],box['width'],box['height']);
- this._c.blur.ctx.restore();
-};
-
-nmsMap._drawSwitch = function(sw)
-{
- // XXX: If a handler sets a color before switches are loaded... The
- // color will get set fine so this isn't a problem.
- if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
- return;
- var box = this._getBox(sw);
- var color = nmsMap._color[sw];
- if(this._highlightActive) {
- if(nmsMap._highlight[sw]) {
- color = nmsColor.green;
- } else {
- color = nmsColor.white;
- }
- }
- if (color == undefined) {
- color = nmsColor.blue;
- }
- this._c.switch.ctx.fillStyle = color;
- this._drawBox(this._c.switch.ctx, box['x'],box['y'],box['width'],box['height']);
- this._c.switch.ctx.shadowBlur = 0;
- var switchtext = sw;
- var textl = switchtext.length;
- // Cut switch name if longer than this
- var text_cut_l = 14;
- // Cut switch name by more if we have a status indicator
- if (this._info[sw]) {
- text_cut_l -= this._info[sw].length
- }
- if (textl > text_cut_l) {
- var rhs_text = this._info[sw];
-
- switchtext = switchtext.slice(0,text_cut_l - 5) + ".." + switchtext.slice(textl-2,textl);
- }
- // Don't display AP name
- if (switchtext[0] == "a" && switchtext[1] == "p") {
- switchtext = "ap";
- }
-
- if (this._lastName[sw] != switchtext) {
- nmsMap.stats.textSwitchDraws++;
- this._drawText(this._c.text.ctx, switchtext,box);
- this._lastName[sw] = switchtext;
- }
-
- if(this._info[sw])
- this._drawSwitchInfo(sw);
-};
-
-nmsMap._drawSwitchInfo = function(sw) {
- var box = this._getBox(sw);
- if (this._lastInfo[sw] == this._info[sw])
- return;
- // Skip info on APs
- if (sw[0] == "a" && sw[1] == "p") {
- return;
- }
- this._clearBox(this._c.textInfo.ctx, box, 3);
- nmsMap.stats.textInfoClears++;
- if (this._info[sw] != undefined) {
- this._drawText(this._c.textInfo.ctx, this._info[sw], box, "right");
- nmsMap.stats.textInfoDraws++;
- }
- this._lastInfo[sw] = this._info[sw];
-};
-
-nmsMap._clearBox = function(ctx,box,margin) {
- if (margin == undefined)
- margin = 0;
- ctx.save();
- margin = Math.floor(margin * this.scale );
- ctx.scale(this.scale,this.scale);
- ctx.clearRect(box['x'] - margin, box['y'] - margin, box['width'] + margin*2, box['height'] + margin*2);
- ctx.restore();
-};
-
-nmsMap._drawText = function(ctx, text, box, align) {
- var rotate = false;
-
- if ((box['width'] + 10 )< box['height'])
- rotate = true;
-
- this._clearBox(ctx,box, 1);
- ctx.save();
- ctx.scale(this.scale, this.scale);
- ctx.font = "bold " + this._settings.fontSize + "px " + this._settings.fontFace;
- ctx.lineWidth = nmsMap._settings.fontLineFactor;
- ctx.fillStyle = "white";
- ctx.strokeStyle = "black";
- ctx.translate(box.x + this._settings.textMargin, box.y + box.height - this._settings.textMargin);
-
- if (rotate) {
- ctx.translate(box.width - this._settings.textMargin * 2,0);
- ctx.rotate(Math.PI * 3/2);
- }
-
- if (align == "right") {
- ctx.textAlign = "right";
- /*
- * Margin*2 is to compensate for the margin above.
- */
- if (rotate)
- ctx.translate(box.height - this._settings.textMargin*2,0);
- else
- ctx.translate(box.width - this._settings.textMargin*2,0);
- }
-
- ctx.strokeText(text, 0, 0);
- ctx.fillText(text, 0, 0);
- ctx.restore();
-};
-
-nmsMap._setLinknetColor = function(l, color1, color2)
-{
- var oldcolor1;
- var oldcolor2;
- try {
- oldcolor1 = nmsMap._linknets[l].sysname1;
- oldcolor2 = nmsMap._linknets[l].sysname2;
- if (oldcolor1 == color1 && oldcolor2 == color2) {
- return ;
- }
- } catch (e) {}
- nmsMap._linknets[l] = {};
- nmsMap._linknets[l].sysname1 = color1;
- nmsMap._linknets[l].sysname2 = color2;
- nmsMap._drawLinknet(l)
-}
-
-nmsMap._drawLinknet = function(l) {
- try {
- var color1 = nmsColor.blue;
- var color2 = nmsColor.blue;
- try {
- color1 = nmsMap._linknets[l].sysname1;
- color2 = nmsMap._linknets[l].sysname2;
- } catch(e) { }
- nmsMap._connectSwitches(nmsData.switches.linknets[l].sysname1, nmsData.switches.linknets[l].sysname2, color1, color2);
- } catch(e) { }
-}
-
-nmsMap._drawAllLinknets = function() {
- for (var l in nmsData.switches.linknets) {
- nmsMap._drawLinknet(l);
- }
-}
-nmsMap._drawAllSwitches = function() {
- if (nmsData.switches == undefined) {
- this.stats.earlyDrawAll++;
- return;
- }
- for (var sw in nmsData.switches.switches) {
- this._drawSwitch(sw);
- }
- if (this._nightmode)
- this._drawAllBlur();
+nmsMap.drawNow = function () {
+ var now = nmsData.now;
+ var ctx = nmsMap._c.top.ctx;
+ if (nmsTime.isRealTime()) {
+ if (!nmsMap._nowCleared) {
+ ctx.save();
+ ctx.scale(this.scale, this.scale);
+ ctx.clearRect(0, 0, 800, 100);
+ ctx.restore();
+ nmsMap._nowCleared = true;
+ nmsMap._lastNow = undefined;
+ }
+ return true;
+ }
+ nmsMap._nowCleared = false;
+ if (String(now).indexOf("T") == -1) {
+ //If now does not contain 'T' we assume its in epoch format
+ now = new Date(nmsData.now * 1000);
+ } else {
+ now = new Date(nmsData.now); //Date assumes UTC
+ }
+ now = now.toString().split(" ").splice(0, 5).join(" "); //Date returns local time
+ if (nmsMap._lastNow == now) {
+ nmsMap.stats.nowDups++;
+ return;
+ }
+ nmsMap.stats.nows++;
+
+ ctx.save();
+ ctx.scale(this.scale, this.scale);
+ ctx.font = 2 * this._settings.fontSize + "px " + this._settings.fontFace;
+ ctx.clearRect(0, 0, 800, 100);
+ ctx.fillStyle = "white";
+ ctx.strokeStyle = "black";
+ ctx.translate(200, 0);
+ ctx.lineWidth = nms.fontLineFactor;
+ ctx.strokeText(now, this._settings.textMargin, 25);
+ ctx.fillText(now, this._settings.textMargin, 25);
+ ctx.restore();
+};
+
+nmsMap.setNightMode = function (toggle) {
+ if (this._nightmode == toggle) return;
+ this._nightmode = toggle;
+ if (this._init == true) {
+ return;
+ }
+ if (!toggle) this._c.blur.c.style.display = "none";
+ else {
+ this._drawAllBlur();
+ this._c.blur.c.style.display = "";
+ }
+ nmsMap._drawBG();
+};
+
+nmsMap._drawBG = function () {
+ var imageObj = document.getElementById("source");
+ this._c.bg.ctx.drawImage(
+ imageObj,
+ 0,
+ 0,
+ nmsMap._canvas.width,
+ nmsMap._canvas.height
+ );
+ if (this._nightmode) nmsMap._invertBG();
+};
+
+nmsMap._invertBG = function () {
+ var imageData = this._c.bg.ctx.getImageData(
+ 0,
+ 0,
+ nmsMap._canvas.width,
+ nmsMap._canvas.height
+ );
+ var data = imageData.data;
+
+ for (var i = 0; i < data.length; i += 4) {
+ data[i] = 255 - data[i];
+ data[i + 1] = 255 - data[i + 1];
+ data[i + 2] = 255 - data[i + 2];
+ }
+ this._c.bg.ctx.putImageData(imageData, 0, 0);
+};
+
+nmsMap._getBox = function (sw) {
+ var box = nmsData.switches.switches[sw]["placement"];
+ box.x = parseInt(box.x);
+ box.y = parseInt(box.y);
+ box.width = parseInt(box.width);
+ box.height = parseInt(box.height);
+ return box;
+};
+
+nmsMap._drawSwitchBlur = function (sw) {
+ if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
+ return;
+ var box = this._getBox(sw);
+ this._c.blur.ctx.save();
+ this._c.blur.ctx.fillStyle = "red";
+ this._c.blur.ctx.shadowBlur = 30;
+ this._c.blur.ctx.shadowColor = "white";
+ this._c.blur.ctx.scale(this.scale, this.scale); // FIXME <- fix what?!
+ this._c.blur.ctx.fillRect(box["x"], box["y"], box["width"], box["height"]);
+ this._c.blur.ctx.restore();
+};
+
+nmsMap._drawSwitch = function (sw) {
+ // XXX: If a handler sets a color before switches are loaded... The
+ // color will get set fine so this isn't a problem.
+ if (nmsData.switches == undefined || nmsData.switches.switches == undefined)
+ return;
+ var box = this._getBox(sw);
+ var color = nmsMap._color[sw];
+ if (this._highlightActive) {
+ if (nmsMap._highlight[sw]) {
+ color = nmsColor.green;
+ } else {
+ color = nmsColor.white;
+ }
+ }
+ if (color == undefined) {
+ color = nmsColor.blue;
+ }
+ this._c.switch.ctx.fillStyle = color;
+ this._drawBox(
+ this._c.switch.ctx,
+ box["x"],
+ box["y"],
+ box["width"],
+ box["height"]
+ );
+ this._c.switch.ctx.shadowBlur = 0;
+ var switchtext = sw;
+ var textl = switchtext.length;
+ // Cut switch name if longer than this
+ var text_cut_l = 18;
+ // Cut switch name by more if we have a status indicator
+ if (this._info[sw]) {
+ text_cut_l -= this._info[sw].length;
+ }
+ if (textl > text_cut_l) {
+ var rhs_text = this._info[sw];
+
+ switchtext =
+ switchtext.slice(0, text_cut_l - 5) +
+ ".." +
+ switchtext.slice(textl - 2, textl);
+ }
+ // Don't display AP name
+ if (switchtext[0] == "a" && switchtext[1] == "p") {
+ switchtext = "ap";
+ }
+
+ if (this._lastName[sw] != switchtext) {
+ nmsMap.stats.textSwitchDraws++;
+ this._drawText(this._c.text.ctx, switchtext, box);
+ this._lastName[sw] = switchtext;
+ }
+
+ if (this._info[sw]) this._drawSwitchInfo(sw);
+};
+
+nmsMap._drawSwitchInfo = function (sw) {
+ var box = this._getBox(sw);
+ if (this._lastInfo[sw] == this._info[sw]) return;
+ // Skip info on APs
+ if (sw[0] == "a" && sw[1] == "p") {
+ return;
+ }
+ this._clearBox(this._c.textInfo.ctx, box, 3);
+ nmsMap.stats.textInfoClears++;
+ if (this._info[sw] != undefined) {
+ this._drawText(this._c.textInfo.ctx, this._info[sw], box, "right");
+ nmsMap.stats.textInfoDraws++;
+ }
+ this._lastInfo[sw] = this._info[sw];
+};
+
+nmsMap._clearBox = function (ctx, box, margin) {
+ if (margin == undefined) margin = 0;
+ ctx.save();
+ margin = Math.floor(margin * this.scale);
+ ctx.scale(this.scale, this.scale);
+ ctx.clearRect(
+ box["x"] - margin,
+ box["y"] - margin,
+ box["width"] + margin * 2,
+ box["height"] + margin * 2
+ );
+ ctx.restore();
+};
+
+nmsMap._drawText = function (ctx, text, box, align) {
+ var rotate = false;
+
+ if (box["width"] + 10 < box["height"]) rotate = true;
+
+ this._clearBox(ctx, box, 1);
+ ctx.save();
+ ctx.scale(this.scale, this.scale);
+ ctx.font =
+ "bold " + this._settings.fontSize + "px " + this._settings.fontFace;
+ ctx.lineWidth = nmsMap._settings.fontLineFactor;
+ ctx.fillStyle = "white";
+ ctx.strokeStyle = "black";
+ ctx.translate(
+ box.x + this._settings.textMargin,
+ box.y + box.height - this._settings.textMargin
+ );
+
+ if (rotate) {
+ ctx.translate(box.width - this._settings.textMargin * 2, 0);
+ ctx.rotate((Math.PI * 3) / 2);
+ }
+
+ if (align == "right") {
+ ctx.textAlign = "right";
+ /*
+ * Margin*2 is to compensate for the margin above.
+ */
+ if (rotate) ctx.translate(box.height - this._settings.textMargin * 2, 0);
+ else ctx.translate(box.width - this._settings.textMargin * 2, 0);
+ }
+
+ ctx.strokeText(text, 0, 0);
+ ctx.fillText(text, 0, 0);
+ ctx.restore();
+};
+
+nmsMap._setLinknetColor = function (l, color1, color2) {
+ var oldcolor1;
+ var oldcolor2;
+ try {
+ oldcolor1 = nmsMap._linknets[l].sysname1;
+ oldcolor2 = nmsMap._linknets[l].sysname2;
+ if (oldcolor1 == color1 && oldcolor2 == color2) {
+ return;
+ }
+ } catch (e) {}
+ nmsMap._linknets[l] = {};
+ nmsMap._linknets[l].sysname1 = color1;
+ nmsMap._linknets[l].sysname2 = color2;
+ nmsMap._drawLinknet(l);
+};
+
+nmsMap._drawLinknet = function (l) {
+ try {
+ var color1 = nmsColor.blue;
+ var color2 = nmsColor.blue;
+ try {
+ color1 = nmsMap._linknets[l].sysname1;
+ color2 = nmsMap._linknets[l].sysname2;
+ } catch (e) {}
+ nmsMap._connectSwitches(
+ nmsData.switches.linknets[l].sysname1,
+ nmsData.switches.linknets[l].sysname2,
+ color1,
+ color2
+ );
+ } catch (e) {}
+};
+
+nmsMap._drawAllLinknets = function () {
+ for (var l in nmsData.switches.linknets) {
+ nmsMap._drawLinknet(l);
+ }
+};
+nmsMap._drawAllSwitches = function () {
+ if (nmsData.switches == undefined) {
+ this.stats.earlyDrawAll++;
+ return;
+ }
+ for (var sw in nmsData.switches.switches) {
+ this._drawSwitch(sw);
+ }
+ if (this._nightmode) this._drawAllBlur();
};
-nmsMap._drawAllBlur = function() {
- if (nmsMap._blurDrawn == true)
- return;
- nmsMap._blurDrawn = true;
- for (var sw in nmsData.switches.switches) {
- nmsMap._drawSwitchBlur(sw);
- }
+nmsMap._drawAllBlur = function () {
+ if (nmsMap._blurDrawn == true) return;
+ nmsMap._blurDrawn = true;
+ for (var sw in nmsData.switches.switches) {
+ nmsMap._drawSwitchBlur(sw);
+ }
};
-nmsMap._drawBox = function(ctx, x, y, boxw, boxh) {
- ctx.save();
- ctx.scale(this.scale, this.scale); // FIXME <- what?!
- ctx.fillRect(x,y, boxw, boxh);
- ctx.lineWidth = 1;
- ctx.strokeStyle = "#000000";
- ctx.strokeRect(x,y, boxw, boxh);
- ctx.restore();
+nmsMap._drawBox = function (ctx, x, y, boxw, boxh) {
+ ctx.save();
+ ctx.scale(this.scale, this.scale); // FIXME <- what?!
+ ctx.fillRect(x, y, boxw, boxh);
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = "#000000";
+ ctx.strokeRect(x, y, boxw, boxh);
+ ctx.restore();
};
-nmsMap._connectSwitches = function(sw1, sw2, color1, color2) {
- nmsMap._connectBoxes(nmsMap._getBox(sw1), nmsMap._getBox(sw2),
- color1, color2);
+nmsMap._connectSwitches = function (sw1, sw2, color1, color2) {
+ nmsMap._connectBoxes(
+ nmsMap._getBox(sw1),
+ nmsMap._getBox(sw2),
+ color1,
+ color2
+ );
};
/*
* Draw a line between two boxes, with a gradient going from color1 to
* color2.
*/
-nmsMap._connectBoxes = function(box1, box2,color1, color2) {
- var ctx = nmsMap._c.link.ctx;
- if (color1 == undefined)
- color1 = nmsColor.blue;
- if (color2 == undefined)
- color2 = nmsColor.blue;
- var x0 = Math.floor(box1.x + box1.width/2);
- var y0 = Math.floor(box1.y + box1.height/2);
- var x1 = Math.floor(box2.x + box2.width/2);
- var y1 = Math.floor(box2.y + box2.height/2);
- ctx.save();
- ctx.scale(nmsMap.scale, nmsMap.scale);
- var gradient = ctx.createLinearGradient(x1,y1,x0,y0);
- gradient.addColorStop(0, color1);
- gradient.addColorStop(1, color2);
- ctx.strokeStyle = gradient;
- ctx.beginPath();
- ctx.moveTo(x0,y0);
- ctx.lineTo(x1,y1);
- ctx.lineWidth = 5;
- ctx.stroke();
- ctx.closePath();
- ctx.restore();
-};
-
-nmsMap.moveSet = function(toggle) {
- nmsMap._moveInProgress = toggle;
- if (!toggle)
- nmsMap._moveStopListen();
+nmsMap._connectBoxes = function (box1, box2, color1, color2) {
+ var ctx = nmsMap._c.link.ctx;
+ if (color1 == undefined) color1 = nmsColor.blue;
+ if (color2 == undefined) color2 = nmsColor.blue;
+ var x0 = Math.floor(box1.x + box1.width / 2);
+ var y0 = Math.floor(box1.y + box1.height / 2);
+ var x1 = Math.floor(box2.x + box2.width / 2);
+ var y1 = Math.floor(box2.y + box2.height / 2);
+ ctx.save();
+ ctx.scale(nmsMap.scale, nmsMap.scale);
+ var gradient = ctx.createLinearGradient(x1, y1, x0, y0);
+ gradient.addColorStop(0, color1);
+ gradient.addColorStop(1, color2);
+ ctx.strokeStyle = gradient;
+ ctx.beginPath();
+ ctx.moveTo(x0, y0);
+ ctx.lineTo(x1, y1);
+ ctx.lineWidth = 5;
+ ctx.stroke();
+ ctx.closePath();
+ ctx.restore();
+};
+
+nmsMap.moveSet = function (toggle) {
+ nmsMap._moveInProgress = toggle;
+ if (!toggle) nmsMap._moveStopListen();
};
/*
@@ -538,91 +570,92 @@ nmsMap.moveSet = function(toggle) {
*
* Currently just shows info for a switch.
*/
-nmsMap.canvasClick = function(e)
-{
- var sw = findSwitch(e.pageX - e.target.offsetLeft, e.pageY - e.target.offsetTop);
- if (sw != undefined) {
- if (nmsMap._moveInProgress) {
- nmsMap._moveStart(sw, e);
- } else {
- nmsInfoBox.click(sw);
- }
- } else {
- nmsInfoBox.hide();
- }
-};
-
-nmsMap._clearOld = function(box) {
- if (box) {
- nmsMap._c.top.ctx.save();
- nmsMap._c.top.ctx.fillStyle = "#000000";
- nmsMap._c.top.ctx.scale(nmsMap.scale, nmsMap.scale); // FIXME
- nmsMap._c.top.ctx.clearRect(box['x'] - 5, box['y'] - 5, box['width'] + 10, box['height'] + 10);
- nmsMap._c.top.ctx.restore();
- }
-};
-
-nmsMap._moveMove = function(e) {
- nmsMap._moveX = (e.pageX - e.target.offsetLeft) / nmsMap.scale;
- nmsMap._moveY = (e.pageY - e.target.offsetTop) / nmsMap.scale;
- var diffx = nmsMap._moveX - nmsMap._moveXstart;
- var diffy = nmsMap._moveY - nmsMap._moveYstart;
- var box = {};
- nmsMap._clearOld(nmsMap._moveOldBox);
- box['x'] = nmsMap._moveBox['x'] + diffx;
- box['y'] = nmsMap._moveBox['y'] + diffy;
- box['height'] = nmsMap._moveBox['height'];
- box['width'] = nmsMap._moveBox['width'];
- nmsMap._moveOldBox = box;
- nmsMap._c.top.ctx.save();
- nmsMap._c.top.ctx.fillStyle = "red";
- nmsMap._drawBox(nmsMap._c.top.ctx, box['x'], box['y'], box['width'], box['height']);
- nmsMap._c.top.ctx.restore();
-};
-
-nmsMap._moveSubmit = function() {
- var data = {
- sysname: nmsMap._moving,
- placement: nmsMap._moveOldBox
- };
- var myData = JSON.stringify([data]);
- $.ajax({
- type: "POST",
- url: "/api/write/switches",
- dataType: "text",
- data:myData,
- success: function (data, textStatus, jqXHR) {
- nmsData.invalidate("switches");
- }
- });
-};
-
-nmsMap._moveStopListen = function() {
- nmsMap._c.input.c.removeEventListener('mousemove',nmsMap._moveMove, true);
- nmsMap._c.input.c.removeEventListener('mouseup',nmsMap._moveDone, true);
-};
-
-nmsMap._moveDone = function(e) {
- nmsMap._moveStopListen();
- if(nmsMap._moveOldBox == false) {
- return;
- }
- nmsMap._moveSubmit();
- nmsMap._clearOld(nmsMap._moveOldBox);
-};
-
-nmsMap._moveStart = function(sw, e)
-{
- nmsMap._moving = sw;
- nmsMap._moveOldBox = false;
- nmsMap._moveXstart = (e.pageX - e.target.offsetLeft) / nmsMap.scale;
- nmsMap._moveYstart = (e.pageY - e.target.offsetTop) / nmsMap.scale;
- nmsMap._moveBox = nmsData.switches.switches[sw].placement;
- nmsMap._c.input.c.addEventListener('mousemove',nmsMap._moveMove,true);
- nmsMap._c.input.c.addEventListener('mouseup',nmsMap._moveDone,true);
+nmsMap.canvasClick = function (e) {
+ var sw = findSwitch(
+ e.pageX - e.target.offsetLeft,
+ e.pageY - e.target.offsetTop
+ );
+ if (sw != undefined) {
+ if (nmsMap._moveInProgress) {
+ nmsMap._moveStart(sw, e);
+ } else {
+ nmsInfoBox.click(sw);
+ }
+ } else {
+ nmsInfoBox.hide();
+ }
+};
+
+nmsMap._clearOld = function (box) {
+ if (box) {
+ nmsMap._c.top.ctx.save();
+ nmsMap._c.top.ctx.fillStyle = "#000000";
+ nmsMap._c.top.ctx.scale(nmsMap.scale, nmsMap.scale); // FIXME
+ nmsMap._c.top.ctx.clearRect(
+ box["x"] - 5,
+ box["y"] - 5,
+ box["width"] + 10,
+ box["height"] + 10
+ );
+ nmsMap._c.top.ctx.restore();
+ }
+};
+
+nmsMap._moveMove = function (e) {
+ nmsMap._moveX = (e.pageX - e.target.offsetLeft) / nmsMap.scale;
+ nmsMap._moveY = (e.pageY - e.target.offsetTop) / nmsMap.scale;
+ var diffx = nmsMap._moveX - nmsMap._moveXstart;
+ var diffy = nmsMap._moveY - nmsMap._moveYstart;
+ var box = {};
+ nmsMap._clearOld(nmsMap._moveOldBox);
+ box["x"] = parseInt(nmsMap._moveBox["x"] + diffx);
+ box["y"] = parseInt(nmsMap._moveBox["y"] + diffy);
+ box["height"] = parseInt(nmsMap._moveBox["height"]);
+ box["width"] = parseInt(nmsMap._moveBox["width"]);
+ nmsMap._moveOldBox = box;
+ nmsMap._c.top.ctx.save();
+ nmsMap._c.top.ctx.fillStyle = "red";
+ nmsMap._drawBox(
+ nmsMap._c.top.ctx,
+ box["x"],
+ box["y"],
+ box["width"],
+ box["height"]
+ );
+ nmsMap._c.top.ctx.restore();
+};
+
+nmsMap._moveSubmit = function () {
+ var sysname = nmsMap._moving;
+ var placement = nmsMap._moveOldBox;
+ const data = postData(`/api/v2/devices/${sysname}/placement`, placement);
+ console.log(data);
+};
+
+nmsMap._moveStopListen = function () {
+ nmsMap._c.input.c.removeEventListener("mousemove", nmsMap._moveMove, true);
+ nmsMap._c.input.c.removeEventListener("mouseup", nmsMap._moveDone, true);
+};
+
+nmsMap._moveDone = function (e) {
+ nmsMap._moveStopListen();
+ if (nmsMap._moveOldBox == false) {
+ return;
+ }
+ nmsMap._moveSubmit();
+ nmsMap._clearOld(nmsMap._moveOldBox);
+};
+
+nmsMap._moveStart = function (sw, e) {
+ nmsMap._moving = sw;
+ nmsMap._moveOldBox = false;
+ nmsMap._moveXstart = (e.pageX - e.target.offsetLeft) / nmsMap.scale;
+ nmsMap._moveYstart = (e.pageY - e.target.offsetTop) / nmsMap.scale;
+ nmsMap._moveBox = nmsData.switches.switches[sw].placement;
+ nmsMap._c.input.c.addEventListener("mousemove", nmsMap._moveMove, true);
+ nmsMap._c.input.c.addEventListener("mouseup", nmsMap._moveDone, true);
};
-
/*
* STUFF NOT YET INTEGRATED, BUT MOVED AWAY FROM nms.js TO TIDY.
*
@@ -634,25 +667,37 @@ nmsMap._moveStart = function(sw, e)
*
* XXX: Might have to change the index here to match backend
*/
-function drawLinknet(i)
-{
- var c1 = nms.linknet_color[i] && nms.linknet_color[i].c1 ? nms.linknet_color[i].c1 : blue;
- var c2 = nms.linknet_color[i] && nms.linknet_color[i].c2 ? nms.linknet_color[i].c2 : blue;
- if (nmsData.switches.switches[nmsData.switches.linknets[i].sysname1] && nmsData.switches.switches[nmsData.switches.linknets[i].sysname2]) {
- connectSwitches(nmsData.switches.linknets[i].sysname1,nmsData.switches.linknets[i].sysname2, c1, c2);
- }
+function drawLinknet(i) {
+ var c1 =
+ nms.linknet_color[i] && nms.linknet_color[i].c1
+ ? nms.linknet_color[i].c1
+ : blue;
+ var c2 =
+ nms.linknet_color[i] && nms.linknet_color[i].c2
+ ? nms.linknet_color[i].c2
+ : blue;
+ if (
+ nmsData.switches.switches[nmsData.switches.linknets[i].sysname1] &&
+ nmsData.switches.switches[nmsData.switches.linknets[i].sysname2]
+ ) {
+ connectSwitches(
+ nmsData.switches.linknets[i].sysname1,
+ nmsData.switches.linknets[i].sysname2,
+ c1,
+ c2
+ );
+ }
}
/*
* Draw all linknets
*/
-function drawLinknets()
-{
- if (nmsData.switches && nmsData.switches.linknets) {
- for (var i in nmsData.switches.linknets) {
- drawLinknet(i);
- }
- }
+function drawLinknets() {
+ if (nmsData.switches && nmsData.switches.linknets) {
+ for (var i in nmsData.switches.linknets) {
+ drawLinknet(i);
+ }
+ }
}
/*
@@ -660,17 +705,15 @@ function drawLinknets()
*
* XXX: Probably have to change this to better match the backend data
*/
-function setLinknetColors(i,c1,c2)
-{
- if (!nms.linknet_color[i] ||
- nms.linknet_color[i].c1 != c1 ||
- nms.linknet_color[i].c2 != c2) {
- if (!nms.linknet_color[i])
- nms.linknet_color[i] = {};
- nms.linknet_color[i]['c1'] = c1;
- nms.linknet_color[i]['c2'] = c2;
- drawLinknet(i);
- }
+function setLinknetColors(i, c1, c2) {
+ if (
+ !nms.linknet_color[i] ||
+ nms.linknet_color[i].c1 != c1 ||
+ nms.linknet_color[i].c2 != c2
+ ) {
+ if (!nms.linknet_color[i]) nms.linknet_color[i] = {};
+ nms.linknet_color[i]["c1"] = c1;
+ nms.linknet_color[i]["c2"] = c2;
+ drawLinknet(i);
+ }
}
-
-
diff --git a/web/js/nms-nightmode.js b/web/js/nms-nightmode.js
index 0246e88..511cdd8 100644
--- a/web/js/nms-nightmode.js
+++ b/web/js/nms-nightmode.js
@@ -1,23 +1,23 @@
"use strict";
-var nmsNightMode = nmsNightMode || {
-
-}
+var nmsNightMode = nmsNightMode || {};
var prefersColorSchemeMediaQuery = "(prefers-color-scheme: dark)";
-nmsNightMode.toggle = function() {
- if (nms.nightMode) {
- console.log("nightmode already set, not following system (remove cookies & url param to re-enable system following)");
- return
- }
+nmsNightMode.toggle = function () {
+ if (nms.nightMode) {
+ console.log(
+ "nightmode already set, not following system (remove cookies & url param to re-enable system following)"
+ );
+ return;
+ }
- var active = window.matchMedia(prefersColorSchemeMediaQuery).matches;
- nms.nightMode = active;
-}
+ var active = window.matchMedia(prefersColorSchemeMediaQuery).matches;
+ nms.nightMode = active;
+};
-nmsNightMode.init = function() {
- var preferColorScheme = window.matchMedia(prefersColorSchemeMediaQuery);
- preferColorScheme.addListener(() => nmsNightMode.toggle());
- nmsNightMode.toggle(); // trigger initial
-}
+nmsNightMode.init = function () {
+ var preferColorScheme = window.matchMedia(prefersColorSchemeMediaQuery);
+ preferColorScheme.addListener(() => nmsNightMode.toggle());
+ nmsNightMode.toggle(); // trigger initial
+};
diff --git a/web/js/nms-oplog.js b/web/js/nms-oplog.js
index 33b2c00..7fc10c3 100644
--- a/web/js/nms-oplog.js
+++ b/web/js/nms-oplog.js
@@ -1,281 +1,292 @@
"use strict";
-/*
+/*
* Please note: I've started moving this to a new and better way of doing
* things and it is by no means a finished move. This means that this file is a
* mess of two different styles at the time of this writing. Fix incomming.
*/
var nmsOplog = nmsOplog || {
- table: {}
-}
-nmsOplog.init = function() {
- nms.oplog = new nmsOplog2()
-}
-nmsOplog.getSwitchLogs = function(sw) {
- var logs = [];
- if (nmsData.oplog == undefined || nmsData['oplog']['oplog'] == undefined)
- return [];
- for (var v in nmsData['oplog']['oplog']) {
- var log = nmsData['oplog']['oplog'][v];
- if (log['systems'] != "" && log['systems'] != undefined) {
- if (nmsSearch.searchTest(log['systems'],sw)) {
- logs.push(log);
- }
- }
- }
- return logs;
-}
+ table: {},
+};
+nmsOplog.init = function () {
+ nms.oplog = new nmsOplog2();
+};
+nmsOplog.getSwitchLogs = function (sw) {
+ var logs = [];
+ if (nmsData.oplog == undefined || nmsData["oplog"]["oplog"] == undefined)
+ return [];
+ for (var v in nmsData["oplog"]["oplog"]) {
+ var log = nmsData["oplog"]["oplog"][v];
+ if (log["systems"] != "" && log["systems"] != undefined) {
+ if (nmsSearch.searchTest(log["systems"], sw)) {
+ logs.push(log);
+ }
+ }
+ }
+ return logs;
+};
// New-style-work-in-progress follows
class nmsOplog2 {
- constructor() {
- this.logger = new nmsOplogInput()
- this.logger.attach("navbar")
- this.logger.show()
- this.mini = new nmsLogTable()
- this.full = new nmsLogTable("full", "large",0,0);
- this.mini.attach("oplog-parent-mini")
- this.full.attach("oplog-parent")
- this.mini.show()
- this.full.show()
- this._username = new nmsBox("p", {html:{className: "navbar-text navbar-right"}});
- if (nms.user) {
- this._username.html.textContent = nms.user
- }
- this._username.attach("navbar");
- this._username.show()
- nmsData.addHandler("oplog", "nmsOplogHandler", this.updateComments,this);
- }
- updateComments(x) {
- if (nms.user && x._username.user != nms.user) {
- x._username.user = nms.user;
- x._username.html.textContent = nms.user
- }
- x.mini.update()
- x.full.update()
- }
+ constructor() {
+ this._username = new nmsBox("span", {
+ html: { className: "navbar-text me-2" },
+ });
+ if (nms.user) {
+ this._username.html.textContent = nms.user;
+ }
+ this._username.attach("navbar");
+ this._username.show();
+ this.logger = new nmsOplogInput();
+ this.logger.attach("navbar");
+ this.logger.show();
+ this.mini = new nmsLogTable();
+ this.full = new nmsLogTable("full", "large", 0, 0);
+ this.mini.attach("oplog-parent-mini");
+ this.full.attach("oplog-parent");
+ this.mini.show();
+ this.full.show();
+ nmsData.addHandler("oplog", "nmsOplogHandler", this.updateComments, this);
+ }
+ updateComments(x) {
+ if (nms.user && x._username.user != nms.user) {
+ x._username.user = nms.user;
+ x._username.html.textContent = nms.user;
+ }
+ x.mini.update();
+ x.full.update();
+ }
}
+
class nmsOplogInput extends nmsBox {
- constructor() {
- super("div",{html:{className:"navbar-form form-inline navbar-right gondul-is-private"}})
- this._systems = new nmsBox("input", {html:{className:"form-control",type:"text",size:"8",placeholder:"System(s)"}});
- this._systems.searchbox = document.getElementById("searchbox")
- this._systems.html.oninput = function(e) {
- this.nmsBox.searchbox.value = this.value;
- this.nmsBox.searchbox.oninput();
- }
- this.add(this._systems)
- this._entry = new nmsBox("input", {html:{className:"form-control",type:"text",size:"30",placeholder:"Log entry"}});
- this.add(this._entry)
- var button = new nmsBox("button",{html:{className:"btn btn-default",type:"button"}});
- button.html.textContent = "Log";
- button.container = this;
- button.html.onclick = function(element) {
- this.nmsBox.container.commit(element)
- }
- this.add(button);
- }
- /* Should be moved to nms.user probably */
- get user() {
- if (nms.user) {
- return nms.user;
- }
- var user = prompt("Who are you? Short nick for the record.");
- if (user == null || user == undefined || user == "") {
- console.log("empty prompt");
- alert("No cake for you.");
- return false;
- }
- nms.user = user;
- saveSettings();
- return nms.user;
- }
- _empty(input) {
- if (input == undefined || input == null || input == "") {
- return "";
- }
- return input;
- }
- get entry() {
- return this._empty(this._entry.html.value)
- }
- get systems() {
- return this._empty(this._systems.html.value)
- }
- commit(element) {
- if (!this.user) {
- console.log("need a user...")
- return false;
- }
- if (this.entry == "") {
- return false;
- }
- var myData = {"user": this.user, "systems": this.systems, "log": this.entry};
- myData = JSON.stringify(myData);
- $.ajax({
- type: "POST",
- url: "/api/write/oplog",
- dataType: "text",
- data:myData,
- success: function (data, textStatus, jqXHR) {
- nmsData.invalidate("oplog");
- }
- });
- this.blank()
- }
- blank() {
- this._entry.html.value = "";
- this._systems.html.value = "";
- this._systems.searchbox.value = "";
- this._systems.searchbox.oninput()
- }
+ constructor() {
+ super("div", {
+ html: {
+ className: "input-group input-group-sm w-25 me-4 gondul-is-private",
+ },
+ });
+ this._systems = new nmsBox("input", {
+ html: {
+ className: "form-control",
+ type: "text",
+ placeholder: "System(s)",
+ },
+ });
+ this._systems.searchbox = document.getElementById("searchbox");
+ this._systems.html.oninput = function (e) {
+ this.nmsBox.searchbox.value = this.value;
+ this.nmsBox.searchbox.oninput();
+ };
+ this.add(this._systems);
+ this._entry = new nmsBox("input", {
+ html: {
+ className: "form-control",
+ type: "text",
+ placeholder: "Log entry",
+ },
+ });
+ this.add(this._entry);
+ var button = new nmsBox("button", {
+ html: { className: "btn btn-outline-secondary", type: "button" },
+ });
+ button.html.textContent = "Log";
+ button.container = this;
+ button.html.onclick = function (element) {
+ this.nmsBox.container.commit(element);
+ };
+ this.add(button);
+ }
+ /* Should be moved to nms.user probably */
+ get user() {
+ if (nms.user) {
+ return nms.user;
+ }
+ var user = prompt("Who are you? Short nick for the record.");
+ if (user == null || user == undefined || user == "") {
+ console.log("empty prompt");
+ alert("No cake for you.");
+ return false;
+ }
+ nms.user = user;
+ saveSettings();
+ return nms.user;
+ }
+ _empty(input) {
+ if (input == undefined || input == null || input == "") {
+ return "";
+ }
+ return input;
+ }
+ get entry() {
+ return this._empty(this._entry.html.value);
+ }
+ get systems() {
+ return this._empty(this._systems.html.value);
+ }
+ commit(element) {
+ if (!this.user) {
+ console.log("need a user...");
+ return false;
+ }
+ if (this.entry == "") {
+ return false;
+ }
+ var myData = { username: this.user, systems: this.systems, message: this.entry };
+ postData("/api/v2/oplog/", myData);
+ nmsData.invalidate("oplog");
+ // $.ajax({
+ // type: "POST",
+ // url: "/api/v2/oplog",
+ // dataType: "text",
+ // data: myData,
+ // success: function (data, textStatus, jqXHR) {
+ // nmsData.invalidate("oplog");
+ // },
+ // });
+ this.blank();
+ }
+ blank() {
+ this._entry.html.value = "";
+ this._systems.html.value = "";
+ this._systems.searchbox.value = "";
+ this._systems.searchbox.oninput();
+ }
}
-
/*
* This can be re-written now that it uses nmsBox... That rewrite was just a short
* test of nmsBox...
*/
class nmsLogTable extends nmsTable {
- constructor(mode = "small", timestyle = "small", cutoff = 100, limit = 10) {
- super([]);
- this.mode = mode;
- this.timestyle = timestyle;
- this.cutoff = cutoff;
- this.limit = limit;
- this.entries = {}
- this.first = true;
- }
- /* This is a horrible implementation. BUT THAT'S WHAT YOU GET
- */
- syncToTable() {
- var i = 1;
- var pastCut = false;
- var indexes = [];
- for (var idx in this.entries) {
- indexes.push(parseInt(idx))
- }
- // Testint to see what browsers I can break with exciting new
- // syntax
- indexes.sort((x,y) => y-x)
- for (var idx in indexes) {
- var entry = this.entries[indexes[idx]];
- if (!pastCut) {
- if (entry == undefined) {
- console.log("wtf, empty?")
- console.log(entry)
- } else {
- entry.build(this.cutoff,this.timestyle)
- if(!this.includes(entry)) {
- // FIXME: This is dumb. It assumes we only get one update.
- if (this.first) {
- this.add(entry)
- } else {
- this.insert(entry)
- }
- }
- }
- } else {
- if(this.includes(entry)) {
- this.remove(entry)
- }
- }
- if(this.limit > 0 && ++i > this.limit) {
- pastCut = true;
- }
- }
- this.first=false;
- }
- update() {
- var candidates = nmsData['oplog']['oplog'];
- for (var i in candidates) {
- var candidate = candidates[i];
- if (this.entries[candidate.id] != undefined) {
- continue;
- } else {
- this.entries[candidate.id] = new nmsOplogEntry(candidate);
- }
- }
- this.syncToTable();
- }
+ constructor(mode = "small", timestyle = "small", cutoff = 100, limit = 10) {
+ super([]);
+ this.mode = mode;
+ this.timestyle = timestyle;
+ this.cutoff = cutoff;
+ this.limit = limit;
+ this.entries = {};
+ this.first = true;
+ }
+ /* This is a horrible implementation. BUT THAT'S WHAT YOU GET
+ */
+ syncToTable() {
+ var i = 1;
+ var pastCut = false;
+ var indexes = [];
+ for (var idx in this.entries) {
+ indexes.push(parseInt(idx));
+ }
+ // Testint to see what browsers I can break with exciting new
+ // syntax
+ indexes.sort((x, y) => y - x);
+ for (var idx in indexes) {
+ var entry = this.entries[indexes[idx]];
+ if (!pastCut) {
+ if (entry == undefined) {
+ console.log("wtf, empty?");
+ console.log(entry);
+ } else {
+ entry.build(this.cutoff, this.timestyle);
+ if (!this.includes(entry)) {
+ // FIXME: This is dumb. It assumes we only get one update.
+ if (this.first) {
+ this.add(entry);
+ } else {
+ this.insert(entry);
+ }
+ }
+ }
+ } else {
+ if (this.includes(entry)) {
+ this.remove(entry);
+ }
+ }
+ if (this.limit > 0 && ++i > this.limit) {
+ pastCut = true;
+ }
+ }
+ this.first = false;
+ }
+ update() {
+ var candidates = nmsData["oplog"]["oplog"];
+ for (var i in candidates) {
+ var candidate = candidates[i];
+ if (this.entries[candidate.id] != undefined) {
+ continue;
+ } else {
+ this.entries[candidate.id] = new nmsOplogEntry(candidate);
+ }
+ }
+ this.syncToTable();
+ }
}
-class nmsOplogEntry extends nmsBox {
- build(cutoff,timestyle) {
- if (this.built) {
- return true;
- }
- var td1 = new nmsBox("td")
- var td2 = new nmsBox("td")
- if(timestyle == "small") {
- td1.add(new nmsString(this.shortTime()))
- } else {
- td1.add(new nmsString(this.longTime()))
- }
- var col2 = new nmsString(this.systems + " [" + this.username + "] " + this.getData(cutoff));
- if (this.title != null) {
- col2.html.title = this.title;
- }
- col2.searchbox = document.getElementById("searchbox")
- col2.entry = this;
- if (this.systems != undefined && this.systems != null && this.systems != "") {
- col2.html.onclick = function(e) {
- this.nmsBox.searchbox.value = this.nmsBox.entry.systems;
- this.nmsBox.searchbox.oninput()
- this.nmsBox.clicked = true;
- setTimeout(function(e){e.clicked = false;},3000,this.nmsBox)
- }
- col2.html.onmouseover = function(e) {
- this.nmsBox.over = true;
- if (this.nmsBox.timer) {
- clearTimeout(this.nmsBox.timer)
- }
- this.nmsBox.searchbox.value = this.nmsBox.entry.systems;
- this.nmsBox.searchbox.hoverSource = this.nmsBox;
- this.nmsBox.searchbox.oninput()
- }
- col2.html.onmouseleave = function(e) {
- this.nmsBox.over = false;
- if (this.nmsBox.clicked) { return; }
- if (this.nmsBox.timer) {
- clearTimeout(this.nmsBox.timer)
- }
- this.nmsBox.timer = setTimeout(function(e){
- if (e.over == false && e.entry.systems == e.searchbox.value && e.searchbox.hoverSource == e) {
- e.searchbox.value = "";
- e.searchbox.oninput()
- }
- },2000,this.nmsBox)
- }
- }
- this.add(td1)
- td2.add(col2)
- this.add(td2)
- this.built = true;
- }
+class nmsOplogEntry extends nmsBox {
+ build(cutoff, timestyle) {
+ if (this.built) {
+ return true;
+ }
+ var td1 = new nmsBox("td");
+ var td2 = new nmsBox("td");
+ if (timestyle == "small") {
+ td1.add(new nmsString(this.shortTime()));
+ } else {
+ td1.add(new nmsString(this.longTime()));
+ }
+ var col2 = new nmsString(
+ this.systems + " [" + this.username + "] " + this.getData(cutoff)
+ );
+ if (this.title != null) {
+ col2.html.title = this.title;
+ }
+ col2.searchbox = document.getElementById("searchbox");
+ col2.entry = this;
+ if (
+ this.systems != undefined &&
+ this.systems != null &&
+ this.systems != ""
+ ) {
+ col2.html.onclick = function (e) {
+ this.nmsBox.searchbox.value = this.nmsBox.entry.systems;
+ this.nmsBox.searchbox.oninput();
+ this.nmsBox.clicked = true;
+ setTimeout(
+ function (e) {
+ e.clicked = false;
+ },
+ 3000,
+ this.nmsBox
+ );
+ };
+ }
+ this.add(td1);
+ td2.add(col2);
+ this.add(td2);
+ this.built = true;
+ }
- constructor(entry) {
- super("tr")
- this.td1 = null;
- this.td2 = null;
- this.time = new Date(entry.timestamp.replace(" ","T"))
- this.id = entry.id;
- this.data = entry.log;
- this.title = null;
- this.systems = entry.systems;
- this.username = entry.username;
- }
- longTime() {
- return this.time.toISOString();
- }
- shortTime() {
- return this.time.toTimeString().replace(/:\d\d .*$/,"");
- }
- getData(cutoff = 0) {
- if (cutoff && this.data.length > cutoff) {
- this.title = this.data;
- return this.data.slice(0,cutoff) + "(...)";
- }
- return this.data;
- }
+ constructor(entry) {
+ super("tr");
+ this.td1 = null;
+ this.td2 = null;
+ this.time = new Date(entry.time * 1000);
+ this.id = entry.id;
+ this.data = entry.message;
+ this.title = null;
+ this.systems = entry.systems;
+ this.username = entry.username;
+ }
+ longTime() {
+ return this.time.toISOString();
+ }
+ shortTime() {
+ return this.time.toTimeString().replace(/:\d\d .*$/, "");
+ }
+ getData(cutoff = 0) {
+ if (cutoff && this.data.length > cutoff) {
+ this.title = this.data;
+ return this.data.slice(0, cutoff) + "(...)";
+ }
+ return this.data;
+ }
}
diff --git a/web/js/nms-search.js b/web/js/nms-search.js
index 0726bb4..5f141bf 100644
--- a/web/js/nms-search.js
+++ b/web/js/nms-search.js
@@ -1,19 +1,20 @@
"use strict";
var nmsSearch = nmsSearch || {
- _handler: false,
- _lastId: false
+ _handler: false,
+ _lastId: false,
};
-nmsSearch.helpText = [
- "The search box can be used to identify switches in several ways. The simplest is by name.",
- "Searching by name can be done by just entering text, or if you want to match \"foobar1\" but not \"foobar15\" you can enclose the name in quotation marks. E.g.: foobar1 matches foobar1 and foobar1123123123, while \"foobar1\" only matches exactly foobar1.",
- "All text-oriented searches are regular expressions. ^row\\d-2$ matches row1-2, row2-2, etc, but not row13-2 or rowx-2.",
- "If you are using the non-public version of Gondul, you can also perform smart searches.",
- "Distro search: Type the name of a distro-switch and all access switches registered to that distro switch will also be hilighted.",
- 'Active ports: Type "active>x", "active<x" or "active=x" to identify switch with "x" amount of active gigabit ethernet (ge) ports. E.g.: "active>30".',
- 'IP search: Start typing an IP and any switch with that IP registered either as management IP or part of its subnet will be identified',
- 'SNMP search: Type anything found in the "sysDescr" SNMP OID to hilight a switch matching that. Practical examples include version numbers for firmware (e.g.: "JUNOS 12." vs "JUNOS 14.").'];
+nmsSearch.helpText = [
+ "The search box can be used to identify switches in several ways. The simplest is by name.",
+ 'Searching by name can be done by just entering text, or if you want to match "foobar1" but not "foobar15" you can enclose the name in quotation marks. E.g.: foobar1 matches foobar1 and foobar1123123123, while "foobar1" only matches exactly foobar1.',
+ "All text-oriented searches are regular expressions. ^row\\d-2$ matches row1-2, row2-2, etc, but not row13-2 or rowx-2.",
+ "If you are using the non-public version of Gondul, you can also perform smart searches.",
+ "Distro search: Type the name of a distro-switch and all access switches registered to that distro switch will also be hilighted.",
+ 'Active ports: Type "active>x", "active<x" or "active=x" to identify switch with "x" amount of active gigabit ethernet (ge) ports. E.g.: "active>30".',
+ "IP search: Start typing an IP and any switch with that IP registered either as management IP or part of its subnet will be identified",
+ 'SNMP search: Type anything found in the "sysDescr" SNMP OID to hilight a switch matching that. Practical examples include version numbers for firmware (e.g.: "JUNOS 12." vs "JUNOS 14.").',
+];
nmsSearch.matches = [];
@@ -22,195 +23,201 @@ nmsSearch.matches = [];
*
* Return true if it does.
*/
-nmsSearch.searchTest = function(id, sw) {
- try {
- var re = new RegExp(id,"i");
- if(re.test(sw)) {
- return true;
- }
- if (id[0] == "\"") {
- if (("\"" + sw.toLowerCase() + "\"") == id.toLowerCase()) {
- return true;
- } else {
- return false;
- }
- }
- try {
- if (re.test(nmsData.switches.switches[sw].distro_name)) {
- return true;
- }
- } catch (e) {}
- try {
- if (id.match("active")) {
- var limit = id;
- limit = limit.replace("active>","");
- limit = limit.replace("active<","");
- limit = limit.replace("active=","");
- var operator = id.replace("active","")[0];
- if (limit == parseInt(limit)) {
- var ports = parseInt(nmsData.switchstate.switches[sw].totals.live);
- limit = parseInt(limit);
- if (operator == ">" ) {
- if (ports > limit) {
- return true;
- }
- } else if (operator == "<") {
- if (ports < limit) {
- return true;
- }
- } else if (operator == "=") {
- if (ports == limit) {
- return true;
- }
- }
- }
- }
- } catch (e) {}
- try {
- if (re.test(nmsData.smanagement.switches[sw].mgmt_v4_addr)) {
- return true;
- }
- if (re.test(nmsData.smanagement.switches[sw].mgmt_v6_addr)) {
- return true;
- }
- } catch (e) {}
- try {
- if (re.test(nmsData.smanagement.switches[sw].subnet4)) {
- return true;
- }
- if (re.test(nmsData.smanagement.switches[sw].subnet6)) {
- return true;
- }
- } catch (e) {}
- try {
- for (var x in nmsData.switches.switches[sw]['tags']) {
- if(re.test(nmsData.switches.switches[sw]['tags'][x])){
- return true;
- }
- }
- } catch (e) {}
- try {
- for (var x in nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum) {
- if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == null) {
- continue;
- }
- if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == undefined) {
- continue;
- }
- if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == "") {
- continue;
- }
- if (re.test("serial:" + nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x])) {
- return true;
- }
- }
- } catch (e) {}
- try {
- for (var x in nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo) {
- if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == null) {
- continue;
- }
- if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == undefined) {
- continue;
- }
- if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == "") {
- continue;
- }
- if (re.test(nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x])) {
- return true;
- }
- }
- } catch (e) {}
- if (re.test(nmsData.snmp.snmp[sw].misc.sysDescr[0])) {
- return true;
- }
- } catch (e) {
- return false;
- }
- return false;
+nmsSearch.searchTest = function (id, sw) {
+ try {
+ var re = new RegExp(id, "i");
+ if (re.test(sw)) {
+ return true;
+ }
+ if (id[0] == '"') {
+ if ('"' + sw.toLowerCase() + '"' == id.toLowerCase()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ try {
+ if (re.test(nmsData.switches.switches[sw].distro_name)) {
+ return true;
+ }
+ } catch (e) {}
+ try {
+ if (id.match("active")) {
+ var limit = id;
+ limit = limit.replace("active>", "");
+ limit = limit.replace("active<", "");
+ limit = limit.replace("active=", "");
+ var operator = id.replace("active", "")[0];
+ if (limit == parseInt(limit)) {
+ var ports = parseInt(nmsData.switchstate.switches[sw].totals.live);
+ limit = parseInt(limit);
+ if (operator == ">") {
+ if (ports > limit) {
+ return true;
+ }
+ } else if (operator == "<") {
+ if (ports < limit) {
+ return true;
+ }
+ } else if (operator == "=") {
+ if (ports == limit) {
+ return true;
+ }
+ }
+ }
+ }
+ } catch (e) {}
+ try {
+ if (re.test(nmsData.smanagement.switches[sw].mgmt_v4_addr)) {
+ return true;
+ }
+ if (re.test(nmsData.smanagement.switches[sw].mgmt_v6_addr)) {
+ return true;
+ }
+ } catch (e) {}
+ try {
+ if (re.test(nmsData.smanagement.switches[sw].subnet4)) {
+ return true;
+ }
+ if (re.test(nmsData.smanagement.switches[sw].subnet6)) {
+ return true;
+ }
+ } catch (e) {}
+ try {
+ for (var x in nmsData.switches.switches[sw]["tags"]) {
+ if (re.test(nmsData.switches.switches[sw]["tags"][x])) {
+ return true;
+ }
+ }
+ } catch (e) {}
+ try {
+ for (var x in nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum) {
+ if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == null) {
+ continue;
+ }
+ if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == undefined) {
+ continue;
+ }
+ if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == "") {
+ continue;
+ }
+ if (
+ re.test(
+ "serial:" + nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x]
+ )
+ ) {
+ return true;
+ }
+ }
+ } catch (e) {}
+ try {
+ for (var x in nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo) {
+ if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == null) {
+ continue;
+ }
+ if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == undefined) {
+ continue;
+ }
+ if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == "") {
+ continue;
+ }
+ if (re.test(nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x])) {
+ return true;
+ }
+ }
+ } catch (e) {}
+ if (re.test(nmsData.snmp.snmp[sw].misc.sysDescr[0])) {
+ return true;
+ }
+ } catch (e) {
+ return false;
+ }
+ return false;
};
-nmsSearch.reset = function() {
- document.getElementById("searchbox").dataset.match = '';
- document.getElementById("searchbox").value = '';
- nmsSearch.search();
-}
-
-nmsSearch._enableTimer = function() {
- if (nmsSearch._handler == false) {
- nmsSearch._handler = setInterval(nmsSearch.search,1000);
- }
-}
+nmsSearch.reset = function () {
+ document.getElementById("searchbox").dataset.match = "";
+ document.getElementById("searchbox").value = "";
+ nmsSearch.search();
+};
-nmsSearch._disableTimer = function() {
- if (nmsSearch._handler != false) {
- clearInterval(nmsSearch.search);
- }
-}
+nmsSearch._enableTimer = function () {
+ if (nmsSearch._handler == false) {
+ nmsSearch._handler = setInterval(nmsSearch.search, 1000);
+ }
+};
-nmsSearch.search = function() {
- var el = document.getElementById("searchbox");
- var id = false;
- nmsSearch.matches = [];
- if (el) {
- id = el.value.toLowerCase();
- }
- if(id) {
- nmsMap.enableHighlights();
- for(var sw in nmsData.switches.switches) {
- if (nmsSearch.searchTest(id,sw)) {
- nmsSearch.matches.push(sw);
- nmsMap.setSwitchHighlight(sw,true);
- } else {
- nmsMap.setSwitchHighlight(sw,false);
- }
- }
- nmsSearch._enableTimer();
- } else {
- nmsSearch._disableTimer();
- nmsMap.disableHighlights();
- }
- if(nmsSearch.matches.length == 0) {
- document.getElementById("searchbox-submit").classList.remove("btn-success");
- document.getElementById("searchbox-submit").classList.remove("btn-primary");
- }
- else if(nmsSearch.matches.length == 1) {
- document.getElementById("searchbox-submit").classList.add("btn-success");
- document.getElementById("searchbox-submit").classList.remove("btn-primary");
- }
- else {
- document.getElementById("searchbox-submit").classList.add("btn-primary");
- document.getElementById("searchbox-submit").classList.remove("btn-success");
- }
+nmsSearch._disableTimer = function () {
+ if (nmsSearch._handler != false) {
+ clearInterval(nmsSearch.search);
+ }
+};
+nmsSearch.search = function () {
+ var el = document.getElementById("searchbox");
+ var id = false;
+ nmsSearch.matches = [];
+ if (el) {
+ id = el.value.toLowerCase();
+ }
+ if (id) {
+ nmsMap.enableHighlights();
+ for (var sw in nmsData.switches.switches) {
+ if (nmsSearch.searchTest(id, sw)) {
+ nmsSearch.matches.push(sw);
+ nmsMap.setSwitchHighlight(sw, true);
+ } else {
+ nmsMap.setSwitchHighlight(sw, false);
+ }
+ }
+ nmsSearch._enableTimer();
+ } else {
+ nmsSearch._disableTimer();
+ nmsMap.disableHighlights();
+ }
+ if (nmsSearch.matches.length == 0) {
+ document.getElementById("searchbox-submit").classList.remove("btn-primary");
+ document.getElementById("searchbox-submit").classList.remove("btn-success");
+ document.getElementById("searchbox-submit").classList.add("btn-secondary");
+ } else if (nmsSearch.matches.length == 1) {
+ document.getElementById("searchbox-submit").classList.add("btn-success");
+ document.getElementById("searchbox-submit").classList.remove("btn-primary");
+ document
+ .getElementById("searchbox-submit")
+ .classList.remove("btn-secondary");
+ } else {
+ document.getElementById("searchbox-submit").classList.add("btn-primary");
+ document.getElementById("searchbox-submit").classList.remove("btn-success");
+ document
+ .getElementById("searchbox-submit")
+ .classList.remove("btn-secondary");
+ }
};
-nmsSearch.runSearch = function() {
- if(nmsSearch.matches.length == 1) {
- nmsInfoBox.showWindow("switchInfo",nmsSearch.matches[0]);
- }
- else if(nmsSearch.matches.length > 1) {
- nmsInfoBox.showWindow('searchResults',nmsSearch.matches.length);
- }
- else {
- document.getElementById("searchbox-submit").classList.remove("btn-primary");
- document.getElementById("searchbox").dataset.match = '';
- }
+nmsSearch.runSearch = function () {
+ if (nmsSearch.matches.length == 1) {
+ nmsInfoBox.showWindow("switchInfo", nmsSearch.matches[0]);
+ } else if (nmsSearch.matches.length > 1) {
+ nmsInfoBox.showWindow("searchResults", nmsSearch.matches.length);
+ } else {
+ document.getElementById("searchbox-submit").classList.remove("btn-primary");
+ document.getElementById("searchbox").dataset.match = "";
+ }
};
-nmsSearch._searchKeyListener = function(e) {
- switch (e.keyCode) {
- case 13:
- nmsSearch.runSearch();
- break;
- case 27:
- nmsSearch.reset();
- break;
- }
-}
+nmsSearch._searchKeyListener = function (e) {
+ switch (e.keyCode) {
+ case 13:
+ nmsSearch.runSearch();
+ break;
+ case 27:
+ nmsSearch.reset();
+ break;
+ }
+};
-nmsSearch.init = function() {
- $("#searchbox").keyup(function(e) {
- nmsSearch._searchKeyListener(e);
- });
-}
+nmsSearch.init = function () {
+ // $("#searchbox").keyup(function(e) {
+ // nmsSearch._searchKeyListener(e);
+ // });
+};
diff --git a/web/js/nms-template.js b/web/js/nms-template.js
index 0f25367..1d2c0e5 100644
--- a/web/js/nms-template.js
+++ b/web/js/nms-template.js
@@ -1,55 +1,60 @@
"use strict";
-var nmsTemplate = nmsTemplate || {
-}
+var nmsTemplate = nmsTemplate || {};
-nmsTemplate.test = function() {
- var input = document.getElementById("template-input");
- var output = document.getElementById("template-output");
- var qp = document.getElementById("template-query-params");
- $.ajax({
- type: "POST",
- url: "/api/templates/test" + qp.value,
- async: false,
- data: input.value,
- dataType: "text",
- success: function (indata, textStatus, jqXHR) {
- var output = document.getElementById("template-output");
- output.value = jqXHR.responseText;
- },
- error: function (jqXHR, textStatus) {
- var output = document.getElementById("template-output");
- output.value = jqXHR.responseText;
- }
- });
-}
+nmsTemplate.test = function () {
+ var input = document.getElementById("template-input");
+ var output = document.getElementById("template-output");
+ var qp = document.getElementById("template-query-params");
+ $.ajax({
+ type: "POST",
+ url: "/api/templates/test" + qp.value,
+ async: false,
+ data: input.value,
+ dataType: "text",
+ success: function (indata, textStatus, jqXHR) {
+ var output = document.getElementById("template-output");
+ output.value = jqXHR.responseText;
+ },
+ error: function (jqXHR, textStatus) {
+ var output = document.getElementById("template-output");
+ output.value = jqXHR.responseText;
+ },
+ });
+};
-nmsTemplate.fromFile = function(template) {
- if(template == '') { return; }
- $.ajax({
- type: "GET",
- url: "/templates/" + template,
- async: false,
- dataType: "text",
- success: function (indata, textStatus, jqXHR) {
- var output = document.getElementById("template-input");
- output.value = indata;
- }
- });
- nmsTemplate.test();
-}
+nmsTemplate.fromFile = function (template) {
+ if (template == "") {
+ return;
+ }
+ $.ajax({
+ type: "GET",
+ url: "/templates/" + template,
+ async: false,
+ dataType: "text",
+ success: function (indata, textStatus, jqXHR) {
+ var output = document.getElementById("template-input");
+ output.value = indata;
+ },
+ });
+ nmsTemplate.test();
+};
-nmsTemplate.getTemplates = function() {
- $.ajax({
- type: "GET",
- url: "/api/read/template-list",
- async: false,
- dataType: "json",
- success: function (indata, textStatus, jqXHR) {
- $.each( indata['templates'], function( value ) {
- $('#nmsTemplate-select').append($("<option></option>").attr("value",indata['templates'][value]['file']).text(indata['templates'][value]['file']));
- });
- }
- });
-}
+nmsTemplate.getTemplates = function () {
+ $.ajax({
+ type: "GET",
+ url: "/api/read/template-list",
+ async: false,
+ dataType: "json",
+ success: function (indata, textStatus, jqXHR) {
+ $.each(indata["templates"], function (value) {
+ $("#nmsTemplate-select").append(
+ $("<option></option>")
+ .attr("value", indata["templates"][value]["file"])
+ .text(indata["templates"][value]["file"])
+ );
+ });
+ },
+ });
+};
//nmsTemplate.getTemplates();
diff --git a/web/js/nms-time.js b/web/js/nms-time.js
index d5b6379..6962fef 100644
--- a/web/js/nms-time.js
+++ b/web/js/nms-time.js
@@ -9,73 +9,80 @@
* The interface is a bit bloated at the moment, though.
*/
var nmsTime = nmsTime || {
- _now: undefined,
- _handle: undefined,
- _stopTime: undefined
-}
+ _now: undefined,
+ _handle: undefined,
+ _stopTime: undefined,
+};
-nmsTime.replayEvent = function() {
- var eStart = setTree(nmsData,["config","config","data","start"],"2018-03-23T00:00:00+0200");
- nmsTime._stopTime = new Date(setTree(nmsData,["config","config","data","end"],"2018-04-01T14:30:00+0200"));
- nmsTime.setNow(eStart);
- nmsTime.startPlayback(60);
-}
+nmsTime.replayEvent = function () {
+ var eStart = setTree(
+ nmsData,
+ ["config", "config", "data", "start"],
+ "2018-03-23T00:00:00+0200"
+ );
+ nmsTime._stopTime = new Date(
+ setTree(
+ nmsData,
+ ["config", "config", "data", "end"],
+ "2018-04-01T14:30:00+0200"
+ )
+ );
+ nmsTime.setNow(eStart);
+ nmsTime.startPlayback(60);
+};
-nmsTime.isRealTime = function() {
- if (nmsTime._now == undefined && nmsTime._handle == undefined)
- return true;
- return false;
-}
+nmsTime.isRealTime = function () {
+ if (nmsTime._now == undefined && nmsTime._handle == undefined) return true;
+ return false;
+};
nmsTime.startNowPicker = function () {
- $.datetimepicker.setLocale('no');
- $('#nowPicker').datetimepicker('destroy');
- var now;
- if (nmsTime._now == undefined)
- now = new Date();
- else
- now = nmsTime._now;
- now.setSeconds(0);
- now.setMilliseconds(0);
- var datepicker = $('#nowPicker').datetimepicker({
- value: now,
- step: 1,
- mask:false,
- inline:true,
- todayButton: true,
- validateOnBlur:false,
- dayOfWeekStart:1,
- maxDate:'+1970/01/01',
- onSelectDate: function(ct,$i){
- document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf());
- },
- onSelectTime: function(ct,$i){
- document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf());
- },
- onGenerate: function(ct,$i){
- document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf());
- }
- });
-}
+ $.datetimepicker.setLocale("no");
+ $("#nowPicker").datetimepicker("destroy");
+ var now;
+ if (nmsTime._now == undefined) now = new Date();
+ else now = nmsTime._now;
+ now.setSeconds(0);
+ now.setMilliseconds(0);
+ var datepicker = $("#nowPicker").datetimepicker({
+ value: now,
+ step: 1,
+ mask: false,
+ inline: true,
+ todayButton: true,
+ validateOnBlur: false,
+ dayOfWeekStart: 1,
+ maxDate: "+1970/01/01",
+ onSelectDate: function (ct, $i) {
+ document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf());
+ },
+ onSelectTime: function (ct, $i) {
+ document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf());
+ },
+ onGenerate: function (ct, $i) {
+ document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf());
+ },
+ });
+};
-nmsTime.setNow = function(now) {
- var newDate = new Date(now);
- newDate.setSeconds(0);
- newDate.setMilliseconds(0);
- newDate.setMinutes(newDate.getMinutes() - newDate.getMinutes()%1);
- nmsTime._now = newDate;
- nmsTime._updateData();
-}
+nmsTime.setNow = function (now) {
+ var newDate = new Date(now);
+ newDate.setSeconds(0);
+ newDate.setMilliseconds(0);
+ newDate.setMinutes(newDate.getMinutes() - (newDate.getMinutes() % 1));
+ nmsTime._now = newDate;
+ nmsTime._updateData();
+};
-nmsTime._updateData = function() {
- nmsData.now = nmsTime._now.getTime() / 1000;
-}
+nmsTime._updateData = function () {
+ nmsData.now = nmsTime._now.getTime() / 1000;
+};
-nmsTime.realTime = function() {
- nmsTime.stopPlayback();
- nmsTime._now = undefined;
- nmsData.now = undefined;
-}
+nmsTime.realTime = function () {
+ nmsTime.stopPlayback();
+ nmsTime._now = undefined;
+ nmsData.now = undefined;
+};
/*
* Step a fixed amount of time, measured in minutes.
@@ -84,41 +91,42 @@ nmsTime.realTime = function() {
* backend versions to avoid bloating the cache and thus also stressing the
* database
*/
-nmsTime.step = function(amount) {
- if (nmsTime._now == null)
- throw "Stepping without nmsTime._now";
- if (amount == 0 || amount == undefined)
- throw "Invalid step";
- if (nmsTime._now.getTime() + (amount * 1000 * 60 ) > Date.now()) {
- nmsTime.realTime();
- return;
- }
- if (nmsTime._stopTime != undefined && nmsTime._now.getTime() >= nmsTime._stopTime.getTime()) {
- nmsTime.stopPlayback();
- nmsTime._stopTime = undefined;
- }
- nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount);
- nmsTime._updateData();
-}
+nmsTime.step = function (amount) {
+ if (nmsTime._now == null) throw "Stepping without nmsTime._now";
+ if (amount == 0 || amount == undefined) throw "Invalid step";
+ if (nmsTime._now.getTime() + amount * 1000 * 60 > Date.now()) {
+ nmsTime.realTime();
+ return;
+ }
+ if (
+ nmsTime._stopTime != undefined &&
+ nmsTime._now.getTime() >= nmsTime._stopTime.getTime()
+ ) {
+ nmsTime.stopPlayback();
+ nmsTime._stopTime = undefined;
+ }
+ nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount);
+ nmsTime._updateData();
+};
/*
* Step based on key-press. Same as step() but stops playback if it's
* active and allows you to rewind from a "live" map.
*/
-nmsTime.stepKey = function(amount) {
- nmsTime.stopPlayback();
- if (nmsTime._now == undefined) {
- nmsTime.setNow(Date.now());
- }
- nmsTime.step(amount);
-}
+nmsTime.stepKey = function (amount) {
+ nmsTime.stopPlayback();
+ if (nmsTime._now == undefined) {
+ nmsTime.setNow(Date.now());
+ }
+ nmsTime.step(amount);
+};
/*
* Target of setInterval() when replaying.
*/
-nmsTime._tick = function() {
- nmsTime.step(nmsTime._speed);
-}
+nmsTime._tick = function () {
+ nmsTime.step(nmsTime._speed);
+};
/*
* We now have a time (presumably), start playback.
@@ -127,32 +135,29 @@ nmsTime._tick = function() {
*
* Gondul does not _yet_ support fast forwarding into the future.
*/
-nmsTime.startPlayback = function(speed) {
- if (nmsTime._handle)
- nmsTime.stopPlayback();
- if (nmsTime._now.getTime() > Date.now()) {
- nmsTime.stopPlayback();
- return;
- }
- nmsTime._speed = speed;
- nmsTime._handle = setInterval(nmsTime._tick,2000);
-}
+nmsTime.startPlayback = function (speed) {
+ if (nmsTime._handle) nmsTime.stopPlayback();
+ if (nmsTime._now.getTime() > Date.now()) {
+ nmsTime.stopPlayback();
+ return;
+ }
+ nmsTime._speed = speed;
+ nmsTime._handle = setInterval(nmsTime._tick, 2000);
+};
-nmsTime.togglePause = function() {
- if (nmsTime._handle) {
- nmsTime.stopPlayback();
- } else {
- if (nmsTime.isRealTime()) {
- nmsTime.setNow(Date.now());
- } else {
- nmsTime.startPlayback(nmsTime._speed ? nmsTime._speed : 60);
- }
- }
-}
+nmsTime.togglePause = function () {
+ if (nmsTime._handle) {
+ nmsTime.stopPlayback();
+ } else {
+ if (nmsTime.isRealTime()) {
+ nmsTime.setNow(Date.now());
+ } else {
+ nmsTime.startPlayback(nmsTime._speed ? nmsTime._speed : 60);
+ }
+ }
+};
-nmsTime.stopPlayback = function() {
- if (nmsTime._handle)
- clearInterval(nmsTime._handle);
- nmsTime._handle = undefined;
-}
-
+nmsTime.stopPlayback = function () {
+ if (nmsTime._handle) clearInterval(nmsTime._handle);
+ nmsTime._handle = undefined;
+};
diff --git a/web/js/nms-types.js b/web/js/nms-types.js
index 4e7c24e..ee33f31 100644
--- a/web/js/nms-types.js
+++ b/web/js/nms-types.js
@@ -1,16 +1,16 @@
"use strict";
/*
* Base type. All nmsType* classes represent a logical family of units.
- * This is used to provide input validation on the class-level and
+ * This is used to provide input validation on the class-level and
* is used to store the value and description of variables.
* This is not bound to editing in theory. It is natural to think
* that nms-map-handlers will leverage the same type-system to
* verify that things are as they should.
*
* An example of future features outside the scope of simply editing stuff:
- * verify that a nmsTypeIP is contained in nmsTypeNetwork
+ * verify that a nmsTypeIP is contained in nmsTypeNetwork
* use nmsTypePlace for all placement-logic
- *
+ *
* Stuff that should be supported within an editor:
* - Validation (duh)
* - Hints (auto-complete, parse-error-feedback)
@@ -22,213 +22,234 @@
* nms-info-box
*/
class nmsType {
- constructor(description, priority) {
- this._value = null;
- this.description = description;
- this.validationReason = "";
- this.ro = false;
- if (priority == undefined) {
- priority = this._defaultPriority;
- }
- this.priority = priority
- }
- // Override this to get free validation. Just return true or false.
- validate(input) {
- return true;
- }
- // Always return text-representation
- // Should be matched by fromString()
- toString() {
- if (this._value == null || this._value == undefined) {
- return ""
- } else {
- return this._value.toString();
- }
- }
- // Set value from string-input
- fromString(input) {
- if (this.validate(input)) {
- this._value = input;
- } else {
- throw "Invalid input. Use .validate() before setting stuff please. I am " + this + " and my input is " + input
- }
- }
- initial(v) {
- this.value = v;
- if(this.priority == nmsPriority.newOnly) {
- this.ro = true;
- }
- }
- get value() {
- return this._value;
- }
- set value(input) {
- this._value = input;
- }
- get _defaultPriority() {
- return nmsPriority.optional;
- }
+ constructor(description, priority) {
+ this._value = null;
+ this.description = description;
+ this.validationReason = "";
+ this.ro = false;
+ if (priority == undefined) {
+ priority = this._defaultPriority;
+ }
+ this.priority = priority;
+ }
+ // Override this to get free validation. Just return true or false.
+ validate(input) {
+ return true;
+ }
+ // Always return text-representation
+ // Should be matched by fromString()
+ toString() {
+ if (this._value == null || this._value == undefined) {
+ return "";
+ } else {
+ return this._value.toString();
+ }
+ }
+ // Set value from string-input
+ fromString(input) {
+ if (this.validate(input)) {
+ this._value = input;
+ } else {
+ throw (
+ "Invalid input. Use .validate() before setting stuff please. I am " +
+ this +
+ " and my input is " +
+ input
+ );
+ }
+ }
+ initial(v) {
+ this.value = v;
+ if (this.priority == nmsPriority.newOnly) {
+ this.ro = true;
+ }
+ }
+ get value() {
+ return this._value;
+ }
+ set value(input) {
+ this._value = input;
+ }
+ get _defaultPriority() {
+ return nmsPriority.optional;
+ }
}
-class nmsTypeInterval extends nmsType {
- validate(input) {
- return !!(input.match(/^\d\d:\d\d:\d\d$/))
- }
+class nmsTypeInterval extends nmsType {
+ validate(input) {
+ return !!input.match(/^\d\d:\d\d:\d\d$/);
+ }
}
-class nmsTypeIP extends nmsType {
- get _defaultPriority() {
- return nmsPriority.important;
- }
- _validateV4(input) {
- var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)$/)
- if (!x) {
- this.validationReason = "Doesn't look like IPv4 address or IPv6";
- return false;
- }
- for (var i = 1; i < 5; i ++) {
- if (x[i] < 0 || x[i] > 255) {
- this.validationReason = "The " + i + "'th octet("+x[i]+") is outside of expected range (0-255)"
- return false
- }
- }
- this.validationReason = "OK"
- return true;
- }
- /* It's so easy to check if IPv6 addresses are valid.
- */
- _validateV6(input) {
- if (!!input.match(/^[a-fA-F0-9:]+$/)) {
- this.validationReason = "OK IPv6 address"
- return true;
- } else {
- this.validationReason = "Doesn't parse as a IPv6 address despite :";
- return false;
- }
- }
- validate(input) {
- if (input.match(":")) {
- return this._validateV6(input);
- } else {
- return this._validateV4(input);
- }
- }
+class nmsTypeIP extends nmsType {
+ get _defaultPriority() {
+ return nmsPriority.important;
+ }
+ _validateV4(input) {
+ var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)$/);
+ if (!x) {
+ this.validationReason = "Doesn't look like IPv4 address or IPv6";
+ return false;
+ }
+ for (var i = 1; i < 5; i++) {
+ if (x[i] < 0 || x[i] > 255) {
+ this.validationReason =
+ "The " +
+ i +
+ "'th octet(" +
+ x[i] +
+ ") is outside of expected range (0-255)";
+ return false;
+ }
+ }
+ this.validationReason = "OK";
+ return true;
+ }
+ /* It's so easy to check if IPv6 addresses are valid.
+ */
+ _validateV6(input) {
+ if (!!input.match(/^[a-fA-F0-9:]+$/)) {
+ this.validationReason = "OK IPv6 address";
+ return true;
+ } else {
+ this.validationReason = "Doesn't parse as a IPv6 address despite :";
+ return false;
+ }
+ }
+ validate(input) {
+ if (input.match(":")) {
+ return this._validateV6(input);
+ } else {
+ return this._validateV4(input);
+ }
+ }
}
class nmsTypeCIDR extends nmsType {
- get _defaultPriority() {
- return nmsPriority.important;
- }
- _validateV4(input) {
- var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)\/(\d+)$/)
- if (!x) {
- this.validationReason = "Doesn't look like IPv4 cidr or IPv6";
- return false;
- }
- for (var i = 1; i < 5; i ++) {
- if (x[i] < 0 || x[i] > 255) {
- this.validationReason = "The " + i + "'th octet("+x[i]+") is outside of expected range (0-255)";
- return false;
- }
- }
- if (x[5] < 8 || x[5] > 32) {
- this.validationReason = "/"+x[5]+" is outside of expected range (8-32)";
- return false;
- }
- this.validationReason = "OK";
- return true;
- }
- _validateV6(input) {
- if (!!input.match(/^[a-fA-F0-9:]+\/(\d+)$/)) {
- this.validationReason = "OK IPv6 cidr"
- return true;
- } else {
- this.validationReason = "Doesn't parse as a IPv6 cidr despite :";
- return false;
- }
- }
- validate(input) {
- if (input.match(":")) {
- return this._validateV6(input);
- } else {
- return this._validateV4(input);
- }
- }
+ get _defaultPriority() {
+ return nmsPriority.important;
+ }
+ _validateV4(input) {
+ var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)\/(\d+)$/);
+ if (!x) {
+ this.validationReason = "Doesn't look like IPv4 cidr or IPv6";
+ return false;
+ }
+ for (var i = 1; i < 5; i++) {
+ if (x[i] < 0 || x[i] > 255) {
+ this.validationReason =
+ "The " +
+ i +
+ "'th octet(" +
+ x[i] +
+ ") is outside of expected range (0-255)";
+ return false;
+ }
+ }
+ if (x[5] < 8 || x[5] > 32) {
+ this.validationReason =
+ "/" + x[5] + " is outside of expected range (8-32)";
+ return false;
+ }
+ this.validationReason = "OK";
+ return true;
+ }
+ _validateV6(input) {
+ if (!!input.match(/^[a-fA-F0-9:]+\/(\d+)$/)) {
+ this.validationReason = "OK IPv6 cidr";
+ return true;
+ } else {
+ this.validationReason = "Doesn't parse as a IPv6 cidr despite :";
+ return false;
+ }
+ }
+ validate(input) {
+ if (input.match(":")) {
+ return this._validateV6(input);
+ } else {
+ return this._validateV4(input);
+ }
+ }
}
-class nmsTypeNetwork extends nmsType {
- get _defaultPriority() {
- return nmsPriority.important;
- }
- validate(input) {
- var x =testTree(nmsData,["networks","networks",input])
- if (x) {
- this.validationReason = "OK"
- } else {
- this.validationReason = "No such network: " + input
- }
- return x;
- }
+class nmsTypeNetwork extends nmsType {
+ get _defaultPriority() {
+ return nmsPriority.important;
+ }
+ validate(input) {
+ var x = testTree(nmsData, ["networks", "networks", input]);
+ if (x) {
+ this.validationReason = "OK";
+ } else {
+ this.validationReason = "No such network: " + input;
+ }
+ return x;
+ }
}
class nmsTypeJSON extends nmsType {
- validate(input) {
- try {
- JSON.parse(input);
- this.validationReason = "OK"
- return true;
- } catch(e) {
- this.validationReason = e.message;
- return false;
- }
- }
- toString() {
- return JSON.stringify(this._value);
- }
- fromString(input) {
- try {
- this.value = JSON.parse(input);
- } catch(e) {
- throw "Invalid input. Use .validate() before setting stuff please. I am " + this + " and my input is " + input
- }
- }
+ validate(input) {
+ try {
+ JSON.parse(input);
+ this.validationReason = "OK";
+ return true;
+ } catch (e) {
+ this.validationReason = e.message;
+ return false;
+ }
+ }
+ toString() {
+ return JSON.stringify(this._value);
+ }
+ fromString(input) {
+ try {
+ this.value = JSON.parse(input);
+ } catch (e) {
+ throw (
+ "Invalid input. Use .validate() before setting stuff please. I am " +
+ this +
+ " and my input is " +
+ input
+ );
+ }
+ }
}
-class nmsTypePlace extends nmsTypeJSON { }
-class nmsTypePort extends nmsType { }
+class nmsTypePlace extends nmsTypeJSON {}
+class nmsTypePort extends nmsType {}
class nmsTypeSysname extends nmsType {
- get _defaultPriority() {
- return nmsPriority.newOnly;
- }
- validate(input) {
- if (this.ro) {
- throw "Trying to validate a r/o field"
- }
- var x = testTree(nmsData,["switches","switches",input])
- if (x) {
- this.validationReason = "Switch already exists"
- } else {
- this.validationReason = "OK: " + input
- }
- return !x;
- }
+ get _defaultPriority() {
+ return nmsPriority.newOnly;
+ }
+ validate(input) {
+ if (this.ro) {
+ throw "Trying to validate a r/o field";
+ }
+ var x = testTree(nmsData, ["switches", "switches", input]);
+ if (x) {
+ this.validationReason = "Switch already exists";
+ } else {
+ this.validationReason = "OK: " + input;
+ }
+ return !x;
+ }
}
class nmsTypeSysnameReference extends nmsType {
- get _defaultPriority() {
- return nmsPriority.important;
- }
- validate(input) {
- var x = testTree(nmsData,["switches","switches",input])
- if (x) {
- this.validationReason = "OK"
- } else {
- this.validationReason = "No such switch: " + input
- }
- return x;
- }
+ get _defaultPriority() {
+ return nmsPriority.important;
+ }
+ validate(input) {
+ var x = testTree(nmsData, ["switches", "switches", input]);
+ if (x) {
+ this.validationReason = "OK";
+ } else {
+ this.validationReason = "No such switch: " + input;
+ }
+ return x;
+ }
}
-class nmsTypeTags extends nmsTypeJSON { }
-class nmsTypeSecret extends nmsType { }
+class nmsTypeTags extends nmsTypeJSON {}
+class nmsTypeSecret extends nmsType {}
var nmsPriority = {
- readOnly: 0,
- required: 1,
- important: 2,
- optional: 3,
- newOnly: 4
-}
+ readOnly: 0,
+ required: 1,
+ important: 2,
+ optional: 3,
+ newOnly: 4,
+};
diff --git a/web/js/nms-ui-boxes.js b/web/js/nms-ui-boxes.js
index ee4dc98..6a89fcd 100644
--- a/web/js/nms-ui-boxes.js
+++ b/web/js/nms-ui-boxes.js
@@ -5,10 +5,10 @@
* The idea is to retain the ability to fiddle with html, but solve common
* problems such as "I need to show a box that looks good" and "I need to
* update the content of this field in this box when something happens".
- *
+ *
* Seeing as how it's 2019, I figured I'd try to use this whole "class"
* thing :D
- *
+ *
* Eventually, everything in nms-info-box.js should use this, but more over,
* if a need to write some code that needs a UI element arises, the general
* problem should be solved here, while the implementation: elsewhere.
@@ -20,221 +20,220 @@
*/
class nmsBox {
- constructor(type,settings = null) {
- this.type = type;
- this._boxes = []
- this.html = document.createElement(type);
- this.html.nmsBox = this;
- if (settings) {
- this.applySettings(settings);
- }
- }
- get value() {
- var values = [];
- for (var x in this._boxes) {
- var tmp = this._boxes[x].value;
- if (tmp != undefined && !((tmp instanceof Array) && tmp.length == 0)) {
- values.push(tmp)
- }
- }
- return values;
- }
+ constructor(type, settings = null) {
+ this.type = type;
+ this._boxes = [];
+ this.html = document.createElement(type);
+ this.html.nmsBox = this;
+ if (settings) {
+ this.applySettings(settings);
+ }
+ }
+ get value() {
+ var values = [];
+ for (var x in this._boxes) {
+ var tmp = this._boxes[x].value;
+ if (tmp != undefined && !(tmp instanceof Array && tmp.length == 0)) {
+ values.push(tmp);
+ }
+ }
+ return values;
+ }
- applySettings(settings) {
- /*
- * This really should go deeper, but the problem is that
- * I'm lazy. You can't just use Object.assign() either because
- * stuff like html.style isn't just any element and we want
- * to be able to do html:{style:{display:"none"}} instead
- * of html:{style:new (style object thing with display:none)}
- *
- * So far this works.
- *
- * Note that this breaks forr classList: This is because
- * classList is just an accessor for className, so you
- * should set className instead initially.
- */
- if (settings.html) {
- for (var x in settings.html) {
- if(settings.html[x] instanceof Object) {
- Object.assign(this.html[x],settings.html[x])
- } else {
- this.html[x] = settings.html[x];
- }
- }
- }
- }
- /* Should rename these to push() and unshift(), really, to be
- * more consistent.
- */
- add(box) {
- this._boxes.push(box);
- box.attach(this.html)
- box.show()
- }
- insert(box) {
- this._boxes.unshift(box)
- box.attach(this.html)
- box.show(true,-1)
- }
-
- /* This is provided so as to allow attaching to non-nmsBox-objects.
- * E.g.: attach the root to a HTML element directly.
- * If you just use foo = document.getElement...,
- * foo.appendChild(box.html), then .hide() will work fine,
- * but there's no way to do .show() afterwards.
- *
- * Be aware:
- * - we want to AVOID the child knowing too much about the parent
- * - HTML elements can only ever be part of a single parent
- * element. This means that it is safe to attach(root1), .show(),
- * atach(root2), show() ... The DOM object wil be removed from root1.
- * - Due to the above, we should probably actually adress that, since
- * there are valid reasons for showing the same nmsBox twice (e.g.:
- * showing a list of tons of stuff, and also a "top 5")
- */
- attach(root) {
- if (!(root instanceof HTMLElement)) {
- root = document.getElementById(root)
- }
- console.assert(root instanceof HTMLElement)
- this._root = root;
- }
- show(show = true,where=1) {
- if (!show) {
- this.hide()
- return
- }
- if (this._root instanceof HTMLElement) {
- if (where>0) {
- this._root.appendChild(this.html);
- } else {
- this._root.insertBefore(this.html,this._root.firstElementChild)
- }
- }
- }
- _remove(source,box) {
- source.html.removeChild(box.html)
- if (box._root == source) {
- box._root = undefined;
- }
- var x = source._boxes.indexOf(box)
- delete source._boxes[x]
- }
- _includes(source,box) {
- if (source._boxes.indexOf(box) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- /*
- * This redirect is to make it easier for subclasses that
- * override add() to make it eaiser to add logical
- * childs, e.g. adding to a table really adds to ._tbody,
- * not the true top-element of the table.
- */
- remove(box) {
- this._remove(this,box)
- }
- includes(box) {
- return this._includes(this,box);
- }
- hide() {
- if (this.html.parentElement instanceof HTMLElement) {
- this.html.parentElement.removeChild(this.html);
- }
- }
- destroy() {
- this.hide()
- for (var i in this._boxes) {
- var x = this._boxes[i];
- x.hide()
- x.destroy()
- delete this._boxes[i]
- }
- delete this.html;
- delete this;
- }
- update() {
- for (var x in this._boxes) {
- this._boxes[x].update();
- }
- }
-};
+ applySettings(settings) {
+ /*
+ * This really should go deeper, but the problem is that
+ * I'm lazy. You can't just use Object.assign() either because
+ * stuff like html.style isn't just any element and we want
+ * to be able to do html:{style:{display:"none"}} instead
+ * of html:{style:new (style object thing with display:none)}
+ *
+ * So far this works.
+ *
+ * Note that this breaks forr classList: This is because
+ * classList is just an accessor for className, so you
+ * should set className instead initially.
+ */
+ if (settings.html) {
+ for (var x in settings.html) {
+ if (settings.html[x] instanceof Object) {
+ Object.assign(this.html[x], settings.html[x]);
+ } else {
+ this.html[x] = settings.html[x];
+ }
+ }
+ }
+ }
+ /* Should rename these to push() and unshift(), really, to be
+ * more consistent.
+ */
+ add(box) {
+ this._boxes.push(box);
+ box.attach(this.html);
+ box.show();
+ }
+ insert(box) {
+ this._boxes.unshift(box);
+ box.attach(this.html);
+ box.show(true, -1);
+ }
+ /* This is provided so as to allow attaching to non-nmsBox-objects.
+ * E.g.: attach the root to a HTML element directly.
+ * If you just use foo = document.getElement...,
+ * foo.appendChild(box.html), then .hide() will work fine,
+ * but there's no way to do .show() afterwards.
+ *
+ * Be aware:
+ * - we want to AVOID the child knowing too much about the parent
+ * - HTML elements can only ever be part of a single parent
+ * element. This means that it is safe to attach(root1), .show(),
+ * atach(root2), show() ... The DOM object wil be removed from root1.
+ * - Due to the above, we should probably actually adress that, since
+ * there are valid reasons for showing the same nmsBox twice (e.g.:
+ * showing a list of tons of stuff, and also a "top 5")
+ */
+ attach(root) {
+ if (!(root instanceof HTMLElement)) {
+ root = document.getElementById(root);
+ }
+ console.assert(root instanceof HTMLElement);
+ this._root = root;
+ }
+ show(show = true, where = 1) {
+ if (!show) {
+ this.hide();
+ return;
+ }
+ if (this._root instanceof HTMLElement) {
+ if (where > 0) {
+ this._root.appendChild(this.html);
+ } else {
+ this._root.insertBefore(this.html, this._root.firstElementChild);
+ }
+ }
+ }
+ _remove(source, box) {
+ source.html.removeChild(box.html);
+ if (box._root == source) {
+ box._root = undefined;
+ }
+ var x = source._boxes.indexOf(box);
+ delete source._boxes[x];
+ }
+ _includes(source, box) {
+ if (source._boxes.indexOf(box) >= 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /*
+ * This redirect is to make it easier for subclasses that
+ * override add() to make it eaiser to add logical
+ * childs, e.g. adding to a table really adds to ._tbody,
+ * not the true top-element of the table.
+ */
+ remove(box) {
+ this._remove(this, box);
+ }
+ includes(box) {
+ return this._includes(this, box);
+ }
+ hide() {
+ if (this.html.parentElement instanceof HTMLElement) {
+ this.html.parentElement.removeChild(this.html);
+ }
+ }
+ destroy() {
+ this.hide();
+ for (var i in this._boxes) {
+ var x = this._boxes[i];
+ x.hide();
+ x.destroy();
+ delete this._boxes[i];
+ }
+ delete this.html;
+ delete this;
+ }
+ update() {
+ for (var x in this._boxes) {
+ this._boxes[x].update();
+ }
+ }
+}
class nmsString extends nmsBox {
- constructor(content,type) {
- type = type ? type : "p";
- super(type,{ html: { textContent: content }})
- }
- set value(input) {
- this.html.textContent = input;
- }
- get value() {
- return this.html.textContent;
- }
+ constructor(content, type) {
+ type = type ? type : "p";
+ super(type, { html: { textContent: content } });
+ }
+ set value(input) {
+ this.html.textContent = input;
+ }
+ get value() {
+ return this.html.textContent;
+ }
}
class nmsButton extends nmsBox {
- constructor(text,type = "btn-default") {
- super("button",{html:{textContent:text,className:"btn "+type,type:"button"}})
- }
+ constructor(text, type = "btn-default") {
+ super("button", {
+ html: { textContent: text, className: "btn " + type, type: "button" },
+ });
+ }
}
/*
* A general-purpose table. It can be created in one go, or
- * as-you-go.
+ * as-you-go.
*/
class nmsTable extends nmsBox {
- constructor(content, caption) {
- super("table",{html:{className:"table table-condensed"}});
- if (caption != undefined) {
- var cap = new nmsBox("caption");
- cap.html.textContent = caption;
- super.add(cap);
- }
- this._tbody = new nmsBox("tbody");
- super.add(this._tbody);
- for (var v in content) {
- this.add(content[v]);
- }
- }
- remove(box) {
- this._remove(this._tbody,box)
- }
- includes(box) {
- return this._tbody.includes(box)
- }
- _makeBox(content) {
- if (content instanceof nmsBox) {
- return content;
- }
- var tr;
- var td1;
- var td2;
- tr = new nmsBox("tr");
- for (var x in content) {
- var td = new nmsBox("td");
- var child = content[x];
- if (child instanceof nmsBox) {
- td.add(child);
- } else {
- td.add(new nmsString(child));
- }
- tr.add(td);
- }
- return tr;
- }
- /* Can take either a single nmsBox-object that will be added as-is,
- * or an array of items that will be added as individual cells
- */
- add(content) {
- this._tbody.add(this._makeBox(content));
- }
- insert(box) {
- this._tbody.insert(this._makeBox(box));
- }
+ constructor(content, caption) {
+ super("table", { html: { className: "table table-sm table-transparent" } });
+ if (caption != undefined) {
+ var cap = new nmsBox("caption");
+ cap.html.textContent = caption;
+ super.add(cap);
+ }
+ this._tbody = new nmsBox("tbody");
+ super.add(this._tbody);
+ for (var v in content) {
+ this.add(content[v]);
+ }
+ }
+ remove(box) {
+ this._remove(this._tbody, box);
+ }
+ includes(box) {
+ return this._tbody.includes(box);
+ }
+ _makeBox(content) {
+ if (content instanceof nmsBox) {
+ return content;
+ }
+ var tr;
+ tr = new nmsBox("tr");
+ for (var x in content) {
+ var td = new nmsBox("td");
+ var child = content[x];
+ if (child instanceof nmsBox) {
+ td.add(child);
+ } else {
+ td.add(new nmsString(child));
+ }
+ tr.add(td);
+ }
+ return tr;
+ }
+ /* Can take either a single nmsBox-object that will be added as-is,
+ * or an array of items that will be added as individual cells
+ */
+ add(content) {
+ this._tbody.add(this._makeBox(content));
+ }
+ insert(box) {
+ this._tbody.insert(this._makeBox(box));
+ }
}
/*
@@ -245,54 +244,57 @@ class nmsTable extends nmsBox {
* myThing.add(nmsString("whatever"))
* myThing.title = "blah...."
*/
-class nmsPanel extends nmsBox{
- constructor(title){
- super("div",{html:{style:{gridColumn: 2}}});
- this._topBox = new nmsBox("div",{ html: { className: "panel panel-default"}});
- this._body = new nmsBox("div",{html:{className: "panel-body"}});
- this.nav = new nmsBox("div",{html:{className: "panel-body"}});
- this._topBox.add(this.makeHeading(title));
- this._topBox.add(this.nav);
- this._topBox.add(this._body);
- super.add(this._topBox);
- }
- attach(root = document.getElementById("genericPanelContainer")) {
- try {
- var x = parseInt(root.lastElementChild.style.gridColumnStart);
- this.html.style.gridColumnStart = x+1;
- } catch(e) {
- }
- super.attach(root)
- }
- show() {
- if (!this._root) {
- this.attach()
- }
- super.show()
- }
- /* Mainly just to make the constructor more readable. */
- makeHeading(title) {
- var titleObject = new nmsBox("div",{html:{className: "panel-heading"}});
- this._titleText = new nmsBox("h4",{html:{textContent: title}});
- var closeButton = new nmsBox("button");
- closeButton.html.className = "close";
- closeButton.panel = this;
- closeButton.html.onclick = function() {
- this.nmsBox.panel.destroy();
- }
- closeButton.html.style = "float: right;";
- closeButton.add(new nmsString("X","span"));
- titleObject.add(closeButton);
- titleObject.add(this._titleText);
- return titleObject;
- }
- add(item) {
- this._body.add(item)
- }
- set title(input) {
- this._titleText.html.textContent = input;
- }
- get title() {
- this._titleText.html.textContent;
- }
+class nmsPanel extends nmsBox {
+ constructor(title) {
+ super("div", { html: { style: { gridColumn: 2 } } });
+ this._topBox = new nmsBox("div", {
+ html: { className: "panel panel-default" },
+ });
+ this._body = new nmsBox("div", { html: { className: "panel-body" } });
+ this.nav = new nmsBox("div", { html: { className: "panel-body" } });
+ this._topBox.add(this.makeHeading(title));
+ this._topBox.add(this.nav);
+ this._topBox.add(this._body);
+ super.add(this._topBox);
+ }
+ attach(root = document.getElementById("genericPanelContainer")) {
+ try {
+ var x = parseInt(root.lastElementChild.style.gridColumnStart);
+ this.html.style.gridColumnStart = x + 1;
+ } catch (e) {}
+ super.attach(root);
+ }
+ show() {
+ if (!this._root) {
+ this.attach();
+ }
+ super.show();
+ }
+ /* Mainly just to make the constructor more readable. */
+ makeHeading(title) {
+ var titleObject = new nmsBox("div", {
+ html: { className: "panel-heading" },
+ });
+ this._titleText = new nmsBox("h4", { html: { textContent: title } });
+ var closeButton = new nmsBox("button");
+ closeButton.html.className = "close";
+ closeButton.panel = this;
+ closeButton.html.onclick = function () {
+ this.nmsBox.panel.destroy();
+ };
+ closeButton.html.style = "float: right;";
+ closeButton.add(new nmsString("X", "span"));
+ titleObject.add(closeButton);
+ titleObject.add(this._titleText);
+ return titleObject;
+ }
+ add(item) {
+ this._body.add(item);
+ }
+ set title(input) {
+ this._titleText.html.textContent = input;
+ }
+ get title() {
+ this._titleText.html.textContent;
+ }
}
diff --git a/web/js/nms-ui-switch-summary.js b/web/js/nms-ui-switch-summary.js
index 9b63b24..edc6921 100644
--- a/web/js/nms-ui-switch-summary.js
+++ b/web/js/nms-ui-switch-summary.js
@@ -1,58 +1,63 @@
"user strict";
class nmsSwitchSummary extends nmsTable {
- constructor(sw) {
- super()
- this._sw = sw;
- this._data = {}
- this.refresh()
- }
-
- refresh() {
- for (var h in handlers ) {
- if (handlers[h].getInfo != undefined) {
- var tmp = handlers[h].getInfo(this._sw);
- if (!tmp) { continue; }
- if (this._data[h] == undefined) {
- this._data[h] = {}
- }
- for (var x in tmp.data) {
- if (this._data[h][x] == undefined) {
- this._data[h][x] = new nmsSwitchItem(tmp.data[x].description,handlers[h])
- this.add(this._data[h][x])
- }
- this._data[h][x].refresh(tmp.data[x])
- }
- }
- }
- }
+ constructor(sw) {
+ super();
+ this._sw = sw;
+ this._data = {};
+ this.refresh();
+ }
+
+ refresh() {
+ for (var h in handlers) {
+ if (handlers[h].getInfo != undefined) {
+ var tmp = handlers[h].getInfo(this._sw);
+ if (!tmp) {
+ continue;
+ }
+ if (this._data[h] == undefined) {
+ this._data[h] = {};
+ }
+ for (var x in tmp.data) {
+ if (this._data[h][x] == undefined) {
+ this._data[h][x] = new nmsSwitchItem(
+ tmp.data[x].description,
+ handlers[h]
+ );
+ this.add(this._data[h][x]);
+ }
+ this._data[h][x].refresh(tmp.data[x]);
+ }
+ }
+ }
+ }
}
class nmsSwitchItem extends nmsBox {
- constructor(description,handler) {
- super("tr")
- this.add(new nmsBox("td",{html:{textContent:description}}));
- this.html.title = handler.tag;
- this._value = new nmsBox("td")
- this.add(this._value)
- }
- refresh(item) {
- if (item.value == null || item.value == undefined || item.value == "") {
- if (this._hidden == true) {
- return;
- }
- this._value_content = undefined;
- this._hidden = true;
- this.hide()
- return;
- }
- if (this._value_content != item.value) {
- this._value.html.textContent = item.value;
- this._value_content = item.value;
- }
- if (this._hidden == true) {
- this.show()
- this._hidden = false;
- }
- }
+ constructor(description, handler) {
+ super("tr");
+ this.add(new nmsBox("td", { html: { textContent: description } }));
+ this.html.title = handler.tag;
+ this._value = new nmsBox("td");
+ this.add(this._value);
+ }
+ refresh(item) {
+ if (item.value == null || item.value == undefined || item.value == "") {
+ if (this._hidden == true) {
+ return;
+ }
+ this._value_content = undefined;
+ this._hidden = true;
+ this.hide();
+ return;
+ }
+ if (this._value_content != item.value) {
+ this._value.html.textContent = item.value;
+ this._value_content = item.value;
+ }
+ if (this._hidden == true) {
+ this.show();
+ this._hidden = false;
+ }
+ }
}
diff --git a/web/js/nms-ui-switch.js b/web/js/nms-ui-switch.js
index 825ecd9..e2663d4 100644
--- a/web/js/nms-ui-switch.js
+++ b/web/js/nms-ui-switch.js
@@ -3,318 +3,352 @@
/* Basic editor for switches, and possibly networks and whatever.
* This is the first real use of both the nmsBox and nmsType, so
* expect changes as the need(s) arise.
- *
+ *
* The general idea is simple, though: Editing and adding is to be treated
* as similar as possible, and there should be no hard-coding anywhere. If
* we need a "one-off" for whatever, we should find a genric way of solving
- * it to avoid complicating things.
- *
+ * it to avoid complicating things.
+ *
*/
class nmsNewSwitch extends nmsPanel {
- constructor() {
- super("Add new switch")
- this.add(new nmsModSwitch(undefined))
- this.nav.add(new nmsString("The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields."));
- }
+ constructor() {
+ super("Add new switch");
+ this.add(new nmsModSwitch(undefined));
+ this.nav.add(
+ new nmsString(
+ "The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields."
+ )
+ );
+ }
}
class nmsNewNet extends nmsPanel {
- constructor() {
- super("Add new network")
- this.add(new nmsModNet(undefined))
- this.nav.add(new nmsString("Only the name is required, but you should probably fill in more."));
- }
+ constructor() {
+ super("Add new network");
+ this.add(new nmsModNet(undefined));
+ this.nav.add(
+ new nmsString(
+ "Only the name is required, but you should probably fill in more."
+ )
+ );
+ }
}
class nmsModThing extends nmsBox {
- constructor(data) {
- super("div");
- this.identifier = data.identifier;
- this.invalidate = data.invalidate;
- this.api = data.api;
- this.item = data.item;
- this.generateBaseTemplate()
- this.populate()
- var save = new nmsButton("Save","btn-primary");
- save.panel = this;
- save.html.onclick = this.save;
- this.add(save)
- var del = new nmsButton("Delete","btn btn-danger");
- del.panel = this
- del.html.onclick = this.del;
- this.add(del)
- }
- commit(data) {
- $.ajax({
- type: "POST",
- url: this.api,
- dataType: "text",
- nmsBox:this,
- data:JSON.stringify(data),
- success: function (data, textStatus, jqXHR) {
- var msg = new nmsString("Changed...");
- msg.attach(this.nmsBox._root);
- msg.show()
- this.nmsBox.destroy()
- //nmsInfoBox.hide();
- for (var x of this.nmsBox.invalidate) {
- nmsData.invalidate(x);
- }
- }
- });
- }
+ constructor(data) {
+ super("div");
+ this.identifier = data.identifier;
+ this.invalidate = data.invalidate;
+ this.api = data.api;
+ this.item = data.item;
+ this.generateBaseTemplate();
+ this.populate();
+ }
+ commit(data) {
+ $.ajax({
+ type: "POST",
+ url: this.api,
+ dataType: "text",
+ nmsBox: this,
+ data: JSON.stringify(data),
+ success: function (data, textStatus, jqXHR) {
+ var msg = new nmsString("Changed...");
+ msg.attach(this.nmsBox._root);
+ msg.show();
+ this.nmsBox.destroy();
+ //nmsInfoBox.hide();
+ for (var x of this.nmsBox.invalidate) {
+ nmsData.invalidate(x);
+ }
+ },
+ });
+ }
- del(e) {
- if(confirm("This will delete the " + this.typeName + ":" + this.nmsBox.panel.item)) {
- this.nmsBox.panel.commit([{'sysname': this.nmsBox.panel.item, 'deleted': true}]);
- };
- }
- save(e) {
- var diff = this.nmsBox.panel.diff()
- if (diff != undefined) {
- this.nmsBox.panel.commit([diff])
- }
- }
- /* Pretty sure that the type-thing is OK, but what I want is to
- * generate a nmsTemplate or something that can be used to get/set
- * variables generically, and replaces nmsEditRow. Since right now,
- * both the template and the row is fiddling with values, luckily
- * all through the same actual object, but still....
- * This is because I wrote nmsEditRow before I added a type-system.
- *
- * The fundamental problem is that the row-rendering is obviously
- * affected by the type, and the overall "template"/parent
- * (nmsModSwitch right now) is also obviously affected by changes to
- * the individual rows.
- *
- * Right now a change in a value means nmsEditRow will get the
- * event, it will use the nmsType to validate, and ultimately set,
- * but it ALSO has to store a text-representation of the value if it
- * changes from other sources (e.g.: auto-complete), and we need to
- * alert nmsModSwitch that a change has occurred so it can act
- * approrpiately (e.g.: Enabling/disabling a save button).
- *
- * This means that nmsType instances, nmsEditRow instances and
- * nmsModSwitch instance is tightly coupled in non-obvious ways.
- *
- * Which means bugs.
- */
- populate() {
- if (this.item != undefined) {
- this._populateTemplate(this.item);
- }
- this.table = new nmsTable();
- this.rows = {}
- for (var v in this._template) {
- this.rows[v] = new nmsEditRow(v, this._template[v]);
- this.rows[v].parent = this;
- this.table.add(this.rows[v]);
- }
- this.add(this.table);
- }
- changed(row) {
- this.title = "saw row change on " + row.name + " to " + row.value;
- }
- get value() {
- var ret = {};
- for (var idx in this.rows) {
- ret[idx] = this.rows[idx].value;
- }
- return ret;
- }
- diff() {
- var ret = {};
- var changed = 0;
- for (var idx in this.rows) {
- if (this.rows[idx].value.toString() != this.rows[idx].original) {
- ret[idx] = this.rows[idx].value.value;
- changed++;
- }
- }
- if (!changed) {
- return undefined;
- }
- ret[this.identifier] = this.rows[this.identifier].value.value;
- return ret;
- }
+ del(e) {
+ if (
+ confirm(
+ "This will delete the " + this.typeName + ":" + this.nmsBox.panel.item
+ )
+ ) {
+ this.nmsBox.panel.commit([
+ { sysname: this.nmsBox.panel.item, deleted: true },
+ ]);
+ }
+ }
+ save(e) {
+ var diff = this.nmsBox.panel.diff();
+ if (diff != undefined) {
+ this.nmsBox.panel.commit([diff]);
+ }
+ }
+ /* Pretty sure that the type-thing is OK, but what I want is to
+ * generate a nmsTemplate or something that can be used to get/set
+ * variables generically, and replaces nmsEditRow. Since right now,
+ * both the template and the row is fiddling with values, luckily
+ * all through the same actual object, but still....
+ * This is because I wrote nmsEditRow before I added a type-system.
+ *
+ * The fundamental problem is that the row-rendering is obviously
+ * affected by the type, and the overall "template"/parent
+ * (nmsModSwitch right now) is also obviously affected by changes to
+ * the individual rows.
+ *
+ * Right now a change in a value means nmsEditRow will get the
+ * event, it will use the nmsType to validate, and ultimately set,
+ * but it ALSO has to store a text-representation of the value if it
+ * changes from other sources (e.g.: auto-complete), and we need to
+ * alert nmsModSwitch that a change has occurred so it can act
+ * approrpiately (e.g.: Enabling/disabling a save button).
+ *
+ * This means that nmsType instances, nmsEditRow instances and
+ * nmsModSwitch instance is tightly coupled in non-obvious ways.
+ *
+ * Which means bugs.
+ */
+ populate() {
+ if (this.item != undefined) {
+ this._populateTemplate(this.item);
+ }
+ this.table = new nmsTable();
+ this.rows = {};
+ for (var v in this._template) {
+ this.rows[v] = new nmsEditRow(v, this._template[v]);
+ this.rows[v].parent = this;
+ this.table.add(this.rows[v]);
+ }
+ this.add(this.table);
+ }
+ changed(row) {
+ this.title = "saw row change on " + row.name + " to " + row.value;
+ }
+ get value() {
+ var ret = {};
+ for (var idx in this.rows) {
+ ret[idx] = this.rows[idx].value;
+ }
+ return ret;
+ }
+ diff() {
+ var ret = {};
+ var changed = 0;
+ for (var idx in this.rows) {
+ if (this.rows[idx].value.toString() != this.rows[idx].original) {
+ ret[idx] = this.rows[idx].value.value;
+ changed++;
+ }
+ }
+ if (!changed) {
+ return undefined;
+ }
+ ret[this.identifier] = this.rows[this.identifier].value.value;
+ return ret;
+ }
}
class nmsEditRow extends nmsBox {
- constructor(text,value) {
- super("tr")
- // This should/could be smarter in the future.
- console.assert(value instanceof nmsType)
- this.name = text;
- this._value = value;
- this.original = value.toString();
- var td1 = new nmsBox("td")
- var name = new nmsString(text+" ");
- name.html.title = value.description;
- td1.add(name)
- this.add(td1);
- td1.html.width="50%"
- this._state = new nmsBox("span",{html:{className:"label label-default",textContent:"Original"}})
- this._valid = new nmsBox("span",{html:{className:"label label-default",textContent:"Not verified"}})
- name.add(this._state)
- name.add(this._valid)
- this._valid.hide()
- this.changed(false)
- var content = new nmsBox("td")
- var input = new nmsBox("input")
- input.html.value = value.toString();
- input.html.className = "form-control";
- input.html.type = "text";
- input.row = this;
- if (value.ro) {
- input.html.disabled = true;
- input.html.title = "Read/only attribute";
- }
- if (value instanceof nmsTypeSecret) {
- input.html.type = "password"
- input.html.autocomplete = "off"
- input.html.onfocus = function f() { this.type = "text" }
- input.html.oninput = function f() { this.type = "text" }
- input.html.onblur = function f() { this.type = "password" }
- }
- input.html.onchange = function() {
- this.nmsBox.row.value = this.value
- }
- input.html.oninput = function() {
- this.nmsBox.row.value = this.value
- }
- this._input = input;
- this._content = content;
- content.add(input)
- this.add(content)
- }
- get value() {
- return this._value;
- }
- changed(val) {
- if (val) {
- this._state.show()
- this._state.html.textContent = "Changed"
- this._state.html.classList.remove("label-default")
- this._state.html.classList.add("label-warning")
- } else {
- this._state.hide()
- }
- }
- valid(val) {
- this._valid.html.classList.remove("label-default")
- this._valid.show()
- if (val) {
- this._valid.html.textContent = "Valid"
- this._valid.html.classList.remove("label-danger")
- this._valid.html.classList.add("label-success")
- } else {
- this._valid.html.textContent = "Invalid"
- this._valid.html.classList.add("label-danger")
- this._valid.html.classList.remove("label-success")
- }
- }
+ constructor(text, value) {
+ super("tr");
+ // This should/could be smarter in the future.
+ console.assert(value instanceof nmsType);
+ this.name = text;
+ this._value = value;
+ this.original = value.toString();
+ var td1 = new nmsBox("td");
+ var name = new nmsString(text + " ");
+ name.html.title = value.description;
+ td1.add(name);
+ this.add(td1);
+ td1.html.width = "50%";
+ this._state = new nmsBox("span", {
+ html: { className: "label label-default", textContent: "Original" },
+ });
+ this._valid = new nmsBox("span", {
+ html: { className: "label label-default", textContent: "Not verified" },
+ });
+ name.add(this._state);
+ name.add(this._valid);
+ this._valid.hide();
+ this.changed(false);
+ var content = new nmsBox("td");
+ var input = new nmsBox("input");
+ input.html.value = value.toString();
+ input.html.className = "form-control";
+ input.html.type = "text";
+ input.row = this;
+ input.html.disabled = true;
+ if (value instanceof nmsTypeSecret) {
+ input.html.type = "password";
+ input.html.autocomplete = "off";
+ input.html.onfocus = function f() {
+ this.type = "text";
+ };
+ input.html.oninput = function f() {
+ this.type = "text";
+ };
+ input.html.onblur = function f() {
+ this.type = "password";
+ };
+ }
+ input.html.onchange = function () {
+ this.nmsBox.row.value = this.value;
+ };
+ input.html.oninput = function () {
+ this.nmsBox.row.value = this.value;
+ };
+ this._input = input;
+ this._content = content;
+ content.add(input);
+ this.add(content);
+ }
+ get value() {
+ return this._value;
+ }
+ changed(val) {
+ if (val) {
+ this._state.show();
+ this._state.html.textContent = "Changed";
+ this._state.html.classList.remove("label-default");
+ this._state.html.classList.add("label-warning");
+ } else {
+ this._state.hide();
+ }
+ }
+ valid(val) {
+ this._valid.html.classList.remove("label-default");
+ this._valid.show();
+ if (val) {
+ this._valid.html.textContent = "Valid";
+ this._valid.html.classList.remove("label-danger");
+ this._valid.html.classList.add("label-success");
+ } else {
+ this._valid.html.textContent = "Invalid";
+ this._valid.html.classList.add("label-danger");
+ this._valid.html.classList.remove("label-success");
+ }
+ }
-
- /* THIS IS A MESS */
- set value(value) {
- if (!this._value.validate(value)) {
- this.valid(false)
- this._content.html.classList.add("has-error");
- return;
- } else {
- this.valid(true)
- this._content.html.classList.remove("has-error");
- this._value.fromString(value);
- }
- if (this._input.html.value != this._value.toString()) {
- this._input.html.value = this._value.toString()
- }
- if (this._value.toString() != this.original) {
- this.changed(true)
- this._content.html.classList.add("has-success");
- } else {
- this.changed(false)
- this._content.html.classList.remove("has-success");
- }
- this.parent.changed(this)
- }
+ /* THIS IS A MESS */
+ set value(value) {
+ if (!this._value.validate(value)) {
+ this.valid(false);
+ this._content.html.classList.add("has-error");
+ return;
+ } else {
+ this.valid(true);
+ this._content.html.classList.remove("has-error");
+ this._value.fromString(value);
+ }
+ if (this._input.html.value != this._value.toString()) {
+ this._input.html.value = this._value.toString();
+ }
+ if (this._value.toString() != this.original) {
+ this.changed(true);
+ this._content.html.classList.add("has-success");
+ } else {
+ this.changed(false);
+ this._content.html.classList.remove("has-success");
+ }
+ this.parent.changed(this);
+ }
}
class nmsModSwitch extends nmsModThing {
- constructor(sw) {
- super({item: sw, identifier: "sysname", invalidate: ["switches","smanagement"], api: "/api/write/switches"})
- }
- generateBaseTemplate() {
- this._template = {
- sysname: new nmsTypeSysname("Unique systemname/switch name. Only required field. Read/only on existing equipment." ),
- mgmt_v4_addr: new nmsTypeIP("Management address IPv4"),
- mgmt_v6_addr: new nmsTypeIP("Management address IPv6"),
- mgmt_vlan: new nmsTypeNetwork("Management VLAN"),
- traffic_vlan: new nmsTypeNetwork("Traffic VLAN"),
- distro_name: new nmsTypeSysnameReference("Distro switch upstream of this system. Required for provisioning."),
- distro_phy_port: new nmsTypePort("Name of port we connect to at the distro switch. Used for provisioning, among other things."),
- poll_frequency: new nmsTypeInterval("Poll frequency for SNMP (will use default from backend)"),
- community: new nmsTypeSecret("SNMP community (will use default from backend)"),
- placement: new nmsTypePlace("Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)"),
- tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.")
- }
- }
- _populateTemplate(sw) {
- var swi = [];
- var swm = [];
- try {
- swi = nmsData.switches["switches"][sw];
- swm = nmsData.smanagement.switches[sw];
- } catch(e) {}
+ constructor(sw) {
+ super({
+ item: sw,
+ identifier: "sysname",
+ invalidate: ["switches", "smanagement"],
+ api: "/api/write/switches",
+ });
+ }
+ generateBaseTemplate() {
+ this._template = {
+ sysname: new nmsTypeSysname(
+ "Unique systemname/switch name. Only required field. Read/only on existing equipment."
+ ),
+ mgmt_v4_addr: new nmsTypeIP("Management address IPv4"),
+ mgmt_v6_addr: new nmsTypeIP("Management address IPv6"),
+ mgmt_vlan: new nmsTypeNetwork("Management VLAN"),
+ traffic_vlan: new nmsTypeNetwork("Traffic VLAN"),
+ distro_name: new nmsTypeSysnameReference(
+ "Distro switch upstream of this system. Required for provisioning."
+ ),
+ distro_phy_port: new nmsTypePort(
+ "Name of port we connect to at the distro switch. Used for provisioning, among other things."
+ ),
+ placement: new nmsTypePlace(
+ "Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)"
+ ),
+ tags: new nmsTypeTags(
+ "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems."
+ ),
+ };
+ }
+ _populateTemplate(sw) {
+ var swi = [];
+ var swm = [];
+ try {
+ swi = nmsData.switches["switches"][sw];
+ swm = nmsData.smanagement.switches[sw];
+ } catch (e) {}
- var template = {}
- for (var v in swi) {
- console.assert(this._template[v] instanceof nmsType)
- if (swi[v] != null) {
- this._template[v].initial(swi[v]);
- }
- }
- for (var v in swm) {
- if (v == "last_updated") {
- continue;
- }
- console.assert(this._template[v] instanceof nmsType)
- if (swm[v] != null) {
- this._template[v].initial(swm[v]);
- }
- }
- }
+ var template = {};
+ for (var v in swi) {
+ console.assert(this._template[v] instanceof nmsType);
+ if (swi[v] != null) {
+ this._template[v].initial(swi[v]);
+ }
+ }
+ for (var v in swm) {
+ if (v == "last_updated") {
+ continue;
+ }
+ console.assert(this._template[v] instanceof nmsType);
+ if (swm[v] != null && this._template[v]) {
+ this._template[v].initial(swm[v]);
+ }
+ }
+ }
}
class nmsModNet extends nmsModThing {
- constructor(net) {
- super({item: net, identifier: "name", invalidate: ["networks","smanagement"], api: "/api/write/networks"})
- }
- generateBaseTemplate() {
- this._template = {
- name: new nmsType("Unique networkname. Only required field. Read/only on existing nets."),
- vlan: new nmsType("VLAN ID"),
- gw4: new nmsTypeIP("Gateway address, IPv4"),
- gw6: new nmsTypeIP("Gateway address, IPv6"),
- subnet4: new nmsTypeCIDR("Subnet, IPv4"),
- subnet6: new nmsTypeCIDR("Subnet, IPv6"),
- router: new nmsTypeSysnameReference("Router where net is terminated. E.g.: r1.noc for floor traffic nets"),
- tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.")
- }
- }
- _populateTemplate(net) {
- var nets = [];
- try {
- nets = nmsData.networks["networks"][net];
- } catch(e) {}
+ constructor(net) {
+ super({
+ item: net,
+ identifier: "name",
+ invalidate: ["networks", "smanagement"],
+ api: "/api/write/networks",
+ });
+ }
+ generateBaseTemplate() {
+ this._template = {
+ name: new nmsType(
+ "Unique networkname. Only required field. Read/only on existing nets."
+ ),
+ vlan: new nmsType("VLAN ID"),
+ gw4: new nmsTypeIP("Gateway address, IPv4"),
+ gw6: new nmsTypeIP("Gateway address, IPv6"),
+ subnet4: new nmsTypeCIDR("Subnet, IPv4"),
+ subnet6: new nmsTypeCIDR("Subnet, IPv6"),
+ router: new nmsTypeSysnameReference(
+ "Router where net is terminated. E.g.: r1.noc for floor traffic nets"
+ ),
+ tags: new nmsTypeTags(
+ "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems."
+ ),
+ };
+ }
+ _populateTemplate(net) {
+ var nets = [];
+ try {
+ nets = nmsData.networks["networks"][net];
+ } catch (e) {}
- var template = {}
- for (var v in nets) {
- console.assert(this._template[v] instanceof nmsType)
- if (nets[v] != null) {
- this._template[v].initial(nets[v]);
- }
- }
- }
+ var template = {};
+ for (var v in nets) {
+ console.assert(this._template[v] instanceof nmsType);
+ if (nets[v] != null) {
+ this._template[v].initial(nets[v]);
+ }
+ }
+ }
}
-
-
diff --git a/web/js/nms-ui.js b/web/js/nms-ui.js
index 48865c4..efbeeec 100644
--- a/web/js/nms-ui.js
+++ b/web/js/nms-ui.js
@@ -1,27 +1,26 @@
"use strict";
-
/*
* The idea is to gradually move pure UI stuff into nmsUi.
*/
var nmsUi = nmsUi || {
- _active: "map"
+ _active: "map",
};
-nmsUi.setActive = function(pane) {
- var old = document.getElementById(nmsUi._active);
- var newp = document.getElementById(pane);
- old.style.display = "none";
- newp.style.display = "block";
-
- var oldlink = document.getElementById(nmsUi._active + "-link");
- var newlink = document.getElementById(pane + "-link");
- oldlink.classList.remove("active");
- newlink.classList.add("active");
+nmsUi.setActive = function (pane) {
+ var old = document.getElementById(nmsUi._active);
+ var newp = document.getElementById(pane);
+ old.style.display = "none";
+ newp.style.display = "block";
+
+ var oldlink = document.getElementById(nmsUi._active + "-link");
+ var newlink = document.getElementById(pane + "-link");
+ oldlink.classList.remove("active");
+ newlink.classList.add("active");
- nmsUi._active = pane;
-}
+ nmsUi._active = pane;
+};
-nmsUi.toggleVertical = function(x) {
- nms.vertical = !nms.vertical;
-}
+nmsUi.toggleVertical = function (x) {
+ nms.vertical = !nms.vertical;
+};
diff --git a/web/js/nms.js b/web/js/nms.js
index f0b82a7..c699726 100644
--- a/web/js/nms.js
+++ b/web/js/nms.js
@@ -15,87 +15,96 @@
* now it's just leftovers.
*/
var nms = {
- stats:{}, // Various internal stats
- get nightMode() { return this._nightMode; },
- set nightMode(val) { if (val != this._nightMode) { this._nightMode = val; setNightMode(val); } },
- /*
- * Various setInterval() handlers. See nmsTimer() for how they are
- * used.
- *
- * FIXME: Should just stop using these.
- */
- timers: {
- tvmode: false
- },
-
- menuShowing:true,
- oplogShowing:true,
- get uptime() {
- return (Date.now() - this._startTime)/1000;
- },
- _vertical: 0,
- get vertical() { return this._vertical },
- set vertical(v) {
- this._vertical = v;
- if(v)
- document.body.classList.add("vertical");
- else
- document.body.classList.remove("vertical");
- saveSettings();
- },
-
- interval: 10,
- _user: undefined,
- get user() { return this._user; },
- set user(u) {
- this._user = u;
- saveSettings();
- },
- /*
- * This is a list of nms[x] variables that we store in our
- * settings-cookie when altered and restore on load.
- */
- settingsList:[
- 'nightMode',
- 'menuShowing',
- 'vertical',
- 'interval',
- 'oplogShowing',
- 'user'
- ],
- keyBindings:{
- '-':toggleMenu,
- 'n':toggleNightMode,
- '1':setMapModeFromN,
- '2':setMapModeFromN,
- '3':setMapModeFromN,
- '4':setMapModeFromN,
- '5':setMapModeFromN,
- '6':setMapModeFromN,
- '7':setMapModeFromN,
- '8':setMapModeFromN,
- '9':setMapModeFromN,
- '0':setMapModeFromN,
- 'c':toggleConnect,
- 'H':moveTimeFromKey,
- 'h':moveTimeFromKey,
- 'j':moveTimeFromKey,
- 'k':moveTimeFromKey,
- 'l':moveTimeFromKey,
- 'L':moveTimeFromKey,
- 'p':moveTimeFromKey,
- 'r':moveTimeFromKey,
- 'o':toggleOplog,
- 'Escape':hideWindow,
- '?':toggleHelp
- },
- tvmode: {
- handlers: [],
- currentIndex: 0,
- interval: 20000,
- active: false,
- vertical: false
- }
+ stats: {}, // Various internal stats
+ get nightMode() {
+ return this._nightMode;
+ },
+ set nightMode(val) {
+ if (val != this._nightMode) {
+ this._nightMode = val;
+ setNightMode(val);
+ }
+ },
+ /*
+ * Various setInterval() handlers. See nmsTimer() for how they are
+ * used.
+ *
+ * FIXME: Should just stop using these.
+ */
+ timers: {
+ tvmode: false,
+ },
+
+ menuShowing: true,
+ oplogShowing: true,
+ get uptime() {
+ return (Date.now() - this._startTime) / 1000;
+ },
+ _vertical: 0,
+ get vertical() {
+ return this._vertical;
+ },
+ set vertical(v) {
+ this._vertical = v;
+ if (v) document.body.classList.add("vertical");
+ else document.body.classList.remove("vertical");
+ saveSettings();
+ },
+
+ interval: 10,
+ _user: undefined,
+ get user() {
+ return this._user;
+ },
+ set user(u) {
+ this._user = u;
+ saveSettings();
+ },
+ /*
+ * This is a list of nms[x] variables that we store in our
+ * settings-cookie when altered and restore on load.
+ */
+ settingsList: [
+ "nightMode",
+ "menuShowing",
+ "vertical",
+ "interval",
+ "oplogShowing",
+ "user",
+ ],
+ keyBindings: {
+ "-": toggleMenu,
+ n: toggleNightMode,
+ 1: setMapModeFromN,
+ 2: setMapModeFromN,
+ 3: setMapModeFromN,
+ 4: setMapModeFromN,
+ 5: setMapModeFromN,
+ 6: setMapModeFromN,
+ 7: setMapModeFromN,
+ 8: setMapModeFromN,
+ 9: setMapModeFromN,
+ 0: setMapModeFromN,
+ c: toggleConnect,
+ H: moveTimeFromKey,
+ h: moveTimeFromKey,
+ j: moveTimeFromKey,
+ k: moveTimeFromKey,
+ l: moveTimeFromKey,
+ L: moveTimeFromKey,
+ p: moveTimeFromKey,
+ r: moveTimeFromKey,
+ o: toggleOplog,
+ Escape: hideWindow,
+ "?": toggleHelp,
+ },
+ tvmode: {
+ handlers: [],
+ currentIndex: 0,
+ interval: 20000,
+ active: false,
+ vertical: false,
+ },
};
/*
@@ -105,76 +114,69 @@ var nms = {
* new code.
*/
function nmsTimer(handler, interval, name, description) {
- this.handler = handler;
- this.handle = false;
- this.interval = parseInt(interval);
- this.name = name;
- this.description = description;
- this.start = function() {
- if (this.handle) {
- this.stop();
- }
- this.handle = setInterval(this.handler,this.interval);
- };
- this.stop = function() {
- if (this.handle)
- clearInterval(this.handle);
- this.handle = false;
- };
-
- this.setInterval = function(interval) {
- var started = this.handle != false;
- this.stop();
- this.interval = parseInt(interval);
- if (started)
- this.start();
- };
+ this.handler = handler;
+ this.handle = false;
+ this.interval = parseInt(interval);
+ this.name = name;
+ this.description = description;
+ this.start = function () {
+ if (this.handle) {
+ this.stop();
+ }
+ this.handle = setInterval(this.handler, this.interval);
+ };
+ this.stop = function () {
+ if (this.handle) clearInterval(this.handle);
+ this.handle = false;
+ };
+
+ this.setInterval = function (interval) {
+ var started = this.handle != false;
+ this.stop();
+ this.interval = parseInt(interval);
+ if (started) this.start();
+ };
}
-
/*
* Convenience function that doesn't support huge numbers, and it's easier
* to comment than to fix. But not really, but I'm not fixing it anyway.
*/
-function byteCount(bytes,precision) {
- if (precision ==undefined)
- precision = 1;
- var units = ['', 'K', 'M', 'G', 'T', 'P', 'E','Z'];
- var i = 0;
- while (bytes > 1024) {
- bytes = bytes / 1024;
- i++;
- }
- if (i == 0)
- return bytes;
- return bytes.toFixed(precision) + units[i];
+function byteCount(bytes, precision) {
+ if (precision == undefined) precision = 1;
+ var units = ["", "K", "M", "G", "T", "P", "E", "Z"];
+ var i = 0;
+ while (bytes > 1024) {
+ bytes = bytes / 1024;
+ i++;
+ }
+ if (i == 0) return bytes;
+ return bytes.toFixed(precision) + units[i];
}
/*
* Definitely not a way to toggle night mode. Does something COMPLETELY
* DIFFERENT.
*/
-function toggleNightMode()
-{
- nms.nightMode = !nms.nightMode;
- saveSettings();
+function toggleNightMode() {
+ nms.nightMode = !nms.nightMode;
+ saveSettings();
}
/*
* There are 4 legend-bars. This is a helper-function to set the color and
* description/name for each one. Used from handler init-functions.
*/
-function setLegend(x,color,name)
-{
- var el = document.getElementById("legend-" + x);
- el.style.background = color;
- el.title = name;
- el.textContent = name;
- if (name == "") {
- el.style.display = 'none';
- } else {
- el.style.display = '';
- }
+function setLegend(x, color, name) {
+ var el = document.getElementById("legend-" + x);
+ el.style.background = color;
+ el.title = name;
+ el.textContent = name;
+ if (name == "") {
+ el.style.display = "none";
+ } else {
+ el.style.display = "";
+ }
}
/*
@@ -186,37 +188,41 @@ function setLegend(x,color,name)
* FIXME: this is getting gradually stripped down from the original, so far
* we're not quite there yet with merging it with the regular code paths.
*/
-nms.tvmode.start = function(views,interval) {
- nms.tvmode.handlers = [];
- for(var view in views) {
- for(var handler in handlers) {
- if(views[view] == handlers[handler].tag) {
- nms.tvmode.handlers.push(handlers[handler]);
- }
- }
- }
- if (nms.tvmode.handlers.length > 1) {
- if(interval > 0)
- nms.tvmode.interval = interval * 1000;
- nms.timers.tvmode = new nmsTimer(nms.tvmode.tick, nms.tvmode.interval, "TV-mode ticker", "Handler used to advance tv-mode");
- nms.timers.tvmode.start();
- nms.tvmode.tick();
- nms.tvmode.active = true;
- }
-}
-nms.tvmode.tick = function() {
- if(nms.tvmode.currentIndex > nms.tvmode.handlers.length - 1) {
- nms.tvmode.currentIndex = 0;
- }
- setUpdater(nms.tvmode.handlers[nms.tvmode.currentIndex],false);
- nms.tvmode.currentIndex++;
-}
-nms.tvmode.stop = function() {
- if (nms.tvmode.active) {
- nms.timers.tvmode.stop();
- nms.tvmode.active = false;
- }
-}
+nms.tvmode.start = function (views, interval) {
+ nms.tvmode.handlers = [];
+ for (var view in views) {
+ for (var handler in handlers) {
+ if (views[view] == handlers[handler].tag) {
+ nms.tvmode.handlers.push(handlers[handler]);
+ }
+ }
+ }
+ if (nms.tvmode.handlers.length > 1) {
+ if (interval > 0) nms.tvmode.interval = interval * 1000;
+ nms.timers.tvmode = new nmsTimer(
+ nms.tvmode.tick,
+ nms.tvmode.interval,
+ "TV-mode ticker",
+ "Handler used to advance tv-mode"
+ );
+ nms.timers.tvmode.start();
+ nms.tvmode.tick();
+ nms.tvmode.active = true;
+ }
+};
+nms.tvmode.tick = function () {
+ if (nms.tvmode.currentIndex > nms.tvmode.handlers.length - 1) {
+ nms.tvmode.currentIndex = 0;
+ }
+ setUpdater(nms.tvmode.handlers[nms.tvmode.currentIndex], false);
+ nms.tvmode.currentIndex++;
+};
+nms.tvmode.stop = function () {
+ if (nms.tvmode.active) {
+ nms.timers.tvmode.stop();
+ nms.tvmode.active = false;
+ }
+};
/*
* Used when changing handler to ensure that the new handler is listed in
@@ -224,15 +230,15 @@ nms.tvmode.stop = function() {
* we only overwrite it if the new view isn't present.
*/
function ensureAnchorHas(view) {
- try {
- var views = document.location.hash.slice(1);
- views = views.split(",");
- if (views.includes(view)) {
- return true;
- }
- } catch(e) { }
- document.location.hash = view;
- return false;
+ try {
+ var views = document.location.hash.slice(1);
+ views = views.split(",");
+ if (views.includes(view)) {
+ return true;
+ }
+ } catch (e) {}
+ document.location.hash = view;
+ return false;
}
/*
@@ -241,56 +247,63 @@ function ensureAnchorHas(view) {
* stopTv esnures that we don't conflict with the tvmode thing. If a
* user-initiated map is selected, tvmode is disabled.
*/
-function setUpdater(fo, stopTv )
-{
- if (stopTv == undefined) {
- stopTv = true;
- }
- if (stopTv)
- nms.tvmode.stop();
- nmsMap.reset();
- nmsData.unregisterHandlerWildcard("mapHandler");
- try {
- fo.init();
- } catch (e) {
- /*
- * This can happen typically on initial load where the data
- * hasn't been retrieved yet. Instead of breaking the
- * entire init-process, just bail out here.
- */
- console.log("Possibly broken handler: " + fo.name);
- console.log(e);
- }
- var foo = document.getElementById("map-mode-title");
- foo.innerHTML = fo.name;
- ensureAnchorHas(fo.tag);
+function setUpdater(fo, stopTv) {
+ if (stopTv == undefined) {
+ stopTv = true;
+ }
+ if (stopTv) nms.tvmode.stop();
+ nmsMap.reset();
+ nmsData.unregisterHandlerWildcard("mapHandler");
+ try {
+ fo.init();
+ } catch (e) {
+ /*
+ * This can happen typically on initial load where the data
+ * hasn't been retrieved yet. Instead of breaking the
+ * entire init-process, just bail out here.
+ */
+ console.log("Possibly broken handler: " + fo.name);
+ console.log(e);
+ }
+ var foo = document.getElementById("map-mode-title");
+ foo.innerHTML = fo.name;
+ ensureAnchorHas(fo.tag);
}
function toggleLayer(layer) {
- var l = document.getElementById(layer);
- if (l.style.display == 'none')
- l.style.display = '';
- else
- l.style.display = 'none';
+ var l = document.getElementById(layer);
+ if (l.classList.contains("show")) {
+ // Hide
+ l.classList.remove("show");
+ l.classList.add("d-none");
+ } else {
+ // Show
+ l.classList.remove("d-none");
+ l.classList.add("show");
+ }
}
function hideLayer(layer) {
- var l = document.getElementById(layer);
- l.style.display = 'none';
+ var l = document.getElementById(layer);
+ l.classList.remove("show");
+ l.classList.add("d-none");
}
-
function toggleConnect() {
- toggleLayer("linkCanvas");
+ toggleLayer("linkCanvas");
}
/*
* Returns true if the coordinates (x,y) is inside the box defined by
* box.{x,y,w.h} (e.g.: placement of a switch).
*/
-function isIn(box, x, y)
-{
- return ((x >= box.x) && (x <= (box.x + box.width)) && (y >= box.y) && (y <= (box.y + box.height)));
+function isIn(box, x, y) {
+ return (
+ x >= box.x &&
+ x <= box.x + box.width &&
+ y >= box.y &&
+ y <= box.y + box.height
+ );
}
/*
@@ -299,16 +312,16 @@ function isIn(box, x, y)
*
* FIXME: this belongs in nmsMap.
*/
-function findSwitch(x,y) {
- x = parseInt(parseInt(x) / nmsMap.scale);
- y = parseInt(parseInt(y) / nmsMap.scale);
-
- for (var v in nmsData.switches.switches) {
- if(isIn(nmsData.switches.switches[v]['placement'],x,y)) {
- return v;
- }
- }
- return undefined;
+function findSwitch(x, y) {
+ x = parseInt(parseInt(x) / nmsMap.scale);
+ y = parseInt(parseInt(y) / nmsMap.scale);
+
+ for (var v in nmsData.switches.switches) {
+ if (isIn(nmsData.switches.switches[v]["placement"], x, y)) {
+ return v;
+ }
+ }
+ return undefined;
}
/*
@@ -317,19 +330,13 @@ function findSwitch(x,y) {
* Changes background and nav-bar, then leaves the rest to nmsMap.
*/
function setNightMode(toggle) {
- nms.nightMode = toggle;
- var body = document.getElementById("body");
- body.style.background = toggle ? "black" : "white";
- var nav = document.getElementsByTagName("nav")[0];
- if (toggle) {
- nav.classList.add('navbar-inverse');
- document.body.classList.add("nightmode");
- } else {
- nav.classList.remove('navbar-inverse');
- document.body.classList.remove("nightmode");
- }
- nmsMap.setNightMode(toggle);
- setNightModeChart(toggle);
+ nms.nightMode = toggle;
+ if (toggle) {
+ document.documentElement.setAttribute("data-bs-theme", "dark");
+ } else {
+ document.documentElement.setAttribute("data-bs-theme", "light");
+ }
+ nmsMap.setNightMode(toggle);
}
/*
@@ -348,23 +355,15 @@ function setNightMode(toggle) {
* just silencing them or by moving this off the main thread, then go
* ahead and fix it. I don't consider it a real problem, though.
*/
-function getInitialConfig() {
- $.ajax({
- type: "GET",
- url: "/api/public/config",
- async: false,
- dataType: "json",
- success: function (data, textStatus, jqXHR) {
- if (data["config"]["public"] == "true") {
- nms._public = true;
- document.body.classList.add("gondul-public");
- } else {
- nms._public = false;
- document.body.classList.add("gondul-private");
- nmsTemplate.getTemplates();
- }
- }
- });
+async function getInitialConfig() {
+ nms._public = false;
+ document.body.classList.add("gondul-private");
+
+ const data = await getData("/api/public/config");
+ if (data["config"]["public"] == "true") {
+ nms._public = true;
+ document.body.classList.add("gondul-public");
+ }
}
/*
@@ -374,230 +373,222 @@ function getInitialConfig() {
* the same framework. Or rather: that's the goal. We're not quite there
* yet.
*/
-function initNMS() {
- // Only used for dev-purposes now. Accessible through nms.uptime.
- nms._startTime = Date.now();
-
- // Public
- nmsData.registerSource("config","/api/public/config");
- nmsData.registerSource("ping", "/api/public/ping");
- nmsData.registerSource("switches","/api/public/switches");
- nmsData.registerSource("switchstate","/api/public/switch-state");
- nmsData.registerSource("dhcpsummary","/api/public/dhcp-summary");
- nmsData.registerSource("dhcp","/api/public/dhcp");
-
- // Fetch initial config. Basically just populates nms._public.
- // All other settings are kept in nmsData['config'].
- getInitialConfig();
-
- // This is a magic dummy-source, it's purpose is to give a unified
- // way to get ticks every second. It is mainly meant to allow map
- // handlers to register for ticks so they will execute without data
- // (and thus notice stale data instead of showing a green ping-map
- // despite no pings)
- nmsData.registerSource("ticker","bananabananbanana");
-
- if (!nms._public) {
- // Private
- nmsData.registerSource("snmp","/api/read/snmp");
- nmsData.registerSource("smanagement","/api/read/switches-management");
- nmsData.registerSource("oplog", "/api/read/oplog");
- nmsData.registerSource("networks","/api/read/networks");
- nmsOplog.init();
- }
- restoreSettings();
- nmsMap.init();
- detectHandler();
- setupKeyhandler();
- nmsSearch.init();
- nmsDhcp.init();
- nmsNightMode.init();
+async function initNMS() {
+ // Only used for dev-purposes now. Accessible through nms.uptime.
+ nms._startTime = Date.now();
+
+ // Public
+ nmsData.registerSource("config", "/api/public/config");
+ nmsData.registerSource("ping", "/api/public/ping");
+ nmsData.registerSource(
+ "switches",
+ "/api/public/switches"
+ );
+ //nmsData.registerSource("switchstate", "/api/public/switch-state");
+ //nmsData.registerSource("dhcpsummary","/api/public/dhcp-summary");
+ //nmsData.registerSource("dhcp","/api/public/dhcp");
+
+ // Fetch initial config. Basically just populates nms._public.
+ // All other settings are kept in nmsData['config'].
+ await getInitialConfig();
+
+ // This is a magic dummy-source, it's purpose is to give a unified
+ // way to get ticks every second. It is mainly meant to allow map
+ // handlers to register for ticks so they will execute without data
+ // (and thus notice stale data instead of showing a green ping-map
+ // despite no pings)
+ nmsData.registerSource("ticker", "bananabananbanana");
+
+ if (!nms._public) {
+ // Private
+ nmsData.registerSource("snmp", "/api/read/snmp");
+ nmsData.registerSource(
+ "smanagement",
+ "/api/read/switches-management"
+ );
+ nmsData.registerSource("oplog", "/api/v2/oplog/");
+ nmsData.registerSource(
+ "networks",
+ "/api/read/networks"
+ );
+ nmsOplog.init();
+ }
+ restoreSettings();
+ nmsMap.init();
+ detectHandler();
+ setupKeyhandler();
+ nmsSearch.init();
+ //nmsDhcp.init();
+ nmsNightMode.init();
}
function detectHandler() {
- var views = document.location.hash.slice(1);
- var interval = nms.interval;
- if (views == undefined || views == "")
- views = "health";
- if (nms._public)
- views = "ping";
- views = views.split(",");
-
- if (views.length > 1) {
- nms.tvmode.start(views,interval);
- return;
- } else {
- for (var i in handlers) {
- if (handlers[i].tag == views[0]) {
- setUpdater(handlers[i]);
- return;
- }
- }
- }
- setUpdater(handler_health);
+ var views = document.location.hash.slice(1);
+ var interval = nms.interval;
+ if (views == undefined || views == "") views = "health";
+ if (nms._public) views = "ping";
+ views = views.split(",");
+
+ if (views.length > 1) {
+ nms.tvmode.start(views, interval);
+ return;
+ } else {
+ for (var i in handlers) {
+ if (handlers[i].tag == views[0]) {
+ setUpdater(handlers[i]);
+ return;
+ }
+ }
+ }
+ setUpdater(handler_health);
}
function getUrlVars() {
- var vars = {};
- var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&#]*)/gi, function(m,key,value) {
- vars[key] = value;
- });
- return vars;
-}
-
-function setMenu()
-{
- var nav = document.getElementsByTagName("nav")[0];
- nav.style.display = nms.menuShowing ? '' : 'none';
- nmsMap.forceResize();
-}
-
-function setOplog()
-{
- if(nms._public == false)
- nms.oplog.mini.show(nms.oplogShowing)
-}
-
-function toggleMenu()
-{
- nms.menuShowing = ! nms.menuShowing;
- setMenu();
- saveSettings();
-}
-function toggleOplog()
-{
- nms.oplogShowing = ! nms.oplogShowing;
- setOplog();
- saveSettings();
-}
-function hideWindow(e,key)
-{
- nmsInfoBox.hide();
-}
-function toggleHelp(e,key) {
- toggleLayer('aboutKeybindings');
-}
-
-function setMapModeFromN(e,key)
-{
- switch(key) {
- case '1':
- setUpdater(handler_health);
- break;
- case '2':
- setUpdater(handler_uplinks);
- break;
- case '3':
- setUpdater(handler_dhcp);
- break;
- case '4':
- setUpdater(handler_ping);
- break;
- case '5':
- setUpdater(handler_temp);
- break;
- case '6':
- setUpdater(handler_traffic);
- break;
- case '7':
- setUpdater(handler_traffic_tot);
- break;
- case '8':
- setUpdater(handler_snmp);
- break;
- case '9':
- setUpdater(handler_cpu);
- break;
- case '0':
- setUpdater(handler_disco);
- break;
- }
- return true;
-}
-
-function moveTimeFromKey(e,key)
-{
- switch(key) {
- case 'H':
- nmsTime.stepKey(-1440);
- break;
- case 'h':
- nmsTime.stepKey(-60);
- break;
- case 'j':
- nmsTime.stepKey(-5);
- break;
- case 'k':
- nmsTime.stepKey(5);
- break;
- case 'l':
- nmsTime.stepKey(60);
- break;
- case 'L':
- nmsTime.stepKey(1440);
- break;
- case 'p':
- nmsTime.togglePause();
- break;
- case 'r':
- nmsTime.realTime();
- break;
- }
- return true;
-}
-
-function keyPressed(e)
-{
- if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") {
- return false;
- }
- if(e.key) {
- var key = e.key;
- } else {
- var key = e.keyCode;
- switch(key) {
- case 187:
- key = '?';
- break;
- case 189:
- key = '-';
- break;
- case 27:
- key = 'Escape';
- break;
- default:
- key = String.fromCharCode(key);
- key = key.toLowerCase();
- break;
- }
- }
- if (nms.keyBindings[key])
- return nms.keyBindings[key](e,key);
- if (nms.keyBindings['default'])
- return nms.keyBindings['default'](e,key);
- return false;
-}
-
-function setupKeyhandler()
-{
- var b = document.getElementsByTagName("body")[0];
- $( "body" ).keyup(function(e) {
- keyPressed(e);
- });
+ var vars = {};
+ var parts = window.location.href.replace(
+ /[?&]+([^=&]+)=([^&#]*)/gi,
+ function (m, key, value) {
+ vars[key] = value;
+ }
+ );
+ return vars;
+}
+
+function setMenu() {
+ var nav = document.getElementsByTagName("nav")[0];
+ nav.style.display = nms.menuShowing ? "" : "none";
+ nmsMap.forceResize();
+}
+
+function setOplog() {
+ if (nms._public == false) nms.oplog.mini.show(nms.oplogShowing);
+}
+
+function toggleMenu() {
+ nms.menuShowing = !nms.menuShowing;
+ setMenu();
+ saveSettings();
+}
+function toggleOplog() {
+ nms.oplogShowing = !nms.oplogShowing;
+ setOplog();
+ saveSettings();
+}
+function hideWindow(e, key) {
+ nmsInfoBox.hide();
+}
+function toggleHelp(e, key) {
+ toggleLayer("aboutKeybindings");
+}
+
+function setMapModeFromN(e, key) {
+ switch (key) {
+ case "1":
+ setUpdater(handler_health);
+ break;
+ case "2":
+ setUpdater(handler_uplinks);
+ break;
+ case "3":
+ setUpdater(handler_dhcp);
+ break;
+ case "4":
+ setUpdater(handler_ping);
+ break;
+ case "5":
+ setUpdater(handler_temp);
+ break;
+ case "6":
+ setUpdater(handler_traffic);
+ break;
+ case "7":
+ setUpdater(handler_traffic_tot);
+ break;
+ case "8":
+ setUpdater(handler_snmp);
+ break;
+ case "9":
+ setUpdater(handler_cpu);
+ break;
+ case "0":
+ setUpdater(handler_disco);
+ break;
+ }
+ return true;
+}
+
+function moveTimeFromKey(e, key) {
+ switch (key) {
+ case "H":
+ nmsTime.stepKey(-1440);
+ break;
+ case "h":
+ nmsTime.stepKey(-60);
+ break;
+ case "j":
+ nmsTime.stepKey(-5);
+ break;
+ case "k":
+ nmsTime.stepKey(5);
+ break;
+ case "l":
+ nmsTime.stepKey(60);
+ break;
+ case "L":
+ nmsTime.stepKey(1440);
+ break;
+ case "p":
+ nmsTime.togglePause();
+ break;
+ case "r":
+ nmsTime.realTime();
+ break;
+ }
+ return true;
+}
+
+function keyPressed(e) {
+ if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") {
+ return false;
+ }
+ if (e.key) {
+ var key = e.key;
+ } else {
+ var key = e.keyCode;
+ switch (key) {
+ case 187:
+ key = "?";
+ break;
+ case 189:
+ key = "-";
+ break;
+ case 27:
+ key = "Escape";
+ break;
+ default:
+ key = String.fromCharCode(key);
+ key = key.toLowerCase();
+ break;
+ }
+ }
+ if (nms.keyBindings[key]) return nms.keyBindings[key](e, key);
+ if (nms.keyBindings["default"]) return nms.keyBindings["default"](e, key);
+ return false;
+}
+
+function setupKeyhandler() {
+ document.addEventListener("keydown", (event) => keyPressed(event), false);
}
-
function getCookie(cname) {
- var name = cname + "=";
- var ca = document.cookie.split(';');
- for(var i=0; i<ca.length; i++) {
- var c = ca[i];
- while (c.charAt(0)==' ')
- c = c.substring(1);
- if (c.indexOf(name) == 0)
- return c.substring(name.length,c.length);
- }
- return "";
+ var name = cname + "=";
+ var ca = document.cookie.split(";");
+ for (var i = 0; i < ca.length; i++) {
+ var c = ca[i];
+ while (c.charAt(0) == " ") c = c.substring(1);
+ if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
+ }
+ return "";
}
/*
@@ -606,15 +597,14 @@ function getCookie(cname) {
* Also prints the value of the cookie on the console. This can then be
* used as part of the URL instead.
*/
-function saveSettings()
-{
- var foo={};
- for ( var v in nms.settingsList ) {
- foo[ nms.settingsList[v] ] = nms[ nms.settingsList[v] ];
- }
- var string = btoa(JSON.stringify(foo));
- document.cookie = 'nms='+string;
- console.log("Add this to the URL to use these settings: nms="+string);
+function saveSettings() {
+ var foo = {};
+ for (var v in nms.settingsList) {
+ foo[nms.settingsList[v]] = nms[nms.settingsList[v]];
+ }
+ var string = btoa(JSON.stringify(foo));
+ document.cookie = 'nms='+string;
+ //console.log("Add this to the URL to use these settings: nms="+string);
}
/*
@@ -622,44 +612,25 @@ function saveSettings()
* paramater" nms.
* Url paramater overrides the cookie.
*/
-function restoreSettings()
-{
- try {
- var retrieve = JSON.parse(atob(getCookie("nms")));
- } catch(e) {
- }
- try {
- var retrieve2 = getUrlVars()['nms'];
- if (retrieve2 != "") {
- retrieve = JSON.parse(atob(retrieve2));
-
- }
- } catch (e) {
- }
-
- for (var v in retrieve) {
- nms[v] = retrieve[v];
- }
- setMenu();
- setOplog();
+function restoreSettings() {
+ try {
+ var retrieve = JSON.parse(atob(getCookie("nms")));
+ } catch (e) {}
+ try {
+ var retrieve2 = getUrlVars()["nms"];
+ if (retrieve2 != "") {
+ retrieve = JSON.parse(atob(retrieve2));
+ }
+ } catch (e) {}
+
+ for (var v in retrieve) {
+ nms[v] = retrieve[v];
+ }
+ setMenu();
+ setOplog();
}
/*
- * Updates a simple legend-free graph, located on the navbar.
- *
- * The idea is to give a general "feeling" of the event. And that it's
- * neat.
- *
- * The timer-thing to bust a cache divides by 10 seconds, so updating more
- * than once every 10 seconds is pointless.
- */
-function nmsUpdateNavbarGraph() {
- var img = document.getElementById("navbar-graph");
- var w = 200;
-
- img.src = "/render/?target=movingAverage(averageSeries(ping.*.*.ipv4),%225min%22)&target=secondYAxis(averageSeries(perSecond(snmp.*.*.ports.*.{ifHCInOctets,ifHCOutOctets})))&bgcolor=%23ffffff00&width=" + w + "&height=20&format=svg&from=-30min&until=now&graphOnly=true";
-}
-/*
* Test if the entire path specified in the arrary "ar" exists under the
* specified root.
*
@@ -673,20 +644,18 @@ function nmsUpdateNavbarGraph() {
* or the provided default.
*/
function setTree(root, ar, def) {
- if (ar == undefined || root == undefined) {
- return def;
- } else {
- for (var i in ar) {
- root = root[ar[i]];
- if (root == undefined)
- return def;
- }
- }
- return root;
+ if (ar == undefined || root == undefined) {
+ return def;
+ } else {
+ for (var i in ar) {
+ root = root[ar[i]];
+ if (root == undefined) return def;
+ }
+ }
+ return root;
}
+
function testTree(root, ar) {
- var x = setTree(root,ar,false);
- if (x != false)
- return true;
+ var x = setTree(root, ar, false);
+ if (x != false) return true;
}
-
diff --git a/web/js/npm.js b/web/js/npm.js
deleted file mode 100644
index bf6aa80..0000000
--- a/web/js/npm.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
-require('../../js/transition.js')
-require('../../js/alert.js')
-require('../../js/button.js')
-require('../../js/carousel.js')
-require('../../js/collapse.js')
-require('../../js/dropdown.js')
-require('../../js/modal.js')
-require('../../js/tooltip.js')
-require('../../js/popover.js')
-require('../../js/scrollspy.js')
-require('../../js/tab.js')
-require('../../js/affix.js') \ No newline at end of file