-
-
+
+
+
+
+
+
+
+
Marlin WebUI by atbox.tech
+
+

+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Printing timer
+
Remain: 0:45:12
+
Estimated: 1:12:34
+
Elapsed: 0:00:00
+
+
+ Printing progress:
+
10%
+
1 of 123456
+
+
+
+
+
+
+
+
+ Auto temperature detection
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | Hotend (extruder) sensor |
+ | Bed sensor |
+
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | All axis |
+ |
+ X axis |
+ |
+ Y axis |
+ |
+ Z axis |
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+ Move on X axis
+
+
+
+
+ Move on Y axis
+
+
+
+
+ Move on Z axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GCode checksum value:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/www/jquery-3.5.1.slim.min.js b/data/www/jquery-3.5.1.slim.min.js
new file mode 100644
index 0000000000..36b4e1a137
--- /dev/null
+++ b/data/www/jquery-3.5.1.slim.min.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,v=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},w=g.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||w).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!b(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0
+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="",m.option=!!le.lastChild;var he={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Le(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function je(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n",2===ft.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Fe(m.pixelPosition,function(e,t){if(t)return t=We(e,n),Ie.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0=0&&/(rv)(?::| )([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[],c=/(ipad)/.exec(a)||/(ipod)/.exec(a)||/(windows phone)/.exec(a)||/(iphone)/.exec(a)||/(kindle)/.exec(a)||/(silk)/.exec(a)||/(android)/.exec(a)||/(win)/.exec(a)||/(mac)/.exec(a)||/(linux)/.exec(a)||/(cros)/.exec(a)||/(playbook)/.exec(a)||/(bb)/.exec(a)||/(blackberry)/.exec(a)||[],d={},e={browser:b[5]||b[3]||b[1]||"",version:b[2]||b[4]||"0",versionNumber:b[4]||b[2]||"0",platform:c[0]||""};if(e.browser&&(d[e.browser]=!0,d.version=e.version,d.versionNumber=parseInt(e.versionNumber,10)),e.platform&&(d[e.platform]=!0),(d.android||d.bb||d.blackberry||d.ipad||d.iphone||d.ipod||d.kindle||d.playbook||d.silk||d["windows phone"])&&(d.mobile=!0),(d.cros||d.mac||d.linux||d.win)&&(d.desktop=!0),(d.chrome||d.opr||d.safari)&&(d.webkit=!0),d.rv||d.iemobile){var f="msie";e.browser=f,d[f]=!0}if(d.edge){delete d.edge;var g="msedge";e.browser=g,d[g]=!0}if(d.safari&&d.blackberry){var h="blackberry";e.browser=h,d[h]=!0}if(d.safari&&d.playbook){var i="playbook";e.browser=i,d[i]=!0}if(d.bb){var j="blackberry";e.browser=j,d[j]=!0}if(d.opr){var k="opera";e.browser=k,d[k]=!0}if(d.safari&&d.android){var l="android";e.browser=l,d[l]=!0}if(d.safari&&d.kindle){var m="kindle";e.browser=m,d[m]=!0}if(d.safari&&d.silk){var n="silk";e.browser=n,d[n]=!0}return d.name=e.browser,d.platform=e.platform,d}return window.jQBrowser=b(window.navigator.userAgent),window.jQBrowser.uaMatch=b,a&&(a.browser=window.jQBrowser),window.jQBrowser});
\ No newline at end of file
diff --git a/data/www/marlin-logo-dark.png b/data/www/marlin-logo-dark.png
new file mode 100644
index 0000000000..f2f5e9e337
Binary files /dev/null and b/data/www/marlin-logo-dark.png differ
diff --git a/data/www/marlin-logo.png b/data/www/marlin-logo.png
deleted file mode 100644
index d0ce790141..0000000000
Binary files a/data/www/marlin-logo.png and /dev/null differ
diff --git a/data/www/marlin.css b/data/www/marlin.css
deleted file mode 100644
index b29ec2e24c..0000000000
--- a/data/www/marlin.css
+++ /dev/null
@@ -1,166 +0,0 @@
-/* CSS reset */
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed,
-figure, figcaption, footer, header, hgroup,
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
- font-family: Impact, Charcoal, sans-serif;
- }
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
- }
-body { line-height: 1; }
-ol, ul { list-style: none; }
-blockquote, q { quotes: none; }
-blockquote:before, blockquote:after,
-q:before, q:after { content: ''; content: none; }
-table {
- border-collapse: collapse;
- border-spacing: 0;
- }
-
-/* Custom */
-
-/* Tabs */
-* { box-sizing: border-box; }
-body {
- display: flex;
- justify-content: center;
- padding: 0px;
- background: #1e1e1e;
- color: #efefef;
- }
-h1 {
- margin: 0;
- font-size: 2em;
- }
-.tabs {
- display: flex;
- width: 100%;
- flex-wrap: wrap;
- background: #e5e5e5;
- }
-.input {
- position: absolute;
- opacity: 0;
- }
-.label {
- width: 100%;
- padding: 18px 28px;
- background: #e5e5e5;
- cursor: pointer;
- font-weight: bold;
- font-size: 18px;
- color: #7f7f7f;
- transition: background 0.1s, color 0.1s;
- border-style: solid;
- border-width: 0 0 4px 0;
- border-color: #acacac;
- }
-.label:hover {
- background: #d8d8d8;
- }
-.label:active {
- background: #ccc;
- }
-.input:focus + .label {
- z-index: 1;
- }
-.input:checked + .label {
- background: #1e1e1e;
- color: #efefef;
- border-width: 4px 0 0 0;
- border-color: #65a57d;
- }
-.panel {
- display: none;
- width: 100%;
- padding: 20px 30px 30px;
- background: #1e1e1e;
- color: #e5e5e5;
- }
-.panel .panel-content {
- width: 100%;
- max-width: 800px;
- }
-
-@media (min-width: 600px) {
- .label { width: auto; }
- .panel { order: 99; }
-}
-
-.input:checked + .label + .panel { display: block; }
-
-#logo {
- width: 130px;
- height: 58px;
- margin-right: 20px;
- background: url(marlin-logo.png) no-repeat center center;
- }
-
-input[type="text"], textarea {
- background-color: #2c2c2c;
- border: solid 2px #314b3b;
- color: #e5e5e5;
- outline: none;
- }
-
-input[type="text"]:focus, textarea:focus {
- border-color: #4d7a5e;
- }
-
-ul#serial-output {
- width: 100%;
- height: 300px;
- overflow-y: scroll;
- background-color: #2c2c2c;
- border: solid 2px #314b3b;
- }
-
-ul#serial-output li {
- padding: 4px;
- font-family: "Lucida Console", Monaco, monospace;
- font-size: 0.8em;
- }
-
-ul#serial-output li:nth-child(odd) {
- background-color: #3c3c3c;
- }
-
-div.form-wrapper {
- display: flex;
- width: 100%;
- margin: 6px 0;
- }
-
-div.form-wrapper input {
- font-size: 1.2em;
- padding: 4px 6px;
- }
-
-div.form-wrapper input[type="text"] {
- flex: 1 1 auto;
- }
-
-div.form-wrapper input[type="submit"],
-div.form-wrapper button {
- border: solid 2px #314b3b;
- background-color: #4d7a5e;
- color: #e5e5e5;
- }
diff --git a/data/www/marlin.js b/data/www/marlin.js
deleted file mode 100644
index 0a95045aff..0000000000
--- a/data/www/marlin.js
+++ /dev/null
@@ -1,24 +0,0 @@
-document.addEventListener('DOMContentLoaded', () => {
- const ws = new WebSocket(`ws://${location.host}/ws`);
-
- ws.onmessage = (e) => {
- if (typeof e.data === 'string') {
- let node = document.createElement('li');
- let text = document.createTextNode(e.data);
- node.appendChild(text);
- document.getElementById('serial-output').appendChild(node);
- }
- };
-
- document.getElementById('serial-command-form').addEventListener('submit', (e) => {
- e.preventDefault();
-
- let value = document.getElementById('serial-command').value.trim();
-
- if (!value) return;
-
- ws.send(`${value}\n`);
-
- document.getElementById('serial-command').value = '';
- });
-});
diff --git a/data/www/marlinui.eot b/data/www/marlinui.eot
new file mode 100644
index 0000000000..7e25d5cab3
Binary files /dev/null and b/data/www/marlinui.eot differ
diff --git a/data/www/marlinui.svg b/data/www/marlinui.svg
new file mode 100644
index 0000000000..aa582fab2d
--- /dev/null
+++ b/data/www/marlinui.svg
@@ -0,0 +1,56 @@
+
+
+
diff --git a/data/www/marlinui.ttf b/data/www/marlinui.ttf
new file mode 100644
index 0000000000..878b47fff9
Binary files /dev/null and b/data/www/marlinui.ttf differ
diff --git a/data/www/marlinui.woff b/data/www/marlinui.woff
new file mode 100644
index 0000000000..8fa04f9efa
Binary files /dev/null and b/data/www/marlinui.woff differ
diff --git a/data/www/moment.min.js b/data/www/moment.min.js
new file mode 100644
index 0000000000..d301ddbbe8
--- /dev/null
+++ b/data/www/moment.min.js
@@ -0,0 +1,7 @@
+//! moment.js
+//! version : 2.13.0
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return fd.apply(null,arguments)}function b(a){fd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c0)for(c in hd)d=hd[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),id===!1&&(id=!0,a.updateOffset(this),id=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function u(b,c){var d=!0;return g(function(){return null!=a.deprecationHandler&&a.deprecationHandler(null,b),d&&(t(b+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),d=!1),c.apply(this,arguments)},c)}function v(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),jd[b]||(t(c),jd[b]=!0)}function w(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function x(a){return"[object Object]"===Object.prototype.toString.call(a)}function y(a){var b,c;for(c in a)b=a[c],w(b)?this[c]=b:this["_"+c]=b;this._config=a,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function z(a,b){var c,d=g({},a);for(c in b)f(b,c)&&(x(a[c])&&x(b[c])?(d[c]={},g(d[c],a[c]),g(d[c],b[c])):null!=b[c]?d[c]=b[c]:delete d[c]);return d}function A(a){null!=a&&this.set(a)}function B(a){return a?a.toLowerCase().replace("_","-"):a}function C(a){for(var b,c,d,e,f=0;f0;){if(d=D(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function D(a){var b=null;if(!nd[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=ld._abbr,require("./locale/"+a),E(b)}catch(c){}return nd[a]}function E(a,b){var c;return a&&(c=m(b)?H(a):F(a,b),c&&(ld=c)),ld._abbr}function F(a,b){return null!==b?(b.abbr=a,null!=nd[a]?(v("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),b=z(nd[a]._config,b)):null!=b.parentLocale&&(null!=nd[b.parentLocale]?b=z(nd[b.parentLocale]._config,b):v("parentLocaleUndefined","specified parentLocale is not defined yet")),nd[a]=new A(b),E(a),nd[a]):(delete nd[a],null)}function G(a,b){if(null!=b){var c;null!=nd[a]&&(b=z(nd[a]._config,b)),c=new A(b),c.parentLocale=nd[a],nd[a]=c,E(a)}else null!=nd[a]&&(null!=nd[a].parentLocale?nd[a]=nd[a].parentLocale:null!=nd[a]&&delete nd[a]);return nd[a]}function H(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return ld;if(!c(a)){if(b=D(a))return b;a=[a]}return C(a)}function I(){return kd(nd)}function J(a,b){var c=a.toLowerCase();od[c]=od[c+"s"]=od[b]=a}function K(a){return"string"==typeof a?od[a]||od[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)f(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(b,c){return function(d){return null!=d?(O(this,b,d),a.updateOffset(this,c),this):N(this,b)}}function N(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function O(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function P(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=K(a),w(this[a]))return this[a](b);return this}function Q(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function R(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(sd[a]=e),b&&(sd[b[0]]=function(){return Q(e.apply(this,arguments),b[1],b[2])}),c&&(sd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function S(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function T(a){var b,c,d=a.match(pd);for(b=0,c=d.length;c>b;b++)sd[d[b]]?d[b]=sd[d[b]]:d[b]=S(d[b]);return function(b){var e,f="";for(e=0;c>e;e++)f+=d[e]instanceof Function?d[e].call(b,a):d[e];return f}}function U(a,b){return a.isValid()?(b=V(b,a.localeData()),rd[b]=rd[b]||T(b),rd[b](a)):a.localeData().invalidDate()}function V(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(qd.lastIndex=0;d>=0&&qd.test(a);)a=a.replace(qd,c),qd.lastIndex=0,d-=1;return a}function W(a,b,c){Kd[a]=w(b)?b:function(a,d){return a&&c?c:b}}function X(a,b){return f(Kd,a)?Kd[a](b._strict,b._locale):new RegExp(Y(a))}function Y(a){return Z(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function Z(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function $(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;cd;++d)f=h([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:null):(e=md.call(this._longMonthsParse,g),-1!==e?e:null):"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:(e=md.call(this._longMonthsParse,g),-1!==e?e:null)):(e=md.call(this._longMonthsParse,g),-1!==e?e:(e=md.call(this._shortMonthsParse,g),-1!==e?e:null))}function fa(a,b,c){var d,e,f;if(this._monthsParseExact)return ea.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ga(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=r(b);else if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),ba(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ha(b){return null!=b?(ga(this,b),a.updateOffset(this,!0),this):N(this,"Month")}function ia(){return ba(this.year(),this.month())}function ja(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ka(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function la(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=Z(d[b]),e[b]=Z(e[b]),f[b]=Z(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function ma(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[Nd]<0||c[Nd]>11?Nd:c[Od]<1||c[Od]>ba(c[Md],c[Nd])?Od:c[Pd]<0||c[Pd]>24||24===c[Pd]&&(0!==c[Qd]||0!==c[Rd]||0!==c[Sd])?Pd:c[Qd]<0||c[Qd]>59?Qd:c[Rd]<0||c[Rd]>59?Rd:c[Sd]<0||c[Sd]>999?Sd:-1,j(a)._overflowDayOfYear&&(Md>b||b>Od)&&(b=Od),j(a)._overflowWeeks&&-1===b&&(b=Td),j(a)._overflowWeekday&&-1===b&&(b=Ud),j(a).overflow=b),a}function na(a){var b,c,d,e,f,g,h=a._i,i=$d.exec(h)||_d.exec(h);if(i){for(j(a).iso=!0,b=0,c=be.length;c>b;b++)if(be[b][1].exec(i[1])){e=be[b][0],d=be[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=ce.length;c>b;b++)if(ce[b][1].exec(i[3])){f=(i[2]||" ")+ce[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!ae.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),Ca(a)}else a._isValid=!1}function oa(b){var c=de.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(na(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function pa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function qa(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ra(a){return sa(a)?366:365}function sa(a){return a%4===0&&a%100!==0||a%400===0}function ta(){return sa(this.year())}function ua(a,b,c){var d=7+b-c,e=(7+qa(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=ra(f)+j):j>ra(a)?(f=a+1,g=j-ra(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(ra(a)-d+e)/7}function ya(a,b,c){return null!=a?a:null!=b?b:c}function za(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function Aa(a){var b,c,d,e,f=[];if(!a._d){for(d=za(a),a._w&&null==a._a[Od]&&null==a._a[Nd]&&Ba(a),a._dayOfYear&&(e=ya(a._a[Md],d[Md]),a._dayOfYear>ra(e)&&(j(a)._overflowDayOfYear=!0),c=qa(e,0,a._dayOfYear),a._a[Nd]=c.getUTCMonth(),a._a[Od]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[Pd]&&0===a._a[Qd]&&0===a._a[Rd]&&0===a._a[Sd]&&(a._nextDay=!0,a._a[Pd]=0),a._d=(a._useUTC?qa:pa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Pd]=24)}}function Ba(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=ya(b.GG,a._a[Md],wa(Ka(),1,4).year),d=ya(b.W,1),e=ya(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=ya(b.gg,a._a[Md],wa(Ka(),f,g).year),d=ya(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>xa(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[Md]=h.year,a._dayOfYear=h.dayOfYear)}function Ca(b){if(b._f===a.ISO_8601)return void na(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=V(b._f,b._locale).match(pd)||[],c=0;c0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),sd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),aa(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[Pd]<=12&&b._a[Pd]>0&&(j(b).bigHour=void 0),j(b).parsedDateParts=b._a.slice(0),j(b).meridiem=b._meridiem,b._a[Pd]=Da(b._locale,b._a[Pd],b._meridiem),Aa(b),ma(b)}function Da(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function Ea(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;ef)&&(d=f,c=b));g(a,c||b)}function Fa(a){if(!a._d){var b=L(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),Aa(a)}}function Ga(a){var b=new o(ma(Ha(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ha(a){var b=a._i,e=a._f;return a._locale=a._locale||H(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(ma(b)):(c(e)?Ea(a):e?Ca(a):d(b)?a._d=b:Ia(a),k(a)||(a._d=null),a))}function Ia(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(f.valueOf()):"string"==typeof f?oa(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),Aa(b)):"object"==typeof f?Fa(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ja(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Ga(f)}function Ka(a,b,c,d){return Ja(a,b,c,d,!1)}function La(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ka();for(d=b[0],e=1;ea&&(a=-a,c="-"),c+Q(~~(a/60),2)+b+Q(~~a%60,2)})}function Ra(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(ie)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Sa(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?b.valueOf():Ka(b).valueOf())-e.valueOf(),e._d.setTime(e._d.valueOf()+f),a.updateOffset(e,!1),e):Ka(b).local()}function Ta(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Ua(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=Ra(Hd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ta(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?jb(this,db(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ta(this):null!=b?this:NaN}function Va(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Wa(a){return this.utcOffset(0,a)}function Xa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ta(this),"m")),this}function Ya(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ra(Gd,this._i)),this}function Za(a){return this.isValid()?(a=a?Ka(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function $a(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function _a(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ha(a),a._a){var b=a._isUTC?h(a._a):Ka(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function ab(){return this.isValid()?!this._isUTC:!1}function bb(){return this.isValid()?this._isUTC:!1}function cb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function db(a,b){var c,d,e,g=a,h=null;return Pa(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=je.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[Od])*c,h:r(h[Pd])*c,m:r(h[Qd])*c,s:r(h[Rd])*c,ms:r(h[Sd])*c}):(h=ke.exec(a))?(c="-"===h[1]?-1:1,g={y:eb(h[2],c),M:eb(h[3],c),w:eb(h[4],c),d:eb(h[5],c),h:eb(h[6],c),m:eb(h[7],c),s:eb(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=gb(Ka(g.from),Ka(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Oa(g),Pa(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function eb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function fb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function gb(a,b){var c;return a.isValid()&&b.isValid()?(b=Sa(b,a),a.isBefore(b)?c=fb(a,b):(c=fb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function hb(a){return 0>a?-1*Math.round(-1*a):Math.round(a)}function ib(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(v(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=db(c,d),jb(this,e,a),this}}function jb(b,c,d,e){var f=c._milliseconds,g=hb(c._days),h=hb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&O(b,"Date",N(b,"Date")+g*d),h&&ga(b,N(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function kb(a,b){var c=a||Ka(),d=Sa(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(w(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ka(c)))}function lb(){return new o(this)}function mb(a,b){var c=p(a)?a:Ka(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function ub(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function vb(){var a=this.clone().utc();return 0f&&(b=f),Vb.call(this,a,b,c,d,e))}function Vb(a,b,c,d,e){var f=va(a,b,c,d,e),g=qa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Wb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Xb(a){return wa(a,this._week.dow,this._week.doy).week}function Yb(){return this._week.dow}function Zb(){return this._week.doy}function $b(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function _b(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function ac(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function bc(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function cc(a){return this._weekdaysShort[a.day()]}function dc(a){return this._weekdaysMin[a.day()]}function ec(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;7>d;++d)f=h([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:null):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null):"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null)))}function fc(a,b,c){var d,e,f;if(this._weekdaysParseExact)return ec.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=h([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function gc(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=ac(a,this.localeData()),this.add(a-b,"d")):b}function hc(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function ic(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function jc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex}function kc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}function lc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}function mc(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],i=[],j=[],k=[];for(b=0;7>b;b++)c=h([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),i.push(e),j.push(f),k.push(d),k.push(e),k.push(f);for(g.sort(a),i.sort(a),j.sort(a),k.sort(a),b=0;7>b;b++)i[b]=Z(i[b]),j[b]=Z(j[b]),k[b]=Z(k[b]);this._weekdaysRegex=new RegExp("^("+k.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function nc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function oc(){return this.hours()%12||12}function pc(){return this.hours()||24}function qc(a,b){R(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function rc(a,b){return b._meridiemParse}function sc(a){return"p"===(a+"").toLowerCase().charAt(0)}function tc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function uc(a,b){b[Sd]=r(1e3*("0."+a))}function vc(){return this._isUTC?"UTC":""}function wc(){return this._isUTC?"Coordinated Universal Time":""}function xc(a){return Ka(1e3*a)}function yc(){return Ka.apply(null,arguments).parseZone()}function zc(a,b,c){var d=this._calendar[a];return w(d)?d.call(b,c):d}function Ac(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function Bc(){return this._invalidDate}function Cc(a){return this._ordinal.replace("%d",a)}function Dc(a){return a}function Ec(a,b,c,d){var e=this._relativeTime[c];return w(e)?e(a,b,c,d):e.replace(/%d/i,a)}function Fc(a,b){var c=this._relativeTime[a>0?"future":"past"];return w(c)?c(b):c.replace(/%s/i,b)}function Gc(a,b,c,d){var e=H(),f=h().set(d,b);return e[c](f,a)}function Hc(a,b,c){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return Gc(a,b,c,"month");var d,e=[];for(d=0;12>d;d++)e[d]=Gc(a,d,c,"month");return e}function Ic(a,b,c,d){"boolean"==typeof a?("number"==typeof b&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,"number"==typeof b&&(c=b,b=void 0),b=b||"");var e=H(),f=a?e._week.dow:0;if(null!=c)return Gc(b,(c+f)%7,d,"day");var g,h=[];for(g=0;7>g;g++)h[g]=Gc(b,(g+f)%7,d,"day");return h}function Jc(a,b){return Hc(a,b,"months")}function Kc(a,b){return Hc(a,b,"monthsShort")}function Lc(a,b,c){return Ic(a,b,c,"weekdays")}function Mc(a,b,c){return Ic(a,b,c,"weekdaysShort")}function Nc(a,b,c){return Ic(a,b,c,"weekdaysMin")}function Oc(){var a=this._data;return this._milliseconds=Le(this._milliseconds),this._days=Le(this._days),this._months=Le(this._months),a.milliseconds=Le(a.milliseconds),a.seconds=Le(a.seconds),a.minutes=Le(a.minutes),a.hours=Le(a.hours),a.months=Le(a.months),a.years=Le(a.years),this}function Pc(a,b,c,d){var e=db(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Qc(a,b){return Pc(this,a,b,1)}function Rc(a,b){return Pc(this,a,b,-1)}function Sc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Tc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Sc(Vc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Uc(g)),h+=e,g-=Sc(Vc(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Uc(a){return 4800*a/146097}function Vc(a){return 146097*a/4800}function Wc(a){var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Uc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Vc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Xc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Yc(a){return function(){return this.as(a)}}function Zc(a){
+return a=K(a),this[a+"s"]()}function $c(a){return function(){return this._data[a]}}function _c(){return q(this.days()/7)}function ad(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function bd(a,b,c){var d=db(a).abs(),e=_e(d.as("s")),f=_e(d.as("m")),g=_e(d.as("h")),h=_e(d.as("d")),i=_e(d.as("M")),j=_e(d.as("y")),k=e=f&&["m"]||f=g&&["h"]||g=h&&["d"]||h=i&&["M"]||i=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,ad.apply(null,k)}function cd(a,b){return void 0===af[a]?!1:void 0===b?af[a]:(af[a]=b,!0)}function dd(a){var b=this.localeData(),c=bd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function ed(){var a,b,c,d=bf(this._milliseconds)/1e3,e=bf(this._days),f=bf(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var fd,gd;gd=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;c>d;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var hd=a.momentProperties=[],id=!1,jd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var kd;kd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c};var ld,md,nd={},od={},pd=/(\[[^\[]*\])|(\\)?([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,qd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,rd={},sd={},td=/\d/,ud=/\d\d/,vd=/\d{3}/,wd=/\d{4}/,xd=/[+-]?\d{6}/,yd=/\d\d?/,zd=/\d\d\d\d?/,Ad=/\d\d\d\d\d\d?/,Bd=/\d{1,3}/,Cd=/\d{1,4}/,Dd=/[+-]?\d{1,6}/,Ed=/\d+/,Fd=/[+-]?\d+/,Gd=/Z|[+-]\d\d:?\d\d/gi,Hd=/Z|[+-]\d\d(?::?\d\d)?/gi,Id=/[+-]?\d+(\.\d{1,3})?/,Jd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Kd={},Ld={},Md=0,Nd=1,Od=2,Pd=3,Qd=4,Rd=5,Sd=6,Td=7,Ud=8;md=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b=a?""+a:"+"+a}),R(0,["YY",2],0,function(){return this.year()%100}),R(0,["YYYY",4],0,"year"),R(0,["YYYYY",5],0,"year"),R(0,["YYYYYY",6,!0],0,"year"),J("year","y"),W("Y",Fd),W("YY",yd,ud),W("YYYY",Cd,wd),W("YYYYY",Dd,xd),W("YYYYYY",Dd,xd),$(["YYYYY","YYYYYY"],Md),$("YYYY",function(b,c){c[Md]=2===b.length?a.parseTwoDigitYear(b):r(b)}),$("YY",function(b,c){c[Md]=a.parseTwoDigitYear(b)}),$("Y",function(a,b){b[Md]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var ee=M("FullYear",!0);a.ISO_8601=function(){};var fe=u("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),ge=u("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),he=function(){return Date.now?Date.now():+new Date};Qa("Z",":"),Qa("ZZ",""),W("Z",Hd),W("ZZ",Hd),$(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ra(Hd,a)});var ie=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var je=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,ke=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;db.fn=Oa.prototype;var le=ib(1,"add"),me=ib(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ne=u("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});R(0,["gg",2],0,function(){return this.weekYear()%100}),R(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Pb("gggg","weekYear"),Pb("ggggg","weekYear"),Pb("GGGG","isoWeekYear"),Pb("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),W("G",Fd),W("g",Fd),W("GG",yd,ud),W("gg",yd,ud),W("GGGG",Cd,wd),W("gggg",Cd,wd),W("GGGGG",Dd,xd),W("ggggg",Dd,xd),_(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),_(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),R("Q",0,"Qo","quarter"),J("quarter","Q"),W("Q",td),$("Q",function(a,b){b[Nd]=3*(r(a)-1)}),R("w",["ww",2],"wo","week"),R("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),W("w",yd),W("ww",yd,ud),W("W",yd),W("WW",yd,ud),_(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var oe={dow:0,doy:6};R("D",["DD",2],"Do","date"),J("date","D"),W("D",yd),W("DD",yd,ud),W("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),$(["D","DD"],Od),$("Do",function(a,b){b[Od]=r(a.match(yd)[0],10)});var pe=M("Date",!0);R("d",0,"do","day"),R("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),R("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),R("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),R("e",0,0,"weekday"),R("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),W("d",yd),W("e",yd),W("E",yd),W("dd",function(a,b){return b.weekdaysMinRegex(a)}),W("ddd",function(a,b){return b.weekdaysShortRegex(a)}),W("dddd",function(a,b){return b.weekdaysRegex(a)}),_(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),_(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),re="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),se="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),te=Jd,ue=Jd,ve=Jd;R("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),W("DDD",Bd),W("DDDD",vd),$(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),R("H",["HH",2],0,"hour"),R("h",["hh",2],0,oc),R("k",["kk",2],0,pc),R("hmm",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)}),R("hmmss",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)+Q(this.seconds(),2)}),R("Hmm",0,0,function(){return""+this.hours()+Q(this.minutes(),2)}),R("Hmmss",0,0,function(){return""+this.hours()+Q(this.minutes(),2)+Q(this.seconds(),2)}),qc("a",!0),qc("A",!1),J("hour","h"),W("a",rc),W("A",rc),W("H",yd),W("h",yd),W("HH",yd,ud),W("hh",yd,ud),W("hmm",zd),W("hmmss",Ad),W("Hmm",zd),W("Hmmss",Ad),$(["H","HH"],Pd),$(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),$(["h","hh"],function(a,b,c){b[Pd]=r(a),j(c).bigHour=!0}),$("hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d)),j(c).bigHour=!0}),$("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e)),j(c).bigHour=!0}),$("Hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d))}),$("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e))});var we=/[ap]\.?m?\.?/i,xe=M("Hours",!0);R("m",["mm",2],0,"minute"),J("minute","m"),W("m",yd),W("mm",yd,ud),$(["m","mm"],Qd);var ye=M("Minutes",!1);R("s",["ss",2],0,"second"),J("second","s"),W("s",yd),W("ss",yd,ud),$(["s","ss"],Rd);var ze=M("Seconds",!1);R("S",0,0,function(){return~~(this.millisecond()/100)}),R(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),R(0,["SSS",3],0,"millisecond"),R(0,["SSSS",4],0,function(){return 10*this.millisecond()}),R(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),R(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),R(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),R(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),R(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),W("S",Bd,td),W("SS",Bd,ud),W("SSS",Bd,vd);var Ae;for(Ae="SSSS";Ae.length<=9;Ae+="S")W(Ae,Ed);for(Ae="S";Ae.length<=9;Ae+="S")$(Ae,uc);var Be=M("Milliseconds",!1);R("z",0,0,"zoneAbbr"),R("zz",0,0,"zoneName");var Ce=o.prototype;Ce.add=le,Ce.calendar=kb,Ce.clone=lb,Ce.diff=sb,Ce.endOf=Eb,Ce.format=wb,Ce.from=xb,Ce.fromNow=yb,Ce.to=zb,Ce.toNow=Ab,Ce.get=P,Ce.invalidAt=Nb,Ce.isAfter=mb,Ce.isBefore=nb,Ce.isBetween=ob,Ce.isSame=pb,Ce.isSameOrAfter=qb,Ce.isSameOrBefore=rb,Ce.isValid=Lb,Ce.lang=ne,Ce.locale=Bb,Ce.localeData=Cb,Ce.max=ge,Ce.min=fe,Ce.parsingFlags=Mb,Ce.set=P,Ce.startOf=Db,Ce.subtract=me,Ce.toArray=Ib,Ce.toObject=Jb,Ce.toDate=Hb,Ce.toISOString=vb,Ce.toJSON=Kb,Ce.toString=ub,Ce.unix=Gb,Ce.valueOf=Fb,Ce.creationData=Ob,Ce.year=ee,Ce.isLeapYear=ta,Ce.weekYear=Qb,Ce.isoWeekYear=Rb,Ce.quarter=Ce.quarters=Wb,Ce.month=ha,Ce.daysInMonth=ia,Ce.week=Ce.weeks=$b,Ce.isoWeek=Ce.isoWeeks=_b,Ce.weeksInYear=Tb,Ce.isoWeeksInYear=Sb,Ce.date=pe,Ce.day=Ce.days=gc,Ce.weekday=hc,Ce.isoWeekday=ic,Ce.dayOfYear=nc,Ce.hour=Ce.hours=xe,Ce.minute=Ce.minutes=ye,Ce.second=Ce.seconds=ze,Ce.millisecond=Ce.milliseconds=Be,Ce.utcOffset=Ua,Ce.utc=Wa,Ce.local=Xa,Ce.parseZone=Ya,Ce.hasAlignedHourOffset=Za,Ce.isDST=$a,Ce.isDSTShifted=_a,Ce.isLocal=ab,Ce.isUtcOffset=bb,Ce.isUtc=cb,Ce.isUTC=cb,Ce.zoneAbbr=vc,Ce.zoneName=wc,Ce.dates=u("dates accessor is deprecated. Use date instead.",pe),Ce.months=u("months accessor is deprecated. Use month instead",ha),Ce.years=u("years accessor is deprecated. Use year instead",ee),Ce.zone=u("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Va);var De=Ce,Ee={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Fe={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"},Ge="Invalid date",He="%d",Ie=/\d{1,2}/,Je={future:"in %s",past:"%s ago",s:"a few 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"},Ke=A.prototype;Ke._calendar=Ee,Ke.calendar=zc,Ke._longDateFormat=Fe,Ke.longDateFormat=Ac,Ke._invalidDate=Ge,Ke.invalidDate=Bc,Ke._ordinal=He,Ke.ordinal=Cc,Ke._ordinalParse=Ie,Ke.preparse=Dc,Ke.postformat=Dc,Ke._relativeTime=Je,Ke.relativeTime=Ec,Ke.pastFuture=Fc,Ke.set=y,Ke.months=ca,Ke._months=Wd,Ke.monthsShort=da,Ke._monthsShort=Xd,Ke.monthsParse=fa,Ke._monthsRegex=Zd,Ke.monthsRegex=ka,Ke._monthsShortRegex=Yd,Ke.monthsShortRegex=ja,Ke.week=Xb,Ke._week=oe,Ke.firstDayOfYear=Zb,Ke.firstDayOfWeek=Yb,Ke.weekdays=bc,Ke._weekdays=qe,Ke.weekdaysMin=dc,Ke._weekdaysMin=se,Ke.weekdaysShort=cc,Ke._weekdaysShort=re,Ke.weekdaysParse=fc,Ke._weekdaysRegex=te,Ke.weekdaysRegex=jc,Ke._weekdaysShortRegex=ue,Ke.weekdaysShortRegex=kc,Ke._weekdaysMinRegex=ve,Ke.weekdaysMinRegex=lc,Ke.isPM=sc,Ke._meridiemParse=we,Ke.meridiem=tc,E("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=u("moment.lang is deprecated. Use moment.locale instead.",E),a.langData=u("moment.langData is deprecated. Use moment.localeData instead.",H);var Le=Math.abs,Me=Yc("ms"),Ne=Yc("s"),Oe=Yc("m"),Pe=Yc("h"),Qe=Yc("d"),Re=Yc("w"),Se=Yc("M"),Te=Yc("y"),Ue=$c("milliseconds"),Ve=$c("seconds"),We=$c("minutes"),Xe=$c("hours"),Ye=$c("days"),Ze=$c("months"),$e=$c("years"),_e=Math.round,af={s:45,m:45,h:22,d:26,M:11},bf=Math.abs,cf=Oa.prototype;cf.abs=Oc,cf.add=Qc,cf.subtract=Rc,cf.as=Wc,cf.asMilliseconds=Me,cf.asSeconds=Ne,cf.asMinutes=Oe,cf.asHours=Pe,cf.asDays=Qe,cf.asWeeks=Re,cf.asMonths=Se,cf.asYears=Te,cf.valueOf=Xc,cf._bubble=Tc,cf.get=Zc,cf.milliseconds=Ue,cf.seconds=Ve,cf.minutes=We,cf.hours=Xe,cf.days=Ye,cf.weeks=_c,cf.months=Ze,cf.years=$e,cf.humanize=dd,cf.toISOString=ed,cf.toString=ed,cf.toJSON=ed,cf.locale=Bb,cf.localeData=Cb,cf.toIsoString=u("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ed),cf.lang=ne,R("X",0,0,"unix"),R("x",0,0,"valueOf"),W("x",Fd),W("X",Id),$("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),$("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.13.0",b(Ka),a.fn=De,a.min=Ma,a.max=Na,a.now=he,a.utc=h,a.unix=xc,a.months=Jc,a.isDate=d,a.locale=E,a.invalid=l,a.duration=db,a.isMoment=p,a.weekdays=Lc,a.parseZone=yc,a.localeData=H,a.isDuration=Pa,a.monthsShort=Kc,a.weekdaysMin=Nc,a.defineLocale=F,a.updateLocale=G,a.locales=I,a.weekdaysShort=Mc,a.normalizeUnits=K,a.relativeTimeThreshold=cd,a.prototype=De;var df=a;return df});
\ No newline at end of file
diff --git a/data/www/webmarlin-class.js b/data/www/webmarlin-class.js
new file mode 100644
index 0000000000..393fd88eef
--- /dev/null
+++ b/data/www/webmarlin-class.js
@@ -0,0 +1,426 @@
+var wmEnums = {
+ Panels : { STATUS:0, CONTROLS:1, FILES:2, CONSOLE:3 },
+ ConsoleDirection : { APPEND:0, PREPEND:1 },
+ ConsoleLevels : { ERROR:0, SUCCESS:1, INFO:2, MONITOR:3, WARNING:4},
+ WSMsgDirection : { SENT:0, RECEIVED:1 },
+ WsMsgSymbols : { SENT:{LETTER:"S",ICON:null}, RECEIVED:{LETTER:"R",ICON:null} },
+ WSSatuses : { CONNECTING:0, OPEN:1, CLOSING:2, CLOSED:3 },
+ LogLevels : { INFO:0, WARNING:1, ERROR:2, DEBUG:3, VERBOSE:4},
+ TempUnits : { CELSIUS: {LABEL:"Celsius",VALUE:0,GP:"C"}, FAHRENHEIT:{LABEL:"Fahrenheit",VALUE:1,GP:"F"}, KELVIN:{LABEL:"Kelvin",VALUE:2,GP:"K"} }
+};
+
+var wmSettings = {
+ AppName: "Marlin WebUI",
+ AppRelease: "January, 1 2020",
+ AppVersion: "1.1",
+ AutoConnect: false,
+ ConsoleDirection: wmEnums.ConsoleDirection.PREPEND,
+ DefaultPanel: wmEnums.Panels.CONTROLS,
+ LogLevel: wmEnums.LogLevels.VERBOSE,
+ SymbolMode: 'letter',
+ SymbolSend: wmEnums.WsMsgSymbols.SENT.LETTER,
+ SymbolReceive: wmEnums.WsMsgSymbols.RECEIVED.LETTER,
+ AutoTempInterval: 1,
+ TempUnit: wmEnums.TempUnits.CELSIUS
+};
+
+class wmLogItem {
+ constructor(text, mdir, mrs, gcmd=null, bgclass=null, ficon=null) {
+ this.DateTime = wmTools.GetDateTime();
+ this.Text = text;
+ this.Direction = mdir;
+ this.RsType = mrs;
+ this.GCode = gcmd;
+ this.BgClass = bgclass === null ? 'console-list-items-info': bgclass;
+ this.FontIcon = ficon === null ? wmIcons.InfoCircle : ficon;
+ this.SdFile = null;
+ }
+ SetValues(text=null, mdir=null, mrs=null, gcmd=null, bgclass=null, ficon=null) {
+ if(text !== null) { this.Text = text; };
+ if(mdir !== null) { this.Direction = mdir; };
+ if(mrs !== null) { this.RsType = mrs; };
+ if(gcmd !== null) { this.GCode = gcmd; };
+ if(bgclass !== null) { this.BgClass = bgclass; };
+ if(ficon !== null) { this.FontIcon = ficon; };
+ }
+ ToJson() { return JSON.stringify(this); }
+ ToCsv() { return wmTools.StringFormatCsv(this); }
+ ToString() { return wmTools.Stringfy(this); }
+ ToLoglist(){
+ switch (this.RsType) {
+ case wmEnums.ConsoleLevels.INFO:
+ this.BgClass = "console-list-items-info";
+ this.FontIcon = wmIcons.InfoCircle;
+ break;
+ case wmEnums.ConsoleLevels.SUCCESS:
+ this.BgClass = "console-list-items-success";
+ this.FontIcon = wmIcons.CheckSquare;
+ break;
+ case wmEnums.ConsoleLevels.ERROR:
+ this.BgClass = "console-list-items-error";
+ this.FontIcon = wmIcons.Triangle;
+ break;
+ case wmEnums.ConsoleLevels.MONITOR:
+ this.BgClass = "console-list-items-terminal";
+ this.FontIcon = wmIcons.Terminal;
+ break;
+ case wmEnums.ConsoleLevels.WARNING:
+ this.BgClass = "console-list-items-warning";
+ this.FontIcon = wmIcons.Triangle;
+ break;
+ }
+ let strout = '';
+ strout += ''+this.FontIcon.ToHtml()+"";
+ strout += ''+this.DateTime+'';
+ strout += '' + this.Text + '';
+ return strout;
+ }
+ ToSdFileList() {
+ if(this.SdFile !== "Begin file list" && this.SdFile !== "End file list") {
+ let a = this.SdFile.split(" ");
+ let strout = '';
+ strout += ''+a[0]+''+wmTools.FileSizeFormat(a[1])+'
';
+ strout += '';
+ return strout;
+ }
+ }
+ static ParseWsMessage(msg) {
+ let li = new wmLogItem();
+ li.Direction = wmEnums.WSMsgDirection.RECEIVED;
+ li.RsType = wmEnums.ConsoleLevels.SUCCESS;
+ if (msg === "ok") {
+ jsLog.Debug("WSMessage match: ok => " + msg);
+ li.Text = "Acknowledge: "+msg;
+ }
+ else if (msg === "Not SD printing") {
+ jsLog.Debug("WSMessage match: " + msg);
+ li.Text = "Ack: "+msg;
+ WmControls.SetPrinterStatusInfo(false, msg);
+ }
+ else if (msg.substring(0, 5) === "echo:") {
+ if (msg.substring(5, 21) === "busy: processing") {
+ jsLog.Debug("WSMessage match: echo:busy: processing: => " + msg);
+ li.Text = msg.substring(5, msg.length);
+ li.RsType = wmEnums.ConsoleLevels.WARNING;
+ }
+ else if (msg.substring(5, 21) === "Unknown command:") {
+ jsLog.Debug("WSMessage match: echo:Unknown command: => " + msg);
+ li.Text = msg.substring(5, msg.length);
+ li.RsType = wmEnums.ConsoleLevels.WARNING;
+ }
+ else if (msg.substring(5,20) === "Now fresh file:") {
+ jsLog.Debug("WSMessage match: echo:Now fresh file: => " + msg);
+ li.Text = "SD: "+msg.substring(5, msg.length);
+ }
+ else if (msg==="File selected") {
+ jsLog.Debug("WSMessage match: echo:File selected: => " + msg);
+ li.Text = "SD: "+msg.substring(5, msg.length);
+ }
+ }
+ else if (msg.substring(0, 6) === "Error:") {
+ jsLog.Debug("WSMessage match: error => " + msg);
+ li.Text = msg.substring(6, msg.length);
+ li.RsType = wmEnums.ConsoleLevels.ERROR;
+ }
+ else if (msg.substring(0, 12) === "File opened:" || msg === "File selected") {
+ jsLog.Debug("WSMessage match: File opened/selected => " + msg);
+ li.Text = "SD: "+msg;
+ }
+ else if (msg.includes("open failed, File:")) {
+ jsLog.Error("WSMessage match: open file error => " + msg);
+ li.Text = "SD Error: "+msg;
+ li.RsType = wmEnums.ConsoleLevels.ERROR;
+ }
+ else if (msg.toLowerCase().includes(".gco") || msg.toLowerCase().includes(".gcode") || msg.toLowerCase().includes(".g") || msg==="Begin file list" || msg==="End file list") {
+ if(msg.substring(0,16)==="Writing to file:") { WmUpload.ReadyToWrite = true; }
+ li.Text = "SD: "+msg;
+ li.SdFile = msg;
+ }
+ //else if() {
+ //}
+ else {
+ let rgx_rtemp_eb = /^T:\d{1,3}\.\d{1,2}\s+\/\d{1,3}\.\d{1,2}\s+B:\d{1,3}\.\d{1,2}\s+\/\d{1,3}\.\d{1,2}/;
+ let rgx_rtemp_e = /^T:\d{1,3}\.\d{1,2}\s+\/\d{1,3}\.\d{1,2}/;
+
+ if(rgx_rtemp_eb.test(msg) || rgx_rtemp_e.test(msg)){
+ jsLog.Verbose("Extruder temperatore report: "+msg);
+ msg = msg.replace(/\//g,"");
+ let tarr = msg.split(/\s/);
+ WmCharts.SetTempReport(tarr);
+ li.Text = "Temp report: "+msg;
+ }
+ else { li.Text = msg; }
+ }
+ jsLog.Verbose(li.ToString());
+ return li;
+ }
+}
+
+class wmGCommandItem {
+ constructor(g,p,v,d,s=null) {
+ this.GCode = g;
+ this.GParams = p;
+ this.Values = v;
+ this.Description = d;
+ this.Supported = s===null ? true : s;
+ }
+ ToJson() { return JSON.stringify(this); }
+ ToString() { return wmTools.Stringfy(this); }
+ static CalcChecksum(gc) {
+ let cs = 0;
+ gc = gc.toUpperCase().replace(/\s/g, '');
+ for(let i=0; gc[i]!=='*' && gc[i]!==null && i "+cs);
+ return cs;
+ }
+ static GetCommandItemByCode(gc) {
+ jsLog.Verbose("GetCommandItemByCode: Find preset for: "+gc);
+ let sgc = gc.split(/\s/);
+ jsLog.Verbose("GetCommandItemByCode: Command to find: "+sgc[0]);
+ for (let [k, v] of Object.entries(wmGCommands)) {
+ if(v.GCode.indexOf(sgc[0]) > -1) { return v; }
+ }
+ return null;
+ }
+}
+
+class wmFontIcon {
+ constructor(ico, mc = null) {
+ this.ico = ico;
+ this.mClass = mc !== null ? " "+mc : "";
+ }
+ ToString() { return wmTools.Stringfy(this); }
+ ToHtml() { return ""; }
+ AddClass(acl) { return ""; }
+}
+
+class wmTools {
+ static Stringfy(obj) {
+ if(obj !== null && obj !== "undefined") {
+ let rt = "";
+ for (let [k, v] of Object.entries(obj)) { rt += `${k}=${v};`; }
+ return rt;
+ } else {
+ return obj;
+ }
+ }
+ static StringFormat() {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return arguments[0].replace(/\{(\d+)\}/g, function (match, index) { return args[index]; });
+ }
+ static StringFormatJson(str) {
+ return JSON.stringify(str);
+ }
+ static StringFormatCsv(obj) {
+ let rt = "";
+ for (let [k, v] of Object.entries(obj)) { rt += `${v},`; }
+ return rt;
+ }
+ static StringRemoveSpecials(str) {
+ var spc = [".","~","{","}"];
+ for (var i=0; i0) {
+ var i = Math.floor( Math.log(size) / Math.log(1000) );
+ return ( size / Math.pow(1000, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
+ } else {
+ return size+" B";
+ }
+ }
+ static EscapeHtml(unsafe) {
+ unsafe = unsafe.replace(/&/g, "&");
+ unsafe = unsafe.replace(//g, ">");
+ unsafe = unsafe.replace(/"/g, """);
+ unsafe = unsafe.replace(/'/g, "'");
+ return unsafe;
+ }
+ static GetDateTime() {
+ var dt = new Date();
+ var hr = dt.getHours() < 10 ? "0" + dt.getHours() : dt.getHours();
+ var mn = dt.getMinutes() < 10 ? "0" + dt.getMinutes() : dt.getMinutes();
+ var sc = dt.getSeconds() < 10 ? "0" + dt.getSeconds() : dt.getSeconds();
+ return hr + ":" + mn + ":" + sc;
+ }
+ static GetBrowser() {
+ return $.browser.name+" v"+$.browser.versionNumber+" on "+$.browser.platform;
+ }
+ static GetScreenSize() {
+ let bwsize = "Viewport="+$(window).width()+"x"+$(window).height();
+ bwsize += " Document="+$(document).width()+"x"+$(document).height();
+ bwsize += " Screen="+window.screen.width+"x"+window.screen.height;
+ return bwsize;
+ }
+ static GetNumPercent(p,n) {
+ return (p / 100) * n;
+ }
+ static GetPercentage(p,n) {
+ return (p * 100) / n;
+ }
+ static FormatNumber(v,d) {
+ v = parseFloat(v);
+ return v.toFixed(d).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');
+ }
+ static CelsiusToFahrenheit(n) {
+ return n * 9 / 5 + 32;
+ }
+ static CelsiusToKelvin(n) {
+ return n+273.15;
+ }
+}
+
+class wmCookie {
+ static Read(cname) {
+ let decCookie = decodeURIComponent(document.cookie);
+ let carr = decCookie.split(';');
+ for (let i=0; i "+r);
+ return r;
+ }
+ }
+ return null;
+ }
+ static Write(cvalue, cname=null) {
+ let d = new Date();
+ d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000));
+ let expires = "expires=" + d.toGMTString();
+ let cn = cname === null ? "E4dWUI" : cname;
+ let cv = cn+ "=" + escape(cvalue) + "; " + expires + ";path=/; SameSite=None; Secure;";
+ document.cookie = cv;
+ jsLog.Verbose("Add/Update cookie => "+cv);
+ }
+ static CheckBrowser() {
+ wmCookie.Write('1','check_browser_cookie');
+ return (document.cookie.indexOf('check_browser_cookie') !== -1) ? true : false;
+ }
+ static Check() {
+ jsLog.Verbose("Checking for browser supported cookie");
+ if(wmCookie.CheckBrowser()===true) {
+ jsLog.Debug("Cookies supported. Looking for custom settings");
+ var cStr = wmCookie.Read("E4dWUI");
+ if(cStr === null){
+ jsLog.Verbose("No settings cookie found. Define defaults");
+ wmCookie.Write(JSON.stringify(wmSettings));
+ } else {
+ jsLog.Debug("Settings cookie found. Loading customized settings");
+ var cv = JSON.parse(cStr);
+ wmSettings.AutoConnect = cv.AutoConnect;
+ wmSettings.DefaultPanel = cv.DefaultPanel;
+ wmSettings.ConsoleDirection = cv.ConsoleDirection;
+ wmSettings.LogLevel = cv.LogLevel;
+ wmSettings.SymbolMode = cv.SymbolMode,
+ jsLog.Verbose("Customized cookie stored settings loaded");
+ jsLog.Verbose(wmTools.Stringfy(wmSettings));
+ }
+ } else {
+ jsLog.Warning("Cookies are not supported by the browser. Use default settings");
+ }
+ }
+}
+
+class jsLog {
+ static Info(logmsg) {
+ if(wmSettings.LogLevel >= wmEnums.LogLevels.INFO) { console.log("[INFO ] "+logmsg); }
+ }
+ static Warning(logmsg) {
+ if(wmSettings.LogLevel >= wmEnums.LogLevels.WARNING) { console.log("[WARN ] "+logmsg); }
+ }
+ static Error(logmsg) {
+ if(wmSettings.LogLevel >= wmEnums.LogLevels.ERROR) { console.log("[ERROR ] "+logmsg); }
+ }
+ static Debug(logmsg) {
+ if(wmSettings.LogLevel >= wmEnums.LogLevels.DEBUG) { console.log("[DEBUG ] "+logmsg); }
+ }
+ static Verbose(logmsg) {
+ if(wmSettings.LogLevel >= wmEnums.LogLevels.VERBOSE) { console.log("[VERBOSE] "+logmsg); }
+ }
+}
+
+var wmGCommands = {
+ CustomCmd : new wmGCommandItem('',null,null,'Custom command'),
+ MoveFw : new wmGCommandItem('G1','Y{0}',10,'Move forward on Y axis'),
+ MoveBw : new wmGCommandItem('G1','Y-{0}',10,'Move backward on Y axis'),
+ MoveSx : new wmGCommandItem('G1','X{0}',10,'Move left on X axis'),
+ MoveDx : new wmGCommandItem('G1','X-{0}',10,'Move right on X axis'),
+ MoveUp : new wmGCommandItem('G1','Z{0}',10,'Move up on Z axis'),
+ MoveDw : new wmGCommandItem('G1','Z-{0}',10,'Move down on Z axis'),
+ FillRetrive : new wmGCommandItem('G10',null,null,'Retract filament'),
+ FillExtrude : new wmGCommandItem('GYYYY',null,null,'Extrude filament'),
+ MoveHome : new wmGCommandItem('G28',null,null,'Go home on all axis'),
+ MoveHomeX : new wmGCommandItem('G28','X',null,'Go home on X axis'),
+ MoveHomeY : new wmGCommandItem('G28','Y',null,'Go home on Y axis'),
+ MoveHomeZ : new wmGCommandItem('G28','Z',null,'Go home on Z axis'),
+ StepEnable : new wmGCommandItem('M17','{0}','E X Y Z','Enable stepper'),
+ StepEnableAll : new wmGCommandItem('M17',null,null,'Enable all steppers'),
+ StepDisable : new wmGCommandItem('M18','{0}','E X Y Z','Disable stepper'),
+ StepDisableAll: new wmGCommandItem('M18',null,null,'Disable all steppers'),
+ SdGetList : new wmGCommandItem('M20',null,null,'Get SD card content'),
+ SdInit : new wmGCommandItem('M21',null,null,'Init SD card'),
+ SdRelease : new wmGCommandItem('M22',null,null,'Release SD card'),
+ SdFileSel : new wmGCommandItem('M23','{0}','','Select an SD file'),
+ SdFilePrint : new wmGCommandItem('M24','{0}','','Start an SD print'),
+ SdPrintStatus : new wmGCommandItem('M27',null,null,'SD print status'),
+ SdPrintReport : new wmGCommandItem('M27','S{0}',5,'SD print status report'),
+ SdFileStart : new wmGCommandItem('M28','{0}','','Start SD write'),
+ SdFileStop : new wmGCommandItem('M29',null,null,'Stop SD write'),
+ SdFileDel : new wmGCommandItem('M30','{0}','','Delete an SD file'),
+ PrintTime : new wmGCommandItem('M31',null,null,'Print time'),
+ FanOn : new wmGCommandItem('M106','S{0}',128,'Set fan on with speed'),
+ FanOff : new wmGCommandItem('M107',null,null,'Set fan off'),
+ GetPosition : new wmGCommandItem('M114',null,null,'Get Current Position'),
+ FWInfo : new wmGCommandItem('M115',null,null,'Get firmware info',false),
+ SetTempUnit : new wmGCommandItem('M149','{0}','C','Set temperature units'),
+ SetTempOff : new wmGCommandItem('M155','S0','','Turn off temperature status'),
+ SetTempOn : new wmGCommandItem('M155','S{0}',1,'Get temp status (1 sec default)'),
+ GetSetting : new wmGCommandItem('M503',null,null,'Get settings report')
+};
+
+var wmIcons = {
+ Wifi: new wmFontIcon('wifi'),
+ Plug: new wmFontIcon('plug'),
+ Ban: new wmFontIcon('ban'),
+ Bolt: new wmFontIcon('bolt'),
+ Info: new wmFontIcon('info'),
+ InfoCircle: new wmFontIcon('info-circled'),
+ Triangle: new wmFontIcon('exclamation-triangle'),
+ CheckSquare: new wmFontIcon('check-square'),
+ Terminal: new wmFontIcon('terminal'),
+ Exchange: new wmFontIcon('exchange'),
+ ChevronUp: new wmFontIcon('chevron-up'),
+ ChevronDown: new wmFontIcon('chevron-down'),
+ ChevronLeft: new wmFontIcon('chevron-left'),
+ ChevronRight: new wmFontIcon('chevron-right'),
+ LongArrowUp: new wmFontIcon('long-arrow-up'),
+ LongArrowDown: new wmFontIcon('long-arrow-down'),
+ LongArrowLeft: new wmFontIcon('long-arrow-left'),
+ LongArrowRight: new wmFontIcon('long-arrow-right')
+};
+
+var wmColors = {
+ Black : 'rgb(0, 0, 0)',
+ Blue : 'rgb(54, 162, 235)',
+ Green : 'rgb(0, 255, 0)',
+ GreenSuc: 'rgb(92, 184, 92)',
+ GreenTur: 'rgb(75, 192, 192)',
+ Grey : 'rgb(201, 203, 207)',
+ Yellow : 'rgb(255, 205, 86)',
+ Orange : 'rgb(255, 159, 64)',
+ Purple : 'rgb(153, 102, 255)',
+ Red : 'rgb(255, 0, 0)',
+ RedCoral: 'rgb(255, 99, 132)'
+};
+// Define default setting onject
+jsLog.Verbose("JS Classes initializzation completed");
+jsLog.Debug("Default settings loaded: "+wmTools.Stringfy(wmSettings));
+wmCookie.Check();
diff --git a/data/www/webmarlin-font.css b/data/www/webmarlin-font.css
new file mode 100644
index 0000000000..ca4c7d976a
--- /dev/null
+++ b/data/www/webmarlin-font.css
@@ -0,0 +1,169 @@
+@charset "UTF-8";
+@font-face {
+ font-family: "marlinui";
+ src:url("marlinui.eot");
+ src:url("marlinui.eot?#iefix") format("embedded-opentype"), url("marlinui.woff") format("woff"), url("marlinui.ttf") format("truetype"), url("marlinui.svg#marlinui") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+[data-icon]:before {
+ font-family: "marlinui" !important;
+ content: attr(data-icon);
+ font-style: normal !important;
+ font-weight: normal !important;
+ font-variant: normal !important;
+ text-transform: none !important;
+ speak: none;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+[class^="icon-"]:before, [class*=" icon-"]:before {
+ font-family: "marlinui" !important;
+ font-style: normal !important;
+ font-weight: normal !important;
+ font-variant: normal !important;
+ text-transform: none !important;
+ speak: none;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.icon-home:before {
+ content: "\61";
+}
+.icon-info:before {
+ content: "\62";
+}
+.icon-cog:before {
+ content: "\63";
+}
+.icon-tasks:before {
+ content: "\64";
+}
+.icon-chevron-down:before {
+ content: "\66";
+}
+.icon-chevron-left:before {
+ content: "\67";
+}
+.icon-chevron-right:before {
+ content: "\68";
+}
+.icon-chevron-up:before {
+ content: "\69";
+}
+.icon-arrows-alt:before {
+ content: "\6a";
+}
+.icon-upload:before {
+ content: "\6b";
+}
+.icon-ban:before {
+ content: "\6d";
+}
+.icon-github:before {
+ content: "\6e";
+}
+.icon-thermometer:before {
+ content: "\6f";
+}
+.icon-bolt:before {
+ content: "\65";
+}
+.icon-sort-asc:before {
+ content: "\70";
+}
+.icon-sort-desc:before {
+ content: "\71";
+}
+.icon-long-arrow-left:before {
+ content: "\72";
+}
+.icon-long-arrow-down:before {
+ content: "\73";
+}
+.icon-long-arrow-right:before {
+ content: "\74";
+}
+.icon-long-arrow-up:before {
+ content: "\75";
+}
+.icon-arrows:before {
+ content: "\76";
+}
+.icon-arrows-v:before {
+ content: "\77";
+}
+.icon-arrows-h:before {
+ content: "\78";
+}
+.icon-angle-double-up:before {
+ content: "\79";
+}
+.icon-angle-double-down:before {
+ content: "\7a";
+}
+.icon-tencent-weibo:before {
+ content: "\41";
+}
+.icon-playback-fast-forward:before {
+ content: "\42";
+}
+.icon-fire:before {
+ content: "\43";
+}
+.icon-forward:before {
+ content: "\44";
+}
+.icon-terminal:before {
+ content: "\45";
+}
+.icon-info-circled:before {
+ content: "\6c";
+}
+.icon-exclamation-triangle:before {
+ content: "\46";
+}
+.icon-exchange:before {
+ content: "\47";
+}
+.icon-plus:before {
+ content: "\48";
+}
+.icon-minus:before {
+ content: "\49";
+}
+.icon-check-square:before {
+ content: "\4a";
+}
+.icon-facebook-square:before {
+ content: "\4b";
+}
+.icon-file:before {
+ content: "\4c";
+}
+.icon-trash:before {
+ content: "\4d";
+}
+.icon-print:before {
+ content: "\4e";
+}
+.icon-refresh:before {
+ content: "\4f";
+}
+.icon-plug:before {
+ content: "\51";
+}
+.icon-wifi:before {
+ content: "\52";
+}
+.icon-sliders:before {
+ content: "\50";
+}
+.icon-folder-open:before {
+ content: "\54";
+}
+.icon-code-download:before {
+ content: "\53";
+}
\ No newline at end of file
diff --git a/data/www/webmarlin.css b/data/www/webmarlin.css
new file mode 100644
index 0000000000..aa1eea9a98
--- /dev/null
+++ b/data/www/webmarlin.css
@@ -0,0 +1,45 @@
+/*
+Bootstrap Toggle: bootstrap4-toggle.css v3.6.1
+https://gitbrent.github.io/bootstrap4-toggle/
+*/
+.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}.toggle{position:relative;overflow:hidden}.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}.toggle input[type=checkbox]{display:none}.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}.toggle-group label,.toggle-group span{cursor:pointer}.toggle.off .toggle-group{left:-100%}.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}.toggle.btn{min-width:3.7rem;min-height:2.15rem}.toggle-on.btn{padding-right:1.5rem}.toggle-off.btn{padding-left:1.5rem}.toggle.btn-lg{min-width:5rem;min-height:2.815rem}.toggle-on.btn-lg{padding-right:2rem}.toggle-off.btn-lg{padding-left:2rem}.toggle-handle.btn-lg{width:2.5rem}.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}.toggle-on.btn-sm{padding-right:1rem}.toggle-off.btn-sm{padding-left:1rem}.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}.toggle-on.btn-xs{padding-right:.8rem}.toggle-off.btn-xs{padding-left:.8rem}
+
+/*
+E4d@box Marlin WUI
+*/
+html, body { height: 100%; margin: 0; }
+
+@media all and (min-width: 500px) {
+ #main-panel{ text-align: center; }
+ #accordion-panels { width: 500px; height:100%; display: block; margin-left: auto; margin-right: auto;}
+ .modal-popup { width:400px; }
+}
+
+.console-listbox { height: 450px; }
+@media all and (max-height: 400px) { .console-listbox { height: 245px; } }
+@media all and (min-height:401px) and (max-height: 500px) { .console-listbox { height: 280px; } }
+@media all and (min-height:501px) and (max-height: 600px) { .console-listbox { height: 350px; } }
+@media all and (min-height:601px) and (max-height: 700px) { .console-listbox { height: 350px; } }
+@media all and (min-height:701px) and (max-height: 800px) { .console-listbox { height: 400px; } }
+@media all and (min-height:801px) and (max-height: 900px) { .console-listbox { height: 445px; } }
+@media all and (min-height:901px) and (max-height: 1000px) { .console-listbox { height: 480px; } }
+@keyframes tgle { 0% { opacity: 0; } 49.99% { opacity: 0; } 50% { opacity: 1; } 99.99% { opacity: 1; } 100% { opacity: 0; } }
+@keyframes blink-info { 0% { background-color: #17a2b8; } 50% { opacity: #f8f9fa; } 75% { opacity: #17a2b8; } 100% { opacity: #f8f9fa; } }
+
+.blink { animation-duration: 500ms; animation-name: tgle; animation-iteration-count: infinite; }
+.bg-info-blink { animation-duration: 500ms; animation-name: blink-info; animation-iteration-count: infinite;}
+.modal-popup { width:calc(100%-100px); }
+.field-labels { font-size: 10pt; font-weight: bold; }
+.field-description { font-size: 10pt; font-style: italic; }
+.action-description { font-size: 10pt; }
+.console-listbox { overflow-y: scroll; overflow-x: hidden; }
+.console-list-items-success { background-color: lightgreen; }
+.console-list-items-info { background-color: lightsteelblue; }
+.console-list-items-error { background-color: lightcoral; }
+.console-list-items-terminal { background-color: lightgray; }
+.console-list-items-warning { background-color: orange; }
+.console-list-items { font-size: 9pt; padding-left: 4px; padding-right: 4px; padding-top: 0px; padding-bottom: 4px; }
+.collapse-panel { overflow-y: scroll; overflow-x: hidden; }
+.card-header-title { font-size: 10pt; font-weight: bold; }
+.card-header-description { font-size: 8pt; }
+.badge-description { font-size: 9pt; }
diff --git a/data/www/webmarlin.js b/data/www/webmarlin.js
new file mode 100644
index 0000000000..943f7b9c08
--- /dev/null
+++ b/data/www/webmarlin.js
@@ -0,0 +1,872 @@
+var wmLogBuffer = new Array();
+var wmSdListCounter = {
+ FILES:0,
+ FOLDERS:0,
+ Reset: function() {
+ wmSdListCounter.FILES = 0;
+ wmSdListCounter.FOLDERS = 0;
+ $('#list-sd-content').empty();
+ $('#div-sdlist-file-count').text(wmSdListCounter.FILES);
+ $('#div-sdlist-folder-count').text(wmSdListCounter.FOLDERS);
+ }
+};
+
+var WmButtonGroups = {
+ FileManagement: ["#btn-get-sdcontent","#btn-set-sdinit","#btn-set-sdrelease","#file-upload","#btn-file-upload"],
+ FileActions: ["#btn-set-sdprint","#btn-set-sddelete"],
+ FileProcess: ["#btn-file-proc","#btn-file-proc-cancel"],
+ TempStatus: ["#set-auto-temp","#auto-temp-interval","#chart-show-extruder","#chart-show-bed"],
+ FanSpeed: ["#fan-speed-range"],
+ MoveHome: ["#btn-move-home-all","#btn-move-home-x","#btn-move-home-y","#btn-move-home-z"],
+ Move: ["#btn-move-xl","#btn-move-xr","#btn-move-yf","#btn-move-yb","#btn-move-zu","#btn-move-zd"],
+ StepperAll: ["#set-stepper-all","#set-stepper-x","#set-stepper-y","#set-stepper-z","#set-stepper-e"],
+ Stepper: ["#set-stepper-x","#set-stepper-y","#set-stepper-z","#set-stepper-e"],
+
+ All: function() {
+ let all = [];
+ all = all.concat(
+ WmButtonGroups.FileManagement,
+ WmButtonGroups.FileActions,
+ WmButtonGroups.FileProcess,
+ WmButtonGroups.TempStatus,
+ WmButtonGroups.FanSpeed,
+ WmButtonGroups.MoveHome,
+ WmButtonGroups.Move,
+ WmButtonGroups.StepperAll
+ );
+ return all;
+ }
+};
+
+var wmWebSoket = {
+ WSObject: null,
+ Connect: function() {
+ WsUrl=`ws://${location.host}/ws`;
+ try {
+ if(wmWebSoket.WSObject === null) {
+ jsLog.Debug("WebSocket: Trying connecting to " + WsUrl);
+ wmWebSoket.WSObject = new WebSocket(WsUrl);
+ wmWebSoket.SetWsStatusBar(wmWebSoket.WSObject.readyState);
+ wmWebSoket.WSObject.onopen = function () {
+ jsLog.Info("WebSocket: Successfully connected to " + WsUrl);
+ wmWebSoket.SetWsStatusBar(wmWebSoket.WSObject.readyState);
+ WmControls.Enable(WmButtonGroups.All());
+ wmWebSoket.Send(wmGCommands.SdPrintStatus);
+ };
+ wmWebSoket.WSObject.onclose = function () {
+ jsLog.Info("WebSocket: Disconnected from "+WsUrl);
+ wmWebSoket.SetWsStatusBar(null);
+ wmWebSoket.WSObject = null;
+ WmControls.Disable(WmButtonGroups.All());
+ };
+ wmWebSoket.WSObject.onerror = function () {
+ jsLog.Error("WebSocket: Connection error");
+ WmConsole.Trace(new wmLogItem("WebSoket connection error", wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR));
+ };
+ wmWebSoket.WSObject.onmessage = function (event) {
+ jsLog.Info("WebSocket: Message received: "+event.data);
+ wmWebSoket.OnMessage(event.data.trim());
+ };
+ }
+ }
+ catch (exception) {
+ jsLog.Error("WebSocket: Exception: "+exception);
+ wmWebSoket.SetWsStatusBar(wmWebSoket.WSObject.readyState);
+ WmConsole.Trace(new wmLogItem("WebSocket: Connection exception", wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR));
+ }
+ },
+ Disconnect: function() {
+ try {
+ if(wmWebSoket.WSObject !== null && wmWebSoket.WSObject.readyState === wmEnums.WSSatuses.OPEN) {
+ jsLog.Debug("WebSocket: Disconnecting from "+WsUrl);
+ WmConsole.Trace(new wmLogItem("WebSoket disconnecting...", wmEnums.WSMsgDirection.SENT, wmEnums.ConsoleLevels.INFO));
+ wmWebSoket.WSObject.close();
+ wmWebSoket.WSObject = null;
+ }
+ }
+ catch (exception) {
+ jsLog.Error("WebSocket: Exception: "+exception);
+ wmWebSoket.SetWsStatusBar(wmWebSoket.WSObject.readyState);
+ WmConsole.Trace(new wmLogItem("WebSoket connection exception", wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR));
+ }
+ },
+ Send: function(gCmd) {
+ if(wmWebSoket.WSObject !== null && wmWebSoket.WSObject.readyState === wmEnums.WSSatuses.OPEN) {
+ let strcmd = gCmd.GCode;
+ if (gCmd.GParams === null) { jsLog.Verbose('WebSocket: Send: Command with no params detected'); }
+ else {
+ jsLog.Verbose('WebSocket: Send: Arguments detected:'+gCmd.GParams);
+ gCmd.GParams = wmTools.StringFormat(gCmd.GParams, gCmd.Value);
+ strcmd = strcmd +" "+gCmd.GParams;
+ }
+ jsLog.Debug('WebSocket: Send commandstring: '+strcmd);
+ WmConsole.Trace(new wmLogItem("GCmd: " + strcmd + " " + gCmd.Description, wmEnums.WSMsgDirection.SENT, wmEnums.ConsoleLevels.SUCCESS));
+ try { wmWebSoket.WSObject.send(strcmd + '\n'); }
+ catch (exception) {
+ jsLog.Error('WebSocket: Exception:' + exception);
+ WmConsole.Trace(new wmLogItem("WebSoket: Command exception: "+exception, wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR));
+ }
+ } else { $('#modal-connect').modal('show'); }
+ },
+ OnMessage: function(mdt) {
+ if(mdt === "") { jsLog.Debug("WSMessage match: Empty message (skipped)"); }
+ else {
+ let litem = wmLogItem.ParseWsMessage(mdt);
+ WmConsole.Trace(litem);
+ if(litem.SdFile !== null) { WmConsole.TraceSdFile(litem); }
+ }
+ },
+ SetWsStatusBar: function(rs) {
+ let cli = new wmLogItem();
+ let ctrls = { div:$('#div-conn-statusmsg'), ico:$('#div-conn-statusico'), btn:$('#btn-connect-status'), bar:$('#div-conn-statusbar') };
+ switch (rs) {
+ case wmEnums.WSSatuses.CONNECTING:
+ cli.SetValues("Connecting to "+WsUrl, wmEnums.WSMsgDirection.SENT, wmEnums.ConsoleLevels.INFO);
+ ctrls.ico.html(""+wmIcons.Exchange.AddClass('')+"");
+ ctrls.div.html("Connecting...");
+ ctrls.btn.html("");
+ ctrls.bar.removeClass('bg-success bg-warning bg-danger text-light text-dark').addClass("bg-warning text-dark");
+ break;
+ case wmEnums.WSSatuses.OPEN:
+ cli.SetValues("Connected to "+WsUrl, wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.SUCCESS);
+ ctrls.ico.html(wmIcons.Wifi.AddClass(''));
+ ctrls.div.html("Connected");
+ ctrls.btn.html(wmIcons.Ban.ToHtml());
+ ctrls.bar.removeClass('bg-success bg-warning bg-danger text-light text-dark').addClass("bg-success text-light");
+ break;
+ case wmEnums.WSSatuses.CLOSED:
+ cli.SetValues("Disconnected from "+WsUrl, wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR);
+ ctrls.ico.html(wmIcons.Plug.AddClass(''));
+ ctrls.div.html("Disconnected");
+ ctrls.btn.html(wmIcons.Bolt.ToHtml());
+ ctrls.bar.removeClass('bg-success bg-warning bg-danger text-light text-dark').addClass("bg-danger text-light");
+ break;
+ case wmEnums.WSSatuses.CLOSING:
+ cli.SetValues("Disconnecting from "+WsUrl, wmEnums.WSMsgDirection.SENT, wmEnums.ConsoleLevels.WARNING);
+ ctrls.ico.html(""+wmIcons.Wifi.AddClass('')+"");
+ ctrls.div.html("Disconnecting...");
+ ctrls.btn.html("");
+ ctrls.bar.removeClass('bg-success bg-warning bg-danger text-light text-dark').addClass("bg-warning text-dark");
+ break;
+ default:
+ cli.SetValues("Disconnected from "+WsUrl, wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR);
+ ctrls.ico.html(wmIcons.Plug.AddClass(''));
+ ctrls.div.html("Disconnected");
+ ctrls.btn.html(wmIcons.Bolt.ToHtml());
+ ctrls.bar.removeClass('bg-success bg-warning bg-danger text-light text-dark').addClass("bg-danger text-light");
+ break;
+ }
+ WmConsole.Trace(cli);
+ }
+};
+
+var WmUpload = {
+ Reader: null,
+ FileName: null,
+ FileSize: null,
+ FileContent: null,
+ ReadyToWrite: false,
+ Cancelled: false,
+ Load: function() {
+ let [fn,fe] = $("#file-upload-label").text().toUpperCase().split(".");
+ WmUpload.FileName = fn.substring(0,7)+".GCO";
+ let input = $('#file-upload').get(0);
+ if (input.files.length) {
+ let tfile = input.files[0];
+ WmUpload.Reader = new FileReader();
+ WmUpload.Reader.onloadstart = function() {
+ jsLog.Debug("File uploading starting");
+ $('#div-upload-fname').html(WmUpload.FileName);
+ if(!$('#upload-process-collapse').hasClass("show")){ $('#upload-process-collapse').collapse('show'); }
+ };
+ WmUpload.Reader.onload = function(e) {
+ jsLog.Debug("File uploading completed");
+ WmUpload.FileSize = e.loaded;
+ WmUpload.FileContent = e.target.result.split("\n");
+ WmUpload.Cancelled = false;
+ $('#div-upload-fsize').html(wmTools.FileSizeFormat(WmUpload.FileSize));
+ $('#div-upload-fproc').html(wmTools.FormatNumber(WmUpload.FileContent.length,0));
+ WmControls.Enable(WmButtonGroups.FileProcess);
+ WmUpload.FileProgress(0,"Ready to process...");
+
+ };
+ WmUpload.Reader.onloadend = function(e) {
+ jsLog.Debug("File uploading finished");
+ jsLog.Debug("___________________onloadend");
+ };
+ WmUpload.Reader.readAsText(tfile);
+ return true;
+ } else {
+ WmControls.ShowModalAlert('Please select the upload file before continuing');
+ WmControls.Enable(WmButtonGroups.FileManagement,WmButtonGroups.FileActions);
+ return false;
+ }
+ },
+ Cancel: function() {
+ jsLog.Debug("File uploading aborted");
+ WmUpload.Reader = null;
+ WmUpload.FileName = null;
+ WmUpload.FileSize = null;
+ WmUpload.Cancelled = true;
+ WmControls.Disable(WmButtonGroups.FileProcess);
+ WmControls.Enable(WmButtonGroups.FileManagement,WmButtonGroups.FileActions);
+ $('#div-upload-fsize').html("-");
+ $('#div-upload-fproc').html("-");
+ $('#div-upload-fname').html("-");
+ WmUpload.FileProgress(0," ");
+ if($('#upload-process-collapse').hasClass("show")){ $('#upload-process-collapse').collapse('hide'); }
+ },
+ FileProcess: function() {
+ WmControls.Disable([$("#btn-file-proc")]);
+ let fl = WmUpload.FileContent.length;
+ jsLog.Debug("Start process GCode lines ("+WmUpload.FileSize+" total)");
+ WmUpload.FileProgress(0,"Start analyzing uploaded GCode...");
+ wmGCommands.SdFileStart.GParams = WmUpload.FileName;
+ wmWebSoket.Send(wmGCommands.SdFileStart);
+ var i = 0;
+ var n = 1;
+ (function pgline() {
+ if(WmUpload.Cancelled){
+ wmWebSoket.Send(wmGCommands.SdFileStop);
+ return;
+ }
+ else if(!WmUpload.ReadyToWrite){
+ jsLog.Debug("WmUpload.FileProcess: Waiting ready to write...");
+ WmUpload.FileProgress(0,"Waiting ready to write...");
+ setTimeout(pgline, 500);
+ }
+ else {
+ let p = wmTools.GetPercentage(i+1,fl);
+ WmUpload.FileProgress(p,"Analyzing line "+(i+1)+" of "+fl);
+ let gitem = { line:WmUpload.FileContent[i], process:false, cksum:0 };
+
+ if(gitem.line.trim()==="" || gitem.line.match(/^ *$/)) { jsLog.Verbose("GLine: "+i+": "+gitem.line+" => Empty line (skip)"); }
+ else if(gitem.line.substring(0,1)===";") { jsLog.Verbose("GLine: "+i+": "+gitem.line+" => Comment line (skip)"); }
+ else if(gitem.line.indexOf(";") > -1) { gitem.line = gitem.line.substring(0,gitem.line.indexOf(";")); gitem.process=true; }
+ else { gitem.process = true; }
+
+ if(gitem.process) {
+ gitem.line = "N"+n+" "+gitem.line.trim();
+ gitem.line = gitem.line+"*"+wmGCommandItem.CalcChecksum(gitem.line);
+ jsLog.Verbose("GLINE TO SEND: "+gitem.line);
+ wmGCommands.CustomCmd.GCode = gitem.line;
+ wmWebSoket.Send(wmGCommands.CustomCmd);
+ n++;
+ }
+ i++;
+ if (i < fl) { setTimeout(pgline, 10); }
+ else {
+ WmUpload.FileProgress(100,"GCode Analysis completed!");
+ WmUpload.ReadyToWrite = false;
+ wmWebSoket.Send(wmGCommands.SdFileStop);
+ WmUpload.FileCompleted();
+ }
+ }
+ })();
+ },
+ FileProgress: function(p,m) {
+ p = wmTools.FormatNumber(p,0);
+ $('#upload-progressbar').text(p+"%");
+ $('#upload-progressbar').css('width',p+'%').attr('aria-valuenow', p);
+ $('#upload-progress-text').html(m);
+ if(p===100) { $('#upload-progressbar').removeClass("progress-bar-animated"); }
+ },
+ FileCompleted: function() {
+ WmControls.Disable(WmButtonGroups.FileProcess);
+ WmButtons.GetSdContentList();
+ },
+};
+
+var WmButtons = {
+ ConsoleListClear: function() { WmConsole.Clear(); },
+ ConsoleListExport: function() { WmConsole.Export(); },
+ DeleteSdConfirm: function() {
+ $('#div-sdfile-delete-badge').html($('#txt-sdfile-selected').val());
+ },
+ DeleteSdSelected: function() {
+ jsLog.Debug("DeleteSdSelected: Delete file:"+$("#txt-sdfile-selected").val());
+ WmControls.Disable(WmButtonGroups.FileActions);
+ $('#div-sdfile-delete-rs').collapse('show');
+ wmGCommands.SdFileDel.GParams = $("#txt-sdfile-selected").val();
+ wmWebSoket.Send(wmGCommands.SdFileDel);
+ setTimeout(function(){
+ $('#modal-sdfile-delete').modal('hide');
+ $('#div-sdfile-delete-rs').collapse('hide');
+ WmButtons.GetSdContentList();
+ }, 2000);
+ },
+ GCommandSetPreset: function(gc) {
+ jsLog.Debug("Set preset GCommand ("+gc+")");
+ $('#text-gcommand').val(gc);
+ $('#modal-presets').modal('hide');
+ WmAutostart.SetGCommandChecksum();
+ },
+ GetSdContentList: function() {
+ wmSdListCounter.Reset();
+ $('#txt-sdfile-selected').val('');
+ WmControls.Disable(WmButtonGroups.FileManagement);
+ wmWebSoket.Send(wmGCommands.SdGetList);
+ },
+ PrintSdConfirm: function() {
+ $('#div-sdfile-print-badge').html($('#txt-sdfile-selected').val());
+ },
+ PrintSdSelected: function() {
+ jsLog.Debug("PrintSdSelected: Print file:"+$("#txt-sdfile-selected").val());
+ WmControls.Disable(WmButtonGroups.FileActions);
+ $('#div-sdfile-print-rs').collapse('show');
+ wmGCommands.SdFilePrint.GParams = $("#txt-sdfile-selected").val();
+ wmWebSoket.Send(wmGCommands.SdFilePrint);
+ setTimeout(function(){
+ $('#modal-sdfile-print').modal('hide');
+ $('#div-sdfile-print-rs').collapse('hide');
+ WmAutostart.SetShownPanel(wmEnums.Panels.STATUS);
+ }, 2000);
+ },
+ SaveSettings: function() {
+ jsLog.Verbose("Button 'btn-save-settings' clicked");
+ WmControls.Disable(['#btn-save-settings','#btn-close-settings']);
+ wmSettings.AutoConnect = document.getElementById('set-auto-connect').checked;
+ wmSettings.DefaultPanel = parseInt($('#set-default-panel').val());
+ wmSettings.LogLevel = parseInt($('#set-log-level').val());
+ wmSettings.SymbolMode = $('#set-log-symbol').val();
+ wmSettings.AutoTempInterval = $('#set-default-autotemp').val();
+ if($('#set-default-tempunit').val()===0) { wmSettings.TempUnit = wmEnums.TempUnits.CELSIUS; }
+ else if($('#set-default-tempunit').val()===1) { wmSettings.TempUnit = wmEnums.TempUnits.FAHRENHEIT; }
+ else if( $('#set-default-tempunit').val()===2) { wmSettings.TempUnit = wmEnums.TempUnits.KELVIN; }
+
+ if(wmSettings.SymbolMode==='letter') {
+ wmSettings.SymbolSend = wmEnums.WsMsgSymbols.SENT.LETTER;
+ wmSettings.SymbolReceive = wmEnums.WsMsgSymbols.RECEIVED.LETTER;
+ } else {
+ wmSettings.SymbolSend = $('#div-log-symbol-icon-sample-s').html();
+ wmSettings.SymbolReceive = $('#div-log-symbol-icon-sample-r').html();
+ }
+ if(document.getElementById('set-trace-mode-append').checked) {
+ wmSettings.ConsoleDirection = wmEnums.ConsoleDirection.APPEND;
+ } else {
+ wmSettings.ConsoleDirection = wmEnums.ConsoleDirection.PREPEND;
+ }
+ wmCookie.Write(wmTools.StringFormatJson(wmSettings));
+ $('#div-save-setting-rs').collapse('show');
+ setTimeout(function(){
+ $('#modal-settings').modal('hide');
+ $('#div-save-setting-rs').collapse('hide');
+ WmControls.Enable(['#btn-save-settings','#btn-close-settings']);
+ }, 2000);
+ },
+ SdInit: function() {
+ wmWebSoket.Send(wmGCommands.SdInit);
+ },
+ SdRelease: function() {
+ wmWebSoket.Send(wmGCommands.SdRelease);
+ },
+ SendGcommand: function() {
+ if(wmWebSoket.WSObject !== null && wmWebSoket.WSObject.readyState === wmEnums.WSSatuses.OPEN) {
+ WmControls.Disable(["#btn-gcommand"]);
+ let gcmd = $('#text-gcommand');
+ if (gcmd.val() === "") {
+ gcmd.removeClass('border-dark').addClass('border-danger');
+ jsLog.Warning("Empty custom command string detected");
+ gcmd.focus();
+ } else {
+ gcmd.removeClass('border-danger').addClass('border-dark');
+ let gc = wmGCommandItem.GetCommandItemByCode(gcmd.val().trim().toUpperCase());
+ if(gc === null) {
+ wmGCommands.CustomCmd.GCode = gcmd.val().trim().toUpperCase();
+ jsLog.Debug("Sending custom command: " + wmGCommands.CustomCmd.GCode);
+ wmWebSoket.Send(wmGCommands.CustomCmd);
+ } else {
+ if(gc.Supported) {
+ wmGCommands.CustomCmd.GCode = gcmd.val().trim().toUpperCase();
+ jsLog.Debug("Sending custom command: " + wmGCommands.CustomCmd.GCode);
+ wmWebSoket.Send(wmGCommands.CustomCmd);
+ } else {
+ jsLog.Warning("Unsupported command: " + wmGCommands.CustomCmd.GCode);
+ WmConsole.Trace(new wmLogItem("GCmd: " + gcmd.val() + " Unsupported command", wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.ERROR));
+ }
+ }
+ gcmd.val('');
+ $('#checksum-gcommand-value').html(' ');
+ WmControls.Enable(["#btn-gcommand"]);
+ }
+ } else { $('#modal-connect').modal('show'); }
+ },
+ SetPositionHome: function(b) {
+ if(b.id==="btn-move-home-all"){ wmWebSoket.Send(wmGCommands.MoveHome); }
+ else if (b.id==="btn-move-home-x"){ wmWebSoket.Send(wmGCommands.MoveHomeX); }
+ else if (b.id==="btn-move-home-y"){ wmWebSoket.Send(wmGCommands.MoveHomeY);}
+ else if (b.id==="btn-move-home-z"){ wmWebSoket.Send(wmGCommands.MoveHomeZ);}
+ },
+ SetSdSelected: function(sdi) {
+ jsLog.Debug("SetSdSelected: Selected file:"+$(sdi).attr("data-sdfile"));
+ $('#txt-sdfile-selected').val($(sdi).attr("data-sdfile"));
+ let lip = document.getElementById("list-sd-content").getElementsByTagName("a");
+ for (let i=0; i 0) {
+ for(let i=0; i 0) {
+ for(let i=0; i"+fsv+"");
+ $('#div-fan-speed-set').html(rv+"%"+fsv+"");
+ if(rv===0) { wmWebSoket.Send(wmGCommands.FanOff); }
+ else {
+ wmGCommands.FanOn.GParams = "S"+fsv;
+ wmWebSoket.Send(wmGCommands.FanOn);
+ }
+ WmChartsData.FanSpeed.DataUpdate(rv);
+ },
+ ResetSdFileCounters() {
+ $('#list-sd-content').empty();
+ $('#div-sdlist-file-count').text(0);
+ $('#div-sdlist-folder-count').text(0);
+ },
+ UpdateTemperatures: function(dt){
+ $('#div-temp-extruder-detect').text(dt.ExtruderTemp);
+ $('#div-temp-extruder-set').text(dt.ExtruderSet);
+ $('#div-temp-extruder-unit').text(wmSettings.TempUnit.LABEL);
+ if(dt.BedTemp !== null) {
+ $('#div-temp-bed-detect').text(dt.BedTemp);
+ $('#div-temp-bed-set').text(dt.BedSet);
+ $('#div-temp-bed-unit').text(wmSettings.TempUnit.LABEL);
+ }
+ },
+ SetPrinterStatusInfo: function(s, m) {
+ if(!s) {
+ $('#div-pstatus-sdprint').removeClass("badge-danger").addClass("badge-info");
+ $('#div-pstatus-sdprint').html("Ready to print");
+ $('#div-pstatus-timer').collapse('hide');
+ $('#div-pstatus-progress').collapse('hide');
+ } else {
+ $('#div-pstatus-sdprint').removeClass("badge-danger badge-info").addClass("badge-success");
+ $('#div-pstatus-sdprint').html("Printing in progress");
+ $('#div-pstatus-timer').collapse('show');
+ $('#div-pstatus-progress').collapse('show');
+ }
+ },
+ SetSteppers: function(o) {
+ if(o.id==="set-stepper-all") {
+ WmControls.SetCheckStatus(WmButtonGroups.Stepper,o.checked);
+ if(o.checked) { wmWebSoket.Send(wmGCommands.StepEnableAll); } else { wmWebSoket.Send(wmGCommands.StepDisableAll); }
+ } else {
+ if(o.id==="set-stepper-x") { wmGCommands.StepEnable.GParams = "X"; }
+ else if(o.id==="set-stepper-y") { wmGCommands.StepEnable.GParams = "Y"; }
+ else if(o.id==="set-stepper-z") { wmGCommands.StepEnable.GParams = "Z"; }
+ else if(o.id==="set-stepper-e") { wmGCommands.StepEnable.GParams = "E"; }
+ if(o.checked) { wmWebSoket.Send(wmGCommands.StepEnable); } else { wmWebSoket.Send(wmGCommands.StepDisable); }
+ }
+ },
+};
+
+var WmChartsData = {
+ Temperatures: {
+ TimeFormat: 'HH:mm:ss',
+ Speed: 1000,
+ Scale: 1,
+ Extruder: {
+ Label: "Extruder",
+ BorderColor: wmColors.RedCoral,
+ BgColor: wmColors.RedCoral,
+ Data:[]
+ },
+ Bed: {
+ Label: "Bed",
+ BorderColor: wmColors.Blue,
+ BgColor: wmColors.Blue,
+ Data:[]
+ },
+ AddEmpty: function(arr, n) {
+ for(var i = 0; i < n; i++) {
+ let xd = moment().subtract((n - i) * WmChartsData.Temperatures.Speed, 'milliseconds').toDate();
+ arr.push({ x: xd, y: null });
+ }
+ },
+ DataUpdate(di) {
+ let dt = new Date();
+ WmChartsData.Temperatures.Extruder.Data.push({ x: dt, y: di.ExtruderTemp });
+ WmChartsData.Temperatures.Extruder.Data.shift();
+ if(di.BedTemp !== null) {
+ WmChartsData.Temperatures.Bed.Data.push({ x: dt, y: di.BedTemp });
+ WmChartsData.Temperatures.Bed.Data.shift();
+ }
+ requestAnimationFrame(WmCharts.Advance);
+ }
+ },
+ FanSpeed: {
+ Values: {
+ Label: ["Fan speed",""],
+ BgColor: [wmColors.GreenSuc, wmColors.Grey],
+ Data: [0,100]
+ },
+ DataUpdate(di) {
+ WmChartsData.FanSpeed.Values.Data[0] = di;
+ WmChartsData.FanSpeed.Values.Data[1] = 100 - di;
+ if(di < 30) { WmChartsData.FanSpeed.Values.BgColor[0] = wmColors.GreenSuc; }
+ else if(di < 60) { WmChartsData.FanSpeed.Values.BgColor[0] = wmColors.Yellow; }
+ else if(di < 80) { WmChartsData.FanSpeed.Values.BgColor[0] = wmColors.Orange; }
+ else { WmChartsData.FanSpeed.Values.BgColor[0] = wmColors.Red; }
+ requestAnimationFrame(function() { WmCharts.FanSpeed.CanvasItem.update()});
+ }
+ }
+};
+
+var WmCharts = {
+ Temperatures: {
+ CanvasItem: null,
+ Config: {
+ type: 'line',
+ data: {
+ datasets: [{
+ label: WmChartsData.Temperatures.Extruder.Label,
+ data: WmChartsData.Temperatures.Extruder.Data,
+ backgroundColor: WmChartsData.Temperatures.Extruder.BgColor,
+ borderColor: WmChartsData.Temperatures.Extruder.BorderColor,
+ borderWidth: 2,
+ fill: false,
+ pointRadius: 1.5
+ },{
+ label: WmChartsData.Temperatures.Bed.Label,
+ data: WmChartsData.Temperatures.Bed.Data,
+ backgroundColor: WmChartsData.Temperatures.Bed.BgColor,
+ borderColor: WmChartsData.Temperatures.Bed.BorderColor,
+ borderWidth: 2,
+ fill: false,
+ pointRadius: 1.5
+ }]
+ },
+ options: {
+ responsive: true,
+ animation: { duration: WmChartsData.Temperatures.Speed * 1.5, easing:'linear' },
+ scales: {
+ xAxes: [{ type:'time', time:{ displayFormats: { second: 'HH:mm:ss'} }, scaleLabel: { display: false } }],
+ yAxes: [{ ticks: { min: 0} }]
+ }
+ }
+ },
+ DisplayAxis: function(ck) {
+ if(ck.id==="chart-show-extruder") {
+ WmCharts.Temperatures.CanvasItem.getDatasetMeta(0).hidden = ck.checked===true ? false : true;
+ $('#chart-show-extruder-label').text(ck.checked===true ? "Show" : "Hide");
+ }
+ else if(ck.id==="chart-show-bed") {
+ WmCharts.Temperatures.CanvasItem.getDatasetMeta(1).hidden = ck.checked===true ? false : true;
+ $('#chart-show-bed-label').text(ck.checked===true ? "Show" : "Hide");
+ }
+ if(!$('#set-auto-temp').prop('checked')){ WmCharts.Temperatures.CanvasItem.update(); }
+ }
+ },
+ FanSpeed: {
+ CanvasItem: null,
+ Config: {
+ type: 'doughnut',
+ data: {
+ datasets: [{
+ data: WmChartsData.FanSpeed.Values.Data,
+ backgroundColor: WmChartsData.FanSpeed.Values.BgColor,
+ }],
+ labels: WmChartsData.FanSpeed.Values.Label
+ },
+ options: {
+ responsive: true,
+ circumference: Math.PI,
+ rotation: -Math.PI,
+ legend: { display: false },
+ tooltips: { enabled: false },
+ title: { display: false },
+ animation: {
+ animateScale: true,
+ animateRotate: true,
+ onComplete: function () {
+ var ctx = this.chart.ctx;
+ ctx.font = "14pt Verdana";
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'bottom';
+ ctx.fillStyle = wmColors.Black;
+ let ds = this.data.datasets;
+ let model = ds[0]._meta[Object.keys(ds[0]._meta)[0]].data[0]._model;
+ let xp = wmTools.FormatNumber(model.x,0), yp = wmTools.FormatNumber(model.y,0);
+ jsLog.Debug("Drawing speed gauge percentage label position (x,y): "+xp+","+yp);
+ ctx.fillText(WmChartsData.FanSpeed.Values.Data[0]+'%', xp, yp);
+ }
+ }
+ }
+ }
+ },
+ Init: function() {
+ WmChartsData.Temperatures.AddEmpty(WmChartsData.Temperatures.Extruder.Data, 20);
+ WmChartsData.Temperatures.AddEmpty(WmChartsData.Temperatures.Bed.Data, 20);
+ WmCharts.Temperatures.CanvasItem = new Chart(document.getElementById('chart-temps'), WmCharts.Temperatures.Config);
+ WmCharts.FanSpeed.CanvasItem = new Chart(document.getElementById('chart-fanspeed'), WmCharts.FanSpeed.Config);
+ },
+ Advance: function() {
+ if (WmChartsData.Temperatures.Extruder.Data[0] !== null && WmChartsData.Temperatures.Extruder.Scale < 4) { WmCharts.Temperatures.CanvasItem.update(); }
+ WmCharts.Temperatures.CanvasItem.update();
+ },
+ SetTempReport: function(tr) {
+ let temps = {
+ ExtruderTemp: tr[0].replace(/T:/,""),
+ ExtruderSet: tr[1],
+ BedTemp: tr[2]==="undefined" ? null : tr[2].replace(/B:/,""),
+ BedSet: tr[3]==="undefined" ? null : tr[3]
+ };
+ WmChartsData.Temperatures.DataUpdate(temps);
+ WmControls.UpdateTemperatures(temps);
+ }
+};
+
+var WmConsole = {
+ Clear: function() {
+ jsLog.Debug("Clearing console message list...");
+ $('#gcommand-console-list').empty();
+ wmLogBuffer.length = 0;
+ WmConsole.Trace(new wmLogItem("Console list cleared by user", wmEnums.WSMsgDirection.RECEIVED, wmEnums.ConsoleLevels.SUCCESS));
+ },
+ Export: function() {
+ jsLog.Debug("Exporting console message list...");
+ var fdt = new Array();
+ // DA FINIRE LA PRIMA RIGA NOMI CAMPI
+ for(i=0; i-1) { wmSdListCounter.FOLDERS++; }
+ }
+ $('#list-sd-content').append(litem.ToSdFileList());
+ $('#div-sdlist-file-count').text(wmSdListCounter.FILES);
+ $('#div-sdlist-folder-count').text(wmSdListCounter.FOLDERS);
+ if(litem.SdFile === "End file list") { WmControls.Enable(WmButtonGroups.FileManagement); }
+ }
+};
+
+var WmAutostart = {
+ SetDefaultPanel: function() {
+ jsLog.Verbose("Set default shown panel ("+wmSettings.DefaultPanel+")");
+ if (wmSettings.DefaultPanel == wmEnums.Panels.STATUS) { $('#accordion-panel-status-body').addClass("show"); }
+ else if (wmSettings.DefaultPanel === wmEnums.Panels.CONTROLS) { $('#accordion-panel-controls-body').addClass("show"); }
+ else if (wmSettings.DefaultPanel === wmEnums.Panels.TEMP) { $('#accordion-panel-temp-body').addClass("show"); }
+ else if (wmSettings.DefaultPanel === wmEnums.Panels.FILES) { $('#accordion-panel-file-body').addClass("show"); }
+ else if (wmSettings.DefaultPanel === wmEnums.Panels.CONSOLE) { $('#accordion-panel-console-body').addClass("show"); }
+ },
+ SetShownPanel: function(p) {
+ jsLog.Verbose("Set shown panel ("+p+")");
+ if (p === wmEnums.Panels.STATUS) { $('#accordion-panel-status-body').removeClass("hide").addClass("show"); } else { $('#accordion-panel-status-body').removeClass("show").addClass("hide"); }
+ if (p === wmEnums.Panels.CONTROLS) { $('#accordion-panel-controls-body').removeClass("hide").addClass("show"); } else { $('#accordion-panel-controls-body').removeClass("show").addClass("hide"); }
+ if (p === wmEnums.Panels.TEMP) { $('#accordion-panel-temp-body').removeClass("hide").addClass("show"); } else { $('#accordion-panel-temp-body').removeClass("show").addClass("hide"); }
+ if (p === wmEnums.Panels.FILES) { $('#accordion-panel-file-body').removeClass("hide").addClass("show"); } else { $('#accordion-panel-file-body').removeClass("show").addClass("hide"); }
+ if (p === wmEnums.Panels.CONSOLE) { $('#accordion-panel-console-body').removeClass("hide").addClass("show"); } else { $('#accordion-panel-console-body').removeClass("show").addClass("hide"); }
+ },
+ SetGCommandChecksum: function() {
+ cs = wmGCommandItem.CalcChecksum($('#text-gcommand').val());
+ $('#checksum-gcommand-value').text(cs);
+ jsLog.Debug("Set GCommand checksum ("+cs+")");
+ },
+ SetGCommandPresetList: function() {
+ jsLog.Verbose("Fill GCommand preset list");
+ let lip = document.getElementById("list-presets").getElementsByTagName("li");
+ let i=0;
+ if(lip.length === 1) {
+ Object.keys(wmGCommands).forEach(key => {
+ if(wmGCommands[key].GCode != "" && wmGCommands[key].Supported) {
+ let gp = wmGCommands[key].GParams !== null ? wmTools.StringFormat(wmGCommands[key].GParams,wmGCommands[key].Values) : '';
+ var lib = "";
+ $('#list-presets').append(lib);
+ i++;
+ }
+ });
+ }
+ jsLog.Verbose("Fill GCommand preset list completed ("+i+" items)");
+ },
+ SetWmSettingsControls: function() {
+ jsLog.Verbose("Set settings controls fields");
+ $('#set-default-panel').val(wmSettings.DefaultPanel);
+ $('#set-auto-connect').bootstrapToggle(wmSettings.AutoConnect==true ? "on" : "off");
+ $('#set-default-autotemp').val(wmSettings.AutoTempInterval);
+ $('#set-default-tempunit').val(wmSettings.TempUnit.VALUE);
+ $('#set-log-level').val(wmSettings.LogLevel);
+ if(wmSettings.ConsoleDirection===wmEnums.ConsoleDirection.APPEND) {
+ $('#set-trace-mode-prepend').prop('checked',false);
+ $('#set-trace-mode-append').prop('checked',true);
+ } else {
+ $('#set-trace-mode-append').prop('checked',false);
+ $('#set-trace-mode-prepend').prop('checked',true);
+ }
+ $('#set-log-symbol').val(wmSettings.SymbolMode);
+ if(wmSettings.SymbolMode==='letter') { $('#div-log-symbol-icon').collapse('hide'); }
+ else { $('#div-log-symbol-icon').collapse('show'); SetConsoleSymbolIcon(); }
+ },
+ SetAutotempDefault: function() {
+ $('#auto-temp-interval').val(wmSettings.AutoTempInterval);
+ }
+};
+
+$(document).ready(function () {
+ $('.accordion-always-open').on('show.bs.collapse', function () { $(this).data('isShowing', true); });
+ $('.accordion-always-open').on('hide.bs.collapse', function (event) {
+ if (!$(this).data('isShowing')) { event.preventDefault(); }
+ $(this).data('isShowing', false);
+ });
+ jsLog.Debug("Browser in use: "+wmTools.GetBrowser());
+ jsLog.Debug("Browser sizes: "+wmTools.GetScreenSize());
+
+ // AutoStar Actions
+ WmAutostart.SetWmSettingsControls();
+ WmAutostart.SetDefaultPanel();
+ WmAutostart.SetGCommandPresetList();
+ WmAutostart.SetAutotempDefault();
+
+ // EVENTS: Buttons
+ $('#btn-clear-console').click(function() { WmButtons.ConsoleListClear(); });
+ $('#btn-export-console').click(function() { WmButtons.ConsoleListExport(); });
+ $('#btn-file-proc').click(function(){ WmUpload.FileProcess(); });
+ $('#btn-file-proc-cancel').click(function() { WmUpload.Cancel(); });
+ $('#btn-file-upload').click(function(){ WmButtons.UploadSdFile(); });
+ $('#btn-gcommand').click(function() { WmButtons.SendGcommand(); });
+ $('#btn-get-sdcontent').click(function() { WmButtons.GetSdContentList(); });
+ $('#btn-move-home-all').click(function() { WmButtons.SetPositionHome(this); });
+ $('#btn-move-home-x').click(function() { WmButtons.SetPositionHome(this); });
+ $('#btn-move-home-y').click(function() { WmButtons.SetPositionHome(this); });
+ $('#btn-move-home-z').click(function() { WmButtons.SetPositionHome(this); });
+ $('#btn-save-settings').click(function() { WmButtons.SaveSettings(); });
+ $('#btn-sdfile-delete-modal').click(function() { WmButtons.DeleteSdSelected(); });
+ $('#btn-sdfile-print-modal').click(function() { WmButtons.PrintSdSelected(); });
+ $('#btn-set-sdinit').click(function() { WmButtons.SdInit(); });
+ $('#btn-set-sdrelease').click(function() { WmButtons.SdRelease(); });
+ $('#btn-wsconnect').click(function() { WmButtons.WsConnect(); });
+ $('#btn-wsconnect-modal').click(function() { WmButtons.WsConnect(); });
+
+ // EVENTS: Inputs fields
+ $('#text-gcommand').keyup(function() { WmAutostart.SetGCommandChecksum(); });
+ $('#text-gcommand').change(function() { WmAutostart.SetGCommandChecksum(); });
+ $('#set-log-symbol').change(function() { WmConsole.SetMessageSymbol(); });
+ $('#set-log-symbol-icon').change(function() { WmConsole.SetSymbolIcon(); });
+ $('#file-upload').change( function() { WmControls.SetUpload(); });
+ $('#set-auto-temp').change( function() { WmControls.SetAutoTemp(); });
+ $('#auto-temp-interval').change( function() { WmControls.SetAutoTemp();} );
+ $('#chart-show-extruder').change( function() { WmCharts.Temperatures.DisplayAxis(this); });
+ $('#chart-show-bed').change( function() { WmCharts.Temperatures.DisplayAxis(this); });
+ $('#fan-speed-range').on("change", function() { WmControls.SetFanSpeed(this.value); });
+ $('#set-stepper-all').change( function() { WmControls.SetSteppers(this); });
+ $('#set-stepper-e').change( function() { WmControls.SetSteppers(this); });
+ $('#set-stepper-x').change( function() { WmControls.SetSteppers(this); });
+ $('#set-stepper-y').change( function() { WmControls.SetSteppers(this); });
+ $('#set-stepper-z').change( function() { WmControls.SetSteppers(this); });
+
+ // Autorun onload
+ WmConsole.Trace(new wmLogItem("Ready", wmEnums.WSMsgDirection.SENT, wmEnums.ConsoleLevels.SUCCESS));
+ if(wmSettings.AutoConnect===true) { wmWebSoket.Connect(); }
+ window.onload = function() {
+ WmCharts.Init();
+ WmCharts.Advance();
+ };
+
+ WmControls.Enable(WmButtonGroups.All());
+});
diff --git a/platformio.ini b/platformio.ini
index 1b3957fc94..d5bd96709a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -284,6 +284,7 @@ EMERGENCY_PARSER = src_filter=+ -
IIC_BL24CXX_EEPROM = src_filter=+
HAS_SPI_FLASH = src_filter=+
+HAS_ETHERNET = src_filter=+
HAS_FANMUX = src_filter=+
FILAMENT_WIDTH_SENSOR = src_filter=+ +
FWRETRACT = src_filter=+ +
@@ -1336,6 +1337,7 @@ platform = espressif32@1.11.2
board = esp32dev
build_flags = ${common.build_flags} -DCORE_DEBUG_LEVEL=0
src_filter = ${common.default_src_filter} +
+lib_ignore = NativeEthernet
upload_speed = 115200
#upload_port = marlinesp.local
#board_build.flash_mode = qio
@@ -1347,6 +1349,7 @@ upload_speed = 115200
platform = teensy
board = teensy31
src_filter = ${common.default_src_filter} +
+lib_ignore = NativeEthernet
#
# Teensy 3.5 / 3.6 (ARM Cortex-M4)
@@ -1355,11 +1358,13 @@ src_filter = ${common.default_src_filter} +
platform = teensy
board = teensy35
src_filter = ${common.default_src_filter} +
+lib_ignore = NativeEthernet
[env:teensy36]
platform = teensy
board = teensy36
src_filter = ${common.default_src_filter} +
+lib_ignore = NativeEthernet
#
# Teensy 4.0 / 4.1 (ARM Cortex-M7)