Merge branch 'gcodeViewer' into devel

Conflicts:
	octoprint/server.py
	octoprint/settings.py
	octoprint/static/js/ui.js
master
Gina Häußge 2013-02-03 21:38:00 +01:00
commit ea52bbfb14
38 changed files with 43499 additions and 4 deletions

View File

@ -30,7 +30,8 @@ def index():
return render_template(
"index.html",
webcamStream=settings().get("webcam", "stream"),
enableTimelapse=(settings().get("webcam", "snapshot") is not None and settings().get("webcam", "ffmpeg") is not None)
enableTimelapse=(settings().get("webcam", "snapshot") is not None and settings().get("webcam", "ffmpeg") is not None),
enableGCodeVisualizer=settings().get("feature", "gCodeVisualizer")
)
#~~ Printer state
@ -231,6 +232,10 @@ def getCustomControls():
def readGcodeFiles():
return jsonify(files=gcodeManager.getAllFileData())
@app.route("/gcodefile/<path:filename>", methods=["GET"])
def readGcodeFile(filename):
return send_from_directory(UPLOAD_FOLDER, filename, as_attachment=True)
@app.route(BASEURL + "gcodefiles/upload", methods=["POST"])
def uploadGcodeFile():
if "gcode_file" in request.files.keys():

View File

@ -39,6 +39,7 @@ old_default_settings = {
"timelapse_tmp": None
},
"feature": {
"gCodeVisualizer": True
},
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

View File

@ -0,0 +1,458 @@
/*! jQuery UI - v1.9.0 - 2012-10-21
* http://jqueryui.com
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande%2CLucida%20Sans%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=deedf7&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=100&borderColorHeader=aed0ea&fcHeader=222222&iconColorHeader=72a7cf&bgColorContent=f2f5f7&bgTextureContent=04_highlight_hard.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=362b36&iconColorContent=72a7cf&bgColorDefault=d7ebf9&bgTextureDefault=02_glass.png&bgImgOpacityDefault=80&borderColorDefault=aed0ea&fcDefault=2779aa&iconColorDefault=3d80b3&bgColorHover=e4f1fb&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=74b2e2&fcHover=0070a3&iconColorHover=2694e8&bgColorActive=3baae3&bgTextureActive=02_glass.png&bgImgOpacityActive=50&borderColorActive=2694e8&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=ffef8f&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=25&borderColorHighlight=f9dd34&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=cd0a0a&bgTextureError=01_flat.png&bgImgOpacityError=15&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffffff&bgColorOverlay=eeeeee&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=90&opacityOverlay=80&bgColorShadow=000000&bgTextureShadow=04_highlight_hard.png&bgImgOpacityShadow=70&opacityShadow=30&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px
* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }
.ui-autocomplete { position: absolute; cursor: default; }
/* workarounds */
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
.ui-button-icons-only { width: 3.4em; }
button.ui-button-icons-only { width: 3.7em; }
/*button text element */
.ui-button .ui-button-text { display: block; line-height: 1.4; }
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
/* no icon support for input elements, provide padding by default */
input.ui-button { padding: .4em 1em; }
/*button icon element(s) */
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
/*button sets*/
.ui-buttonset { margin-right: 7px; }
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
/* workarounds */
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
position: absolute; /*must have*/
z-index: -1; /*must have*/
filter: mask(); /*must have*/
top: -4px; /*must have*/
left: -4px; /*must have*/
width: 200px; /*must have*/
height: 200px; /*must have*/
}.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }
.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
.ui-menu .ui-state-disabled a { cursor: default; }
/* icon support */
.ui-menu-icons { position: relative; }
.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
/* left-aligned */
.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }
/* right-aligned */
.ui-menu .ui-menu-icon { position: static; float: right; }
.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.ui-slider { position: relative; text-align: left; }
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
.ui-slider-horizontal { height: .8em; }
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
.ui-slider-vertical { width: .8em; height: 100px; }
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
.ui-slider-vertical .ui-slider-range-max { top: 0; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
.ui-spinner-up { top: 0; }
.ui-spinner-down { bottom: 0; }
/* TR overrides */
span.ui-spinner { background: none; }
.ui-spinner .ui-icon-triangle-1-s {
/* need to fix icons sprite */
background-position:-65px -16px;
}
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
.ui-tooltip {
padding:8px;
position:absolute;
z-index:9999;
-o-box-shadow: 0 0 5px #aaa;
-moz-box-shadow: 0 0 5px #aaa;
-webkit-box-shadow: 0 0 5px #aaa;
box-shadow: 0 0 5px #aaa;
}
/* Fades and background-images don't work well together in IE6, drop the image */
* html .ui-tooltip {
background-image: none;
}
body .ui-tooltip { border-width:2px; }
/* Component containers
----------------------------------*/
.ui-widget { font-family: Lucida Grande,Lucida Sans,Arial,sans-serif; font-size: 1em; }
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande,Lucida Sans,Arial,sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #dddddd; background: #f2f5f7 url(images/ui-bg_highlight-hard_100_f2f5f7_1x100.png) 50% top repeat-x; color: #362b36; }
.ui-widget-content a { color: #362b36; }
.ui-widget-header { border: 1px solid #aed0ea; background: #deedf7 url(images/ui-bg_highlight-soft_100_deedf7_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
.ui-widget-header a { color: #222222; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #aed0ea; background: #d7ebf9 url(images/ui-bg_glass_80_d7ebf9_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2779aa; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2779aa; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #74b2e2; background: #e4f1fb url(images/ui-bg_glass_100_e4f1fb_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #0070a3; }
.ui-state-hover a, .ui-state-hover a:hover { color: #0070a3; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #2694e8; background: #3baae3 url(images/ui-bg_glass_50_3baae3_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #f9dd34; background: #ffef8f url(images/ui-bg_highlight-soft_25_ffef8f_1x100.png) 50% top repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #cd0a0a url(images/ui-bg_flat_15_cd0a0a_40x100.png) 50% 50% repeat-x; color: #ffffff; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_72a7cf_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_72a7cf_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_72a7cf_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_3d80b3_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_2694e8_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -khtml-border-top-left-radius: 6px; border-top-left-radius: 6px; }
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -khtml-border-top-right-radius: 6px; border-top-right-radius: 6px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -khtml-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; -khtml-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
/* Overlays */
.ui-widget-overlay { background: #eeeeee url(images/ui-bg_diagonals-thick_90_eeeeee_40x40.png) 50% 50% repeat; opacity: .8;filter:Alpha(Opacity=80); }
.ui-widget-shadow { margin: -7px 0 0 -7px; padding: 7px; background: #000000 url(images/ui-bg_highlight-hard_70_000000_1x100.png) 50% top repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,161 @@
/*body,*/
/*#wrap {*/
/*width:1000px;*/
/*height: 680px;*/
/*position: absolute;*/
/*top: 50%;*/
/*margin-top: -350px;*/
/*left: 50%;*/
/*margin-left: -500px;*/
/**/
/*background:#ffffff;*/
/*border: 5px outset #bbb;*/
/*-moz-border-radius: 5px;*/
/*-webkit-border-radius: 5px;*/
/*border-radius: 5px;*/
/*}*/
/*#control {*/
/*float:left;*/
/*width:300px;*/
/*margin-top: 10px;*/
/*margin-left: 10px;*/
/*background:#ffffff;*/
/*margin-right: 10px;*/
/*height: 680px;*/
/*}*/
#file_block {
/*margin-top: 20px;*/
/*margin-left: 20px;*/
}
#control_bottom {
position: absolute;
bottom: 0;
width: 300px;
margin-bottom: 10px;
}
#options{
float: left;
margin-left: 5px;
margin-bottom: 5px;
}
#gcode {
background: #ffffff;
float:right;
width: 680px;
height: 680px;
border-width: 2px;
border-style: none none none solid;
}
#canvas{
/*float: left;*/
clear:none;
}
#drop_zone {
border: 2px dashed #bbb;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
padding: 40px;
margin: 5px;
text-align: center;
font: 20pt bold;
color: #bbb
}
#slider-vertical {
/*position: absolute;*/
/*right: 0;*/
/*top: 0;*/
height: 580px;
width: 10px;
float: right;
}
#slider-horizontal {
height: 10px;
width: 570px;
/*position: absolute;*/
/*bottom: 0;*/
}
#main_button_block {
/*float: right;*/
margin-bottom: 5px;
margin-right: 5px;
}
.mbut{
height:60px;
width: 250px;
font-size: 1em;
}
#tabs-min {
height: 680px;
padding: 0px;
}
.mtab{
background: transparent;
border: none;
font-weight: normal;
font-size: 0.5em;
}
.mtab-defstate{
background: transparent;
border: none;
}
.mtab-content{
background: #ffffff;
background-image: none;
border: 0px none #dddddd;
border-bottom-style: none;
margin: 0px;
}
.bar {
-webkit-transition: width 0s linear !important;
-moz-transition: width 0s linear !important;
-o-transition: width 0s linear !important;
transition: width 0s linear !important;
}
.nav {
margin-bottom: 0px !important;
}
.tab-content {
overflow: visible;
}
.aboutpage {
margin: 10px;
}
#accordion_top .ui-accordion-content{
padding: 5px;
}
#tabs-min .ui-tabs-panel {
padding: 0px;
}
#progressBlock {
margin-left: 10px;
margin-right: 10px;
margin-bottom: 10px;
}
.colorBox {
width: 50px;
height: 15px;
border: 1px solid #000000;
float:left;
}
.activeline {background: #fff0b6 !important;}

View File

@ -0,0 +1,502 @@
/**
* User: hudbrog (hudbrog@gmail.com)
* Date: 10/24/12
* Time: 12:18 PM
*/
var gcode;
var firstReport;
var z_heights = {};
var model = [];
var gCodeOptions = {
sortLayers: false,
purgeEmptyLayers: true,
analyzeModel: false
};
var max = {x: undefined, y: undefined, z: undefined};
var min = {x: undefined, y: undefined, z: undefined};
var modelSize = {x: undefined, y: undefined, z: undefined};
var filamentByLayer = {};
var totalFilament=0;
var printTime=0;
var printTimeByLayer = {};
var layerHeight=0;
var layerCnt = 0;
var speeds = {extrude: [], retract: [], move: []};
var speedsByLayer = {extrude: {}, retract: {}, move: {}};
var sendLayerToParent = function(layerNum, z, progress){
self.postMessage({
"cmd": "returnLayer",
"msg": {
cmds: model[layerNum],
layerNum: layerNum,
zHeightObject: {zValue: z, layer: z_heights[z]},
isEmpty: false,
progress: progress
}
});
};
var sendMultiLayerToParent = function(layerNum, z, progress){
var tmpModel = [];
var tmpZHeight = {};
for(var i=0;i<layerNum.length;i++){
tmpModel[layerNum[i]] = model[layerNum[i]];
tmpZHeight[layerNum[i]] = z_heights[z[i]];
}
self.postMessage({
"cmd": "returnMultiLayer",
"msg": {
model: tmpModel,
layerNum: layerNum,
zHeightObject: {zValue: z, layer: tmpZHeight},
isEmpty: false,
progress: progress
}
});
};
var sendSizeProgress = function(progress){
self.postMessage({
"cmd": "analyzeProgress",
"msg": {
progress: progress,
printTime: printTime
}
});
};
var sendAnalyzeDone = function(){
self.postMessage({
"cmd": "analyzeDone",
"msg": {
max: max,
min: min,
modelSize: modelSize,
totalFilament:totalFilament,
filamentByLayer: filamentByLayer,
printTime: printTime,
layerHeight: layerHeight,
layerCnt: layerCnt,
layerTotal: model.length,
speeds: speeds,
speedsByLayer: speedsByLayer,
printTimeByLayer: printTimeByLayer
}
});
};
var purgeLayers = function(){
var purge=true;
for(var i=0;i<model.length;i++){
purge=true;
if(!model[i])purge=true;
else {
for(var j=0;j<model[i].length;j++){
if(model[i][j].extrude)purge=false;
}
}
if(!purge){
layerCnt+=1;
}
}
// self.postMessage('LayerCnt: ' + layerCnt);
};
var analyzeModel = function(){
var i,j;
var x_ok=false, y_ok=false;
var cmds;
var tmp1= 0, tmp2=0;
var speedIndex=0;
var type;
var printTimeAdd=0;
// var moveTime=0;
for(i=0;i<model.length;i++){
cmds = model[i];
if(!cmds)continue;
for(j=0;j<cmds.length;j++){
x_ok=false;
y_ok=false;
if(typeof(cmds[j].x) !== 'undefined'&&typeof(cmds[j].prevX) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].x))
{
max.x = parseFloat(max.x)>parseFloat(cmds[j].x)?parseFloat(max.x):parseFloat(cmds[j].x);
max.x = parseFloat(max.x)>parseFloat(cmds[j].prevX)?parseFloat(max.x):parseFloat(cmds[j].prevX);
min.x = parseFloat(min.x)<parseFloat(cmds[j].x)?parseFloat(min.x):parseFloat(cmds[j].x);
min.x = parseFloat(min.x)<parseFloat(cmds[j].prevX)?parseFloat(min.x):parseFloat(cmds[j].prevX);
x_ok=true;
}
if(typeof(cmds[j].y) !== 'undefined'&&typeof(cmds[j].prevY) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].y)){
max.y = parseFloat(max.y)>parseFloat(cmds[j].y)?parseFloat(max.y):parseFloat(cmds[j].y);
max.y = parseFloat(max.y)>parseFloat(cmds[j].prevY)?parseFloat(max.y):parseFloat(cmds[j].prevY);
min.y = parseFloat(min.y)<parseFloat(cmds[j].y)?parseFloat(min.y):parseFloat(cmds[j].y);
min.y = parseFloat(min.y)<parseFloat(cmds[j].prevY)?parseFloat(min.y):parseFloat(cmds[j].prevY);
y_ok=true;
}
if(typeof(cmds[j].prevZ) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].prevZ)){
max.z = parseFloat(max.z)>parseFloat(cmds[j].prevZ)?parseFloat(max.z):parseFloat(cmds[j].prevZ);
min.z = parseFloat(min.z)<parseFloat(cmds[j].prevZ)?parseFloat(min.z):parseFloat(cmds[j].prevZ);
}
if(typeof(cmds[j].extrude) !== 'undefined'||cmds[j].retract!=0){
totalFilament+=cmds[j].extrusion;
if(!filamentByLayer[cmds[j].prevZ])filamentByLayer[cmds[j].prevZ]=0;
filamentByLayer[cmds[j].prevZ]+=cmds[j].extrusion;
}
if(x_ok&&y_ok){
printTimeAdd = Math.sqrt(Math.pow(parseFloat(cmds[j].x)-parseFloat(cmds[j].prevX),2)+Math.pow(parseFloat(cmds[j].y)-parseFloat(cmds[j].prevY),2))/(cmds[j].speed/60);
}else if(cmds[j].retract===0&&cmds[j].extrusion!==0){
tmp1 = Math.sqrt(Math.pow(parseFloat(cmds[j].x)-parseFloat(cmds[j].prevX),2)+Math.pow(parseFloat(cmds[j].y)-parseFloat(cmds[j].prevY),2))/(cmds[j].speed/60);
tmp2 = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
printTimeAdd = tmp1>=tmp2?tmp1:tmp2;
}else if(cmds[j].retract!==0){
printTimeAdd = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
}
printTime += printTimeAdd;
if(typeof(printTimeByLayer[cmds[j].prevZ])==='undefined'){printTimeByLayer[cmds[j].prevZ]=0;}
printTimeByLayer[cmds[j].prevZ] += printTimeAdd;
if(cmds[j].extrude&&cmds[j].retract===0){
type = 'extrude';
}else if(cmds[j].retract!==0){
type = 'retract';
}else if(!cmds[j].extrude&&cmds[j].retract===0){
type = 'move';
// if(cmds[j].prevZ == '17.1'){
// self.postMessage({cmd: 'Got speed ' + cmds[j].speed + 'with line ' + cmds[j].gcodeLine});
// }
}else {
self.postMessage({cmd: 'unknown type of move'});
type = 'unknown';
}
speedIndex = speeds[type].indexOf(cmds[j].speed);
if (speedIndex === -1) {
speeds[type].push(cmds[j].speed);
speedIndex = speeds[type].indexOf(cmds[j].speed);
}
if(typeof(speedsByLayer[type][cmds[j].prevZ]) === 'undefined'){
speedsByLayer[type][cmds[j].prevZ] = [];
}
if(speedsByLayer[type][cmds[j].prevZ].indexOf(cmds[j].speed) === -1){
speedsByLayer[type][cmds[j].prevZ][speedIndex] = cmds[j].speed;
}
}
sendSizeProgress(i/model.length*100);
}
purgeLayers();
modelSize.x = Math.abs(max.x - min.x);
modelSize.y = Math.abs(max.y - min.y);
modelSize.z = Math.abs(max.z - min.z);
layerHeight = (max.z-min.z)/(layerCnt-1);
sendAnalyzeDone();
};
var doParse = function(){
var argChar, numSlice;
model=[];
var sendLayer = undefined;
var sendLayerZ = 0;
var sendMultiLayer = [];
var sendMultiLayerZ = [];
var lastSend = 0;
// console.time("parseGCode timer");
var reg = new RegExp(/^(?:G0|G1)\s/i);
var comment = new RegExp()
var j, layer= 0, extrude=false, prevRetract= 0, retract=0, x, y, z=0, f, prevZ=0, prevX, prevY,lastF=4000, prev_extrude = {a: undefined, b: undefined, c: undefined, e: undefined, abs: undefined}, extrudeRelative=false;
var dcExtrude=false;
var assumeNonDC = false;
for(var i=0;i<gcode.length;i++){
// for(var len = gcode.length- 1, i=0;i!=len;i++){
x=undefined;
y=undefined;
z=undefined;
retract = 0;
extrude=false;
gcode[i] = gcode[i].split(/[\(;]/)[0];
// prevRetract=0;
// retract=0;
// if(gcode[i].match(/^(?:G0|G1)\s+/i)){
if(reg.test(gcode[i])){
var args = gcode[i].split(/\s/);
for(j=0;j<args.length;j++){
// console.log(args);
// if(!args[j])continue;
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
// if(x === prevX){
// x=undefined;
// }
break;
case 'y':
y=args[j].slice(1);
// if(y===prevY){
// y=undefined;
// }
break;
case 'z':
z=args[j].slice(1);
z = Number(z);
if(z == prevZ)continue;
// z = Number(z);
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
}
sendLayer = layer;
sendLayerZ = z;
// if(parseFloat(prevZ) < )
// if(args[j].charAt(1) === "-")layer--;
// else layer++;
prevZ = z;
break;
case 'e':
case 'a':
case 'b':
case 'c':
assumeNonDC = true;
numSlice = parseFloat(args[j].slice(1)).toFixed(3);
if(!extrudeRelative){
// absolute extrusion positioning
prev_extrude["abs"] = parseFloat(numSlice)-parseFloat(prev_extrude[argChar]);
}else{
prev_extrude["abs"] = parseFloat(numSlice);
}
extrude = prev_extrude["abs"]>0;
if(prev_extrude["abs"]<0){
prevRetract = -1;
retract = -1;
}
else if(prev_extrude["abs"]==0){
// if(prevRetract <0 )prevRetract=retract;
retract = 0;
}else if(prev_extrude["abs"]>0&&prevRetract < 0){
prevRetract = 0;
retract = 1;
} else {
// prevRetract = retract;
retract = 0;
}
prev_extrude[argChar] = numSlice;
break;
case 'f':
numSlice = args[j].slice(1);
lastF = numSlice;
break;
default:
break;
}
}
if(dcExtrude&&!assumeNonDC){
extrude = true;
prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y));
}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i)};
//{x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i};
if(typeof(x) !== 'undefined') prevX = x;
if(typeof(y) !== 'undefined') prevY = y;
} else if(gcode[i].match(/^(?:M82)/i)){
extrudeRelative = false;
}else if(gcode[i].match(/^(?:G91)/i)){
extrudeRelative=true;
}else if(gcode[i].match(/^(?:G90)/i)){
extrudeRelative=false;
}else if(gcode[i].match(/^(?:M83)/i)){
extrudeRelative=true;
}else if(gcode[i].match(/^(?:M101)/i)){
dcExtrude=true;
}else if(gcode[i].match(/^(?:M103)/i)){
dcExtrude=false;
}else if(gcode[i].match(/^(?:G92)/i)){
var args = gcode[i].split(/\s/);
for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
break;
case 'y':
y=args[j].slice(1);
break;
case 'z':
z=args[j].slice(1);
prevZ = z;
break;
case 'e'||'a'||'b'||'c':
numSlice = args[j].slice(1);
if(!extrudeRelative)
prev_extrude[argChar] = 0;
else {
prev_extrude[argChar] = numSlice;
}
// prevZ = z;
break;
default:
break;
}
}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: parseFloat(x), y: parseFloat(y), z: parseFloat(z), extrude: extrude, retract: parseFloat(retract), noMove: true, extrusion: (extrude||retract)?parseFloat(prev_extrude["abs"]):0, prevX: parseFloat(prevX), prevY: parseFloat(prevY), prevZ: parseFloat(prevZ), speed: parseFloat(lastF),gcodeLine: parseFloat(i)};
}else if(gcode[i].match(/^(?:G28)/i)){
var args = gcode[i].split(/\s/);
for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
break;
case 'y':
y=args[j].slice(1);
break;
case 'z':
z=args[j].slice(1);
z = Number(z);
if(z === prevZ)continue;
sendLayer = layer;
sendLayerZ = z;//}
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
}
prevZ = z;
break;
default:
break;
}
}
// G28 with no arguments
if(args.length == 1){
//need to init values to default here
}
// if it's the first layer and G28 was without
if(layer==0&&typeof(z) === 'undefined'){
z=0;
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
}
prevZ = z;
}
// x=0, y=0,z=0,prevZ=0, extrude=false;
// if(typeof(prevX) === 'undefined'){prevX=0;}
// if(typeof(prevY) === 'undefined'){prevY=0;}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i)};
// if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: x, y: y, z: z, extrude: extrude, retract: retract, noMove:false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: parseFloat(i)};
}
if(typeof(sendLayer) !== "undefined"){
// sendLayerToParent(sendLayer, sendLayerZ, i/gcode.length*100);
// sendLayer = undefined;
if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){
lastSend = i;
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
sendMultiLayer = [];
sendMultiLayerZ = [];
}
sendMultiLayer[sendMultiLayer.length] = sendLayer;
sendMultiLayerZ[sendMultiLayerZ.length] = sendLayerZ;
sendLayer = undefined;
sendLayerZ = undefined;
}
}
// sendMultiLayer[sendMultiLayer.length] = layer;
// sendMultiLayerZ[sendMultiLayerZ.length] = z;
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
// if(gCodeOptions["sortLayers"])sortLayers();
// if(gCodeOptions["purgeEmptyLayers"])purgeLayers();
};
var parseGCode = function(message){
gcode = message.gcode;
firstReport = message.options.firstReport;
doParse();
gcode = [];
self.postMessage({
"cmd": "returnModel",
"msg": {
// model: model
}
});
};
var runAnalyze = function(message){
analyzeModel();
model = [];
z_heights = [];
gcode = undefined;
firstReport = undefined;
z_heights = {};
model = [];
max = {x: undefined, y: undefined, z: undefined};
min = {x: undefined, y: undefined, z: undefined};
modelSize = {x: undefined, y: undefined, z: undefined};
filamentByLayer = {};
totalFilament=0;
printTime=0;
printTimeByLayer = {};
layerHeight=0;
layerCnt = 0;
speeds = {extrude: [], retract: [], move: []};
speedsByLayer = {extrude: {}, retract: {}, move: {}};
};
var setOption = function(options){
for(var opt in options){
gCodeOptions[opt] = options[opt];
}
};
onmessage = function (e){
var data = e.data;
// for some reason firefox doesn't garbage collect when something inside closures is deleted, so we delete and recreate whole object eaech time
switch (data.cmd) {
case 'parseGCode':
parseGCode(data.msg);
break;
case 'setOption':
setOption(data.msg);
break;
case 'analyzeModel':
runAnalyze(data.msg);
break;
default:
self.postMessage('Unknown command: ' + data.msg);
}
};

