Fresh Web GUI (based on bootstrap.js) (#19812)
This commit is contained in:
		
							
								
								
									
										6
									
								
								data/www/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								data/www/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										6
									
								
								data/www/bootstrap.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								data/www/bootstrap.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10
									
								
								data/www/bootstrap4-toggle.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								data/www/bootstrap4-toggle.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /*\ | ||||
| |*| ======================================================================== | ||||
| |*| Bootstrap Toggle: bootstrap4-toggle.js v3.6.1 | ||||
| |*| https://gitbrent.github.io/bootstrap4-toggle/ | ||||
| |*| ======================================================================== | ||||
| |*| Copyright 2018-2019 Brent Ely | ||||
| |*| Licensed under MIT | ||||
| |*| ======================================================================== | ||||
| \*/ | ||||
| !function(a){"use strict";function l(t,e){this.$element=a(t),this.options=a.extend({},this.defaults(),e),this.render()}l.VERSION="3.6.0",l.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},l.prototype.defaults=function(){return{on:this.$element.attr("data-on")||l.DEFAULTS.on,off:this.$element.attr("data-off")||l.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||l.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||l.DEFAULTS.offstyle,size:this.$element.attr("data-size")||l.DEFAULTS.size,style:this.$element.attr("data-style")||l.DEFAULTS.style,width:this.$element.attr("data-width")||l.DEFAULTS.width,height:this.$element.attr("data-height")||l.DEFAULTS.height}},l.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var t="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",e=a('<label for="'+this.$element.prop("id")+'" class="btn">').html(this.options.on).addClass(this._onstyle+" "+t),s=a('<label for="'+this.$element.prop("id")+'" class="btn">').html(this.options.off).addClass(this._offstyle+" "+t),o=a('<span class="toggle-handle btn btn-light">').addClass(t),i=a('<div class="toggle-group">').append(e,s,o),l=a('<div class="toggle btn" data-toggle="toggle" role="button">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(t).addClass(this.options.style);this.$element.wrap(l),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:e,$toggleOff:s,$toggleGroup:i}),this.$toggle.append(i);var n=this.options.width||Math.max(e.outerWidth(),s.outerWidth())+o.outerWidth()/2,h=this.options.height||Math.max(e.outerHeight(),s.outerHeight());e.addClass("toggle-on"),s.addClass("toggle-off"),this.$toggle.css({width:n,height:h}),this.options.height&&(e.css("line-height",e.height()+"px"),s.css("line-height",s.height()+"px")),this.update(!0),this.trigger(!0)},l.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},l.prototype.on=function(t){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),t||this.trigger()},l.prototype.off=function(t){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),t||this.trigger()},l.prototype.enable=function(){this.$toggle.removeClass("disabled"),this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},l.prototype.disable=function(){this.$toggle.addClass("disabled"),this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},l.prototype.update=function(t){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(t):this.off(t)},l.prototype.trigger=function(t){this.$element.off("change.bs.toggle"),t||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},l.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var t=a.fn.bootstrapToggle;a.fn.bootstrapToggle=function(o){var i=Array.prototype.slice.call(arguments,1)[0];return this.each(function(){var t=a(this),e=t.data("bs.toggle"),s="object"==typeof o&&o;e||t.data("bs.toggle",e=new l(this,s)),"string"==typeof o&&e[o]&&"boolean"==typeof i?e[o](i):"string"==typeof o&&e[o]&&e[o]()})},a.fn.bootstrapToggle.Constructor=l,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=t,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(t){a(this).find("input[type=checkbox]").bootstrapToggle("toggle"),t.preventDefault()})}(jQuery); | ||||
							
								
								
									
										234
									
								
								data/www/chart.lineargauge.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								data/www/chart.lineargauge.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,234 @@ | ||||
| (function(Chart) { | ||||
| 	var helpers = Chart.helpers; | ||||
| 	var plugins = Chart.plugins; | ||||
| 	Chart.defaults.global.animation.duration = 1000; | ||||
|  | ||||
| 	Chart.defaults._set('linearGauge', { | ||||
| 		scale: { | ||||
| 			type: 'linearGauge', | ||||
| 			horizontal: false, | ||||
| 			range: { | ||||
| 				startValue: -100, | ||||
| 				endValue: 500 | ||||
| 			}, | ||||
| 			responsive: true, | ||||
| 			font: { | ||||
| 				fontName: 'Arial', | ||||
| 				fontSize: 12 | ||||
| 			}, | ||||
| 			axisWidth: 6, | ||||
| 			ticks: { | ||||
| 				majorTicks: { | ||||
| 					interval: 100, | ||||
| 					height: 1, | ||||
| 				} | ||||
| 			}, | ||||
| 			scaleLabel: { | ||||
| 				display: true, | ||||
| 				interval: 100, | ||||
| 				units: '', | ||||
| 				customValues: [], | ||||
| 				offset: -10, | ||||
| 				color: '#777b80' | ||||
| 			} | ||||
| 		}, | ||||
| 		padding: { | ||||
| 			top: 0, | ||||
| 			bottom: 0, | ||||
| 			left: 0, | ||||
| 			right: 0 | ||||
| 		}, | ||||
| 		tooltips: { | ||||
| 			callbacks: { | ||||
| 				label: function(tooltipItem, data) { | ||||
| 					var label = data.datasets[tooltipItem.datasetIndex].label || ''; | ||||
|  | ||||
| 					if (label) { | ||||
| 						label += ': '; | ||||
| 					} | ||||
| 					label += Math.round(data.datasets[tooltipItem.datasetIndex].data[0] * 100) / 100; | ||||
| 					return label; | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		legend: { | ||||
| 			display: true, | ||||
| 			labels: { | ||||
| 				fontColor: 'rgb(0, 0, 0)' | ||||
| 			}, | ||||
| 			position: 'bottom' | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	Chart.controllers.linearGauge = Chart.DatasetController.extend({ | ||||
|  | ||||
| 		dataElementType: Chart.elements.Gaugerect, | ||||
|  | ||||
| 		initialize: function() { | ||||
| 			var me = this; | ||||
| 			var meta; | ||||
|  | ||||
| 			Chart.DatasetController.prototype.initialize.apply(me, arguments); | ||||
|  | ||||
| 			meta = me.getMeta(); | ||||
|  | ||||
| 		}, | ||||
|  | ||||
| 		linkScales: helpers.noop, | ||||
|  | ||||
| 		update: function(reset) { | ||||
| 			var me = this; | ||||
| 			var rects = me.getMeta().data; | ||||
| 			var i, ilen; | ||||
| 			me.datashifts = 0; | ||||
|  | ||||
| 			for (i = 0, ilen = rects.length; i < ilen; ++i) { | ||||
| 				me.updateElement(rects[i], i, me.datashifts); | ||||
| 				me.datashifts += 10; | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		updateElement: function(rectangle, index, reset) { | ||||
| 			var me = this; | ||||
| 			var chart = me.chart; | ||||
| 			var meta = me.getMeta(); | ||||
| 			var dataset = me.getDataset(); | ||||
|  | ||||
| 			var custom = rectangle.custom || {}; | ||||
| 			var rectangleOptions = chart.options.elements.rectangle; | ||||
| 			var gaugeOptions = chart.options.elements.gaugerect; | ||||
| 			rectangle._Scale = me.getScaleForId(chart.options.scale.id || 'gaugescale'); | ||||
| 			rectangle._datasetIndex = me.index; | ||||
| 			rectangle._index = index; | ||||
| 			rectangle.rangeColorImage = null; | ||||
|  | ||||
| 			//	Init element model | ||||
| 			rectangle._model = { | ||||
| 				datasetLabel: dataset.label, | ||||
| 				label: chart.data.labels[index], | ||||
| 				borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped, | ||||
| 				backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, gaugeOptions.backgroundColor), | ||||
| 				borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor), | ||||
| 				borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth) | ||||
| 			}; | ||||
|  | ||||
| 			//	Set empty view as start point for animation | ||||
| 			if(typeof rectangle._view === 'undefined') rectangle._view = {}; | ||||
|  | ||||
| 			me.updateElementGeometry(rectangle, index, reset); | ||||
|  | ||||
| 		}, | ||||
|  | ||||
| 		updateElementGeometry: function(rectangle, index, reset) { | ||||
| 			var me = this; | ||||
| 			var model = rectangle._model; | ||||
| 			var start = rectangle._view; | ||||
| 			var dataset = me.getDataset().data; | ||||
| 			var dopt = me.getDataset(); | ||||
| 			var chart = me.chart; | ||||
| 			var datasets = chart.data.datasets; | ||||
| 			var gaugeOptions = chart.options.elements.gaugerect; | ||||
| 			var vscale = me.getScaleForId(chart.options.scale.id || 'gaugescale'); | ||||
| 			//var base = vscale.getBasePixel(); | ||||
| 			var base = vscale.getBase(); | ||||
| 			var horizontal = rectangle._Scale.isHorizontal(); | ||||
| 			//var ruler = me._ruler || me.getRuler(); | ||||
| 			var vpixels = me.calculateBarValuePixels(me.index, index, horizontal); | ||||
|  | ||||
| 			model.horizontal = horizontal; | ||||
| 			model.base = base; | ||||
| 			model.head = vpixels.head; | ||||
| 			model.x = horizontal ? vpixels.base : vpixels.offset; | ||||
| 			model.y = horizontal ? (vpixels.offset - (dopt.width || gaugeOptions.width)) : vpixels.head; | ||||
| 			model.height = horizontal ? (dopt.width || gaugeOptions.width) : (vpixels.base - vpixels.head); | ||||
| 			model.width = horizontal ? (vpixels.head - vpixels.base) : (dopt.width || gaugeOptions.width); | ||||
| 			model.value = vscale.getRightValue(datasets[me.index].data[index]); | ||||
|  | ||||
| 			model.scaleValue = 0; | ||||
| 			if (horizontal) { | ||||
| 				model.scaleValue = vscale.width / (vscale.options.range.endValue - vscale.options.range.startValue); | ||||
| 			} else { | ||||
| 				model.scaleValue = vscale.height / (vscale.options.range.endValue - vscale.options.range.startValue); | ||||
| 			} | ||||
|  | ||||
| 			if(typeof start.x === 'undefined' && typeof start.y === 'undefined'){ | ||||
| 				if(horizontal){ | ||||
| 					start.x = vpixels.base; | ||||
| 					start.width = 0; | ||||
| 				} else { | ||||
| 					start.y = vpixels.base; | ||||
| 					start.height = 0; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 		}, | ||||
|  | ||||
| 		calculateBarValuePixels: function(datasetIndex, index, horizontal) { | ||||
| 			var me = this; | ||||
| 			var chart = me.chart; | ||||
| 			var scale = me.getScaleForId(chart.options.scale.id || 'gaugescale'); | ||||
| 			var datasets = chart.data.datasets; | ||||
| 			var dopt = datasets[datasetIndex]; | ||||
| 			var value = scale.getRightValue(datasets[datasetIndex].data[index]); | ||||
| 			var stacked = scale.options.stacked; | ||||
| 			var start = 0; | ||||
| 			var i, imeta, ivalue, base, head, size, offset; | ||||
|  | ||||
| 			base = scale.scalePoint(start); | ||||
| 			head = scale.scalePoint(start + value); | ||||
| 			size = (head - base) / 2; | ||||
| 			offset = horizontal ? scale.yCenter - dopt.offset : scale.xCenter + dopt.offset; | ||||
|  | ||||
| 			return { | ||||
| 				size: size, | ||||
| 				base: base, | ||||
| 				head: head, | ||||
| 				center: head + size / 2, | ||||
| 				offset: offset | ||||
| 			}; | ||||
| 		}, | ||||
|  | ||||
| 		draw: function() { | ||||
| 			var me = this; | ||||
| 			var chart = me.chart; | ||||
| 			var rects = me.getMeta().data; | ||||
| 			var dataset = me.getDataset(); | ||||
| 			var ilen = rects.length; | ||||
| 			var i = 0; | ||||
|  | ||||
| 			helpers.canvas.clipArea(chart.ctx, chart.chartArea); | ||||
|  | ||||
| 			for (; i < ilen; ++i) { | ||||
| 				if (!isNaN(dataset.data[i])) { | ||||
| 					rects[i].draw(); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			helpers.canvas.unclipArea(chart.ctx); | ||||
| 		}, | ||||
|  | ||||
| 		setHoverStyle: function(rectangle) { | ||||
| 			var dataset = this.chart.data.datasets[rectangle._datasetIndex]; | ||||
| 			var index = rectangle._index; | ||||
| 			var custom = rectangle.custom || {}; | ||||
| 			var model = rectangle._model; | ||||
|  | ||||
| 			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); | ||||
| 			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); | ||||
| 			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); | ||||
| 		}, | ||||
|  | ||||
| 		removeHoverStyle: function(rectangle) { | ||||
| 			var dataset = this.chart.data.datasets[rectangle._datasetIndex]; | ||||
| 			var index = rectangle._index; | ||||
| 			var custom = rectangle.custom || {}; | ||||
| 			var model = rectangle._model; | ||||
| 			var rectangleElementOptions = this.chart.options.elements.gaugerect; | ||||
|  | ||||
| 			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); | ||||
| 			model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); | ||||
| 			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); | ||||
| 		} | ||||
|  | ||||
| 	}); | ||||
| }).call(this, Chart); | ||||
							
								
								
									
										7
									
								
								data/www/chart.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								data/www/chart.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								data/www/filesaver.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								data/www/filesaver.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| (function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)}); | ||||
							
								
								
									
										22
									
								
								data/www/index-ie.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								data/www/index-ie.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <!doctype html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta name="Title" content="Marlin WebUI" /> | ||||
|     <meta name="Description" content="Marlin WebUI based on E4d@box WebUI" /> | ||||
|     <meta name="Generator" content="E4d@box" /> | ||||
|     <meta name="Owner" content="E4d@box" /> | ||||
|     <meta name="Author" content="MandrakeDesign" /> | ||||
|     <meta name="google" content="notranslate" /> | ||||
|     <meta http-equiv="Content-Language" content="en_GB" /> | ||||
|     <title>Marlin WebUI</title> | ||||
|     <link rel="shortcut icon" href="#" /> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div style="padding-top:100px; text-align:center"> | ||||
|       <h1>Sorry, but MS Internet Explorer browser is not supported by this web application.<br>Please upgrade to Edge or use another browser</h1> | ||||
|       <br><br><br> | ||||
|       <h1>Marlin WebUI</h1> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @@ -1,37 +1,749 @@ | ||||
| <!doctype html> | ||||
| <html lang=en> | ||||
| <!doctype html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|   <meta charset=utf-8> | ||||
|   <title>Marlin</title> | ||||
|  | ||||
|   <link rel="stylesheet" type="text/css" href="marlin.css" /> | ||||
|  | ||||
|   <script type="text/javascript" src="marlin.js"></script> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimal-ui,shrink-to-fit=no" /> | ||||
|   <meta name="Title" content="Marlin WebUI" /> | ||||
|   <meta name="Description" content="Marlin WebUI based on E4d@box WebUI" /> | ||||
|   <meta name="Generator" content="E4d@box" /> | ||||
|   <meta name="Owner" content="E4d@box" /> | ||||
|   <meta name="Author" content="MandrakeDesign" /> | ||||
|   <meta name="google" content="notranslate" /> | ||||
|   <meta http-equiv="Content-Language" content="en_GB" /> | ||||
|   <title>Marlin WebUI</title> | ||||
|   <link rel="shortcut icon" href="#" /> | ||||
|   <link rel="stylesheet" type="text/css" href="bootstrap.min.css" /> | ||||
|   <link rel="stylesheet" type="text/css" href="webmarlin-font.css"> | ||||
|   <link rel="stylesheet" type="text/css" href="webmarlin.css" /> | ||||
|   <script> | ||||
|     var ua = window.navigator.userAgent; | ||||
|     var msie = ua.indexOf("MSIE "); | ||||
|     if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)){ top.location.replace('index-ie.html'); } | ||||
|     function hideAddressBar() { if(!window.location.hash) { if(document.height < window.outerHeight) { document.body.style.height = (window.outerHeight + 50) + 'px'; } | ||||
|         setTimeout( function(){ window.scrollTo(0, 1); }, 50 ); | ||||
|     }} | ||||
|     window.addEventListener("load", function(){ if(!window.pageYOffset){ hideAddressBar(); } } ); | ||||
|     window.addEventListener("orientationchange", hideAddressBar ); | ||||
|   </script> | ||||
|   <script src="moment.min.js"></script> | ||||
|   <script src="webmarlin-class.js"></script> | ||||
| </head> | ||||
| <body> | ||||
|   <div class="tabs"> | ||||
|     <div id="logo"></div> | ||||
|     <input class="input" name="tabs" type="radio" id="tab-1" checked="checked"/> | ||||
|     <label class="label" for="tab-1">console</label> | ||||
|     <div class="panel"> | ||||
|       <div class="panel-content"> | ||||
|         <ul id="serial-output"></ul> | ||||
|   <!-- Javascript sources ========================================================================================== --> | ||||
|   <script type="text/javascript" src="jquery-3.5.1.slim.min.js"></script> | ||||
|   <script type="text/javascript" src="jquery.browser.min.js"></script> | ||||
|   <script type="text/javascript" src="bootstrap.min.js"></script> | ||||
|   <script type="text/javascript" src="bootstrap4-toggle.min.js"></script> | ||||
|   <script async="" src="filesaver.min.js"></script> | ||||
|   <script type="text/javascript" src="chart.min.js"></script> | ||||
|   <script type="text/javascript" src="webmarlin.js"></script> | ||||
|  | ||||
|         <form id="serial-command-form" autocomplete="off"> | ||||
|           <div class="form-wrapper"> | ||||
|             <input type="text" id="serial-command"> | ||||
|             <input type="submit" value="Send"> | ||||
|   <!-- Accordion =================================================================================================== --> | ||||
|   <div id="main-panel" class="h-100 bg-secondary m-0 p-0"> | ||||
|     <div class="container-fluid h-100 p-0"> | ||||
|       <div class="accordion accordion-always-open h-100 d-flex flex-column bg-light" id="accordion-panels"> | ||||
|  | ||||
|         <!-- PANEL: Fixed Title ==================================================================================== --> | ||||
|         <div class="bg-dark text-light text-left p-2"> | ||||
|           <span class="h4">Marlin WebUI </span> by atbox.tech | ||||
|           <button type="button" class="btn btn-sm btn-success float-right ml-1" data-toggle="modal" data-target="#modal-info" style="width:35px; height:33px"><i class="icon icon-info"></i></button> | ||||
|           <a href="http://marlinfw.org/" target="_blank" class="float-right"><img src="marlin-logo-dark.png" alt="MarlinLogo" width="100" height="33" /></a> | ||||
|         </div> | ||||
|  | ||||
|         <!-- PANEL: Fixed connection status bar ==================================================================== --> | ||||
|         <div id="div-conn-statusbar" class="bg-danger text-light text-left p-1"> | ||||
|           <div class="float-left font-italic h5 my-0 pl-1"> | ||||
|             <span id="div-conn-statusico" class="badge badge-light mr-2" style="width:30px;"><i class="icon icon-plug"></i></span><span id="div-conn-statusmsg">Disconnected</span> | ||||
|           </div> | ||||
|         </form> | ||||
|       </div> | ||||
|     </div> | ||||
|     <input class="input" name="tabs" type="radio" id="tab-2"/> | ||||
|     <label class="label" for="tab-2">controls</label> | ||||
|     <div class="panel"> | ||||
|       <div class="panel-content"> | ||||
|         #controls | ||||
|           <div class="btn-toolbar float-right mr-1" role="toolbar"> | ||||
|             <div class="btn-group mr-1" role="group"> | ||||
|               <button type="button" id="btn-wsconnect" class="btn btn-sm btn-dark" style="width:35px; height:30px"><span id="btn-connect-status"><i class="icon icon-bolt"></i></span></button> | ||||
|             </div> | ||||
|             <div class="btn-group" role="group"> | ||||
|               <button type="button" id="btn-settings" class="btn btn-sm btn-dark" style="width:35px; height:30px" data-toggle="modal" data-target="#modal-settings"><i class="icon icon-sliders"></i></button> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- PANEL: Printer status ================================================================================= --> | ||||
|         <div class="card-header flex-shrink-1 p-0 bg-dark text-light" id="accordion-panel-status-head"> | ||||
|           <button class="btn btn-sm btn-dark btn-block text-left" type="button" data-toggle="collapse" data-target="#accordion-panel-status-body" aria-expanded="true" aria-controls="accordion-panel-status-body"> | ||||
|             <span class="h5"><span class="badge badge-success" style="width:30px;"><i class="icon icon-info-circled"></i></span><span class="ml-2">Status</span></span> | ||||
|             <div class="badge badge-secondary float-right"><span class="h5 icon icon-chevron-down"></span></div> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div id="accordion-panel-status-body" class="collapse flex-grow-1 collapse-panel" aria-labelledby="accordion-panel-status-head" data-parent="#accordion-panels"> | ||||
|           <div class="card-body h-100 border-bottom p-1 text-left"> | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-info mr-1 ml-1"></i>Printer status</div> | ||||
|               <div class="card-body px-0 py-1 bg-light badge-description"> | ||||
|                 <div class="border-bottom pb-1"> | ||||
|                   Printing status <div id="div-pstatus-sdprint" class="badge badge-danger badge-description float-right pb-1">Idle</div> | ||||
|                 </div> | ||||
|                 <div id="div-pstatus-timer" class="border-bottom py-1 collapse"> | ||||
|                   Printing timer | ||||
|                   <div class="float-right ml-1">Remain: <span id="div-pstatus-timer-remain" class="badge badge-info badge-description pb-1">0:45:12</span></div> | ||||
|                   <div class="float-right ml-1">Estimated: <span id="div-pstatus-timer-estimated" class="badge badge-info badge-description pb-1">1:12:34</span></div> | ||||
|                   <div class="float-right">Elapsed: <span id="div-pstatus-timer-elapsed" class="badge badge-info badge-description pb-1">0:00:00</span></div> | ||||
|                 </div> | ||||
|                 <div id="div-pstatus-progress" class="pt-1 collapse"> | ||||
|                   Printing progress: | ||||
|                   <div id="div-pstatus-progress-percent" class="badge badge-info badge-description float-right pb-1">10%</div> | ||||
|                   <div id="div-pstatus-progress-bytes" class="badge badge-info badge-description float-right pb-1 mr-1">1 of 123456</div> | ||||
|                   <div class="progress mt-1" style="height: 10px;"><div class="progress-bar bg-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-thermometer mr-1 ml-1"></i>Temperatures</div> | ||||
|               <div class="card-body px-0 py-1 bg-light"> | ||||
|                 <div> | ||||
|                   Auto temperature detection | ||||
|                   <div class="float-right form-inline"> | ||||
|                     <select id="auto-temp-interval" class="form-control form-control-sm mr-1" style="width:80px;" disabled> | ||||
|                       <option value="1">1 sec</option> | ||||
|                       <option value="5">5 sec</option> | ||||
|                       <option value="10">10 sec</option> | ||||
|                       <option value="30">30 sec</option> | ||||
|                       <option value="60">60 sec</option> | ||||
|                     </select> | ||||
|                     <input type="checkbox" id="set-auto-temp" data-input-type="togglebtn" data-size="sm" data-width="80" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="ON" data-off="OFF" disabled> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <canvas id="chart-temps" height="150"></canvas> | ||||
|                 <table class="w-100" cellpadding="0" cellspacing="0"> | ||||
|                   <tr> | ||||
|                     <td width="40%"> | ||||
|                       <div class="card mr-1"> | ||||
|                         <div class="card-header py-0 px-1 bg-info text-light card-header-description">Sensor</div> | ||||
|                         <div class="card-body py-0 px-1 card-header-description"> | ||||
|                           <table class="w-100"> | ||||
|                             <tr><td class="border-bottom" style="height:28px;">Hotend (extruder) sensor</td></tr> | ||||
|                             <tr><td style="height:28px;">Bed sensor</td></tr> | ||||
|                           </table> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                     <td width="15%"> | ||||
|                       <div class="card mr-1"> | ||||
|                         <div class="card-header py-0 px-1 bg-info text-light card-header-description">Detected</div> | ||||
|                         <div class="card-body py-0 px-1 card-header-description text-right"> | ||||
|                           <table class="w-100"> | ||||
|                             <tr><td class="border-bottom" style="height:28px;"><div id="div-temp-extruder-detect">-</div></td></tr> | ||||
|                             <tr><td style="height:28px;"><div id="div-temp-bed-detect">-</div></td></tr> | ||||
|                           </table> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                     <td width="15%"> | ||||
|                       <div class="card mr-1"> | ||||
|                         <div class="card-header py-0 px-1 bg-info text-light card-header-description">Set</div> | ||||
|                         <div class="card-body py-0 px-1 card-header-description text-right"> | ||||
|                           <table class="w-100"> | ||||
|                             <tr><td class="border-bottom" style="height:28px;"><div id="div-temp-extruder-set">-</div></td></tr> | ||||
|                             <tr><td style="height:28px;"><div id="div-temp-bed-set">-</div></td></tr> | ||||
|                           </table> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                     <td width="15%"> | ||||
|                       <div class="card mr-1"> | ||||
|                         <div class="card-header py-0 px-1 bg-info text-light card-header-description">Unit</div> | ||||
|                         <div class="card-body py-0 px-1 card-header-description text-center"> | ||||
|                           <table class="w-100"> | ||||
|                             <tr><td class="border-bottom" style="height:28px;"><div id="div-temp-extruder-unit">-</div></td></tr> | ||||
|                             <tr><td style="height:28px;"><div id="div-temp-bed-unit">-</div></td></tr> | ||||
|                           </table> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                     <td width="20%"> | ||||
|                       <div class="card"> | ||||
|                         <div class="card-header py-0 px-1 bg-info text-light card-header-description">Chart display</div> | ||||
|                         <div class="card-body py-0 px-1 card-header-description text-center"> | ||||
|                           <table class="w-100"> | ||||
|                             <tr> | ||||
|                               <td class="border-bottom" style="height:28px;"> | ||||
|                                 <div class="custom-control custom-switch"> | ||||
|                                   <input type="checkbox" class="custom-control-input" id="chart-show-extruder" checked disabled> | ||||
|                                   <label id="chart-show-extruder-label" class="custom-control-label" for="chart-show-extruder">Show</label> | ||||
|                                 </div> | ||||
|                               </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                               <td style="height:28px;"> | ||||
|                                 <div class="custom-control custom-switch"> | ||||
|                                   <input type="checkbox" class="custom-control-input" id="chart-show-bed" checked disabled> | ||||
|                                   <label id="chart-show-bed-label" class="custom-control-label" for="chart-show-bed">Show</label> | ||||
|                                 </div> | ||||
|                               </td> | ||||
|                             </tr> | ||||
|                           </table> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                 </table> | ||||
|               </div> | ||||
|               <div class="card mb-1 border-0"> | ||||
|                 <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-refresh mr-1 ml-1"></i>Hotend fan speed</div> | ||||
|                 <div class="card-body px-0 py-1 bg-light"> | ||||
|                   <table width="100%" cellspacing="0" cellpadding="0" border="0"> | ||||
|                     <tr> | ||||
|                       <td width="70%" valign="top" class="pr-2"> | ||||
|                         <table class="w-100" cellspacing="0" cellpadding="0" border="0"> | ||||
|                           <tr style="height:20px;"> | ||||
|                             <td class="border-bottom card-header-description">Current fan speed</td> | ||||
|                             <td class="border-bottom card-header-description text-right"><div id="div-fan-speed-current">-</div></td> | ||||
|                           </tr> | ||||
|                           <tr style="height:20px;"> | ||||
|                             <td class="border-bottom card-header-description">Set fan speed</td> | ||||
|                             <td class="border-bottom card-header-description text-right"><div id="div-fan-speed-set">-</div></td> | ||||
|                           </tr> | ||||
|                           <tr> | ||||
|                             <td colspan="2" class="card-header-description"> | ||||
|                               <table class="w-100"> | ||||
|                                 <tr> | ||||
|                                   <td width="9%" class="text-left">OFF</td> | ||||
|                                   <td width="9%" class="text-center">10%</td> | ||||
|                                   <td width="9%" class="text-center">20%</td> | ||||
|                                   <td width="9%" class="text-center">30%</td> | ||||
|                                   <td width="9%" class="text-center">40%</td> | ||||
|                                   <td width="10%" class="text-center">50%</td> | ||||
|                                   <td width="9%" class="text-center">60%</td> | ||||
|                                   <td width="9%" class="text-center">70%</td> | ||||
|                                   <td width="9%" class="text-center">80%</td> | ||||
|                                   <td width="9%" class="text-center">90%</td> | ||||
|                                   <td width="9%" class="text-right">FULL</td> | ||||
|                                 </tr> | ||||
|                               </table> | ||||
|                             </td> | ||||
|                           </tr> | ||||
|                           <tr><td colspan="2"><input type="range" class="custom-range" min="0" max="100" step="1" value="0" id="fan-speed-range" disabled></td></tr> | ||||
|                         </table> | ||||
|                       </td> | ||||
|                       <td width="30%"><canvas id="chart-fanspeed" height="70" width="100"></canvas></td> | ||||
|                     </tr> | ||||
|                   </table> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- PANEL: Printer controls =============================================================================== --> | ||||
|         <div class="card-header flex-shrink-1 p-0 bg-dark text-light" id="accordion-panel-controls-head"> | ||||
|           <button class="btn btn-sm btn-dark btn-block text-left" type="button" data-toggle="collapse" data-target="#accordion-panel-controls-body" aria-expanded="true" aria-controls="accordion-panel-controls-body"> | ||||
|             <span class="h5"><span class="badge badge-success" style="width:30px;"><i class="icon icon-tasks"></i></span><span class="ml-2">Controls</span></span> | ||||
|             <div class="badge badge-secondary float-right"><span class="h5 icon icon-chevron-down"></span></div> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div id="accordion-panel-controls-body" class="collapse flex-grow-1 collapse-panel" aria-labelledby="accordion-panel-controls-head" data-parent="#accordion-panels"> | ||||
|           <div class="card-body h-100 border-bottom p-1 text-left"> | ||||
|  | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-home mr-1 ml-1"></i>Home positioning</div> | ||||
|               <div class="card-body px-0 py-1 bg-light badge-description"> | ||||
|                 <table class="w-100" cellpadding="0" cellspacing="0"> | ||||
|                   <tr> | ||||
|                     <td class="text-center text-light bg-info rounded-top">All axis</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">X axis</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">Y axis</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">Z axis</td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <td class="text-center"><button id="btn-move-home-all" type="button" class="btn btn-block btn-dark" style="border-radius:0px 0px 5px 5px;" disabled><i class="icon icon-home mr-1"></i><i class="icon icon-arrows"></i></button></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center"><button id="btn-move-home-x" type="button" class="btn btn-block btn-dark" style="border-radius:0px 0px 5px 5px;" disabled><i class="icon icon-home mr-1"></i><i class="icon icon-arrows-h"></i></button></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center"><button id="btn-move-home-y" type="button" class="btn btn-block btn-dark" style="border-radius:0px 0px 5px 5px;" disabled><i class="icon icon-home mr-1"></i><i class="icon icon-arrows-v"></i></button></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center"><button id="btn-move-home-z" type="button" class="btn btn-block btn-dark" style="border-radius:0px 0px 5px 5px;" disabled><i class="icon icon-home mr-1"></i><i class="icon icon-angle-double-down"></i></button></td> | ||||
|                   </tr> | ||||
|                 </table> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-arrows-alt mr-1 ml-1"></i>Movements</div> | ||||
|               <div class="card-body px-0 py-1 bg-light badge-description"> | ||||
|                 <div class="list-group list-group-flush"> | ||||
|                   <div class="list-group-item bg-light px-0 py-1"> | ||||
|                     <label for="txt-move-steps" class="">Steps movements size (mm)</label> | ||||
|  | ||||
|                     <div class="form-group"> | ||||
|                       <input type="text" id="txt-move-steps" class="form-control form-control-sm float-right" value="10" style="width:80px"/> | ||||
|                       <input type="range" class="form-control-range" min="0" max="50" step="1" id="customRange3" value="10"> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                   <div class="list-group-item bg-light px-0 py-1"> | ||||
|                     Move on X axis | ||||
|                     <button type="button" id="btn-move-xr" class="btn btn-sm btn-dark float-right" style="width:80px;"><i class="icon icon-long-arrow-right"></i></button> | ||||
|                     <button type="button" id="btn-move-xl" class="btn btn-sm btn-dark float-right mr-1" style="width:80px;"><i class="icon icon-long-arrow-left"></i></button> | ||||
|                   </div> | ||||
|                   <div class="list-group-item bg-light px-0 py-1"> | ||||
|                     Move on Y axis | ||||
|                     <button type="button" id="btn-move-yb" class="btn btn-sm btn-dark float-right" style="width:80px;"><i class="icon icon-long-arrow-down"></i></button> | ||||
|                     <button type="button" id="btn-move-yf" class="btn btn-sm btn-dark float-right mr-1" style="width:80px;"><i class="icon icon-long-arrow-up"></i></button> | ||||
|                   </div> | ||||
|                   <div class="list-group-item bg-light px-0 py-1"> | ||||
|                     Move on Z axis | ||||
|                     <button type="button" id="btn-move-zd" class="btn btn-sm btn-dark float-right" style="width:80px;"><i class="icon icon-angle-double-down"></i></button> | ||||
|                     <button type="button" id="btn-move-zu" class="btn btn-sm btn-dark float-right mr-1" style="width:80px;"><i class="icon icon-angle-double-up"></i></button> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-cog mr-1 ml-1"></i>Steppers locking</div> | ||||
|               <div class="card-body px-0 py-1 bg-light badge-description"> | ||||
|                 <table class="w-100" cellpadding="0" cellspacing="0"> | ||||
|                   <tr> | ||||
|                     <td colspan="6" class="pb-1"> | ||||
|                       Lock/Unlock all steppers (X, Y, Z, E) | ||||
|                     </td> | ||||
|                     <td class="pb-1"> | ||||
|                       <input type="checkbox" class="float-right" id="set-stepper-all" data-input-type="togglebtn" data-size="sm" data-width="100%" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="Lock" data-off="Unlock" disabled> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <td class="text-center text-light bg-info rounded-top">X stepper</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">Y stepper</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">Z stepper</td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center text-light bg-info rounded-top">E stepper</td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <td class="text-center pt-1"><input type="checkbox" id="set-stepper-x" data-input-type="togglebtn" data-size="sm" data-width="100%" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="Locked" data-off="Unlocked" disabled></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center pt-1"><input type="checkbox" id="set-stepper-y" data-input-type="togglebtn" data-size="sm" data-width="100%" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="Locked" data-off="Unlocked" disabled></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center pt-1"><input type="checkbox" id="set-stepper-z" data-input-type="togglebtn" data-size="sm" data-width="100%" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="Locked" data-off="Unlocked" disabled></td> | ||||
|                     <td style="width:2px"></td> | ||||
|                     <td class="text-center pt-1"><input type="checkbox" id="set-stepper-e" data-input-type="togglebtn" data-size="sm" data-width="100%" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="Locked" data-off="Unlocked" disabled></td> | ||||
|                   </tr> | ||||
|                 </table> | ||||
|  | ||||
|                 <div class="row mb-1"> | ||||
|                   <div class="col"> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-tencent-weibo mr-1 ml-1"></i>Filament</div> | ||||
|               <div class="card-body px-0 py-1 bg-light badge-description"> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- PANEL: File management ================================================================================ --> | ||||
|         <div class="card-header flex-shrink-1 p-0 bg-dark text-light" id="accordion-panel-file-head"> | ||||
|           <button class="btn btn-sm btn-dark btn-block text-left" type="button" data-toggle="collapse" data-target="#accordion-panel-file-body" aria-expanded="true" aria-controls="accordion-panel-file-body"> | ||||
|             <span class="h5"><span class="badge badge-success" style="width:30px;"><i class="icon icon-file"></i></span><span class="ml-2">File management</span></span> | ||||
|             <div class="badge badge-secondary float-right"><span class="h5 icon icon-chevron-down"></span></div> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div id="accordion-panel-file-body" class="collapse flex-grow-1 collapse-panel" aria-labelledby="accordion-panel-file-head" data-parent="#accordion-panels"> | ||||
|           <div class="card-body h-100 p-1 text-left"> | ||||
|             <div class="card mb-1 border-0"> | ||||
|               <div class="card-header card-header-title text-light bg-secondary m-0 p-1"><i class="icon icon-upload mr-1 ml-1"></i>Upload...</div> | ||||
|               <div class="card-body px-0 py-1 bg-light"> | ||||
|                 <div class="input-group input-group-sm mb-1"> | ||||
|                   <div class="custom-file"> | ||||
|                     <input type="file" class="custom-file-input" id="file-upload" accept=".g,.gco,.gcode" aria-describedby="btn-file-upload" disabled> | ||||
|                     <label id="file-upload-label" class="custom-file-label" for="file-upload" data-browse='Pick'>Choose file</label> | ||||
|                   </div> | ||||
|                   <div class="input-group-append"> | ||||
|                     <button id="btn-file-upload" class="btn btn-sm btn-success" type="button" disabled>Upload<i class="icon icon-upload ml-1"></i></button> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div id="upload-process-collapse" class="collapse mt-1"> | ||||
|                   <table class="w-100 mb-1" cellspacing="0" cellpadding="0"> | ||||
|                     <tr> | ||||
|                       <td width="34%"> | ||||
|                         <div class="card mr-1"> | ||||
|                           <div class="card-header py-0 px-1 bg-info text-light card-header-description">Filename (DOS8 Format)</div> | ||||
|                           <div id="div-upload-fname" class="card-body py-0 px-1 card-header-description text-center">-</div> | ||||
|                         </div> | ||||
|                       </td> | ||||
|                       <td width="33%"> | ||||
|                         <div class="card"> | ||||
|                           <div class="card-header py-0 px-1 bg-info text-light card-header-description">File size</div> | ||||
|                           <div id="div-upload-fsize" class="card-body py-0 px-1 card-header-description text-center">-</div> | ||||
|                         </div> | ||||
|                       </td> | ||||
|                       <td width="33%"> | ||||
|                         <div class="card ml-1"> | ||||
|                           <div class="card-header py-0 px-1 bg-info text-light card-header-description">GCode Lines</div> | ||||
|                           <div id="div-upload-fproc" class="card-body py-0 px-1 card-header-description text-center">-</div> | ||||
|                         </div> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   </table> | ||||
|                   <div class="card"> | ||||
|                     <div class="card-header py-0 px-1 bg-info text-light card-header-description">File processing</div> | ||||
|                     <table class="w-100" cellspacing="0" cellpadding="0"> | ||||
|                       <tr> | ||||
|                         <td width="60%" class="p-1"> | ||||
|                           <div id="upload-progress-text" class="card-header-description"> </div> | ||||
|                           <div class="progress"> | ||||
|                             <div id="upload-progressbar" class="progress-bar progress-bar-striped progress-bar-animated bg-info" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div> | ||||
|                           </div> | ||||
|                         </td> | ||||
|                         <td width="40%" class="p-1 text-right"> | ||||
|                           <button id="btn-file-proc-cancel" class="btn btn-sm btn-danger" type="button" disabled>Cancel<i class="icon icon-ban ml-1"></i></button> | ||||
|                           <button id="btn-file-proc" class="btn btn-sm btn-info" type="button" disabled>Process<i class="icon icon-cog ml-1"></i></button> | ||||
|                         </td> | ||||
|                       </tr> | ||||
|                     </table> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="card mb-0 border-0"> | ||||
|               <div class="card-header card-header-title text-white bg-secondary m-0 p-1"><i class="icon icon-file ml-1 mr-1"></i>SD Content management</div> | ||||
|               <div class="card-body px-0 py-1 bg-light"> | ||||
|                 <div> | ||||
|                   <button id="btn-get-sdcontent" class="btn btn-sm btn-success" disabled><i class="icon icon-angle-double-down mr-1"></i>Get content</button> | ||||
|                   <div class="btn-group float-right" role="group"> | ||||
|                     <button id="btn-set-sdinit" class="btn btn-sm btn-outline-success" style="width:120px" disabled><i class="icon icon-long-arrow-down mr-1"></i>SD Init</button> | ||||
|                     <button id="btn-set-sdrelease" class="btn btn-sm btn-outline-success"  style="width:120px" disabled><i class="icon icon-long-arrow-up mr-1"></i>SD Release</button> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div id="div-sd-selected-file" class="collapse mt-1 show"> | ||||
|                   <div class="input-group input-group-sm"> | ||||
|                     <div class="input-group-prepend"><span class="input-group-text" id="lbl-sdfile-selected">Selected file:</span></div> | ||||
|                     <input type="text" id="txt-sdfile-selected" class="form-control" aria-describedby="lbl-sdfile-selected" value="" readonly/> | ||||
|                     <div class="input-group-append"> | ||||
|                       <button id="btn-set-sdprint" class="btn btn-sm btn-success" data-toggle="modal" data-target="#modal-sdfile-print" onclick="WmButtons.PrintSdConfirm();" disabled><i class="icon icon-print"></i></button> | ||||
|                       <button id="btn-set-sddelete" class="btn btn-sm btn-danger" data-toggle="modal" data-target="#modal-sdfile-delete" onclick="WmButtons.DeleteSdConfirm();" disabled><i class="icon icon-trash"></i></button> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="card mb-0 border-0"> | ||||
|               <div class="card-header card-header-title text-white bg-secondary m-0 p-1"> | ||||
|                 <div class="float-right">Files: <div id="div-sdlist-file-count" class="badge badge-light">0</div></div> | ||||
|                 <div class="float-right mr-1">Folders: <div id="div-sdlist-folder-count" class="badge badge-light">0</div></div> | ||||
|                 <i class="icon icon-file ml-1 mr-1"></i>SD File list | ||||
|               </div> | ||||
|               <div class="card-body px-0 py-1 bg-light"><div id="list-sd-content" class="list-group list-group-flush"></div></div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- PANEL: Console ======================================================================================== --> | ||||
|         <div class="card-header flex-shrink-1 p-0 bg-dark text-light" id="accordion-panel-console-head"> | ||||
|           <button class="btn btn-sm btn-dark btn-block text-left" type="button" data-toggle="collapse" data-target="#accordion-panel-console-body" aria-expanded="true" aria-controls="accordion-panel-console-body"> | ||||
|             <span class="h5"><span class="badge badge-success" style="width:30px;"><i class="icon icon-terminal"></i></span><span class="ml-2">Console</span></span> | ||||
|             <div class="badge badge-secondary float-right"><span class="h5 icon icon-chevron-down"></span></div> | ||||
|             <div id="div-counter-badge" class="badge badge-secondary float-right mr-1"><span id="log-counter-badge" class="h5">0</span></div> | ||||
|           </button> | ||||
|         </div> | ||||
|         <div id="accordion-panel-console-body" class="collapse flex-grow-1 collapse-panel" aria-labelledby="accordion-panel-console-head" data-parent="#accordion-panels"> | ||||
|           <div class="card-body h-100 p-1 text-left"> | ||||
|             <label for="text-gcommand" class="mb-0 field-labels">G-Code command:</label> | ||||
|             <div class="input-group"> | ||||
|               <div class="input-group-prepend"> | ||||
|                 <a class="btn btn-sm btn-dark" target="_blank" href="http://marlinfw.org/meta/gcode/"><i class="icon icon-info"></i></a> | ||||
|                 <button class="btn btn-sm btn-outline-dark" type="button" id="btn-gcommand-preset" data-toggle="modal" data-target="#modal-presets"><i class="icon icon-tasks"></i></button> | ||||
|               </div> | ||||
|               <input type="text" id="text-gcommand" class="form-control form-control-sm border-dark text-uppercase" value="" required> | ||||
|               <div class="input-group-append"> | ||||
|                 <button class="btn btn-sm btn-outline-dark" type="button" id="btn-gcommand-checksum" data-toggle="button" aria-pressed="false" onclick="WmButtons.ToggleChecksumDiv();"><i class="icon icon-check-square"></i></button> | ||||
|                 <button class="btn btn-sm btn-dark mr-1" type="button" id="btn-gcommand">Send <i class="icon icon-chevron-right"></i></button> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div id="checksum-gcommand-div" class="collapse m-0 pr-1 text-right"> | ||||
|               <span class="field-description mr-1">GCode checksum value:</span> | ||||
|               <span class="h5"><span class="badge badge-secondary" id="checksum-gcommand-value" style="width:100px;"> </span></span> | ||||
|             </div> | ||||
|             <div id="checksum-gcommand-div" class="input-group input-group-sm collapse my-1"> | ||||
|               <input type="text" class="form-control" aria-describedby="checksum-gcommand-value" placeholder="GCode checksum value" readonly/> | ||||
|               <div class="input-group-append text-center"><span class="input-group-text" id="checksum-gcommand-value" style="width:100px;"></span></div> | ||||
|             </div> | ||||
|             <label for="btn-gcommand" class="mb-0 field-labels">Console output:</label> | ||||
|             <div class="border rounded p-0 mb-1 console-listbox text-left"> | ||||
|               <ul class="list-group list-group-flush" id="gcommand-console-list"></ul> | ||||
|             </div> | ||||
|             <div class="row"> | ||||
|               <div class="col"><button class="btn btn-sm btn-secondary btn-block" type="button" id="btn-clear-console"><i class="icon icon-ban mr-1"></i> Clear list</button></div> | ||||
|               <div class="col"><button class="btn btn-sm btn-success btn-block" type="button" id="btn-export-console"><i class="icon icon-angle-double-down mr-1"></i>Save..</button></div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: About window ========================================================================================= --> | ||||
|   <div class="modal fade" id="modal-info" tabindex="-1" role="dialog" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup" role="document"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-info mr-2"></i>Info...</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-2 text-left"> | ||||
|           <span class="h3">Marlin WebUI</span> | ||||
|           <p>Release date: January, 1 2020</p> | ||||
|           <p> | ||||
|             <i class="icon icon-github"></i> Github project: <a href="https://github.com/exilaus/E4d-box-project" target="_blank">E4d-box-project</a><br /> | ||||
|             <i class="icon icon-facebook-square"></i> Facebook: <a href="https://www.facebook.com/groups/372792116726814/about/" target="_blank">E4d@box</a> | ||||
|           </p> | ||||
|           <p>Open source dependencies:</p> | ||||
|           <ul> | ||||
|             <li><a href="https://marlinfw.org/" target="_blank">Marlin firmware</a></li> | ||||
|             <li><a href="https://jquery.com/" target="_blank">JQuery 3.5.1 (slim version)</a></li> | ||||
|             <li><a href="https://getbootstrap.com/" target="_blank">Bootstrap v4.5.0</a></li> | ||||
|             <li><a href="https://gitbrent.github.io/bootstrap4-toggle/" target="_blank">Bootstrap4 toggle switch v3.6.1</a></li> | ||||
|             <li><a href="http://fontastic.me/">Fontastic</a> | ||||
|             <li><a href="https://www.chartjs.org/" target="_blank">Chart.js</a></li> | ||||
|             <li><a href="https://github.com/eligrey/FileSaver.js" target="_blank">FileSaver.js</a></li> | ||||
|           </ul> | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"><button type="button" class="btn btn-dark btn-block" data-dismiss="modal">Close</button></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: Settings ============================================================================================= --> | ||||
|   <div class="modal fade" id="modal-settings" data-backdrop="static" tabindex="-1" role="dialog" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup" role="document"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-sliders mr-2"></i>Settings..</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-1 text-left"> | ||||
|           <ul class="list-group list-group-flush"> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Auto connect:</div> | ||||
|                 <div class="col-7 m-0"><input type="checkbox" id="set-auto-connect" data-size="sm" data-width="100" data-toggle="toggle" data-onstyle="success" data-offstyle="outline-dark" data-on="ON" data-off="OFF"></div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">If ON the application will try to connect automatically on start</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Temp interval:</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <select class="form-control form-control-sm mb-1" id="set-default-autotemp"> | ||||
|                     <option value="1">1 sec</option> | ||||
|                     <option value="5">5 sec</option> | ||||
|                     <option value="10">10 sec</option> | ||||
|                     <option value="30">30 sec</option> | ||||
|                     <option value="60">60 sec</option> | ||||
|                   </select> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the default temperature detection interval (secs)</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Temp unit:</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <select class="form-control form-control-sm mb-1" id="set-default-tempunit"> | ||||
|                     <option value="0">Celsius (default)</option> | ||||
|                     <option value="1">Fahrenheit</option> | ||||
|                     <option value="2">Kelvin</option> | ||||
|                   </select> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the default temperature unit</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row mb-0"> | ||||
|                 <div class="col-5 m-0">Default panel:</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <select class="form-control form-control-sm mb-1" id="set-default-panel"> | ||||
|                     <option value="4">Console</option> | ||||
|                     <option value="1">Controls</option> | ||||
|                     <option value="0">Status (default)</option> | ||||
|                     <option value="2">Temperature</option> | ||||
|                     <option value="3">Upload</option> | ||||
|                   </select> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the default shown panel on start</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Trace direction:</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <div class="btn-group btn-group-toggle" data-toggle="buttons"> | ||||
|                     <label class="btn btn-sm btn-secondary"><input type="radio" name="set-trace-mode" id="set-trace-mode-append"><i class="icon icon-angle-double-down mr-1"></i>Append</label> | ||||
|                     <label class="btn btn-sm btn-secondary"><input type="radio" name="set-trace-mode" id="set-trace-mode-prepend"><i class="icon icon-angle-double-up mr-1"></i>Prepend</label> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the console trace direction</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Trace symbol</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <select class="form-control form-control-sm mb-1" id="set-log-symbol"> | ||||
|                     <option value="icon">Icon</option> | ||||
|                     <option value="letter">Letter</option> | ||||
|                   </select> | ||||
|                   <div id="div-log-symbol-icon" class="collapse form-check-inline mb-0 h4"> | ||||
|                     <select class="form-control form-control-sm mb-0 mr-1" id="set-log-symbol-icon"> | ||||
|                       <option value="0">Chevron: U/D</option> | ||||
|                       <option value="2">Chevron: L/R</option> | ||||
|                       <option value="1">Arrow: U/D</option> | ||||
|                       <option value="3">Arrow: L/R</option> | ||||
|                     </select> | ||||
|                     <div id="div-log-symbol-icon-sample-s" class="badge badge-success mr-1"></div> | ||||
|                     <div id="div-log-symbol-icon-sample-r" class="badge badge-danger"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the console message direction symbol</small> | ||||
|             </li> | ||||
|             <li class="list-group-item p-1"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-5 m-0">Logging level</div> | ||||
|                 <div class="col-7 m-0"> | ||||
|                   <select class="form-control form-control-sm mb-1" id="set-log-level"> | ||||
|                     <option value="0">Info (default)</option> | ||||
|                     <option value="1">Warning</option> | ||||
|                     <option value="2">Error</option> | ||||
|                     <option value="3">Debug</option> | ||||
|                     <option value="4">Verbose</option> | ||||
|                   </select> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <small class="form-text text-muted font-italic mt-0">Set the JavaScript logging level</small> | ||||
|             </li> | ||||
|           </ul> | ||||
|           <div class="collapse mt-2" id="div-save-setting-rs"><div class="card card-body border-success p-1 text-success text-center">Settings saved successfully</div></div> | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"> | ||||
|           <div class="row w-100"> | ||||
|             <div class="col"><button type="button" class="btn btn-dark btn-block" id="btn-close-settings" data-dismiss="modal">Close</button></div> | ||||
|             <div class="col"><button type="button" class="btn btn-success btn-block" id="btn-save-settings">Save</button></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: Presets command ====================================================================================== --> | ||||
|   <div class="modal fade" id="modal-presets" tabindex="-1" role="dialog" aria-labelledby="modal-presets-label" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup" role="document"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-sliders mr-2"></i>GCommand presets</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-1 text-left"> | ||||
|           <div id="list-presets" class="list-group list-group-flush"> | ||||
|             <li class="list-group-item p-1 bg-light field-labels">Replace {N} chars with the specific parameter that you need if present (ie: G1 X{0} => G1 X10)</li> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"><button type="button" class="btn btn-dark btn-block" data-dismiss="modal">Close</button></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: Connect ============================================================================================== --> | ||||
|   <div class="modal fade" id="modal-connect" data-backdrop="static" tabindex="-1" role="dialog" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup" role="document"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-warning text-dark m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-exchange mr-2"></i>Connect...</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-2 text-center my-4"> | ||||
|           <i class="icon icon-exclamation-triangle"></i><br>Ooopsss!<br />Marlin firmware Web Socket is not connected.<br />Would you like connect it now? | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"> | ||||
|           <div class="row w-100"> | ||||
|             <div class="col"><button type="button" class="btn btn-sm btn-dark btn-block" data-dismiss="modal">Cancel</button></div> | ||||
|             <div class="col"><button id="btn-wsconnect-modal" type="button" class="btn btn-sm btn-warning btn-block" data-dismiss="modal"><i class="icon icon-bolt mr-1"></i>Connect now</button></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: SD file deletion confirmation  ======================================================================= --> | ||||
|   <div class="modal fade" id="modal-sdfile-delete" data-backdrop="static" role="dialog" tabindex="-1" aria-labelledby="modal-sdfile-label" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-exclamation-triangle mr-2"></i>Deletion confirmation</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-1 text-center mt-4 mb-1"> | ||||
|           <span class="h5"><i class="icon icon-exclamation-triangle"></i><br>Are you sure to delete<br><div id="div-sdfile-delete-badge" class="badge badge-danger"></div><br>SD card file?<br> | ||||
|           This operation cannot be undone.</span> | ||||
|           <div id="div-sdfile-delete-rs" class="collapse mt-2"><div class="card card-body border-success p-1 text-success text-center">File deleted successfully</div></div> | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"> | ||||
|           <div class="row w-100"> | ||||
|             <div class="col"><button type="button" class="btn btn-sm btn-dark btn-block" data-dismiss="modal">No</button></div> | ||||
|             <div class="col"><button id="btn-sdfile-delete-modal" type="button" class="btn btn-sm btn-success btn-block"><i class="icon icon-trash mr-1"></i>Yes</button></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: SD file print confirmation  ======================================================================= --> | ||||
|   <div class="modal fade" id="modal-sdfile-print" data-backdrop="static" role="dialog" tabindex="-1" aria-labelledby="modal-sdfile-print" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-print mr-2"></i>Print confirmation</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-1 text-center my-4"> | ||||
|           <span class="h5"><i class="icon icon-print"></i><br>Are you sure to start printing of<br><div id="div-sdfile-print-badge" class="badge badge-success"></div></span> | ||||
|         </div> | ||||
|         <div id="div-sdfile-print-rs" class="collapse mt-2"><div class="card card-body border-success p-1 m-2 text-success text-center">Printing started successfully</div></div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"> | ||||
|           <div class="row w-100"> | ||||
|             <div class="col"><button type="button" class="btn btn-sm btn-dark btn-block" data-dismiss="modal">No</button></div> | ||||
|             <div class="col"><button id="btn-sdfile-print-modal" type="button" class="btn btn-sm btn-success btn-block"><i class="icon icon-print mr-1"></i>Yes</button></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <!-- MODAL: Alert message  ======================================================================= --> | ||||
|   <div class="modal fade" id="modal-alert" data-backdrop="static" role="dialog" tabindex="-1" aria-labelledby="modal-alert" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-popup"> | ||||
|       <div class="modal-content"> | ||||
|         <div class="modal-header bg-secondary text-light m-0 px-2 py-1"> | ||||
|           <span class="h5 font-italic mt-1"><i class="icon icon-info-circled mr-2"></i>Message</span> | ||||
|           <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||||
|         </div> | ||||
|         <div class="modal-body p-1 text-center my-4"> | ||||
|           <span class="h5"><i class="icon icon-info-circled"></i><br><div id="div-alert-message"></div></span> | ||||
|         </div> | ||||
|         <div class="modal-footer bg-secondary m-0 p-1"> | ||||
|           <div class="row w-100"> | ||||
|             <div class="col"><button type="button" class="btn btn-sm btn-success btn-block" data-dismiss="modal">OK</button></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										2
									
								
								data/www/jquery-3.5.1.slim.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								data/www/jquery-3.5.1.slim.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10
									
								
								data/www/jquery.browser.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								data/www/jquery.browser.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /*! | ||||
|  * jQuery Browser Plugin 0.1.0 | ||||
|  * https://github.com/gabceb/jquery-browser-plugin | ||||
|  * Original jquery-browser code Copyright 2005, 2015 jQuery Foundation, Inc. and other contributors | ||||
|  * http://jquery.org/license | ||||
|  * Modifications Copyright 2015 Gabriel Cebrian | ||||
|  * https://github.com/gabceb | ||||
|  * Released under the MIT license | ||||
|  * Date: 23-11-2015 | ||||
|  */!function(a){"function"==typeof define&&define.amd?define(["jquery"],function(b){return a(b)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=a(require("jquery")):a(window.jQuery)}(function(a){"use strict";function b(a){void 0===a&&(a=window.navigator.userAgent),a=a.toLowerCase();var b=/(edge)\/([\w.]+)/.exec(a)||/(opr)[\/]([\w.]+)/.exec(a)||/(chrome)[ \/]([\w.]+)/.exec(a)||/(iemobile)[\/]([\w.]+)/.exec(a)||/(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("trident")>=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}); | ||||
							
								
								
									
										
											BIN
										
									
								
								data/www/marlin-logo-dark.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/www/marlin-logo-dark.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 881 B | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 2.3 KiB | 
| @@ -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; | ||||
|   } | ||||
| @@ -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 = ''; | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										
											BIN
										
									
								
								data/www/marlinui.eot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/www/marlinui.eot
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										56
									
								
								data/www/marlinui.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								data/www/marlinui.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| <?xml version="1.0" standalone="no"?> | ||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | ||||
| <svg xmlns="http://www.w3.org/2000/svg"> | ||||
| <metadata>Generated by Fontastic.me</metadata> | ||||
| <defs> | ||||
| <font id="marlinui" horiz-adv-x="512"> | ||||
| <font-face font-family="marlinui" units-per-em="512" ascent="480" descent="-32"/> | ||||
| <missing-glyph horiz-adv-x="512" /> | ||||
|  | ||||
| <glyph glyph-name="home" unicode="a" d="M421 229l0-138c0-5-2-9-6-12-3-4-8-6-13-6l-109 0 0 110-74 0 0-110-109 0c-5 0-10 2-13 6-4 3-6 7-6 12l0 138c0 0 0 0 0 0 0 1 0 1 0 1l164 136 165-136c0 0 0-1 0-1z m63 19l-17-21c-2-2-4-3-6-3l-1 0c-3 0-5 1-6 2l-198 165-198-165c-2-2-4-2-7-2-2 0-4 1-6 3l-17 21c-2 2-2 4-2 7 0 3 1 5 3 6l205 171c6 5 14 8 22 8 8 0 16-3 22-8l69-58 0 56c0 2 1 5 3 6 2 2 4 3 7 3l54 0c3 0 5-1 7-3 2-1 3-4 3-6l0-117 62-52c2-1 3-3 3-6 0-3 0-5-2-7z"/> | ||||
| <glyph glyph-name="info" unicode="b" d="M318 512c17 0 29-5 38-14 9-9 14-21 14-35 0-17-7-32-20-45-14-13-30-20-49-20-16 0-29 5-38 14-9 9-13 21-12 37 0 15 6 30 18 43 12 13 28 20 49 20m-105-512c-34 0-43 30-28 91 0 0 31 130 31 130 5 19 5 29 0 29-4 0-13-3-28-9-14-7-26-13-36-20 0 0-14 23-14 23 31 26 63 48 97 64 34 17 60 25 77 25 27 0 33-28 19-83 0 0-36-136-36-136-6-22-5-33 3-33 15 0 35 10 60 31 0 0 16-21 16-21-29-29-59-52-90-67-31-16-55-24-71-24"/> | ||||
| <glyph glyph-name="cog" unicode="c" d="M329 256c0 20-7 37-21 52-15 14-32 21-52 21-20 0-37-7-52-21-14-15-21-32-21-52 0-20 7-37 21-52 15-14 32-21 52-21 20 0 37 7 52 21 14 15 21 32 21 52z m146 31l0-63c0-3 0-5-2-7-1-2-3-3-6-4l-52-8c-4-10-8-19-12-26 7-9 17-22 31-39 2-2 3-5 3-7 0-3-1-5-3-7-5-7-14-17-28-31-14-13-23-20-27-20-2 0-5 1-7 3l-40 31c-8-5-17-8-26-11-3-26-6-44-8-53-1-6-5-8-10-8l-64 0c-2 0-5 0-7 2-2 2-3 4-3 6l-8 53c-9 3-18 6-26 10l-40-30c-2-2-4-3-7-3-3 0-5 1-7 3-24 22-40 38-47 48-2 2-2 4-2 7 0 2 0 4 2 6 3 4 8 11 14 19 7 9 12 16 16 21-5 9-9 19-12 28l-52 8c-3 0-5 1-6 3-2 2-2 4-2 7l0 63c0 3 0 5 2 7 1 2 3 3 5 4l53 8c3 8 7 17 12 26-8 11-18 24-31 39-2 3-3 5-3 7 0 2 1 4 3 7 5 7 14 17 28 30 14 14 23 21 27 21 2 0 5-1 7-3l40-31c8 5 17 8 26 11 3 26 6 44 8 53 1 6 5 8 10 8l64 0c2 0 5 0 7-2 2-2 3-4 3-6l8-53c9-3 18-6 26-10l40 30c2 2 4 3 7 3 3 0 5-1 7-3 25-23 41-39 47-49 2-1 2-3 2-6 0-2 0-4-2-6-3-4-8-11-14-19-7-9-12-16-16-21 5-9 9-18 12-28l52-8c3 0 5-1 6-3 2-2 2-4 2-7z"/> | ||||
| <glyph glyph-name="tasks" unicode="d" d="M293 110l182 0 0 36-182 0z m-110 146l292 0 0 37-292 0z m183 146l109 0 0 37-109 0z m146-237l0-74c0-5-2-9-5-12-4-4-8-6-13-6l-476 0c-5 0-9 2-13 6-3 3-5 7-5 12l0 74c0 5 2 9 5 12 4 4 8 6 13 6l476 0c5 0 9-2 13-6 3-3 5-7 5-12z m0 146l0-73c0-5-2-10-5-13-4-4-8-6-13-6l-476 0c-5 0-9 2-13 6-3 3-5 8-5 13l0 73c0 5 2 9 5 13 4 3 8 5 13 5l476 0c5 0 9-2 13-5 3-4 5-8 5-13z m0 146l0-73c0-5-2-9-5-13-4-3-8-5-13-5l-476 0c-5 0-9 2-13 5-3 4-5 8-5 13l0 73c0 5 2 9 5 13 4 4 8 5 13 5l476 0c5 0 9-1 13-5 3-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="chevron-down" unicode="f" d="M481 281l-212-212c-4-3-8-5-13-5-5 0-9 2-13 5l-212 212c-3 4-5 8-5 13 0 5 2 10 5 13l48 47c3 4 7 6 12 6 5 0 10-2 13-6l152-151 152 151c3 4 8 6 13 6 5 0 9-2 12-6l48-47c3-3 5-8 5-13 0-5-2-9-5-13z"/> | ||||
| <glyph glyph-name="chevron-left" unicode="g" d="M408 426l-152-152 152-151c3-4 5-8 5-13 0-5-2-10-5-13l-48-48c-3-3-8-5-13-5-5 0-9 2-12 5l-212 212c-4 4-6 8-6 13 0 5 2 10 6 13l212 212c3 4 7 6 12 6 5 0 10-2 13-6l48-47c3-4 5-8 5-13 0-5-2-9-5-13z"/> | ||||
| <glyph glyph-name="chevron-right" unicode="h" d="M389 261l-212-212c-3-3-7-5-12-5-5 0-10 2-13 5l-48 48c-3 3-5 8-5 13 0 5 2 9 5 13l152 151-152 152c-3 4-5 8-5 13 0 5 2 9 5 13l48 47c3 4 8 6 13 6 5 0 9-2 12-6l212-212c4-3 6-8 6-13 0-5-2-9-6-13z"/> | ||||
| <glyph glyph-name="chevron-up" unicode="i" d="M481 132l-48-47c-3-4-7-6-12-6-5 0-10 2-13 6l-152 151-152-151c-3-4-8-6-13-6-5 0-9 2-12 6l-48 47c-3 3-5 8-5 13 0 5 2 9 5 13l212 211c4 4 8 6 13 6 5 0 9-2 13-6l212-211c3-4 5-8 5-13 0-5-2-10-5-13z"/> | ||||
| <glyph glyph-name="arrows-alt" unicode="j" d="M403 357l-101-101 101-101 41 41c6 6 12 7 20 4 8-4 11-9 11-17l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-8 0-13 3-17 11-3 7-2 14 4 20l41 41-101 101-101-101 41-41c6-6 7-13 4-20-4-8-9-11-17-11l-128 0c-5 0-9 1-13 5-4 4-5 8-5 13l0 128c0 8 3 13 11 17 7 3 14 2 20-4l41-41 101 101-101 101-41-41c-4-3-8-5-13-5-2 0-5 0-7 1-8 4-11 9-11 17l0 128c0 5 1 9 5 13 4 4 8 5 13 5l128 0c8 0 13-3 17-11 3-7 2-14-4-20l-41-41 101-101 101 101-41 41c-6 6-7 13-4 20 4 8 9 11 17 11l128 0c5 0 9-1 13-5 4-4 5-8 5-13l0-128c0-8-3-13-11-17-2-1-5-1-7-1-5 0-9 2-13 5z"/> | ||||
| <glyph glyph-name="upload" unicode="k" d="M384 91c0 5-2 10-5 13-4 4-8 6-13 6-5 0-10-2-13-6-4-3-6-8-6-13 0-5 2-9 6-12 3-4 8-6 13-6 5 0 9 2 13 6 3 3 5 7 5 12z m73 0c0 5-2 10-5 13-4 4-8 6-13 6-5 0-9-2-13-6-4-3-5-8-5-13 0-5 1-9 5-12 4-4 8-6 13-6 5 0 9 2 13 6 3 3 5 7 5 12z m37 64l0-91c0-8-3-14-8-19-6-6-12-8-20-8l-420 0c-8 0-14 2-20 8-5 5-8 11-8 19l0 91c0 8 3 15 8 20 6 5 12 8 20 8l122 0c4-11 10-20 20-26 9-7 20-11 31-11l74 0c11 0 22 4 31 11 10 6 16 15 20 26l122 0c8 0 14-3 20-8 5-5 8-12 8-20z m-93 186c-3-8-9-12-17-12l-73 0 0-128c0-5-2-9-6-13-3-3-7-5-12-5l-74 0c-5 0-9 2-12 5-4 4-6 8-6 13l0 128-73 0c-8 0-14 4-17 12-3 7-2 14 4 19l128 128c4 4 8 6 13 6 5 0 9-2 13-6l128-128c6-5 7-12 4-19z"/> | ||||
| <glyph glyph-name="ban" unicode="m" d="M411 257c0 31-8 59-24 84l-216-215c26-17 55-25 85-25 21 0 41 4 60 12 20 8 36 19 50 33 14 14 25 31 33 50 8 19 12 40 12 61z m-285-86l216 216c-26 17-55 26-86 26-28 0-54-7-78-21-24-14-43-33-57-57-13-24-20-50-20-78 0-31 8-59 25-86z m349 86c0-30-5-59-17-86-12-27-27-51-47-70-19-20-43-35-70-47-27-12-55-17-85-17-30 0-58 5-85 17-27 12-51 27-70 47-20 19-35 43-47 70-12 27-17 56-17 86 0 30 5 58 17 85 12 28 27 51 47 71 19 19 43 35 70 46 27 12 55 18 85 18 30 0 58-6 85-18 27-11 51-27 70-46 20-20 35-43 47-71 12-27 17-55 17-85z"/> | ||||
| <glyph glyph-name="github" unicode="n" d="M475 256c0-48-14-91-41-129-28-38-64-65-109-79-5-1-8-1-11 2-2 2-3 5-3 8l0 61c0 18-5 32-15 40 11 1 20 3 29 5 9 3 18 6 27 11 9 6 17 12 23 19 6 8 11 18 15 30 4 13 6 27 6 43 0 23-8 43-23 59 7 18 7 37-2 59-5 1-13 0-23-4-10-3-19-8-26-12l-11-7c-18 5-36 7-55 7-19 0-37-2-55-7-3 2-7 5-12 8-5 3-13 6-24 11-11 4-19 5-24 4-9-22-9-41-2-59-15-16-23-36-23-59 0-16 2-30 6-42 4-13 9-23 15-30 6-8 14-14 23-20 9-5 18-8 27-11 8-2 18-4 29-5-8-7-12-17-14-29-4-2-8-4-13-5-4-1-10-1-16-1-6 0-13 2-19 6-6 4-11 10-16 18-3 6-8 11-14 15-5 4-10 6-14 7l-5 1c-4 0-7-1-9-2-1-1-2-2-1-3 0-1 1-3 2-4 2-1 3-2 4-3l2-2c4-2 8-5 13-11 4-5 7-10 9-14l2-7c3-7 7-13 13-17 6-5 12-8 19-9 7-1 14-2 20-2 6 0 12 0 16 1l6 1c0-7 0-16 1-25 0-10 0-15 0-16 0-3-2-6-4-8-2-3-6-3-11-2-45 14-81 41-109 79-27 38-41 81-41 129 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/> | ||||
| <glyph glyph-name="thermometer" unicode="o" d="M323 259c21-12 39-29 52-50 13-21 19-45 19-71 0-38-13-71-40-98-27-27-60-40-98-40-38 0-71 13-98 40-27 27-40 60-40 98 0 26 6 50 19 71 13 21 31 38 52 50 0 0 0 227 0 227 0 17 7 26 21 26 0 0 87 0 87 0 7 0 13-3 18-8 5-5 8-11 8-18 0 0 0-227 0-227m-67-208c24 0 44 9 61 26 18 17 26 37 26 61 0 19-5 36-16 51-11 15-26 26-43 31 0 0 0 190 0 190 0 0-52 0-52 0 0 0 0-189 0-189-18-5-33-16-45-31-12-15-18-33-18-52 0-24 8-44 26-61 17-17 37-26 61-26"/> | ||||
| <glyph glyph-name="bolt" unicode="e" d="M381 350c3-4 4-8 2-12l-154-331c-3-5-7-7-12-7-1 0-3 0-4 1-4 1-6 2-8 5-1 3-2 6-1 9l56 230-116-28c0-1-2-1-3-1-4 0-7 1-9 3-3 3-5 7-4 12l58 235c0 3 2 5 4 7 3 2 5 2 8 2l94 0c4 0 7-1 9-3 3-3 4-5 4-9 0-1-1-3-2-5l-48-132 113 28c1 0 2 1 3 1 4 0 7-2 10-5z"/> | ||||
| <glyph glyph-name="sort-asc" unicode="p" d="M402 311c0-5-2-9-5-13-4-4-8-5-13-5l-256 0c-5 0-9 1-13 5-3 4-5 8-5 13 0 5 2 9 5 13l128 128c4 3 8 5 13 5 5 0 9-2 13-5l128-128c3-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="sort-desc" unicode="q" d="M402 201c0-5-2-9-5-13l-128-128c-4-3-8-5-13-5-5 0-9 2-13 5l-128 128c-3 4-5 8-5 13 0 5 2 9 5 13 4 4 8 5 13 5l256 0c5 0 9-1 13-5 3-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="long-arrow-left" unicode="r" d="M512 283l0-54c0-3-1-5-3-7-1-2-3-3-6-3l-357 0 0-64c0-4-2-6-5-8-4-1-7-1-10 2l-110 100c-2 1-3 4-3 6 0 3 1 5 3 7l110 101c3 3 6 3 10 2 3-2 5-5 5-8l0-64 357 0c3 0 5-1 6-3 2-2 3-4 3-7z"/> | ||||
| <glyph glyph-name="long-arrow-down" unicode="s" d="M365 141c1-4 1-7-2-10l-100-110c-1-2-4-3-6-3-3 0-5 1-7 3l-101 110c-3 3-3 6-2 10 2 3 5 5 8 5l64 0 0 357c0 3 1 5 3 6 2 2 4 3 7 3l54 0c3 0 5-1 7-3 2-1 3-3 3-6l0-357 64 0c4 0 6-2 8-5z"/> | ||||
| <glyph glyph-name="long-arrow-right" unicode="t" d="M494 257c0-3-1-5-3-7l-110-101c-3-3-6-3-10-2-3 2-5 5-5 8l0 64-357 0c-3 0-5 1-6 3-2 2-3 4-3 7l0 54c0 3 1 5 3 7 1 2 3 3 6 3l357 0 0 64c0 4 2 6 5 8 4 1 7 1 10-2l110-100c2-1 3-4 3-6z"/> | ||||
| <glyph glyph-name="long-arrow-up" unicode="u" d="M365 371c-2-3-5-5-8-5l-64 0 0-357c0-3-1-5-3-6-2-2-4-3-7-3l-54 0c-3 0-5 1-7 3-2 1-3 3-3 6l0 357-64 0c-4 0-6 2-8 5-1 4-1 7 2 10l100 110c1 2 4 3 6 3 3 0 5-1 7-3l101-110c3-3 3-6 2-10z"/> | ||||
| <glyph glyph-name="arrows" unicode="v" d="M512 256c0-5-2-9-5-13l-74-73c-3-4-7-5-12-5-5 0-10 1-13 5-4 4-6 8-6 13l0 36-109 0 0-109 36 0c5 0 9-2 13-6 4-3 5-8 5-13 0-5-1-9-5-12l-73-74c-4-3-8-5-13-5-5 0-9 2-13 5l-73 74c-4 3-5 7-5 12 0 5 1 10 5 13 4 4 8 6 13 6l36 0 0 109-109 0 0-36c0-5-2-9-6-13-3-4-8-5-13-5-5 0-9 1-12 5l-74 73c-3 4-5 8-5 13 0 5 2 9 5 13l74 73c3 4 7 5 12 5 5 0 10-1 13-5 4-4 6-8 6-13l0-36 109 0 0 109-36 0c-5 0-9 2-13 6-4 3-5 8-5 13 0 5 1 9 5 12l73 74c4 3 8 5 13 5 5 0 9-2 13-5l73-74c4-3 5-7 5-12 0-5-1-10-5-13-4-4-8-6-13-6l-36 0 0-109 109 0 0 36c0 5 2 9 6 13 3 4 8 5 13 5 5 0 9-1 12-5l74-73c3-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="arrows-v" unicode="w" d="M347 421c0-5-1-10-5-13-4-4-8-6-13-6l-36 0 0-292 36 0c5 0 9-2 13-6 4-3 5-8 5-13 0-5-1-9-5-12l-73-74c-4-3-8-5-13-5-5 0-9 2-13 5l-73 74c-4 3-5 7-5 12 0 5 1 10 5 13 4 4 8 6 13 6l36 0 0 292-36 0c-5 0-9 2-13 6-4 3-5 8-5 13 0 5 1 9 5 12l73 74c4 3 8 5 13 5 5 0 9-2 13-5l73-74c4-3 5-7 5-12z"/> | ||||
| <glyph glyph-name="arrows-h" unicode="x" d="M512 256c0-5-2-9-5-13l-74-73c-3-4-7-5-12-5-5 0-10 1-13 5-4 4-6 8-6 13l0 36-292 0 0-36c0-5-2-9-6-13-3-4-8-5-13-5-5 0-9 1-12 5l-74 73c-3 4-5 8-5 13 0 5 2 9 5 13l74 73c3 4 7 5 12 5 5 0 10-1 13-5 4-4 6-8 6-13l0-36 292 0 0 36c0 5 2 9 6 13 3 4 8 5 13 5 5 0 9-1 12-5l74-73c3-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="angle-double-up" unicode="y" d="M399 137c0-2-1-5-3-6l-15-15c-1-2-4-3-6-3-3 0-5 1-7 3l-112 113-112-113c-2-2-4-3-7-3-2 0-5 1-6 3l-15 15c-2 1-3 4-3 6 0 3 1 5 3 7l133 133c2 2 5 3 7 3 2 0 5-1 7-3l133-133c2-2 3-4 3-7z m0 110c0-3-1-5-3-7l-15-14c-1-2-4-3-6-3-3 0-5 1-7 3l-112 112-112-112c-2-2-4-3-7-3-2 0-5 1-6 3l-15 14c-2 2-3 4-3 7 0 2 1 5 3 6l133 134c2 1 5 2 7 2 2 0 5-1 7-2l133-134c2-1 3-4 3-6z"/> | ||||
| <glyph glyph-name="angle-double-down" unicode="z" d="M399 265c0-2-1-5-3-6l-133-134c-2-1-5-2-7-2-2 0-5 1-7 2l-133 134c-2 1-3 4-3 6 0 3 1 5 3 7l15 14c1 2 4 3 6 3 3 0 5-1 7-3l112-112 112 112c2 2 4 3 7 3 2 0 5-1 6-3l15-14c2-2 3-4 3-7z m0 110c0-3-1-5-3-7l-133-133c-2-2-5-3-7-3-2 0-5 1-7 3l-133 133c-2 2-3 4-3 7 0 2 1 5 3 6l15 15c1 2 4 3 6 3 3 0 5-1 7-3l112-113 112 113c2 2 4 3 7 3 2 0 5-1 6-3l15-15c2-1 3-4 3-6z"/> | ||||
| <glyph glyph-name="tencent-weibo" unicode="A" d="M314 349c0-16-6-29-17-39-10-11-23-17-38-17-12 0-22 4-32 10-12-12-23-26-33-41-47-71-66-153-58-246 0-4-1-8-3-11-3-3-6-5-10-5l-2 0c-3 0-7 1-10 4-2 2-4 6-4 9-3 24-3 48-1 71 2 23 4 44 8 62 4 18 9 36 15 53 7 18 14 32 20 45 7 12 14 24 21 35 12 18 24 33 38 48-3 6-5 14-5 22 0 15 6 28 17 39 10 10 23 16 39 16 15 0 28-6 39-16 10-11 16-24 16-39z m109-4c0-30-8-57-23-83-15-26-35-46-60-61-26-14-54-22-84-22-12 0-25 1-37 4-4 1-8 3-10 7-2 3-3 7-2 11 1 4 4 7 7 9 3 2 7 3 11 2 10-2 20-3 31-3 18 0 36 3 53 10 17 8 32 17 44 30 12 12 22 26 29 43 7 17 11 35 11 53 0 19-4 37-11 54-7 17-17 31-29 43-12 12-27 22-44 29-17 8-35 11-53 11-18 0-36-3-53-11-17-7-32-17-44-29-12-12-22-26-29-43-7-17-11-35-11-54 0-21 5-42 15-62 2-4 2-7 1-11-1-4-4-7-7-9-4-2-8-2-12-1-3 2-6 4-8 8-12 23-19 48-19 75 0 23 5 45 14 65 9 21 20 39 35 53 15 15 33 27 53 36 21 9 43 13 65 13 30 0 58-7 84-22 25-15 45-35 60-61 15-26 23-53 23-84z"/> | ||||
| <glyph glyph-name="playback-fast-forward" unicode="B" d="M64 128l192 128-192 128z m384 128l-192 128 0-256z"/> | ||||
| <glyph glyph-name="fire" unicode="C" d="M457 27l0-18c0-2-1-4-3-6-1-2-4-3-6-3l-384 0c-2 0-5 1-6 3-2 2-3 4-3 6l0 18c0 3 1 5 3 7 1 2 4 3 6 3l384 0c2 0 5-1 6-3 2-2 3-4 3-7z m-73 302c0-15-2-28-7-41-5-13-11-23-18-32-8-9-16-17-25-25-9-8-19-16-28-22-9-7-17-14-25-21-7-7-13-15-18-23-5-9-7-18-7-28 0-18 6-39 19-64l-1 0 0 0c-17 8-32 16-45 24-14 8-27 17-40 28-13 11-24 23-32 35-9 13-16 27-21 43-5 17-8 34-8 53 0 15 2 29 7 41 5 13 11 23 18 32 8 9 16 18 25 25 9 8 19 16 28 23 9 6 17 13 25 20 7 7 13 15 18 23 5 9 7 18 7 28 0 18-6 39-19 64l1 0 0 0c17-8 32-16 45-24 14-8 27-17 40-28 13-11 24-23 32-35 9-13 16-27 21-43 5-17 8-34 8-53z"/> | ||||
| <glyph glyph-name="forward" unicode="D" d="M31 40c-3-3-7-5-9-3-2 1-4 4-4 9l0 420c0 5 2 8 4 9 2 2 6 0 9-3l203-203c2-2 3-3 4-6l0 203c0 5 1 8 3 9 3 2 6 0 10-3l202-203c4-4 6-8 6-13 0-5-2-9-6-13l-202-203c-4-3-7-5-10-3-2 1-3 4-3 9l0 203c-1-2-2-4-4-6z"/> | ||||
| <glyph glyph-name="terminal" unicode="E" d="M448 448l-384 0c-18 0-32-14-32-32l0-320c0-17 14-32 32-32l384 0c17 0 32 15 32 32l0 320c0 18-15 32-32 32z m-352-224l64 64-64 64 32 32 96-96-96-96z m256-32l-128 0 0 32 128 0z"/> | ||||
| <glyph glyph-name="info-circled" unicode="l" d="M253 492c65 0 120-22 167-67 46-45 70-100 72-165 0-65-22-121-68-167-45-47-100-71-165-73-65 0-121 22-167 68-47 45-71 100-72 165-1 65 21 121 67 167 46 47 101 71 166 72m27-78c-15 0-26-4-34-13-8-8-12-16-12-25 0-10 2-17 8-23 6-5 14-8 25-8 13 0 24 4 31 11 8 8 12 17 12 28 0 20-10 30-30 30m-62-304c10 0 25 4 43 13 19 9 37 22 54 40 0 0-9 12-9 12-16-12-28-18-37-18-4 0-5 6-2 19 0 0 22 82 22 82 9 33 5 49-11 49-11 0-26-5-46-15-20-10-40-22-59-38 0 0 8-13 8-13 18 11 31 17 38 17 4 0 4-6 0-17 0 0-18-78-18-78-9-36-3-53 17-53"/> | ||||
| <glyph glyph-name="exclamation-triangle" unicode="F" d="M293 119l0 54c0 3-1 5-3 7-2 2-4 3-7 3l-54 0c-3 0-5-1-7-3-2-2-3-4-3-7l0-54c0-3 1-5 3-7 2-1 4-2 7-2l54 0c3 0 5 1 7 2 2 2 3 4 3 7z m-1 107l5 131c0 2-1 4-3 6-2 2-4 3-7 3l-62 0c-3 0-5-1-7-3-2-2-3-4-3-6l5-131c0-2 1-3 3-5 1-1 4-2 6-2l53 0c3 0 5 1 7 2 2 2 3 3 3 5z m-4 267l219-402c7-12 7-24 0-36-3-6-8-10-13-14-6-3-12-4-19-4l-438 0c-7 0-13 1-19 4-5 4-10 8-13 14-7 12-7 24 0 36l219 402c3 6 8 10 13 14 6 3 12 5 19 5 7 0 13-2 19-5 5-4 10-8 13-14z"/> | ||||
| <glyph glyph-name="exchange" unicode="G" d="M512 174l0-55c0-3-1-5-3-7-2-1-4-2-6-2l-393 0 0-55c0-3-1-5-3-7-2-1-4-2-6-2-3 0-5 1-7 3l-91 91c-2 2-3 4-3 6 0 3 1 5 3 7l91 91c2 2 4 3 7 3 2 0 4-1 6-3 2-2 3-4 3-6l0-55 393 0c2 0 4-1 6-3 2-2 3-4 3-6z m0 155c0-3-1-5-3-6l-91-92c-2-2-4-2-7-2-2 0-4 0-6 2-2 2-3 4-3 7l0 55-393 0c-2 0-4 0-6 2-2 2-3 4-3 7l0 55c0 2 1 4 3 6 2 2 4 3 6 3l393 0 0 55c0 2 1 4 3 6 2 2 4 3 6 3 3 0 5-1 7-3l91-91c2-2 3-4 3-7z"/> | ||||
| <glyph glyph-name="plus" unicode="H" d="M457 302l0-55c0-8-3-14-8-20-5-5-12-8-19-8l-119 0 0-118c0-8-3-15-8-20-5-5-12-8-20-8l-54 0c-8 0-15 3-20 8-5 5-8 12-8 20l0 118-119 0c-7 0-14 3-19 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 19 8l119 0 0 119c0 8 3 14 8 19 5 6 12 8 20 8l54 0c8 0 15-2 20-8 5-5 8-11 8-19l0-119 119 0c7 0 14-3 19-8 5-5 8-12 8-19z"/> | ||||
| <glyph glyph-name="minus" unicode="I" d="M457 302l0-55c0-8-3-14-8-20-5-5-12-8-19-8l-348 0c-7 0-14 3-19 8-5 6-8 12-8 20l0 55c0 7 3 14 8 19 5 5 12 8 19 8l348 0c7 0 14-3 19-8 5-5 8-12 8-19z"/> | ||||
| <glyph glyph-name="check-square" unicode="J" d="M232 141l176 175c3 4 5 8 5 13 0 5-2 9-5 13l-29 29c-4 4-8 6-13 6-5 0-10-2-13-6l-134-133-60 60c-3 4-8 5-13 5-5 0-9-1-13-5l-29-29c-3-4-5-8-5-13 0-5 2-9 5-13l103-102c3-4 7-6 12-6 5 0 10 2 13 6z m243 252l0-274c0-23-8-42-24-58-16-16-35-24-58-24l-274 0c-23 0-42 8-58 24-16 16-24 35-24 58l0 274c0 23 8 42 24 58 16 16 35 24 58 24l274 0c23 0 42-8 58-24 16-16 24-35 24-58z"/> | ||||
| <glyph glyph-name="facebook-square" unicode="K" d="M393 475c23 0 42-8 58-24 16-16 24-35 24-58l0-274c0-23-8-42-24-58-16-16-35-24-58-24l-54 0 0 170 57 0 9 66-66 0 0 42c0 11 3 19 7 24 5 5 13 8 26 8l35 0 0 60c-12 1-29 2-51 2-26 0-46-7-62-23-15-15-23-36-23-64l0-49-57 0 0-66 57 0 0-170-152 0c-23 0-42 8-58 24-16 16-24 35-24 58l0 274c0 23 8 42 24 58 16 16 35 24 58 24z"/> | ||||
| <glyph glyph-name="file" unicode="L" d="M329 366l0 135c4-3 8-6 10-8l117-117c3-3 5-6 8-10z m-36-9c0-8 2-15 8-20 5-5 11-8 19-8l155 0 0-302c0-7-2-14-8-19-5-5-11-8-19-8l-384 0c-8 0-14 3-19 8-6 5-8 12-8 19l0 458c0 7 2 14 8 19 5 5 11 8 19 8l229 0z"/> | ||||
| <glyph glyph-name="trash" unicode="M" d="M201 119l0 201c0 3-1 5-2 7-2 1-4 2-7 2l-18 0c-3 0-5-1-7-2-2-2-2-4-2-7l0-201c0-3 0-5 2-7 2-1 4-2 7-2l18 0c3 0 5 1 7 2 1 2 2 4 2 7z m73 0l0 201c0 3-1 5-2 7-2 1-4 2-7 2l-18 0c-3 0-5-1-7-2-1-2-2-4-2-7l0-201c0-3 1-5 2-7 2-1 4-2 7-2l18 0c3 0 5 1 7 2 1 2 2 4 2 7z m73 0l0 201c0 3 0 5-2 7-2 1-4 2-7 2l-18 0c-3 0-5-1-7-2-1-2-2-4-2-7l0-201c0-3 1-5 2-7 2-1 4-2 7-2l18 0c3 0 5 1 7 2 2 2 2 4 2 7z m-155 283l128 0-14 34c-1 1-3 2-5 3l-90 0c-2-1-4-2-5-3z m265-9l0-18c0-3-1-5-2-7-2-1-4-2-7-2l-27 0 0-271c0-16-5-30-14-41-9-12-20-17-32-17l-238 0c-12 0-23 5-32 16-9 11-14 25-14 41l0 272-27 0c-3 0-5 1-7 2-1 2-2 4-2 7l0 18c0 3 1 5 2 7 2 1 4 2 7 2l88 0 20 48c3 7 8 13 16 18 7 5 15 7 22 7l92 0c7 0 15-2 22-7 8-5 13-11 16-18l20-48 88 0c3 0 5-1 7-2 1-2 2-4 2-7z"/> | ||||
| <glyph glyph-name="print" unicode="N" d="M128 73l256 0 0 73-256 0z m0 183l256 0 0 110-46 0c-7 0-14 2-19 8-5 5-8 12-8 19l0 46-183 0z m329-18c0 5-2 9-5 13-4 3-8 5-13 5-5 0-9-2-13-5-4-4-5-8-5-13 0-5 1-10 5-13 4-4 8-6 13-6 5 0 9 2 13 6 3 3 5 8 5 13z m37 0l0-119c0-3-1-5-3-7-2-1-4-2-6-2l-64 0 0-46c0-8-3-14-8-19-6-6-12-8-20-8l-274 0c-8 0-14 2-20 8-5 5-8 11-8 19l0 46-64 0c-2 0-4 1-6 2-2 2-3 4-3 7l0 119c0 15 6 28 16 38 11 11 24 17 39 17l18 0 0 155c0 8 3 14 8 19 6 6 12 8 20 8l192 0c7 0 16-1 25-5 9-4 16-9 22-14l43-43c5-6 10-13 14-22 4-9 6-18 6-25l0-73 18 0c15 0 28-6 39-17 10-10 16-23 16-38z"/> | ||||
| <glyph glyph-name="refresh" unicode="O" d="M468 210c0-1 0-1 0-2-12-51-38-92-77-124-38-32-84-47-136-47-28 0-55 5-81 15-26 11-49 26-69 45l-37-37c-4-3-8-5-13-5-5 0-9 2-13 5-4 4-5 8-5 13l0 128c0 5 1 9 5 13 4 4 8 5 13 5l128 0c5 0 9-1 13-5 3-4 5-8 5-13 0-5-2-9-5-13l-39-39c13-12 28-22 46-29 17-7 35-10 53-10 26 0 49 6 71 18 23 13 40 30 54 51 2 4 7 15 15 34 1 4 4 6 8 6l55 0c3 0 5 0 7-2 1-2 2-4 2-7z m7 229l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-5 0-9 1-13 5-3 4-5 8-5 13 0 5 2 9 5 13l40 39c-28 26-62 39-100 39-26 0-49-6-71-18-23-13-40-30-54-51-2-4-7-15-15-34-1-4-4-6-8-6l-57 0c-3 0-5 0-7 2-1 2-2 4-2 7l0 2c12 51 38 92 77 124 39 32 85 47 137 47 28 0 55-5 81-15 26-11 50-26 70-45l37 37c4 3 8 5 13 5 5 0 9-2 13-5 4-4 5-8 5-13z"/> | ||||
| <glyph glyph-name="plug" unicode="Q" d="M502 410l-1 0c-12 12-32 12-45 0l-22-23-46 46 23 22c13 13 13 33 0 45l0 1c-13 12-33 12-45 0l-24-24c-31 20-73 17-101-11l-12-12c-55-54-61-139-20-200l-2-2c-31-32-31-82 0-113 6-7 6-17 0-23-6-7-16-6-22 0l-45 44c-31 32-82 32-114 1-31-31-31-82 0-113l5-5c12-12 32-12 44 0l1 1c12 12 12 32 0 45l-4 4c-6 6-7 16-1 22 6 7 17 7 23 1l45-45c31-31 83-32 114 0 31 31 31 81 0 113-7 6-7 16 0 22l2 2c61-41 146-35 200 20l13 12c27 28 30 70 10 101l24 24c12 12 12 32 0 45z m-57-147c-19-19-49-19-68 0l-113 113c-19 19-19 49 0 68 15 15 37 18 55 9l-21-21c-13-12-13-32 0-45l0 0c12-12 32-12 45 0l23 23 45-45-23-23c-12-13-12-33 0-45l1 0c12-13 32-13 44 0l21 20c9-17 6-39-9-54z"/> | ||||
| <glyph glyph-name="wifi" unicode="R" d="M256 416c-80 0-156-30-214-84l-10-10 10-9 32-32 10-10 9 9c45 41 102 64 163 64 60 0 118-23 163-64l9-9 10 10 32 32 10 9-10 10c-58 54-134 84-214 84z m141-160c-38 35-88 54-141 54l-9 0 0 0c-49-2-96-21-132-54l-11-10 10-10 33-32 9-9 10 8c25 22 57 35 90 35 33 0 65-13 91-35l9-8 9 9 33 32 10 10z m-141-160l10 9 53 53 10 10-11 10c-16 11-33 20-62 20-29 0-45-10-61-20l-12-10 11-10 53-53z"/> | ||||
| <glyph glyph-name="sliders" unicode="P" d="M137 110l0-37-100 0 0 37z m101 36c5 0 9-2 13-5 3-4 5-8 5-13l0-73c0-5-2-9-5-13-4-4-8-5-13-5l-73 0c-5 0-10 1-13 5-4 4-6 8-6 13l0 73c0 5 2 9 6 13 3 3 8 5 13 5z m45 110l0-37-246 0 0 37z m-182 146l0-36-64 0 0 36z m374-292l0-37-210 0 0 37z m-274 329c5 0 9-2 13-6 4-3 5-7 5-12l0-74c0-5-1-9-5-12-4-4-8-6-13-6l-73 0c-5 0-9 2-13 6-3 3-5 7-5 12l0 74c0 5 2 9 5 12 4 4 8 6 13 6z m183-146c5 0 9-2 13-6 3-3 5-8 5-13l0-73c0-5-2-9-5-13-4-3-8-5-13-5l-73 0c-5 0-9 2-13 5-4 4-5 8-5 13l0 73c0 5 1 10 5 13 4 4 8 6 13 6z m91-37l0-37-64 0 0 37z m0 146l0-36-246 0 0 36z"/> | ||||
| <glyph glyph-name="folder-open" unicode="T" d="M501 241c0-5-3-11-8-18l-90-105c-7-9-18-17-32-23-14-7-26-10-38-10l-290 0c-6 0-12 1-16 4-5 2-8 6-8 11 0 6 3 12 9 18l89 105c8 10 19 17 32 24 14 6 27 9 39 9l290 0c6 0 11-1 16-3 5-3 7-7 7-12z m-91 92l0-43-222 0c-17 0-34-4-53-13-18-8-33-19-44-31l-89-106-2-2c0 1 0 2 0 4 0 1 0 2 0 3l0 256c0 16 6 30 18 42 11 12 25 18 42 18l85 0c16 0 30-6 42-18 12-12 18-26 18-42l0-8 145 0c16 0 30-6 42-18 12-12 18-26 18-42z"/> | ||||
| <glyph glyph-name="code-download" unicode="S" d="M331 228c6 6 6 17 0 23-7 7-17 7-24 0l-35-34 0 118c0 10-7 17-16 17-9 0-16-7-16-17l0-118-35 34c-6 7-17 7-24 0-6-6-6-17 0-23l63-63c0 0 0 0 0 0 1-1 2-2 3-2 0 0 0 0 0 0 0-1 1-1 1-1 0 0 0 0 0 0 1 0 1-1 2-1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1-1 3-1 4-1 2 0 3 0 4 1 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 1 2 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0z m-163-108c-6 0-12 2-17 7l-112 112c-9 9-9 25 0 34l112 112c9 9 25 9 34 0 9-9 9-25 0-34l-95-95 95-95c9-9 9-25 0-34-5-5-11-7-17-7z m176 0c6 0 12 2 17 7l112 112c9 9 9 25 0 34l-112 112c-9 9-25 9-34 0-9-9-9-25 0-34l95-95-95-95c-9-9-9-25 0-34 5-5 11-7 17-7z"/> | ||||
| </font></defs></svg> | ||||
| After Width: | Height: | Size: 21 KiB | 
							
								
								
									
										
											BIN
										
									
								
								data/www/marlinui.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/www/marlinui.ttf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/www/marlinui.woff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/www/marlinui.woff
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										7
									
								
								data/www/moment.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								data/www/moment.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										426
									
								
								data/www/webmarlin-class.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								data/www/webmarlin-class.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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 = '<li class="list-group-item console-list-items '+this.BgClass+'">'; | ||||
|     strout += '<span class="badge badge-light mr-1">'+this.FontIcon.ToHtml()+"</span>"; | ||||
|     strout += '<span class="badge badge-secondary mr-1">'+this.DateTime+'</span>'; | ||||
|     strout += '<span class="badge badge-'+(this.Direction === wmEnums.WSMsgDirection.SENT ? "danger" : "success")+' mr-1">'; | ||||
|     strout += this.Direction === wmEnums.WSMsgDirection.SENT ? wmSettings.SymbolSend : wmSettings.SymbolReceive; | ||||
|     strout += '</span>' + this.Text + '</li>'; | ||||
|     return strout; | ||||
|   } | ||||
|   ToSdFileList() { | ||||
|     if(this.SdFile !== "Begin file list" && this.SdFile !== "End file list") { | ||||
|       let a = this.SdFile.split(" "); | ||||
|       let strout = '<a href="javascript:void(0);" class="list-group-item list-group-item-action list-group-item-light p-1" data-sdfile="'+a[0]+'" onclick="WmButtons.SetSdSelected(this)">'; | ||||
|       strout += '<i class="icon icon-file mr-1"></i>'+a[0]+'<div class="badge badge-secondary float-right">'+wmTools.FileSizeFormat(a[1])+'</div>'; | ||||
|       strout += '</a>'; | ||||
|       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<gc.length; i++) { cs = cs ^ gc.charCodeAt(i); } | ||||
|     jsLog.Verbose("Calculate GCommand checksum of: "+gc+" => "+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 "<i class=\"icon icon-"+ this.ico + this.mClass+"\"></i>"; } | ||||
|   AddClass(acl) { return "<i class=\"icon icon-"+ this.ico + " "+ acl+"\"></i>"; } | ||||
| } | ||||
|  | ||||
| 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; i<spc.length; i++) { str = str.replace(spc[i],""); } | ||||
|     return str; | ||||
|   } | ||||
|   static FileDownload(fname, ftype, fdata){ | ||||
|     var blob = new Blob(fdata, {type: ftype}); | ||||
|     window.saveAs(blob, fname); | ||||
|   } | ||||
|   static FileSizeFormat(size) { | ||||
|     if(size>0) { | ||||
|       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, """); | ||||
|     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<carr.length; i++) { | ||||
|       while (carr[i].charAt(0)===' ') { carr[i] = carr[i].substring(1); } | ||||
|       if (carr[i].indexOf(cname)===0) { | ||||
|         let r = carr[i].substring(cname.length+1, carr[i].length); | ||||
|         jsLog.Verbose("Load cookie '"+cname+"' => "+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(); | ||||
							
								
								
									
										169
									
								
								data/www/webmarlin-font.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								data/www/webmarlin-font.css
									
									
									
									
									
										Normal file
									
								
							| @@ -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"; | ||||
| } | ||||
							
								
								
									
										45
									
								
								data/www/webmarlin.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								data/www/webmarlin.css
									
									
									
									
									
										Normal file
									
								
							| @@ -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; } | ||||
							
								
								
									
										872
									
								
								data/www/webmarlin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										872
									
								
								data/www/webmarlin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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: <span class=\"badge badge-light\">" + strcmd + "</span> " + 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("<span class=\"blink\">"+wmIcons.Exchange.AddClass('')+"</span>"); | ||||
|         ctrls.div.html("Connecting..."); | ||||
|         ctrls.btn.html("<span class=\"spinner-border spinner-border-sm\"></span>"); | ||||
|         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("<span class=\"blink\">"+wmIcons.Wifi.AddClass('')+"</span>"); | ||||
|         ctrls.div.html("Disconnecting..."); | ||||
|         ctrls.btn.html("<span class=\"spinner-border spinner-border-sm\"></span>"); | ||||
|         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: <span class=\"badge badge-light\">" + gcmd.val() + "</span> 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<lip.length; i++) { $(lip[i]).removeClass('list-group-item-success').addClass("list-group-item-light"); } | ||||
|     $(sdi).removeClass('list-group-item-light').addClass("list-group-item-success"); | ||||
|     WmControls.Enable(WmButtonGroups.FileActions); | ||||
|     if(!$('#div-sd-selected-file').hasClass("show")) { $('#div-sd-selected-file').collapse("show"); } | ||||
|     wmGCommands.SdFileSel.GParams = $(sdi).attr("data-sdfile"); | ||||
|     wmWebSoket.Send(wmGCommands.SdFileSel); | ||||
|   }, | ||||
|   ToggleChecksumDiv: function() { | ||||
|     let csdiv = $('#checksum-gcommand-div'); | ||||
|     if($('#btn-gcommand-checksum').hasClass('active')===true) { csdiv.collapse('hide'); } else { csdiv.collapse('show'); } | ||||
|   }, | ||||
|   UploadSdFile: function() { | ||||
|     WmControls.Disable(WmButtonGroups.FileManagement); | ||||
|     WmControls.Disable(WmButtonGroups.FileActions); | ||||
|     if (!window.FileReader) { | ||||
|         jsLog.Error('Your browser do not support JS file uploading'); | ||||
|         alert('Your browser do not support JS file uploading'); | ||||
|         WmControls.Enable(WmButtonGroups.FileManagement,WmButtonGroups.FileActions); | ||||
|     } else { | ||||
|       jsLog.Debug("Starting upload file process"); | ||||
|       if(WmUpload.Load()) { jsLog.Debug("Upload completed"); } | ||||
|       else { | ||||
|         jsLog.Error("Upload failed"); | ||||
|         WmControls.Enable(WmButtonGroups.FileManagement,WmButtonGroups.FileActions); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   WsConnect: function() { | ||||
|     if(wmWebSoket.WSObject === null) { wmWebSoket.Connect(); } | ||||
|     else { if(wmWebSoket.WSObject.readyState === wmEnums.WSSatuses.OPEN) { wmWebSoket.Disconnect(); } } | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| var WmControls = { | ||||
|   Enable: function() { | ||||
|     if(arguments.length > 0) { | ||||
|       for(let i=0; i<arguments.length; i++) { | ||||
|         let fld = arguments[i]; | ||||
|         for(let c=0; c<fld.length; c++) { WmControls.SetInputStatus(fld[c],'enabled'); } | ||||
|       } | ||||
|     } else { jsLog.Warning("WmControls.Enable: Missing input arguments"); } | ||||
|   }, | ||||
|   Disable: function() { | ||||
|     if(arguments.length > 0) { | ||||
|       for(let i=0; i<arguments.length; i++) { | ||||
|         let fld = arguments[i]; | ||||
|         for(let c=0; c<fld.length; c++) { WmControls.SetInputStatus(fld[c],'disabled'); } | ||||
|       } | ||||
|     } else { jsLog.Warning("WmControls.Disable: Missing input arguments"); } | ||||
|   }, | ||||
|   SetInputStatus(inid,st) { | ||||
|     if($(inid).attr("data-input-type")==="togglebtn"){ | ||||
|       if(st==="enabled") { $(inid).bootstrapToggle('enable'); } else { $(inid).bootstrapToggle('disable'); } | ||||
|     } else { | ||||
|       if(st==="enabled") { $(inid).prop("disabled", false); } else { $(inid).prop("disabled", true); } | ||||
|     } | ||||
|   }, | ||||
|   SetCheckStatus: function(ao,b) { | ||||
|     let cs="off"; | ||||
|     if(b) { cs="on"; } | ||||
|     for(let i=0; i<ao.length; i++) { $(ao[i]).bootstrapToggle(cs); } | ||||
|   }, | ||||
|   SetUpload: function() { | ||||
|     let f = $("#file-upload").val(); | ||||
|     jsLog.Debug("SetUploadFilename: Ready to upload file:"+f); | ||||
|     $("#file-upload-label").html(f.split("\\").pop()); | ||||
|     WmControls.Enable(WmButtonGroups.FileManagement); | ||||
|     WmControls.Disable(WmButtonGroups.FileProcess); | ||||
|   }, | ||||
|   ShowModalAlert: function(m) { | ||||
|     $('#div-alert-message').html(m); | ||||
|     $('#modal-alert').modal('show'); | ||||
|   }, | ||||
|   SetAutoTemp: function() { | ||||
|     if($('#set-auto-temp').prop('checked')) { | ||||
|       wmGCommands.SetTempOn.GParams = "S"+$('#auto-temp-interval').val(); | ||||
|       wmWebSoket.Send(wmGCommands.SetTempOn); | ||||
|     } else { wmWebSoket.Send(wmGCommands.SetTempOff); } | ||||
|   }, | ||||
|   SetFanSpeed: function(rv) { | ||||
|     rv = parseInt(rv); | ||||
|     jsLog.Debug("Set fan speed to: "+rv+"%"); | ||||
|     let fsv = wmTools.FormatNumber(wmTools.GetNumPercent(rv,255),0); | ||||
|     $('#div-fan-speed-current').html(rv+"%<span class='badge badge-success ml-1'>"+fsv+"</span>"); | ||||
|     $('#div-fan-speed-set').html(rv+"%<span class='badge badge-success ml-1'>"+fsv+"</span>"); | ||||
|     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<wmLogBuffer.length; i++) { fdt.push(wmLogBuffer[i].ToCsv()+"\n"); } | ||||
|     wmTools.FileDownload("e4dbox_log.csv", "text/csv;charset=utf-8", fdt); | ||||
|   }, | ||||
|   SetMessageSymbol: function() { | ||||
|     if($('#set-log-symbol').val()==="icon") { | ||||
|       jsLog.Verbose("Set message symbol icon collapse panel to 'show'",this); | ||||
|       WmConsole.SetSymbolIcon(); | ||||
|       $('#div-log-symbol-icon').collapse('show'); | ||||
|     } else { | ||||
|       jsLog.Verbose("Set message symbol icon collapse panel to 'hide'",this); | ||||
|       $('#div-log-symbol-icon').collapse('hide'); | ||||
|     } | ||||
|   }, | ||||
|   SetSymbolIcon: function() { | ||||
|     let ctrl = parseInt($('#set-log-symbol-icon').val()); | ||||
|     let hc = {s:null, r:null}; | ||||
|     jsLog.Verbose("Set settings symbol sample fields ("+ctrl+")"); | ||||
|     if(ctrl===0) { hc.s = wmIcons.ChevronUp.ToHtml(); hc.r = wmIcons.ChevronDown.ToHtml(); } | ||||
|     else if(ctrl===1) { hc.s = wmIcons.LongArrowUp.ToHtml(); hc.r = wmIcons.LongArrowDown.ToHtml(); } | ||||
|     else if(ctrl===2) { hc.s = wmIcons.ChevronLeft.ToHtml(); hc.r = wmIcons.ChevronRight.ToHtml(); } | ||||
|     else if(ctrl===3) { hc.s = wmIcons.LongArrowLeft.ToHtml(); hc.r = wmIcons.LongArrowRight.ToHtml(); } | ||||
|     $('#div-log-symbol-icon-sample-s').html(hc.s); | ||||
|     $('#div-log-symbol-icon-sample-r').html(hc.r); | ||||
|   }, | ||||
|   Trace: function(litem) { | ||||
|     wmLogBuffer.push(litem); | ||||
|     let clist = $('#gcommand-console-list'); | ||||
|     if (wmSettings.ConsoleDirection === wmEnums.ConsoleDirection.APPEND) { clist.append(litem.ToLoglist()); } else { clist.prepend(litem.ToLoglist()); } | ||||
|     $('#log-counter-badge').text(wmLogBuffer.length); | ||||
|   }, | ||||
|   TraceSdFile: function(litem) { | ||||
|     if(litem.SdFile === "Begin file list") { wmSdListCounter.Reset(); } | ||||
|     if(litem.SdFile !== "Begin file list" && litem.SdFile !== "End file list") { | ||||
|       wmSdListCounter.FILES++; | ||||
|       if(litem.SdFile.indexOf("/")>-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 = "<button type=\"button\" class=\"list-group-item list-group-item-action p-1\" onclick=\"WmButtons.GCommandSetPreset('"+wmGCommands[key].GCode+" "+gp+"')\">"; | ||||
|           lib += "<span class=\"h5\"><span class=\"badge badge-success mr-1\" style=\"width:100px;\">"+wmGCommands[key].GCode+" "+gp+"</span></span>"; | ||||
|           lib += wmGCommands[key].Description+"</button>"; | ||||
|           $('#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()); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user