You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by pv...@apache.org on 2018/10/04 16:45:39 UTC

[1/2] hive git commit: HIVE-17300: WebUI query plan graphs (Karen Coppage, reviewed by Szehon Ho and Peter Vary)

Repository: hive
Updated Branches:
  refs/heads/master 6c34a3742 -> 1cfe4f913


http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/service/src/resources/hive-webapps/static/js/vis.min.js
----------------------------------------------------------------------
diff --git a/service/src/resources/hive-webapps/static/js/vis.min.js b/service/src/resources/hive-webapps/static/js/vis.min.js
new file mode 100644
index 0000000..09730da
--- /dev/null
+++ b/service/src/resources/hive-webapps/static/js/vis.min.js
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * vis.js
+ * https://github.com/almende/vis
+ *
+ * A dynamic, browser-based visualization library.
+ *
+ * @version 4.20.0
+ * @date    2017-05-21
+ *
+ * @license
+ * Copyright (C) 2011-2017 Almende B.V, http://almende.com
+ *
+ * Vis.js is dual licensed under both
+ *
+ * * The Apache 2.0 License
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * and
+ *
+ * * The MIT License
+ *   http://opensource.org/licenses/MIT
+ *
+ * Vis.js may be distributed under either license.
+ */
+"use strict";!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.vis=e():t.vis=e()}(this,function(){return function(t){function e(o){if(i[o])return i[o].exports;var n=i[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){var o=i(1);o.extend(e,i(87)),o.extend(e,i(116)),o.extend(e,i(158))},function(t,e,i){function o(t){return t&&t.__esModule?t:{default:t}}var n=i(2),s=o(n),r=i(55),a=o(r),h=i(58),d=o(h),l=i(62),u=o(l),c=i(82),p=i(86);e.isNumber=function(t){return t instanceof Number||"number"==typeof t},e.recursiveDOMDelete=function(t){if(t)for(;!0===t.hasChildNodes();)e.recursiveDOMDelete(t.firstChild),t.removeChild(t.firstChild)},e.giveRange=function(t,e,i,o){if(e==t)return.5;var n=1/(e-t);return Math.max(0,(o-t)*n)},e.isString=function(t){return t instanceof String||"st
 ring"==typeof t},e.isDate=function(t){if(t instanceof Date)return!0;if(e.isString(t)){if(f.exec(t))return!0;if(!isNaN(Date.parse(t)))return!0}return!1},e.randomUUID=function(){return p.v4()},e.assignAllKeys=function(t,e){for(var i in t)t.hasOwnProperty(i)&&"object"!==(0,u.default)(t[i])&&(t[i]=e)},e.fillIfDefined=function(t,i){var o=arguments.length>2&&void 0!==arguments[2]&&arguments[2];for(var n in t)void 0!==i[n]&&("object"!==(0,u.default)(i[n])?void 0!==i[n]&&null!==i[n]||void 0===t[n]||!0!==o?t[n]=i[n]:delete t[n]:"object"===(0,u.default)(t[n])&&e.fillIfDefined(t[n],i[n],o))},e.protoExtend=function(t,e){for(var i=1;i<arguments.length;i++){var o=arguments[i];for(var n in o)t[n]=o[n]}return t},e.extend=function(t,e){for(var i=1;i<arguments.length;i++){var o=arguments[i];for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])}return t},e.selectiveExtend=function(t,e,i){if(!Array.isArray(t))throw new Error("Array with property names expected as first argument");for(var o=2;o<arguments.leng
 th;o++)for(var n=arguments[o],s=0;s<t.length;s++){var r=t[s];n&&n.hasOwnProperty(r)&&(e[r]=n[r])}return e},e.selectiveDeepExtend=function(t,i,o){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(Array.isArray(o))throw new TypeError("Arrays are not supported by deepExtend");for(var s=2;s<arguments.length;s++)for(var r=arguments[s],a=0;a<t.length;a++){var h=t[a];if(r.hasOwnProperty(h))if(o[h]&&o[h].constructor===Object)void 0===i[h]&&(i[h]={}),i[h].constructor===Object?e.deepExtend(i[h],o[h],!1,n):null===o[h]&&void 0!==i[h]&&!0===n?delete i[h]:i[h]=o[h];else{if(Array.isArray(o[h]))throw new TypeError("Arrays are not supported by deepExtend");null===o[h]&&void 0!==i[h]&&!0===n?delete i[h]:i[h]=o[h]}}return i},e.selectiveNotDeepExtend=function(t,i,o){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(Array.isArray(o))throw new TypeError("Arrays are not supported by deepExtend");for(var s in o)if(o.hasOwnProperty(s)&&-1==t.indexOf(s))if(o[s]&&o[s].constructor
 ===Object)void 0===i[s]&&(i[s]={}),i[s].constructor===Object?e.deepExtend(i[s],o[s]):null===o[s]&&void 0!==i[s]&&!0===n?delete i[s]:i[s]=o[s];else if(Array.isArray(o[s])){i[s]=[];for(var r=0;r<o[s].length;r++)i[s].push(o[s][r])}else null===o[s]&&void 0!==i[s]&&!0===n?delete i[s]:i[s]=o[s];return i},e.deepExtend=function(t,i,o,n){for(var s in i)if(i.hasOwnProperty(s)||!0===o)if(i[s]&&i[s].constructor===Object)void 0===t[s]&&(t[s]={}),t[s].constructor===Object?e.deepExtend(t[s],i[s],o):null===i[s]&&void 0!==t[s]&&!0===n?delete t[s]:t[s]=i[s];else if(Array.isArray(i[s])){t[s]=[];for(var r=0;r<i[s].length;r++)t[s].push(i[s][r])}else null===i[s]&&void 0!==t[s]&&!0===n?delete t[s]:t[s]=i[s];return t},e.equalArray=function(t,e){if(t.length!=e.length)return!1;for(var i=0,o=t.length;i<o;i++)if(t[i]!=e[i])return!1;return!0},e.convert=function(t,i){var o;if(void 0!==t){if(null===t)return null;if(!i)return t;if("string"!=typeof i&&!(i instanceof String))throw new Error("Type must be a string");
 switch(i){case"boolean":case"Boolean":return Boolean(t);case"number":case"Number":return e.isString(t)&&!isNaN(Date.parse(t))?c(t).valueOf():Number(t.valueOf());case"string":case"String":return String(t);case"Date":if(e.isNumber(t))return new Date(t);if(t instanceof Date)return new Date(t.valueOf());if(c.isMoment(t))return new Date(t.valueOf());if(e.isString(t))return o=f.exec(t),o?new Date(Number(o[1])):c(new Date(t)).toDate();throw new Error("Cannot convert object of type "+e.getType(t)+" to type Date");case"Moment":if(e.isNumber(t))return c(t);if(t instanceof Date)return c(t.valueOf());if(c.isMoment(t))return c(t);if(e.isString(t))return o=f.exec(t),c(o?Number(o[1]):t);throw new Error("Cannot convert object of type "+e.getType(t)+" to type Date");case"ISODate":if(e.isNumber(t))return new Date(t);if(t instanceof Date)return t.toISOString();if(c.isMoment(t))return t.toDate().toISOString();if(e.isString(t))return o=f.exec(t),o?new Date(Number(o[1])).toISOString():c(t).format();throw
  new Error("Cannot convert object of type "+e.getType(t)+" to type ISODate");case"ASPDate":if(e.isNumber(t))return"/Date("+t+")/";if(t instanceof Date)return"/Date("+t.valueOf()+")/";if(e.isString(t)){o=f.exec(t);return"/Date("+(o?new Date(Number(o[1])).valueOf():new Date(t).valueOf())+")/"}throw new Error("Cannot convert object of type "+e.getType(t)+" to type ASPDate");default:throw new Error('Unknown type "'+i+'"')}}};var f=/^\/?Date\((\-?\d+)/i;e.getType=function(t){var e=void 0===t?"undefined":(0,u.default)(t);return"object"==e?null===t?"null":t instanceof Boolean?"Boolean":t instanceof Number?"Number":t instanceof String?"String":Array.isArray(t)?"Array":t instanceof Date?"Date":"Object":"number"==e?"Number":"boolean"==e?"Boolean":"string"==e?"String":void 0===e?"undefined":e},e.copyAndExtendArray=function(t,e){for(var i=[],o=0;o<t.length;o++)i.push(t[o]);return i.push(e),i},e.copyArray=function(t){for(var e=[],i=0;i<t.length;i++)e.push(t[i]);return e},e.getAbsoluteLeft=functi
 on(t){return t.getBoundingClientRect().left},e.getAbsoluteRight=function(t){return t.getBoundingClientRect().right},e.getAbsoluteTop=function(t){return t.getBoundingClientRect().top},e.addClassName=function(t,e){var i=t.className.split(" "),o=e.split(" ");i=i.concat(o.filter(function(t){return i.indexOf(t)<0})),t.className=i.join(" ")},e.removeClassName=function(t,e){var i=t.className.split(" "),o=e.split(" ");i=i.filter(function(t){return o.indexOf(t)<0}),t.className=i.join(" ")},e.forEach=function(t,e){var i,o;if(Array.isArray(t))for(i=0,o=t.length;i<o;i++)e(t[i],i,t);else for(i in t)t.hasOwnProperty(i)&&e(t[i],i,t)},e.toArray=function(t){var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(t[i]);return e},e.updateProperty=function(t,e,i){return t[e]!==i&&(t[e]=i,!0)},e.throttle=function(t){var e=!1;return function(){e||(e=!0,requestAnimationFrame(function(){e=!1,t()}))}},e.addEventListener=function(t,e,i,o){t.addEventListener?(void 0===o&&(o=!1),"mousewheel"===e&&navigator.userAge
 nt.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.addEventListener(e,i,o)):t.attachEvent("on"+e,i)},e.removeEventListener=function(t,e,i,o){t.removeEventListener?(void 0===o&&(o=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.removeEventListener(e,i,o)):t.detachEvent("on"+e,i)},e.preventDefault=function(t){t||(t=window.event),t.preventDefault?t.preventDefault():t.returnValue=!1},e.getTarget=function(t){t||(t=window.event);var e;return t.target?e=t.target:t.srcElement&&(e=t.srcElement),void 0!=e.nodeType&&3==e.nodeType&&(e=e.parentNode),e},e.hasParent=function(t,e){for(var i=t;i;){if(i===e)return!0;i=i.parentNode}return!1},e.option={},e.option.asBoolean=function(t,e){return"function"==typeof t&&(t=t()),null!=t?0!=t:e||null},e.option.asNumber=function(t,e){return"function"==typeof t&&(t=t()),null!=t?Number(t)||e||null:e||null},e.option.asString=function(t,e){return"function"==typeof t&&(t=t()),null!=t?String(t):e||null},e.option.asSize=function(t
 ,i){return"function"==typeof t&&(t=t()),e.isString(t)?t:e.isNumber(t)?t+"px":i||null},e.option.asElement=function(t,e){return"function"==typeof t&&(t=t()),t||e||null},e.hexToRGB=function(t){var e=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(e,function(t,e,i,o){return e+e+i+i+o+o});var i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return i?{r:parseInt(i[1],16),g:parseInt(i[2],16),b:parseInt(i[3],16)}:null},e.overrideOpacity=function(t,i){if(-1!=t.indexOf("rgba"))return t;if(-1!=t.indexOf("rgb")){var o=t.substr(t.indexOf("(")+1).replace(")","").split(",");return"rgba("+o[0]+","+o[1]+","+o[2]+","+i+")"}var o=e.hexToRGB(t);return null==o?t:"rgba("+o.r+","+o.g+","+o.b+","+i+")"},e.RGBToHex=function(t,e,i){return"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1)},e.parseColor=function(t){var i;if(!0===e.isString(t)){if(!0===e.isValidRGB(t)){var o=t.substr(4).substr(0,t.length-5).split(",").map(function(t){return parseInt(t)});t=e.RGBToHex(o[0],o[1],o[2])}if(!0===e.isValidHex(t
 )){var n=e.hexToHSV(t),s={h:n.h,s:.8*n.s,v:Math.min(1,1.02*n.v)},r={h:n.h,s:Math.min(1,1.25*n.s),v:.8*n.v},a=e.HSVToHex(r.h,r.s,r.v),h=e.HSVToHex(s.h,s.s,s.v);i={background:t,border:a,highlight:{background:h,border:a},hover:{background:h,border:a}}}else i={background:t,border:t,highlight:{background:t,border:t},hover:{background:t,border:t}}}else i={},i.background=t.background||void 0,i.border=t.border||void 0,e.isString(t.highlight)?i.highlight={border:t.highlight,background:t.highlight}:(i.highlight={},i.highlight.background=t.highlight&&t.highlight.background||void 0,i.highlight.border=t.highlight&&t.highlight.border||void 0),e.isString(t.hover)?i.hover={border:t.hover,background:t.hover}:(i.hover={},i.hover.background=t.hover&&t.hover.background||void 0,i.hover.border=t.hover&&t.hover.border||void 0);return i},e.RGBToHSV=function(t,e,i){t/=255,e/=255,i/=255;var o=Math.min(t,Math.min(e,i)),n=Math.max(t,Math.max(e,i));if(o==n)return{h:0,s:0,v:o};var s=t==o?e-i:i==o?t-e:i-t;return{
 h:60*((t==o?3:i==o?1:5)-s/(n-o))/360,s:(n-o)/n,v:n}};var m={split:function(t){var e={};return t.split(";").forEach(function(t){if(""!=t.trim()){var i=t.split(":"),o=i[0].trim(),n=i[1].trim();e[o]=n}}),e},join:function(t){return(0,d.default)(t).map(function(e){return e+": "+t[e]}).join("; ")}};e.addCssText=function(t,i){var o=m.split(t.style.cssText),n=m.split(i),s=e.extend(o,n);t.style.cssText=m.join(s)},e.removeCssText=function(t,e){var i=m.split(t.style.cssText),o=m.split(e);for(var n in o)o.hasOwnProperty(n)&&delete i[n];t.style.cssText=m.join(i)},e.HSVToRGB=function(t,e,i){var o,n,s,r=Math.floor(6*t),a=6*t-r,h=i*(1-e),d=i*(1-a*e),l=i*(1-(1-a)*e);switch(r%6){case 0:o=i,n=l,s=h;break;case 1:o=d,n=i,s=h;break;case 2:o=h,n=i,s=l;break;case 3:o=h,n=d,s=i;break;case 4:o=l,n=h,s=i;break;case 5:o=i,n=h,s=d}return{r:Math.floor(255*o),g:Math.floor(255*n),b:Math.floor(255*s)}},e.HSVToHex=function(t,i,o){var n=e.HSVToRGB(t,i,o);return e.RGBToHex(n.r,n.g,n.b)},e.hexToHSV=function(t){var i=e.
 hexToRGB(t);return e.RGBToHSV(i.r,i.g,i.b)},e.isValidHex=function(t){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(t)},e.isValidRGB=function(t){return t=t.replace(" ",""),/rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(t)},e.isValidRGBA=function(t){return t=t.replace(" ",""),/rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(.{1,3})\)/i.test(t)},e.selectiveBridgeObject=function(t,i){if("object"==(void 0===i?"undefined":(0,u.default)(i))){for(var o=(0,a.default)(i),n=0;n<t.length;n++)i.hasOwnProperty(t[n])&&"object"==(0,u.default)(i[t[n]])&&(o[t[n]]=e.bridgeObject(i[t[n]]));return o}return null},e.bridgeObject=function(t){if("object"==(void 0===t?"undefined":(0,u.default)(t))){var i=(0,a.default)(t);for(var o in t)t.hasOwnProperty(o)&&"object"==(0,u.default)(t[o])&&(i[o]=e.bridgeObject(t[o]));return i}return null},e.insertSort=function(t,e){for(var i=0;i<t.length;i++){for(var o=t[i],n=i;n>0&&e(o,t[n-1])<0;n--)t[n]=t[n-1];t[n]=o}return t},e.mergeOptions=function(t,e,i){var o=(arguments.length>3&&vo
 id 0!==arguments[3]&&arguments[3],arguments.length>4&&void 0!==arguments[4]?arguments[4]:{});if(null===e[i])t[i]=(0,a.default)(o[i]);else if(void 0!==e[i])if("boolean"==typeof e[i])t[i].enabled=e[i];else{void 0===e[i].enabled&&(t[i].enabled=!0);for(var n in e[i])e[i].hasOwnProperty(n)&&(t[i][n]=e[i][n])}},e.binarySearchCustom=function(t,e,i,o){for(var n=0,s=0,r=t.length-1;s<=r&&n<1e4;){var a=Math.floor((s+r)/2),h=t[a],d=void 0===o?h[i]:h[i][o],l=e(d);if(0==l)return a;-1==l?s=a+1:r=a-1,n++}return-1},e.binarySearchValue=function(t,e,i,o,n){for(var s,r,a,h,d=0,l=0,u=t.length-1,n=void 0!=n?n:function(t,e){return t==e?0:t<e?-1:1};l<=u&&d<1e4;){if(h=Math.floor(.5*(u+l)),s=t[Math.max(0,h-1)][i],r=t[h][i],a=t[Math.min(t.length-1,h+1)][i],0==n(r,e))return h;if(n(s,e)<0&&n(r,e)>0)return"before"==o?Math.max(0,h-1):h;if(n(r,e)<0&&n(a,e)>0)return"before"==o?h:Math.min(t.length-1,h+1);n(r,e)<0?l=h+1:u=h-1,d++}return-1},e.easingFunctions={linear:function(t){return t},easeInQuad:function(t){return 
 t*t},easeOutQuad:function(t){return t*(2-t)},easeInOutQuad:function(t){return t<.5?2*t*t:(4-2*t)*t-1},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return--t*t*t+1},easeInOutCubic:function(t){return t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return 1- --t*t*t*t},easeInOutQuart:function(t){return t<.5?8*t*t*t*t:1-8*--t*t*t*t},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return 1+--t*t*t*t*t},easeInOutQuint:function(t){return t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t}},e.getScrollBarWidth=function(){var t=document.createElement("p");t.style.width="100%",t.style.height="200px";var e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.left="0px",e.style.visibility="hidden",e.style.width="200px",e.style.height="150px",e.style.overflow="hidden",e.appendChild(t),document.body.appendChild(e);var i=t.offsetWidth;e.style.overflow="scroll";var o=t.offsetWidth;return i==o&
 &(o=e.clientWidth),document.body.removeChild(e),i-o},e.topMost=function(t,e){var i=void 0;Array.isArray(e)||(e=[e]);var o=!0,n=!1,r=void 0;try{for(var a,h=(0,s.default)(t);!(o=(a=h.next()).done);o=!0){var d=a.value;if(d){i=d[e[0]];for(var l=1;l<e.length;l++)i&&(i=i[e[l]]);if(void 0!==i)break}}}catch(t){n=!0,r=t}finally{try{!o&&h.return&&h.return()}finally{if(n)throw r}}return i}},function(t,e,i){t.exports={default:i(3),__esModule:!0}},function(t,e,i){i(4),i(50),t.exports=i(52)},function(t,e,i){i(5);for(var o=i(16),n=i(20),s=i(8),r=i(47)("toStringTag"),a=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],h=0;h<5;h++){var d=a[h],l=o[d],u=l&&l.prototype;u&&!u[r]&&n(u,r,d),s[d]=s.Array}},function(t,e,i){var o=i(6),n=i(7),s=i(8),r=i(9);t.exports=i(13)(Array,"Array",function(t,e){this._t=r(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,i=this._i++;return!t||i>=t.length?(this._t=void 0,n(1)):"keys"==e?n(0,i):"values"==e?n(0,t[i]):n(0,[i,t[i]])},"values"),s.A
 rguments=s.Array,o("keys"),o("values"),o("entries")},function(t,e){t.exports=function(){}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e){t.exports={}},function(t,e,i){var o=i(10),n=i(12);t.exports=function(t){return o(n(t))}},function(t,e,i){var o=i(11);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==o(t)?t.split(""):Object(t)}},function(t,e){var i={}.toString;t.exports=function(t){return i.call(t).slice(8,-1)}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on  "+t);return t}},function(t,e,i){var o=i(14),n=i(15),s=i(30),r=i(20),a=i(31),h=i(8),d=i(32),l=i(46),u=i(48),c=i(47)("iterator"),p=!([].keys&&"next"in[].keys()),f=function(){return this};t.exports=function(t,e,i,m,v,g,y){d(i,e,m);var b,_,w,x=function(t){if(!p&&t in D)return D[t];switch(t){case"keys":case"values":return function(){return new i(this,t)}}return function(){return new i(this,t)}},k=e+" Iterator",M="values"==v,S=!1
 ,D=t.prototype,O=D[c]||D["@@iterator"]||v&&D[v],C=O||x(v),T=v?M?x("entries"):C:void 0,E="Array"==e?D.entries||O:O;if(E&&(w=u(E.call(new t)))!==Object.prototype&&(l(w,k,!0),o||a(w,c)||r(w,c,f)),M&&O&&"values"!==O.name&&(S=!0,C=function(){return O.call(this)}),o&&!y||!p&&!S&&D[c]||r(D,c,C),h[e]=C,h[k]=f,v)if(b={values:M?C:x("values"),keys:g?C:x("keys"),entries:T},y)for(_ in b)_ in D||s(D,_,b[_]);else n(n.P+n.F*(p||S),e,b);return b}},function(t,e){t.exports=!0},function(t,e,i){var o=i(16),n=i(17),s=i(18),r=i(20),a=function(t,e,i){var h,d,l,u=t&a.F,c=t&a.G,p=t&a.S,f=t&a.P,m=t&a.B,v=t&a.W,g=c?n:n[e]||(n[e]={}),y=g.prototype,b=c?o:p?o[e]:(o[e]||{}).prototype;c&&(i=e);for(h in i)(d=!u&&b&&void 0!==b[h])&&h in g||(l=d?b[h]:i[h],g[h]=c&&"function"!=typeof b[h]?i[h]:m&&d?s(l,o):v&&b[h]==l?function(t){var e=function(e,i,o){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,i)}return new t(e,i,o)}return t.apply(this,arguments)};return
  e.prototype=t.prototype,e}(l):f&&"function"==typeof l?s(Function.call,l):l,f&&((g.virtual||(g.virtual={}))[h]=l,t&a.R&&y&&!y[h]&&r(y,h,l)))};a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},function(t,e){var i=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(t,e){var i=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=i)},function(t,e,i){var o=i(19);t.exports=function(t,e,i){if(o(t),void 0===e)return t;switch(i){case 1:return function(i){return t.call(e,i)};case 2:return function(i,o){return t.call(e,i,o)};case 3:return function(i,o,n){return t.call(e,i,o,n)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,i){var o=i(21),n=i(29);t.exports=i(25)?function(t,e,i){return o.f(t,e,n(1,i))}:function(t,e,i){return t[e]=
 i,t}},function(t,e,i){var o=i(22),n=i(24),s=i(28),r=Object.defineProperty;e.f=i(25)?Object.defineProperty:function(t,e,i){if(o(t),e=s(e,!0),o(i),n)try{return r(t,e,i)}catch(t){}if("get"in i||"set"in i)throw TypeError("Accessors not supported!");return"value"in i&&(t[e]=i.value),t}},function(t,e,i){var o=i(23);t.exports=function(t){if(!o(t))throw TypeError(t+" is not an object!");return t}},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,i){t.exports=!i(25)&&!i(26)(function(){return 7!=Object.defineProperty(i(27)("div"),"a",{get:function(){return 7}}).a})},function(t,e,i){t.exports=!i(26)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,i){var o=i(23),n=i(16).document,s=o(n)&&o(n.createElement);t.exports=function(t){return s?n.createElement(t):{}}},function(t,e,i){var o=i(23);t.exports=function(t,e){if(!o(t))
 return t;var i,n;if(e&&"function"==typeof(i=t.toString)&&!o(n=i.call(t)))return n;if("function"==typeof(i=t.valueOf)&&!o(n=i.call(t)))return n;if(!e&&"function"==typeof(i=t.toString)&&!o(n=i.call(t)))return n;throw TypeError("Can't convert object to primitive value")}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,i){t.exports=i(20)},function(t,e){var i={}.hasOwnProperty;t.exports=function(t,e){return i.call(t,e)}},function(t,e,i){var o=i(33),n=i(29),s=i(46),r={};i(20)(r,i(47)("iterator"),function(){return this}),t.exports=function(t,e,i){t.prototype=o(r,{next:n(1,i)}),s(t,e+" Iterator")}},function(t,e,i){var o=i(22),n=i(34),s=i(44),r=i(41)("IE_PROTO"),a=function(){},h=function(){var t,e=i(27)("iframe"),o=s.length;for(e.style.display="none",i(45).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("<script>document.F=Object<\/script>"),t.close(),h=t.F;o--;)delete h.prototype[s[o]]
 ;return h()};t.exports=Object.create||function(t,e){var i;return null!==t?(a.prototype=o(t),i=new a,a.prototype=null,i[r]=t):i=h(),void 0===e?i:n(i,e)}},function(t,e,i){var o=i(21),n=i(22),s=i(35);t.exports=i(25)?Object.defineProperties:function(t,e){n(t);for(var i,r=s(e),a=r.length,h=0;a>h;)o.f(t,i=r[h++],e[i]);return t}},function(t,e,i){var o=i(36),n=i(44);t.exports=Object.keys||function(t){return o(t,n)}},function(t,e,i){var o=i(31),n=i(9),s=i(37)(!1),r=i(41)("IE_PROTO");t.exports=function(t,e){var i,a=n(t),h=0,d=[];for(i in a)i!=r&&o(a,i)&&d.push(i);for(;e.length>h;)o(a,i=e[h++])&&(~s(d,i)||d.push(i));return d}},function(t,e,i){var o=i(9),n=i(38),s=i(40);t.exports=function(t){return function(e,i,r){var a,h=o(e),d=n(h.length),l=s(r,d);if(t&&i!=i){for(;d>l;)if((a=h[l++])!=a)return!0}else for(;d>l;l++)if((t||l in h)&&h[l]===i)return t||l||0;return!t&&-1}}},function(t,e,i){var o=i(39),n=Math.min;t.exports=function(t){return t>0?n(o(t),9007199254740991):0}},function(t,e){var i=Math.c
 eil,o=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?o:i)(t)}},function(t,e,i){var o=i(39),n=Math.max,s=Math.min;t.exports=function(t,e){return t=o(t),t<0?n(t+e,0):s(t,e)}},function(t,e,i){var o=i(42)("keys"),n=i(43);t.exports=function(t){return o[t]||(o[t]=n(t))}},function(t,e,i){var o=i(16),n=o["__core-js_shared__"]||(o["__core-js_shared__"]={});t.exports=function(t){return n[t]||(n[t]={})}},function(t,e){var i=0,o=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++i+o).toString(36))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,i){t.exports=i(16).document&&document.documentElement},function(t,e,i){var o=i(21).f,n=i(31),s=i(47)("toStringTag");t.exports=function(t,e,i){t&&!n(t=i?t:t.prototype,s)&&o(t,s,{configurable:!0,value:e})}},function(t,e,i){var o=i(42)("wks"),n=i(43),s=i(16).Symbol,r="function"==typeof s;(t.exports=function(t){return
  o[t]||(o[t]=r&&s[t]||(r?s:n)("Symbol."+t))}).store=o},function(t,e,i){var o=i(31),n=i(49),s=i(41)("IE_PROTO"),r=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=n(t),o(t,s)?t[s]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?r:null}},function(t,e,i){var o=i(12);t.exports=function(t){return Object(o(t))}},function(t,e,i){var o=i(51)(!0);i(13)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,i=this._i;return i>=e.length?{value:void 0,done:!0}:(t=o(e,i),this._i+=t.length,{value:t,done:!1})})},function(t,e,i){var o=i(39),n=i(12);t.exports=function(t){return function(e,i){var s,r,a=String(n(e)),h=o(i),d=a.length;return h<0||h>=d?t?"":void 0:(s=a.charCodeAt(h),s<55296||s>56319||h+1===d||(r=a.charCodeAt(h+1))<56320||r>57343?t?a.charAt(h):s:t?a.slice(h,h+2):r-56320+(s-55296<<10)+65536)}}},function(t,e,i){var o=i(22),n=i(53);t.exports=i(17).getIterator=function(t){var e=n(t);if
 ("function"!=typeof e)throw TypeError(t+" is not iterable!");return o(e.call(t))}},function(t,e,i){var o=i(54),n=i(47)("iterator"),s=i(8);t.exports=i(17).getIteratorMethod=function(t){if(void 0!=t)return t[n]||t["@@iterator"]||s[o(t)]}},function(t,e,i){var o=i(11),n=i(47)("toStringTag"),s="Arguments"==o(function(){return arguments}()),r=function(t,e){try{return t[e]}catch(t){}};t.exports=function(t){var e,i,a;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(i=r(e=Object(t),n))?i:s?o(e):"Object"==(a=o(e))&&"function"==typeof e.callee?"Arguments":a}},function(t,e,i){t.exports={default:i(56),__esModule:!0}},function(t,e,i){i(57);var o=i(17).Object;t.exports=function(t,e){return o.create(t,e)}},function(t,e,i){var o=i(15);o(o.S,"Object",{create:i(33)})},function(t,e,i){t.exports={default:i(59),__esModule:!0}},function(t,e,i){i(60),t.exports=i(17).Object.keys},function(t,e,i){var o=i(49),n=i(35);i(61)("keys",function(){return function(t){return n(o(t))}})},function(t,e,i){v
 ar o=i(15),n=i(17),s=i(26);t.exports=function(t,e){var i=(n.Object||{})[t]||Object[t],r={};r[t]=e(i),o(o.S+o.F*s(function(){i(1)}),"Object",r)}},function(t,e,i){function o(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var n=i(63),s=o(n),r=i(66),a=o(r),h="function"==typeof a.default&&"symbol"==typeof s.default?function(t){return typeof t}:function(t){return t&&"function"==typeof a.default&&t.constructor===a.default&&t!==a.default.prototype?"symbol":typeof t};e.default="function"==typeof a.default&&"symbol"===h(s.default)?function(t){return void 0===t?"undefined":h(t)}:function(t){return t&&"function"==typeof a.default&&t.constructor===a.default&&t!==a.default.prototype?"symbol":void 0===t?"undefined":h(t)}},function(t,e,i){t.exports={default:i(64),__esModule:!0}},function(t,e,i){i(50),i(4),t.exports=i(65).f("iterator")},function(t,e,i){e.f=i(47)},function(t,e,i){t.exports={default:i(67),__esModule:!0}},function(t,e,i){i(68),i(79),i(80),i(81),t.exports=i(17).Symbol},function
 (t,e,i){var o=i(16),n=i(31),s=i(25),r=i(15),a=i(30),h=i(69).KEY,d=i(26),l=i(42),u=i(46),c=i(43),p=i(47),f=i(65),m=i(70),v=i(71),g=i(72),y=i(75),b=i(22),_=i(9),w=i(28),x=i(29),k=i(33),M=i(76),S=i(78),D=i(21),O=i(35),C=S.f,T=D.f,E=M.f,P=o.Symbol,I=o.JSON,N=I&&I.stringify,R=p("_hidden"),A=p("toPrimitive"),z={}.propertyIsEnumerable,L=l("symbol-registry"),F=l("symbols"),B=l("op-symbols"),j=Object.prototype,H="function"==typeof P,W=o.QObject,Y=!W||!W.prototype||!W.prototype.findChild,G=s&&d(function(){return 7!=k(T({},"a",{get:function(){return T(this,"a",{value:7}).a}})).a})?function(t,e,i){var o=C(j,e);o&&delete j[e],T(t,e,i),o&&t!==j&&T(j,e,o)}:T,V=function(t){var e=F[t]=k(P.prototype);return e._k=t,e},U=H&&"symbol"==typeof P.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof P},q=function(t,e,i){return t===j&&q(B,e,i),b(t),e=w(e,!0),b(i),n(F,e)?(i.enumerable?(n(t,R)&&t[R][e]&&(t[R][e]=!1),i=k(i,{enumerable:x(0,!1)})):(n(t,R)||T(t,R,x(1,{})),t[R][e]=!0),G(t,
 e,i)):T(t,e,i)},X=function(t,e){b(t);for(var i,o=g(e=_(e)),n=0,s=o.length;s>n;)q(t,i=o[n++],e[i]);return t},Z=function(t,e){return void 0===e?k(t):X(k(t),e)},K=function(t){var e=z.call(this,t=w(t,!0));return!(this===j&&n(F,t)&&!n(B,t))&&(!(e||!n(this,t)||!n(F,t)||n(this,R)&&this[R][t])||e)},J=function(t,e){if(t=_(t),e=w(e,!0),t!==j||!n(F,e)||n(B,e)){var i=C(t,e);return!i||!n(F,e)||n(t,R)&&t[R][e]||(i.enumerable=!0),i}},Q=function(t){for(var e,i=E(_(t)),o=[],s=0;i.length>s;)n(F,e=i[s++])||e==R||e==h||o.push(e);return o},$=function(t){for(var e,i=t===j,o=E(i?B:_(t)),s=[],r=0;o.length>r;)!n(F,e=o[r++])||i&&!n(j,e)||s.push(F[e]);return s};H||(P=function(){if(this instanceof P)throw TypeError("Symbol is not a constructor!");var t=c(arguments.length>0?arguments[0]:void 0),e=function(i){this===j&&e.call(B,i),n(this,R)&&n(this[R],t)&&(this[R][t]=!1),G(this,t,x(1,i))};return s&&Y&&G(j,t,{configurable:!0,set:e}),V(t)},a(P.prototype,"toString",function(){return this._k}),S.f=J,D.f=q,i(77).f=M.
 f=Q,i(74).f=K,i(73).f=$,s&&!i(14)&&a(j,"propertyIsEnumerable",K,!0),f.f=function(t){return V(p(t))}),r(r.G+r.W+r.F*!H,{Symbol:P});for(var tt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),et=0;tt.length>et;)p(tt[et++]);for(var tt=O(p.store),et=0;tt.length>et;)m(tt[et++]);r(r.S+r.F*!H,"Symbol",{for:function(t){return n(L,t+="")?L[t]:L[t]=P(t)},keyFor:function(t){if(U(t))return v(L,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){Y=!0},useSimple:function(){Y=!1}}),r(r.S+r.F*!H,"Object",{create:Z,defineProperty:q,defineProperties:X,getOwnPropertyDescriptor:J,getOwnPropertyNames:Q,getOwnPropertySymbols:$}),I&&r(r.S+r.F*(!H||d(function(){var t=P();return"[null]"!=N([t])||"{}"!=N({a:t})||"{}"!=N(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!U(t)){for(var e,i,o=[t],n=1;arguments.length>n;)o.push(arguments[n++]);return e=o[1],"function"==typeof e&&(i=e),!i&&y(e)||(e=function(t,e){if(i&&
 (e=i.call(this,t,e)),!U(e))return e}),o[1]=e,N.apply(I,o)}}}),P.prototype[A]||i(20)(P.prototype,A,P.prototype.valueOf),u(P,"Symbol"),u(Math,"Math",!0),u(o.JSON,"JSON",!0)},function(t,e,i){var o=i(43)("meta"),n=i(23),s=i(31),r=i(21).f,a=0,h=Object.isExtensible||function(){return!0},d=!i(26)(function(){return h(Object.preventExtensions({}))}),l=function(t){r(t,o,{value:{i:"O"+ ++a,w:{}}})},u=function(t,e){if(!n(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!s(t,o)){if(!h(t))return"F";if(!e)return"E";l(t)}return t[o].i},c=function(t,e){if(!s(t,o)){if(!h(t))return!0;if(!e)return!1;l(t)}return t[o].w},p=function(t){return d&&f.NEED&&h(t)&&!s(t,o)&&l(t),t},f=t.exports={KEY:o,NEED:!1,fastKey:u,getWeak:c,onFreeze:p}},function(t,e,i){var o=i(16),n=i(17),s=i(14),r=i(65),a=i(21).f;t.exports=function(t){var e=n.Symbol||(n.Symbol=s?{}:o.Symbol||{});"_"==t.charAt(0)||t in e||a(e,t,{value:r.f(t)})}},function(t,e,i){var o=i(35),n=i(9);t.exports=function(t,e){for(var i,s=n(t),r=o(s
 ),a=r.length,h=0;a>h;)if(s[i=r[h++]]===e)return i}},function(t,e,i){var o=i(35),n=i(73),s=i(74);t.exports=function(t){var e=o(t),i=n.f;if(i)for(var r,a=i(t),h=s.f,d=0;a.length>d;)h.call(t,r=a[d++])&&e.push(r);return e}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,i){var o=i(11);t.exports=Array.isArray||function(t){return"Array"==o(t)}},function(t,e,i){var o=i(9),n=i(77).f,s={}.toString,r="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],a=function(t){try{return n(t)}catch(t){return r.slice()}};t.exports.f=function(t){return r&&"[object Window]"==s.call(t)?a(t):n(o(t))}},function(t,e,i){var o=i(36),n=i(44).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return o(t,n)}},function(t,e,i){var o=i(74),n=i(29),s=i(9),r=i(28),a=i(31),h=i(24),d=Object.getOwnPropertyDescriptor;e.f=i(25)?d:function(t,e){if(t=s(t),e=r(e,!0),h)try{return d(t,e)}catch(t){}if(a(t,e))
 return n(!o.f.call(t,e),t[e])}},function(t,e){},function(t,e,i){i(70)("asyncIterator")},function(t,e,i){i(70)("observable")},function(t,e,i){t.exports="undefined"!=typeof window&&window.moment||i(83)},function(t,e,i){(function(t){!function(e,i){t.exports=i()}(0,function(){function e(){return bo.apply(null,arguments)}function i(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function o(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function n(t){var e;for(e in t)return!1;return!0}function s(t){return void 0===t}function r(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function a(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function h(t,e){var i,o=[];for(i=0;i<t.length;++i)o.push(e(t[i],i));return o}function d(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function l(t,e){for(var i in e)d(e,i)&&(t[i]=e[i]);return d(e,"toString")&&(t.toString=e.toS
 tring),d(e,"valueOf")&&(t.valueOf=e.valueOf),t}function u(t,e,i,o){return ye(t,e,i,o,!0).utc()}function c(){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 p(t){return null==t._pf&&(t._pf=c()),t._pf}function f(t){if(null==t._isValid){var e=p(t),i=wo.call(e.parsedDateParts,function(t){return null!=t}),o=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&i);if(t._strict&&(o=o&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return o;t._isValid=o}return t._isValid}function m(t){var e=u(NaN);return null!=t?l(p(e),t):p(e).userInvalidated=!0,e}function v(t,e){var i,o,n;if(s(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),s(e._i)||(t._i
 =e._i),s(e._f)||(t._f=e._f),s(e._l)||(t._l=e._l),s(e._strict)||(t._strict=e._strict),
+s(e._tzm)||(t._tzm=e._tzm),s(e._isUTC)||(t._isUTC=e._isUTC),s(e._offset)||(t._offset=e._offset),s(e._pf)||(t._pf=p(e)),s(e._locale)||(t._locale=e._locale),xo.length>0)for(i=0;i<xo.length;i++)o=xo[i],n=e[o],s(n)||(t[o]=n);return t}function g(t){v(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===ko&&(ko=!0,e.updateOffset(this),ko=!1)}function y(t){return t instanceof g||null!=t&&null!=t._isAMomentObject}function b(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function _(t){var e=+t,i=0;return 0!==e&&isFinite(e)&&(i=b(e)),i}function w(t,e,i){var o,n=Math.min(t.length,e.length),s=Math.abs(t.length-e.length),r=0;for(o=0;o<n;o++)(i&&t[o]!==e[o]||!i&&_(t[o])!==_(e[o]))&&r++;return r+s}function x(t){!1===e.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function k(t,i){var o=!0;return l(function(){if(null!=e.deprecationHandler&&e.deprecationHandler(null,t),o){for(var n,s=[],r=0;
 r<arguments.length;r++){if(n="","object"==typeof arguments[r]){n+="\n["+r+"] ";for(var a in arguments[0])n+=a+": "+arguments[0][a]+", ";n=n.slice(0,-2)}else n=arguments[r];s.push(n)}x(t+"\nArguments: "+Array.prototype.slice.call(s).join("")+"\n"+(new Error).stack),o=!1}return i.apply(this,arguments)},i)}function M(t,i){null!=e.deprecationHandler&&e.deprecationHandler(t,i),Mo[t]||(x(i),Mo[t]=!0)}function S(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function D(t){var e,i;for(i in t)e=t[i],S(e)?this[i]=e:this["_"+i]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function O(t,e){var i,n=l({},t);for(i in e)d(e,i)&&(o(t[i])&&o(e[i])?(n[i]={},l(n[i],t[i]),l(n[i],e[i])):null!=e[i]?n[i]=e[i]:delete n[i]);for(i in t)d(t,i)&&!d(e,i)&&o(t[i])&&(n[i]=l({},n[i]));return n}function C(t){null!=t&&this.set(t)}function T(t,e,i){var o=this._calendar[t]||
 this._calendar.sameElse;return S(o)?o.call(e,i):o}function E(t){var e=this._longDateFormat[t],i=this._longDateFormat[t.toUpperCase()];return e||!i?e:(this._longDateFormat[t]=i.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function P(){return this._invalidDate}function I(t){return this._ordinal.replace("%d",t)}function N(t,e,i,o){var n=this._relativeTime[i];return S(n)?n(t,e,i,o):n.replace(/%d/i,t)}function R(t,e){var i=this._relativeTime[t>0?"future":"past"];return S(i)?i(e):i.replace(/%s/i,e)}function A(t,e){var i=t.toLowerCase();Io[i]=Io[i+"s"]=Io[e]=t}function z(t){return"string"==typeof t?Io[t]||Io[t.toLowerCase()]:void 0}function L(t){var e,i,o={};for(i in t)d(t,i)&&(e=z(i))&&(o[e]=t[i]);return o}function F(t,e){No[t]=e}function B(t){var e=[];for(var i in t)e.push({unit:i,priority:No[i]});return e.sort(function(t,e){return t.priority-e.priority}),e}function j(t,i){return function(o){return null!=o?(W(this,t,o),e.updateOffset(this,i),this):H
 (this,t)}}function H(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function W(t,e,i){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](i)}function Y(t){return t=z(t),S(this[t])?this[t]():this}function G(t,e){if("object"==typeof t){t=L(t);for(var i=B(t),o=0;o<i.length;o++)this[i[o].unit](t[i[o].unit])}else if(t=z(t),S(this[t]))return this[t](e);return this}function V(t,e,i){var o=""+Math.abs(t),n=e-o.length;return(t>=0?i?"+":"":"-")+Math.pow(10,Math.max(0,n)).toString().substr(1)+o}function U(t,e,i,o){var n=o;"string"==typeof o&&(n=function(){return this[o]()}),t&&(Lo[t]=n),e&&(Lo[e[0]]=function(){return V(n.apply(this,arguments),e[1],e[2])}),i&&(Lo[i]=function(){return this.localeData().ordinal(n.apply(this,arguments),t)})}function q(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function X(t){var e,i,o=t.match(Ro);for(e=0,i=o.length;e<i;e++)Lo[o[e]]?o[e]=Lo[o[e]]:o[e]=q(o[e]);return function(e){var n,s="";for(n=0;n<i;n++)s+=S(o[n])?o[n].ca
 ll(e,t):o[n];return s}}function Z(t,e){return t.isValid()?(e=K(e,t.localeData()),zo[e]=zo[e]||X(e),zo[e](t)):t.localeData().invalidDate()}function K(t,e){function i(t){return e.longDateFormat(t)||t}var o=5;for(Ao.lastIndex=0;o>=0&&Ao.test(t);)t=t.replace(Ao,i),Ao.lastIndex=0,o-=1;return t}function J(t,e,i){en[t]=S(e)?e:function(t,o){return t&&i?i:e}}function Q(t,e){return d(en,t)?en[t](e._strict,e._locale):new RegExp($(t))}function $(t){return tt(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,i,o,n){return e||i||o||n}))}function tt(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function et(t,e){var i,o=e;for("string"==typeof t&&(t=[t]),r(e)&&(o=function(t,i){i[e]=_(t)}),i=0;i<t.length;i++)on[t[i]]=o}function it(t,e){et(t,function(t,i,o,n){o._w=o._w||{},e(t,o._w,o,n)})}function ot(t,e,i){null!=e&&d(on,t)&&on[t](e,i._a,i,t)}function nt(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function st(t,e){return t?i(this._months)?this._months[t.mont
 h()]:this._months[(this._months.isFormat||fn).test(e)?"format":"standalone"][t.month()]:i(this._months)?this._months:this._months.standalone}function rt(t,e){return t?i(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[fn.test(e)?"format":"standalone"][t.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone}function at(t,e,i){var o,n,s,r=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],o=0;o<12;++o)s=u([2e3,o]),this._shortMonthsParse[o]=this.monthsShort(s,"").toLocaleLowerCase(),this._longMonthsParse[o]=this.months(s,"").toLocaleLowerCase();return i?"MMM"===e?(n=pn.call(this._shortMonthsParse,r),-1!==n?n:null):(n=pn.call(this._longMonthsParse,r),-1!==n?n:null):"MMM"===e?-1!==(n=pn.call(this._shortMonthsParse,r))?n:(n=pn.call(this._longMonthsParse,r),-1!==n?n:null):-1!==(n=pn.call(this._longMonthsParse,r))?n:(n=pn.call(this._shortMonthsParse,r),-1!==n?n:null)}function ht(t,e,
 i){var o,n,s;if(this._monthsParseExact)return at.call(this,t,e,i);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),o=0;o<12;o++){if(n=u([2e3,o]),i&&!this._longMonthsParse[o]&&(this._longMonthsParse[o]=new RegExp("^"+this.months(n,"").replace(".","")+"$","i"),this._shortMonthsParse[o]=new RegExp("^"+this.monthsShort(n,"").replace(".","")+"$","i")),i||this._monthsParse[o]||(s="^"+this.months(n,"")+"|^"+this.monthsShort(n,""),this._monthsParse[o]=new RegExp(s.replace(".",""),"i")),i&&"MMMM"===e&&this._longMonthsParse[o].test(t))return o;if(i&&"MMM"===e&&this._shortMonthsParse[o].test(t))return o;if(!i&&this._monthsParse[o].test(t))return o}}function dt(t,e){var i;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=_(e);else if(e=t.localeData().monthsParse(e),!r(e))return t;return i=Math.min(t.date(),nt(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,i),t}function lt(t){return null!=t?(dt(this,t),e.updateOffset(this,
 !0),this):H(this,"Month")}function ut(){return nt(this.year(),this.month())}function ct(t){return this._monthsParseExact?(d(this,"_monthsRegex")||ft.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=gn),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)}function pt(t){return this._monthsParseExact?(d(this,"_monthsRegex")||ft.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=yn),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)}function ft(){function t(t,e){return e.length-t.length}var e,i,o=[],n=[],s=[];for(e=0;e<12;e++)i=u([2e3,e]),o.push(this.monthsShort(i,"")),n.push(this.months(i,"")),s.push(this.months(i,"")),s.push(this.monthsShort(i,""));for(o.sort(t),n.sort(t),s.sort(t),e=0;e<12;e++)o[e]=tt(o[e]),n[e]=tt(n[e]);for(e=0;e<24;e++)s[e]=tt(s[e]);this._monthsRegex=new RegExp("^("+s.join("|")+")","i"),this._mon
 thsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+n.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+o.join("|")+")","i")}function mt(t){return vt(t)?366:365}function vt(t){return t%4==0&&t%100!=0||t%400==0}function gt(){return vt(this.year())}function yt(t,e,i,o,n,s,r){var a=new Date(t,e,i,o,n,s,r);return t<100&&t>=0&&isFinite(a.getFullYear())&&a.setFullYear(t),a}function bt(t){var e=new Date(Date.UTC.apply(null,arguments));return t<100&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function _t(t,e,i){var o=7+e-i;return-(7+bt(t,0,o).getUTCDay()-e)%7+o-1}function wt(t,e,i,o,n){var s,r,a=(7+i-o)%7,h=_t(t,o,n),d=1+7*(e-1)+a+h;return d<=0?(s=t-1,r=mt(s)+d):d>mt(t)?(s=t+1,r=d-mt(t)):(s=t,r=d),{year:s,dayOfYear:r}}function xt(t,e,i){var o,n,s=_t(t.year(),e,i),r=Math.floor((t.dayOfYear()-s-1)/7)+1;return r<1?(n=t.year()-1,o=r+kt(n,e,i)):r>kt(t.year(),e,i)?(o=r-kt(t.year(),e,i),n=t.year()+1):(n=t.year(),o=r),{week:o,year:n}}function kt(t,e,i
 ){var o=_t(t,e,i),n=_t(t+1,e,i);return(mt(t)-o+n)/7}function Mt(t){return xt(t,this._week.dow,this._week.doy).week}function St(){return this._week.dow}function Dt(){return this._week.doy}function Ot(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function Ct(t){var e=xt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function Tt(t,e){return"string"!=typeof t?t:isNaN(t)?(t=e.weekdaysParse(t),"number"==typeof t?t:null):parseInt(t,10)}function Et(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function Pt(t,e){return t?i(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:i(this._weekdays)?this._weekdays:this._weekdays.standalone}function It(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort}function Nt(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin}function Rt(t,e,i){var o,n,s,r=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysP
 arse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],o=0;o<7;++o)s=u([2e3,1]).day(o),this._minWeekdaysParse[o]=this.weekdaysMin(s,"").toLocaleLowerCase(),this._shortWeekdaysParse[o]=this.weekdaysShort(s,"").toLocaleLowerCase(),this._weekdaysParse[o]=this.weekdays(s,"").toLocaleLowerCase();return i?"dddd"===e?(n=pn.call(this._weekdaysParse,r),-1!==n?n:null):"ddd"===e?(n=pn.call(this._shortWeekdaysParse,r),-1!==n?n:null):(n=pn.call(this._minWeekdaysParse,r),-1!==n?n:null):"dddd"===e?-1!==(n=pn.call(this._weekdaysParse,r))?n:-1!==(n=pn.call(this._shortWeekdaysParse,r))?n:(n=pn.call(this._minWeekdaysParse,r),-1!==n?n:null):"ddd"===e?-1!==(n=pn.call(this._shortWeekdaysParse,r))?n:-1!==(n=pn.call(this._weekdaysParse,r))?n:(n=pn.call(this._minWeekdaysParse,r),-1!==n?n:null):-1!==(n=pn.call(this._minWeekdaysParse,r))?n:-1!==(n=pn.call(this._weekdaysParse,r))?n:(n=pn.call(this._shortWeekdaysParse,r),-1!==n?n:null)}function At(t,e,i){var o,n,s;if(this._weekdaysParseExact)return Rt.ca
 ll(this,t,e,i);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),o=0;o<7;o++){if(n=u([2e3,1]).day(o),i&&!this._fullWeekdaysParse[o]&&(this._fullWeekdaysParse[o]=new RegExp("^"+this.weekdays(n,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[o]=new RegExp("^"+this.weekdaysShort(n,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[o]=new RegExp("^"+this.weekdaysMin(n,"").replace(".",".?")+"$","i")),this._weekdaysParse[o]||(s="^"+this.weekdays(n,"")+"|^"+this.weekdaysShort(n,"")+"|^"+this.weekdaysMin(n,""),this._weekdaysParse[o]=new RegExp(s.replace(".",""),"i")),i&&"dddd"===e&&this._fullWeekdaysParse[o].test(t))return o;if(i&&"ddd"===e&&this._shortWeekdaysParse[o].test(t))return o;if(i&&"dd"===e&&this._minWeekdaysParse[o].test(t))return o;if(!i&&this._weekdaysParse[o].test(t))return o}}function zt(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay(
 );return null!=t?(t=Tt(t,this.localeData()),this.add(t-e,"d")):e}function Lt(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function Ft(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=Et(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7}function Bt(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Wt.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Mn),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)}function jt(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Wt.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Sn),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Ht(t){return this._weekdaysParseExact?(d(this,"_weekdaysR
 egex")||Wt.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Dn),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Wt(){function t(t,e){return e.length-t.length}var e,i,o,n,s,r=[],a=[],h=[],d=[];for(e=0;e<7;e++)i=u([2e3,1]).day(e),o=this.weekdaysMin(i,""),n=this.weekdaysShort(i,""),s=this.weekdays(i,""),r.push(o),a.push(n),h.push(s),d.push(o),d.push(n),d.push(s);for(r.sort(t),a.sort(t),h.sort(t),d.sort(t),e=0;e<7;e++)a[e]=tt(a[e]),h[e]=tt(h[e]),d[e]=tt(d[e]);this._weekdaysRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Yt(){return this.hours()%12||12}function Gt(){return this.hours()||24
 }function Vt(t,e){U(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function Ut(t,e){return e._meridiemParse}function qt(t){return"p"===(t+"").toLowerCase().charAt(0)}function Xt(t,e,i){return t>11?i?"pm":"PM":i?"am":"AM"}function Zt(t){return t?t.toLowerCase().replace("_","-"):t}function Kt(t){for(var e,i,o,n,s=0;s<t.length;){for(n=Zt(t[s]).split("-"),e=n.length,i=Zt(t[s+1]),i=i?i.split("-"):null;e>0;){if(o=Jt(n.slice(0,e).join("-")))return o;if(i&&i.length>=e&&w(n,i,!0)>=e-1)break;e--}s++}return null}function Jt(e){var i=null;if(!Pn[e]&&void 0!==t&&t&&t.exports)try{i=On._abbr,function(){var t=new Error('Cannot find module "./locale"');throw t.code="MODULE_NOT_FOUND",t}(),Qt(i)}catch(t){}return Pn[e]}function Qt(t,e){var i;return t&&(i=s(e)?ee(t):$t(t,e))&&(On=i),On._abbr}function $t(t,e){if(null!==e){var i=En;if(e.abbr=t,null!=Pn[t])M("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineL
 ocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=Pn[t]._config;else if(null!=e.parentLocale){if(null==Pn[e.parentLocale])return In[e.parentLocale]||(In[e.parentLocale]=[]),In[e.parentLocale].push({name:t,config:e}),null;i=Pn[e.parentLocale]._config}return Pn[t]=new C(O(i,e)),In[t]&&In[t].forEach(function(t){$t(t.name,t.config)}),Qt(t),Pn[t]}return delete Pn[t],null}function te(t,e){if(null!=e){var i,o=En;null!=Pn[t]&&(o=Pn[t]._config),e=O(o,e),i=new C(e),i.parentLocale=Pn[t],Pn[t]=i,Qt(t)}else null!=Pn[t]&&(null!=Pn[t].parentLocale?Pn[t]=Pn[t].parentLocale:null!=Pn[t]&&delete Pn[t]);return Pn[t]}function ee(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return On;if(!i(t)){if(e=Jt(t))return e;t=[t]}return Kt(t)}function ie(){return Oo(Pn)}function oe(t){var e,i=t._a;return i&&-2===p(t).overflow&&(e=i[sn]<0||i[sn]>11?sn:i[rn]<1||i[rn]>nt(i[nn],i[sn])?rn:i[an]<0||i[an]
 >24||24===i[an]&&(0!==i[hn]||0!==i[dn]||0!==i[ln])?an:i[hn]<0||i[hn]>59?hn:i[dn]<0||i[dn]>59?dn:i[ln]<0||i[ln]>999?ln:-1,p(t)._overflowDayOfYear&&(e<nn||e>rn)&&(e=rn),p(t)._overflowWeeks&&-1===e&&(e=un),p(t)._overflowWeekday&&-1===e&&(e=cn),p(t).overflow=e),t}function ne(t){var e,i,o,n,s,r,a=t._i,h=Nn.exec(a)||Rn.exec(a);if(h){for(p(t).iso=!0,e=0,i=zn.length;e<i;e++)if(zn[e][1].exec(h[1])){n=zn[e][0],o=!1!==zn[e][2];break}if(null==n)return void(t._isValid=!1);if(h[3]){for(e=0,i=Ln.length;e<i;e++)if(Ln[e][1].exec(h[3])){s=(h[2]||" ")+Ln[e][0];break}if(null==s)return void(t._isValid=!1)}if(!o&&null!=s)return void(t._isValid=!1);if(h[4]){if(!An.exec(h[4]))return void(t._isValid=!1);r="Z"}t._f=n+(s||"")+(r||""),ue(t)}else t._isValid=!1}function se(t){var e,i,o,n,s,r,a,h,d={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"},l="YXWVUTSRQPONZABCDEFGHIKLM";if(e=t._i.replace(/\([^\)]*\)|[\n\t]/g," "
 ).replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),i=Bn.exec(e)){if(o=i[1]?"ddd"+(5===i[1].length?", ":" "):"",n="D MMM "+(i[2].length>10?"YYYY ":"YY "),s="HH:mm"+(i[4]?":ss":""),i[1]){var u=new Date(i[2]),c=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][u.getDay()];if(i[1].substr(0,3)!==c)return p(t).weekdayMismatch=!0,void(t._isValid=!1)}switch(i[5].length){case 2:0===h?a=" +0000":(h=l.indexOf(i[5][1].toUpperCase())-12,a=(h<0?" -":" +")+(""+h).replace(/^-?/,"0").match(/..$/)[0]+"00");break;case 4:a=d[i[5]];break;default:a=d[" GMT"]}i[5]=a,t._i=i.splice(1).join(""),r=" ZZ",t._f=o+n+s+r,ue(t),p(t).rfc2822=!0}else t._isValid=!1}function re(t){var i=Fn.exec(t._i);if(null!==i)return void(t._d=new Date(+i[1]));ne(t),!1===t._isValid&&(delete t._isValid,se(t),!1===t._isValid&&(delete t._isValid,e.createFromInputFallback(t)))}function ae(t,e,i){return null!=t?t:null!=e?e:i}function he(t){var i=new Date(e.now());return t._useUTC?[i.getUTCFullYear(),i.getUTCMonth(),i.getUTCDate()]:[i.getFullYear(
 ),i.getMonth(),i.getDate()]}function de(t){var e,i,o,n,s=[];if(!t._d){for(o=he(t),t._w&&null==t._a[rn]&&null==t._a[sn]&&le(t),null!=t._dayOfYear&&(n=ae(t._a[nn],o[nn]),(t._dayOfYear>mt(n)||0===t._dayOfYear)&&(p(t)._overflowDayOfYear=!0),i=bt(n,0,t._dayOfYear),t._a[sn]=i.getUTCMonth(),t._a[rn]=i.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=o[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[an]&&0===t._a[hn]&&0===t._a[dn]&&0===t._a[ln]&&(t._nextDay=!0,t._a[an]=0),t._d=(t._useUTC?bt:yt).apply(null,s),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[an]=24)}}function le(t){var e,i,o,n,s,r,a,h;if(e=t._w,null!=e.GG||null!=e.W||null!=e.E)s=1,r=4,i=ae(e.GG,t._a[nn],xt(be(),1,4).year),o=ae(e.W,1),((n=ae(e.E,1))<1||n>7)&&(h=!0);else{s=t._locale._week.dow,r=t._locale._week.doy;var d=xt(be(),s,r);i=ae(e.gg,t._a[nn],d.year),o=ae(e.w,d.week),null!=e.d?((n=e.d)<0||n>6)&&(h=!0):null!=e.e?(n=e.e+s,(e.e<0||e.e>6)&&(h=!0)):n=s}o<1||o>kt(i,s
 ,r)?p(t)._overflowWeeks=!0:null!=h?p(t)._overflowWeekday=!0:(a=wt(i,o,n,s,r),t._a[nn]=a.year,t._dayOfYear=a.dayOfYear)}function ue(t){if(t._f===e.ISO_8601)return void ne(t);if(t._f===e.RFC_2822)return void se(t);t._a=[],p(t).empty=!0;var i,o,n,s,r,a=""+t._i,h=a.length,d=0;for(n=K(t._f,t._locale).match(Ro)||[],i=0;i<n.length;i++)s=n[i],o=(a.match(Q(s,t))||[])[0],o&&(r=a.substr(0,a.indexOf(o)),r.length>0&&p(t).unusedInput.push(r),a=a.slice(a.indexOf(o)+o.length),d+=o.length),Lo[s]?(o?p(t).empty=!1:p(t).unusedTokens.push(s),ot(s,o,t)):t._strict&&!o&&p(t).unusedTokens.push(s);p(t).charsLeftOver=h-d,a.length>0&&p(t).unusedInput.push(a),t._a[an]<=12&&!0===p(t).bigHour&&t._a[an]>0&&(p(t).bigHour=void 0),p(t).parsedDateParts=t._a.slice(0),p(t).meridiem=t._meridiem,t._a[an]=ce(t._locale,t._a[an],t._meridiem),de(t),oe(t)}function ce(t,e,i){var o;return null==i?e:null!=t.meridiemHour?t.meridiemHour(e,i):null!=t.isPM?(o=t.isPM(i),o&&e<12&&(e+=12),o||12!==e||(e=0),e):e}function pe(t){var e,i,o,n
 ,s;if(0===t._f.length)return p(t).invalidFormat=!0,void(t._d=new Date(NaN));for(n=0;n<t._f.length;n++)s=0,e=v({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[n],ue(e),f(e)&&(s+=p(e).charsLeftOver,s+=10*p(e).unusedTokens.length,p(e).score=s,(null==o||s<o)&&(o=s,i=e));l(t,i||e)}function fe(t){if(!t._d){var e=L(t._i);t._a=h([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),de(t)}}function me(t){var e=new g(oe(ve(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function ve(t){var e=t._i,o=t._f;return t._locale=t._locale||ee(t._l),null===e||void 0===o&&""===e?m({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),y(e)?new g(oe(e)):(a(e)?t._d=e:i(o)?pe(t):o?ue(t):ge(t),f(t)||(t._d=null),t))}function ge(t){var n=t._i;s(n)?t._d=new Date(e.now()):a(n)?t._d=new Date(n.valueOf()):"string"==typeof n?re(t):i(n)?(t._a=h(n.slice(0),function(t){return parseInt(t,10)}),de(t)):o(n)?fe(t):r(n)?t._d=new Date(n):e
 .createFromInputFallback(t)}function ye(t,e,s,r,a){var h={};return!0!==s&&!1!==s||(r=s,s=void 0),(o(t)&&n(t)||i(t)&&0===t.length)&&(t=void 0),h._isAMomentObject=!0,h._useUTC=h._isUTC=a,h._l=s,h._i=t,h._f=e,h._strict=r,me(h)}function be(t,e,i,o){return ye(t,e,i,o,!1)}function _e(t,e){var o,n;if(1===e.length&&i(e[0])&&(e=e[0]),!e.length)return be();for(o=e[0],n=1;n<e.length;++n)e[n].isValid()&&!e[n][t](o)||(o=e[n]);return o}function we(){return _e("isBefore",[].slice.call(arguments,0))}function xe(){return _e("isAfter",[].slice.call(arguments,0))}function ke(t){for(var e in t)if(-1===Yn.indexOf(e)||null!=t[e]&&isNaN(t[e]))return!1;for(var i=!1,o=0;o<Yn.length;++o)if(t[Yn[o]]){if(i)return!1;parseFloat(t[Yn[o]])!==_(t[Yn[o]])&&(i=!0)}return!0}function Me(){return this._isValid}function Se(){return Ge(NaN)}function De(t){var e=L(t),i=e.year||0,o=e.quarter||0,n=e.month||0,s=e.week||0,r=e.day||0,a=e.hour||0,h=e.minute||0,d=e.second||0,l=e.millisecond||0;this._isValid=ke(e),this._millisecon
 ds=+l+1e3*d+6e4*h+1e3*a*60*60,this._days=+r+7*s,this._months=+n+3*o+12*i,this._data={},this._locale=ee(),this._bubble()}function Oe(t){return t instanceof De}function Ce(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function Te(t,e){U(t,0,0,function(){var t=this.utcOffset(),i="+";return t<0&&(t=-t,i="-"),i+V(~~(t/60),2)+e+V(~~t%60,2)})}function Ee(t,e){var i=(e||"").match(t);if(null===i)return null;var o=i[i.length-1]||[],n=(o+"").match(Gn)||["-",0,0],s=60*n[1]+_(n[2]);return 0===s?0:"+"===n[0]?s:-s}function Pe(t,i){var o,n;return i._isUTC?(o=i.clone(),n=(y(t)||a(t)?t.valueOf():be(t).valueOf())-o.valueOf(),o._d.setTime(o._d.valueOf()+n),e.updateOffset(o,!1),o):be(t).local()}function Ie(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Ne(t,i,o){var n,s=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=Ee(Qo,t)))return this}else Math.abs(t)<16&&!o&&(t*=60);return!this._isUTC&&i&&(n=Ie(this)),this._offset=t,this._
 isUTC=!0,null!=n&&this.add(n,"m"),s!==t&&(!i||this._changeInProgress?Ze(this,Ge(t-s,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,e.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?s:Ie(this)}function Re(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function Ae(t){return this.utcOffset(0,t)}function ze(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ie(this),"m")),this}function Le(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=Ee(Jo,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this}function Fe(t){return!!this.isValid()&&(t=t?be(t).utcOffset():0,(this.utcOffset()-t)%60==0)}function Be(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function je(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(v(t,this),t=ve(t),t._a){var e=t._is
 UTC?u(t._a):be(t._a);this._isDSTShifted=this.isValid()&&w(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function He(){return!!this.isValid()&&!this._isUTC}function We(){return!!this.isValid()&&this._isUTC}function Ye(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Ge(t,e){var i,o,n,s=t,a=null;return Oe(t)?s={ms:t._milliseconds,d:t._days,M:t._months}:r(t)?(s={},e?s[e]=t:s.milliseconds=t):(a=Vn.exec(t))?(i="-"===a[1]?-1:1,s={y:0,d:_(a[rn])*i,h:_(a[an])*i,m:_(a[hn])*i,s:_(a[dn])*i,ms:_(Ce(1e3*a[ln]))*i}):(a=Un.exec(t))?(i="-"===a[1]?-1:1,s={y:Ve(a[2],i),M:Ve(a[3],i),w:Ve(a[4],i),d:Ve(a[5],i),h:Ve(a[6],i),m:Ve(a[7],i),s:Ve(a[8],i)}):null==s?s={}:"object"==typeof s&&("from"in s||"to"in s)&&(n=qe(be(s.from),be(s.to)),s={},s.ms=n.milliseconds,s.M=n.months),o=new De(s),Oe(t)&&d(t,"_locale")&&(o._locale=t._locale),o}function Ve(t,e){var i=t&&parseFloat(t.replace(",","."));return(isNaN(i)?0:i)*e}function Ue(t,e){var i={milliseconds:0,months:0};ret
 urn i.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(i.months,"M").isAfter(e)&&--i.months,i.milliseconds=+e-+t.clone().add(i.months,"M"),i}function qe(t,e){var i;return t.isValid()&&e.isValid()?(e=Pe(e,t),t.isBefore(e)?i=Ue(t,e):(i=Ue(e,t),i.milliseconds=-i.milliseconds,i.months=-i.months),i):{milliseconds:0,months:0}}function Xe(t,e){return function(i,o){var n,s;return null===o||isNaN(+o)||(M(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),s=i,i=o,o=s),i="string"==typeof i?+i:i,n=Ge(i,o),Ze(this,n,t),this}}function Ze(t,i,o,n){var s=i._milliseconds,r=Ce(i._days),a=Ce(i._months);t.isValid()&&(n=null==n||n,s&&t._d.setTime(t._d.valueOf()+s*o),r&&W(t,"Date",H(t,"Date")+r*o),a&&dt(t,H(t,"Month")+a*o),n&&e.updateOffset(t,r||a))}function Ke(t,e){var i=t.diff(e,"days",!0);return i<-6?"sameElse":i<-1?"lastWeek":i<0?"lastDay":i<1?"sameDay":i<2?"nextDay":
 i<7?"nextWeek":"sameElse"}function Je(t,i){var o=t||be(),n=Pe(o,this).startOf("day"),s=e.calendarFormat(this,n)||"sameElse",r=i&&(S(i[s])?i[s].call(this,o):i[s]);return this.format(r||this.localeData().calendar(s,this,be(o)))}function Qe(){return new g(this)}function $e(t,e){var i=y(t)?t:be(t);return!(!this.isValid()||!i.isValid())&&(e=z(s(e)?"millisecond":e),"millisecond"===e?this.valueOf()>i.valueOf():i.valueOf()<this.clone().startOf(e).valueOf())}function ti(t,e){var i=y(t)?t:be(t);return!(!this.isValid()||!i.isValid())&&(e=z(s(e)?"millisecond":e),"millisecond"===e?this.valueOf()<i.valueOf():this.clone().endOf(e).valueOf()<i.valueOf())}function ei(t,e,i,o){return o=o||"()",("("===o[0]?this.isAfter(t,i):!this.isBefore(t,i))&&(")"===o[1]?this.isBefore(e,i):!this.isAfter(e,i))}function ii(t,e){var i,o=y(t)?t:be(t);return!(!this.isValid()||!o.isValid())&&(e=z(e||"millisecond"),"millisecond"===e?this.valueOf()===o.valueOf():(i=o.valueOf(),this.clone().startOf(e).valueOf()<=i&&i<=this.
 clone().endOf(e).valueOf()))}function oi(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function ni(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function si(t,e,i){var o,n,s,r;return this.isValid()?(o=Pe(t,this),o.isValid()?(n=6e4*(o.utcOffset()-this.utcOffset()),e=z(e),"year"===e||"month"===e||"quarter"===e?(r=ri(this,o),"quarter"===e?r/=3:"year"===e&&(r/=12)):(s=this-o,r="second"===e?s/1e3:"minute"===e?s/6e4:"hour"===e?s/36e5:"day"===e?(s-n)/864e5:"week"===e?(s-n)/6048e5:s),i?r:b(r)):NaN):NaN}function ri(t,e){var i,o,n=12*(e.year()-t.year())+(e.month()-t.month()),s=t.clone().add(n,"months");return e-s<0?(i=t.clone().add(n-1,"months"),o=(e-s)/(s-i)):(i=t.clone().add(n+1,"months"),o=(e-s)/(i-s)),-(n+o)||0}function ai(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function hi(){if(!this.isValid())return null;var t=this.clone().utc();return t.year()<0||t.year()>9999?Z(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):S(Date.prototype.toISOString)?this.toDate().to
 ISOString():Z(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function di(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var i="["+t+'("]',o=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=e+'[")]';return this.format(i+o+"-MM-DD[T]HH:mm:ss.SSS"+n)}function li(t){t||(t=this.isUtc()?e.defaultFormatUtc:e.defaultFormat);var i=Z(this,t);return this.localeData().postformat(i)}function ui(t,e){return this.isValid()&&(y(t)&&t.isValid()||be(t).isValid())?Ge({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function ci(t){return this.from(be(),t)}function pi(t,e){return this.isValid()&&(y(t)&&t.isValid()||be(t).isValid())?Ge({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function fi(t){return this.to(be(),t)}function mi(t){var e;return void 0===t?this._locale._abbr:(e=ee(t),null!=e&&(this._locale=e),this)}function vi(
 ){return this._locale}function gi(t){switch(t=z(t)){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"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this}function yi(t){return void 0===(t=z(t))||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))}function bi(){return this._d.valueOf()-6e4*(this._offset||0)}function _i(){return Math.floor(this.valueOf()/1e3)}function wi(){return new Date(this.valueOf())}function xi(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function ki(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function Mi(){retur
 n this.isValid()?this.toISOString():null}function Si(){return f(this)}function Di(){return l({},p(this))}function Oi(){return p(this).overflow}function Ci(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Ti(t,e){U(0,[t,t.length],0,e)}function Ei(t){return Ri.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Pi(t){return Ri.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function Ii(){return kt(this.year(),1,4)}function Ni(){var t=this.localeData()._week;return kt(this.year(),t.dow,t.doy)}function Ri(t,e,i,o,n){var s;return null==t?xt(this,o,n).year:(s=kt(t,o,n),e>s&&(e=s),Ai.call(this,t,e,i,o,n))}function Ai(t,e,i,o,n){var s=wt(t,e,i,o,n),r=bt(s.year,0,s.dayOfYear);return this.year(r.getUTCFullYear()),this.month(r.getUTCMonth()),this.date(r.getUTCDate()),this}function zi(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}function Li(t){var
  e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}function Fi(t,e){e[ln]=_(1e3*("0."+t))}function Bi(){return this._isUTC?"UTC":""}function ji(){return this._isUTC?"Coordinated Universal Time":""}function Hi(t){return be(1e3*t)}function Wi(){return be.apply(null,arguments).parseZone()}function Yi(t){return t}function Gi(t,e,i,o){var n=ee(),s=u().set(o,e);return n[i](s,t)}function Vi(t,e,i){if(r(t)&&(e=t,t=void 0),t=t||"",null!=e)return Gi(t,e,i,"month");var o,n=[];for(o=0;o<12;o++)n[o]=Gi(t,o,i,"month");return n}function Ui(t,e,i,o){"boolean"==typeof t?(r(e)&&(i=e,e=void 0),e=e||""):(e=t,i=e,t=!1,r(e)&&(i=e,e=void 0),e=e||"");var n=ee(),s=t?n._week.dow:0;if(null!=i)return Gi(e,(i+s)%7,o,"day");var a,h=[];for(a=0;a<7;a++)h[a]=Gi(e,(a+s)%7,o,"day");return h}function qi(t,e){return Vi(t,e,"months")}function Xi(t,e){return Vi(t,e,"monthsShort")}function Zi(t,e,i){return Ui(t,e,i,"weekdays")}function Ki(t,e,i){return Ui(t
 ,e,i,"weekdaysShort")}function Ji(t,e,i){return Ui(t,e,i,"weekdaysMin")}function Qi(){
+var t=this._data;return this._milliseconds=os(this._milliseconds),this._days=os(this._days),this._months=os(this._months),t.milliseconds=os(t.milliseconds),t.seconds=os(t.seconds),t.minutes=os(t.minutes),t.hours=os(t.hours),t.months=os(t.months),t.years=os(t.years),this}function $i(t,e,i,o){var n=Ge(e,i);return t._milliseconds+=o*n._milliseconds,t._days+=o*n._days,t._months+=o*n._months,t._bubble()}function to(t,e){return $i(this,t,e,1)}function eo(t,e){return $i(this,t,e,-1)}function io(t){return t<0?Math.floor(t):Math.ceil(t)}function oo(){var t,e,i,o,n,s=this._milliseconds,r=this._days,a=this._months,h=this._data;return s>=0&&r>=0&&a>=0||s<=0&&r<=0&&a<=0||(s+=864e5*io(so(a)+r),r=0,a=0),h.milliseconds=s%1e3,t=b(s/1e3),h.seconds=t%60,e=b(t/60),h.minutes=e%60,i=b(e/60),h.hours=i%24,r+=b(i/24),n=b(no(r)),a+=n,r-=io(so(n)),o=b(a/12),a%=12,h.days=r,h.months=a,h.years=o,this}function no(t){return 4800*t/146097}function so(t){return 146097*t/4800}function ro(t){if(!this.isValid())return 
 NaN;var e,i,o=this._milliseconds;if("month"===(t=z(t))||"year"===t)return e=this._days+o/864e5,i=this._months+no(e),"month"===t?i:i/12;switch(e=this._days+Math.round(so(this._months)),t){case"week":return e/7+o/6048e5;case"day":return e+o/864e5;case"hour":return 24*e+o/36e5;case"minute":return 1440*e+o/6e4;case"second":return 86400*e+o/1e3;case"millisecond":return Math.floor(864e5*e)+o;default:throw new Error("Unknown unit "+t)}}function ao(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12):NaN}function ho(t){return function(){return this.as(t)}}function lo(t){return t=z(t),this.isValid()?this[t+"s"]():NaN}function uo(t){return function(){return this.isValid()?this._data[t]:NaN}}function co(){return b(this.days()/7)}function po(t,e,i,o,n){return n.relativeTime(e||1,!!i,t,o)}function fo(t,e,i){var o=Ge(t).abs(),n=bs(o.as("s")),s=bs(o.as("m")),r=bs(o.as("h")),a=bs(o.as("d")),h=bs(o.as("M")),d=bs(o.as("y")),l=n<=_s.ss&&["s",n]|
 |n<_s.s&&["ss",n]||s<=1&&["m"]||s<_s.m&&["mm",s]||r<=1&&["h"]||r<_s.h&&["hh",r]||a<=1&&["d"]||a<_s.d&&["dd",a]||h<=1&&["M"]||h<_s.M&&["MM",h]||d<=1&&["y"]||["yy",d];return l[2]=e,l[3]=+t>0,l[4]=i,po.apply(null,l)}function mo(t){return void 0===t?bs:"function"==typeof t&&(bs=t,!0)}function vo(t,e){return void 0!==_s[t]&&(void 0===e?_s[t]:(_s[t]=e,"s"===t&&(_s.ss=e-1),!0))}function go(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),i=fo(this,!t,e);return t&&(i=e.pastFuture(+this,i)),e.postformat(i)}function yo(){if(!this.isValid())return this.localeData().invalidDate();var t,e,i,o=ws(this._milliseconds)/1e3,n=ws(this._days),s=ws(this._months);t=b(o/60),e=b(t/60),o%=60,t%=60,i=b(s/12),s%=12;var r=i,a=s,h=n,d=e,l=t,u=o,c=this.asSeconds();return c?(c<0?"-":"")+"P"+(r?r+"Y":"")+(a?a+"M":"")+(h?h+"D":"")+(d||l||u?"T":"")+(d?d+"H":"")+(l?l+"M":"")+(u?u+"S":""):"P0D"}var bo,_o;_o=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this)
 ,i=e.length>>>0,o=0;o<i;o++)if(o in e&&t.call(this,e[o],o,e))return!0;return!1};var wo=_o,xo=e.momentProperties=[],ko=!1,Mo={};e.suppressDeprecationWarnings=!1,e.deprecationHandler=null;var So;So=Object.keys?Object.keys:function(t){var e,i=[];for(e in t)d(t,e)&&i.push(e);return i};var Do,Oo=So,Co={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},To={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"},Eo=/\d{1,2}/,Po={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"},Io={},No={},Ro=/(\[[^\[]*\])|(\\)?([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,Ao=/(\[[^\[]*\])
 |(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,zo={},Lo={},Fo=/\d/,Bo=/\d\d/,jo=/\d{3}/,Ho=/\d{4}/,Wo=/[+-]?\d{6}/,Yo=/\d\d?/,Go=/\d\d\d\d?/,Vo=/\d\d\d\d\d\d?/,Uo=/\d{1,3}/,qo=/\d{1,4}/,Xo=/[+-]?\d{1,6}/,Zo=/\d+/,Ko=/[+-]?\d+/,Jo=/Z|[+-]\d\d:?\d\d/gi,Qo=/Z|[+-]\d\d(?::?\d\d)?/gi,$o=/[+-]?\d+(\.\d{1,3})?/,tn=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,en={},on={},nn=0,sn=1,rn=2,an=3,hn=4,dn=5,ln=6,un=7,cn=8;Do=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1};var pn=Do;U("M",["MM",2],"Mo",function(){return this.month()+1}),U("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),U("MMMM",0,0,function(t){return this.localeData().months(this,t)}),A("month","M"),F("month",8),J("M",Yo),J("MM",Yo,Bo),J("MMM",function(t,e){return e.monthsShortRegex(t)}),J("MMMM",function(t,e){return e.monthsRegex(t)}),et(["M","MM"],function(t,e){e[sn]=_(t)-1}),et
 (["MMM","MMMM"],function(t,e,i,o){var n=i._locale.monthsParse(t,o,i._strict);null!=n?e[sn]=n:p(i).invalidMonth=t});var fn=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,mn="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),vn="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),gn=tn,yn=tn;U("Y",0,0,function(){var t=this.year();return t<=9999?""+t:"+"+t}),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"),A("year","y"),F("year",1),J("Y",Ko),J("YY",Yo,Bo),J("YYYY",qo,Ho),J("YYYYY",Xo,Wo),J("YYYYYY",Xo,Wo),et(["YYYYY","YYYYYY"],nn),et("YYYY",function(t,i){i[nn]=2===t.length?e.parseTwoDigitYear(t):_(t)}),et("YY",function(t,i){i[nn]=e.parseTwoDigitYear(t)}),et("Y",function(t,e){e[nn]=parseInt(t,10)}),e.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var bn=j("FullYear",!0);U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),A("week","w"),A("isoWe
 ek","W"),F("week",5),F("isoWeek",5),J("w",Yo),J("ww",Yo,Bo),J("W",Yo),J("WW",Yo,Bo),it(["w","ww","W","WW"],function(t,e,i,o){e[o.substr(0,1)]=_(t)});var _n={dow:0,doy:6};U("d",0,"do","day"),U("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),U("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),U("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),A("day","d"),A("weekday","e"),A("isoWeekday","E"),F("day",11),F("weekday",11),F("isoWeekday",11),J("d",Yo),J("e",Yo),J("E",Yo),J("dd",function(t,e){return e.weekdaysMinRegex(t)}),J("ddd",function(t,e){return e.weekdaysShortRegex(t)}),J("dddd",function(t,e){return e.weekdaysRegex(t)}),it(["dd","ddd","dddd"],function(t,e,i,o){var n=i._locale.weekdaysParse(t,o,i._strict);null!=n?e.d=n:p(i).invalidWeekday=t}),it(["d","e","E"],function(t,e,i,o){e[o]=_(t)});var wn="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),xn="Sun_Mon_Tue_W
 ed_Thu_Fri_Sat".split("_"),kn="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Mn=tn,Sn=tn,Dn=tn;U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Yt),U("k",["kk",2],0,Gt),U("hmm",0,0,function(){return""+Yt.apply(this)+V(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Yt.apply(this)+V(this.minutes(),2)+V(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+V(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+V(this.minutes(),2)+V(this.seconds(),2)}),Vt("a",!0),Vt("A",!1),A("hour","h"),F("hour",13),J("a",Ut),J("A",Ut),J("H",Yo),J("h",Yo),J("k",Yo),J("HH",Yo,Bo),J("hh",Yo,Bo),J("kk",Yo,Bo),J("hmm",Go),J("hmmss",Vo),J("Hmm",Go),J("Hmmss",Vo),et(["H","HH"],an),et(["k","kk"],function(t,e,i){var o=_(t);e[an]=24===o?0:o}),et(["a","A"],function(t,e,i){i._isPm=i._locale.isPM(t),i._meridiem=t}),et(["h","hh"],function(t,e,i){e[an]=_(t),p(i).bigHour=!0}),et("hmm",function(t,e,i){var o=t.length-2;e[an]=_(t.substr(0,o)),e[hn]=_(t.substr(o)),p(i).bigHour=!0}),et("hmmss",function(t,e,i){
 var o=t.length-4,n=t.length-2;e[an]=_(t.substr(0,o)),e[hn]=_(t.substr(o,2)),e[dn]=_(t.substr(n)),p(i).bigHour=!0}),et("Hmm",function(t,e,i){var o=t.length-2;e[an]=_(t.substr(0,o)),e[hn]=_(t.substr(o))}),et("Hmmss",function(t,e,i){var o=t.length-4,n=t.length-2;e[an]=_(t.substr(0,o)),e[hn]=_(t.substr(o,2)),e[dn]=_(t.substr(n))});var On,Cn=/[ap]\.?m?\.?/i,Tn=j("Hours",!0),En={calendar:Co,longDateFormat:To,invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:Eo,relativeTime:Po,months:mn,monthsShort:vn,week:_n,weekdays:wn,weekdaysMin:kn,weekdaysShort:xn,meridiemParse:Cn},Pn={},In={},Nn=/^\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)?)?$/,Rn=/^\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)?)?$/,An=/Z|[+-]\d\d(?::?\d\d)?/,zn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GG
 GG-[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}/]],Ln=[["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/]],Fn=/^\/?Date\((\-?\d+)/i,Bn=/^((?: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}))$/;e.createFromInputFallback=k("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 up
 coming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),e.ISO_8601=function(){},e.RFC_2822=function(){};var jn=k("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=be.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:m()}),Hn=k("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=be.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:m()}),Wn=function(){return Date.now?Date.now():+new Date},Yn=["year","quarter","month","week","day","hour","minute","second","millisecond"];Te("Z",":"),Te("ZZ",""),J("Z",Qo),J("ZZ",Qo),et(["Z","ZZ"],function(t,e,i){i._useUTC=!0,i._tzm=Ee(Qo,t)});var Gn=/([\+\-]|\d\d)/gi;e.updateOffset=function(){};var Vn=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Un=/^(-)?P(?:(-?[0-9,.]*)Y
 )?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Ge.fn=De.prototype,Ge.invalid=Se;var qn=Xe(1,"add"),Xn=Xe(-1,"subtract");e.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",e.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Zn=k("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});U(0,["gg",2],0,function(){return this.weekYear()%100}),U(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Ti("gggg","weekYear"),Ti("ggggg","weekYear"),Ti("GGGG","isoWeekYear"),Ti("GGGGG","isoWeekYear"),A("weekYear","gg"),A("isoWeekYear","GG"),F("weekYear",1),F("isoWeekYear",1),J("G",Ko),J("g",Ko),J("GG",Yo,Bo),J("gg",Yo,Bo),J("GGGG",qo,Ho),J("gggg",qo,Ho),J("GGGGG",Xo,Wo),J("ggggg",Xo,Wo),it(["gggg","ggggg","GGGG","GGGGG"],function(t,e,i,o){e[o.substr(0,2)]=_(t)}),it(["gg","GG"],function(t,
 i,o,n){i[n]=e.parseTwoDigitYear(t)}),U("Q",0,"Qo","quarter"),A("quarter","Q"),F("quarter",7),J("Q",Fo),et("Q",function(t,e){e[sn]=3*(_(t)-1)}),U("D",["DD",2],"Do","date"),A("date","D"),F("date",9),J("D",Yo),J("DD",Yo,Bo),J("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),et(["D","DD"],rn),et("Do",function(t,e){e[rn]=_(t.match(Yo)[0],10)});var Kn=j("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),A("dayOfYear","DDD"),F("dayOfYear",4),J("DDD",Uo),J("DDDD",jo),et(["DDD","DDDD"],function(t,e,i){i._dayOfYear=_(t)}),U("m",["mm",2],0,"minute"),A("minute","m"),F("minute",14),J("m",Yo),J("mm",Yo,Bo),et(["m","mm"],hn);var Jn=j("Minutes",!1);U("s",["ss",2],0,"second"),A("second","s"),F("second",15),J("s",Yo),J("ss",Yo,Bo),et(["s","ss"],dn);var Qn=j("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(){re
 turn 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()}),A("millisecond","ms"),F("millisecond",16),J("S",Uo,Fo),J("SS",Uo,Bo),J("SSS",Uo,jo);var $n;for($n="SSSS";$n.length<=9;$n+="S")J($n,Zo);for($n="S";$n.length<=9;$n+="S")et($n,Fi);var ts=j("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var es=g.prototype;es.add=qn,es.calendar=Je,es.clone=Qe,es.diff=si,es.endOf=yi,es.format=li,es.from=ui,es.fromNow=ci,es.to=pi,es.toNow=fi,es.get=Y,es.invalidAt=Oi,es.isAfter=$e,es.isBefore=ti,es.isBetween=ei,es.isSame=ii,es.isSameOrAfter=oi,es.isSameOrBefore=ni,es.isValid=Si,es.lang=Zn,es.locale=mi,es.localeData=vi,es.max=Hn,es.min=jn,es.parsingFlags=Di,es.set=G,es.startOf=gi,es.subtract=Xn,es.toArra
 y=xi,es.toObject=ki,es.toDate=wi,es.toISOString=hi,es.inspect=di,es.toJSON=Mi,es.toString=ai,es.unix=_i,es.valueOf=bi,es.creationData=Ci,es.year=bn,es.isLeapYear=gt,es.weekYear=Ei,es.isoWeekYear=Pi,es.quarter=es.quarters=zi,es.month=lt,es.daysInMonth=ut,es.week=es.weeks=Ot,es.isoWeek=es.isoWeeks=Ct,es.weeksInYear=Ni,es.isoWeeksInYear=Ii,es.date=Kn,es.day=es.days=zt,es.weekday=Lt,es.isoWeekday=Ft,es.dayOfYear=Li,es.hour=es.hours=Tn,es.minute=es.minutes=Jn,es.second=es.seconds=Qn,es.millisecond=es.milliseconds=ts,es.utcOffset=Ne,es.utc=Ae,es.local=ze,es.parseZone=Le,es.hasAlignedHourOffset=Fe,es.isDST=Be,es.isLocal=He,es.isUtcOffset=We,es.isUtc=Ye,es.isUTC=Ye,es.zoneAbbr=Bi,es.zoneName=ji,es.dates=k("dates accessor is deprecated. Use date instead.",Kn),es.months=k("months accessor is deprecated. Use month instead",lt),es.years=k("years accessor is deprecated. Use year instead",bn),es.zone=k("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warn
 ings/zone/",Re),es.isDSTShifted=k("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",je);var is=C.prototype;is.calendar=T,is.longDateFormat=E,is.invalidDate=P,is.ordinal=I,is.preparse=Yi,is.postformat=Yi,is.relativeTime=N,is.pastFuture=R,is.set=D,is.months=st,is.monthsShort=rt,is.monthsParse=ht,is.monthsRegex=pt,is.monthsShortRegex=ct,is.week=Mt,is.firstDayOfYear=Dt,is.firstDayOfWeek=St,is.weekdays=Pt,is.weekdaysMin=Nt,is.weekdaysShort=It,is.weekdaysParse=At,is.weekdaysRegex=Bt,is.weekdaysShortRegex=jt,is.weekdaysMinRegex=Ht,is.isPM=qt,is.meridiem=Xt,Qt("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===_(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),e.lang=k("moment.lang is deprecated. Use moment.locale instead.",Qt),e.langData=k("moment.langData is deprecated. Use moment.localeData instead.",ee);var os=Math.abs,ns=ho("ms"),ss=ho("s"),rs=ho("m"),as=ho("h"),hs=ho("d"),ds=h
 o("w"),ls=ho("M"),us=ho("y"),cs=uo("milliseconds"),ps=uo("seconds"),fs=uo("minutes"),ms=uo("hours"),vs=uo("days"),gs=uo("months"),ys=uo("years"),bs=Math.round,_s={ss:44,s:45,m:45,h:22,d:26,M:11},ws=Math.abs,xs=De.prototype;return xs.isValid=Me,xs.abs=Qi,xs.add=to,xs.subtract=eo,xs.as=ro,xs.asMilliseconds=ns,xs.asSeconds=ss,xs.asMinutes=rs,xs.asHours=as,xs.asDays=hs,xs.asWeeks=ds,xs.asMonths=ls,xs.asYears=us,xs.valueOf=ao,xs._bubble=oo,xs.get=lo,xs.milliseconds=cs,xs.seconds=ps,xs.minutes=fs,xs.hours=ms,xs.days=vs,xs.weeks=co,xs.months=gs,xs.years=ys,xs.humanize=go,xs.toISOString=yo,xs.toString=yo,xs.toJSON=yo,xs.locale=mi,xs.localeData=vi,xs.toIsoString=k("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",yo),xs.lang=Zn,U("X",0,0,"unix"),U("x",0,0,"valueOf"),J("x",Ko),J("X",$o),et("X",function(t,e,i){i._d=new Date(1e3*parseFloat(t,10))}),et("x",function(t,e,i){i._d=new Date(_(t))}),e.version="2.18.1",function(t){bo=t}(be),e.fn=es,e.min=we,e.max=xe,
 e.now=Wn,e.utc=u,e.unix=Hi,e.months=qi,e.isDate=a,e.locale=Qt,e.invalid=m,e.duration=Ge,e.isMoment=y,e.weekdays=Zi,e.parseZone=Wi,e.localeData=ee,e.isDuration=Oe,e.monthsShort=Xi,e.weekdaysMin=Ji,e.defineLocale=$t,e.updateLocale=te,e.locales=ie,e.weekdaysShort=Ki,e.normalizeUnits=z,e.relativeTimeRounding=mo,e.relativeTimeThreshold=vo,e.calendarFormat=Ke,e.prototype=es,e})}).call(e,i(84)(t))},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}},function(t,e){function i(t){throw new Error("Cannot find module '"+t+"'.")}i.keys=function(){return[]},i.resolve=i,t.exports=i,i.id=85},function(t,e){(function(e){function i(t,e,i){var o=e&&i||0,n=0;for(e=e||[],t.toLowerCase().replace(/[0-9a-f]{2}/g,function(t){n<16&&(e[o+n++]=u[t])});n<16;)e[o+n++]=0;return e}function o(t,e){var i=e||0,o=l;return o[t[i++]]+o[t[i++]]+o[t[i++]]+o[t[i++]]+"-"+o[t[i++]]+o[t[i++]]+"-"+o[t[i++]]+o[t[i++]]+"-"+o[t[i++]]+o[t[i++]]+"-
 "+o[t[i++]]+o[t[i++]]+o[t[i++]]+o[t[i++]]+o[t[i++]]+o[t[i++]]}function n(t,e,i){var n=e&&i||0,s=e||[];t=t||{};var r=void 0!==t.clockseq?t.clockseq:m,a=void 0!==t.msecs?t.msecs:(new Date).getTime(),h=void 0!==t.nsecs?t.nsecs:g+1,d=a-v+(h-g)/1e4;if(d<0&&void 0===t.clockseq&&(r=r+1&16383),(d<0||a>v)&&void 0===t.nsecs&&(h=0),h>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");v=a,g=h,m=r,a+=122192928e5;var l=(1e4*(268435455&a)+h)%4294967296;s[n++]=l>>>24&255,s[n++]=l>>>16&255,s[n++]=l>>>8&255,s[n++]=255&l;var u=a/4294967296*1e4&268435455;s[n++]=u>>>8&255,s[n++]=255&u,s[n++]=u>>>24&15|16,s[n++]=u>>>16&255,s[n++]=r>>>8|128,s[n++]=255&r;for(var c=t.node||f,p=0;p<6;p++)s[n+p]=c[p];return e||o(s)}function s(t,e,i){var n=e&&i||0;"string"==typeof t&&(e="binary"==t?new Array(16):null,t=null),t=t||{};var s=t.random||(t.rng||r)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,e)for(var a=0;a<16;a++)e[n+a]=s[a];return e||o(s)}var r,a="undefined"!=typeof window?window:void 0!==e?e:null;i
 f(a&&a.crypto&&crypto.getRandomValues){var h=new Uint8Array(16);r=function(){return crypto.getRandomValues(h),h}}if(!r){var d=new Array(16);r=function(){for(var t,e=0;e<16;e++)0==(3&e)&&(t=4294967296*Math.random()),d[e]=t>>>((3&e)<<3)&255;return d}}for(var l=[],u={},c=0;c<256;c++)l[c]=(c+256).toString(16).substr(1),u[l[c]]=c;var p=r(),f=[1|p[0],p[1],p[2],p[3],p[4],p[5]],m=16383&(p[6]<<8|p[7]),v=0,g=0,y=s;y.v1=n,y.v4=s,y.parse=i,y.unparse=o,t.exports=y}).call(e,function(){return this}())},function(t,e,i){e.util=i(1),e.DOMutil=i(88),e.DataSet=i(89),e.DataView=i(93),e.Queue=i(92),e.Graph3d=i(94),e.graph3d={Camera:i(102),Filter:i(107),Point2d:i(101),Point3d:i(100),Slider:i(108),StepNumber:i(109)},e.moment=i(82),e.Hammer=i(112),e.keycharm=i(115)},function(t,e){e.prepareElements=function(t){for(var e in t)t.hasOwnProperty(e)&&(t[e].redundant=t[e].used,t[e].used=[])},e.cleanupElements=function(t){for(var e in t)if(t.hasOwnProperty(e)&&t[e].redundant){for(var i=0;i<t[e].redundant.length;i++
 )t[e].redundant[i].parentNode.removeChild(t[e].redundant[i]);t[e].redundant=[]}},e.resetElements=function(t){e.prepareElements(t),e.cleanupElements(t),e.prepareElements(t)},e.getSVGElement=function(t,e,i){var o;return e.hasOwnProperty(t)?e[t].redundant.length>0?(o=e[t].redundant[0],e[t].redundant.shift()):(o=document.createElementNS("http://www.w3.org/2000/svg",t),i.appendChild(o)):(o=document.createElementNS("http://www.w3.org/2000/svg",t),e[t]={used:[],redundant:[]},i.appendChild(o)),e[t].used.push(o),o},e.getDOMElement=function(t,e,i,o){var n;return e.hasOwnProperty(t)?e[t].redundant.length>0?(n=e[t].redundant[0],e[t].redundant.shift()):(n=document.createElement(t),void 0!==o?i.insertBefore(n,o):i.appendChild(n)):(n=document.createElement(t),e[t]={used:[],redundant:[]},void 0!==o?i.insertBefore(n,o):i.appendChild(n)),e[t].used.push(n),n},e.drawPoint=function(t,i,o,n,s,r){var a;if("circle"==o.style?(a=e.getSVGElement("circle",n,s),a.setAttributeNS(null,"cx",t),a.setAttributeNS(nul
 l,"cy",i),a.setAttributeNS(null,"r",.5*o.size)):(a=e.getSVGElement("rect",n,s),a.setAttributeNS(null,"x",t-.5*o.size),a.setAttributeNS(null,"y",i-.5*o.size),a.setAttributeNS(null,"width",o.size),a.setAttributeNS(null,"height",o.size)),void 0!==o.styles&&a.setAttributeNS(null,"style",o.styles),a.setAttributeNS(null,"class",o.className+" vis-point"),r){var h=e.getSVGElement("text",n,s);r.xOffset&&(t+=r.xOffset),r.yOffset&&(i+=r.yOffset),r.content&&(h.textContent=r.content),r.className&&h.setAttributeNS(null,"class",r.className+" vis-label"),h.setAttributeNS(null,"x",t),h.setAttributeNS(null,"y",i)}return a},e.drawBar=function(t,i,o,n,s,r,a,h){if(0!=n){n<0&&(n*=-1,i-=n);var d=e.getSVGElement("rect",r,a);d.setAttributeNS(null,"x",t-.5*o),d.setAttributeNS(null,"y",i),d.setAttributeNS(null,"width",o),d.setAttributeNS(null,"height",n),d.setAttributeNS(null,"class",s),h&&d.setAttributeNS(null,"style",h)}}},function(t,e,i){function o(t){return t&&t.__esModule?t:{default:t}}function n(t,e){if
 (t&&!Array.isArray(t)&&(e=t,t=null),this._options=e||{},this._data={},this.length=0,this._fieldId=this._options.fieldId||"id",this._type={},this._options.type)for(var i=(0,l.default)(this._options.type),o=0,n=i.length;o<n;o++){var s=i[o],r=this._options.type[s];this._type[s]="Date"==r||"ISODate"==r||"ASPDate"==r?"Date":r}if(this._options.convert)throw new Error('Option "convert" is deprecated. Use "type" instead.');this._subscribers={},t&&this.add(t),this.setOptions(e)}var s=i(90),r=o(s),a=i(62),h=o(a),d=i(58),l=o(d),u=i(1),c=i(92);n.prototype.setOptions=function(t){t&&void 0!==t.queue&&(!1===t.queue?this._queue&&(this._queue.destroy(),delete this._queue):(this._queue||(this._queue=c.extend(this,{replace:["add","update","remove"]})),"object"===(0,h.default)(t.queue)&&this._queue.setOptions(t.queue)))},n.prototype.on=function(t,e){var i=this._subscribers[t];i||(i=[],this._subscribers[t]=i),i.push({callback:e})},n.prototype.subscribe=function(){throw new Error("DataSet.subscribe is de
 precated. Use DataSet.on instead.")},n.prototype.off=function(t,e){var i=this._subscribers[t];i&&(this._subscribers[t]=i.filter(function(t){return t.callback!=e}))},n.prototype.unsubscribe=function(){throw new Error("DataSet.unsubscribe is deprecated. Use DataSet.off instead.")},n.prototype._trigger=function(t,e,i){if("*"==t)throw new Error("Cannot trigger event *");var o=[];t in this._subscribers&&(o=o.concat(this._subscribers[t])),"*"in this._subscribers&&(o=o.concat(this._subscribers["*"]));for(var n=0,s=o.length;n<s;n++){var r=o[n];r.callback&&r.callback(t,e,i||null)}},n.prototype.add=function(t,e){var i,o=[],n=this;if(Array.isArray(t))for(var s=0,r=t.length;s<r;s++)i=n._addItem(t[s]),o.push(i);else{if(!t||"object"!==(void 0===t?"undefined":(0,h.default)(t)))throw new Error("Unknown dataT

<TRUNCATED>

[2/2] hive git commit: HIVE-17300: WebUI query plan graphs (Karen Coppage, reviewed by Szehon Ho and Peter Vary)

Posted by pv...@apache.org.
HIVE-17300: WebUI query plan graphs (Karen Coppage, reviewed by Szehon Ho and Peter Vary)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/1cfe4f91
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/1cfe4f91
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/1cfe4f91

Branch: refs/heads/master
Commit: 1cfe4f913b7806707259c0894ddb991d2e3ddae4
Parents: 6c34a37
Author: Karen Coppage <ka...@cloudera.com>
Authored: Thu Oct 4 18:44:24 2018 +0200
Committer: Peter Vary <pv...@cloudera.com>
Committed: Thu Oct 4 18:44:24 2018 +0200

----------------------------------------------------------------------
 .../org/apache/hadoop/hive/common/LogUtils.java |  25 +
 .../org/apache/hadoop/hive/conf/HiveConf.java   |  11 +
 .../service/cli/session/TestQueryDisplay.java   |  83 +++
 .../java/org/apache/hadoop/hive/ql/Driver.java  |  20 +-
 .../org/apache/hadoop/hive/ql/MapRedStats.java  |  12 +-
 .../org/apache/hadoop/hive/ql/QueryDisplay.java |  82 +++
 .../org/apache/hadoop/hive/ql/QueryInfo.java    |  10 +
 .../apache/hadoop/hive/ql/exec/ExplainTask.java |   5 +-
 .../hive/ql/exec/mr/HadoopJobExecHelper.java    |  34 +-
 .../hadoop/hive/ql/exec/mr/MapRedTask.java      |  16 +
 .../org/apache/hive/tmpl/QueryProfileTmpl.jamon |  91 +++-
 .../service/cli/operation/SQLOperation.java     |   3 +
 .../static/css/query-plan-graph.css             |  22 +
 .../hive-webapps/static/js/query-plan-graph.js  | 533 +++++++++++++++++++
 .../resources/hive-webapps/static/js/vis.min.js |  63 +++
 15 files changed, 975 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/common/src/java/org/apache/hadoop/hive/common/LogUtils.java
----------------------------------------------------------------------
diff --git a/common/src/java/org/apache/hadoop/hive/common/LogUtils.java b/common/src/java/org/apache/hadoop/hive/common/LogUtils.java
index 5068eb5..874a3e1 100644
--- a/common/src/java/org/apache/hadoop/hive/common/LogUtils.java
+++ b/common/src/java/org/apache/hadoop/hive/common/LogUtils.java
@@ -29,7 +29,10 @@ import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.appender.FileAppender;
+import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender;
 import org.apache.logging.log4j.core.appender.routing.RoutingAppender;
 import org.apache.logging.log4j.core.config.Configurator;
 import org.apache.logging.log4j.core.config.LoggerConfig;
@@ -231,6 +234,28 @@ public class LogUtils {
   }
 
   /**
+   * Get path of the log file for user to see on the WebUI.
+   */
+  public static String getLogFilePath() {
+    String logFilePath = null;
+    org.apache.logging.log4j.Logger rootLogger = LogManager.getRootLogger();
+    if (rootLogger instanceof org.apache.logging.log4j.core.Logger) {
+      org.apache.logging.log4j.core.Logger coreLogger =
+          (org.apache.logging.log4j.core.Logger)rootLogger;
+      for (Appender appender : coreLogger.getAppenders().values()) {
+        if (appender instanceof FileAppender) {
+          logFilePath = ((FileAppender) appender).getFileName();
+        } else if (appender instanceof RollingFileAppender) {
+          logFilePath = ((RollingFileAppender) appender).getFileName();
+        } else if (appender instanceof RollingRandomAccessFileAppender) {
+          logFilePath = ((RollingRandomAccessFileAppender) appender).getFileName();
+        }
+      }
+    }
+    return logFilePath;
+  }
+
+  /**
    * Stop the subordinate appender for the operation log so it will not leak a file descriptor.
    * @param routingAppenderName the name of the RoutingAppender
    * @param queryId the id of the query that is closing

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
----------------------------------------------------------------------
diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index 799fc05..58951ef 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -3140,6 +3140,17 @@ public class HiveConf extends Configuration {
     HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT("hive.server2.webui.explain.output", false,
         "When set to true, the EXPLAIN output for every query is displayed"
             + " in the HS2 WebUI / Drilldown / Query Plan tab.\n"),
+    HIVE_SERVER2_WEBUI_SHOW_GRAPH("hive.server2.webui.show.graph", false,
+        "Set this to true to to display query plan as a graph instead of text in the WebUI. " +
+        "Only works with hive.server2.webui.explain.output set to true."),
+    HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE("hive.server2.webui.max.graph.size", 25,
+        "Max number of stages graph can display. If number of stages exceeds this, no query" +
+        "plan will be shown. Only works when hive.server2.webui.show.graph and " +
+        "hive.server2.webui.explain.output set to true."),
+    HIVE_SERVER2_WEBUI_SHOW_STATS("hive.server2.webui.show.stats", false,
+        "Set this to true to to display statistics for MapReduce tasks in the WebUI. " +
+        "Only works when hive.server2.webui.show.graph and hive.server2.webui.explain.output " +
+        "set to true."),
     HIVE_SERVER2_WEBUI_ENABLE_CORS("hive.server2.webui.enable.cors", false,
       "Whether to enable cross origin requests (CORS)\n"),
     HIVE_SERVER2_WEBUI_CORS_ALLOWED_ORIGINS("hive.server2.webui.cors.allowed.origins", "*",

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java
----------------------------------------------------------------------
diff --git a/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java b/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java
index 95b46a8..a65388a 100644
--- a/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java
+++ b/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java
@@ -151,6 +151,89 @@ public class TestQueryDisplay {
     }
   }
 
+  /**
+   * Test for the HiveConf options HIVE_SERVER2_WEBUI_SHOW_GRAPH,
+   * HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE.
+   */
+  @Test
+  public void checkWebuiShowGraph() throws Exception {
+    // WebUI-related boolean confs must be set before build, since the implementation of
+    // QueryProfileTmpl.jamon depends on them.
+    // They depend on HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT being set to true.
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT, true);
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH, true);
+
+    HiveSession session = sessionManager
+        .createSession(new SessionHandle(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8),
+            TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8, "testuser", "", "",
+            new HashMap<String, String>(), false, "");
+    SessionState.start(conf);
+
+    session.getSessionConf()
+        .setIntVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE, 0);
+    testGraphDDL(session, true);
+    session.getSessionConf()
+        .setIntVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE, 40);
+    testGraphDDL(session, false);
+
+    session.close();
+    resetConfToDefaults();
+  }
+
+  private void testGraphDDL(HiveSession session, boolean exceedMaxGraphSize) throws Exception {
+    OperationHandle opHandleGraph = session.executeStatement("show tables", null);
+    session.closeOperation(opHandleGraph);
+
+    // Check for a query plan. If the graph size exceeds the max allowed, none should appear.
+    verifyDDLHtml("Query information not available.",
+        opHandleGraph.getHandleIdentifier().toString(), exceedMaxGraphSize);
+    verifyDDLHtml("STAGE DEPENDENCIES",
+        opHandleGraph.getHandleIdentifier().toString(), !exceedMaxGraphSize);
+    // Check that if plan Json is there, it is not empty
+    verifyDDLHtml("jsonPlan = {}", opHandleGraph.getHandleIdentifier().toString(), false);
+  }
+
+  /**
+   * Test for the HiveConf option HIVE_SERVER2_WEBUI_SHOW_STATS, which is available for MapReduce
+   * jobs only.
+   */
+  @Test
+  public void checkWebUIShowStats() throws Exception {
+    // WebUI-related boolean confs must be set before build. HIVE_SERVER2_WEBUI_SHOW_STATS depends
+    // on HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT and HIVE_SERVER2_WEBUI_SHOW_GRAPH being set to true.
+    conf.setVar(HiveConf.ConfVars.HIVE_EXECUTION_ENGINE, "mr");
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT, true);
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH, true);
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE, 40);
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_STATS, true);
+
+    HiveSession session = sessionManager
+        .createSession(new SessionHandle(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8),
+            TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8, "testuser", "", "",
+            new HashMap<String, String>(), false, "");
+    SessionState.start(conf);
+
+    OperationHandle opHandleSetup =
+        session.executeStatement("CREATE TABLE statsTable (i int)", null);
+    session.closeOperation(opHandleSetup);
+    OperationHandle opHandleMrQuery =
+        session.executeStatement("INSERT INTO statsTable VALUES (0)", null);
+    session.closeOperation(opHandleMrQuery);
+
+    // INSERT queries include  a MapReduce task.
+    verifyDDLHtml("Counters", opHandleMrQuery.getHandleIdentifier().toString(), true);
+
+    session.close();
+    resetConfToDefaults();
+  }
+
+  private void resetConfToDefaults() {
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT, false);
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH, false);
+    conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_STATS, false);
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE, 25);
+  }
+
   private void verifyDDL(QueryInfo queryInfo, String stmt, String handle, boolean finished) {
 
     Assert.assertEquals(queryInfo.getUserName(), "testuser");

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
index 95619a4..6441e67 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
@@ -149,6 +149,7 @@ import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hive.common.util.ShutdownHookManager;
 import org.apache.hive.common.util.TxnIdUtils;
 import org.apache.thrift.TException;
+import org.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -1035,9 +1036,22 @@ public class Driver implements IDriver {
     PrintStream ps = new PrintStream(baos);
     try {
       List<Task<?>> rootTasks = sem.getAllRootTasks();
-      task.getJSONPlan(ps, rootTasks, sem.getFetchTask(), false, true, true, sem.getCboInfo(),
-          plan.getOptimizedQueryString());
-      ret = baos.toString();
+      if (conf.getBoolVar(ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH)) {
+        JSONObject jsonPlan = task.getJSONPlan(
+            null, rootTasks, sem.getFetchTask(), true, true, true, sem.getCboInfo(),
+            plan.getOptimizedQueryString());
+        if (jsonPlan.getJSONObject(ExplainTask.STAGE_DEPENDENCIES) != null &&
+            jsonPlan.getJSONObject(ExplainTask.STAGE_DEPENDENCIES).length() <=
+                conf.getIntVar(ConfVars.HIVE_SERVER2_WEBUI_MAX_GRAPH_SIZE)) {
+          ret = jsonPlan.toString();
+        } else {
+          ret = null;
+        }
+      } else {
+        task.getJSONPlan(ps, rootTasks, sem.getFetchTask(), false, true, true, sem.getCboInfo(),
+            plan.getOptimizedQueryString());
+        ret = baos.toString();
+      }
     } catch (Exception e) {
       LOG.warn("Exception generating explain output: " + e, e);
     }

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/MapRedStats.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/MapRedStats.java b/ql/src/java/org/apache/hadoop/hive/ql/MapRedStats.java
index ac45ec4..f13b496 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/MapRedStats.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/MapRedStats.java
@@ -40,13 +40,13 @@ public class MapRedStats {
   private static final String CLASS_NAME = MapRedStats.class.getName();
   private static final Logger LOG = LoggerFactory.getLogger(CLASS_NAME);
   private JobConf jobConf;
-  int numMap;
-  int numReduce;
-  long cpuMSec;
-  Counters counters = null;
-  boolean success;
+  private int numMap;
+  private int numReduce;
+  private long cpuMSec;
+  private Counters counters = null;
+  private boolean success;
 
-  String jobId;
+  private String jobId;
 
   private long numModifiedRows;
 

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/QueryDisplay.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/QueryDisplay.java b/ql/src/java/org/apache/hadoop/hive/ql/QueryDisplay.java
index 9a77c29..79cfd84 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/QueryDisplay.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/QueryDisplay.java
@@ -18,16 +18,22 @@
 package org.apache.hadoop.hive.ql;
 
 import com.google.common.collect.ImmutableMap;
+import org.apache.hadoop.hive.common.LogUtils;
 import org.apache.hadoop.hive.ql.exec.Task;
 import org.apache.hadoop.hive.ql.exec.TaskResult;
 import org.apache.hadoop.hive.ql.plan.api.StageType;
 
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.*;
 
+import org.apache.hadoop.mapred.Counters;
+import org.apache.hadoop.mapred.RunningJob;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonWriteNullProperties;
 import org.codehaus.jackson.annotate.JsonIgnore;
+import org.json.JSONException;
+import org.json.JSONObject;
 
 /**
  * Some limited query information to save for WebUI.
@@ -56,16 +62,40 @@ public class QueryDisplay {
     tasks.get(tTask.getId()).updateStatus(tTask);
   }
 
+  public synchronized <T extends Serializable> void updateTaskStatistics(MapRedStats mapRedStats,
+      RunningJob rj, String taskId) throws IOException, JSONException {
+    if (tasks.containsKey(taskId)) {
+      tasks.get(taskId).updateMapRedStatsJson(mapRedStats, rj);
+    }
+  }
+
   //Inner classes
   public enum Phase {
     COMPILATION,
     EXECUTION,
   }
 
+  public String getFullLogLocation() {
+    return LogUtils.getLogFilePath();
+  }
+
   @JsonWriteNullProperties(false)
   @JsonIgnoreProperties(ignoreUnknown = true)
   public static class TaskDisplay {
 
+    public static final String NUMBER_OF_MAPPERS = "Number of Mappers";
+    public static final String NUMBER_OF_REDUCERS = "Number of Reducers";
+    public static final String COUNTERS = "Counters";
+    public static final String JOB_ID = "Job Id";
+    public static final String JOB_FILE = "Job File";
+    public static final String TRACKING_URL = "Tracking URL";
+    public static final String MAP_PROGRESS = "Map Progress (%)";
+    public static final String REDUCE_PROGRESS = "Reduce Progress (%)";
+    public static final String CLEANUP_PROGRESS = "Cleanup Progress (%)";
+    public static final String SETUP_PROGRESS = "Setup Progress (%)";
+    public static final String COMPLETE = "Complete";
+    public static final String SUCCESSFUL = "Successful";
+
     private Integer returnValue;  //if set, determines that task is complete.
     private String errorMsg;
 
@@ -80,6 +110,7 @@ public class QueryDisplay {
     private String name;
     private boolean requireLock;
     private String statusMessage;
+    private JSONObject statsJSON;
 
     // required for jackson
     public TaskDisplay() {
@@ -103,6 +134,57 @@ public class QueryDisplay {
       }
     }
 
+    private void updateMapRedStatsJson(MapRedStats stats, RunningJob rj) throws IOException, JSONException {
+      if (statsJSON == null) {
+        statsJSON = new JSONObject();
+      }
+      if (stats != null) {
+        if (stats.getNumMap() >= 0) {
+          statsJSON.put(NUMBER_OF_MAPPERS, stats.getNumMap());
+        }
+        if (stats.getNumReduce() >= 0) {
+          statsJSON.put(NUMBER_OF_REDUCERS, stats.getNumReduce());
+        }
+        if (stats.getCounters() != null) {
+          statsJSON.put(COUNTERS, getCountersJson(stats.getCounters()));
+        }
+      }
+      if (rj != null) {
+        statsJSON.put(JOB_ID, rj.getID().toString());
+        statsJSON.put(JOB_FILE, rj.getJobFile());
+        statsJSON.put(TRACKING_URL, rj.getTrackingURL());
+        statsJSON.put(MAP_PROGRESS, Math.round(rj.mapProgress() * 100));
+        statsJSON.put(REDUCE_PROGRESS, Math.round(rj.reduceProgress() * 100));
+        statsJSON.put(CLEANUP_PROGRESS, Math.round(rj.cleanupProgress() * 100));
+        statsJSON.put(SETUP_PROGRESS, Math.round(rj.setupProgress() * 100));
+        statsJSON.put(COMPLETE, rj.isComplete());
+        statsJSON.put(SUCCESSFUL, rj.isSuccessful());
+      }
+    }
+
+    public synchronized String getStatsJsonString() {
+      if (statsJSON != null) {
+        return statsJSON.toString();
+      }
+      return null;
+    }
+
+    private JSONObject getCountersJson(Counters ctrs) throws JSONException {
+      JSONObject countersJson = new JSONObject();
+      Iterator<Counters.Group> iterator = ctrs.iterator();
+      while(iterator.hasNext()) {
+        Counters.Group group = iterator.next();
+        Iterator<Counters.Counter> groupIterator = group.iterator();
+        JSONObject groupJson = new JSONObject();
+        while(groupIterator.hasNext()) {
+          Counters.Counter counter = groupIterator.next();
+          groupJson.put(counter.getDisplayName(), counter.getCounter());
+        }
+        countersJson.put(group.getDisplayName(), groupJson);
+      }
+      return countersJson;
+    }
+
     public synchronized Long getElapsedTime() {
       if (endTime == null) {
         if (beginTime == null) {

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/QueryInfo.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/QueryInfo.java b/ql/src/java/org/apache/hadoop/hive/ql/QueryInfo.java
index 0f127ec..376037a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/QueryInfo.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/QueryInfo.java
@@ -32,6 +32,8 @@ public class QueryInfo {
   private String state;
   private QueryDisplay queryDisplay;
 
+  private String operationLogLocation;
+
   public QueryInfo(String state, String userName, String executionEngine, String operationId) {
     this.state = state;
     this.userName = userName;
@@ -99,4 +101,12 @@ public class QueryInfo {
   public synchronized Long getRuntime() {
     return runtime;
   }
+
+  public String getOperationLogLocation() {
+    return operationLogLocation;
+  }
+
+  public void setOperationLogLocation(String operationLogLocation) {
+    this.operationLogLocation = operationLogLocation;
+  }
 }

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java
index 2f20dd4..46bf088 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/ExplainTask.java
@@ -82,6 +82,7 @@ import com.google.common.annotations.VisibleForTesting;
  *
  **/
 public class ExplainTask extends Task<ExplainWork> implements Serializable {
+  public static final String STAGE_DEPENDENCIES = "STAGE DEPENDENCIES";
   private static final long serialVersionUID = 1L;
   public static final String EXPL_COLUMN_NAME = "Explain";
   private final Set<Operator<?>> visitedOps = new HashSet<Operator<?>>();
@@ -283,7 +284,7 @@ public class ExplainTask extends Task<ExplainWork> implements Serializable {
         if (cboInfo != null) {
           outJSONObject.put("cboInfo", cboInfo);
         }
-        outJSONObject.put("STAGE DEPENDENCIES", jsonDependencies);
+        outJSONObject.put(STAGE_DEPENDENCIES, jsonDependencies);
       }
 
       // Go over all the tasks and dump out the plans
@@ -1216,7 +1217,7 @@ public class ExplainTask extends Task<ExplainWork> implements Serializable {
       throws Exception {
 
     if (out != null) {
-      out.println("STAGE DEPENDENCIES:");
+      out.println(STAGE_DEPENDENCIES + ":");
     }
 
     JSONObject json = jsonOutput ? new JSONObject(new LinkedHashMap<>()) : null;

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/HadoopJobExecHelper.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/HadoopJobExecHelper.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/HadoopJobExecHelper.java
index eb6cbf7..cb8d81a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/HadoopJobExecHelper.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/HadoopJobExecHelper.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.hadoop.hive.common.LogUtils;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hadoop.hive.ql.Context;
@@ -56,11 +57,6 @@ import org.apache.hadoop.mapred.RunningJob;
 import org.apache.hadoop.mapred.TaskCompletionEvent;
 import org.apache.hadoop.mapred.TaskReport;
 import org.apache.hive.common.util.ShutdownHookManager;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.appender.FileAppender;
-import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.slf4j.LoggerFactory;
 
 public class HadoopJobExecHelper {
@@ -239,6 +235,10 @@ public class HadoopJobExecHelper {
     List<ClientStatsPublisher> clientStatPublishers = getClientStatPublishers();
     final boolean localMode = ShimLoader.getHadoopShims().isLocalMode(job);
 
+    MapRedStats mapRedStats = new MapRedStats(
+            job, numMap, numReduce, cpuMsec, false, rj.getID().toString());
+    updateMapRedTaskWebUIStatistics(mapRedStats, rj);
+
     while (!rj.isComplete()) {
       if (th.getContext() != null) {
         th.getContext().checkHeartbeaterLockException();
@@ -314,6 +314,11 @@ public class HadoopJobExecHelper {
 
       Counters ctrs = th.getCounters();
 
+      mapRedStats.setCounters(ctrs);
+      mapRedStats.setNumMap(numMap);
+      mapRedStats.setNumReduce(numReduce);
+      updateMapRedTaskWebUIStatistics(mapRedStats, rj);
+
       if (fatal = checkFatalErrors(ctrs, errMsg)) {
         console.printError("[Fatal Error] " + errMsg.toString() + ". Killing the job.");
         rj.killJob();
@@ -419,8 +424,10 @@ public class HadoopJobExecHelper {
       }
     }
 
-    MapRedStats mapRedStats = new MapRedStats(job, numMap, numReduce, cpuMsec, success, rj.getID().toString());
+    mapRedStats.setSuccess(success);
     mapRedStats.setCounters(ctrs);
+    mapRedStats.setCpuMSec(cpuMsec);
+    updateMapRedTaskWebUIStatistics(mapRedStats, rj);
 
     // update based on the final value of the counters
     updateCounters(ctrs, rj);
@@ -443,6 +450,12 @@ public class HadoopJobExecHelper {
     return mapRedStats;
   }
 
+  private void updateMapRedTaskWebUIStatistics(MapRedStats mapRedStats, RunningJob rj) {
+    if (task instanceof MapRedTask) {
+      ((MapRedTask) task).updateWebUiStats(mapRedStats, rj);
+    }
+  }
+
 
   private String getId() {
     return this.task.getId();
@@ -511,14 +524,7 @@ public class HadoopJobExecHelper {
     sb.append("Task ID:\n  " + taskId + "\n\n");
     sb.append("Logs:\n");
     console.printError(sb.toString());
-
-    for (Appender appender : ((Logger) LogManager.getRootLogger()).getAppenders().values()) {
-      if (appender instanceof FileAppender) {
-        console.printError(((FileAppender) appender).getFileName());
-      } else if (appender instanceof RollingFileAppender) {
-        console.printError(((RollingFileAppender) appender).getFileName());
-      }
-    }
+    console.printError(LogUtils.getLogFilePath());
   }
 
   public int progressLocal(Process runningJob, String taskId) {

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/MapRedTask.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/MapRedTask.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/MapRedTask.java
index a71faf8..8266906 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/MapRedTask.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/mr/MapRedTask.java
@@ -38,6 +38,7 @@ import org.apache.hadoop.hive.common.metrics.common.MetricsConstant;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.ql.Context;
 import org.apache.hadoop.hive.ql.DriverContext;
+import org.apache.hadoop.hive.ql.MapRedStats;
 import org.apache.hadoop.hive.ql.exec.Operator;
 import org.apache.hadoop.hive.ql.exec.SerializationUtilities;
 import org.apache.hadoop.hive.ql.exec.Utilities;
@@ -49,6 +50,8 @@ import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.hive.ql.session.SessionState.ResourceType;
 import org.apache.hadoop.hive.shims.ShimLoader;
 import org.apache.hive.common.util.StreamPrinter;
+import org.apache.hadoop.mapred.RunningJob;
+import org.json.JSONException;
 
 /**
  * Extension of ExecDriver:
@@ -496,6 +499,19 @@ public class MapRedTask extends ExecDriver implements Serializable {
     return null;
   }
 
+  public void updateWebUiStats(MapRedStats mapRedStats, RunningJob rj) {
+    if (queryDisplay != null &&
+        conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_STATS) &&
+        conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH) &&
+        conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT)) {
+      try {
+        queryDisplay.updateTaskStatistics(mapRedStats, rj, getId());
+      } catch (IOException | JSONException e) {
+        LOG.error(org.apache.hadoop.util.StringUtils.stringifyException(e), e);
+      }
+    }
+  }
+
   @Override
   public void shutdown() {
     super.shutdown();

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/service/src/jamon/org/apache/hive/tmpl/QueryProfileTmpl.jamon
----------------------------------------------------------------------
diff --git a/service/src/jamon/org/apache/hive/tmpl/QueryProfileTmpl.jamon b/service/src/jamon/org/apache/hive/tmpl/QueryProfileTmpl.jamon
index f04d655..fd3fbc1 100644
--- a/service/src/jamon/org/apache/hive/tmpl/QueryProfileTmpl.jamon
+++ b/service/src/jamon/org/apache/hive/tmpl/QueryProfileTmpl.jamon
@@ -26,6 +26,10 @@ org.apache.hadoop.hive.ql.QueryDisplay;
 org.apache.hadoop.hive.ql.QueryInfo;
 org.apache.hadoop.hive.conf.HiveConf;
 </%import>
+<%class>
+private boolean showGraph = false;
+private boolean showStats = false;
+</%class>
 <!--[if IE]>
 <!DOCTYPE html>
 <![endif]-->
@@ -40,6 +44,22 @@ org.apache.hadoop.hive.conf.HiveConf;
     <link href="/static/css/bootstrap.min.css" rel="stylesheet">
     <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
     <link href="/static/css/hive.css" rel="stylesheet">
+
+    <script src="/static/js/jquery.min.js" type="text/javascript"></script>
+    <script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+    <script src="/static/js/tab.js" type="text/javascript"></script>
+    <%if hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_GRAPH) &&
+      hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT) %>
+      <%java showGraph = true; %>
+      <%if hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_SHOW_STATS) %>
+        <%java showStats = true; %>
+      </%if>
+    </%if>
+    <%if showGraph %>
+      <script type="text/javascript" src="/static/js/vis.min.js"></script>
+      <link href="/static/css/query-plan-graph.css" rel="stylesheet">
+      <script src="/static/js/query-plan-graph.js"></script>
+    </%if>
   </head>
 
   <body>
@@ -204,18 +224,72 @@ org.apache.hadoop.hive.conf.HiveConf;
     <div class="panel panel-default">
       <div class="panel-heading">Explain plan</div>
       <div class="panel-body">
-        <%if hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT) %>
-          <pre>
-          <% queryInfo.getQueryDisplay() == null ? "Unknown" : queryInfo.getQueryDisplay().getExplainPlan() %>
-          </pre>
+        <%if showGraph %>
+          <%if queryInfo.getQueryDisplay() != null &&
+                queryInfo.getQueryDisplay().getExplainPlan() != null &&
+                !queryInfo.getQueryDisplay().getExplainPlan().equals("UNKNOWN")%>
+            <div id='plan-visualization'></div>
+            <%if showStats %>
+              <div class="row">
+                <div class="col-md-6">
+                  <pre id='stage-info'></pre>
+                </div>
+                <div class="col-md-6">
+                  <pre id='statistics-info'><div id='statistics-info-head'></div><div id='statistics-info-body'></div></pre>
+                </div>
+              </div>
+            <%else>
+              <pre id='stage-info'></pre>
+            </%if>
+            <script type="text/javascript">
+              var jsonPlan = <% queryInfo.getQueryDisplay().getExplainPlan() %>
+              var jsonStatuses = {};
+              var jsonStatistics = {};
+              var jsonLogs = {};
+              <%if queryInfo.getOperationLogLocation() != null %>
+                jsonLogs["Operation Log - will be deleted after query completes"] = "<% queryInfo.getOperationLogLocation() %>"
+              </%if>
+              <%if queryInfo.getQueryDisplay().getFullLogLocation() != null %>
+                jsonLogs["Full Log"] = "<% queryInfo.getQueryDisplay().getFullLogLocation() %>"
+              </%if>
+              <%for QueryDisplay.TaskDisplay taskDisplay : queryInfo.getQueryDisplay().getTaskDisplays() %>
+                jsonStatuses["<% taskDisplay.getTaskId() %>"] = "<% taskDisplay.getStatus() %>";
+                <%if showStats && taskDisplay.getStatsJsonString() != null %>
+                  jsonStatistics["<% taskDisplay.getTaskId() %>"] = <% taskDisplay.getStatsJsonString() %>;
+                </%if>
+              </%for>
+              const MAP_PROGRESS = '<% QueryDisplay.TaskDisplay.MAP_PROGRESS %>';
+              const REDUCE_PROGRESS = '<% QueryDisplay.TaskDisplay.REDUCE_PROGRESS %>';
+              network = visualizeJsonPlan('plan-visualization', 'stage-info', 'statistics-info', 'statistics-info-head',
+                'statistics-info-body', jsonPlan, jsonStatuses, jsonStatistics, jsonLogs);
+            </script>
+          <%else>
+            <pre>Query information not available. Query may have failed or plan size may exceed value of config hive.server2.webui.max.graph.size.</pre>
+          </%if>
         <%else>
-          <pre>
-          Set configuration hive.server2.webui.explain.output to true to view future query plans
-          </pre>
+          <%if hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_WEBUI_EXPLAIN_OUTPUT) %>
+            <pre>
+            <% queryInfo.getQueryDisplay() == null ? "Unknown" : queryInfo.getQueryDisplay().getExplainPlan() %>
+            </pre>
+          <%else>
+            <pre>
+            Set configuration hive.server2.webui.explain.output to true to view future query plans
+            </pre>
+          </%if>
         </%if>
       </div>
     </div>
 </%def>
+<%if showGraph %>
+  <script type="text/javascript">
+    // reload network to centralize graph upon switching to "Query Plan" tab
+    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+      if (e.target.toString().includes("queryPlan") && typeof network !== 'undefined') {
+        network.fit();
+      }
+    });
+  </script>
+</%if>
 
 
 <%def perfLogging>
@@ -301,8 +375,5 @@ org.apache.hadoop.hive.conf.HiveConf;
 
 </div>
 </div>
-<script src="/static/js/jquery.min.js" type="text/javascript"></script>
-<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
-<script src="/static/js/tab.js" type="text/javascript"></script>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java
----------------------------------------------------------------------
diff --git a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java
index 0e6bd4d..01c9249 100644
--- a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java
+++ b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java
@@ -184,6 +184,9 @@ public class SQLOperation extends ExecuteStatementOperation {
       }
 
       queryInfo.setQueryDisplay(driver.getQueryDisplay());
+      if (operationLog != null) {
+        queryInfo.setOperationLogLocation(operationLog.toString());
+      }
 
       // set the operation handle information in Driver, so that thrift API users
       // can use the operation handle they receive, to lookup query information in

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/service/src/resources/hive-webapps/static/css/query-plan-graph.css
----------------------------------------------------------------------
diff --git a/service/src/resources/hive-webapps/static/css/query-plan-graph.css b/service/src/resources/hive-webapps/static/css/query-plan-graph.css
new file mode 100644
index 0000000..d4d8c4b
--- /dev/null
+++ b/service/src/resources/hive-webapps/static/css/query-plan-graph.css
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#plan-visualization {
+  width: 100%;
+  min-height: 300px;
+  border: 1px solid grey;
+  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/1cfe4f91/service/src/resources/hive-webapps/static/js/query-plan-graph.js
----------------------------------------------------------------------
diff --git a/service/src/resources/hive-webapps/static/js/query-plan-graph.js b/service/src/resources/hive-webapps/static/js/query-plan-graph.js
new file mode 100644
index 0000000..ac1d1a3
--- /dev/null
+++ b/service/src/resources/hive-webapps/static/js/query-plan-graph.js
@@ -0,0 +1,533 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+* query-plan-graph.js
+*
+* Display a visualization of query plan
+*/
+
+const DEFAULT_TEXT_INDENT = 2;
+const MAX_ORDER_TRIES = 100;
+
+const SUCCESS = "Success";
+const RUNNING = "Running";
+const FAILED = "Failure";
+
+const PROGRESS_ELEMENT = "progress-bar-element";
+const LONGEST_PATH_FROM_ROOT = "longestPathFromRoot";
+const NODE_ID = "nodeId";
+
+const BLUE = {
+  border:'#2B7CE9',
+  background : '#D2E5FF',
+  highlight : {
+  border : '#2B7CE9',
+  background : '#D2E5FF'
+  }
+}
+const GREEN = {
+  border : '#009900',
+  background : '#99E699',
+  highlight : {
+  border : '#009900',
+    background : '#99E699'
+  }
+}
+const PINK = 'pink';
+const LIGHT_GRAY = 'rgba(200,200,200,0.5)';
+
+
+/**
+* Displays query plan as a graph as well as information about a selected stage.
+*/
+function visualizeJsonPlan(displayGraphElement, displayStagePlanElement, displayStatisticsElement,
+  displayStatisticsElementHead, displayStatisticsElementBody, jsonPlan, jsonStatuses, jsonStats,
+  jsonLogs, displayInformationTextIndent = DEFAULT_TEXT_INDENT) {
+
+  setUpInstructions(displayStagePlanElement, displayStatisticsElementHead);
+  networkData = getNodesAndEdges(jsonPlan["STAGE DEPENDENCIES"]);
+  network = createNetwork(networkData.nodes, networkData.edges, displayGraphElement);
+  network.on('click', function (params) {
+    displayStagePlan(params, displayStagePlanElement, jsonPlan, displayInformationTextIndent);
+    if (document.getElementById(displayStatisticsElement) != null) {
+      displayStatistics(params, displayStatisticsElement, displayStatisticsElementHead,
+        displayStatisticsElementBody, jsonStats, jsonStatuses, jsonLogs,
+        displayInformationTextIndent);
+    }
+  });
+  colorTasks(networkData.edges, networkData.nodes, jsonStatuses)
+  return network;
+}
+
+
+function setUpInstructions(displayStagePlanElement, displayStatisticsElementHead) {
+  document.getElementById(displayStagePlanElement).innerHTML =
+    "Click on a stage to view its plan";
+  if (document.getElementById(displayStatisticsElementHead) != null) {
+    document.getElementById(displayStatisticsElementHead).innerHTML =
+      "Click on a colored-in stage to view stats";
+  }
+}
+
+function colorTasks(edges, nodes, jsonStatuses) {
+  grayFilteredOutTasks(edges, nodes, jsonStatuses);
+  showSuccessfulTasks(edges, nodes, jsonStatuses);
+  showRunningTasks(nodes, jsonStatuses);
+  showFailedTasks(nodes, jsonStatuses);
+  }
+
+/**
+* Set color of node or edge
+*/
+function setColor(dataSet, itemToChange, newColor) {
+  itemToChange.color = newColor;
+  dataSet.update(itemToChange);
+}
+
+
+/**
+* Colors all edges connected to the node.
+*/
+function setAllNodeEdgesColor(edgesDataSet, nodeId, newColor) {
+  var theseEdges = edgesDataSet.get({
+    filter: function(item) {
+      return (item.to == nodeId || item.from == nodeId);
+    }});
+  for (var i = theseEdges.length - 1; i >= 0; i--) {
+    setColor(edgesDataSet, theseEdges[i], newColor);
+  }
+}
+
+
+/**
+* If two nodes are the same color, change the color of their connecting edge to match
+*/
+function matchAllEdgeColors(nodesDataSet, edgesDataSet) {
+  for (node in nodesDataSet.getIds()) {
+      nodeId = nodesDataSet.getIds()[node];
+    var toEdges = edgesDataSet.get({
+      filter: function (item) {
+        return item.to == nodeId;
+      }});
+    for (var i = toEdges.length - 1; i >= 0; i--) {
+      if (nodesDataSet.get(nodeId).color == nodesDataSet.get(parseInt(toEdges[i].from)).color) {
+        setColor(edgesDataSet, toEdges[i], nodesDataSet.get(nodeId).color.border);
+      }
+    }
+  }
+}
+
+
+/**
+* If a task is not filtered out by conditional statements, it will be in jsonStatuses.
+* Set all other tasks' node & edge colors to light gray
+*/
+function grayFilteredOutTasks(edgesDataSet, nodesDataSet, jsonStatuses) {
+
+  for (node in nodesDataSet.getIds()) {
+    nodeId = nodesDataSet.getIds()[node];
+    var taskId = "Stage-" + nodeId;
+    var otherTaskId = nodesDataSet.get(nodeId).id;
+    if (!Object.keys(jsonStatuses).includes(taskId)) {
+      setColor(nodesDataSet, nodesDataSet.get(nodeId), LIGHT_GRAY);
+      setAllNodeEdgesColor(edgesDataSet, nodeId, LIGHT_GRAY);
+    }
+  }
+}
+
+
+/**
+* If a task is successful, color it green!
+*/
+function showSuccessfulTasks(edgesDataSet, nodesDataSet, jsonStatuses) {
+  changeNodeColorByStatus(nodesDataSet, jsonStatuses, SUCCESS, GREEN)
+  matchAllEdgeColors(nodesDataSet, edgesDataSet);
+}
+
+function showRunningTasks(nodesDataSet, jsonStatuses) {
+  changeNodeColorByStatus(nodesDataSet, jsonStatuses, RUNNING, BLUE)
+}
+
+function showFailedTasks(nodesDataSet, jsonStatuses) {
+  changeNodeColorByStatus(nodesDataSet, jsonStatuses, FAILED, PINK)
+}
+
+function changeNodeColorByStatus(nodesDataSet, jsonStatuses, statusString, color) {
+  for (node in nodesDataSet.getIds()) {
+    nodeId = nodesDataSet.getIds()[node];
+    var taskId = "Stage-" + nodeId;
+    if (Object.keys(jsonStatuses).includes(taskId)) {
+      if (jsonStatuses[taskId].search(statusString) != -1) {
+        setColor(nodesDataSet, nodesDataSet.get(nodeId), color);
+      }
+    }
+  }
+}
+
+
+/**
+* Removes all non-number characters from string, casts to integer
+* @param {Object} stageDependencies - json object containing node and edge information
+* returns {nodes, edges} - javascript arrayObjects containing node, edge info readable by vis.js
+*/
+function getNodesAndEdges(stageDependencies) {
+  var nodes = [];
+  var edges = [];
+  var paths = [];
+  var childNodes = [];
+  var nodeIndex = 0;
+  var edgeIndex = 0;
+  var newNode = {};
+  var newEdge = {};
+  var nodeId = 0;
+  var newLabel = "";
+  for (stage in stageDependencies) {
+    newNode = {};
+    nodeId = getStageNumber(stage);
+    newNode['id'] = nodeId;
+    newLabel = nodeId + " - " + stageDependencies[stage]["TASK TYPE"];
+    if (stageDependencies[stage]["ROOT STAGE"] == "TRUE") {
+      newLabel += " - ROOT";
+      //create new path
+      paths.push([nodeId]);
+    }
+    else {
+      childNodes.push(nodeId);
+    }
+    newNode['label'] = newLabel;
+    if (stageDependencies[stage]["CONDITIONAL CHILD TASKS"] != null) {
+      newNode['shape'] = 'text';
+    }
+    nodes[nodeIndex] = newNode;
+    edgeIndex = linkStages("DEPENDENT STAGES", stageDependencies, stage, nodeId, edgeIndex, edges);
+    edgeIndex = linkStages("CONDITIONAL CHILD TASKS", stageDependencies, stage, nodeId, edgeIndex,
+      edges, true);
+
+    nodeIndex++;
+  }
+
+  for (var i = paths.length - 1; i >= 0; i--) {
+    for (ndx in childNodes) {
+      paths[i].push(childNodes[ndx]);
+    }
+  }
+  assignNodeLevel(paths, nodes, edges);
+
+  var nodesDataSet = new vis.DataSet(nodes);
+  var edgesDataSet = new vis.DataSet(edges);
+  return {
+    nodes: nodesDataSet,
+    edges: edgesDataSet
+  }
+}
+
+
+/**
+* Make each node's level in hierarchy longest path from any root
+*/
+function assignNodeLevel(paths, nodes, edges) {
+
+  orderPathsByEdgeDirection(paths, edges);
+  for (pathNdx in paths) {
+    prepareMap(paths[pathNdx]);
+    assignLongestPathFromRoot(paths[pathNdx], edges)
+  }
+  assignLevelByLongestPathFromAllRoots(paths, nodes);
+}
+
+
+function orderPathsByEdgeDirection(paths, edges) {
+  for (pathNdx in paths) {
+    var currentPath = paths[pathNdx];
+    var orderedPath = []
+    var listOfEdges = edges.slice(0);
+    for (var edgeNdx = 0; edgeNdx < listOfEdges.length; edgeNdx++) {
+      if (!(currentPath.includes(listOfEdges[edgeNdx].to) && currentPath.includes(listOfEdges[edgeNdx].from))) {
+        listOfEdges.splice(edgeNdx, 1);
+        edgeNdx--;
+      }
+    }
+    var count = 0;
+    while (currentPath.length != 0 && count < MAX_ORDER_TRIES) {
+      for (var nodeNdx in currentPath) {
+        var node = currentPath[nodeNdx];
+        var edgesIn = 0;
+        for (edgeNdx in listOfEdges) {
+          if (listOfEdges[edgeNdx].to == node) {
+            edgesIn++;
+            break;
+          }
+        }
+        if (edgesIn == 0) {
+          orderedPath.push(node);
+          currentPath.splice(nodeNdx, 1);
+          for (var edgeNdx = 0; edgeNdx < listOfEdges.length; edgeNdx++) {
+            if (listOfEdges[edgeNdx].from == node || listOfEdges[edgeNdx].to == node) {
+              listOfEdges.splice(edgeNdx, 1);
+              edgeNdx--;
+            }
+          }
+        }
+      }
+      count++;
+    }
+    paths[pathNdx] = orderedPath;
+  }
+}
+
+
+function prepareMap(currentPath) {
+  for (currentPathNdx in currentPath) {
+    nodeId = currentPath[currentPathNdx];
+    currentPath[currentPathNdx] = {};
+    currentPath[currentPathNdx][NODE_ID] = nodeId;
+    if (currentPathNdx == 0) {
+      currentPath[currentPathNdx][LONGEST_PATH_FROM_ROOT] = 0;
+    }
+    else {
+      currentPath[currentPathNdx][LONGEST_PATH_FROM_ROOT] = -Infinity;
+    }
+  }
+}
+
+
+function assignLongestPathFromRoot(currentPath, edges) {
+  for (var nodeIndex = 1; nodeIndex <= currentPath.length - 1; nodeIndex++) { //skips index 0, root
+    var node = currentPath[nodeIndex];
+    var nodeId = node[NODE_ID];
+    for (var prevNodeIndex = 0; prevNodeIndex < nodeIndex; prevNodeIndex++) {
+      var prevNode = currentPath[prevNodeIndex];
+      for (edgeNdx in edges) {
+        if (edges[edgeNdx].to == nodeId && edges[edgeNdx].from == prevNode.nodeId &&
+          currentPath[nodeIndex][LONGEST_PATH_FROM_ROOT] <= prevNode[LONGEST_PATH_FROM_ROOT]) {
+          currentPath[nodeIndex][LONGEST_PATH_FROM_ROOT] = prevNode[LONGEST_PATH_FROM_ROOT] + 1;
+        }
+      }
+    }
+  }
+}
+
+
+function assignLevelByLongestPathFromAllRoots(paths, nodes) {
+  for (nodeNdx in nodes) {
+    var nodeId = nodes[nodeNdx].id;
+    var longestPath = 0;
+    for (pathNdx in paths) {
+      currentPath = paths[pathNdx];
+      for (pathNodeNdx in currentPath) {
+        if (currentPath[pathNodeNdx][NODE_ID] == nodeId &&
+          currentPath[pathNodeNdx][LONGEST_PATH_FROM_ROOT] > longestPath) {
+          longestPath = currentPath[pathNodeNdx][LONGEST_PATH_FROM_ROOT];
+        }
+      }
+    }
+    nodes[nodeNdx]['level'] = longestPath;
+  }
+}
+
+/**
+* Creates a vis.js hierarchical network
+* @param {nodes} - vis DataSet, node info
+* @param {edges} - vis DataSet, edge info
+* @param {documentElement} - where to place the network
+*/
+function createNetwork(nodes, edges, documentElement) {
+  var data = {
+    nodes: nodes,
+    edges: edges
+  };
+  var container = document.getElementById(documentElement);
+  var options = {
+    layout: {
+      hierarchical: {
+        direction: 'LR',
+        sortMethod: 'directed',
+        levelSeparation: 150,
+        parentCentralization: true
+      }
+    },
+    edges: {
+      smooth: true,
+      arrows: {to : true }
+    },
+    physics: {
+      hierarchicalRepulsion: {
+        nodeDistance: 150
+      }
+    },
+    interaction: {
+      zoomView: false
+    }
+  };
+  var network = new vis.Network(container, data, options);
+  return network;
+}
+
+
+/**
+* Removes all non-number characters from string, casts to integer
+* @param {string} - string to mine the number from
+* returns {int} - the integer needed from the string
+*/
+function getStageNumber(string) {
+  return parseInt(string.replace( /^\D+/g, ''));
+}
+
+function prettifyJsonString(jsonString) {
+  return jsonString.replace(/{/g, "").replace(/}/g, "").replace(/,/g, "");
+}
+
+
+function addDashedEdge(parent, child, edgeIndex, edges) {
+  addEdge(parent, child, edgeIndex, edges);
+  edges[edgeIndex]['dashes'] = 'true';
+}
+
+
+function addEdge(parent, child, edgeIndex, edges) {
+  newEdge = {};
+  newEdge['from'] = parent;
+  newEdge['to'] = child;
+  newEdge['color'] = 'gray';
+  edges[edgeIndex] = newEdge;
+}
+
+
+/**
+* Add edge information
+* returns {int} edgeIndex - where we are in the list of edges
+*/
+function linkStages(linkType, data, stage, nodeId, edgeIndex, edges, dashes=false) {
+  if (data[stage][linkType] != null) {
+    linkedStages = data[stage][linkType].split(",");
+    for (index in linkedStages) {
+      if (dashes == true) {
+        addDashedEdge(nodeId, getStageNumber(linkedStages[index]), edgeIndex, edges);
+      }
+      else {
+        addEdge(getStageNumber(linkedStages[index]), nodeId, edgeIndex, edges);
+      }
+      edgeIndex ++
+    }
+  }
+  return edgeIndex;
+}
+
+
+function displayStagePlan(params, displayStagePlanElement, jsonPlan, textIndent) {
+  nodeId = params.nodes;
+  stageName = "Stage-" + nodeId;
+  if (nodeId != "") {
+    document.getElementById(displayStagePlanElement).innerHTML =
+      'Stage ' + nodeId + " plan:\n" +
+      prettifyJsonString(JSON.stringify(jsonPlan['STAGE PLANS'][stageName], null, textIndent));
+  }
+  //show nothing if no node is selected
+  else {
+    document.getElementById(displayStagePlanElement).innerHTML =
+      "Click on a stage to view its plan";
+  }
+}
+
+
+function displayStatistics(params, displayStatisticsElement, displayStatisticsElementHead,
+  displayStatisticsElementBody, jsonStats, jsonStatuses, jsonLogs, textIndent) {
+  if (document.getElementById(PROGRESS_ELEMENT)) {
+    document.getElementById(PROGRESS_ELEMENT).remove();
+  }
+  nodeId = params.nodes;
+  stageName = "Stage-" + nodeId;
+  if (nodeId != "" && jsonStatuses[stageName] != null) {
+    if (jsonStats[stageName] != null) {
+
+      document.getElementById(displayStatisticsElementHead).innerHTML =
+        "Stage " + nodeId + " statistics:\n" +
+        "Status: " + jsonStatuses[stageName] + "\n" +
+        "Logs: " + prettifyJsonString(JSON.stringify(jsonLogs, null, textIndent)) + "\n\n" +
+        "MapReduce job progress:\n";
+      document.getElementById(displayStatisticsElementBody).innerHTML =
+        prettifyJsonString(JSON.stringify(jsonStats[stageName], null, textIndent));
+
+      if (jsonStats[stageName][MAP_PROGRESS] != null) {
+        var mapProgress = jsonStats[stageName][MAP_PROGRESS];
+      }
+      if (jsonStats[stageName][REDUCE_PROGRESS] != null) {
+        var reduceProgress = jsonStats[stageName][REDUCE_PROGRESS];
+      }
+      var progressBar = getMainProgressBar(mapProgress, reduceProgress, PROGRESS_ELEMENT);
+      if (progressBar != null) {
+        document.getElementById(displayStatisticsElement).insertBefore(
+          progressBar, document.getElementById(displayStatisticsElementBody));
+      }
+    }
+    else { // stage without statistics
+      document.getElementById(displayStatisticsElementHead).innerHTML =
+        "Stage " + nodeId + " statistics:\n" +
+        "Status: " + jsonStatuses[stageName]+ "\n" +
+        "Logs: " + prettifyJsonString(JSON.stringify(jsonLogs, null, textIndent));
+      document.getElementById(displayStatisticsElementBody).innerHTML = '';
+    }
+  }
+  //show nothing if no node is selected or selected node isn't executed
+  else {
+    document.getElementById(displayStatisticsElementHead).innerHTML =
+      "Click on a colored-in stage to view stats";
+    document.getElementById(displayStatisticsElementBody).innerHTML = '';
+  }
+}
+
+
+function getMainProgressBar(mapProgress, reduceProgress, elementId) {
+  var progressBar = document.createElement("div");
+  progressBar.className = "progress";
+  progressBar.id = elementId;
+  var numChildProgressBars = 2;
+  if (mapProgress == null || reduceProgress == null) {
+    numChildProgressBars = 1;
+  }
+  if (mapProgress != null) {
+    progressBar.appendChild(getSubProgressBar("map", mapProgress, progressBar,
+        numChildProgressBars));
+  }
+  if (reduceProgress != null) {
+    progressBar.appendChild(getSubProgressBar("reduce", reduceProgress, progressBar,
+        numChildProgressBars, 'green'));
+  }
+  if (mapProgress == null && reduceProgress == null) {
+    progressBar = null;
+  }
+  return progressBar;
+}
+
+
+function getSubProgressBar(type, progress, mainProgressBar, numChildProgressBars, color) {
+  var new_progress_bar = document.createElement("div");
+  new_progress_bar.id = "progress-" + type;
+  var className = "progress-bar";
+  if (color == "green") {
+    className += " progress-bar-success";
+  }
+  new_progress_bar.className = className;
+  new_progress_bar.role = "progressbar";
+  new_progress_bar['aria-valuenow'] = "0";
+  new_progress_bar['aria-valuemin'] = progress / numChildProgressBars;
+  new_progress_bar['aria-valuemax'] = "100";
+  new_progress_bar.style = "width: " + progress / numChildProgressBars + "%; min-width: 2em;";
+  new_progress_bar.innerHTML = progress + "% " + type;
+  return new_progress_bar;
+}
\ No newline at end of file