View File

@ -0,0 +1,197 @@
/**
* User: hudbrog (hudbrog@gmail.com)
* Date: 10/21/12
* Time: 7:31 AM
*/
GCODE.gCodeReader = (function(){
// ***** PRIVATE ******
var gcode, lines;
var z_heights = {};
var model = [];
var max = {x: undefined, y: undefined, z: undefined};
var min = {x: undefined, y: undefined, z: undefined};
var modelSize = {x: undefined, y: undefined, z: undefined};
var filamentByLayer = {};
var printTimeByLayer;
var totalFilament=0;
var printTime=0;
var speeds = {};
var speedsByLayer = {};
var gCodeOptions = {
sortLayers: false,
purgeEmptyLayers: true,
analyzeModel: false
};
var linesCmdIndex = {};
var prepareGCode = function(){
if(!lines)return;
gcode = [];
var i, tmp;
for(i=0;i<lines.length;i++){
// if(lines[i].match(/^(G0|G1|G90|G91|G92|M82|M83|G28)/i))gcode.push(lines[i]);
tmp = lines[i].indexOf(";");
if(tmp > 1 || tmp === -1) {
gcode.push(lines[i]);
}
}
lines = [];
// console.log("GCode prepared");
};
var sortLayers = function(){
var sortedZ = [];
var tmpModel = [];
// var cnt = 0;
// console.log(z_heights);
for(var layer in z_heights){
sortedZ[z_heights[layer]] = layer;
// cnt++;
}
// console.log("cnt is " + cnt);
sortedZ.sort(function(a,b){
return a-b;
});
// console.log(sortedZ);
// console.log(model.length);
for(var i=0;i<sortedZ.length;i++){
// console.log("i is " + i +" and sortedZ[i] is " + sortedZ[i] + "and z_heights[] is " + z_heights[sortedZ[i]] );
if(typeof(z_heights[sortedZ[i]]) === 'undefined')continue;
tmpModel[i] = model[z_heights[sortedZ[i]]];
}
model = tmpModel;
// console.log(model.length);
delete tmpModel;
};
var prepareLinesIndex = function(){
linesCmdIndex = {};
for (var l in model){
for (var i=0; i< model[l].length; i++){
linesCmdIndex[model[l][i].gcodeLine] = {layer: l, cmd: i};
}
}
}
var purgeLayers = function(){
var purge=true;
if(!model){
console.log("Something terribly wring just happened.");
return;
}
for(var i=0;i<model.length;i++){
purge=true;
if(typeof(model[i])==='undefined')purge=true;
else {
for(var j=0;j<model[i].length;j++){
if(model[i][j].extrude)purge=false;
}
}
if(purge){
model.splice(i,1);
i--;
}
}
};
// ***** PUBLIC *******
return {
loadFile: function(reader){
// console.log("loadFile");
model = [];
z_heights = [];
lines = reader.target.result.split(/\n/);
reader.target.result = null;
prepareGCode();
worker.postMessage({
"cmd":"parseGCode",
"msg":{
gcode: gcode,
options: {
firstReport: 5
}
}
}
);
delete lines;
delete gcode;
},
setOption: function(options){
for(var opt in options){
gCodeOptions[opt] = options[opt];
}
},
passDataToRenderer: function(){
// console.log(model);
if(gCodeOptions["sortLayers"])sortLayers();
// console.log(model);
if(gCodeOptions["purgeEmptyLayers"])purgeLayers();
prepareLinesIndex();
// console.log(model);
GCODE.renderer.doRender(model, 0);
// GCODE.renderer3d.setModel(model);
},
processLayerFromWorker: function(msg){
// var cmds = msg.cmds;
// var layerNum = msg.layerNum;
// var zHeightObject = msg.zHeightObject;
// var isEmpty = msg.isEmpty;
// console.log(zHeightObject);
model[msg.layerNum] = msg.cmds;
z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer;
// GCODE.renderer.doRender(model, msg.layerNum);
},
processMultiLayerFromWorker: function(msg){
for(var i=0;i<msg.layerNum.length;i++){
model[msg.layerNum[i]] = msg.model[msg.layerNum[i]];
z_heights[msg.zHeightObject.zValue[i]] = msg.layerNum[i];
}
// console.log(model);
},
processAnalyzeModelDone: function(msg){
min = msg.min;
max = msg.max;
modelSize = msg.modelSize;
totalFilament = msg.totalFilament;
filamentByLayer = msg.filamentByLayer;
speeds = msg.speeds;
speedsByLayer = msg.speedsByLayer;
printTime = msg.printTime;
printTimeByLayer = msg.printTimeByLayer;
},
getLayerFilament: function(z){
return filamentByLayer[z];
},
getLayerSpeeds: function(z){
return speedsByLayer[z]?speedsByLayer[z]:{};
},
getModelInfo: function(){
return {
min: min,
max: max,
modelSize: modelSize,
totalFilament: totalFilament,
speeds: speeds,
speedsByLayer: speedsByLayer,
printTime: printTime,
printTimeByLayer: printTimeByLayer
};
},
getGCodeLines: function(layer, fromSegments, toSegments){
var i=0;
var result = {first: model[layer][fromSegments].gcodeLine, last: model[layer][toSegments].gcodeLine};
return result;
},
getLinesCmdIndex: function(line){
return linesCmdIndex[line];
}
}
}());

View File

@ -0,0 +1,417 @@
/**
* User: hudbrog (hudbrog@gmail.com)
* Date: 10/20/12
* Time: 1:36 PM
* To change this template use File | Settings | File Templates.
*/
GCODE.renderer = (function(){
// ***** PRIVATE ******
var canvas;
var ctx;
var zoomFactor= 2.8, zoomFactorDelta = 0.4;
var gridSizeX=200,gridSizeY=200,gridStep=10;
var ctxHeight, ctxWidth;
var prevX=0, prevY=0;
// var colorGrid="#bbbbbb", colorLine="#000000";
var sliderHor, sliderVer;
var layerNumStore, progressStore={from: 0, to: -1};
var lastX, lastY;
var dragStart,dragged;
var scaleFactor = 1.1;
var model;
var initialized=false;
var renderOptions = {
showMoves: true,
showRetracts: true,
colorGrid: "#bbbbbb",
extrusionWidth: 1,
// colorLine: ["#000000", "#aabb88", "#ffe7a0", "#6e7700", "#331a00", "#44ba97", "#08262f", "#db0e00", "#ff9977"],
colorLine: ["#000000", "#45c7ba", "#a9533a", "#ff44cc", "#dd1177", "#eeee22", "#ffbb55", "#ff5511", "#777788"],
colorMove: "#00ff00",
colorRetract: "#ff0000",
colorRestart: "#0000ff",
sizeRetractSpot: 2,
modelCenter: {x: 0, y: 0},
moveModel: true,
differentiateColors: true,
showNextLayer: false
};
var offsetModelX=0, offsetModelY=0;
var speeds = [];
var speedsByLayer = {};
var reRender = function(){
var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
drawGrid();
if(renderOptions['showNextLayer'] && layerNumStore < model.length - 1) {
drawLayer(layerNumStore+1, 0, GCODE.renderer.getLayerNumSegments(layerNumStore+1), true);
}
drawLayer(layerNumStore, progressStore.from, progressStore.to);
};
function trackTransforms(ctx){
var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
var xform = svg.createSVGMatrix();
ctx.getTransform = function(){ return xform; };
var savedTransforms = [];
var save = ctx.save;
ctx.save = function(){
savedTransforms.push(xform.translate(0,0));
return save.call(ctx);
};
var restore = ctx.restore;
ctx.restore = function(){
xform = savedTransforms.pop();
return restore.call(ctx);
};
var scale = ctx.scale;
ctx.scale = function(sx,sy){
xform = xform.scaleNonUniform(sx,sy);
return scale.call(ctx,sx,sy);
};
var rotate = ctx.rotate;
ctx.rotate = function(radians){
xform = xform.rotate(radians*180/Math.PI);
return rotate.call(ctx,radians);
};
var translate = ctx.translate;
ctx.translate = function(dx,dy){
xform = xform.translate(dx,dy);
return translate.call(ctx,dx,dy);
};
var transform = ctx.transform;
ctx.transform = function(a,b,c,d,e,f){
var m2 = svg.createSVGMatrix();
m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f;
xform = xform.multiply(m2);
return transform.call(ctx,a,b,c,d,e,f);
};
var setTransform = ctx.setTransform;
ctx.setTransform = function(a,b,c,d,e,f){
xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx,a,b,c,d,e,f);
};
var pt = svg.createSVGPoint();
ctx.transformedPoint = function(x,y){
pt.x=x; pt.y=y;
return pt.matrixTransform(xform.inverse());
}
}
var startCanvas = function() {
canvas = document.getElementById('canvas');
// Проверяем понимает ли браузер canvas
if (!canvas.getContext) {
throw "exception";
}
ctx = canvas.getContext('2d'); // Получаем 2D контекст
ctxHeight = canvas.height;
ctxWidth = canvas.width;
lastX = ctxWidth/2;
lastY = ctxHeight/2;
ctx.lineWidth = 2;
ctx.lineCap = 'round';
trackTransforms(ctx);
canvas.addEventListener('mousedown',function(evt){
document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
dragStart = ctx.transformedPoint(lastX,lastY);
dragged = false;
},false);
canvas.addEventListener('mousemove',function(evt){
lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
dragged = true;
if (dragStart){
var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);
reRender();
}
},false);
canvas.addEventListener('mouseup',function(evt){
dragStart = null;
if (!dragged) zoom(evt.shiftKey ? -1 : 1 );
},false);
var zoom = function(clicks){
var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x,pt.y);
var factor = Math.pow(scaleFactor,clicks);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);
reRender();
};
var handleScroll = function(evt){
var delta;
if(evt.detail<0 || evt.wheelDelta>0)delta=zoomFactorDelta;
else delta=-1*zoomFactorDelta;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
canvas.addEventListener('DOMMouseScroll',handleScroll,false);
canvas.addEventListener('mousewheel',handleScroll,false);
};
var drawGrid = function() {
var i;
ctx.strokeStyle = renderOptions["colorGrid"];
ctx.lineWidth = 1;
var offsetX=0, offsetY=0;
if(renderOptions["moveModel"]){
offsetX = offsetModelX;
offsetY = offsetModelY;
}
ctx.beginPath();
for(i=0;i<=gridSizeX;i+=gridStep){
ctx.moveTo(i*zoomFactor-offsetX, 0-offsetY);
ctx.lineTo(i*zoomFactor-offsetX, -gridSizeY*zoomFactor-offsetY);
}
ctx.stroke();
ctx.beginPath();
for(i=0;i<=gridSizeY;i+=gridStep){
ctx.moveTo(0-offsetX, -i*zoomFactor-offsetY);
ctx.lineTo(gridSizeX*zoomFactor-offsetX, -i*zoomFactor-offsetY);
}
ctx.stroke();
};
var drawLayer = function(layerNum, fromProgress, toProgress, isNextLayer){
var i, speedIndex= 0, prevZ = 0;
isNextLayer = typeof isNextLayer !== 'undefined' ? isNextLayer : false;
if(!isNextLayer){
layerNumStore=layerNum;
progressStore = {from: fromProgress, to: toProgress};
}
if(!model||!model[layerNum])return;
var cmds = model[layerNum];
var x, y;
// if(toProgress === -1){
// toProgress=cmds.length;
// }
if(fromProgress>0){
prevX = cmds[fromProgress-1].x*zoomFactor;
prevY = -cmds[fromProgress-1].y*zoomFactor;
}else if(fromProgress===0 && layerNum==0){
if(model[0]&&model[0].x !== undefined &&model[0].y !== undefined){
prevX = model[0].x*zoomFactor;
prevY = -model[0].y*zoomFactor;
}else {
prevX = 0;
prevY = 0;
}
}else if(typeof(cmds[0].prevX) !== 'undefined' && typeof(cmds[0].prevY) !== 'undefined'){
prevX = cmds[0].prevX*zoomFactor;
prevY = -cmds[0].prevY*zoomFactor;
}else{
if(model[layerNum-1]){
prevX=undefined;
prevY=undefined;
for(i=model[layerNum-1].length-1;i>=0;i--){
if(prevX === undefined && model[layerNum-1][i].x!==undefined)prevX=model[layerNum-1][i].x*zoomFactor;
if(prevY === undefined && model[layerNum-1][i].y!==undefined)prevY=-model[layerNum-1][i].y*zoomFactor;
}
if(prevX === undefined)prevX=0;
if(prevY === undefined)prevY=0;
}else{
prevX=0;
prevY=0;
}
}
prevZ = GCODE.renderer.getZ(layerNum);
// ctx.strokeStyle = renderOptions["colorLine"];
for(i=fromProgress;i<=toProgress;i++){
ctx.lineWidth = 1;
if(typeof(cmds[i]) === 'undefined')continue;
if(typeof(cmds[i].prevX) !== 'undefined' && typeof(cmds[i].prevY) !== 'undefined'){
prevX = cmds[i].prevX*zoomFactor;
prevY = -cmds[i].prevY*zoomFactor;
}
// console.log(cmds[i]);
if(typeof(cmds[i].x)==='undefined'||isNaN(cmds[i].x))x=prevX/zoomFactor;
else x = cmds[i].x;
if(typeof(cmds[i].y) === 'undefined'||isNaN(cmds[i].y))y=prevY/zoomFactor;
else y = -cmds[i].y;
if(renderOptions["differentiateColors"]&&!renderOptions['showNextLayer']){
// if(speedsByLayer['extrude'][prevZ]){
speedIndex = speeds['extrude'].indexOf(cmds[i].speed);
// speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer['extrude'][prevZ], function(obj) {return obj.speed === cmds[i].speed;});
// } else {
// speedIndex = -1;
// }
if(speedIndex === -1){
speedIndex = 0;
}else if(speedIndex > renderOptions["colorLine"].length -1){
speedIndex = speedIndex % (renderOptions["colorLine"].length-1);
// console.log("Too much colors");
}
}else if(renderOptions['showNextLayer']&&isNextLayer){
speedIndex=3;
}else{
speedIndex=0;
}
if(!cmds[i].extrude&&!cmds[i].noMove){
// ctx.stroke();
if(cmds[i].retract == -1){
if(renderOptions["showRetracts"]){
ctx.strokeStyle = renderOptions["colorRetract"];
ctx.fillStyle = renderOptions["colorRetract"];
ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke();
ctx.fill();
}
}
if(renderOptions["showMoves"]){
ctx.strokeStyle = renderOptions["colorMove"];
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke();
}
// ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath();
// console.log("moveto: "+cmds[i].x+":"+cmds[i].y)
// ctx.moveTo(cmds[i].x*zoomFactor,cmds[i].y*zoomFactor);
}
else if(cmds[i].extrude){
if(cmds[i].retract==0){
ctx.strokeStyle = renderOptions["colorLine"][speedIndex];
ctx.lineWidth = renderOptions['extrusionWidth'];
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke();
}else {
if(renderOptions["showRetracts"]){
// ctx.stroke();
ctx.strokeStyle = renderOptions["colorRestart"];
ctx.fillStyle = renderOptions["colorRestart"];
ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke();
ctx.fill();
// ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath();
}
}
}
prevX = x*zoomFactor;
prevY = y*zoomFactor;
}
ctx.stroke();
};
// ***** PUBLIC *******
return {
init: function(){
startCanvas();
initialized = true;
ctx.translate(10,gridSizeY*zoomFactor+20);
},
setOption: function(options){
for(var opt in options){
if(options.hasOwnProperty(opt))renderOptions[opt] = options[opt];
};
if(initialized)reRender();
},
getOptions: function(){
return renderOptions;
},
debugGetModel: function(){
return model;
},
render: function(layerNum, fromProgress, toProgress){
if(!initialized)this.init();
if(!model){
drawGrid();
}else{
if(layerNum < model.length){
var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
drawGrid();
// ctx.globalAlpha = 0.5;
if(renderOptions['showNextLayer'] && layerNum < model.length - 1) {
drawLayer(layerNum+1, 0, this.getLayerNumSegments(layerNum+1), true);
}
drawLayer(layerNum, fromProgress, toProgress);
}else{
console.log("Got request to render non-existent layer!!");
}
}
},
getModelNumLayers: function(){
return model?model.length:1;
},
getLayerNumSegments: function(layer){
if(model){
return model[layer]?model[layer].length:1;
}else{
return 1;
}
},
doRender: function(mdl, layerNum){
var mdlInfo;
model = mdl;
prevX=0;
prevY=0;
if(!initialized)this.init();
mdlInfo = GCODE.gCodeReader.getModelInfo();
speeds = mdlInfo.speeds;
speedsByLayer = mdlInfo.speedsByLayer;
// console.log(speeds);
// console.log(mdlInfo.min.x + ' ' + mdlInfo.modelSize.x);
offsetModelX = (gridSizeX/2-(mdlInfo.min.x+mdlInfo.modelSize.x/2))*zoomFactor;
offsetModelY = (mdlInfo.min.y+mdlInfo.modelSize.y/2)*zoomFactor-gridSizeY/2*zoomFactor;
if(ctx)ctx.translate(offsetModelX, offsetModelY);
this.render(layerNum, 0, model[layerNum].length);
},
getZ: function(layerNum){
if(!model&&!model[layerNum]){
return '-1';
}
var cmds = model[layerNum];
for(var i=0;i<cmds.length;i++){
if(cmds[i].prevZ!==undefined)return cmds[i].prevZ;
}
return '-1';
}
}
}());

View File

@ -0,0 +1,206 @@
/**
* User: hudbrog (hudbrog@gmail.com)
* Date: 10/21/12
* Time: 4:59 PM
*/
GCODE.renderer3d = (function(){
// ***** PRIVATE ******
var modelLoaded=false;
var model;
var prevX=0, prevY= 0, prevZ=0;
var sliderHor, sliderVer;
var object;
var geometry;
var WIDTH = 650, HEIGHT = 630;
var VIEW_ANGLE = 70,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
var renderer;
var scene;
var camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
var controls;
var halfWidth = window.innerWidth / 2;
var halfHeight = window.innerHeight / 2;
var mouseX = 0, mouseY = 0;
var renderOptions = {
showMoves: true,
colorLine: 0x000000,
colorMove: 0x00ff00,
rendererType: "webgl"
};
var render = function(){
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
};
var buildModelIteration = function(layerNum){
var j;
var cmds = model[layerNum];
if(!cmds)return;
for(j=0;j<cmds.length;j++){
if(!cmds[j])continue;
if(!cmds[j].x)cmds[j].x=prevX;
if(!cmds[j].y)cmds[j].y=prevY;
if(!cmds[j].z)cmds[j].z=prevZ;
if(!cmds[j].extrude){
}
else {
geometry.vertices.push( new THREE.Vector3(prevX, prevY, prevZ));
geometry.vertices.push( new THREE.Vector3(cmds[j].x, cmds[j].y, cmds[j].z));
}
prevX = cmds[j].x;
prevY = cmds[j].y;
prevZ = cmds[j].z;
}
};
var buildModelIteratively = function(){
var i;
for(i=0;i<model.length;i+=1){
buildModelIteration(i);
//TODO: need to remove UI stuff from here
}
var lineMaterial = new THREE.LineBasicMaterial({color: renderOptions["colorLine"], lineWidth: 2, opacity: 0.6, fog: false});
geometry.computeBoundingBox();
object.add(new THREE.Line(geometry, lineMaterial, THREE.LinePieces));
var center = new THREE.Vector3().add(geometry.boundingBox.min, geometry.boundingBox.max).divideScalar(2);
object.position = center.multiplyScalar(-1);
}
var buildModel = function(){
var i,j;
var cmds = [];
for(i=0;i<model.length;i++){
cmds = model[i];
if(!cmds)continue;
for(j=0;j<cmds.length;j++){
if(!cmds[j])continue;
if(!cmds[j].x)cmds[j].x=prevX;
if(!cmds[j].y)cmds[j].y=prevY;
if(!cmds[j].z)cmds[j].z=prevZ;
if(!cmds[j].extrude){
}
else {
geometry.vertices.push( new THREE.Vector3(prevX, prevY, prevZ));
geometry.vertices.push( new THREE.Vector3(cmds[j].x, cmds[j].y, cmds[j].z));
}
prevX = cmds[j].x;
prevY = cmds[j].y;
prevZ = cmds[j].z;
}
//TODO: need to remove UI stuff from here
$(function() {
$( "#progressbar" ).progressbar({
value: i/model.length*100
});
});
}
var lineMaterial = new THREE.LineBasicMaterial({color: renderOptions["colorLine"], lineWidth: 4, opacity: 1, fog: false});
geometry.computeBoundingBox();
object.add(new THREE.Line(geometry, lineMaterial, THREE.LinePieces));
var center = new THREE.Vector3().add(geometry.boundingBox.min, geometry.boundingBox.max).divideScalar(2);
object.position = center.multiplyScalar(-1);
};
var debugAxis = function(axisLength){
//Shorten the vertex function
function v(x,y,z){
return new THREE.Vector3(x,y,z);
}
//Create axis (point1, point2, colour)
function createAxis(p1, p2, color){
var line, lineGeometry = new THREE.Geometry(),
lineMat = new THREE.LineBasicMaterial({color: color, lineWidth: 1});
lineGeometry.vertices.push(p1, p2);
line = new THREE.Line(lineGeometry, lineMat);
scene.add(line);
}
createAxis(v(-axisLength, 0, 0), v(axisLength, 0, 0), 0xFF0000);
createAxis(v(0, -axisLength, 0), v(0, axisLength, 0), 0x00FF00);
createAxis(v(0, 0, -axisLength), v(0, 0, axisLength), 0x0000FF);
};
// ***** PUBLIC *******
return {
init: function(){
modelLoaded = false;
if(renderOptions["rendererType"]=="webgl")renderer = new THREE.WebGLRenderer({clearColor:0xffffff, clearAlpha: 1});
else if(renderOptions["rendererType"]=="canvas")renderer = new THREE.CanvasRenderer({clearColor:0xffffff, clearAlpha: 1});
else { console.log("unknown rendererType"); return;}
scene = new THREE.Scene()
var $container = $('#3d_container');
camera.position.z = 200;
scene.add(camera);
renderer.setSize(WIDTH, HEIGHT);
$container.empty();
$container.append(renderer.domElement);
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
},
isModelReady: function(){
return modelLoaded;
},
setOption: function(options){
for(var opt in options){
if(options.hasOwnProperty(opt))renderOptions[opt] = options[opt];
}
},
setModel: function(mdl){
model = mdl;
modelLoaded=false;
},
doRender: function(){
// model = mdl;
prevX=0;
prevY=0;
prevZ=0;
object = new THREE.Object3D();
geometry = new THREE.Geometry();
this.init();
if(model)modelLoaded=true;
else return;
// buildModel();
buildModelIteratively();
scene.add(object);
debugAxis(100);
var mousemove = function(e){
mouseX = e.clientX - halfWidth;
mouseY = e.clientY - halfHeight;
};
// Action!
render();
// renderer.render(scene, camera);
}
}
}());

View File

@ -0,0 +1,345 @@
/**
* User: hudbrog (hudbrog@gmail.com)
* Date: 10/21/12
* Time: 7:45 AM
*/
var GCODE = {};
GCODE.ui = (function(){
var reader;
var myCodeMirror;
var sliderVer;
var sliderHor;
var gCodeLines = {first: 0, last: 0};
var showGCode = false;
var setProgress = function(id, progress){
$('#'+id).width(parseInt(progress)+'%');
$('#'+id).text(parseInt(progress)+'%');
};
var chooseAccordion = function(id){
// debugger;
$('#'+id).collapse("show");
};
var setLinesColor = function(toggle){
// var i=0;
// for(i=gCodeLines.first;i<gCodeLines.last; i++){
// if(toggle){
// myCodeMirror.setLineClass(Number(i), null, "activeline");
// }else{
// myCodeMirror.setLineClass(Number(i), null, null);
// }
// }
}
var printLayerInfo = function(layerNum){
var z = GCODE.renderer.getZ(layerNum);
var segments = GCODE.renderer.getLayerNumSegments(layerNum);
var filament = GCODE.gCodeReader.getLayerFilament(z);
var layerSpeeds = GCODE.gCodeReader.getModelInfo().speedsByLayer;
var renderOptions = GCODE.renderer.getOptions();
var colors = renderOptions["colorLine"];
var speedIndex = 0;
var keys, type;
var showMove=false;
var i = 0;
var output = [];
output.push("Layer number: " + layerNum);
output.push("Layer height (mm): " + z);
output.push("GCODE commands in layer: " + segments);
output.push("Filament used by layer (mm): " + filament.toFixed(2));
output.push("Print time for layer: " + parseFloat(GCODE.gCodeReader.getModelInfo().printTimeByLayer[z]).toFixed(1) + "sec");
output.push("Extrude speeds:");
for(i=0;i<layerSpeeds['extrude'][z].length;i++){
if(typeof(layerSpeeds['extrude'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<div id='colorBox"+i+"' class='colorBox' style='background-color: "+colors[speedIndex] + "'></div> = " + (parseFloat(layerSpeeds['extrude'][z][i])/60).toFixed(2)+"mm/s");
}
if(typeof(layerSpeeds['move'][z]) !== 'undefined'){
output.push("Move speeds:");
for(i=0;i<layerSpeeds['move'][z].length;i++){
if(typeof(layerSpeeds['move'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<div id='colorBox"+i+"' class='colorBox' style='background-color: "+renderOptions['colorMove'] + "'></div> = " + (parseFloat(layerSpeeds['move'][z][i])/60).toFixed(2)+"mm/s");
}
}
if(typeof(layerSpeeds['retract'][z]) !== 'undefined'){
output.push("Retract speeds:");
for(i=0;i<layerSpeeds['retract'][z].length;i++){
if(typeof(layerSpeeds['retract'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<span style='color: " + renderOptions['colorRetract'] +"'>&#9679;</span> <span style='color: " + renderOptions['colorRestart'] +"'>&#9679;</span> = " +(parseFloat(layerSpeeds['retract'][z][i])/60).toFixed(2)+"mm/s");
}
}
$('#layerInfo').html(output.join('<br>'));
// chooseAccordion('layerAccordionTab');
};
var handleFileSelect = function(evt) {
// console.log("handleFileSelect");
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer?evt.dataTransfer.files:evt.target.files; // FileList object.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
if(f.name.toLowerCase().match(/^.*\.(?:gcode|g|txt)$/)){
output.push('<li>File extensions suggests GCODE</li>');
}else{
output.push('<li><strong>You should only upload *.gcode files! I will not work with this one!</strong></li>');
document.getElementById('errorList').innerHTML = '<ul>' + output.join('') + '</ul>';
return;
}
reader = new FileReader();
reader.onload = function(theFile){
chooseAccordion('progressAccordionTab');
setProgress('loadProgress', 0);
setProgress('analyzeProgress', 0);
// myCodeMirror.setValue(theFile.target.result);
GCODE.gCodeReader.loadFile(theFile);
if(showGCode){
myCodeMirror.setValue(theFile.target.result);
}else{
myCodeMirror.setValue("GCode view is disabled. You can enable it in 'GCode analyzer options' section.")
}
};
reader.readAsText(f);
}
};
var handleDragOver = function(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.target.dropEffect = 'copy'; // Explicitly show this is a copy.
};
var initSliders = function(){
var prevX=0;
var prevY=0;
var handle;
sliderVer = $( "#slider-vertical" );
sliderHor = $( "#slider-horizontal" );
var onLayerChange = function(val){
var progress = GCODE.renderer.getLayerNumSegments(val)-1;
GCODE.renderer.render(val,0, progress);
sliderHor.slider({max: progress, values: [0,progress]});
setLinesColor(false); //clear current selection
gCodeLines = GCODE.gCodeReader.getGCodeLines(val, sliderHor.slider("values",0), sliderHor.slider("values",1));
setLinesColor(true); // highlight lines
printLayerInfo(val);
};
sliderVer.slider({
orientation: "vertical",
range: "min",
min: 0,
max: GCODE.renderer.getModelNumLayers()-1,
value: 0,
slide: function( event, ui ) {
onLayerChange(ui.value);
}
});
//this stops slider reacting to arrow keys, since we do it below manually
$( "#slider-vertical .ui-slider-handle" ).unbind('keydown');
sliderHor.slider({
orientation: "horizontal",
range: "min",
min: 0,
max: GCODE.renderer.getLayerNumSegments(0)-1,
values: [0,GCODE.renderer.getLayerNumSegments(0)-1],
slide: function( event, ui ) {
setLinesColor(false); //clear current selection
gCodeLines = GCODE.gCodeReader.getGCodeLines(sliderVer.slider("value"),ui.values[0], ui.values[1]);
setLinesColor(true); // highlight lines
GCODE.renderer.render(sliderVer.slider("value"), ui.values[0], ui.values[1]);
}
});
window.onkeydown = function (event){
if(event.keyCode === 38 || event.keyCode === 33){
if(sliderVer.slider('value') < sliderVer.slider('option', 'max')){
sliderVer.slider('value', sliderVer.slider('value')+1);
onLayerChange(sliderVer.slider('value'));
}
}else if(event.keyCode === 40 || event.keyCode === 34){
if(sliderVer.slider('value') > 0){
sliderVer.slider('value', sliderVer.slider('value')-1);
onLayerChange(sliderVer.slider('value'));
}
}
event.stopPropagation()
}
};
var processMessage = function(e){
var data = e.data;
switch (data.cmd) {
case 'returnModel':
setProgress('loadProgress', 100);
worker.postMessage({
"cmd":"analyzeModel",
"msg":{
}
}
);
break;
case 'analyzeDone':
var resultSet = [];
setProgress('analyzeProgress',100);
GCODE.gCodeReader.processAnalyzeModelDone(data.msg);
GCODE.gCodeReader.passDataToRenderer();
initSliders();
resultSet.push("Model size is: " + data.msg.modelSize.x.toFixed(2) + 'x' + data.msg.modelSize.y.toFixed(2) + 'x' + data.msg.modelSize.z.toFixed(2)+'mm<br>');
resultSet.push("Total filament used: " + data.msg.totalFilament.toFixed(2) + "mm<br>");
resultSet.push("Estimated print time: " + parseInt(parseFloat(data.msg.printTime)/60/60) + ":" + parseInt((parseFloat(data.msg.printTime)/60)%60) + ":" + parseInt(parseFloat(data.msg.printTime)%60) + "<br>");
resultSet.push("Estimated layer height: " + data.msg.layerHeight.toFixed(2) + "mm<br>");
resultSet.push("Layer count: " + data.msg.layerCnt.toFixed(0) + "printed, " + data.msg.layerTotal.toFixed(0) + 'visited<br>');
document.getElementById('list').innerHTML = resultSet.join('');
chooseAccordion('infoAccordionTab');
$('#myTab a[href="#tab2d"]').tab('show');
break;
case 'returnLayer':
GCODE.gCodeReader.processLayerFromWorker(data.msg);
setProgress('loadProgress',data.msg.progress);
break;
case 'returnMultiLayer':
GCODE.gCodeReader.processMultiLayerFromWorker(data.msg);
setProgress('loadProgress',data.msg.progress);
break;
case "analyzeProgress":
setProgress('analyzeProgress',data.msg.progress);
break;
default:
console.log("default msg received" + data.cmd);
}
};
var checkCapabilities = function(){
var warnings = [];
var fatal = [];
Modernizr.addTest('filereader', function () {
return !!(window.File && window.FileList && window.FileReader);
});
if(!Modernizr.canvas)fatal.push("<li>Your browser doesn't seem to support HTML5 Canvas, this application won't work without it.</li>");
if(!Modernizr.filereader)fatal.push("<li>Your browser doesn't seem to support HTML5 File API, this application won't work without it.</li>");
if(!Modernizr.webworkers)fatal.push("<li>Your browser doesn't seem to support HTML5 Web Workers, this application won't work without it.</li>");
if(!Modernizr.svg)fatal.push("<li>Your browser doesn't seem to support HTML5 SVG, this application won't work without it.</li>");
if(fatal.length>0){
document.getElementById('errorList').innerHTML = '<ul>' + fatal.join('') + '</ul>';
console.log("Initialization failed: unsupported browser.")
return false;
}
if(!Modernizr.webgl){
warnings.push("<li>Your browser doesn't seem to support HTML5 Web GL, 3d mode is not recommended, going to be SLOW!</li>");
GCODE.renderer3d.setOption({rendererType: "canvas"});
}
if(!Modernizr.draganddrop)warnings.push("<li>Your browser doesn't seem to support HTML5 Drag'n'Drop, Drop area will not work.</li>");
if(warnings.length>0){
document.getElementById('errorList').innerHTML = '<ul>' + wanings.join('') + '</ul>';
console.log("Initialization succeeded with warnings.")
}
return true;
};
return {
worker: undefined,
initHandlers: function(){
var capabilitiesResult = checkCapabilities();
if(!capabilitiesResult){
return;
}
setProgress('loadProgress', 0);
setProgress('analyzeProgress', 0);
worker = new Worker('static/gcodeviewer/js/Worker.js');
worker.addEventListener('message', processMessage, false);
GCODE.ui.processOptions();
GCODE.renderer.render(0,0);
console.log("Application initialized");
},
ArrayIndexOf: function(a, fnc) {
if (!fnc || typeof (fnc) != 'function') {
return -1;
}
if (!a || !a.length || a.length < 1) return -1;
for (var i = 0; i < a.length; i++) {
if(!a[i]) continue;
if (fnc(a[i])) return i;
}
return -1;
},
updateLayerInfo: function(layerNum){
printLayerInfo(layerNum);
},
processOptions: function(){
if(document.getElementById('sortLayersCheckbox').checked)GCODE.gCodeReader.setOption({sortLayers: true});
else GCODE.gCodeReader.setOption({sortLayers: false});
if(document.getElementById('purgeEmptyLayersCheckbox').checked)GCODE.gCodeReader.setOption({purgeEmptyLayers: true});
else GCODE.gCodeReader.setOption({purgeEmptyLayers: false});
if(document.getElementById('showGCodeCheckbox').checked)showGCode = true;
else showGCode = false;
// if(document.getElementById('sortLayersCheckbox').checked) worker.postMessage({"cmd":"setOption", "msg":{sortLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{sortLayers: false}});
//
// if(document.getElementById('purgeEmptyLayersCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: false}});
// if(document.getElementById('analyzeModelCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: false}});
if(document.getElementById('moveModelCheckbox').checked)GCODE.renderer.setOption({moveModel: true});
else GCODE.renderer.setOption({moveModel: false});
if(document.getElementById('showMovesCheckbox').checked)GCODE.renderer.setOption({showMoves: true});
else GCODE.renderer.setOption({showMoves: false});
if(document.getElementById('showRetractsCheckbox').checked)GCODE.renderer.setOption({showRetracts: true});
else GCODE.renderer.setOption({showRetracts: false});
if(document.getElementById('differentiateColorsCheckbox').checked)GCODE.renderer.setOption({differentiateColors: true});
else GCODE.renderer.setOption({differentiateColors: false});
var widthMod = 2;
if(Number($('#widthModifier').attr('value'))) {widthMod = Number($('#widthModifier').attr('value'));}
if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({extrusionWidth: widthMod});
else GCODE.renderer.setOption({extrusionWidth: 1});
if(document.getElementById('showNextLayer').checked)GCODE.renderer.setOption({showNextLayer: true});
else GCODE.renderer.setOption({showNextLayer: false});
}
}
}());

View File

@ -0,0 +1,406 @@
/**
* @author Eberhard Graether / http://egraether.com/
*/
THREE.TrackballControls = function ( object, domElement ) {
THREE.EventTarget.call( this );
var _this = this;
var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2 };
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
this.enabled = true;
this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 };
this.radius = ( this.screen.width + this.screen.height ) / 4;
this.rotateSpeed = 1.0;
this.zoomSpeed = 1.2;
this.panSpeed = 0.3;
this.noRotate = false;
this.noZoom = false;
this.noPan = false;
this.staticMoving = false;
this.dynamicDampingFactor = 0.2;
this.minDistance = 0;
this.maxDistance = Infinity;
this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
// internals
this.target = new THREE.Vector3();
var lastPosition = new THREE.Vector3();
var _state = STATE.NONE,
_prevState = STATE.NONE,
_eye = new THREE.Vector3(),
_rotateStart = new THREE.Vector3(),
_rotateEnd = new THREE.Vector3(),
_zoomStart = new THREE.Vector2(),
_zoomEnd = new THREE.Vector2(),
_panStart = new THREE.Vector2(),
_panEnd = new THREE.Vector2();
// events
var changeEvent = { type: 'change' };
// methods
this.handleResize = function () {
this.screen.width = window.innerWidth;
this.screen.height = window.innerHeight;
this.screen.offsetLeft = 0;
this.screen.offsetTop = 0;
this.radius = ( this.screen.width + this.screen.height ) / 4;
};
this.handleEvent = function ( event ) {
if ( typeof this[ event.type ] == 'function' ) {
this[ event.type ]( event );
}
};
this.getMouseOnScreen = function ( clientX, clientY ) {
return new THREE.Vector2(
( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5,
( clientY - _this.screen.offsetTop ) / _this.radius * 0.5
);
};
this.getMouseProjectionOnBall = function ( clientX, clientY ) {
var mouseOnBall = new THREE.Vector3(
( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius,
( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius,
0.0
);
var length = mouseOnBall.length();
if ( length > 1.0 ) {
mouseOnBall.normalize();
} else {
mouseOnBall.z = Math.sqrt( 1.0 - length * length );
}
_eye.copy( _this.object.position ).subSelf( _this.target );
var projection = _this.object.up.clone().setLength( mouseOnBall.y );
projection.addSelf( _this.object.up.clone().crossSelf( _eye ).setLength( mouseOnBall.x ) );
projection.addSelf( _eye.setLength( mouseOnBall.z ) );
return projection;
};
this.rotateCamera = function () {
var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
if ( angle ) {
var axis = ( new THREE.Vector3() ).cross( _rotateStart, _rotateEnd ).normalize(),
quaternion = new THREE.Quaternion();
angle *= _this.rotateSpeed;
quaternion.setFromAxisAngle( axis, -angle );
quaternion.multiplyVector3( _eye );
quaternion.multiplyVector3( _this.object.up );
quaternion.multiplyVector3( _rotateEnd );
if ( _this.staticMoving ) {
_rotateStart.copy( _rotateEnd );
} else {
quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
quaternion.multiplyVector3( _rotateStart );
}
}
};
this.zoomCamera = function () {
var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
if ( factor !== 1.0 && factor > 0.0 ) {
_eye.multiplyScalar( factor );
if ( _this.staticMoving ) {
_zoomStart.copy( _zoomEnd );
} else {
_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
}
}
};
this.panCamera = function () {
var mouseChange = _panEnd.clone().subSelf( _panStart );
if ( mouseChange.lengthSq() ) {
mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
var pan = _eye.clone().crossSelf( _this.object.up ).setLength( mouseChange.x );
pan.addSelf( _this.object.up.clone().setLength( mouseChange.y ) );
_this.object.position.addSelf( pan );
_this.target.addSelf( pan );
if ( _this.staticMoving ) {
_panStart = _panEnd;
} else {
_panStart.addSelf( mouseChange.sub( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
}
}
};
this.checkDistances = function () {
if ( !_this.noZoom || !_this.noPan ) {
if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) {
_this.object.position.setLength( _this.maxDistance );
}
if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
_this.object.position.add( _this.target, _eye.setLength( _this.minDistance ) );
}
}
};
this.update = function () {
_eye.copy( _this.object.position ).subSelf( _this.target );
if ( !_this.noRotate ) {
_this.rotateCamera();
}
if ( !_this.noZoom ) {
_this.zoomCamera();
}
if ( !_this.noPan ) {
_this.panCamera();
}
_this.object.position.add( _this.target, _eye );
_this.checkDistances();
_this.object.lookAt( _this.target );
if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) {
_this.dispatchEvent( changeEvent );
lastPosition.copy( _this.object.position );
}
};
// listeners
function keydown( event ) {
if ( ! _this.enabled ) return;
window.removeEventListener( 'keydown', keydown );
_prevState = _state;
if ( _state !== STATE.NONE ) {
return;
} else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
_state = STATE.ROTATE;
} else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
_state = STATE.ZOOM;
} else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
_state = STATE.PAN;
}
}
function keyup( event ) {
if ( ! _this.enabled ) return;
_state = _prevState;
window.addEventListener( 'keydown', keydown, false );
}
function mousedown( event ) {
if ( ! _this.enabled ) return;
event.preventDefault();
event.stopPropagation();
if ( _state === STATE.NONE ) {
_state = event.button;
}
if ( _state === STATE.ROTATE && !_this.noRotate ) {
_rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
_zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
} else if ( _state === STATE.PAN && !_this.noPan ) {
_panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
}
document.addEventListener( 'mousemove', mousemove, false );
document.addEventListener( 'mouseup', mouseup, false );
}
function mousemove( event ) {
if ( ! _this.enabled ) return;
if ( _state === STATE.ROTATE && !_this.noRotate ) {
_rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
_zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
} else if ( _state === STATE.PAN && !_this.noPan ) {
_panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
}
}
function mouseup( event ) {
if ( ! _this.enabled ) return;
event.preventDefault();
event.stopPropagation();
_state = STATE.NONE;
document.removeEventListener( 'mousemove', mousemove );
document.removeEventListener( 'mouseup', mouseup );
}
function mousewheel( event ) {
if ( ! _this.enabled ) return;
event.preventDefault();
event.stopPropagation();
var delta = 0;
if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
delta = event.wheelDelta / 40;
} else if ( event.detail ) { // Firefox
delta = - event.detail / 3;
}
_zoomStart.y += ( 1 / delta ) * 0.05;
}
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', mousedown, false );
this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false );
this.domElement.addEventListener( 'mousewheel', mousewheel, false );
window.addEventListener( 'keydown', keydown, false );
window.addEventListener( 'keyup', keyup, false );
this.handleResize();
};

View File

@ -0,0 +1,174 @@
.CodeMirror {
line-height: 1em;
font-family: monospace;
/* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
position: relative;
/* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
overflow: hidden;
}
.CodeMirror-scroll {
overflow: auto;
height: 300px;
/* This is needed to prevent an IE[67] bug where the scrolled content
is visible outside of the scrolling box. */
position: relative;
outline: none;
}
/* Vertical scrollbar */
.CodeMirror-scrollbar {
position: absolute;
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
z-index: 5;
}
.CodeMirror-scrollbar-inner {
/* This needs to have a nonzero width in order for the scrollbar to appear
in Firefox and IE9. */
width: 1px;
}
.CodeMirror-scrollbar.cm-sb-overlap {
/* Ensure that the scrollbar appears in Lion, and that it overlaps the content
rather than sitting to the right of it. */
position: absolute;
z-index: 1;
float: none;
right: 0;
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-nonoverlap {
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-ie7 {
min-width: 18px;
}
.CodeMirror-gutter {
position: absolute; left: 0; top: 0;
z-index: 10;
background-color: #f7f7f7;
border-right: 1px solid #eee;
min-width: 2em;
height: 100%;
}
.CodeMirror-gutter-text {
color: #aaa;
text-align: right;
padding: .4em .2em .4em .4em;
white-space: pre !important;
cursor: default;
}
.CodeMirror-lines {
padding: .4em;
white-space: pre;
cursor: text;
}
.CodeMirror pre {
-moz-border-radius: 0;
-webkit-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border-width: 0; margin: 0; padding: 0; background: transparent;
font-family: inherit;
font-size: inherit;
padding: 0; margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
overflow: visible;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
}
.CodeMirror textarea {
outline: none !important;
}
.CodeMirror pre.CodeMirror-cursor {
z-index: 10;
position: absolute;
visibility: hidden;
border-left: 1px solid black;
border-right: none;
width: 0;
}
.cm-keymap-fat-cursor pre.CodeMirror-cursor {
width: auto;
border: 0;
background: transparent;
background: rgba(0, 200, 0, .4);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
}
/* Kludge to turn off filter in ie9+, which also accepts rgba */
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
.CodeMirror-focused pre.CodeMirror-cursor {
visibility: visible;
}
div.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Default theme */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #997;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
.cm-s-default span.cm-header {color: blue;}
.cm-s-default span.cm-quote {color: #090;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-link {color: #00c;}
span.cm-header, span.cm-strong {font-weight: bold;}
span.cm-em {font-style: italic;}
span.cm-emstrong {font-style: italic; font-weight: bold;}
span.cm-link {text-decoration: underline;}
span.cm-invalidchar {color: #f00;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
@media print {
/* Hide the cursor when printing */
.CodeMirror pre.CodeMirror-cursor {
visibility: hidden;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
CodeMirror.defineMode("diff", function() {
var TOKEN_NAMES = {
'G': 'tag',
'M': 'string',
';': 'meta'
};
return {
token: function(stream) {
var tw_pos = stream.string.search(/[\t ]+?$/);
if (!stream.sol() || tw_pos === 0) {
stream.skipToEnd();
return ("error " + (
TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
}
var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
if (tw_pos === -1) {
stream.skipToEnd();
} else {
stream.pos = tw_pos;
}
return token_name;
}
};
});
CodeMirror.defineMIME("text/x-diff", "diff");

View File

@ -0,0 +1,815 @@
/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
* Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
*/
;
window.Modernizr = (function( window, document, undefined ) {
var version = '2.6.2',
Modernizr = {},
enableClasses = true,
docElement = document.documentElement,
mod = 'modernizr',
modElem = document.createElement(mod),
mStyle = modElem.style,
inputElem = document.createElement('input') ,
smile = ':)',
toString = {}.toString,
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
ns = {'svg': 'http://www.w3.org/2000/svg'},
tests = {},
inputs = {},
attrs = {},
classes = [],
slice = classes.slice,
featureName,
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
body = document.body,
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
while ( nodes-- ) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if ( !body ) {
fakeBody.style.background = '';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
isEventSupported = (function() {
var TAGNAMES = {
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
};
function isEventSupported( eventName, element ) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
var isSupported = eventName in element;
if ( !isSupported ) {
if ( !element.setAttribute ) {
element = document.createElement('div');
}
if ( element.setAttribute && element.removeAttribute ) {
element.setAttribute(eventName, '');
isSupported = is(element[eventName], 'function');
if ( !is(element[eventName], 'undefined') ) {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
element = null;
return isSupported;
}
return isEventSupported;
})(),
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProp = function (object, property) {
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
}
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = this;
if (typeof target != "function") {
throw new TypeError();
}
var args = slice.call(arguments, 1),
bound = function () {
if (this instanceof bound) {
var F = function(){};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
return bound;
};
}
function setCss( str ) {
mStyle.cssText = str;
}
function setCssAll( str1, str2 ) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
function is( obj, type ) {
return typeof obj === type;
}
function contains( str, substr ) {
return !!~('' + str).indexOf(substr);
}
function testProps( props, prefixed ) {
for ( var i in props ) {
var prop = props[i];
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
return prefixed == 'pfx' ? prop : true;
}
}
return false;
}
function testDOMProps( props, obj, elem ) {
for ( var i in props ) {
var item = obj[props[i]];
if ( item !== undefined) {
if (elem === false) return props[i];
if (is(item, 'function')){
return item.bind(elem || obj);
}
return item;
}
}
return false;
}
function testPropsAll( prop, prefixed, elem ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
if(is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
}
} tests['flexbox'] = function() {
return testPropsAll('flexWrap');
}; tests['canvas'] = function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
};
tests['canvastext'] = function() {
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
};
tests['webgl'] = function() {
return !!window.WebGLRenderingContext;
};
tests['touch'] = function() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
bool = node.offsetTop === 9;
});
}
return bool;
};
tests['geolocation'] = function() {
return 'geolocation' in navigator;
};
tests['postmessage'] = function() {
return !!window.postMessage;
};
tests['websqldatabase'] = function() {
return !!window.openDatabase;
};
tests['indexedDB'] = function() {
return !!testPropsAll("indexedDB", window);
};
tests['hashchange'] = function() {
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
};
tests['history'] = function() {
return !!(window.history && history.pushState);
};
tests['draganddrop'] = function() {
var div = document.createElement('div');
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
};
tests['websockets'] = function() {
return 'WebSocket' in window || 'MozWebSocket' in window;
};
tests['rgba'] = function() {
setCss('background-color:rgba(150,255,150,.5)');
return contains(mStyle.backgroundColor, 'rgba');
};
tests['hsla'] = function() {
setCss('background-color:hsla(120,40%,100%,.5)');
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
};
tests['multiplebgs'] = function() {
setCss('background:url(https://),url(https://),red url(https://)');
return (/(url\s*\(.*?){3}/).test(mStyle.background);
}; tests['backgroundsize'] = function() {
return testPropsAll('backgroundSize');
};
tests['borderimage'] = function() {
return testPropsAll('borderImage');
};
tests['borderradius'] = function() {
return testPropsAll('borderRadius');
};
tests['boxshadow'] = function() {
return testPropsAll('boxShadow');
};
tests['textshadow'] = function() {
return document.createElement('div').style.textShadow === '';
};
tests['opacity'] = function() {
setCssAll('opacity:.55');
return (/^0.55$/).test(mStyle.opacity);
};
tests['cssanimations'] = function() {
return testPropsAll('animationName');
};
tests['csscolumns'] = function() {
return testPropsAll('columnCount');
};
tests['cssgradients'] = function() {
var str1 = 'background-image:',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str3 = 'linear-gradient(left top,#9f9, white);';
setCss(
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
prefixes.join(str3 + str1)).slice(0, -str1.length)
);
return contains(mStyle.backgroundImage, 'gradient');
};
tests['cssreflections'] = function() {
return testPropsAll('boxReflect');
};
tests['csstransforms'] = function() {
return !!testPropsAll('transform');
};
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
if ( ret && 'webkitPerspective' in docElement.style ) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
tests['csstransitions'] = function() {
return testPropsAll('transition');
};
tests['fontface'] = function() {
var bool;
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
var style = document.getElementById('smodernizr'),
sheet = style.sheet || style.styleSheet,
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
});
return bool;
};
tests['generatedcontent'] = function() {
var bool;
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
bool = node.offsetHeight >= 3;
});
return bool;
};
tests['video'] = function() {
var elem = document.createElement('video'),
bool = false;
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
tests['audio'] = function() {
var elem = document.createElement('audio'),
bool = false;
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
tests['localstorage'] = function() {
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['sessionstorage'] = function() {
try {
sessionStorage.setItem(mod, mod);
sessionStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['webworkers'] = function() {
return !!window.Worker;
};
tests['applicationcache'] = function() {
return !!window.applicationCache;
};
tests['svg'] = function() {
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
};
tests['inlinesvg'] = function() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
};
tests['smil'] = function() {
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
};
tests['svgclippaths'] = function() {
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
};
function webforms() {
Modernizr['input'] = (function( props ) {
for ( var i = 0, len = props.length; i < len; i++ ) {
attrs[ props[i] ] = !!(props[i] in inputElem);
}
if (attrs.list){
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
}
return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
Modernizr['inputtypes'] = (function(props) {
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
inputElem.setAttribute('type', inputElemType = props[i]);
bool = inputElem.type !== 'text';
if ( bool ) {
inputElem.value = smile;
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
docElement.appendChild(inputElem);
defaultView = document.defaultView;
bool = defaultView.getComputedStyle &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
(inputElem.offsetHeight !== 0);
docElement.removeChild(inputElem);
} else if ( /^(search|tel)$/.test(inputElemType) ){
} else if ( /^(url|email)$/.test(inputElemType) ) {
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
} else {
bool = inputElem.value != smile;
}
}
inputs[ props[i] ] = !!bool;
}
return inputs;
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
}
for ( var feature in tests ) {
if ( hasOwnProp(tests, feature) ) {
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
Modernizr.input || webforms();
Modernizr.addTest = function ( feature, test ) {
if ( typeof feature == 'object' ) {
for ( var key in feature ) {
if ( hasOwnProp( feature, key ) ) {
Modernizr.addTest( key, feature[ key ] );
}
}
} else {
feature = feature.toLowerCase();
if ( Modernizr[feature] !== undefined ) {
return Modernizr;
}
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
Modernizr[feature] = test;
}
return Modernizr;
};
setCss('');
modElem = inputElem = null;
;(function(window, document) {
var options = window.html5 || {};
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
var supportsHtml5Styles;
var expando = '_html5shiv';
var expanID = 0;
var expandoData = {};
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}()); function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
}
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
getElements().join().replace(/\w+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
} function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}' +
'mark{background:#FF0;color:#000}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
} var html5 = {
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
'shivCSS': (options.shivCSS !== false),
'supportsUnknownElements': supportsUnknownElements,
'shivMethods': (options.shivMethods !== false),
'type': 'default',
'shivDocument': shivDocument,
createElement: createElement,
createDocumentFragment: createDocumentFragment
}; window.html5 = html5;
shivDocument(document);
}(this, document));
Modernizr._version = version;
Modernizr._prefixes = prefixes;
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
Modernizr.hasEvent = isEventSupported;
Modernizr.testProp = function(prop){
return testProps([prop]);
};
Modernizr.testAllProps = testPropsAll;
Modernizr.testStyles = injectElementWithStyles;
Modernizr.prefixed = function(prop, obj, elem){
if(!obj) {
return testPropsAll(prop, 'pfx');
} else {
return testPropsAll(prop, obj, elem);
}
};
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
(enableClasses ? ' js ' + classes.join(' ') : '');
return Modernizr;
})(this, this.document);
/*yepnope1.5.4|WTFPL*/
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);
Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));};
;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

356
octoprint/static/js/jquery.ui.core.js vendored Normal file
View File

@ -0,0 +1,356 @@
/*!
* jQuery UI Core 1.9.2
* http://jqueryui.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/ui-core/
*/
(function( $, undefined ) {
var uuid = 0,
runiqueId = /^ui-id-\d+$/;
// prevent duplicate loading
// this is only a problem because we proxy existing functions
// and we don't want to double proxy them
$.ui = $.ui || {};
if ( $.ui.version ) {
return;
}
$.extend( $.ui, {
version: "1.9.2",
keyCode: {
BACKSPACE: 8,
COMMA: 188,
DELETE: 46,
DOWN: 40,
END: 35,
ENTER: 13,
ESCAPE: 27,
HOME: 36,
LEFT: 37,
NUMPAD_ADD: 107,
NUMPAD_DECIMAL: 110,
NUMPAD_DIVIDE: 111,
NUMPAD_ENTER: 108,
NUMPAD_MULTIPLY: 106,
NUMPAD_SUBTRACT: 109,
PAGE_DOWN: 34,
PAGE_UP: 33,
PERIOD: 190,
RIGHT: 39,
SPACE: 32,
TAB: 9,
UP: 38
}
});
// plugins
$.fn.extend({
_focus: $.fn.focus,
focus: function( delay, fn ) {
return typeof delay === "number" ?
this.each(function() {
var elem = this;
setTimeout(function() {
$( elem ).focus();
if ( fn ) {
fn.call( elem );
}
}, delay );
}) :
this._focus.apply( this, arguments );
},
scrollParent: function() {
var scrollParent;
if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
scrollParent = this.parents().filter(function() {
return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
}).eq(0);
} else {
scrollParent = this.parents().filter(function() {
return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
}).eq(0);
}
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
},
zIndex: function( zIndex ) {
if ( zIndex !== undefined ) {
return this.css( "zIndex", zIndex );
}
if ( this.length ) {
var elem = $( this[ 0 ] ), position, value;
while ( elem.length && elem[ 0 ] !== document ) {
// Ignore z-index if position is set to a value where z-index is ignored by the browser
// This makes behavior of this function consistent across browsers
// WebKit always returns auto if the element is positioned
position = elem.css( "position" );
if ( position === "absolute" || position === "relative" || position === "fixed" ) {
// IE returns 0 when zIndex is not specified
// other browsers return a string
// we ignore the case of nested elements with an explicit value of 0
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
value = parseInt( elem.css( "zIndex" ), 10 );
if ( !isNaN( value ) && value !== 0 ) {
return value;
}
}
elem = elem.parent();
}
}
return 0;
},
uniqueId: function() {
return this.each(function() {
if ( !this.id ) {
this.id = "ui-id-" + (++uuid);
}
});
},
removeUniqueId: function() {
return this.each(function() {
if ( runiqueId.test( this.id ) ) {
$( this ).removeAttr( "id" );
}
});
}
});
// selectors
function focusable( element, isTabIndexNotNaN ) {
var map, mapName, img,
nodeName = element.nodeName.toLowerCase();
if ( "area" === nodeName ) {
map = element.parentNode;
mapName = map.name;
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
return false;
}
img = $( "img[usemap=#" + mapName + "]" )[0];
return !!img && visible( img );
}
return ( /input|select|textarea|button|object/.test( nodeName ) ?
!element.disabled :
"a" === nodeName ?
element.href || isTabIndexNotNaN :
isTabIndexNotNaN) &&
// the element and all of its ancestors must be visible
visible( element );
}
function visible( element ) {
return $.expr.filters.visible( element ) &&
!$( element ).parents().andSelf().filter(function() {
return $.css( this, "visibility" ) === "hidden";
}).length;
}
$.extend( $.expr[ ":" ], {
data: $.expr.createPseudo ?
$.expr.createPseudo(function( dataName ) {
return function( elem ) {
return !!$.data( elem, dataName );
};
}) :
// support: jQuery <1.8
function( elem, i, match ) {
return !!$.data( elem, match[ 3 ] );
},
focusable: function( element ) {
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
},
tabbable: function( element ) {
var tabIndex = $.attr( element, "tabindex" ),
isTabIndexNaN = isNaN( tabIndex );
return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
}
});
// support
$(function() {
var body = document.body,
div = body.appendChild( div = document.createElement( "div" ) );
// access offsetHeight before setting the style to prevent a layout bug
// in IE 9 which causes the element to continue to take up space even
// after it is removed from the DOM (#8026)
div.offsetHeight;
$.extend( div.style, {
minHeight: "100px",
height: "auto",
padding: 0,
borderWidth: 0
});
$.support.minHeight = div.offsetHeight === 100;
$.support.selectstart = "onselectstart" in div;
// set display to none to avoid a layout bug in IE
// http://dev.jquery.com/ticket/4014
body.removeChild( div ).style.display = "none";
});
// support: jQuery <1.8
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
$.each( [ "Width", "Height" ], function( i, name ) {
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
type = name.toLowerCase(),
orig = {
innerWidth: $.fn.innerWidth,
innerHeight: $.fn.innerHeight,
outerWidth: $.fn.outerWidth,
outerHeight: $.fn.outerHeight
};
function reduce( elem, size, border, margin ) {
$.each( side, function() {
size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
if ( border ) {
size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
}
if ( margin ) {
size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
}
});
return size;
}
$.fn[ "inner" + name ] = function( size ) {
if ( size === undefined ) {
return orig[ "inner" + name ].call( this );
}
return this.each(function() {
$( this ).css( type, reduce( this, size ) + "px" );
});
};
$.fn[ "outer" + name] = function( size, margin ) {
if ( typeof size !== "number" ) {
return orig[ "outer" + name ].call( this, size );
}
return this.each(function() {
$( this).css( type, reduce( this, size, true, margin ) + "px" );
});
};
});
}
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
$.fn.removeData = (function( removeData ) {
return function( key ) {
if ( arguments.length ) {
return removeData.call( this, $.camelCase( key ) );
} else {
return removeData.call( this );
}
};
})( $.fn.removeData );
}
// deprecated
(function() {
var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
$.ui.ie = uaMatch.length ? true : false;
$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
})();
$.fn.extend({
disableSelection: function() {
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
".ui-disableSelection", function( event ) {
event.preventDefault();
});
},
enableSelection: function() {
return this.unbind( ".ui-disableSelection" );
}
});
$.extend( $.ui, {
// $.ui.plugin is deprecated. Use the proxy pattern instead.
plugin: {
add: function( module, option, set ) {
var i,
proto = $.ui[ module ].prototype;
for ( i in set ) {
proto.plugins[ i ] = proto.plugins[ i ] || [];
proto.plugins[ i ].push( [ option, set[ i ] ] );
}
},
call: function( instance, name, args ) {
var i,
set = instance.plugins[ name ];
if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
return;
}
for ( i = 0; i < set.length; i++ ) {
if ( instance.options[ set[ i ][ 0 ] ] ) {
set[ i ][ 1 ].apply( instance.element, args );
}
}
}
},
contains: $.contains,
// only used by resizable
hasScroll: function( el, a ) {
//If overflow is hidden, the element might have extra content, but the user wants to hide it
if ( $( el ).css( "overflow" ) === "hidden") {
return false;
}
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
has = false;
if ( el[ scroll ] > 0 ) {
return true;
}
// TODO: determine which cases actually cause this to happen
// if the element doesn't have the scroll set, see if it's possible to
// set the scroll
el[ scroll ] = 1;
has = ( el[ scroll ] > 0 );
el[ scroll ] = 0;
return has;
},
// these are odd functions, fix the API or move into individual plugins
isOverAxis: function( x, reference, size ) {
//Determines when x coordinate is over "b" element axis
return ( x > reference ) && ( x < ( reference + size ) );
},
isOver: function( y, x, top, left, height, width ) {
//Determines when x, y coordinates is over "b" element
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
}
});
})( jQuery );

169
octoprint/static/js/jquery.ui.mouse.js vendored Normal file
View File

@ -0,0 +1,169 @@
/*!
* jQuery UI Mouse 1.9.2
* http://jqueryui.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/mouse/
*
* Depends:
* jquery.ui.widget.js
*/
(function( $, undefined ) {
var mouseHandled = false;
$( document ).mouseup( function( e ) {
mouseHandled = false;
});
$.widget("ui.mouse", {
version: "1.9.2",
options: {
cancel: 'input,textarea,button,select,option',
distance: 1,
delay: 0
},
_mouseInit: function() {
var that = this;
this.element
.bind('mousedown.'+this.widgetName, function(event) {
return that._mouseDown(event);
})
.bind('click.'+this.widgetName, function(event) {
if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
$.removeData(event.target, that.widgetName + '.preventClickEvent');
event.stopImmediatePropagation();
return false;
}
});
this.started = false;
},
// TODO: make sure destroying one instance of mouse doesn't mess with
// other instances of mouse
_mouseDestroy: function() {
this.element.unbind('.'+this.widgetName);
if ( this._mouseMoveDelegate ) {
$(document)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
}
},
_mouseDown: function(event) {
// don't let more than one widget handle mouseStart
if( mouseHandled ) { return; }
// we may have missed mouseup (out of window)
(this._mouseStarted && this._mouseUp(event));
this._mouseDownEvent = event;
var that = this,
btnIsLeft = (event.which === 1),
// event.target.nodeName works around a bug in IE 8 with
// disabled inputs (#7620)
elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
return true;
}
this.mouseDelayMet = !this.options.delay;
if (!this.mouseDelayMet) {
this._mouseDelayTimer = setTimeout(function() {
that.mouseDelayMet = true;
}, this.options.delay);
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted = (this._mouseStart(event) !== false);
if (!this._mouseStarted) {
event.preventDefault();
return true;
}
}
// Click event may never have fired (Gecko & Opera)
if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
$.removeData(event.target, this.widgetName + '.preventClickEvent');
}
// these delegates are required to keep context
this._mouseMoveDelegate = function(event) {
return that._mouseMove(event);
};
this._mouseUpDelegate = function(event) {
return that._mouseUp(event);
};
$(document)
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
event.preventDefault();
mouseHandled = true;
return true;
},
_mouseMove: function(event) {
// IE mouseup check - mouseup happened when mouse was out of window
if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
return this._mouseUp(event);
}
if (this._mouseStarted) {
this._mouseDrag(event);
return event.preventDefault();
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted =
(this._mouseStart(this._mouseDownEvent, event) !== false);
(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
}
return !this._mouseStarted;
},
_mouseUp: function(event) {
$(document)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
if (this._mouseStarted) {
this._mouseStarted = false;
if (event.target === this._mouseDownEvent.target) {
$.data(event.target, this.widgetName + '.preventClickEvent', true);
}
this._mouseStop(event);
}
return false;
},
_mouseDistanceMet: function(event) {
return (Math.max(
Math.abs(this._mouseDownEvent.pageX - event.pageX),
Math.abs(this._mouseDownEvent.pageY - event.pageY)
) >= this.options.distance
);
},
_mouseDelayMet: function(event) {
return this.mouseDelayMet;
},
// These are placeholder methods, to be overriden by extending plugin
_mouseStart: function(event) {},
_mouseDrag: function(event) {},
_mouseStop: function(event) {},
_mouseCapture: function(event) { return true; }
});
})(jQuery);

644
octoprint/static/js/jquery.ui.slider.js vendored Normal file
View File

@ -0,0 +1,644 @@
/*!
* jQuery UI Slider 1.9.2
* http://jqueryui.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/slider/
*
* Depends:
* jquery.ui.core.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
*/
(function( $, undefined ) {
// number of pages in a slider
// (how many times can you page up/down to go through the whole range)
var numPages = 5;
$.widget( "ui.slider", $.ui.mouse, {
version: "1.9.2",
widgetEventPrefix: "slide",
options: {
animate: false,
distance: 0,
max: 100,
min: 0,
orientation: "horizontal",
range: false,
step: 1,
value: 0,
values: null
},
_create: function() {
var i, handleCount,
o = this.options,
existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
handles = [];
this._keySliding = false;
this._mouseSliding = false;
this._animateOff = true;
this._handleIndex = null;
this._detectOrientation();
this._mouseInit();
this.element
.addClass( "ui-slider" +
" ui-slider-" + this.orientation +
" ui-widget" +
" ui-widget-content" +
" ui-corner-all" +
( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
this.range = $([]);
if ( o.range ) {
if ( o.range === true ) {
if ( !o.values ) {
o.values = [ this._valueMin(), this._valueMin() ];
}
if ( o.values.length && o.values.length !== 2 ) {
o.values = [ o.values[0], o.values[0] ];
}
}
this.range = $( "<div></div>" )
.appendTo( this.element )
.addClass( "ui-slider-range" +
// note: this isn't the most fittingly semantic framework class for this element,
// but worked best visually with a variety of themes
" ui-widget-header" +
( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
}
handleCount = ( o.values && o.values.length ) || 1;
for ( i = existingHandles.length; i < handleCount; i++ ) {
handles.push( handle );
}
this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
this.handle = this.handles.eq( 0 );
this.handles.add( this.range ).filter( "a" )
.click(function( event ) {
event.preventDefault();
})
.mouseenter(function() {
if ( !o.disabled ) {
$( this ).addClass( "ui-state-hover" );
}
})
.mouseleave(function() {
$( this ).removeClass( "ui-state-hover" );
})
.focus(function() {
if ( !o.disabled ) {
$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
$( this ).addClass( "ui-state-focus" );
} else {
$( this ).blur();
}
})
.blur(function() {
$( this ).removeClass( "ui-state-focus" );
});
this.handles.each(function( i ) {
$( this ).data( "ui-slider-handle-index", i );
});
this._on( this.handles, {
keydown: function( event ) {
var allowed, curVal, newVal, step,
index = $( event.target ).data( "ui-slider-handle-index" );
switch ( event.keyCode ) {
case $.ui.keyCode.HOME:
case $.ui.keyCode.END:
case $.ui.keyCode.PAGE_UP:
case $.ui.keyCode.PAGE_DOWN:
case $.ui.keyCode.UP:
case $.ui.keyCode.RIGHT:
case $.ui.keyCode.DOWN:
case $.ui.keyCode.LEFT:
event.preventDefault();
if ( !this._keySliding ) {
this._keySliding = true;
$( event.target ).addClass( "ui-state-active" );
allowed = this._start( event, index );
if ( allowed === false ) {
return;
}
}
break;
}
step = this.options.step;
if ( this.options.values && this.options.values.length ) {
curVal = newVal = this.values( index );
} else {
curVal = newVal = this.value();
}
switch ( event.keyCode ) {
case $.ui.keyCode.HOME:
newVal = this._valueMin();
break;
case $.ui.keyCode.END:
newVal = this._valueMax();
break;
case $.ui.keyCode.PAGE_UP:
newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
break;
case $.ui.keyCode.PAGE_DOWN:
newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
break;
case $.ui.keyCode.UP:
case $.ui.keyCode.RIGHT:
if ( curVal === this._valueMax() ) {
return;
}
newVal = this._trimAlignValue( curVal + step );
break;
case $.ui.keyCode.DOWN:
case $.ui.keyCode.LEFT:
if ( curVal === this._valueMin() ) {
return;
}
newVal = this._trimAlignValue( curVal - step );
break;
}
this._slide( event, index, newVal );
},
keyup: function( event ) {
var index = $( event.target ).data( "ui-slider-handle-index" );
if ( this._keySliding ) {
this._keySliding = false;
this._stop( event, index );
this._change( event, index );
$( event.target ).removeClass( "ui-state-active" );
}
}
});
this._refreshValue();
this._animateOff = false;
},
_destroy: function() {
this.handles.remove();
this.range.remove();
this.element
.removeClass( "ui-slider" +
" ui-slider-horizontal" +
" ui-slider-vertical" +
" ui-slider-disabled" +
" ui-widget" +
" ui-widget-content" +
" ui-corner-all" );
this._mouseDestroy();
},
_mouseCapture: function( event ) {
var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
that = this,
o = this.options;
if ( o.disabled ) {
return false;
}
this.elementSize = {
width: this.element.outerWidth(),
height: this.element.outerHeight()
};
this.elementOffset = this.element.offset();
position = { x: event.pageX, y: event.pageY };
normValue = this._normValueFromMouse( position );
distance = this._valueMax() - this._valueMin() + 1;
this.handles.each(function( i ) {
var thisDistance = Math.abs( normValue - that.values(i) );
if ( distance > thisDistance ) {
distance = thisDistance;
closestHandle = $( this );
index = i;
}
});
// workaround for bug #3736 (if both handles of a range are at 0,
// the first is always used as the one with least distance,
// and moving it is obviously prevented by preventing negative ranges)
if( o.range === true && this.values(1) === o.min ) {
index += 1;
closestHandle = $( this.handles[index] );
}
allowed = this._start( event, index );
if ( allowed === false ) {
return false;
}
this._mouseSliding = true;
this._handleIndex = index;
closestHandle
.addClass( "ui-state-active" )
.focus();
offset = closestHandle.offset();
mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
top: event.pageY - offset.top -
( closestHandle.height() / 2 ) -
( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
};
if ( !this.handles.hasClass( "ui-state-hover" ) ) {
this._slide( event, index, normValue );
}
this._animateOff = true;
return true;
},
_mouseStart: function() {
return true;
},
_mouseDrag: function( event ) {
var position = { x: event.pageX, y: event.pageY },
normValue = this._normValueFromMouse( position );
this._slide( event, this._handleIndex, normValue );
return false;
},
_mouseStop: function( event ) {
this.handles.removeClass( "ui-state-active" );
this._mouseSliding = false;
this._stop( event, this._handleIndex );
this._change( event, this._handleIndex );
this._handleIndex = null;
this._clickOffset = null;
this._animateOff = false;
return false;
},
_detectOrientation: function() {
this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
},
_normValueFromMouse: function( position ) {
var pixelTotal,
pixelMouse,
percentMouse,
valueTotal,
valueMouse;
if ( this.orientation === "horizontal" ) {
pixelTotal = this.elementSize.width;
pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
} else {
pixelTotal = this.elementSize.height;
pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
}
percentMouse = ( pixelMouse / pixelTotal );
if ( percentMouse > 1 ) {
percentMouse = 1;
}
if ( percentMouse < 0 ) {
percentMouse = 0;
}
if ( this.orientation === "vertical" ) {
percentMouse = 1 - percentMouse;
}
valueTotal = this._valueMax() - this._valueMin();
valueMouse = this._valueMin() + percentMouse * valueTotal;
return this._trimAlignValue( valueMouse );
},
_start: function( event, index ) {
var uiHash = {
handle: this.handles[ index ],
value: this.value()
};
if ( this.options.values && this.options.values.length ) {
uiHash.value = this.values( index );
uiHash.values = this.values();
}
return this._trigger( "start", event, uiHash );
},
_slide: function( event, index, newVal ) {
var otherVal,
newValues,
allowed;
if ( this.options.values && this.options.values.length ) {
otherVal = this.values( index ? 0 : 1 );
if ( ( this.options.values.length === 2 && this.options.range === true ) &&
( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
) {
newVal = otherVal;
}
if ( newVal !== this.values( index ) ) {
newValues = this.values();
newValues[ index ] = newVal;
// A slide can be canceled by returning false from the slide callback
allowed = this._trigger( "slide", event, {
handle: this.handles[ index ],
value: newVal,
values: newValues
} );
otherVal = this.values( index ? 0 : 1 );
if ( allowed !== false ) {
this.values( index, newVal, true );
}
}
} else {
if ( newVal !== this.value() ) {
// A slide can be canceled by returning false from the slide callback
allowed = this._trigger( "slide", event, {
handle: this.handles[ index ],
value: newVal
} );
if ( allowed !== false ) {
this.value( newVal );
}
}
}
},
_stop: function( event, index ) {
var uiHash = {
handle: this.handles[ index ],
value: this.value()
};
if ( this.options.values && this.options.values.length ) {
uiHash.value = this.values( index );
uiHash.values = this.values();
}
this._trigger( "stop", event, uiHash );
},
_change: function( event, index ) {
if ( !this._keySliding && !this._mouseSliding ) {
var uiHash = {
handle: this.handles[ index ],
value: this.value()
};
if ( this.options.values && this.options.values.length ) {
uiHash.value = this.values( index );
uiHash.values = this.values();
}
this._trigger( "change", event, uiHash );
}
},
value: function( newValue ) {
if ( arguments.length ) {
this.options.value = this._trimAlignValue( newValue );
this._refreshValue();
this._change( null, 0 );
return;
}
return this._value();
},
values: function( index, newValue ) {
var vals,
newValues,
i;
if ( arguments.length > 1 ) {
this.options.values[ index ] = this._trimAlignValue( newValue );
this._refreshValue();
this._change( null, index );
return;
}
if ( arguments.length ) {
if ( $.isArray( arguments[ 0 ] ) ) {
vals = this.options.values;
newValues = arguments[ 0 ];
for ( i = 0; i < vals.length; i += 1 ) {
vals[ i ] = this._trimAlignValue( newValues[ i ] );
this._change( null, i );
}
this._refreshValue();
} else {
if ( this.options.values && this.options.values.length ) {
return this._values( index );
} else {
return this.value();
}
}
} else {
return this._values();
}
},
_setOption: function( key, value ) {
var i,
valsLength = 0;
if ( $.isArray( this.options.values ) ) {
valsLength = this.options.values.length;
}
$.Widget.prototype._setOption.apply( this, arguments );
switch ( key ) {
case "disabled":
if ( value ) {
this.handles.filter( ".ui-state-focus" ).blur();
this.handles.removeClass( "ui-state-hover" );
this.handles.prop( "disabled", true );
this.element.addClass( "ui-disabled" );
} else {
this.handles.prop( "disabled", false );
this.element.removeClass( "ui-disabled" );
}
break;
case "orientation":
this._detectOrientation();
this.element
.removeClass( "ui-slider-horizontal ui-slider-vertical" )
.addClass( "ui-slider-" + this.orientation );
this._refreshValue();
break;
case "value":
this._animateOff = true;
this._refreshValue();
this._change( null, 0 );
this._animateOff = false;
break;
case "values":
this._animateOff = true;
this._refreshValue();
for ( i = 0; i < valsLength; i += 1 ) {
this._change( null, i );
}
this._animateOff = false;
break;
case "min":
case "max":
this._animateOff = true;
this._refreshValue();
this._animateOff = false;
break;
}
},
//internal value getter
// _value() returns value trimmed by min and max, aligned by step
_value: function() {
var val = this.options.value;
val = this._trimAlignValue( val );
return val;
},
//internal values getter
// _values() returns array of values trimmed by min and max, aligned by step
// _values( index ) returns single value trimmed by min and max, aligned by step
_values: function( index ) {
var val,
vals,
i;
if ( arguments.length ) {
val = this.options.values[ index ];
val = this._trimAlignValue( val );
return val;
} else {
// .slice() creates a copy of the array
// this copy gets trimmed by min and max and then returned
vals = this.options.values.slice();
for ( i = 0; i < vals.length; i+= 1) {
vals[ i ] = this._trimAlignValue( vals[ i ] );
}
return vals;
}
},
// returns the step-aligned value that val is closest to, between (inclusive) min and max
_trimAlignValue: function( val ) {
if ( val <= this._valueMin() ) {
return this._valueMin();
}
if ( val >= this._valueMax() ) {
return this._valueMax();
}
var step = ( this.options.step > 0 ) ? this.options.step : 1,
valModStep = (val - this._valueMin()) % step,
alignValue = val - valModStep;
if ( Math.abs(valModStep) * 2 >= step ) {
alignValue += ( valModStep > 0 ) ? step : ( -step );
}
// Since JavaScript has problems with large floats, round
// the final value to 5 digits after the decimal point (see #4124)
return parseFloat( alignValue.toFixed(5) );
},
_valueMin: function() {
return this.options.min;
},
_valueMax: function() {
return this.options.max;
},
_refreshValue: function() {
var lastValPercent, valPercent, value, valueMin, valueMax,
oRange = this.options.range,
o = this.options,
that = this,
animate = ( !this._animateOff ) ? o.animate : false,
_set = {};
if ( this.options.values && this.options.values.length ) {
this.handles.each(function( i ) {
valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
if ( that.options.range === true ) {
if ( that.orientation === "horizontal" ) {
if ( i === 0 ) {
that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
}
if ( i === 1 ) {
that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
}
} else {
if ( i === 0 ) {
that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
}
if ( i === 1 ) {
that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
}
}
}
lastValPercent = valPercent;
});
} else {
value = this.value();
valueMin = this._valueMin();
valueMax = this._valueMax();
valPercent = ( valueMax !== valueMin ) ?
( value - valueMin ) / ( valueMax - valueMin ) * 100 :
0;
_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
if ( oRange === "min" && this.orientation === "horizontal" ) {
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
}
if ( oRange === "max" && this.orientation === "horizontal" ) {
this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
}
if ( oRange === "min" && this.orientation === "vertical" ) {
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
}
if ( oRange === "max" && this.orientation === "vertical" ) {
this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
}
}
}
});
}(jQuery));

View File

@ -669,7 +669,8 @@ function GcodeFilesViewModel() {
})
}
self.removeFile = function(filename) {
self.removeFile = function() {
var filename = this.name;
$.ajax({
url: AJAX_BASEURL + "gcodefiles/delete",
type: "POST",
@ -811,7 +812,70 @@ function WebcamViewModel() {
}
}
function DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, controlsViewModel, speedViewModel, terminalViewModel, gcodeFilesViewModel, webcamViewModel) {
function GcodeViewModel() {
var self = this;
self.loadedFilename = undefined;
self.status = 'idle';
self.enabled = false;
self.initialize = function(){
self.enabled = true;
GCODE.ui.initHandlers();
}
self.loadFile = function(filename){
if(self.status == 'idle'){
self.status = 'request';
$.ajax({
url: "gcodefile/"+filename,
type: "GET",
success: function(response, rstatus) {
if(rstatus === 'success'){
self.showGCodeViewer(response, rstatus);
self.loadedFilename=filename;
self.status = 'idle';
}
},
error: function() {
self.status = 'idle';
}
})
}
}
self.showGCodeViewer = function(response, rstatus){
var par = {};
par.target = {};
par.target.result = response;
GCODE.gCodeReader.loadFile(par);
}
self.fromHistoryData = function(data) {
self._processData(data);
}
self.fromCurrentData = function(data) {
self._processData(data);
}
self._processData = function(data) {
if(!self.enabled)return;
if(self.loadedFilename == data.job.filename){
var cmdIndex = GCODE.gCodeReader.getLinesCmdIndex(data.progress.progress);
if(cmdIndex){
GCODE.renderer.render(cmdIndex.layer, 0, cmdIndex.cmd);
GCODE.ui.updateLayerInfo(cmdIndex.layer);
}
}else{
self.loadFile(data.job.filename);
}
}
}
function DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, controlsViewModel, speedViewModel, terminalViewModel, gcodeFilesViewModel, webcamViewModel, gcodeViewModel) {
var self = this;
self.connectionViewModel = connectionViewModel;
@ -822,6 +886,7 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
self.speedViewModel = speedViewModel;
self.gcodeFilesViewModel = gcodeFilesViewModel;
self.webcamViewModel = webcamViewModel;
self.gcodeViewModel = gcodeViewModel;
self._socket = io.connect();
self._socket.on("connect", function() {
@ -852,6 +917,7 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
self.controlsViewModel.fromHistoryData(data);
self.terminalViewModel.fromHistoryData(data);
self.webcamViewModel.fromHistoryData(data);
self.gcodeViewModel.fromHistoryData(data);
})
self._socket.on("current", function(data) {
self.connectionViewModel.fromCurrentData(data);
@ -860,6 +926,7 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
self.controlsViewModel.fromCurrentData(data);
self.terminalViewModel.fromCurrentData(data);
self.webcamViewModel.fromCurrentData(data);
self.gcodeViewModel.fromCurrentData(data);
})
self._socket.on("updateTrigger", function(type) {
if (type == "gcodeFiles") {
@ -883,6 +950,18 @@ $(function() {
var terminalViewModel = new TerminalViewModel();
var gcodeFilesViewModel = new GcodeFilesViewModel();
var webcamViewModel = new WebcamViewModel();
var gcodeViewModel = new GcodeViewModel();
var dataUpdater = new DataUpdater(
connectionViewModel,
printerStateViewModel,
temperatureViewModel,
controlsViewModel,
speedViewModel,
terminalViewModel,
gcodeFilesViewModel,
webcamViewModel,
gcodeViewModel
);
var dataUpdater = new DataUpdater(
connectionViewModel,
@ -1046,7 +1125,10 @@ $(function() {
if (webcamElement) {
ko.applyBindings(webcamViewModel, document.getElementById("webcam"));
}
var gCodeVisualizerElement = document.getElementById("tab2d");
if(gCodeVisualizerElement){
gcodeViewModel.initialize();
}
//~~ startup commands
connectionViewModel.requestData();

View File

@ -8,6 +8,8 @@
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='css/jquery.fileupload-ui.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='css/ui.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='gcodeviewer/css/cupertino/jquery-ui-1.9.0.custom.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='gcodeviewer/css/style.css') }}" rel="stylesheet" media="screen">
<script lang="javascript">
var AJAX_BASEURL = "/ajax/";
@ -124,6 +126,7 @@
<ul class="nav nav-tabs" id="tabs">
<li class="active"><a href="#temp" data-toggle="tab">Temperature</a></li>
<li><a href="#controls" data-toggle="tab">Controls</a></li>
{% if gCodeVisualizer %}<li><a href="#tab2d" data-toggle="tab">GCode Viewer</a></li>{% endif %}
<!--<li><a href="#speed" data-toggle="tab">Speed</a></li>-->
<li><a href="#term" data-toggle="tab">Terminal</a></li>
{% if webcamStream %}<li><a href="#webcam" data-toggle="tab">Webcam</a></li>{% endif %}
@ -241,6 +244,92 @@
</div>
</div>
</div>
<div class="tab-pane" id="tab2d">
<canvas id="canvas" width="572" height="588"></canvas>
<div id="slider-vertical"></div>
<div id="slider-horizontal"></div>
<div id="accordion2" class="accordion">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#progressAccordionTab">
Progress indicators
</a>
</div>
<div id="progressAccordionTab" class="accordion-body collapse">
<div class="accordion-inner">
<div id="progressBlock">
<div class="progress" >
<div id="loadProgress" class="bar" style="width: 0%;"></div>
</div>
<div class="progress" >
<div id="analyzeProgress" class="bar" style="width: 0%;"></div>
</div>
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#infoAccordionTab">
Model info
</a>
</div>
<div id="infoAccordionTab" class="accordion-body collapse">
<div class="accordion-inner">
<p id="list"></p>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#layerAccordionTab">
Layer Info
</a>
</div>
<div id="layerAccordionTab" class="accordion-body collapse">
<div class="accordion-inner">
<p id="layerInfo"></p>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#options2DAccordionTab">
2D Render options
</a>
</div>
<div id="options2DAccordionTab" class="accordion-body collapse">
<div class="accordion-inner">
<input type="checkbox" id="showMovesCheckbox" value="1" onclick="GCODE.ui.processOptions()" checked>Show non-extrusion moves</input><br>
<input type="checkbox" id="showRetractsCheckbox" value="2" onclick="GCODE.ui.processOptions()" checked>Show retracts and restarts</input><br>
<input type="checkbox" id="moveModelCheckbox" value="3" onclick="GCODE.ui.processOptions()" checked>Move model to the center of the grid</input><br>
<input type="checkbox" id="differentiateColorsCheckbox" value="7" onclick="GCODE.ui.processOptions()" checked>Show different speeds with different colors</input><br>
<input type="checkbox" id="thickExtrusionCheckbox" value="8" onclick="GCODE.ui.processOptions()">Emulate extrusion width</input><br>
Width modifier: <input type="text" value="2" id="widthModifier" onchange="GCODE.ui.processOptions()"/><br>
<input type="checkbox" id="showNextLayer" value="9" onclick="GCODE.ui.processOptions()" >Show +1 layer</input><br>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#analyzeOptionsAccordioinTab">
GCode analyzer options
</a>
</div>
<div id="analyzeOptionsAccordioinTab" class="accordion-body collapse">
<div class="accordion-inner">
These require re-analyzing file:<br>
<input type="checkbox" id="sortLayersCheckbox" value="4" onclick="GCODE.ui.processOptions()" checked>Sort layers by Z</input><br>
<input type="checkbox" id="purgeEmptyLayersCheckbox" value="5" onclick="GCODE.ui.processOptions()" checked>Hide empty layers</input><br>
<input type="checkbox" id="showGCodeCheckbox" value="6" onclick="GCODE.ui.processOptions()" checked>Show GCode in GCode tab (memory intensive!)</input><br>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="term">
<pre id="terminal-output" class="pre-scrollable"></pre>
<label class="checkbox">
@ -327,11 +416,20 @@
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ url_for('static', filename='js/knockout-2.2.1.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.ui.core.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.ui.widget.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.ui.mouse.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.ui.slider.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.iframe-transport.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.fileupload.js') }}"></script>
<script src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script src="{{ url_for('static', filename='js/ui.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='gcodeviewer/lib/modernizr.custom.09684.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='gcodeviewer/js/ui.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='gcodeviewer/js/gCodeReader.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='gcodeviewer/js/renderer.js') }}"></script>
<!--<script type="text/javascript" src="{{ url_for('static', filename='gcodeviewer/lib/jquery-ui-1.9.0.custom.js') }}"></script>-->
</body>
</html>