From: Joseph Coffland Date: Sun, 30 Sep 2018 08:04:05 +0000 (-0700) Subject: Added path view, better camera support X-Git-Url: https://git.buildbotics.com/?a=commitdiff_plain;h=a271b2c17917dedc400d3040016dadc883f0547c;p=bbctrl-firmware Added path view, better camera support --- diff --git a/CHANGELOG.md b/CHANGELOG.md index c0aece3..1c8da4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Buildbotics CNC Controller Firmware Changelog - Move camera video to header. - Click to switch through three video sizes. - Automount/unmount USB drives. + - Automatically install ``buildbotics.gc`` when no other GCode exists. ## v0.3.28 - Show step rate on motor configuration page. diff --git a/MANIFEST.in b/MANIFEST.in index 2c0a49c..62b99b0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,5 +2,6 @@ recursive-include src/py/bbctrl/http * include package.json README.md scripts/install.sh include src/avr/bbctrl-avr-firmware.hex include scripts/avr109-flash.py +include scripts/buildbotics.gc recursive-include src/py/camotics * global-exclude .gitignore diff --git a/Makefile b/Makefile index 2810fe1..85f51f3 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,9 @@ DIR := $(shell dirname $(lastword $(MAKEFILE_LIST))) NODE_MODS := $(DIR)/node_modules -JADE := $(NODE_MODS)/jade/bin/jade.js -STYLUS := $(NODE_MODS)/stylus/bin/stylus -AP := $(NODE_MODS)/autoprefixer/autoprefixer -BROWSERIFY := $(NODE_MODS)/browserify/bin/cmd.js +PUG := $(NODE_MODS)/.bin/pug +STYLUS := $(NODE_MODS)/.bin/stylus +BROWSERIFY := $(NODE_MODS)/.bin/browserify TARGET := build/http HTML := index @@ -12,10 +11,10 @@ HTML := $(patsubst %,$(TARGET)/%.html,$(HTML)) CSS := $(wildcard src/stylus/*.styl) CSS_ASSETS := build/css/style.css JS := $(wildcard src/js/*.js) -JS_ASSETS := $(TARGET)/js/assets.js +JS_ASSETS := build/js/assets.js STATIC := $(shell find src/resources -type f) STATIC := $(patsubst src/resources/%,$(TARGET)/%,$(STATIC)) -TEMPLS := $(wildcard src/jade/templates/*.jade) +TEMPLS := $(wildcard src/pug/templates/*.pug) AVR_FIRMWARE := src/avr/bbctrl-avr-firmware.hex GPLAN_MOD := rpi-share/camotics/gplan.so @@ -44,7 +43,7 @@ ifndef DEST DEST=mnt endif -WATCH := src/jade src/jade/templates src/stylus src/js src/resources Makefile +WATCH := src/pug src/pug/templates src/stylus src/js src/resources Makefile all: html css js static @$(MAKE) -C src/avr @@ -95,6 +94,7 @@ update: pkg http_proxy= curl -i -X PUT -H "Content-Type: multipart/form-data" \ -F "firmware=@dist/$(PKG_NAME).tar.bz2" -F "password=$(PASSWORD)" \ http://$(HOST)/api/firmware/update + @-tput sgr0 && echo # Fix terminal output mount: mkdir -p $(DEST) @@ -115,22 +115,21 @@ js: $(JS_ASSETS) $(JS_ASSETS).sha256 static: $(STATIC) -templates: build/templates.jade +templates: build/templates.pug -build/templates.jade: $(TEMPLS) +build/templates.pug: $(TEMPLS) mkdir -p build cat $(TEMPLS) >$@ -build/hashes.jade: $(CSS_ASSETS).sha256 $(JS_ASSETS).sha256 +build/hashes.pug: $(CSS_ASSETS).sha256 $(JS_ASSETS).sha256 echo "- var css_hash = '$(shell cat $(CSS_ASSETS).sha256)'" > $@ echo "- var js_hash = '$(shell cat $(JS_ASSETS).sha256)'" >> $@ -$(TARGET)/index.html: build/templates.jade build/hashes.jade +$(TARGET)/index.html: build/templates.pug build/hashes.pug $(JS_ASSETS): $(JS) node_modules @mkdir -p $(shell dirname $@) - $(BROWSERIFY) src/js/main.js -s main -o $@ || \ - (rm -f $@; exit 1) + $(BROWSERIFY) src/js/main.js -s main -o $@ || (rm -f $@; exit 1) node_modules: npm install @@ -142,11 +141,11 @@ node_modules: $(TARGET)/%: src/resources/% install -D $< $@ -$(TARGET)/%.html: src/jade/%.jade $(wildcard src/jade/*.jade) node_modules +$(TARGET)/%.html: src/pug/%.pug $(wildcard src/pug/*.pug) node_modules @mkdir -p $(shell dirname $@) - $(JADE) -P $< -o $(TARGET) || (rm -f $@; exit 1) + $(PUG) -P $< -o $(TARGET) || (rm -f $@; exit 1) -build/css/%.css: src/stylus/%.styl node_modules +$(CSS_ASSETS): src/stylus/style.styl node_modules mkdir -p $(shell dirname $@) $(STYLUS) < $< > $@ || (rm -f $@; exit 1) diff --git a/package-lock.json b/package-lock.json index 9e7bec2..e87ebe8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bbctrl", - "version": "0.3.4", + "version": "0.3.29", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -9,7 +9,7 @@ "resolved": "https://registry.npmjs.org/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz", "integrity": "sha512-sFCUPzgeEjdq3rinwy4TFXtak2YZdhqpj6MdNusxkdTFr9TXAUEYK4YQSamR8Joqt/yii1drgl5hk8q/AtJDKA==", "requires": { - "acorn": "5.3.0" + "acorn": "^5.2.1" }, "dependencies": { "acorn": { @@ -19,43 +19,123 @@ } } }, + "@gulp-sourcemaps/identity-map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", + "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "requires": { + "acorn": "^5.0.3", + "css": "^2.2.1", + "normalize-path": "^2.1.1", + "source-map": "^0.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + } + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + } + }, + "@types/pug": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz", + "integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=" + }, "JSONStream": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" } }, - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" - }, - "acorn-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", - "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", + "accord": { + "version": "0.26.4", + "resolved": "https://registry.npmjs.org/accord/-/accord-0.26.4.tgz", + "integrity": "sha1-/EyNPrq0BqB8sogZuFllHESpLoA=", "requires": { - "acorn": "2.7.0" + "convert-source-map": "^1.2.0", + "glob": "^7.0.5", + "indx": "^0.2.3", + "lodash.clone": "^4.3.2", + "lodash.defaults": "^4.0.1", + "lodash.flatten": "^4.2.0", + "lodash.merge": "^4.4.0", + "lodash.partialright": "^4.1.4", + "lodash.pick": "^4.2.1", + "lodash.uniq": "^4.3.0", + "resolve": "^1.1.7", + "semver": "^5.3.0", + "uglify-js": "^2.7.0", + "when": "^3.7.7" }, "dependencies": { - "acorn": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", - "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=" + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + } } } }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "amdefine": { @@ -63,14 +143,78 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "ansi-colors": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", "requires": { - "color-convert": "1.9.1" + "ansi-wrap": "0.1.0" } }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + }, "array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", @@ -86,19 +230,29 @@ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" }, - "asap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", - "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0=" + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "asn1.js": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "assert": { @@ -109,51 +263,140 @@ "util": "0.10.3" } }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, "astw": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", "requires": { - "acorn": "4.0.13" + "acorn": "^4.0.3" } }, - "autoprefixer": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.5.tgz", - "integrity": "sha512-XqHfo8Ht0VU+T5P+eWEVoXza456KJ4l62BPewu3vpNf3LP9s2+zYXkXBznzYby4XeECXgG3N4i+hGvOhXErZmA==", - "requires": { - "browserslist": "2.11.1", - "caniuse-lite": "1.0.30000791", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "6.0.16", - "postcss-value-parser": "3.3.0" - } + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, "base64-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -164,11 +407,11 @@ "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", - "defined": "1.0.0", - "through2": "2.0.3", - "umd": "3.0.1" + "JSONStream": "^1.0.3", + "combine-source-map": "~0.7.1", + "defined": "^1.0.0", + "through2": "^2.0.0", + "umd": "^3.0.0" } }, "browser-resolve": { @@ -191,53 +434,53 @@ "resolved": "https://registry.npmjs.org/browserify/-/browserify-15.1.0.tgz", "integrity": "sha512-CulQKBiROFN+EssphwJEY4wWBACqWR1Iv+wxgO0GvOiweLb1Rwja4J/XbTCxx1ixTDK6llgUB3iG8fFxLBbJDA==", "requires": { - "JSONStream": "1.3.2", - "assert": "1.4.1", - "browser-pack": "6.0.2", - "browser-resolve": "1.11.2", - "browserify-zlib": "0.2.0", - "buffer": "5.0.8", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "defined": "1.0.0", - "deps-sort": "2.0.0", - "domain-browser": "1.1.7", - "duplexer2": "0.1.4", - "events": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "htmlescape": "1.1.1", - "https-browserify": "1.0.0", - "inherits": "2.0.3", - "insert-module-globals": "7.0.1", - "labeled-stream-splicer": "2.0.0", - "module-deps": "5.0.1", - "os-browserify": "0.3.0", - "parents": "1.0.1", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", - "resolve": "1.5.0", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.7.2", - "string_decoder": "1.0.3", - "subarg": "1.0.0", - "syntax-error": "1.3.0", - "through2": "2.0.3", - "timers-browserify": "1.4.2", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4", - "xtend": "4.0.1" + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.5.1", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "~1.1.0", + "duplexer2": "~0.1.2", + "events": "~1.1.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "module-deps": "^5.0.1", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "~1.0.0", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "~0.0.0", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "~0.0.1", + "xtend": "^4.0.0" } }, "browserify-aes": { @@ -245,12 +488,12 @@ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { @@ -258,9 +501,9 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, "browserify-des": { @@ -268,9 +511,9 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" } }, "browserify-rsa": { @@ -278,8 +521,8 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { - "bn.js": "4.11.8", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sign": { @@ -287,13 +530,13 @@ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, "browserify-zlib": { @@ -301,16 +544,7 @@ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { - "pako": "1.0.6" - } - }, - "browserslist": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.1.tgz", - "integrity": "sha512-Gp4oJOQOby5TpOJJuUtCrGE0KSJOUYVa/I+/3eD/TRWEK8jqZuJPAK1t+VuG6jp0keudrqtxlH4MbYbmylun9g==", - "requires": { - "caniuse-lite": "1.0.30000791", - "electron-to-chromium": "1.3.30" + "pako": "~1.0.5" } }, "buffer": { @@ -318,8 +552,8 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz", "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "buffer-xor": { @@ -332,6 +566,22 @@ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, "cached-path-relative": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", @@ -342,77 +592,84 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" }, - "caniuse-lite": { - "version": "1.0.30000791", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000791.tgz", - "integrity": "sha1-jjV0Xv1IOj4ju301CZAybSMZ/BY=" - }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" }, "dependencies": { - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", "requires": { - "has-flag": "2.0.0" + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" } } } }, - "character-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz", - "integrity": "sha1-wN3kqxgnE7kZuXCVmhI+zBow/NY=" - }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "requires": { - "commander": "2.8.1", - "source-map": "0.4.4" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "requires": { - "graceful-readlink": "1.0.1" - } - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "amdefine": "1.0.1" + "is-descriptor": "^0.1.0" } } } @@ -423,7 +680,7 @@ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", "requires": { "exit": "0.1.2", - "glob": "7.1.2" + "glob": "^7.1.1" } }, "cliui": { @@ -431,8 +688,8 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { @@ -443,28 +700,83 @@ } } }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "cloneable-readable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { - "color-name": "1.1.3" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "color-name": { + "color-support": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "combine-source-map": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" }, "dependencies": { "source-map": { @@ -474,10 +786,10 @@ } } }, - "commander": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", - "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=" + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "concat-map": { "version": "0.0.1", @@ -489,9 +801,9 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" }, "dependencies": { "readable-stream": { @@ -499,12 +811,12 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -514,12 +826,20 @@ } } }, + "concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", + "requires": { + "source-map": "^0.6.1" + } + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "constantinople": { @@ -527,7 +847,7 @@ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz", "integrity": "sha1-S5RdmTeQe82Y7ldRIsOBdRZUQUE=", "requires": { - "acorn": "2.7.0" + "acorn": "^2.1.0" }, "dependencies": { "acorn": { @@ -547,6 +867,11 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=" }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -557,8 +882,8 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.0" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, "create-hash": { @@ -566,10 +891,10 @@ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.9" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -577,12 +902,12 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.9" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "crypto-browserify": { @@ -590,43 +915,77 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "requires": { - "browserify-cipher": "1.0.0", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", - "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", - "randombytes": "2.0.6", - "randomfill": "1.0.3" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, - "css": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", - "integrity": "sha1-k4aBHKgrzMnuf7WnMrHioxfIo+c=", + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "requires": { - "css-parse": "1.0.4", - "css-stringify": "1.0.5" + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" } }, - "css-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz", - "integrity": "sha1-OLBQP7+dqfVOnB29pg4UXHcRe90=" + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } }, - "css-stringify": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", - "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE=" + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" + }, + "csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "requires": { + "css-tree": "1.0.0-alpha.29" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -635,25 +994,102 @@ "ms": "2.0.0" } }, + "debug-fabulous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", + "requires": { + "debug": "3.X", + "memoizee": "0.4.X", + "object-assign": "4.X" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" + }, "deps-sort": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "requires": { - "JSONStream": "1.3.2", - "shasum": "1.0.2", - "subarg": "1.0.0", - "through2": "2.0.3" + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" } }, "des.js": { @@ -661,18 +1097,28 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + }, "detective": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/detective/-/detective-5.0.2.tgz", "integrity": "sha512-NUsLoezj4wb9o7vpxS9F3L5vcO87ceyRBcl48op06YFNwkyIEY997JpSCA5lDlDuDc6JxOtaL5qfK3muoWxpMA==", "requires": { - "@browserify/acorn5-object-spread": "5.0.1", - "acorn": "5.3.0", - "defined": "1.0.0" + "@browserify/acorn5-object-spread": "^5.0.1", + "acorn": "^5.2.1", + "defined": "^1.0.0" }, "dependencies": { "acorn": { @@ -687,18 +1133,23 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "requires": { - "bn.js": "4.11.8", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" + "domelementtype": "~1.1.1", + "entities": "~1.1.1" }, "dependencies": { "domelementtype": { @@ -728,7 +1179,7 @@ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", "requires": { - "domelementtype": "1.3.0" + "domelementtype": "1" } }, "domutils": { @@ -736,29 +1187,21 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" + "dom-serializer": "0", + "domelementtype": "1" } }, + "duplexer": { + "version": "0.1.1", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "requires": { - "readable-stream": "2.3.3" - } - }, - "electron-releases": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", - "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==" - }, - "electron-to-chromium": { - "version": "1.3.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", - "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", - "requires": { - "electron-releases": "2.1.0" + "readable-stream": "^2.0.2" } }, "elliptic": { @@ -766,13 +1209,31 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "requires": { + "once": "~1.3.0" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + } } }, "entities": { @@ -780,11 +1241,75 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" }, + "es5-ext": { + "version": "0.10.46", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", + "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "event-stream": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz", + "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==", + "requires": { + "duplexer": "^0.1.1", + "flatmap-stream": "^0.1.0", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -795,8 +1320,8 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "exit": { @@ -804,8 +1329,244 @@ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" }, - "fs.realpath": { - "version": "1.0.0", + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "fancy-log": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "time-stamp": "^1.0.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "fined": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", + "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flagged-respawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" + }, + "flatmap-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz", + "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, + "fs.realpath": { + "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, @@ -814,43 +1575,503 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "requires": { + "globule": "~0.1.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "graceful-readlink": { + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "requires": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "requires": { + "gaze": "^0.5.1" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "requires": { + "find-index": "^0.1.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "requires": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "requires": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" + }, + "lodash": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } + } + }, + "glogg": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz", + "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", + "requires": { + "sparkles": "^1.0.0" + } + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "requires": { + "natives": "^1.1.0" + } + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "requires": { + "archy": "^1.0.0", + "chalk": "^1.0.0", + "deprecated": "^0.0.1", + "gulp-util": "^3.0.0", + "interpret": "^1.0.0", + "liftoff": "^2.1.0", + "minimist": "^1.1.0", + "orchestrator": "^0.3.0", + "pretty-hrtime": "^1.0.0", + "semver": "^4.1.0", + "tildify": "^1.0.0", + "v8flags": "^2.0.2", + "vinyl-fs": "^0.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "gulp-concat": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", + "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", + "requires": { + "concat-with-sourcemaps": "^1.0.0", + "through2": "^2.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "gulp-csso": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/gulp-csso/-/gulp-csso-3.0.1.tgz", + "integrity": "sha512-zhkvq06x1SJrpBN8YNJfc1PDono2+xjB6nI9UmBPh88nS4Weuz0hZMgJ4YruOw9Bf+oDrX71U6pkos6pIQhc1g==", + "requires": { + "csso": "^3.0.0", + "plugin-error": "^0.1.2", + "vinyl-sourcemaps-apply": "^0.2.1" + } + }, + "gulp-inline": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/gulp-inline/-/gulp-inline-0.1.3.tgz", + "integrity": "sha1-iYdqnJNORR12u8tkzAJErA5ZtHw=", + "requires": { + "cheerio": "^0.22.0", + "event-stream": "^3.3.4", + "gulp-util": "^3.0.7", + "through2": "^2.0.3" + } + }, + "gulp-pug": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/gulp-pug/-/gulp-pug-4.0.1.tgz", + "integrity": "sha512-RsayLPwJtKKMub9bbO4VYlMPVnImUPdK8+BjvkiulkorrjWnahTbI3a3Li/7YkD0xs7ap7ePciNiPwweoVEPMQ==", + "requires": { + "@types/pug": "^2.0.4", + "fancy-log": "^1.3.2", + "plugin-error": "^1.0.1", + "pug": "^2.0.3", + "replace-ext": "^1.0.0", + "through2": "^2.0.3" + }, + "dependencies": { + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + } + } + }, + "gulp-sourcemaps": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz", + "integrity": "sha1-y7IAhFCxvM5s0jv5gze+dRv24wo=", + "requires": { + "@gulp-sourcemaps/identity-map": "1.X", + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "5.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "1.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom-string": "1.X", + "through2": "2.X" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + } + } + }, + "gulp-stylus": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/gulp-stylus/-/gulp-stylus-2.7.0.tgz", + "integrity": "sha512-LlneLeHcaRBaEqxwo5YCirpsfkR7uleQ4pHXW8IE2ZeA6M3jpgI90+zQ6SptMTSWr1RSQW3WYFZVA3P0coUojw==", + "requires": { + "accord": "^0.26.3", + "lodash.assign": "^3.2.0", + "plugin-error": "^0.1.2", + "replace-ext": "0.0.1", + "stylus": "^0.54.0", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "requires": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "requires": { + "glogg": "^1.0.0" + } }, "has": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.0.2" } }, - "has-flag": { + "has-ansi": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } }, "hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "hash.js": { @@ -858,8 +2079,8 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" } }, "hmac-drbg": { @@ -867,9 +2088,17 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" } }, "htmlescape": { @@ -882,11 +2111,11 @@ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.3.0", - "domutils": "1.5.1", - "entities": "1.0.0", - "readable-stream": "1.1.14" + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" }, "dependencies": { "isarray": { @@ -899,10 +2128,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -927,13 +2156,18 @@ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, + "indx": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/indx/-/indx-0.2.3.tgz", + "integrity": "sha1-Fdz1bunPZcAjTFE8J/vVgOcPvFA=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -941,12 +2175,17 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, "inline-source-map": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "requires": { - "source-map": "0.5.7" + "source-map": "~0.5.3" }, "dependencies": { "source-map": { @@ -961,14 +2200,36 @@ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", - "concat-stream": "1.5.2", - "is-buffer": "1.1.6", - "lexical-scope": "1.2.0", - "process": "0.11.10", - "through2": "2.0.3", - "xtend": "4.0.1" + "JSONStream": "^1.0.3", + "combine-source-map": "~0.7.1", + "concat-stream": "~1.5.1", + "is-buffer": "^1.1.0", + "lexical-scope": "^1.2.0", + "process": "~0.11.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" } }, "is-buffer": { @@ -976,46 +2237,153 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", + "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", + "requires": { + "acorn": "~4.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "jade": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", - "integrity": "sha1-nIDlOMEtP7lcjZu5VZ+gzAQEBf0=", - "requires": { - "character-parser": "1.2.1", - "clean-css": "3.4.28", - "commander": "2.6.0", - "constantinople": "3.0.2", - "jstransformer": "0.0.2", - "mkdirp": "0.5.1", - "transformers": "2.1.0", - "uglify-js": "2.8.29", - "void-elements": "2.0.1", - "with": "4.0.3" - } + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" }, "jshint": { "version": "2.9.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", "requires": { - "cli": "1.0.1", - "console-browserify": "1.1.0", - "exit": "0.1.2", - "htmlparser2": "3.8.3", - "lodash": "3.7.0", - "minimatch": "3.0.4", - "shelljs": "0.3.0", - "strip-json-comments": "1.0.4" + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "3.7.x", + "minimatch": "~3.0.2", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x" } }, "json-stable-stringify": { @@ -1023,7 +2391,7 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "jsonify": { @@ -1036,21 +2404,12 @@ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" }, - "jstransformer": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz", - "integrity": "sha1-eq4pqQPRls+glz2IXT5HlH7Ndqs=", - "requires": { - "is-promise": "2.1.0", - "promise": "6.1.0" - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "labeled-stream-splicer": { @@ -1058,9 +2417,9 @@ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", "requires": { - "inherits": "2.0.3", - "isarray": "0.0.1", - "stream-splicer": "2.0.0" + "inherits": "^2.0.1", + "isarray": "~0.0.1", + "stream-splicer": "^2.0.0" }, "dependencies": { "isarray": { @@ -1070,41 +2429,314 @@ } } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lexical-scope": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "requires": { + "astw": "^2.0.0" + } + }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=" + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" + }, + "lodash._createassigner": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", + "requires": { + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" + } + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "lodash.assign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", + "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "requires": { + "lodash._root": "^3.0.0" + } + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" }, - "lexical-scope": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", - "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "requires": { - "astw": "2.2.0" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, - "lodash": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", - "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=" + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=" }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + }, + "lodash.partialright": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.partialright/-/lodash.partialright-4.2.1.tgz", + "integrity": "sha1-ATDYDoM2MmTUAHTzKbij56ihzEs=" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" }, "dependencies": { "hash-base": { @@ -1112,19 +2744,66 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } } } }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + }, + "memoizee": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "requires": { + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0" + "bn.js": "^4.0.0", + "brorand": "^1.0.1" } }, "minimalistic-assert": { @@ -1142,7 +2821,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1150,6 +2829,25 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -1170,21 +2868,21 @@ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-5.0.1.tgz", "integrity": "sha512-sigq/hm/L+Z5IGi1DDl0x2ptkw7S86aFh213QhPLD8v9Opv90IHzKIuWJrRa5bJ77DVKHco2CfIEuThcT/vDJA==", "requires": { - "JSONStream": "1.3.2", - "browser-resolve": "1.11.2", - "cached-path-relative": "1.0.1", - "concat-stream": "1.6.0", - "defined": "1.0.0", - "detective": "5.0.2", - "duplexer2": "0.1.4", - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.3", - "resolve": "1.5.0", - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", - "xtend": "4.0.1" + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.3", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" }, "dependencies": { "concat-stream": { @@ -1192,9 +2890,9 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } } } @@ -1204,37 +2902,190 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "normalize-range": { + "multipipe": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "~1.1.9" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "natives": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.5.tgz", + "integrity": "sha512-1pJ+02gl2KJgCPFtpZGtuD4lGSJnIZvvFHCQTOeDRMSXjfu2GmYWuhI8NFMA4W2I5NNFRbfy/YCiVt4CgNpP8A==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "requires": { + "boolbase": "~1.0.0" + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, - "optimist": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", - "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", "requires": { - "wordwrap": "0.0.3" + "end-of-stream": "~0.1.5", + "sequencify": "~0.0.7", + "stream-consume": "~0.1.0" } }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=" + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", @@ -1245,7 +3096,7 @@ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "requires": { - "path-platform": "0.11.15" + "path-platform": "~0.11.15" } }, "parse-asn1": { @@ -1253,13 +3104,33 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "requires": { - "asn1.js": "4.9.2", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", @@ -1280,32 +3151,94 @@ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=" }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "~2.3" + } + }, "pbkdf2": { "version": "3.0.14", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.9" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "postcss": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", - "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "5.1.0" + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=" + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=" + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=" + } } }, - "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "process": { "version": "0.11.10", @@ -1317,26 +3250,269 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, - "promise": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", - "integrity": "sha1-LOcp9rlLRcJoka0GAsXJDgTG7vY=", - "requires": { - "asap": "1.0.0" - } - }, "public-encrypt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "pug": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.3.tgz", + "integrity": "sha1-ccuoJTfJWl6rftBGluQiH1Oqh44=", + "requires": { + "pug-code-gen": "^2.0.1", + "pug-filters": "^3.1.0", + "pug-lexer": "^4.0.0", + "pug-linker": "^3.0.5", + "pug-load": "^2.0.11", + "pug-parser": "^5.0.0", + "pug-runtime": "^2.0.4", + "pug-strip-comments": "^1.0.3" + } + }, + "pug-attrs": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.3.tgz", + "integrity": "sha1-owlflw5kFR972tlX7vVftdeQXRU=", + "requires": { + "constantinople": "^3.0.1", + "js-stringify": "^1.0.1", + "pug-runtime": "^2.0.4" + } + }, + "pug-cli": { + "version": "1.0.0-alpha6", + "resolved": "https://registry.npmjs.org/pug-cli/-/pug-cli-1.0.0-alpha6.tgz", + "integrity": "sha1-HKU56krA67ac5KroSu7V1k/+ZQE=", + "requires": { + "chalk": "^1.0.0", + "commander": "^2.8.1", + "mkdirp": "^0.5.1", + "pug": "^2.0.0-alpha7" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "pug-code-gen": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.1.tgz", + "integrity": "sha1-CVHsgyJddNjPxHan+Zolm199BQw=", + "requires": { + "constantinople": "^3.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.1", + "pug-attrs": "^2.0.3", + "pug-error": "^1.3.2", + "pug-runtime": "^2.0.4", + "void-elements": "^2.0.1", + "with": "^5.0.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "^4.0.4" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "with": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", + "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", + "requires": { + "acorn": "^3.1.0", + "acorn-globals": "^3.0.0" + } + } + } + }, + "pug-error": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz", + "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY=" + }, + "pug-filters": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.0.tgz", + "integrity": "sha1-JxZVVbwEwjbkqisDZiRt+gIbYm4=", + "requires": { + "clean-css": "^4.1.11", + "constantinople": "^3.0.1", + "jstransformer": "1.0.0", + "pug-error": "^1.3.2", + "pug-walk": "^1.1.7", + "resolve": "^1.1.6", + "uglify-js": "^2.6.1" + }, + "dependencies": { + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "requires": { + "source-map": "~0.6.0" + } + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + } + } + }, + "pug-lexer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.0.0.tgz", + "integrity": "sha1-IQwYRX7y4XYCQnQMXmR715TOwng=", + "requires": { + "character-parser": "^2.1.1", + "is-expression": "^3.0.0", + "pug-error": "^1.3.2" + }, + "dependencies": { + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + } + } + }, + "pug-linker": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.5.tgz", + "integrity": "sha1-npp65ABWgtAn3uuWsAD4juuDoC8=", + "requires": { + "pug-error": "^1.3.2", + "pug-walk": "^1.1.7" } }, + "pug-load": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.11.tgz", + "integrity": "sha1-5kjlftET/iwfRdV4WOorrWvAFSc=", + "requires": { + "object-assign": "^4.1.0", + "pug-walk": "^1.1.7" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "pug-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.0.tgz", + "integrity": "sha1-45Stmz/KkxI5QK/4hcBuRKt+aOQ=", + "requires": { + "pug-error": "^1.3.2", + "token-stream": "0.0.1" + } + }, + "pug-runtime": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.4.tgz", + "integrity": "sha1-4XjhvaaKsujArPybztLFT9iM61g=" + }, + "pug-strip-comments": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.3.tgz", + "integrity": "sha1-8VWVkiBu3G+FMQ2s9K+0igJa9Z8=", + "requires": { + "pug-error": "^1.3.2" + } + }, + "pug-walk": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.7.tgz", + "integrity": "sha1-wA1cUSi6xYBr7BXSt+fNq+QlMfM=" + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -1357,7 +3533,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.1.0" } }, "randomfill": { @@ -1365,8 +3541,8 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, "read-only-stream": { @@ -1374,7 +3550,7 @@ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "requires": { - "readable-stream": "2.3.3" + "readable-stream": "^2.0.2" } }, "readable-stream": { @@ -1382,34 +3558,85 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" } }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "ripemd160": { @@ -1417,8 +3644,8 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", "requires": { - "hash-base": "2.0.2", - "inherits": "2.0.3" + "hash-base": "^2.0.0", + "inherits": "^2.0.1" } }, "safe-buffer": { @@ -1426,18 +3653,57 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, "sax": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "sha.js": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "shasum": { @@ -1445,8 +3711,8 @@ "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "requires": { - "json-stable-stringify": "0.0.1", - "sha.js": "2.4.9" + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" } }, "shell-quote": { @@ -1454,10 +3720,10 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "requires": { - "array-filter": "0.0.1", - "array-map": "0.0.0", - "array-reduce": "0.0.0", - "jsonify": "0.0.0" + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" } }, "shelljs": { @@ -1465,18 +3731,194 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" } }, "stream-combiner2": { @@ -1484,20 +3926,25 @@ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "requires": { - "duplexer2": "0.1.4", - "readable-stream": "2.3.3" + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" } }, + "stream-consume": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" + }, "stream-http": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.2.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" } }, "stream-splicer": { @@ -1505,8 +3952,8 @@ "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3" + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" } }, "string_decoder": { @@ -1514,9 +3961,31 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "requires": { + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" + } + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" + }, "strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", @@ -1527,12 +3996,12 @@ "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", "requires": { - "css-parse": "1.7.0", - "debug": "3.1.0", - "glob": "7.0.6", - "mkdirp": "0.5.1", - "sax": "0.5.8", - "source-map": "0.1.43" + "css-parse": "1.7.x", + "debug": "*", + "glob": "7.0.x", + "mkdirp": "0.5.x", + "sax": "0.5.x", + "source-map": "0.1.x" }, "dependencies": { "css-parse": { @@ -1545,12 +4014,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "source-map": { @@ -1558,7 +4027,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -1568,15 +4037,7 @@ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "requires": { - "minimist": "1.2.0" - } - }, - "supports-color": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", - "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", - "requires": { - "has-flag": "2.0.0" + "minimist": "^1.1.0" } }, "syntax-error": { @@ -1584,7 +4045,7 @@ "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", "requires": { - "acorn": "4.0.13" + "acorn": "^4.0.3" } }, "through": { @@ -1597,16 +4058,38 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" } }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, "timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "requires": { - "process": "0.11.10" + "process": "~0.11.0" + } + }, + "timers-ext": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.5.tgz", + "integrity": "sha512-tsEStd7kmACHENhsUPaxb8Jf8/+GZZxyNFQbZD07HQOyooOa6At1rQqjffgvg7n+dxscQa9cjjMdWhJtsP2sxg==", + "requires": { + "es5-ext": "~0.10.14", + "next-tick": "1" } }, "to-arraybuffer": { @@ -1614,48 +4097,39 @@ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" }, - "transformers": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", - "integrity": "sha1-XSPLNVYd2F3Gf7hIIwm0fVPM6ac=", + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { - "css": "1.0.8", - "promise": "2.0.0", - "uglify-js": "2.2.5" - }, - "dependencies": { - "is-promise": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", - "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" - }, - "promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz", - "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=", - "requires": { - "is-promise": "1.0.1" - } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "requires": { - "amdefine": "1.0.1" - } - }, - "uglify-js": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.2.5.tgz", - "integrity": "sha1-puAqcNg5eSuXgEiLe4sYTAlcmcc=", - "requires": { - "optimist": "0.3.7", - "source-map": "0.1.43" - } - } + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, + "token-stream": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", + "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -1667,19 +4141,18 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "commander": "~2.17.1", + "source-map": "~0.6.1" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" } } }, @@ -1694,6 +4167,89 @@ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=" }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -1710,6 +4266,16 @@ } } }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" + }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -1730,6 +4296,100 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "requires": { + "user-home": "^1.1.1" + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "requires": { + "defaults": "^1.0.0", + "glob-stream": "^3.1.5", + "glob-watcher": "^0.0.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "strip-bom": "^1.0.0", + "through2": "^0.6.1", + "vinyl": "^0.4.0" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + } + } + } + }, + "vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "requires": { + "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -1743,31 +4403,23 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + "when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" }, - "with": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz", - "integrity": "sha1-7v0VTp550sjTQXtkeo8U2f7M4U4=", + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { - "acorn": "1.2.2", - "acorn-globals": "1.0.9" - }, - "dependencies": { - "acorn": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", - "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" - } + "isexe": "^2.0.0" } }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" }, "wrappy": { "version": "1.0.2", @@ -1784,9 +4436,9 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } } diff --git a/package.json b/package.json index 5992cd8..42aff74 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,17 @@ "repository": "https://github.com/buildbotics/bbctrl-firmware", "license": "GPL-3.0+", "dependencies": { - "autoprefixer": ">=3.0.0", - "jade": ">=1.3.0", - "stylus": ">=0.42.3", "browserify": ">=8.1.1", - "jshint": "" + "gulp": "^3.9.1", + "gulp-concat": "^2.6.1", + "gulp-csso": "^3.0.1", + "gulp-inline": "^0.1.3", + "gulp-pug": "^4.0.1", + "gulp-sourcemaps": "^2.6.4", + "gulp-stylus": "^2.7.0", + "jshint": "", + "pug-cli": "^1.0.0-alpha6", + "stylus": ">=0.42.3", + "uglify-js": "^3.4.9" } } diff --git a/scripts/buildbotics.gc b/scripts/buildbotics.gc new file mode 100644 index 0000000..8c5ddb0 --- /dev/null +++ b/scripts/buildbotics.gc @@ -0,0 +1,403 @@ +G21 +(File: 'buildbotics_logo.tpl') +G0 Z3 +F1600 +M3 S10000 +M6 T2 +G0 X59.25 Y5.85 +G1 Z-1.5 +G1 X61.68 Y6.7 +G1 X63.86 Y8.07 +G1 X65.68 Y9.89 +G1 X67.05 Y12.07 +G1 X67.9 Y14.5 +G1 X68.2 Y17.09 +G1 Y56.6 +G1 X67.73 Y59.04 +G1 X50.8 +G1 Y34.9 +G1 X50.65 Y34.55 +G1 X50.3 Y34.4 +G1 X23.46 +G1 X23.1 Y34.55 +G1 X22.96 Y34.9 +G1 X22.98 Y49.88 +G1 X22.96 Y59.05 +G1 X22.41 +G1 X19.26 +G1 X6.04 +G1 X5.56 Y56.53 +G1 Y17.09 +G1 X5.85 Y14.5 +G1 X6.7 Y12.07 +G1 X8.07 Y9.89 +G1 X9.89 Y8.07 +G1 X12.07 Y6.7 +G1 X14.5 Y5.85 +G1 X17.09 Y5.56 +G1 X56.67 +G1 X59.25 Y5.85 +G0 Z3 +G0 X64.26 Y64.72 +G1 Z-1.5 +G1 X61.78 Y66.52 +G1 X58.91 Y67.68 +G1 X56.54 Y68.08 +G1 X17.22 +G1 X14.84 Y67.68 +G1 X11.97 Y66.52 +G1 X9.49 Y64.72 +G1 X8.08 Y63.16 +G1 X27.35 +G1 X27.89 Y63.45 +G1 X27.96 Y63.48 +G1 X31.48 Y64.75 +G1 X31.52 Y64.76 +G1 X31.56 Y64.77 +G1 X35.19 Y65.41 +G1 X35.26 +G1 X35.97 Y65.44 +G1 X36.04 Y65.45 +G1 X36.07 +G1 X36.82 Y65.44 +G1 X36.83 +G1 X36.89 +G1 X36.95 +G1 X36.97 +G1 X37.72 Y65.43 +G1 X37.74 +G1 X37.8 +G1 X37.81 +G1 X37.88 +G1 X37.89 +G1 X38.65 Y65.38 +G1 X38.68 +G1 X38.75 Y65.37 +G1 X39.38 Y65.32 +G1 X39.44 Y65.31 +G1 X42.68 Y64.64 +G1 X42.76 Y64.62 +G1 X45.87 Y63.44 +G1 X45.93 Y63.41 +G1 X46.4 Y63.16 +G1 X65.67 +G1 X64.26 Y64.72 +G0 Z3 +G0 X36.88 Y9.4 +G1 Z-1.5 +G1 X37.31 Y9.64 +G1 X39.58 Y13.48 +G1 X39.63 Y13.6 +G1 X39.65 Y13.73 +G1 Y27.54 +G1 X41.67 +G1 Y25.39 +G1 X41.75 Y25.12 +G1 X41.97 Y24.93 +G1 X46.41 Y22.92 +G1 Y19.97 +G1 X45.44 +G1 X45.08 Y19.82 +G1 X44.94 Y19.47 +G1 Y13.73 +G1 X45.08 Y13.38 +G1 X45.44 Y13.23 +G1 X49.94 Y13.24 +G1 X50.29 Y13.39 +G1 X50.44 Y13.74 +G1 Y19.47 +G1 X50.29 Y19.83 +G1 X49.93 Y19.97 +G1 X48.92 +G1 Y23.61 +G1 X48.84 Y23.88 +G1 X48.63 Y24.06 +G1 X44.19 Y26.12 +G1 Y27.54 +G1 X49.22 +G1 X49.33 Y27.56 +G1 X49.44 Y27.6 +G1 X50.13 Y27.94 +G1 X50.25 Y28.02 +G1 X50.34 Y28.13 +G1 X50.73 Y28.77 +G1 X50.78 Y28.89 +G1 X50.8 Y29.03 +G1 Y33.05 +G1 Y34.25 +G1 Y34.65 +G1 X50.66 Y35.01 +G1 X50.3 Y35.15 +G1 X23.46 +G1 X23.1 Y35.01 +G1 X22.96 Y34.65 +G1 Y29.07 +G1 X22.97 Y28.94 +G1 X23.02 Y28.82 +G1 X23.4 Y28.17 +G1 X23.49 Y28.06 +G1 X23.6 Y27.98 +G1 X24.29 Y27.6 +G1 X24.4 Y27.56 +G1 X24.52 Y27.54 +G1 X25.55 +G1 Y26.4 +G1 X23.4 Y25.52 +G1 X23.17 Y25.33 +G1 X23.09 Y25.06 +G1 Y17.54 +G1 X23.23 Y17.19 +G1 X23.59 Y17.04 +G1 X24.6 +G1 Y10.36 +G1 X24.62 Y10.23 +G1 X24.66 Y10.11 +G1 X24.8 Y9.88 +G1 X24.88 Y9.77 +G1 X24.99 Y9.68 +G1 X25.25 Y9.54 +G1 X25.37 Y9.5 +G1 X25.49 Y9.48 +G1 X26.53 +G1 X26.65 Y9.49 +G1 X26.76 Y9.54 +G1 X27.01 Y9.66 +G1 X27.12 Y9.74 +G1 X27.21 Y9.85 +G1 X27.35 Y10.09 +G1 X27.41 Y10.22 +G1 X27.43 Y10.35 +G1 Y10.43 +G1 X27.47 Y17.04 +G1 X28.57 +G1 X28.92 Y17.19 +G1 X29.07 Y17.54 +G1 Y24.64 +G1 X30.72 Y25.3 +G1 X30.95 Y25.49 +G1 X31.03 Y25.77 +G1 X31.02 Y27.54 +G1 X34.03 +G1 Y13.73 +G1 X34.05 Y13.59 +G1 X34.1 Y13.47 +G1 X36.45 Y9.64 +G1 X36.88 Y9.4 +G0 Z3 +G0 X49.94 Y10.82 +G1 Z-1.5 +G1 X50.29 Y10.97 +G1 X50.44 Y11.32 +G1 Y13.34 +G1 X50.29 Y13.69 +G1 X49.94 Y13.84 +G1 X45.44 +G1 X45.08 Y13.69 +G1 X44.94 Y13.34 +G1 Y11.32 +G1 X45.08 Y10.97 +G1 X45.44 Y10.82 +G1 X49.94 +G0 Z3 +G0 X48.46 Y9.7 +G1 Z-1.5 +G1 X48.59 Y9.72 +G1 X48.71 Y9.77 +G1 X50.03 Y10.53 +G1 X50.21 Y10.71 +G1 X50.28 Y10.96 +G1 X50.14 Y11.31 +G1 X49.78 Y11.46 +G1 X45.62 +G1 X45.14 Y11.09 +G1 X45.37 Y10.53 +G1 X46.69 Y9.77 +G1 X46.81 Y9.72 +G1 X46.94 Y9.7 +G1 X48.46 +G0 Z3 +G0 X50.3 Y34.4 +G1 Z-1.5 +G1 X50.66 Y34.55 +G1 X50.8 Y34.9 +G1 Y49.88 +G1 X50.79 Y59.52 +G1 X50.76 Y59.69 +G1 X50.67 Y59.84 +G1 X50.09 Y60.52 +G1 X50.06 Y60.55 +G1 X50.02 Y60.58 +G1 X47.89 Y62.26 +G1 X47.85 Y62.28 +G1 X47.81 Y62.31 +G1 X44.46 Y64.03 +G1 X44.41 Y64.05 +G1 X44.37 Y64.06 +G1 X40.69 Y65.1 +G1 X40.62 Y65.12 +G1 X37.86 Y65.45 +G1 X37.8 Y65.46 +G1 X36.89 Y65.44 +G1 X36.83 +G1 X36.82 +G1 X36.07 Y65.45 +G1 X36.04 Y65.44 +G1 X35.97 +G1 X35.1 Y65.41 +G1 X35.04 Y65.4 +G1 X32.44 Y64.99 +G1 X32.37 Y64.97 +G1 X28.94 Y63.9 +G1 X28.89 Y63.88 +G1 X28.85 Y63.86 +G1 X25.74 Y62.2 +G1 X25.7 Y62.18 +G1 X25.66 Y62.15 +G1 X23.68 Y60.56 +G1 X23.65 Y60.53 +G1 X23.62 Y60.5 +G1 X23.08 Y59.87 +G1 X22.99 Y59.71 +G1 X22.96 Y59.54 +G1 X22.98 Y49.88 +G1 X22.96 Y34.9 +G1 X23.1 Y34.55 +G1 X23.46 Y34.4 +G1 X50.3 +G0 Z3 +G0 X55.2 Y43.67 +G1 Z-1.5 +G1 Y51.34 +G1 X55.11 Y51.94 +G1 X54.83 Y52.88 +G1 X54.39 Y53.88 +G1 X53.8 Y54.85 +G1 X53.09 Y55.74 +G1 X52.28 Y56.47 +G1 X51.41 Y56.98 +G1 X51.07 Y57.09 +G1 Y43.67 +G1 X55.2 +G0 Z3 +G0 X22.69 Y43.63 +G1 Z-1.5 +G1 Y57.09 +G1 X22.35 Y56.98 +G1 X21.47 Y56.47 +G1 X20.67 Y55.74 +G1 X19.95 Y54.85 +G1 X19.36 Y53.88 +G1 X18.92 Y52.88 +G1 X18.64 Y51.94 +G1 X18.55 Y51.34 +G1 Y43.63 +G1 X22.69 +G0 Z3 +G0 X28.55 Y35.84 +G1 Z-0.99 +G1 X30.11 Y36.15 +G1 X31.43 Y37.03 +G1 X32.32 Y38.35 +G1 X32.63 Y39.91 +G1 X32.32 Y41.47 +G1 X31.43 Y42.79 +G1 X30.11 Y43.68 +G1 X28.55 Y43.99 +G1 X26.99 Y43.68 +G1 X25.67 Y42.79 +G1 X24.79 Y41.47 +G1 X24.48 Y39.91 +G1 X24.79 Y38.35 +G1 X25.67 Y37.03 +G1 X26.99 Y36.15 +G1 X28.55 Y35.84 +G0 Z3 +G0 X45.33 Y35.93 +G1 Z-0.99 +G1 X46.88 Y36.24 +G1 X48.21 Y37.12 +G1 X49.09 Y38.45 +G1 X49.4 Y40 +G1 X49.09 Y41.56 +G1 X48.21 Y42.88 +G1 X46.88 Y43.77 +G1 X45.33 Y44.08 +G1 X43.77 Y43.77 +G1 X42.45 Y42.88 +G1 X41.56 Y41.56 +G1 X41.25 Y40 +G1 X41.56 Y38.45 +G1 X42.45 Y37.12 +G1 X43.77 Y36.24 +G1 X45.33 Y35.93 +G0 Z3 +G0 X45.2 Y39.12 +G1 Z-0.99 +G1 X45.7 Y39.19 +G1 X46.07 Y39.52 +G1 X46.22 Y40 +G1 X46.07 Y40.49 +G1 X45.7 Y40.81 +G1 X45.2 Y40.89 +G1 X44.74 Y40.68 +G1 X44.47 Y40.26 +G1 Y39.75 +G1 X44.74 Y39.33 +G1 X45.2 Y39.12 +G0 Z3 +G0 X28.43 Y39.03 +G1 Z-0.99 +G1 X28.92 Y39.1 +G1 X29.3 Y39.43 +G1 X29.44 Y39.91 +G1 X29.3 Y40.4 +G1 X28.92 Y40.72 +G1 X28.43 Y40.8 +G1 X27.97 Y40.59 +G1 X27.7 Y40.16 +G1 Y39.66 +G1 X27.97 Y39.24 +G1 X28.43 Y39.03 +G0 Z3 +G0 X55.76 Y0 +G1 Z-1.5 +G1 X59.27 Y0.35 +G1 X62.65 Y1.37 +G1 X65.76 Y3.03 +G1 X68.49 Y5.27 +G1 X70.73 Y8 +G1 X72.39 Y11.11 +G1 X73.42 Y14.49 +G1 X73.76 Y18 +G1 Y55.69 +G1 X73.42 Y59.2 +G1 X72.39 Y62.57 +G1 X70.73 Y65.69 +G1 X68.49 Y68.41 +G1 X65.76 Y70.65 +G1 X62.65 Y72.31 +G1 X59.27 Y73.34 +G1 X55.76 Y73.69 +G1 X18 +G1 X14.49 Y73.34 +G1 X11.11 Y72.31 +G1 X8 Y70.65 +G1 X5.27 Y68.41 +G1 X3.03 Y65.69 +G1 X1.37 Y62.57 +G1 X0.35 Y59.2 +G1 X0 Y55.69 +G1 Y18 +G1 X0.35 Y14.49 +G1 X1.37 Y11.11 +G1 X3.03 Y8 +G1 X5.27 Y5.27 +G1 X8 Y3.03 +G1 X11.11 Y1.37 +G1 X14.49 Y0.35 +G1 X18 Y0 +G1 X55.76 +G0 Z3 +M5 +G0 X40 Y75 +M2 diff --git a/scripts/install.sh b/scripts/install.sh index ba7a344..b73ba25 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -89,6 +89,11 @@ if [ ! -e /etc/udev/rules.d/11-automount.rules ]; then REBOOT=true fi +# Install default GCode +if [ -z "$(ls -A /var/lib/bbctrl/upload)" ]; then + cp scripts/buildbotics.gc /var/lib/bbctrl/upload/ +fi + if $UPDATE_PY; then rm -rf /usr/local/lib/python*/dist-packages/bbctrl-* ./setup.py install --force diff --git a/scripts/ssh-bbctrl b/scripts/ssh-bbctrl index b7438ac..ad9ed9a 100755 --- a/scripts/ssh-bbctrl +++ b/scripts/ssh-bbctrl @@ -13,4 +13,4 @@ else LOGIN=$USER@$HOST fi -ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$LOGIN" +ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$LOGIN" diff --git a/src/jade/index.jade b/src/jade/index.jade deleted file mode 100644 index b579bbd..0000000 --- a/src/jade/index.jade +++ /dev/null @@ -1,212 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -include ../../build/hashes.jade - - -doctype html -html(lang="en") - head - meta(charset="utf-8") - meta(name="viewport", content="width=device-width, initial-scale=1.0") - - title Buildbotics Controller - Web interface - - link(rel="stylesheet", href="/css/pure-min.css") - //if lte IE 8 - link(rel="stylesheet", href="css/side-menu-old-ie.css") - // [if gt IE 8] {{firmwareName}}? - - p.pure-control-group - label(for="pass") Password - input(name="pass", v-model="password", type="password", - @keyup.enter="upload_confirmed") - - div(slot="footer") - button.pure-button(@click="confirmUpload=false") Cancel - button.pure-button.pure-button-primary(@click="upload_confirmed") - | Upload - - message(:show.sync="firmwareUpgrading") - h3(slot="header") Firmware upgrading - div(slot="body") - h3 Please wait... - p Loss of power during an upgrade may damage the controller. - div(slot="footer") - - message(:show.sync="showMessages") - h3(slot="header") GCode message - - div(slot="body") - ul - li(v-for="msg in messages", track-by="$index") {{msg}} - - div(slot="footer") - button.pure-button.button-success(v-if="state.xx != 'HOLDING'", - @click="close_messages('ok')") OK - - div(v-if="state.xx == 'HOLDING'") - button.pure-button(@click="close_messages('stop')") - | Stop - .fa.fa-stop - - button.pure-button(@click="close_messages('continue')") - | Continue - .fa.fa-play - - #templates - include ../../build/templates.jade - - iframe#download-target(style="display:none") - - script(src="js/jquery-1.11.3.min.js") - script(src="js/vue.js") - script(src="js/sockjs.min.js") - script(src="js/clusterize.min.js") - script(src='/js/assets-' + js_hash + '.js') - script(src="js/ui.js") diff --git a/src/jade/templates/admin-general-view.jade b/src/jade/templates/admin-general-view.jade deleted file mode 100644 index 14afba4..0000000 --- a/src/jade/templates/admin-general-view.jade +++ /dev/null @@ -1,67 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#admin-general-view-template(type="text/x-template") - #admin-general - h2 Firmware - button.pure-button.pure-button-primary(@click="check") Check - button.pure-button.pure-button-primary(@click="upgrade") Upgrade - label.pure-button.pure-button-primary.file-upload - input(type="file", accept=".tar.bz2", @change="upload") - | Upload - - p - input(type="checkbox", v-model="autoCheckUpgrade", - @change="change_auto_check_upgrade") - label(for="auto-check-upgrade")   Automatically check for upgrades - - h2 Configuration - button.pure-button.pure-button-primary(@click="backup") Backup - - label.pure-button.pure-button-primary.file-upload - input(type="file", accept=".json", @change="restore") - | Restore - message(:show.sync="configRestored") - h3(slot="header") Success - p(slot="body") Configuration restored. - - button.pure-button.pure-button-primary(@click="confirmReset = true") - | Reset - message(:show.sync="confirmReset") - h3(slot="header") Reset to default configuration? - p(slot="body") All configuration changes will be lost. - div(slot="footer") - button.pure-button(@click="confirmReset = false") Cancel - button.pure-button.button-success(@click="reset") OK - - message(:show.sync="configReset") - h3(slot="header") Success - p(slot="body") Configuration reset. - - h2 Debugging - a(href="/api/log", target="_blank") - button.pure-button.pure-button-primary View Log diff --git a/src/jade/templates/admin-network-view.jade b/src/jade/templates/admin-network-view.jade deleted file mode 100644 index 1ff0b4b..0000000 --- a/src/jade/templates/admin-network-view.jade +++ /dev/null @@ -1,123 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#admin-network-view-template(type="text/x-template") - #admin-network - h2 Hostname - .pure-form.pure-form-aligned - .pure-control-group - label(for="hostname") Hostname - input(name="hostname", v-model="hostname", @keyup.enter="set_hostname") - button.pure-button.pure-button-primary(@click="set_hostname") Set - - message(:show.sync="hostnameSet") - h3(slot="header") Hostname Set - div(slot="body") - p Hostname was successfuly set to {{hostname}}. - p Rebooting to apply changes. - p Redirecting to new hostname in {{redirectTimeout}} seconds. - div(slot="footer") - - h2 Remote SSH User - .pure-form.pure-form-aligned - .pure-control-group - label(for="username") Username - input(name="username", v-model="username", @keyup.enter="set_username") - button.pure-button.pure-button-primary(@click="set_username") Set - - .pure-form.pure-form-aligned - .pure-control-group - label(for="current") Current Password - input(name="current", v-model="current", type="password") - .pure-control-group - label(for="pass1") New Password - input(name="pass1", v-model="password", type="password") - .pure-control-group - label(for="pass2") New Password - input(name="pass2", v-model="password2", type="password") - button.pure-button.pure-button-primary(@click="set_password") Set - - message(:show.sync="passwordSet") - h3(slot="header") Password Set - p(slot="body") - - message(:show.sync="usernameSet") - h3(slot="header") Username Set - p(slot="body") - - h2 Wifi Setup - .pure-form.pure-form-aligned - .pure-control-group - label(for="wifi_mode") Mode - select(name="wifi_mode", v-model="wifi_mode", - title="Select client or access point mode") - option(value="disabled") Disabled - option(value="client") Client - option(value="ap") Access Point - button.pure-button.pure-button-primary(@click="wifiConfirm = true", - v-if="wifi_mode == 'disabled'") Set - .pure-control-group(v-if="wifi_mode == 'ap'") - label(for="wifi_ch") Channel - select(name="wifi_ch", v-model="wifi_ch") - each ch in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - option(value="#{ch}")= ch - .pure-control-group(v-if="wifi_mode != 'disabled'") - label(for="ssid") Network (SSID) - input(name="ssid", v-model="wifi_ssid") - .pure-control-group(v-if="wifi_mode != 'disabled'") - label(for="wifi_pass") Password - input(name="wifi_pass", v-model="wifi_pass", type="password") - button.pure-button.pure-button-primary(@click="wifiConfirm = true") Set - - message.wifi-confirm(:show.sync="wifiConfirm") - h3(slot="header") Configure Wifi and reboot? - div(slot="body") - p - | After configuring the Wifi settings the controller will - | automatically reboot. - table - tr - th Mode - td  {{wifi_mode}} - tr(v-if="wifi_mode == 'ap'") - th Channel - td  {{wifi_ch}} - tr(v-if="wifi_mode != 'disabled'") - th SSID - td  {{wifi_ssid}} - tr(v-if="wifi_mode != 'disabled'") - th Auth - td  {{wifi_pass ? 'WPA2' : 'Open'}} - - div(slot="footer") - button.pure-button(@click="wifiConfirm = false") Cancel - button.pure-button.button-success(@click="config_wifi") OK - - message(:show.sync="rebooting") - h3(slot="header") Rebooting - p(slot="body") Please wait... - div(slot="footer") diff --git a/src/jade/templates/axis-control.jade b/src/jade/templates/axis-control.jade deleted file mode 100644 index 37ec1f3..0000000 --- a/src/jade/templates/axis-control.jade +++ /dev/null @@ -1,207 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#axis-control-template(type="text/x-template") - svg(xmlns="http://www.w3.org/2000/svg", - xmlns:xlink="http://www.w3.org/1999/xlink", - width="200", height="200") - defs - lineargradient#red - stop(offset="0", stop-color="#d26969") - stop(offset="1", stop-color="#ff7f7f") - - lineargradient#green - stop(offset="0", stop-color="#69d269") - stop(offset="1", stop-color="#7fff7f") - - lineargradient#blue - stop(offset="0", stop-color="#6969d2") - stop(offset="1", stop-color="#7f7fff") - - lineargradient#orange - stop(offset="0", stop-color="#d29d69") - stop(offset="1", stop-color="#ffbf7f") - - lineargradient#cyan - stop(offset="0", stop-color="#69d2d2") - stop(offset="1", stop-color="#7fffff") - - lineargradient#purple - stop(offset="0", stop-color="#d269d2") - stop(offset="1", stop-color="#ff7fff") - - - each color in 'red green blue orange cyan purple'.split(' ') - lineargradient(xlink:href="##{color}", id="#{color}-1", - gradientunits="userSpaceOnUse", gradienttransform="rotate(180 7 5)", - x1="0", y1="0", x2="15", y2="10") - - lineargradient(xlink:href="##{color}", id="#{color}-2", - gradientunits="userSpaceOnUse", x1="10", y1="10", x2="40", y2="40") - - - filter#shadow(x="-50%" y="-50%" width="200%" height="200%") - feOffset(in="SourceAlpha", dx="3", dy="3") - feComponentTransfer - feFuncR(type="discrete", tableValues="0.05") - feFuncG(type="discrete", tableValues="0.05") - feFuncB(type="discrete", tableValues="0.05") - feGaussianBlur(result="shadow", stdDeviation="5") - feBlend(in="SourceGraphic", in2="shadow", mode="normal") - - path#pie-1(d="M107,0 83,0 0,83 0,107A107,107 0 0 0 107,0Z") - path#pie-2(d="M83,0 59,0 0,59 0,83A83,83 0 0 0 83,0Z") - path#pie-3(d="M59,0 35,0 0,35 0,59A59,59 0 0 0 59,0Z") - path#pie-4(d="M35,0 0,0 0,35A35,35 0 0 0 35,0Z") - - path#arrow(d="M-16,9 0,9 0,17 17,0 0,-17 0,-9 -16,-9 -16,9Z") - - - g(transform="scale(0.8, 0.8)") - // 100% ring - g.ring(fill="#9f9f9f", filter="url(#shadow)") - use.button(xlink:href="#pie-1", v-if="enabled[0]", - transform="translate(134 121) rotate(-45)", - @mousedown="jog(0, 1)", @mouseup="release(0)") - - use.button(xlink:href="#pie-1", v-if="enabled[0]", - transform="translate(115 121) rotate(135)", - @mousedown="jog(0, -1)", @mouseup="release(0)") - - g.button(@mousedown="jog(1, 1)", @mouseup="release(1)", - v-if="enabled[1]") - use.button(xlink:href="#pie-1", - transform="translate(124 111) rotate(-135)") - text(x="125", y="24", transform="rotate(22 125 125)") - | {{adjust | fixed 0}}% - text(x="125", y="24", transform="rotate(-22 125 125)") - | {{adjust | fixed 0}}% - use.button(xlink:href="#pie-1", fill="transparent", - transform="translate(124 111) rotate(-135)") - - use.button(xlink:href="#pie-1", v-if="enabled[1]", - transform="translate(124 130) rotate(45)", @mousedown="jog(1, -1)", - @mouseup="release(1)") - - // 50% ring - g.ring(fill="#c5c5c5", filter="url(#shadow)") - use.button(xlink:href="#pie-2", v-if="enabled[0]", - transform="translate(134 121) rotate(-45)", - @mousedown="jog(0, 0.5)", @mouseup="release(0)") - - use.button(xlink:href="#pie-2", v-if="enabled[0]", - transform="translate(115 121) rotate(135)", - @mousedown="jog(0, -0.5)", @mouseup="release(0)") - - g.button(@mousedown="jog(1, 0.5)", @mouseup="release(1)", - v-if="enabled[1]") - use.button(xlink:href="#pie-2", - transform="translate(124 111) rotate(-135)") - text(x="125", y="48") {{0.5 * adjust | fixed 1}}% - use.button(xlink:href="#pie-2", fill="transparent", - transform="translate(124 111) rotate(-135)") - - use.button(xlink:href="#pie-2", v-if="enabled[1]", - transform="translate(124 130) rotate(45)", - @mousedown="jog(1, -0.5)", @mouseup="release(1)") - - - // 25% ring - g.ring(fill="#e2e2e2", filter="url(#shadow)") - use.button(xlink:href="#pie-3", v-if="enabled[0]", - transform="translate(134 121) rotate(-45)", - @mousedown="jog(0, 0.25)", @mouseup="release(0)") - - use.button(xlink:href="#pie-3", v-if="enabled[0]", - transform="translate(115 121) rotate(135)", - @mousedown="jog(0, -0.25)", @mouseup="release(0)") - - g.button(@mousedown="jog(1, 0.25)", @mouseup="release(1)", - v-if="enabled[1]") - use.button(xlink:href="#pie-3", - transform="translate(124 111) rotate(-135)") - text(x="125", y="73") {{0.25 * adjust | fixed 1}}% - use.button(xlink:href="#pie-3", fill="transparent", - transform="translate(124 111) rotate(-135)") - - use.button(xlink:href="#pie-3", v-if="enabled[1]", - transform="translate(124 130) rotate(45)", - @mousedown="jog(1, -0.25)", @mouseup="release(1)") - - - // 10% ring - g.ring(fill="#f7f7f7", filter="url(#shadow)") - use.button(xlink:href="#pie-4", v-if="enabled[0]", - transform="translate(134 121) rotate(-45)", - @mousedown="jog(0, 0.1)", @mouseup="release(0)") - - use.button(xlink:href="#pie-4", v-if="enabled[0]", - transform="translate(115 121) rotate(135)", - @mousedown="jog(0, -0.1)", @mouseup="release(0)") - - g.button(@mousedown="jog(1, 0.1)", @mouseup="release(1)", - v-if="enabled[1]") - use.button(xlink:href="#pie-4", - transform="translate(124 111) rotate(-135)") - text(x="125", y="95") {{0.1 * adjust | fixed 1}}% - use.button(xlink:href="#pie-4", fill="transparent", - transform="translate(124 111) rotate(-135)") - - use.button(xlink:href="#pie-4", v-if="enabled[1]", - transform="translate(124 130) rotate(45)", - @mousedown="jog(1, -0.1)", @mouseup="release(1)") - - - // +A - g.button.arrow(@mousedown="jog(0, 1)", @mouseup="release(0)", - transform="translate(230 120)", v-if="enabled[0]") - use(xlink:href="#arrow", fill="url(#{{colors[0]}}-1)") - text(x="-12", y="5", font-size="14", textLength="21") +{{axes[0]}} - - - // -A - g.button.arrow(@mousedown="jog(0, -1)", @mouseup="release(0)", - transform="translate(20 120)", v-if="enabled[0]") - use(xlink:href="#arrow", fill="url(#{{colors[0]}}-1)", - transform="rotate(180)") - text(x="-8", y="5", font-size="14", textLength="16") -{{axes[0]}} - - - // +B - g.button.arrow(@mousedown="jog(1, 1)", @mouseup="release(1)", - transform="translate(125, 18)", v-if="enabled[1]") - use(xlink:href="#arrow", fill="url(#{{colors[1]}}-1)", - transform="rotate(-90)") - text(x="-8", y="5", font-size="12", textLength="16") +{{axes[1]}} - - - // -B - g.button.arrow(@mousedown="jog(1, -1)", @mouseup="release(1)", - transform="translate(125, 225)", v-if="enabled[1]") - use(xlink:href="#arrow", fill="url(#{{colors[1]}}-1)", - transform="rotate(90)") - text(x="-7", y="5", font-size="12", textLength="14") -{{axes[1]}} diff --git a/src/jade/templates/cheat-sheet-view.jade b/src/jade/templates/cheat-sheet-view.jade deleted file mode 100644 index 41f422f..0000000 --- a/src/jade/templates/cheat-sheet-view.jade +++ /dev/null @@ -1,563 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#cheat-sheet-view-template(type="text/x-template") - // Modified from http://linuxcnc.org/docs/html/gcode.html - - var base = 'http://linuxcnc.org/docs/html/gcode'; - .cheat-sheet - h2 GCode Cheat Sheet - - table - tr - th Code - th Parameters - th Description - - tr.spacer-row: th - tr.header-row - th(colspan='3') Motion - tr - td - a(href="#{base}/g-code.html#gcode:g0") G0 - td - td Rapid Move - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g1") G1 - td - td Linear Move - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g2-g3") G2, G3 - td I J K or R, P - td Arc Move - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g4") G4 - td P - td Dwell - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g5") G5 - td I J P Q - td Cubic Spline - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g5.1") G5.1 - td I J - td Quadratic Spline - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g5.2-g5.3") G5.2 - td P L - td NURBS - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g38") G38.2 - G38.5 - td - td Straight Probe - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g33.1") G33.1 - td K - td Rigid Tapping - - tr.spacer-row: th - tr.header-row - th(colspan='3') Tool Control - tr - td - a(href="#{base}/other-code.html#sec:select-tool") T - td - td Select Tool - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m6") M6 - td T - td Tool Change - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m61") M61 - td Q - td Set Current Tool - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g10-l1") G10 L1 - td P Q R - td Set Tool Table - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g10-l10") G10 L10 - td P - td Set Tool Table - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g10-l11") G10 L11 - td P - td Set Tool Table - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g43") G43 - td H - td Tool Length Offset - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g43.1") G43.1 - td - td Dynamic Tool Length Offset - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g43.2") G43.2 - td H - td Apply additional Tool Length Offset - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g49") G49 - td - td Cancel Tool Length Compensation - - tr.spacer-row: th - tr.header-row - th(colspan='3') Feed Control - tr - td - a(href="#{base}/other-code.html#sec:set-feed-rate") F - td - td Set Feed Rate - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g93-g94-g95") - | G93, G94, G95 - td - td Feed Rate Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m52") M52 - td P0 (off) or P1 (on) - td Adaptive Feed Control - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m53") M53 - td P0 (off) or P1 (on) - td Feed Stop Control - - tr.spacer-row: th - tr.header-row - th(colspan='3') Spindle Control - tr - td - a(href="#{base}/other-code.html#sec:set-spindle-speed") S - td - td Set Spindle Speed - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m3-m4-m5") - | M3, M4, M5 - td S - td Spindle Control - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m19") M19 - td - td Orient Spindle - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g96-g97") G96, G97 - td S D - td Spindle Control Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g33") G33 - td K - td Spindle Synchronized Motion - - tr.spacer-row: th - tr.header-row - th(colspan='3') Coolant - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m7-m8-m9") - | M7, M8, M9 - td - td Coolant Control - - tr.spacer-row: th - tr.header-row - th(colspan='3') Stopping - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m0-m1") M0, M1 - td - td Program Pause - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m2-m30") M2, M30 - td - td Program End - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m60") M60 - td - td Pallet Change Pause - - tr.spacer-row: th - tr.header-row - th(colspan='3') Units - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g20-g21") G20, G21 - td - td Units (inch, mm) - - tr.spacer-row: th - tr.header-row - th(colspan='3') Distance Mode - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g90-g91") G90, G91 - td - td Distance Mode - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g90.1-g91.1") - | G90.1, G91.1 - td - td Arc Distance Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g7") G7 - td - td Lathe Diameter Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g8") G8 - td - td Lathe Radius Mode - - tr.spacer-row.unimplemented(v-if="showUnimplemented"): th - tr.header-row.unimplemented(v-if="showUnimplemented") - th(colspan='3') Cutter Radius Compensation - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g40") G40 - td - td Compensation Off - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g41-g42") G41,G42 - td D - td Cutter Compensation - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g41.1-g42.1") - | G41.1, G42.1 - td D L - td Dynamic Cutter Compensation - - tr.spacer-row.unimplemented(v-if="showUnimplemented"): th - tr.header-row.unimplemented(v-if="showUnimplemented") - th(colspan='3') Path Control Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g61-g61.1") - | G61 G61.1 - td - td Exact Path Mode - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g64") G64 - td P Q - td Path Blending - - tr.spacer-row.unimplemented(v-if="showUnimplemented"): th - tr.header-row.unimplemented(v-if="showUnimplemented") - th(colspan='3') Overrides - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m48-m49") M48, M49 - td - td Speed and Feed Override Control - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m50") M50 - td P0 (off) or P1 (on) - td Feed Override Control - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m51") M51 - td P0 (off) or P1 (on) - td Spindle Speed Override Control - - tr.spacer-row: th - tr.header-row - th(colspan='3') Coordinate Systems, Offsets & Planes - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g54-g59.3") - | G54-G59.3 - td - td Select Coordinate System - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g10-l2") G10 L2 - td P R - td Set Coordinate System - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g10-l20") G10 L20 - td P - td Set Coordinate System - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g53") G53 - td - td Move in Machine Coordinates - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g92") G92 - td - td Coordinate System Offset - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g92.1-g92.2") - | G92.1, G92.2 - td - td Reset G92 Offsets - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g92.3") G92.3 - td - td Restore G92 Offsets - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g28-g28.1") - | G28, G28.1 - td - td Go/Set Predefined Position - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g30-g30.1") - | G30, G30.1 - td - td Go/Set Predefined Position - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g17-g19.1") - | G17 - G19.1 - td (affects G2, G3, G81…G89, G40…G42) - td Plane Select - - tr.spacer-row: th - tr.header-row - th(colspan='3') Flow-control Codes - tr - td - a(target="_blank", href="#{base}/o-code.html#ocode:subroutines") - | o sub/endsub/call - td - td Subroutines, sub/endsub call - tr - td - a(target="_blank", href="#{base}/o-code.html#ocode:looping") o while - td - td Looping, while/endwhile do/while - tr - td - a(target="_blank", href="#{base}/o-code.html#ocode:conditional") o if - td - td Conditional, if/else/endif - tr - td - a(target="_blank", href="#{base}/o-code.html#ocode:repeat") o repeat - td - td Repeat a loop of code - tr - td - a(target="_blank", href="#{base}/o-code.html#ocode:indirection") [] - td - td Indirection - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/o-code.html#ocode:calling-files") - | o call - td - td Call named or numbered file - - tr.spacer-row: th - tr.header-row - th(colspan='3') Modal State - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m70") M70 - td - td Save modal state - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m71") M71 - td - td Invalidate stored state - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m72") M72 - td - td Restore modal state - tr - td - a(target="_blank", href="#{base}/m-code.html#mcode:m73") M73 - td - td Save and Auto-restore modal state - - tr.spacer-row.unimplemented(v-if="showUnimplemented"): th - tr.header-row.unimplemented(v-if="showUnimplemented") - th(colspan='3') Input/Output - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m62-m65") M62 - M65 - td P - td Digital Output Control - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m66") M66 - td P E L Q - td Wait on Input - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m67") M67 - td T - td Analog Output,Synchronized - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m68") M68 - td T - td Analog Output, Immediate - - tr.spacer-row.unimplemented(v-if="showUnimplemented"): th - tr.header-row.unimplemented(v-if="showUnimplemented") - th(colspan='3') User Defined Commands - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/m-code.html#mcode:m100-m199") - | M101 - M199 - td P Q - td User Defined Commands - - tr.spacer-row: th - tr.header-row - th(colspan='3') Canned cycles - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g80") G80 - td - td Cancel Canned Cycle - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g81") G81 - td R L (P) - td Drilling Cycle - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g82") G82 - td R L (P) - td Drilling Cycle, Dwell - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g83") G83 - td R L Q - td Drilling Cycle, Peck - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g73") G73 - td R L Q - td Drilling Cycle, Chip Breaking - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g85") G85 - td R L (P) - td Boring Cycle, Feed Out - tr - td - a(target="_blank", href="#{base}/g-code.html#gcode:g89") G89 - td R L (P) - td Boring Cycle, Dwell, Feed Out - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g76") G76 - td P Z I J R K Q H L E - td Threading Cycle - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/g-code.html#gcode:g98-g99") G98, G99 - td - td Canned Cycle Return Level - - tr.spacer-row: th - tr.header-row - th(colspan='3') Comments & Messages - tr - td - a(target="_blank", href="#{base}/overview.html#gcode:comments") ; (…) - td - td Comments - tr - td - a(target="_blank", href="#{base}/overview.html#gcode:messages") - | (MSG,…) - td - td Messages - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/overview.html#gcode:debug") (DEBUG,…) - td - td Debug Messages - tr.unimplemented(v-if="showUnimplemented") - td - a(target="_blank", href="#{base}/overview.html#gcode:print") (PRINT,…) - td - td Print Messages - - div - input(type="checkbox", v-model="showUnimplemented") - label Show unsupported codes - - h2 Further GCode Programming Documentation - - p - | The Buildbotics controller implements a subset of LinuxCNC GCode. - | Supported commands are listed above. You can find further help with - | GCode - | programming on the LinuxCNC website: - - ul - li: a(href="http://linuxcnc.org/docs/html/gcode/overview.html", - target="_blank") - | G Code overview - li: a(href="http://linuxcnc.org/docs/html/gcode/g-code.html", - target="_blank") - | G Code reference - li: a(href="http://linuxcnc.org/docs/html/gcode/m-code.html", - target="_blank") - | M Code reference diff --git a/src/jade/templates/console.jade b/src/jade/templates/console.jade deleted file mode 100644 index bc8df6c..0000000 --- a/src/jade/templates/console.jade +++ /dev/null @@ -1,49 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#console-template(type="text/x-template") - .console - .toolbar - button.pure-button(title="Clear console.", @click="clear") - .fa.fa-trash - |  Clear - - .console-wrapper - table - tr - th Level - th Source - th Location - th Repeat - th Message - - tr(v-for="msg in messages", class="log-{{msg.level || 'info'}}") - td {{msg.level || 'info'}} - td {{msg.source || ''}} - td {{msg.where || ''}} - td {{msg.repeat}} - td.message {{msg.msg}} diff --git a/src/jade/templates/control-view.jade b/src/jade/templates/control-view.jade deleted file mode 100644 index d5074dd..0000000 --- a/src/jade/templates/control-view.jade +++ /dev/null @@ -1,290 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#control-view-template(type="text/x-template") - #control - table.axes - tr(:class="{'homed': is_homed()}") - th.name Axis - th.position Position - th.absolute Absolute - th.offset Offset - th.actions - button.pure-button(:disabled="!is_ready", - title="Zero all axis offsets.", @click="zero()") ∅ - - button.pure-button(title="Home all axes.", @click="home()", - :disabled="!is_ready") - .fa.fa-home - - each axis in 'xyzabc' - tr.axis(:class="{'homed': is_homed('#{axis}'), 'axis-#{axis}': true}", - v-if="enabled('#{axis}')") - th.name #{axis} - td.position - unit-value(:value="state.#{axis}p + get_offset('#{axis}')", - precision="4") - td.absolute: unit-value(:value="state.#{axis}p", precision="3") - td.offset: unit-value(:value="get_offset('#{axis}')", precision="3") - th.actions - button.pure-button(:disabled="!is_ready", - title="Set {{'#{axis}' | upper}} axis position.", - @click="show_set_position('#{axis}')") - .fa.fa-cog - - button.pure-button(:disabled="!is_ready", - title="Zero {{'#{axis}' | upper}} axis offset.", - @click="zero('#{axis}')") ∅ - - button.pure-button(:disabled="!is_ready", - title="Home {{'#{axis}' | upper}} axis.", - @click="home('#{axis}')") - .fa.fa-home - - message(:show.sync="position_msg['#{axis}']") - h3(slot="header") Set {{'#{axis}' | upper}} axis position - - div(slot="body") - .pure-form - .pure-control-group - label Position - input(v-model="axis_position", - @keyup.enter="set_position('#{axis}', axis_position)") - p - - div(slot="footer") - button.pure-button(@click="position_msg['#{axis}'] = false") - | Cancel - - button.pure-button(v-if="is_homed('#{axis}')", - @click="unhome('#{axis}')") Unhome - - button.pure-button.button-success( - @click="set_position('#{axis}', axis_position)") Set - - - message(:show.sync="manual_home['#{axis}']") - h3(slot="header") Manually home {{'#{axis}' | upper}} axis - - div(slot="body") - p Set axis absolute position. - - .pure-form - .pure-control-group - label Absolute - input(v-model="axis_position", - @keyup.enter="set_home('#{axis}', axis_position)") - - p - - div(slot="footer") - button.pure-button(@click="manual_home['#{axis}'] = false") - | Cancel - - button.pure-button.button-success( - title="Home {{'#{axis}' | upper}} axis.", - @click="set_home('#{axis}', axis_position)") Set - - - table.info - tr - th State - td(:class="{attention: highlight_reason}") {{mach_state}} - td - tr - th Message - td.reason(:class="{attention: highlight_reason}") {{reason}} - td - tr(title="Currently active machine units") - th Units - td.mach_units - select(v-model="mach_units", :disabled="!can_mdi") - option(value="METRIC") METRIC - option(value="IMPERIAL") IMPERIAL - td - tr - th Feed - td: unit-value(:value="state.feed", precision="2", unit="", iunit="") - td {{metric ? 'mm/min' : 'IPM'}} - tr - th Speed - td - | {{state.speed || 0 | fixed 0}} - span(v-if="!isNaN(state.s)") ({{state.s | fixed 0}}) - td RPM - - table.info - tr( - title="Current velocity in {{metric ? 'meters' : 'inches'}} per minute") - th Velocity - td: unit-value(:value="state.v", precision="2", unit="", iunit="", - scale="0.0254") - td {{metric ? 'm/min' : 'IPM'}} - tr - th Line - td {{0 <= state.line ? state.line : '-'}} - td - tr - th Tool - td {{state.tool || 0}} - td - tr - th Load 1 - td(:class="state['1oa'] ? 'load-on' : ''") - | {{state['1oa'] ? 'On' : 'Off'}} - td - tr - th Load 2 - td(:class="state['2oa'] ? 'load-on' : ''") - | {{state['2oa'] ? 'On' : 'Off'}} - td - - .override(title="Feed rate override.") - label Feed - input(type="range", min="0", max="2", step="0.01", - v-model="feed_override", @change="override_feed") - span.percent {{feed_override | percent 0}} - - .override(title="Spindle speed override.") - label Speed - input(type="range", min="0", max="2", step="0.01", - v-model="speed_override", @change="override_speed") - span.percent {{speed_override | percent 0}} - - .tabs - input#tab1(type="radio", name="tabs" checked, @click="tab = 'auto'") - label(for="tab1", title="Run GCode programs") Auto - - input#tab2(type="radio", name="tabs", @click="tab = 'mdi'") - label(for="tab2", title="Manual GCode entry") MDI - - input#tab3(type="radio", name="tabs", @click="tab = 'jog'") - label(for="tab3", "Jog the axes manually") Jog - - input#tab4(type="radio", name="tabs", @click="tab = 'messages'") - label(for="tab4") Messages - - input#tab5(type="radio", name="tabs", @click="tab = 'indicators'") - label(for="tab5") Indicators - - section#content1.tab-content.pure-form - .toolbar.pure-control-group - button.pure-button( - title="{{is_running ? 'Pause' : 'Start'}} program.", - @click="start_pause", :disabled="!state.selected") - .fa(:class="is_running ? 'fa-pause' : 'fa-play'") - - button.pure-button(title="Stop program.", @click="stop") - .fa.fa-stop - - button.pure-button(title="Pause program at next optional stop (M1).", - @click="optional_pause", v-if="false") - .fa.fa-stop-circle-o - - button.pure-button(title="Execute one program step.", @click="step", - :disabled="(!is_ready && !is_holding) || !state.selected", - v-if="false") - .fa.fa-step-forward - - button.pure-button(title="Upload a new GCode program.", @click="open", - :disabled="is_running || is_stopping") - .fa.fa-folder-open - - input.gcode-file-input(type="file", @change="upload", - style="display:none", accept=".nc,.gcode,.gc,.ngc") - - button.pure-button(title="Delete current GCode program.", - @click="deleteGCode = true", - :disabled="!state.selected || is_running || is_stopping") - .fa.fa-trash - - message(:show.sync="deleteGCode") - h3(slot="header") Delete GCode? - p(slot="body") - div(slot="footer") - button.pure-button(@click="deleteGCode = false") Cancel - button.pure-button.button-error(@click="deleteAll") - .fa.fa-trash - |  all - button.pure-button.button-success(@click="deleteCurrent") - .fa.fa-trash - |  selected - - select(title="Select previously uploaded GCode programs.", - v-model="state.selected", @change="load", - :disabled="is_running || is_stopping") - option(v-for="file in files", :value="file") {{file}} - - gcode-viewer - - section#content2.tab-content - .mdi.pure-form(title="Manual GCode entry.") - button.pure-button(:disabled="!can_mdi", - title="{{is_running ? 'Pause' : 'Start'}} command.", - @click="mdi_start_pause") - .fa(:class="is_running ? 'fa-pause' : 'fa-play'") - - button.pure-button(title="Stop command.", @click="stop") - .fa.fa-stop - - input(v-model="mdi", :disabled="!can_mdi", @keyup.enter="submit_mdi") - - .history(:class="{placeholder: !history}") - span(v-if="!history.length") MDI history displays here. - ul - li(v-for="item in history", @click="load_history($index)", - track-by="$index") - | {{item}} - - section#content3.tab-content - .jog - axis-control(axes="XY", :colors="['red', 'green']", - :enabled="[enabled('x'), enabled('y')]", - v-if="enabled('x') || enabled('y')", :adjust="jog_adjust") - - axis-control(axes="AZ", :colors="['orange', 'blue']", - :enabled="[enabled('a'), enabled('z')]", - v-if="enabled('a') || enabled('z')", :adjust="jog_adjust") - - axis-control(axes="BC", :colors="['cyan', 'purple']", - :enabled="[enabled('b'), enabled('c')]", - v-if="enabled('b') || enabled('c')", :adjust="jog_adjust") - - .jog-adjust - | Fine adjust - input(type="range", v-model="jog_adjust", min=1, max=100, step=1) - - center - | Left click the axes above holding down the mouse button to jog the - | machine. - center Jogging speed is set by the ring that is clicked. - - section#content4.tab-content - console - - section#content5.tab-content - indicators(:state="state") diff --git a/src/jade/templates/estop.jade b/src/jade/templates/estop.jade deleted file mode 100644 index 472c72c..0000000 --- a/src/jade/templates/estop.jade +++ /dev/null @@ -1,121 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#estop-template(type="text/x-template") - svg(version="1.1", xmlns:svg="http://www.w3.org/2000/svg", - xmlns="http://www.w3.org/2000/svg", - xmlns:xlink="http://www.w3.org/1999/xlink", - width="130", height="130") - defs - path#text-path-1(style="fill:none;stroke:none", d="m 73.735867,673.1299 c 0,55.10749 44.673453,99.78094 99.780973,99.78094 55.10748,0 99.78093,-44.67345 99.78093,-99.78094 0,-55.10749 -44.67345,-99.78094 -99.78093,-99.78094 -55.10752,0 -99.780973,44.67345 -99.780973,99.78094 z") - - path#text-path-2(style="fill:none;stroke:none", d="m 258.7149,673.1299 c 0,47.0536 -38.14448,85.19809 -85.19809,85.19809 -47.0536,0 -85.198083,-38.14449 -85.198083,-85.19809 0,-47.05361 38.144483,-85.19809 85.198083,-85.19809 47.05361,0 85.19809,38.14448 85.19809,85.19809 z") - - filter#filter5134(style="color-interpolation-filters:sRGB") - feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)") - fecomposite(in2="SourceGraphic", operator="in") - fegaussianblur(stddeviation="4", result="blur") - feoffset(dx="4", dy="4", result="offset") - fecomposite(in="SourceGraphic", in2="offset", operator="over", - result="fbSourceGraphic") - fecolormatrix(result="fbSourceGraphicAlpha", in="fbSourceGraphic", - values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0") - feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)", - in="fbSourceGraphic") - fecomposite(in2="fbSourceGraphic", operator="out") - fegaussianblur(stddeviation="4", result="blur") - feoffset(dx="-4", dy="-4", result="offset") - fecomposite(in2="fbSourceGraphic", in="offset", operator="atop", - result="fbSourceGraphic") - fecolormatrix(result="fbSourceGraphicAlpha", in="fbSourceGraphic", - values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0") - feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)", - in="fbSourceGraphic") - fecomposite(in2="fbSourceGraphic", operator="in") - fegaussianblur(stddeviation="4", result="blur") - feoffset(dx="4", dy="4", result="offset") - fecomposite(in2="offset", in="fbSourceGraphic", operator="over") - - filter#filter5158(style="color-interpolation-filters:sRGB",) - feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)") - fecomposite(in2="SourceGraphic", operator="out") - fegaussianblur(stddeviation="7", result="blur") - feoffset(dx="4", dy="4") - fecomposite(in2="SourceGraphic", operator="atop") - - filter#filter5266(style="color-interpolation-filters:sRGB") - feflood(flood-opacity="0.372549", flood-color="rgb(0,0,0)") - fecomposite(in2="SourceGraphic", operator="in") - fegaussianblur(stddeviation="2", result="blur") - feoffset(dx="1", dy="1", result="offset") - fecomposite(in="SourceGraphic", in2="offset", operator="over") - - filter#filter5278(style="color-interpolation-filters:sRGB") - feflood(flood-opacity="0.372549", flood-color="rgb(0,0,0)") - fecomposite(in2="SourceGraphic", operator="out") - fegaussianblur(stddeviation="2", result="blur") - feoffset(dx="2", dy="2", result="offset") - fecomposite(in="offset", in2="SourceGraphic", operator="atop") - - - g(transform="scale(0.6, 0.6),translate(-65, -526)") - // Yellow ring - circle.ring(style="fill:#f5e138;filter:url(#filter5266)", - cx="173", cy="633", r="100") - - // Text - text(style="font-weight:bold;font-size:20px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none", - transform="matrix(-0.73361478,-0.67956556,0.67956556,-0.73361478,-156.72624,1250.7027)", - x="-1350.5394", y="-1579.3965") - textpath(xlink:href="#text-path-2") EMERGENCY - - text(style="font-weight:bold;font-size:20px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none", - transform="matrix(0.27634044,-0.96105981,0.96105981,0.27634044,-523.81801,609.02637)", - x="-754.20117", y="157.03941") - textpath(xlink:href="#text-path-1") STOP - - g.button - circle(style="fill:#b72424;filter:url(#filter5134)", - cx="173", cy="633", r="74") - - // Inner circle - circle(style="fill:#b72424;filter:url(#filter5158)", - cx="173", cy="633", r="37") - - // Arrows - g(transform="matrix(0.32737901,0,0,0.32737901,50.806169,478.96619)", style="stroke:#fff;stroke-width:26;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;filter:url(#filter5278);fill:none") - g - path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -12.91355,-13.50409 -17.38625,-24.07872") - path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") - - g(transform="matrix(-0.5,-0.8660254,0.8660254,-0.5,149.81163,1033.4478)") - path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -11.52544,-14.20559 -17.38625,-24.07872") - path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") - - g(transform="matrix(-0.5,0.8660254,-0.8660254,-0.5,971.43059,383.18517)") - path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -9.56206,-8.6246 -14.03476,-19.19923") - path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") diff --git a/src/jade/templates/gcode-viewer.jade b/src/jade/templates/gcode-viewer.jade deleted file mode 100644 index c79197a..0000000 --- a/src/jade/templates/gcode-viewer.jade +++ /dev/null @@ -1,33 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#gcode-viewer-template(type="text/x-template") - .gcode - .clusterize - .clusterize-scroll - ul.clusterize-content - li.clusterize-no-data.placeholder GCode displays here. diff --git a/src/jade/templates/help-view.jade b/src/jade/templates/help-view.jade deleted file mode 100644 index 1c0187b..0000000 --- a/src/jade/templates/help-view.jade +++ /dev/null @@ -1,61 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#help-view-template(type="text/x-template") - #help - h2 User Manual - p - | You can find a detailed user manual at docs.buildbotics.com. - - h2 Discussion Forum - p - | If you're having trouble or just want to chat with other Buildbotics - | CNC controller owners, head over to the Buildbotics forum at - | forum.buildbotics.com. Register on the site and post a message. - | We'll be happy to help. - - h2 CAD/CAM Software - p - | CAM software can be used to create GCode - | automatically from - | CAD models. Here are a few CAD/CAM resources: - ul - li: a(href="http://camotics.org/", target="_blank") - | CAMotics - Open-Source CNC Simulator - li: a(href="http://librecad.org/", target="_blank") - | LibreCAD - Open-Source 2D CAD - li: a(href="https://www.freecadweb.org/", target="_blank") - | FreeCAD - Open-Source 3D CAD - li: a(href="http://www.openscad.org/", target="_blank") - | OpenSCAD - Open-Source 3D CAD for programmers - li: a(href="http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Cam", - target="_blank") LinuxCNC CAM resources diff --git a/src/jade/templates/indicators.jade b/src/jade/templates/indicators.jade deleted file mode 100644 index f9650c4..0000000 --- a/src/jade/templates/indicators.jade +++ /dev/null @@ -1,245 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#indicators-template(type="text/x-template") - .indicators - table.legend - tr - th.header(colspan=100) Legend - - tr - td - .fa.fa-plus-circle.io - th Hi/+3.3v - th.separator - td - .fa.fa-minus-circle.io - th Lo/Gnd - th.separator - td - .fa.fa-circle.io.active - th Active - th.separator - td - .fa.fa-circle.io.inactive - th Inactive - th.separator - td - .fa.fa-circle-o.io - th Tristated/Disabled - - table.inputs - tr - th.header(colspan=7) Inputs - - tr - th State - th Pin - th Name - th.separator - th State - th Pin - th Name - - each motor in '0123' - tr - td - .fa.io(:class="get_input_class('#{motor}lw', '#{motor}ls')", - :title="get_input_tooltip('#{motor}lw', '#{motor}ls')") - td {{get_min_pin(#{motor})}} - th Motor #{motor} Min - th.separator - td - .fa.io(:class="get_input_class('#{motor}xw', '#{motor}xs')", - :title="get_input_tooltip('#{motor}xw', '#{motor}xs')") - td {{get_max_pin(#{motor})}} - th Motor #{motor} Max - - tr - td - .fa.io(:class="get_input_class('ew', 'et')", - :title="get_input_tooltip('ew', 'et')") - td 23 - th EStop - th.separator - td - .fa.io(:class="get_input_class('pw', 'pt')", - :title="get_input_tooltip('pw', 'pt')") - td 22 - th Probe - - table.outputs - tr - th.header(colspan=7) Outputs - - tr - th State - th Pin - th Name - th.separator - th State - th Pin - th Name - - tr - td - .fa.io(:class="get_output_class('e')", - :title="get_output_tooltip('e')") - td 15 - th Tool Enable - th.separator - td - .fa.io(:class="get_output_class('1')", - :title="get_output_tooltip('1')") - td 2 - th Load 1 - - tr - td - .fa.io(:class="get_output_class('d')", - :title="get_output_tooltip('d')") - td 16 - th Tool Direction - th.separator - td - .fa.io(:class="get_output_class('2')", - :title="get_output_tooltip('2')") - td 1 - th Load 2 - - tr - td {{state.pd | percent 0}} - td 17 - th Tool PWM - th.separator - td - .fa.io(:class="get_output_class('f')", - :title="get_output_tooltip('f')") - td 21 - th Fault - - table.pwr_fault - tr - th.header(colspan=5) - | Power Faults - span(v-if="state.pwr_version")  (Version {{state.pwr_version}}) - tr - th(:class="{error: state.under_voltage}") Under voltage - td(:class="{error: state.under_voltage}") - | {{state.under_voltage ? 'True' : 'False'}} - th.separator - th(:class="{error: state.over_voltage}") Over voltage - td(:class="{error: state.over_voltage}") - | {{state.over_voltage ? 'True' : 'False'}} - tr - th(:class="{error: state.over_current}") Over current - td(:class="{error: state.over_current}") - | {{state.over_current ? 'True' : 'False'}} - th.separator - th(:class="{error: state.sense_error}", :title="sense_error") - | Sense error - td(:class="{error: state.sense_error}") - | {{state.sense_error ? 'True' : 'False'}} - tr - th(:class="{error: state.shunt_overload}") Shunt overload - td(:class="{error: state.shunt_overload}") - | {{state.shunt_overload ? 'True' : 'False'}} - th.separator - th(:class="{error: state.motor_overload}") Motor overload - td(:class="{error: state.motor_overload}") - | {{state.motor_overload ? 'True' : 'False'}} - tr - th(:class="{error: state.load1_shutdown}") Load 1 shutdown - td(:class="{error: state.load1_shutdown}") - | {{state.load1_shutdown ? 'True' : 'False'}} - th.separator - th(:class="{error: state.load2_shutdown}") Load 2 shutdown - td(:class="{error: state.load2_shutdown}") - | {{state.load2_shutdown ? 'True' : 'False'}} - tr - th(:class="{error: state.motor_under_voltage}") Motor under volt - td(:class="{error: state.motor_under_voltage}") - | {{state.motor_under_voltage ? 'True' : 'False'}} - th.separator - th - td - - table.measurements - tr - th.header(colspan=5) Measurements - - tr - td {{state.vin | fixed 1}} V - th Input - th.separator - td {{state.vout | fixed 1}} V - th Output - - tr - td {{state.motor | fixed 2}} A - th Motor - th.separator - td {{state.temp | fixed 0}} ℃ - th Temp - - tr - td {{state.load1 | fixed 2}} A - th Load 1 - th.separator - td {{state.load2 | fixed 2}} A - th Load 2 - - tr - td {{state['1ai'] | percent 0}} A - th Analog 1 - th.separator - td {{state['2ai'] | percent 0}} A - th Analog 2 - - table.modbus - tr - th.header(colspan=5) Modbus VFD - - tr - td {{modbus_status}} - th Status - th.separator - td {{state.hz}} Hz - th Frequency - - tr - td {{state.s}} RPM - th Speed - th.separator - td {{state.hc}} A - th Current - - h2 DB25 breakout box - img(width=700, src="/images/DB25_breakout_box.png") - - h2 DB25-M2 breakout - img(width=400, src="/images/DB25-M2_breakout.png") diff --git a/src/jade/templates/io-view.jade b/src/jade/templates/io-view.jade deleted file mode 100644 index f0c81a3..0000000 --- a/src/jade/templates/io-view.jade +++ /dev/null @@ -1,41 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#io-view-template(type="text/x-template") - #io - h1 I/O Configuration - - .pure-form.pure-form-aligned - fieldset - h2 Switches - templated-input(v-for="templ in template.switches", :name="$key", - :model.sync="config.switches[$key]", :template="templ") - - fieldset - h2 Outputs - templated-input(v-for="templ in template.outputs", :name="$key", - :model.sync="config.outputs[$key]", :template="templ") diff --git a/src/jade/templates/message.jade b/src/jade/templates/message.jade deleted file mode 100644 index dcaf93c..0000000 --- a/src/jade/templates/message.jade +++ /dev/null @@ -1,40 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#message-template(type="text/x-template") - .modal-mask(v-show="show", transition="modal") - .modal-wrapper - .modal-container - .modal-header - slot(name="header") default header - - .modal-body - slot(name="body") default body - - .modal-footer - slot(name="footer") - button.pure-button.button-success(@click="show = false") OK diff --git a/src/jade/templates/modbus-reg-view.jade b/src/jade/templates/modbus-reg-view.jade deleted file mode 100644 index ac86cfd..0000000 --- a/src/jade/templates/modbus-reg-view.jade +++ /dev/null @@ -1,45 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#modbus-reg-view-template(type="text/x-template") - tr.modbus-reg - td.reg-index {{index}} - td.reg-type - select(v-model="model['reg-type']", @change="change") - option(v-for="opt in template['reg-type']['values']", :value="opt") - | {{opt}} - - td.reg-addr - input(v-model="model['reg-addr']", @change="change", type="text", - :min="template['reg-addr'].min", :max="template['reg-addr'].max", - pattern="[0-9]*", :disabled="model['reg-type'] == 'disabled'", - number) - - td.reg-value - input(v-model="model['reg-value']", @change="change", type="text", - :min="template['reg-value'].min", :max="template['reg-value'].max", - pattern="[0-9]*", :disabled="!has_user_value", number) diff --git a/src/jade/templates/motor-view.jade b/src/jade/templates/motor-view.jade deleted file mode 100644 index 17c52a7..0000000 --- a/src/jade/templates/motor-view.jade +++ /dev/null @@ -1,61 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#motor-view-template(type="text/x-template") - .motor(:class="{slave: is_slave}") - h1 Motor {{index}} Configuration - - .pure-form.pure-form-aligned - fieldset(v-for="category in template.motors.template", :class="$key") - h2 {{$key}} - - templated-input(v-for="templ in category", :name="$key", - :model.sync="motor[$key]", :template="templ") - - label.extra(v-if="$key == 'microsteps'", slot="extra", - :class="{error: invalidMaxVelocity}", - title="Microsteps per second") - | ({{ustepPerSec / 1000 | fixed 1}}k µstep/sec) - - label.extra(v-if="$key == 'max-velocity'", slot="extra", - title="Revolutions Per Minute") ({{rpm | fixed 0}} RPM) - - label.extra(v-if="$key == 'max-accel' && metric", slot="extra", - title="G-force") ({{gForce | fixed 3}} g) - - label.extra(v-if="$key == 'max-jerk' && metric", slot="extra", - title="G-force per minute") ({{gForcePerMin | fixed 2}} g/min) - - label.extra(v-if="$key == 'step-angle'", slot="extra", - title="Steps per revolution") ({{stepsPerRev | fixed 0}} steps/rev) - - label.extra(v-if="$key == 'travel-per-rev' && metric", slot="extra", - title="Micrometers per step") ({{umPerStep | fixed 1}} µm/step) - - label.extra(v-if="$key == 'travel-per-rev' && !metric", slot="extra", - title="Thousandths of an inch per step") - | ({{milPerStep | fixed 2}} mil/step) diff --git a/src/jade/templates/settings-view.jade b/src/jade/templates/settings-view.jade deleted file mode 100644 index cd3444b..0000000 --- a/src/jade/templates/settings-view.jade +++ /dev/null @@ -1,41 +0,0 @@ -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#settings-view-template(type="text/x-template") - #settings - h1 Settings - - .pure-form.pure-form-aligned - fieldset - h2 Units - templated-input(name="units", :model.sync="config.settings.units", - :template="template.settings.units") - - p - | Note, units sets both the machine default units and the - | units used in motor configuration. GCode program-start, - | set below, may also change the default machine units. - - fieldset - h2 GCode - templated-input(v-for="templ in template.gcode", :name="$key", - :model.sync="config.gcode[$key]", :template="templ") diff --git a/src/jade/templates/templated-input.jade b/src/jade/templates/templated-input.jade deleted file mode 100644 index 0e456ac..0000000 --- a/src/jade/templates/templated-input.jade +++ /dev/null @@ -1,61 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#templated-input-template(type="text/x-template") - .pure-control-group(class="tmpl-input-{{name}}", - title="Default {{template.default}} {{template.unit || ''}}") - label(:for="name") {{name}} - - select(v-if="template.type == 'enum' || template.values", v-model="view", - :name="name", @change="change") - option(v-for="opt in template.values", :value="opt") {{opt}} - - input(v-if="template.type == 'bool'", type="checkbox", v-model="view", - :name="name", @change="change") - - input(v-if="template.type == 'float'", v-model="view", number, - :min="template.min", :max="template.max", :step="template.step || 'any'", - type="number", :name="name", @change="change") - - input(v-if="template.type == 'int' && !template.values", v-model="view", - number, :min="template.min", :max="template.max", type="number", - :name="name", @change="change") - - input(v-if="template.type == 'string'", v-model="view", type="text", - :name="name", @change="change") - - textarea(v-if="template.type == 'text'", v-model="view", :name="name", - @change="change") - - span.range(v-if="template.type == 'percent'") - input(type="range", v-model="view", :name="name", number, min="0", - max="100", step="1", @change="change") - | {{view}} - - label.units {{units}} - - slot(name="extra") diff --git a/src/jade/templates/tool-view.jade b/src/jade/templates/tool-view.jade deleted file mode 100644 index e889502..0000000 --- a/src/jade/templates/tool-view.jade +++ /dev/null @@ -1,184 +0,0 @@ -//-///////////////////////////////////////////////////////////////////////////// -//- // -//- This file is part of the Buildbotics firmware. // -//- // -//- Copyright (c) 2015 - 2018, Buildbotics LLC // -//- All rights reserved. // -//- // -//- This file ("the software") is free software: you can redistribute it // -//- and/or modify it under the terms of the GNU General Public License, // -//- version 2 as published by the Free Software Foundation. You should // -//- have received a copy of the GNU General Public License, version 2 // -//- along with the software. If not, see . // -//- // -//- The software is distributed in the hope that it will be useful, but // -//- WITHOUT ANY WARRANTY; without even the implied warranty of // -//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -//- Lesser General Public License for more details. // -//- // -//- You should have received a copy of the GNU Lesser General Public // -//- License along with the software. If not, see // -//- . // -//- // -//- For information regarding this software email: // -//- "Joseph Coffland" // -//- // -//-///////////////////////////////////////////////////////////////////////////// - -script#tool-view-template(type="text/x-template") - #tool - h1 Tool Configuration - - .pure-form.pure-form-aligned - fieldset - templated-input(v-for="templ in template.tool", :name="$key", - :model.sync="config.tool[$key]", :template="templ", - v-if="tool_type != 'DISABLED' || $key == 'tool-type'") - - fieldset(v-if="tool_type == 'PWM SPINDLE'") - h2 PWM Spindle - templated-input(v-for="templ in template['pwm-spindle']", - :name="$key", :model.sync="config['pwm-spindle'][$key]", - :template="templ") - - fieldset(v-if="is_modbus") - h2 Modbus Configuration - .pure-control-group - label status - tt {{modbus_status}} - templated-input(v-for="templ in template['modbus-spindle']", - :name="$key", :model.sync="config['modbus-spindle'][$key]", - :template="templ", v-if="$key != 'regs'") - - fieldset.modbus-program( - v-if="is_modbus && this.tool_type != 'HUANYANG VFD'") - h2 Active Modbus Program - p - | (Click Save to activate the selected - | tool-type.) - table.modbus-regs.fixed-regs - tr - th Index - th Command - th Address - th Value - th Failures - - tr(v-for="(index, reg) in regs_tmpl.index", v-if="state[reg + 'vt']", - :class="{warn: get_reg_fails(reg)}") - td.reg-index {{index}} - td.reg-type {{get_reg_type(reg)}} - td.reg-addr {{get_reg_addr(reg)}} - td.reg-value {{get_reg_value(reg)}} - td.reg-fails {{get_reg_fails(reg)}} - - button.pure-button-secondary(@click="customize") Customize - button.pure-button-secondary(@click="clear", - v-if="tool_type == 'CUSTOM MODBUS VFD'") Clear - button.pure-button-secondary(@click="reset_failures") Reset Failures - - fieldset(v-if="tool_type == 'CUSTOM MODBUS VFD'") - h2 Edit Modbus Program - table.modbus-regs - tr - th Index - th Command - th Address - th Value - - tr(v-for="(index, reg) in config['modbus-spindle'].regs", - is="modbus-reg", :index="index", :model.sync="reg", - :template="template['modbus-spindle'].regs.template", - v-if="!index || reg['reg-type'] != 'disabled' || " + - "config['modbus-spindle'].regs[index - 1]['reg-type'] != " + - "'disabled'") - - .notes(v-if="tool_type == 'HUANYANG VFD'") - h2 Notes - p Set the following using the VFD's frontpanel. - table.modbus-regs.fixed-regs - tr - th Address - th Value - td Meaning - th Description - tr - td.reg-addr PD000 - td.reg-value 0 - td Unlock - td Unlock parameters - tr - td.reg-addr PD001 - td.reg-value 2 - td RS485 - td Command source - tr - td.reg-addr PD002 - td.reg-value 2 - td RS485 - td Speed/frequency source - tr - td.reg-addr PD163 - td.reg-value 1 - td Modbus ID - td Must match bus-id above. - tr - td.reg-addr PD164 - td.reg-value 1 - td 9600 baud - td Must match baud above. - tr - td.reg-addr PD166 - td.reg-value 3 - td 8 bit, no parity, RTU mode - td Must match parity above. - - p - | Other settings according to the Huanyang VFD manual and spindle type. - - .notes(v-if="tool_type.startsWith('DELTA VFD015M21A')") - h2 Notes - p Set the following using the VFD's frontpanel. - table.modbus-regs.fixed-regs - tr - th Address - th Value - th Meaning - th Description - tr - td.reg-addr Pr.00 - td.reg-value 3 - td RS-485 - td Source of frequency command - tr - td.reg-addr Pr.01 - td.reg-value 3 - td RS-485 with STOP - td Source of operation command - tr - td.reg-addr Pr.88 - td.reg-value 1 - td Modbus ID - td Must match bus-id above - tr - td.reg-addr Pr.89 - td.reg-value 1 - td 9600 baud - td Must match baud above - tr - td.reg-addr Pr.92 - td.reg-value 3 - td 8 bit, no parity, RTU mode - td Must match parity above - tr - td.reg-addr Pr.157 - td.reg-value 1 - td Modbus mode - td Communication mode - - p - | Other settings according to the Delta VFD015M21A VFD manual and spindle type. diff --git a/src/js/api.js b/src/js/api.js index f5bb507..e8186b2 100644 --- a/src/js/api.js +++ b/src/js/api.js @@ -51,7 +51,7 @@ function api_cb(method, url, data, config) { try {text = $.parseJSON(xhr.responseText)} catch(e) {} d.reject(text, xhr, status, error); console.debug('API Error: ' + url + ': ' + xhr.responseText); - }) + }); return d.promise(); } diff --git a/src/js/app.js b/src/js/app.js index 7ce3c21..c5da73e 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -218,8 +218,7 @@ module.exports = new Vue({ toggle_video: function () { - if (this.video_size == 'small') this.video_size = 'medium'; - else if (this.video_size == 'medium') this.video_size = 'large'; + if (this.video_size == 'small') this.video_size = 'large'; else if (this.video_size == 'large') this.video_size = 'small'; }, diff --git a/src/js/control-view.js b/src/js/control-view.js index 8328b90..2648fca 100644 --- a/src/js/control-view.js +++ b/src/js/control-view.js @@ -51,6 +51,9 @@ module.exports = { mach_units: 'METRIC', mdi: '', files: [], + last_file: undefined, + toolpath: {}, + progress: 0, axes: 'xyzabc', history: [], speed_override: 1, @@ -69,6 +72,7 @@ module.exports = { components: { 'axis-control': require('./axis-control'), + 'path-viewer': require('./path-viewer'), 'gcode-viewer': require('./gcode-viewer') }, @@ -222,8 +226,30 @@ module.exports = { load: function () { var file = this.state.selected; + if (this.last_file == file) return; + this.last_file = file; + if (typeof file != 'undefined') this.$broadcast('gcode-load', file); this.$broadcast('gcode-line', this.state.line); + this.progress = 0; + this.load_toolpath(file); + }, + + + load_toolpath: function (file) { + this.toolpath = {}; + + if (typeof file == 'undefined') return; + + api.get('path/' + file).done(function (toolpath) { + if (this.last_file != file) return; + + if (typeof toolpath.progress == 'undefined') this.toolpath = toolpath; + else { + this.progress = toolpath.progress; + this.load_toolpath(file); // Try again + } + }.bind(this)); }, @@ -312,6 +338,11 @@ module.exports = { }, + get_position: function (axis) { + return this.state[axis + 'p'] + this.get_offset(axis); + }, + + get_offset: function (axis) {return this.state['offset_' + axis] || 0}, diff --git a/src/js/gcode-viewer.js b/src/js/gcode-viewer.js index d8584a8..67847e4 100644 --- a/src/js/gcode-viewer.js +++ b/src/js/gcode-viewer.js @@ -79,6 +79,8 @@ module.exports = { api.get('file/' + file) .done(function (data) { + if (this.file != file) return; + var lines = data.trimRight().split(/\r?\n/); for (var i = 0; i < lines.length; i++) { diff --git a/src/js/main.js b/src/js/main.js index 2a65204..9aa3aad 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -40,11 +40,22 @@ $(function() { Vue.component('console', require('./console')); Vue.component('unit-value', require('./unit-value')); + Vue.filter('number', function (value) { + if (isNaN(value)) return 'NaN'; + return value.toLocaleString(); + }); + Vue.filter('percent', function (value, precision) { if (typeof precision == 'undefined') precision = 2; return (value * 100.0).toFixed(precision) + '%'; }); + Vue.filter('non_zero_percent', function (value, precision) { + if (!value) return ''; + if (typeof precision == 'undefined') precision = 2; + return (value * 100.0).toFixed(precision) + '%'; + }); + Vue.filter('fixed', function (value, precision) { if (typeof value == 'undefined') return ''; return parseFloat(value).toFixed(precision) @@ -55,6 +66,40 @@ $(function() { return value.toUpperCase() }); + Vue.filter('time', function (value, precision) { + if (isNaN(value)) return ''; + if (isNaN(precision)) precision = 0; + + var MIN = 60; + var HR = MIN * 60; + var DAY = HR * 24; + var parts = []; + + if (DAY <= value) { + parts.push(value / DAY); + value %= DAY; + } + + if (HR <= value) { + parts.push(value / HR); + value %= HR; + } + + if (MIN <= value) { + parts.push(value / MIN); + value %= MIN; + } + + parts.push(value.toFixed(precision)); + + for (var i = 0; i < parts.length - 1; i++) { + parts[i] = parts[i].toFixed(0); + if (i && parts[i] < 10) parts[i] = '0' + parts[i]; + } + + return parts.join(':'); + }); + // Vue app require('./app'); }); diff --git a/src/js/orbit.js b/src/js/orbit.js new file mode 100644 index 0000000..5225f9a --- /dev/null +++ b/src/js/orbit.js @@ -0,0 +1,683 @@ +/** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + * @author jcoffland / https://buildbotics.com/ + */ + +'use strict' + +// This set of controls performs orbiting, dollying (zooming), and panning. +// Unlike TrackballControls, it maintains the "up" direction object.up +// (+Y by default). +// +// Orbit - left mouse / touch: one-finger move +// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish +// Pan - right mouse, or arrow keys / touch: two-finger move + + +var OrbitControls = function (object, domElement) { + this.object = object; + this.domElement = domElement != undefined ? domElement : document; + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + + // How far you can zoom in and out (OrthographicCamera only) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [- Math.PI, Math.PI]. + this.minAzimuthAngle = -Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option enables dollying in and out; + // left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; + + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if true, pan in screen-space + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // Set to false to disable use of the keys + this.enableKeys = true; + + // The four arrow keys + this.keys = {LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40}; + + // Mouse buttons + this.mouseButtons = { + ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT + }; + + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // public methods + this.getPolarAngle = function () {return spherical.phi} + this.getAzimuthalAngle = function () {return spherical.theta} + + + this.saveState = function () { + scope.target0.copy(scope.target); + scope.position0.copy(scope.object.position); + scope.zoom0 = scope.object.zoom; + } + + + this.reset = function () { + scope.target.copy(scope.target0); + scope.object.position.copy(scope.position0); + scope.object.zoom = scope.zoom0; + scope.object.updateProjectionMatrix(); + + scope.dispatchEvent(changeEvent); + scope.update(); + + state = STATE.NONE; + } + + + this.update = function () { + var offset = new THREE.Vector3(); + + // so camera.up is the orbit axis + var quat = new THREE.Quaternion() + .setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0)); + var quatInverse = quat.clone().inverse(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + return function update() { + var position = scope.object.position; + + offset.copy(position).sub(scope.target); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion(quat); + + // angle from z-axis around y-axis + spherical.setFromVector3(offset); + + if (scope.autoRotate && state == STATE.NONE) + rotateLeft(getAutoRotationAngle()); + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = + Math.max(scope.minAzimuthAngle, + Math.min(scope.maxAzimuthAngle, spherical.theta)); + + // restrict phi to be between desired limits + spherical.phi = + Math.max(scope.minPolarAngle, + Math.min(scope.maxPolarAngle, spherical.phi)); + + spherical.makeSafe(); + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = + Math.max(10, Math.min(scope.object.far * 0.8, spherical.radius)); + + // move target to panned location + scope.target.add(panOffset); + + offset.setFromSpherical(spherical); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion(quatInverse); + + position.copy(scope.target).add(offset); + scope.object.lookAt(scope.target); + + if (scope.enableDamping) { + sphericalDelta.theta *= (1 - scope.dampingFactor); + sphericalDelta.phi *= (1 - scope.dampingFactor); + panOffset.multiplyScalar(1 - scope.dampingFactor); + + } else { + sphericalDelta.set(0, 0, 0); + panOffset.set(0, 0, 0); + } + + scale = 1; + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + if (zoomChanged || + lastPosition.distanceToSquared(scope.object.position) > EPS || + 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) { + + scope.dispatchEvent(changeEvent); + + lastPosition.copy(scope.object.position); + lastQuaternion.copy(scope.object.quaternion); + zoomChanged = false; + + return true; + } + + return false; + } + }() + + + this.dispose = function () { + scope.domElement.removeEventListener('contextmenu', onContextMenu, false); + scope.domElement.removeEventListener('mousedown', onMouseDown, false); + scope.domElement.removeEventListener('wheel', onMouseWheel, false); + scope.domElement.removeEventListener('touchstart', onTouchStart, false); + scope.domElement.removeEventListener('touchend', onTouchEnd, false); + scope.domElement.removeEventListener('touchmove', onTouchMove, false); + document.removeEventListener('mousemove', onMouseMove, false); + document.removeEventListener('mouseup', onMouseUp, false); + window.removeEventListener('keydown', onKeyDown, false); + } + + + // internals + var scope = this; + + var changeEvent = {type: 'change'}; + var startEvent = {type: 'start'}; + var endEvent = {type: 'end'}; + + var STATE = { + NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 + }; + + var state = STATE.NONE; + var EPS = 0.000001; + + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); + + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + + function getAutoRotationAngle() { + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + } + + + function getZoomScale() {return Math.pow(0.95, scope.zoomSpeed)} + function rotateLeft(angle) {sphericalDelta.theta -= angle} + function rotateUp(angle) {sphericalDelta.phi -= angle} + + + var panLeft = function () { + var v = new THREE.Vector3(); + + return function panLeft(distance, objectMatrix) { + v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix + v.multiplyScalar(-distance); + panOffset.add(v); + } + }() + + + var panUp = function () { + var v = new THREE.Vector3(); + + return function panUp(distance, objectMatrix) { + if (scope.screenSpacePanning) v.setFromMatrixColumn(objectMatrix, 1); + else { + v.setFromMatrixColumn(objectMatrix, 0); + v.crossVectors(scope.object.up, v); + } + + v.multiplyScalar(distance); + panOffset.add(v); + } + }() + + + function unknownCamera() { + console.warn('WARNING: OrbitControls.js encountered an unknown camera ' + + 'type - pan & zoom disabled.'); + scope.enablePan = false; + scope.enableZoom = false; + } + + + // deltaX and deltaY are in pixels; right and down are positive + var pan = function () { + var offset = new THREE.Vector3(); + + return function pan(deltaX, deltaY) { + var element = scope.domElement === document ? + scope.domElement.body : scope.domElement; + + if (scope.object.isPerspectiveCamera) { + // perspective + offset.copy(scope.object.position).sub(scope.target); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0); + + // we use only clientHeight here so aspect ratio does not distort speed + panLeft(2 * deltaX * targetDistance / element.clientHeight, + scope.object.matrix); + panUp(2 * deltaY * targetDistance / element.clientHeight, + scope.object.matrix); + + } else if (scope.object.isOrthographicCamera) { + // orthographic + panLeft(deltaX * (scope.object.right - scope.object.left) / + scope.object.zoom / element.clientWidth, scope.object.matrix); + panUp(deltaY * (scope.object.top - scope.object.bottom) / + scope.object.zoom / element.clientHeight, scope.object.matrix); + + } else unknownCamera(); + } + }() + + + function dollyIn(dollyScale) { + if (scope.object.isPerspectiveCamera) scale /= dollyScale; + + else if (scope.object.isOrthographicCamera) { + scope.object.zoom = + Math.max(scope.minZoom, + Math.min(scope.maxZoom, scope.object.zoom * dollyScale)); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else unknownCamera(); + } + + + function dollyOut(dollyScale) { + if (scope.object.isPerspectiveCamera) scale *= dollyScale; + + else if (scope.object.isOrthographicCamera) { + scope.object.zoom = + Math.max(scope.minZoom, + Math.min(scope.maxZoom, scope.object.zoom / dollyScale)); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else unknownCamera(); + } + + + // event callbacks - update the object state + function handleMouseDownRotate(event) { + rotateStart.set(event.clientX, event.clientY); + } + + + function handleMouseDownDolly(event) { + dollyStart.set(event.clientX, event.clientY); + } + + + function handleMouseDownPan(event) { + panStart.set(event.clientX, event.clientY); + } + + + function handleMouseMoveRotate(event) { + rotateEnd.set(event.clientX, event.clientY); + rotateDelta.subVectors(rotateEnd, rotateStart) + .multiplyScalar(scope.rotateSpeed); + + var element = scope.domElement === document ? + scope.domElement.body : scope.domElement; + + // yes, height + rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); + rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); + + rotateStart.copy(rotateEnd); + + scope.update(); + } + + + function handleMouseMoveDolly(event) { + dollyEnd.set(event.clientX, event.clientY); + dollyDelta.subVectors(dollyEnd, dollyStart); + + if (dollyDelta.y > 0) dollyIn(getZoomScale()); + else if (dollyDelta.y < 0) dollyOut(getZoomScale()); + + dollyStart.copy(dollyEnd); + scope.update(); + } + + + function handleMouseMovePan(event) { + panEnd.set(event.clientX, event.clientY); + panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); + pan(panDelta.x, panDelta.y); + panStart.copy(panEnd); + scope.update(); + } + + + function handleMouseUp(event) {} + + + function handleMouseWheel(event) { + if (event.deltaY < 0) dollyOut(getZoomScale()); + else if (event.deltaY > 0) dollyIn(getZoomScale()); + + scope.update(); + } + + + function handleKeyDown(event) { + switch (event.keyCode) { + case scope.keys.UP: + pan(0, scope.keyPanSpeed); + scope.update(); + break; + + case scope.keys.BOTTOM: + pan(0, -scope.keyPanSpeed); + scope.update(); + break; + + case scope.keys.LEFT: + pan(scope.keyPanSpeed, 0); + scope.update(); + break; + + case scope.keys.RIGHT: + pan(-scope.keyPanSpeed, 0); + scope.update(); + break; + } + } + + + function handleTouchStartRotate(event) { + rotateStart.set(event.touches[0].pageX, event.touches[0].pageY); + } + + + function handleTouchStartDollyPan(event) { + if (scope.enableZoom) { + var dx = event.touches[0].pageX - event.touches[1].pageX; + var dy = event.touches[0].pageY - event.touches[1].pageY; + var distance = Math.sqrt(dx * dx + dy * dy); + + dollyStart.set(0, distance); + } + + if (scope.enablePan) { + var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); + var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); + panStart.set(x, y); + } + } + + + function handleTouchMoveRotate(event) { + rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY); + rotateDelta.subVectors(rotateEnd, rotateStart) + .multiplyScalar(scope.rotateSpeed); + + var element = scope.domElement === document ? + scope.domElement.body : scope.domElement; + + // yes, height + rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); + rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); + rotateStart.copy(rotateEnd); + scope.update(); + } + + + function handleTouchMoveDollyPan(event) { + if (scope.enableZoom) { + var dx = event.touches[0].pageX - event.touches[1].pageX; + var dy = event.touches[0].pageY - event.touches[1].pageY; + var distance = Math.sqrt(dx * dx + dy * dy); + + dollyEnd.set(0, distance); + dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed)); + dollyIn(dollyDelta.y); + dollyStart.copy(dollyEnd); + } + + + if (scope.enablePan) { + var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); + var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); + + panEnd.set(x, y); + panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); + pan(panDelta.x, panDelta.y); + panStart.copy(panEnd); + } + + scope.update(); + } + + + function handleTouchEnd(event) {} + + + // event handlers - listen for events and reset state + function onMouseDown(event) { + if (!scope.enabled) return; + + event.preventDefault(); + + switch (event.button) { + case scope.mouseButtons.ORBIT: + if (!scope.enableRotate) return; + handleMouseDownRotate(event); + state = STATE.ROTATE; + break; + + case scope.mouseButtons.ZOOM: + if (!scope.enableZoom) return; + handleMouseDownDolly(event); + state = STATE.DOLLY; + break; + + case scope.mouseButtons.PAN: + if (!scope.enablePan) return; + handleMouseDownPan(event); + state = STATE.PAN; + break; + } + + if (state != STATE.NONE) { + document.addEventListener('mousemove', onMouseMove, false); + document.addEventListener('mouseup', onMouseUp, false); + scope.dispatchEvent(startEvent); + } + } + + + function onMouseMove(event) { + if (!scope.enabled) return; + + event.preventDefault(); + + switch (state) { + case STATE.ROTATE: + if (!scope.enableRotate) return; + handleMouseMoveRotate(event); + break; + + case STATE.DOLLY: + if (!scope.enableZoom) return; + handleMouseMoveDolly(event); + break; + + case STATE.PAN: + if (!scope.enablePan) return; + handleMouseMovePan(event); + break; + } + } + + + function onMouseUp(event) { + if (!scope.enabled) return; + + handleMouseUp(event); + document.removeEventListener('mousemove', onMouseMove, false); + document.removeEventListener('mouseup', onMouseUp, false); + scope.dispatchEvent(endEvent); + state = STATE.NONE; + } + + + function onMouseWheel(event) { + if (!scope.enabled || !scope.enableZoom || + (state != STATE.NONE && state != STATE.ROTATE)) return; + + event.preventDefault(); + event.stopPropagation(); + scope.dispatchEvent(startEvent); + handleMouseWheel(event); + scope.dispatchEvent(endEvent); + } + + + function onKeyDown(event) { + if (!scope.enabled || !scope.enableKeys || !scope.enablePan) return; + + handleKeyDown(event); + } + + + function onTouchStart(event) { + if (!scope.enabled) return; + + event.preventDefault(); + + switch (event.touches.length) { + case 1: // one-fingered touch: rotate + if (!scope.enableRotate) return; + handleTouchStartRotate(event); + state = STATE.TOUCH_ROTATE; + break; + + case 2: // two-fingered touch: dolly-pan + if (!scope.enableZoom && !scope.enablePan) return; + handleTouchStartDollyPan(event); + state = STATE.TOUCH_DOLLY_PAN; + break; + + default: state = STATE.NONE; + } + + if (state != STATE.NONE) scope.dispatchEvent(startEvent); + } + + + function onTouchMove(event) { + if (!scope.enabled) return; + + event.preventDefault(); + event.stopPropagation(); + + switch (event.touches.length) { + case 1: // one-fingered touch: rotate + if (!scope.enableRotate) return; + if (state != STATE.TOUCH_ROTATE) return; // is this needed? + + handleTouchMoveRotate(event); + break; + + case 2: // two-fingered touch: dolly-pan + if (!scope.enableZoom && !scope.enablePan) return; + if (state != STATE.TOUCH_DOLLY_PAN) return; // is this needed? + + handleTouchMoveDollyPan(event); + break; + + default: state = STATE.NONE; + } + } + + + function onTouchEnd(event) { + if (!scope.enabled) return; + + handleTouchEnd(event); + scope.dispatchEvent(endEvent); + state = STATE.NONE; + } + + + function onContextMenu(event) { + if (!scope.enabled) return; + event.preventDefault(); + } + + + scope.domElement.addEventListener('contextmenu', onContextMenu, false); + scope.domElement.addEventListener('mousedown', onMouseDown, false); + scope.domElement.addEventListener('wheel', onMouseWheel, false); + scope.domElement.addEventListener('touchstart', onTouchStart, false); + scope.domElement.addEventListener('touchend', onTouchEnd, false); + scope.domElement.addEventListener('touchmove', onTouchMove, false); + window .addEventListener('keydown', onKeyDown, false); + + this.update(); // force an update at start +} + + +OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype); +OrbitControls.prototype.constructor = OrbitControls; +module.exports = OrbitControls; diff --git a/src/js/path-viewer.js b/src/js/path-viewer.js new file mode 100644 index 0000000..2fe9d67 --- /dev/null +++ b/src/js/path-viewer.js @@ -0,0 +1,612 @@ +/******************************************************************************\ + + Copyright 2018. Buildbotics LLC + All Rights Reserved. + + For information regarding this software email: + Joseph Coffland + joseph@buildbotics.com + + This software is free software: you clan redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation, either version 2.1 of + the License, or (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the C! library. If not, see + . + +\******************************************************************************/ + +'use strict' + +var orbit = require('./orbit'); + + +function get(obj, name, defaultValue) { + return typeof obj[name] == 'undefined' ? defaultValue : obj[name]; +} + + +function set_visible(target, visible) { + if (typeof target != 'undefined') target.visible = visible; +} + + +var surfaceModes = ['cut', 'wire', 'solid', 'off']; + + +module.exports = { + template: '#path-viewer-template', + props: ['toolpath', 'progress', 'x', 'y', 'z'], + + + data: function () { + return { + enabled: true, + loading: false, + small: true, + surfaceMode: 'cut', + showPath: true, + showTool: true, + showBBox: true, + showAxes: true, + error: false, + message: '' + } + }, + + + components: { + 'tool-button': require('./tool-button') + }, + + + computed: { + hasPath: function () {return typeof this.toolpath.path != 'undefined'} + }, + + + watch: { + toolpath: function () {Vue.nextTick(this.update)}, + surfaceMode: function (mode) {this.updateSurfaceMode(mode)}, + small: function () {Vue.nextTick(this.update_view)}, + showPath: function (enable) {set_visible(this.path, enable)}, + showTool: function (enable) {set_visible(this.tool, enable)}, + showBBox: function (enable) {set_visible(this.bbox, enable)}, + showAxes: function (enable) {set_visible(this.axes, enable)}, + x: function () {this.update_tool()}, + y: function () {this.update_tool()}, + z: function () {this.update_tool()} + }, + + + ready: function () { + this.graphics(); + if (typeof this.toolpath.path != 'undefined') Vue.nextTick(this.update); + }, + + + methods: { + update: function () { + if (!this.enabled) return; + + // Reset message + this.message = '' + this.error = false; + this.loading = !this.hasPath; + + // Update scene + this.scene = new THREE.Scene(); + if (this.hasPath) { + this.draw(this.scene); + this.snap('isometric'); + } + + this.update_view(); + }, + + + updateSurfaceMode: function (mode) { + if (!this.enabled) return; + + if (typeof this.surfaceMaterial != 'undefined') { + this.surfaceMaterial.wireframe = mode == 'wire'; + this.surfaceMaterial.needsUpdate = true; + } + + set_visible(this.surfaceMesh, mode == 'cut' || mode == 'wire'); + set_visible(this.workpieceMesh, mode == 'solid'); + }, + + + load_surface: function (surface) { + if (typeof surface == 'undefined') { + this.vertices = undefined; + this.normals = undefined; + return; + } + + this.vertices = surface.vertices; + + // Expand normals + this.normals = []; + for (var i = 0; i < surface.normals.length / 3; i++) + for (var j = 0; j < 3; j++) + for (var k = 0; k < 3; k++) + this.normals.push(surface.normals[i * 3 + k]); + }, + + + getTarget: function () { + return this.$el.querySelector('.path-viewer-content'); + }, + + + getDims: function () { + var t = $(this.getTarget()); + var width = t.innerWidth(); + var height = t.innerHeight(); + return {width: width, height: height}; + }, + + + update_view: function () { + if (!this.enabled) return; + var dims = this.getDims(); + + this.camera.aspect = dims.width / dims.height; + this.camera.updateProjectionMatrix(); + this.renderer.setSize(dims.width, dims.height); + }, + + + update_tool: function (tool) { + if (!this.enabled) return; + if (typeof tool == 'undefined') tool = this.tool; + if (typeof tool == 'undefined') return; + tool.position.x = this.x; + tool.position.y = this.y; + tool.position.z = this.z; + }, + + + graphics: function () { + try { + // Renderer + this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}); + this.renderer.setPixelRatio(window.devicePixelRatio); + this.renderer.setClearColor(0, 0); + + this.getTarget().appendChild(this.renderer.domElement); + + } catch (e) { + this.error = true; + this.message = 'WebGL not supported'; + this.enabled = false; + return; + } + + // Camera + this.camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000); + + // Lighting + this.ambient = new THREE.AmbientLight(0xffffff, 0.5); + + var keyLight = new THREE.DirectionalLight + (new THREE.Color('hsl(30, 100%, 75%)'), 0.75); + keyLight.position.set(-100, 0, 100); + + var fillLight = new THREE.DirectionalLight + (new THREE.Color('hsl(240, 100%, 75%)'), 0.25); + fillLight.position.set(100, 0, 100); + + var backLight = new THREE.DirectionalLight(0xffffff, 0.5); + backLight.position.set(100, 0, -100).normalize(); + + this.lights = new THREE.Group(); + this.lights.add(keyLight); + this.lights.add(fillLight); + this.lights.add(backLight); + + // Surface material + this.surfaceMaterial = this.createSurfaceMaterial(); + + // Controls + this.controls = new orbit(this.camera, this.renderer.domElement); + this.controls.enableDamping = true; + this.controls.dampingFactor = 0.2; + this.controls.rotateSpeed = 0.25; + this.controls.enableZoom = true; + //this.controls.enablePan = false; + + // Move lights with scene + this.controls.addEventListener('change', function (scope) { + return function () { + keyLight.position.copy(scope.camera.position); + fillLight.position.copy(scope.camera.position); + backLight.position.copy(scope.camera.position); + keyLight.lookAt(scope.controls.target); + fillLight.lookAt(scope.controls.target); + backLight.lookAt(scope.controls.target); + } + }(this)) + + // Events + window.addEventListener('resize', this.update_view, false); + + // Start it + this.render(); + }, + + + createSurfaceMaterial: function () { + return new THREE.MeshPhongMaterial({ + specular: 0x111111, + shininess: 10, + side: THREE.FrontSide, + color: 0x0c2d53 + }); + }, + + + drawWorkpiece: function (scene, material) { + if (typeof this.workpiece == 'undefined') return; + + var min = this.workpiece.min; + var max = this.workpiece.max; + + min = new THREE.Vector3(min[0], min[1], min[2]); + max = new THREE.Vector3(max[0], max[1], max[2]); + var dims = max.clone().sub(min); + + var geometry = new THREE.BoxGeometry(dims.x, dims.y, dims.z) + var mesh = new THREE.Mesh(geometry, material); + + var offset = dims.clone(); + offset.divideScalar(2); + offset.add(min); + + mesh.position.add(offset); + + geometry.computeBoundingBox(); + + scene.add(mesh); + + return mesh; + }, + + + drawSurface: function (scene, material) { + if (typeof this.vertices == 'undefined') return; + + var geometry = new THREE.BufferGeometry(); + + geometry.addAttribute + ('position', new THREE.Float32BufferAttribute(this.vertices, 3)); + geometry.addAttribute + ('normal', new THREE.Float32BufferAttribute(this.normals, 3)); + + geometry.computeBoundingSphere(); + geometry.computeBoundingBox(); + + return new THREE.Mesh(geometry, material); + }, + + + drawTool: function (scene, bbox) { + // Tool size is relative to bounds + var size = bbox.getSize(new THREE.Vector3()); + var length = (size.x + size.y + size.z) / 24; + + var material = new THREE.MeshPhongMaterial({ + transparent: true, + opacity: 0.75, + specular: 0x161616, + shininess: 10, + color: 0xffa500 // Orange + }); + + var geometry = new THREE.CylinderGeometry(length / 2, 0, length, 128); + geometry.translate(0, length / 2, 0); + geometry.rotateX(0.5 * Math.PI); + + var mesh = new THREE.Mesh(geometry, material); + this.update_tool(mesh); + scene.add(mesh); + return mesh; + }, + + + drawAxis: function (axis, up, length, radius) { + var color; + + if (axis == 0) color = 0xff0000; // Red + else if (axis == 1) color = 0x00ff00; // Green + else if (axis == 2) color = 0x0000ff; // Blue + + var group = new THREE.Group(); + var material = new THREE.MeshPhongMaterial({ + specular: 0x161616, shininess: 10, color: color + }); + var geometry = new THREE.CylinderGeometry(radius, radius, length, 128); + geometry.translate(0, -length / 2, 0); + group.add(new THREE.Mesh(geometry, material)); + + geometry = new THREE.CylinderGeometry(1.5 * radius, 0, 2 * radius, 128); + geometry.translate(0, -length - radius, 0); + group.add(new THREE.Mesh(geometry, material)); + + if (axis == 0) group.rotateZ((up ? 0.5 : 1.5) * Math.PI); + else if (axis == 1) group.rotateX((up ? 0 : 1 ) * Math.PI); + else if (axis == 2) group.rotateX((up ? 1.5 : 0.5) * Math.PI); + + return group; + }, + + + drawAxes: function (scene, bbox) { + var size = bbox.getSize(new THREE.Vector3()); + var length = (size.x + size.y + size.z) / 3; + length /= 10; + var radius = length / 20; + + var group = new THREE.Group(); + + for (var axis = 0; axis < 3; axis++) + for (var up = 0; up < 2; up++) + group.add(this.drawAxis(axis, up, length, radius)); + + group.visible = this.showAxes; + scene.add(group); + + return group; + }, + + + drawPath: function (scene) { + var cutting = [0, 1, 0]; + var rapid = [1, 0, 0]; + + var x = this.x; + var y = this.y; + var z = this.z; + var color = undefined; + + var positions = []; + var colors = []; + + for (var i = 0; i < this.toolpath.path.length; i++) { + var step = this.toolpath.path[i]; + var newColor = step.rapid ? rapid : cutting; + + if (!i) { + color = newColor; + positions.push(x, y, z); + colors.push.apply(colors, color); + } + + x = get(step, 'x', x); + y = get(step, 'y', y); + z = get(step, 'z', z); + + positions.push(x, y, z); + colors.push.apply(colors, color); + + // Handle type change + if (newColor != color) { + color = newColor; + positions.push(x, y, z); + colors.push.apply(colors, color); + } + } + + var geometry = new THREE.BufferGeometry(); + var material = + new THREE.LineBasicMaterial({ + vertexColors: THREE.VertexColors, + linewidth: 1.5 + }); + + geometry.addAttribute('position', + new THREE.Float32BufferAttribute(positions, 3)); + geometry.addAttribute('color', + new THREE.Float32BufferAttribute(colors, 3)); + + geometry.computeBoundingSphere(); + geometry.computeBoundingBox(); + + var line = new THREE.Line(geometry, material); + + line.visible = this.showPath; + scene.add(line); + + return line; + }, + + + drawBBox: function (scene, bbox) { + if (bbox.isEmpty()) return; + + var vertices = []; + + // Top + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + + // Bottom + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + + // Sides + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + + var geometry = new THREE.BufferGeometry(); + var material = new THREE.LineBasicMaterial({color: 0xffffff}); + + geometry.addAttribute('position', + new THREE.Float32BufferAttribute(vertices, 3)); + + var line = new THREE.LineSegments(geometry, material) + + line.visible = this.showBBox; + + scene.add(line); + + return line; + }, + + + draw: function (scene) { + // Lights + scene.add(this.ambient); + scene.add(this.lights); + + // Model + this.path = this.drawPath(scene); + this.surfaceMesh = this.drawSurface(scene, this.surfaceMaterial); + this.workpieceMesh = this.drawWorkpiece(scene, this.surfaceMaterial); + this.updateSurfaceMode(this.surfaceMode); + + // Compute bounding box + var bbox = this.get_model_bounds(); + + // Tool, axes & bounds + this.tool = this.drawTool(scene, bbox); + this.axes = this.drawAxes(scene, bbox); + this.bbox = this.drawBBox(scene, bbox); + }, + + + render: function () { + window.requestAnimationFrame(this.render); + if (typeof this.scene == 'undefined') return; + this.controls.update(); + this.renderer.render(this.scene, this.camera); + }, + + + get_model_bounds: function () { + var bbox = new THREE.Box3(); + + function add(o) { + if (typeof o != 'undefined') bbox.union(o.geometry.boundingBox); + } + + add(this.path); + add(this.surfaceMesh); + add(this.workpieceMesh); + + return bbox; + }, + + + snap: function (view) { + var bbox = this.get_model_bounds(); + this.controls.reset(); + bbox.getCenter(this.controls.target); + this.update_view(); + + // Compute new camera position + var center = bbox.getCenter(new THREE.Vector3()); + var offset = new THREE.Vector3(); + + if (view == 'isometric') {offset.y -= 1; offset.z += 1;} + if (view == 'front') offset.y -= 1; + if (view == 'back') offset.y += 1; + if (view == 'left') offset.x -= 1; + if (view == 'right') offset.x += 1; + if (view == 'top') offset.z += 1; + if (view == 'bottom') offset.z -= 1; + offset.normalize(); + + // Initial camera position + var position = new THREE.Vector3().copy(center).add(offset); + this.camera.position.copy(position); + this.camera.lookAt(center); // Get correct camera orientation + + var theta = this.camera.fov / 180 * Math.PI; // View angle + var cameraLine = new THREE.Line3(center, position); + var cameraUp = new THREE.Vector3().copy(this.camera.up) + .applyQuaternion(this.camera.quaternion); + var cameraLeft = + new THREE.Vector3().copy(offset).cross(cameraUp).normalize(); + + var corners = [ + new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.min.z), + new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.max.z), + new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.min.z), + new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.max.z), + new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.min.z), + new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.max.z), + new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.min.z), + new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.max.z), + ] + + var dist = this.camera.near; // Min camera dist + + for (var i = 0; i < corners.length; i++) { + // Project on to camera line + var p1 = cameraLine + .closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute distance from projection to center + var d = p1.distanceTo(center); + if (cameraLine.closestPointToPointParameter(p1, false) < 0) d = -d; + + // Compute up line + var up = + new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraUp)); + + // Project on to up line + var p2 = up.closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute length + var l = p1.distanceTo(p2); + + // Update min camera distance + dist = Math.max(dist, d + l / Math.tan(theta / 2)); + + // Compute left line + var left = + new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraLeft)); + + // Project on to left line + var p3 = + left.closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute length + l = p1.distanceTo(p3); + + // Update min camera distance + dist = Math.max(dist, d + l / Math.tan(theta / 2) / this.camera.aspect); + } + + this.camera.position.copy(offset.multiplyScalar(dist * 1.2).add(center)); + } + } +} diff --git a/src/js/sock.js b/src/js/sock.js index 7700b9c..6d1f7f7 100644 --- a/src/js/sock.js +++ b/src/js/sock.js @@ -37,6 +37,8 @@ var Sock = function (url, retry, timeout) { this.url = url; this.retry = retry; this.timeout = timeout; + this.divisions = 4; + this.count = 0; this.connect(); } @@ -55,14 +57,14 @@ Sock.prototype.connect = function () { this._sock.onmessage = function (e) { console.debug('msg:', e.data); - this._set_timeout(); + this.heartbeat('msg'); this.onmessage(e); }.bind(this); this._sock.onopen = function () { console.debug('connected'); - this._set_timeout(); + this.heartbeat('open'); this.onopen(); }.bind(this); @@ -78,22 +80,35 @@ Sock.prototype.connect = function () { } -Sock.prototype._set_timeout = function () { - this._cancel_timeout(); - this._timeout = setTimeout(this._timedout.bind(this), this.timeout); -} - - Sock.prototype._timedout = function () { - console.debug('connection timedout'); - this._timeout = undefined; - this._sock.close(); + // Divide timeout so slow browser doesn't trigger timeouts when the + // connection is good. + if (this.divisions <= ++this.count) { + console.debug('connection timedout'); + this._timeout = undefined; + this._sock.close(); + + } else this._set_timeout(); } Sock.prototype._cancel_timeout = function () { clearTimeout(this._timeout); this._timeout = undefined; + this.count = 0; +} + + +Sock.prototype._set_timeout = function () { + this._timeout = setTimeout(this._timedout.bind(this), + this.timeout / this.divisions); +} + + +Sock.prototype.heartbeat = function (msg) { + //console.debug('heartbeat ' + new Date().toLocaleTimeString() + ' ' + msg); + this._cancel_timeout(); + this._set_timeout(); } @@ -106,9 +121,7 @@ Sock.prototype.close = function () { } -Sock.prototype.send = function (msg) { - this._sock.send(msg); -} +Sock.prototype.send = function (msg) {this._sock.send(msg)} module.exports = Sock diff --git a/src/js/tool-button.js b/src/js/tool-button.js new file mode 100644 index 0000000..f77d0fd --- /dev/null +++ b/src/js/tool-button.js @@ -0,0 +1,32 @@ +/******************************************************************************\ + + Copyright 2018. Buildbotics LLC + All Rights Reserved. + + For information regarding this software email: + Joseph Coffland + joseph@buildbotics.com + + This software is free software: you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation, either version 2.1 of + the License, or (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the C! library. If not, see + . + +\******************************************************************************/ + +'use strict' + + +module.exports = { + template: '#tool-button-template', + props: ['name', 'active'] +} diff --git a/src/pug/index.pug b/src/pug/index.pug new file mode 100644 index 0000000..d50f5ae --- /dev/null +++ b/src/pug/index.pug @@ -0,0 +1,213 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +include ../../build/hashes.pug + + +doctype html +html(lang="en") + head + meta(charset="utf-8") + meta(name="viewport", content="width=device-width, initial-scale=1.0") + + title Buildbotics Controller - Web interface + + link(rel="stylesheet", href="/css/pure-min.css") + //if lte IE 8 + link(rel="stylesheet", href="css/side-menu-old-ie.css") + // [if gt IE 8] {{firmwareName}}? + + p.pure-control-group + label(for="pass") Password + input(name="pass", v-model="password", type="password", + @keyup.enter="upload_confirmed") + + div(slot="footer") + button.pure-button(@click="confirmUpload=false") Cancel + button.pure-button.pure-button-primary(@click="upload_confirmed") + | Upload + + message(:show.sync="firmwareUpgrading") + h3(slot="header") Firmware upgrading + div(slot="body") + h3 Please wait... + p Loss of power during an upgrade may damage the controller. + div(slot="footer") + + message(:show.sync="showMessages") + h3(slot="header") GCode message + + div(slot="body") + ul + li(v-for="msg in messages", track-by="$index") {{msg}} + + div(slot="footer") + button.pure-button.button-success(v-if="state.xx != 'HOLDING'", + @click="close_messages('ok')") OK + + div(v-if="state.xx == 'HOLDING'") + button.pure-button(@click="close_messages('stop')") + | Stop + .fa.fa-stop + + button.pure-button(@click="close_messages('continue')") + | Continue + .fa.fa-play + + #templates + include ../../build/templates.pug + + iframe#download-target(style="display:none") + + script(src="js/jquery-1.11.3.min.js") + script(src="js/vue.js") + script(src="js/sockjs.min.js") + script(src="js/clusterize.min.js") + script(src="js/three.min.js") + script(src="/js/assets-" + js_hash + ".js") + script(src="js/ui.js") diff --git a/src/pug/templates/admin-general-view.pug b/src/pug/templates/admin-general-view.pug new file mode 100644 index 0000000..14afba4 --- /dev/null +++ b/src/pug/templates/admin-general-view.pug @@ -0,0 +1,67 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#admin-general-view-template(type="text/x-template") + #admin-general + h2 Firmware + button.pure-button.pure-button-primary(@click="check") Check + button.pure-button.pure-button-primary(@click="upgrade") Upgrade + label.pure-button.pure-button-primary.file-upload + input(type="file", accept=".tar.bz2", @change="upload") + | Upload + + p + input(type="checkbox", v-model="autoCheckUpgrade", + @change="change_auto_check_upgrade") + label(for="auto-check-upgrade")   Automatically check for upgrades + + h2 Configuration + button.pure-button.pure-button-primary(@click="backup") Backup + + label.pure-button.pure-button-primary.file-upload + input(type="file", accept=".json", @change="restore") + | Restore + message(:show.sync="configRestored") + h3(slot="header") Success + p(slot="body") Configuration restored. + + button.pure-button.pure-button-primary(@click="confirmReset = true") + | Reset + message(:show.sync="confirmReset") + h3(slot="header") Reset to default configuration? + p(slot="body") All configuration changes will be lost. + div(slot="footer") + button.pure-button(@click="confirmReset = false") Cancel + button.pure-button.button-success(@click="reset") OK + + message(:show.sync="configReset") + h3(slot="header") Success + p(slot="body") Configuration reset. + + h2 Debugging + a(href="/api/log", target="_blank") + button.pure-button.pure-button-primary View Log diff --git a/src/pug/templates/admin-network-view.pug b/src/pug/templates/admin-network-view.pug new file mode 100644 index 0000000..1ff0b4b --- /dev/null +++ b/src/pug/templates/admin-network-view.pug @@ -0,0 +1,123 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#admin-network-view-template(type="text/x-template") + #admin-network + h2 Hostname + .pure-form.pure-form-aligned + .pure-control-group + label(for="hostname") Hostname + input(name="hostname", v-model="hostname", @keyup.enter="set_hostname") + button.pure-button.pure-button-primary(@click="set_hostname") Set + + message(:show.sync="hostnameSet") + h3(slot="header") Hostname Set + div(slot="body") + p Hostname was successfuly set to {{hostname}}. + p Rebooting to apply changes. + p Redirecting to new hostname in {{redirectTimeout}} seconds. + div(slot="footer") + + h2 Remote SSH User + .pure-form.pure-form-aligned + .pure-control-group + label(for="username") Username + input(name="username", v-model="username", @keyup.enter="set_username") + button.pure-button.pure-button-primary(@click="set_username") Set + + .pure-form.pure-form-aligned + .pure-control-group + label(for="current") Current Password + input(name="current", v-model="current", type="password") + .pure-control-group + label(for="pass1") New Password + input(name="pass1", v-model="password", type="password") + .pure-control-group + label(for="pass2") New Password + input(name="pass2", v-model="password2", type="password") + button.pure-button.pure-button-primary(@click="set_password") Set + + message(:show.sync="passwordSet") + h3(slot="header") Password Set + p(slot="body") + + message(:show.sync="usernameSet") + h3(slot="header") Username Set + p(slot="body") + + h2 Wifi Setup + .pure-form.pure-form-aligned + .pure-control-group + label(for="wifi_mode") Mode + select(name="wifi_mode", v-model="wifi_mode", + title="Select client or access point mode") + option(value="disabled") Disabled + option(value="client") Client + option(value="ap") Access Point + button.pure-button.pure-button-primary(@click="wifiConfirm = true", + v-if="wifi_mode == 'disabled'") Set + .pure-control-group(v-if="wifi_mode == 'ap'") + label(for="wifi_ch") Channel + select(name="wifi_ch", v-model="wifi_ch") + each ch in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + option(value="#{ch}")= ch + .pure-control-group(v-if="wifi_mode != 'disabled'") + label(for="ssid") Network (SSID) + input(name="ssid", v-model="wifi_ssid") + .pure-control-group(v-if="wifi_mode != 'disabled'") + label(for="wifi_pass") Password + input(name="wifi_pass", v-model="wifi_pass", type="password") + button.pure-button.pure-button-primary(@click="wifiConfirm = true") Set + + message.wifi-confirm(:show.sync="wifiConfirm") + h3(slot="header") Configure Wifi and reboot? + div(slot="body") + p + | After configuring the Wifi settings the controller will + | automatically reboot. + table + tr + th Mode + td  {{wifi_mode}} + tr(v-if="wifi_mode == 'ap'") + th Channel + td  {{wifi_ch}} + tr(v-if="wifi_mode != 'disabled'") + th SSID + td  {{wifi_ssid}} + tr(v-if="wifi_mode != 'disabled'") + th Auth + td  {{wifi_pass ? 'WPA2' : 'Open'}} + + div(slot="footer") + button.pure-button(@click="wifiConfirm = false") Cancel + button.pure-button.button-success(@click="config_wifi") OK + + message(:show.sync="rebooting") + h3(slot="header") Rebooting + p(slot="body") Please wait... + div(slot="footer") diff --git a/src/pug/templates/axis-control.pug b/src/pug/templates/axis-control.pug new file mode 100644 index 0000000..37ec1f3 --- /dev/null +++ b/src/pug/templates/axis-control.pug @@ -0,0 +1,207 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#axis-control-template(type="text/x-template") + svg(xmlns="http://www.w3.org/2000/svg", + xmlns:xlink="http://www.w3.org/1999/xlink", + width="200", height="200") + defs + lineargradient#red + stop(offset="0", stop-color="#d26969") + stop(offset="1", stop-color="#ff7f7f") + + lineargradient#green + stop(offset="0", stop-color="#69d269") + stop(offset="1", stop-color="#7fff7f") + + lineargradient#blue + stop(offset="0", stop-color="#6969d2") + stop(offset="1", stop-color="#7f7fff") + + lineargradient#orange + stop(offset="0", stop-color="#d29d69") + stop(offset="1", stop-color="#ffbf7f") + + lineargradient#cyan + stop(offset="0", stop-color="#69d2d2") + stop(offset="1", stop-color="#7fffff") + + lineargradient#purple + stop(offset="0", stop-color="#d269d2") + stop(offset="1", stop-color="#ff7fff") + + + each color in 'red green blue orange cyan purple'.split(' ') + lineargradient(xlink:href="##{color}", id="#{color}-1", + gradientunits="userSpaceOnUse", gradienttransform="rotate(180 7 5)", + x1="0", y1="0", x2="15", y2="10") + + lineargradient(xlink:href="##{color}", id="#{color}-2", + gradientunits="userSpaceOnUse", x1="10", y1="10", x2="40", y2="40") + + + filter#shadow(x="-50%" y="-50%" width="200%" height="200%") + feOffset(in="SourceAlpha", dx="3", dy="3") + feComponentTransfer + feFuncR(type="discrete", tableValues="0.05") + feFuncG(type="discrete", tableValues="0.05") + feFuncB(type="discrete", tableValues="0.05") + feGaussianBlur(result="shadow", stdDeviation="5") + feBlend(in="SourceGraphic", in2="shadow", mode="normal") + + path#pie-1(d="M107,0 83,0 0,83 0,107A107,107 0 0 0 107,0Z") + path#pie-2(d="M83,0 59,0 0,59 0,83A83,83 0 0 0 83,0Z") + path#pie-3(d="M59,0 35,0 0,35 0,59A59,59 0 0 0 59,0Z") + path#pie-4(d="M35,0 0,0 0,35A35,35 0 0 0 35,0Z") + + path#arrow(d="M-16,9 0,9 0,17 17,0 0,-17 0,-9 -16,-9 -16,9Z") + + + g(transform="scale(0.8, 0.8)") + // 100% ring + g.ring(fill="#9f9f9f", filter="url(#shadow)") + use.button(xlink:href="#pie-1", v-if="enabled[0]", + transform="translate(134 121) rotate(-45)", + @mousedown="jog(0, 1)", @mouseup="release(0)") + + use.button(xlink:href="#pie-1", v-if="enabled[0]", + transform="translate(115 121) rotate(135)", + @mousedown="jog(0, -1)", @mouseup="release(0)") + + g.button(@mousedown="jog(1, 1)", @mouseup="release(1)", + v-if="enabled[1]") + use.button(xlink:href="#pie-1", + transform="translate(124 111) rotate(-135)") + text(x="125", y="24", transform="rotate(22 125 125)") + | {{adjust | fixed 0}}% + text(x="125", y="24", transform="rotate(-22 125 125)") + | {{adjust | fixed 0}}% + use.button(xlink:href="#pie-1", fill="transparent", + transform="translate(124 111) rotate(-135)") + + use.button(xlink:href="#pie-1", v-if="enabled[1]", + transform="translate(124 130) rotate(45)", @mousedown="jog(1, -1)", + @mouseup="release(1)") + + // 50% ring + g.ring(fill="#c5c5c5", filter="url(#shadow)") + use.button(xlink:href="#pie-2", v-if="enabled[0]", + transform="translate(134 121) rotate(-45)", + @mousedown="jog(0, 0.5)", @mouseup="release(0)") + + use.button(xlink:href="#pie-2", v-if="enabled[0]", + transform="translate(115 121) rotate(135)", + @mousedown="jog(0, -0.5)", @mouseup="release(0)") + + g.button(@mousedown="jog(1, 0.5)", @mouseup="release(1)", + v-if="enabled[1]") + use.button(xlink:href="#pie-2", + transform="translate(124 111) rotate(-135)") + text(x="125", y="48") {{0.5 * adjust | fixed 1}}% + use.button(xlink:href="#pie-2", fill="transparent", + transform="translate(124 111) rotate(-135)") + + use.button(xlink:href="#pie-2", v-if="enabled[1]", + transform="translate(124 130) rotate(45)", + @mousedown="jog(1, -0.5)", @mouseup="release(1)") + + + // 25% ring + g.ring(fill="#e2e2e2", filter="url(#shadow)") + use.button(xlink:href="#pie-3", v-if="enabled[0]", + transform="translate(134 121) rotate(-45)", + @mousedown="jog(0, 0.25)", @mouseup="release(0)") + + use.button(xlink:href="#pie-3", v-if="enabled[0]", + transform="translate(115 121) rotate(135)", + @mousedown="jog(0, -0.25)", @mouseup="release(0)") + + g.button(@mousedown="jog(1, 0.25)", @mouseup="release(1)", + v-if="enabled[1]") + use.button(xlink:href="#pie-3", + transform="translate(124 111) rotate(-135)") + text(x="125", y="73") {{0.25 * adjust | fixed 1}}% + use.button(xlink:href="#pie-3", fill="transparent", + transform="translate(124 111) rotate(-135)") + + use.button(xlink:href="#pie-3", v-if="enabled[1]", + transform="translate(124 130) rotate(45)", + @mousedown="jog(1, -0.25)", @mouseup="release(1)") + + + // 10% ring + g.ring(fill="#f7f7f7", filter="url(#shadow)") + use.button(xlink:href="#pie-4", v-if="enabled[0]", + transform="translate(134 121) rotate(-45)", + @mousedown="jog(0, 0.1)", @mouseup="release(0)") + + use.button(xlink:href="#pie-4", v-if="enabled[0]", + transform="translate(115 121) rotate(135)", + @mousedown="jog(0, -0.1)", @mouseup="release(0)") + + g.button(@mousedown="jog(1, 0.1)", @mouseup="release(1)", + v-if="enabled[1]") + use.button(xlink:href="#pie-4", + transform="translate(124 111) rotate(-135)") + text(x="125", y="95") {{0.1 * adjust | fixed 1}}% + use.button(xlink:href="#pie-4", fill="transparent", + transform="translate(124 111) rotate(-135)") + + use.button(xlink:href="#pie-4", v-if="enabled[1]", + transform="translate(124 130) rotate(45)", + @mousedown="jog(1, -0.1)", @mouseup="release(1)") + + + // +A + g.button.arrow(@mousedown="jog(0, 1)", @mouseup="release(0)", + transform="translate(230 120)", v-if="enabled[0]") + use(xlink:href="#arrow", fill="url(#{{colors[0]}}-1)") + text(x="-12", y="5", font-size="14", textLength="21") +{{axes[0]}} + + + // -A + g.button.arrow(@mousedown="jog(0, -1)", @mouseup="release(0)", + transform="translate(20 120)", v-if="enabled[0]") + use(xlink:href="#arrow", fill="url(#{{colors[0]}}-1)", + transform="rotate(180)") + text(x="-8", y="5", font-size="14", textLength="16") -{{axes[0]}} + + + // +B + g.button.arrow(@mousedown="jog(1, 1)", @mouseup="release(1)", + transform="translate(125, 18)", v-if="enabled[1]") + use(xlink:href="#arrow", fill="url(#{{colors[1]}}-1)", + transform="rotate(-90)") + text(x="-8", y="5", font-size="12", textLength="16") +{{axes[1]}} + + + // -B + g.button.arrow(@mousedown="jog(1, -1)", @mouseup="release(1)", + transform="translate(125, 225)", v-if="enabled[1]") + use(xlink:href="#arrow", fill="url(#{{colors[1]}}-1)", + transform="rotate(90)") + text(x="-7", y="5", font-size="12", textLength="14") -{{axes[1]}} diff --git a/src/pug/templates/cheat-sheet-view.pug b/src/pug/templates/cheat-sheet-view.pug new file mode 100644 index 0000000..41f422f --- /dev/null +++ b/src/pug/templates/cheat-sheet-view.pug @@ -0,0 +1,563 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#cheat-sheet-view-template(type="text/x-template") + // Modified from http://linuxcnc.org/docs/html/gcode.html + - var base = 'http://linuxcnc.org/docs/html/gcode'; + .cheat-sheet + h2 GCode Cheat Sheet + + table + tr + th Code + th Parameters + th Description + + tr.spacer-row: th + tr.header-row + th(colspan='3') Motion + tr + td + a(href="#{base}/g-code.html#gcode:g0") G0 + td + td Rapid Move + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g1") G1 + td + td Linear Move + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g2-g3") G2, G3 + td I J K or R, P + td Arc Move + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g4") G4 + td P + td Dwell + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g5") G5 + td I J P Q + td Cubic Spline + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g5.1") G5.1 + td I J + td Quadratic Spline + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g5.2-g5.3") G5.2 + td P L + td NURBS + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g38") G38.2 - G38.5 + td + td Straight Probe + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g33.1") G33.1 + td K + td Rigid Tapping + + tr.spacer-row: th + tr.header-row + th(colspan='3') Tool Control + tr + td + a(href="#{base}/other-code.html#sec:select-tool") T + td + td Select Tool + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m6") M6 + td T + td Tool Change + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m61") M61 + td Q + td Set Current Tool + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g10-l1") G10 L1 + td P Q R + td Set Tool Table + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g10-l10") G10 L10 + td P + td Set Tool Table + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g10-l11") G10 L11 + td P + td Set Tool Table + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g43") G43 + td H + td Tool Length Offset + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g43.1") G43.1 + td + td Dynamic Tool Length Offset + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g43.2") G43.2 + td H + td Apply additional Tool Length Offset + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g49") G49 + td + td Cancel Tool Length Compensation + + tr.spacer-row: th + tr.header-row + th(colspan='3') Feed Control + tr + td + a(href="#{base}/other-code.html#sec:set-feed-rate") F + td + td Set Feed Rate + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g93-g94-g95") + | G93, G94, G95 + td + td Feed Rate Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m52") M52 + td P0 (off) or P1 (on) + td Adaptive Feed Control + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m53") M53 + td P0 (off) or P1 (on) + td Feed Stop Control + + tr.spacer-row: th + tr.header-row + th(colspan='3') Spindle Control + tr + td + a(href="#{base}/other-code.html#sec:set-spindle-speed") S + td + td Set Spindle Speed + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m3-m4-m5") + | M3, M4, M5 + td S + td Spindle Control + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m19") M19 + td + td Orient Spindle + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g96-g97") G96, G97 + td S D + td Spindle Control Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g33") G33 + td K + td Spindle Synchronized Motion + + tr.spacer-row: th + tr.header-row + th(colspan='3') Coolant + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m7-m8-m9") + | M7, M8, M9 + td + td Coolant Control + + tr.spacer-row: th + tr.header-row + th(colspan='3') Stopping + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m0-m1") M0, M1 + td + td Program Pause + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m2-m30") M2, M30 + td + td Program End + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m60") M60 + td + td Pallet Change Pause + + tr.spacer-row: th + tr.header-row + th(colspan='3') Units + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g20-g21") G20, G21 + td + td Units (inch, mm) + + tr.spacer-row: th + tr.header-row + th(colspan='3') Distance Mode + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g90-g91") G90, G91 + td + td Distance Mode + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g90.1-g91.1") + | G90.1, G91.1 + td + td Arc Distance Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g7") G7 + td + td Lathe Diameter Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g8") G8 + td + td Lathe Radius Mode + + tr.spacer-row.unimplemented(v-if="showUnimplemented"): th + tr.header-row.unimplemented(v-if="showUnimplemented") + th(colspan='3') Cutter Radius Compensation + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g40") G40 + td + td Compensation Off + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g41-g42") G41,G42 + td D + td Cutter Compensation + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g41.1-g42.1") + | G41.1, G42.1 + td D L + td Dynamic Cutter Compensation + + tr.spacer-row.unimplemented(v-if="showUnimplemented"): th + tr.header-row.unimplemented(v-if="showUnimplemented") + th(colspan='3') Path Control Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g61-g61.1") + | G61 G61.1 + td + td Exact Path Mode + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g64") G64 + td P Q + td Path Blending + + tr.spacer-row.unimplemented(v-if="showUnimplemented"): th + tr.header-row.unimplemented(v-if="showUnimplemented") + th(colspan='3') Overrides + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m48-m49") M48, M49 + td + td Speed and Feed Override Control + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m50") M50 + td P0 (off) or P1 (on) + td Feed Override Control + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m51") M51 + td P0 (off) or P1 (on) + td Spindle Speed Override Control + + tr.spacer-row: th + tr.header-row + th(colspan='3') Coordinate Systems, Offsets & Planes + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g54-g59.3") + | G54-G59.3 + td + td Select Coordinate System + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g10-l2") G10 L2 + td P R + td Set Coordinate System + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g10-l20") G10 L20 + td P + td Set Coordinate System + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g53") G53 + td + td Move in Machine Coordinates + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g92") G92 + td + td Coordinate System Offset + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g92.1-g92.2") + | G92.1, G92.2 + td + td Reset G92 Offsets + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g92.3") G92.3 + td + td Restore G92 Offsets + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g28-g28.1") + | G28, G28.1 + td + td Go/Set Predefined Position + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g30-g30.1") + | G30, G30.1 + td + td Go/Set Predefined Position + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g17-g19.1") + | G17 - G19.1 + td (affects G2, G3, G81…G89, G40…G42) + td Plane Select + + tr.spacer-row: th + tr.header-row + th(colspan='3') Flow-control Codes + tr + td + a(target="_blank", href="#{base}/o-code.html#ocode:subroutines") + | o sub/endsub/call + td + td Subroutines, sub/endsub call + tr + td + a(target="_blank", href="#{base}/o-code.html#ocode:looping") o while + td + td Looping, while/endwhile do/while + tr + td + a(target="_blank", href="#{base}/o-code.html#ocode:conditional") o if + td + td Conditional, if/else/endif + tr + td + a(target="_blank", href="#{base}/o-code.html#ocode:repeat") o repeat + td + td Repeat a loop of code + tr + td + a(target="_blank", href="#{base}/o-code.html#ocode:indirection") [] + td + td Indirection + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/o-code.html#ocode:calling-files") + | o call + td + td Call named or numbered file + + tr.spacer-row: th + tr.header-row + th(colspan='3') Modal State + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m70") M70 + td + td Save modal state + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m71") M71 + td + td Invalidate stored state + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m72") M72 + td + td Restore modal state + tr + td + a(target="_blank", href="#{base}/m-code.html#mcode:m73") M73 + td + td Save and Auto-restore modal state + + tr.spacer-row.unimplemented(v-if="showUnimplemented"): th + tr.header-row.unimplemented(v-if="showUnimplemented") + th(colspan='3') Input/Output + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m62-m65") M62 - M65 + td P + td Digital Output Control + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m66") M66 + td P E L Q + td Wait on Input + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m67") M67 + td T + td Analog Output,Synchronized + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m68") M68 + td T + td Analog Output, Immediate + + tr.spacer-row.unimplemented(v-if="showUnimplemented"): th + tr.header-row.unimplemented(v-if="showUnimplemented") + th(colspan='3') User Defined Commands + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/m-code.html#mcode:m100-m199") + | M101 - M199 + td P Q + td User Defined Commands + + tr.spacer-row: th + tr.header-row + th(colspan='3') Canned cycles + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g80") G80 + td + td Cancel Canned Cycle + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g81") G81 + td R L (P) + td Drilling Cycle + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g82") G82 + td R L (P) + td Drilling Cycle, Dwell + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g83") G83 + td R L Q + td Drilling Cycle, Peck + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g73") G73 + td R L Q + td Drilling Cycle, Chip Breaking + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g85") G85 + td R L (P) + td Boring Cycle, Feed Out + tr + td + a(target="_blank", href="#{base}/g-code.html#gcode:g89") G89 + td R L (P) + td Boring Cycle, Dwell, Feed Out + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g76") G76 + td P Z I J R K Q H L E + td Threading Cycle + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/g-code.html#gcode:g98-g99") G98, G99 + td + td Canned Cycle Return Level + + tr.spacer-row: th + tr.header-row + th(colspan='3') Comments & Messages + tr + td + a(target="_blank", href="#{base}/overview.html#gcode:comments") ; (…) + td + td Comments + tr + td + a(target="_blank", href="#{base}/overview.html#gcode:messages") + | (MSG,…) + td + td Messages + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/overview.html#gcode:debug") (DEBUG,…) + td + td Debug Messages + tr.unimplemented(v-if="showUnimplemented") + td + a(target="_blank", href="#{base}/overview.html#gcode:print") (PRINT,…) + td + td Print Messages + + div + input(type="checkbox", v-model="showUnimplemented") + label Show unsupported codes + + h2 Further GCode Programming Documentation + + p + | The Buildbotics controller implements a subset of LinuxCNC GCode. + | Supported commands are listed above. You can find further help with + | GCode + | programming on the LinuxCNC website: + + ul + li: a(href="http://linuxcnc.org/docs/html/gcode/overview.html", + target="_blank") + | G Code overview + li: a(href="http://linuxcnc.org/docs/html/gcode/g-code.html", + target="_blank") + | G Code reference + li: a(href="http://linuxcnc.org/docs/html/gcode/m-code.html", + target="_blank") + | M Code reference diff --git a/src/pug/templates/console.pug b/src/pug/templates/console.pug new file mode 100644 index 0000000..bc8df6c --- /dev/null +++ b/src/pug/templates/console.pug @@ -0,0 +1,49 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#console-template(type="text/x-template") + .console + .toolbar + button.pure-button(title="Clear console.", @click="clear") + .fa.fa-trash + |  Clear + + .console-wrapper + table + tr + th Level + th Source + th Location + th Repeat + th Message + + tr(v-for="msg in messages", class="log-{{msg.level || 'info'}}") + td {{msg.level || 'info'}} + td {{msg.source || ''}} + td {{msg.where || ''}} + td {{msg.repeat}} + td.message {{msg.msg}} diff --git a/src/pug/templates/control-view.pug b/src/pug/templates/control-view.pug new file mode 100644 index 0000000..7b753bb --- /dev/null +++ b/src/pug/templates/control-view.pug @@ -0,0 +1,303 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#control-view-template(type="text/x-template") + #control + table.axes + tr(:class="{'homed': is_homed()}") + th.name Axis + th.position Position + th.absolute Absolute + th.offset Offset + th.actions + button.pure-button(:disabled="!is_ready", + title="Zero all axis offsets.", @click="zero()") ∅ + + button.pure-button(title="Home all axes.", @click="home()", + :disabled="!is_ready") + .fa.fa-home + + each axis in 'xyzabc' + tr.axis(:class="{'homed': is_homed('#{axis}'), 'axis-#{axis}': true}", + v-if="enabled('#{axis}')") + th.name #{axis} + td.position + unit-value(:value="get_position('#{axis}')", precision="4") + td.absolute: unit-value(:value="state.#{axis}p", precision="3") + td.offset: unit-value(:value="get_offset('#{axis}')", precision="3") + th.actions + button.pure-button(:disabled="!is_ready", + title="Set {{'#{axis}' | upper}} axis position.", + @click="show_set_position('#{axis}')") + .fa.fa-cog + + button.pure-button(:disabled="!is_ready", + title="Zero {{'#{axis}' | upper}} axis offset.", + @click="zero('#{axis}')") ∅ + + button.pure-button(:disabled="!is_ready", + title="Home {{'#{axis}' | upper}} axis.", + @click="home('#{axis}')") + .fa.fa-home + + message(:show.sync="position_msg['#{axis}']") + h3(slot="header") Set {{'#{axis}' | upper}} axis position + + div(slot="body") + .pure-form + .pure-control-group + label Position + input(v-model="axis_position", + @keyup.enter="set_position('#{axis}', axis_position)") + p + + div(slot="footer") + button.pure-button(@click="position_msg['#{axis}'] = false") + | Cancel + + button.pure-button(v-if="is_homed('#{axis}')", + @click="unhome('#{axis}')") Unhome + + button.pure-button.button-success( + @click="set_position('#{axis}', axis_position)") Set + + + message(:show.sync="manual_home['#{axis}']") + h3(slot="header") Manually home {{'#{axis}' | upper}} axis + + div(slot="body") + p Set axis absolute position. + + .pure-form + .pure-control-group + label Absolute + input(v-model="axis_position", + @keyup.enter="set_home('#{axis}', axis_position)") + + p + + div(slot="footer") + button.pure-button(@click="manual_home['#{axis}'] = false") + | Cancel + + button.pure-button.button-success( + title="Home {{'#{axis}' | upper}} axis.", + @click="set_home('#{axis}', axis_position)") Set + + table.info + tr + th State + td(:class="{attention: highlight_reason}") {{mach_state}} + tr + th Message + td.reason(:class="{attention: highlight_reason}") {{reason}} + tr(title="Currently active machine units") + th Units + td.mach_units + select(v-model="mach_units", :disabled="!can_mdi") + option(value="METRIC") METRIC + option(value="IMPERIAL") IMPERIAL + tr + th Tool + td {{state.tool || 0}} + + table.info + tr( + title="Current velocity in {{metric ? 'meters' : 'inches'}} per minute") + th Velocity + td + unit-value(:value="state.v", precision="2", unit="", iunit="", + scale="0.0254") + | {{metric ? ' m/min' : ' IPM'}} + tr + th Feed + td + unit-value(:value="state.feed", precision="2", unit="", iunit="") + | {{metric ? ' mm/min' : ' IPM'}} + tr + th Speed + td + | {{state.speed || 0 | fixed 0}} + span(v-if="!isNaN(state.s)")  ({{state.s | fixed 0}}) + = ' RPM' + tr + th Loads + td + span(:class="state['1oa'] ? 'load-on' : ''") + | 1:{{state['1oa'] ? 'On' : 'Off'}} + |   + span(:class="state['2oa'] ? 'load-on' : ''") + | 2:{{state['2oa'] ? 'On' : 'Off'}} + + table.info + tr + th Time + td(title="Total run time (days:hours:mins:secs)") + | {{toolpath.time / 1000 | time}} + tr + th ETA + td + tr + th Line + td + | {{0 <= state.line ? state.line : '0'}} + span(v-if="toolpath.lines") + |  of {{toolpath.lines | number}} + tr + th Progress + td.progress + label {{(state.progress || 0) | percent}} + .bar(:style="'width:' + (state.progress || 0.01) * 100 + '%'") + + .override(title="Feed rate override.") + label Feed + input(type="range", min="0", max="2", step="0.01", + v-model="feed_override", @change="override_feed") + span.percent {{feed_override | percent 0}} + + .override(title="Spindle speed override.") + label Speed + input(type="range", min="0", max="2", step="0.01", + v-model="speed_override", @change="override_speed") + span.percent {{speed_override | percent 0}} + + .tabs + input#tab1(type="radio", name="tabs" checked, @click="tab = 'auto'") + label(for="tab1", title="Run GCode programs") Auto + + input#tab2(type="radio", name="tabs", @click="tab = 'mdi'") + label(for="tab2", title="Manual GCode entry") MDI + + input#tab3(type="radio", name="tabs", @click="tab = 'jog'") + label(for="tab3", "Jog the axes manually") Jog + + input#tab4(type="radio", name="tabs", @click="tab = 'messages'") + label(for="tab4") Messages + + input#tab5(type="radio", name="tabs", @click="tab = 'indicators'") + label(for="tab5") Indicators + + section#content1.tab-content.pure-form + .toolbar.pure-control-group + button.pure-button( + title="{{is_running ? 'Pause' : 'Start'}} program.", + @click="start_pause", :disabled="!state.selected") + .fa(:class="is_running ? 'fa-pause' : 'fa-play'") + + button.pure-button(title="Stop program.", @click="stop") + .fa.fa-stop + + button.pure-button(title="Pause program at next optional stop (M1).", + @click="optional_pause", v-if="false") + .fa.fa-stop-circle-o + + button.pure-button(title="Execute one program step.", @click="step", + :disabled="(!is_ready && !is_holding) || !state.selected", + v-if="false") + .fa.fa-step-forward + + button.pure-button(title="Upload a new GCode program.", @click="open", + :disabled="is_running || is_stopping") + .fa.fa-folder-open + + input.gcode-file-input(type="file", @change="upload", + style="display:none", accept=".nc,.gcode,.gc,.ngc") + + button.pure-button(title="Delete current GCode program.", + @click="deleteGCode = true", + :disabled="!state.selected || is_running || is_stopping") + .fa.fa-trash + + message(:show.sync="deleteGCode") + h3(slot="header") Delete GCode? + p(slot="body") + div(slot="footer") + button.pure-button(@click="deleteGCode = false") Cancel + button.pure-button.button-error(@click="deleteAll") + .fa.fa-trash + |  all + button.pure-button.button-success(@click="deleteCurrent") + .fa.fa-trash + |  selected + + select(title="Select previously uploaded GCode programs.", + v-model="state.selected", @change="load", + :disabled="is_running || is_stopping") + option(v-for="file in files", :value="file") {{file}} + + path-viewer(:toolpath="toolpath", :progress="progress", + :x="get_position('x')", :y="get_position('y')", + :z="get_position('z')") + gcode-viewer + + section#content2.tab-content + .mdi.pure-form(title="Manual GCode entry.") + button.pure-button(:disabled="!can_mdi", + title="{{is_running ? 'Pause' : 'Start'}} command.", + @click="mdi_start_pause") + .fa(:class="is_running ? 'fa-pause' : 'fa-play'") + + button.pure-button(title="Stop command.", @click="stop") + .fa.fa-stop + + input(v-model="mdi", :disabled="!can_mdi", @keyup.enter="submit_mdi") + + .history(:class="{placeholder: !history}") + span(v-if="!history.length") MDI history displays here. + ul + li(v-for="item in history", @click="load_history($index)", + track-by="$index") + | {{item}} + + section#content3.tab-content + .jog + axis-control(axes="XY", :colors="['red', 'green']", + :enabled="[enabled('x'), enabled('y')]", + v-if="enabled('x') || enabled('y')", :adjust="jog_adjust") + + axis-control(axes="AZ", :colors="['orange', 'blue']", + :enabled="[enabled('a'), enabled('z')]", + v-if="enabled('a') || enabled('z')", :adjust="jog_adjust") + + axis-control(axes="BC", :colors="['cyan', 'purple']", + :enabled="[enabled('b'), enabled('c')]", + v-if="enabled('b') || enabled('c')", :adjust="jog_adjust") + + .jog-adjust + | Fine adjust + input(type="range", v-model="jog_adjust", min=1, max=100, step=1) + + center + | Left click the axes above holding down the mouse button to jog the + | machine. + center Jogging speed is set by the ring that is clicked. + + section#content4.tab-content + console + + section#content5.tab-content + indicators(:state="state") diff --git a/src/pug/templates/estop.pug b/src/pug/templates/estop.pug new file mode 100644 index 0000000..472c72c --- /dev/null +++ b/src/pug/templates/estop.pug @@ -0,0 +1,121 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#estop-template(type="text/x-template") + svg(version="1.1", xmlns:svg="http://www.w3.org/2000/svg", + xmlns="http://www.w3.org/2000/svg", + xmlns:xlink="http://www.w3.org/1999/xlink", + width="130", height="130") + defs + path#text-path-1(style="fill:none;stroke:none", d="m 73.735867,673.1299 c 0,55.10749 44.673453,99.78094 99.780973,99.78094 55.10748,0 99.78093,-44.67345 99.78093,-99.78094 0,-55.10749 -44.67345,-99.78094 -99.78093,-99.78094 -55.10752,0 -99.780973,44.67345 -99.780973,99.78094 z") + + path#text-path-2(style="fill:none;stroke:none", d="m 258.7149,673.1299 c 0,47.0536 -38.14448,85.19809 -85.19809,85.19809 -47.0536,0 -85.198083,-38.14449 -85.198083,-85.19809 0,-47.05361 38.144483,-85.19809 85.198083,-85.19809 47.05361,0 85.19809,38.14448 85.19809,85.19809 z") + + filter#filter5134(style="color-interpolation-filters:sRGB") + feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)") + fecomposite(in2="SourceGraphic", operator="in") + fegaussianblur(stddeviation="4", result="blur") + feoffset(dx="4", dy="4", result="offset") + fecomposite(in="SourceGraphic", in2="offset", operator="over", + result="fbSourceGraphic") + fecolormatrix(result="fbSourceGraphicAlpha", in="fbSourceGraphic", + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0") + feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)", + in="fbSourceGraphic") + fecomposite(in2="fbSourceGraphic", operator="out") + fegaussianblur(stddeviation="4", result="blur") + feoffset(dx="-4", dy="-4", result="offset") + fecomposite(in2="fbSourceGraphic", in="offset", operator="atop", + result="fbSourceGraphic") + fecolormatrix(result="fbSourceGraphicAlpha", in="fbSourceGraphic", + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0") + feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)", + in="fbSourceGraphic") + fecomposite(in2="fbSourceGraphic", operator="in") + fegaussianblur(stddeviation="4", result="blur") + feoffset(dx="4", dy="4", result="offset") + fecomposite(in2="offset", in="fbSourceGraphic", operator="over") + + filter#filter5158(style="color-interpolation-filters:sRGB",) + feflood(flood-opacity="0.431373", flood-color="rgb(0,0,0)") + fecomposite(in2="SourceGraphic", operator="out") + fegaussianblur(stddeviation="7", result="blur") + feoffset(dx="4", dy="4") + fecomposite(in2="SourceGraphic", operator="atop") + + filter#filter5266(style="color-interpolation-filters:sRGB") + feflood(flood-opacity="0.372549", flood-color="rgb(0,0,0)") + fecomposite(in2="SourceGraphic", operator="in") + fegaussianblur(stddeviation="2", result="blur") + feoffset(dx="1", dy="1", result="offset") + fecomposite(in="SourceGraphic", in2="offset", operator="over") + + filter#filter5278(style="color-interpolation-filters:sRGB") + feflood(flood-opacity="0.372549", flood-color="rgb(0,0,0)") + fecomposite(in2="SourceGraphic", operator="out") + fegaussianblur(stddeviation="2", result="blur") + feoffset(dx="2", dy="2", result="offset") + fecomposite(in="offset", in2="SourceGraphic", operator="atop") + + + g(transform="scale(0.6, 0.6),translate(-65, -526)") + // Yellow ring + circle.ring(style="fill:#f5e138;filter:url(#filter5266)", + cx="173", cy="633", r="100") + + // Text + text(style="font-weight:bold;font-size:20px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none", + transform="matrix(-0.73361478,-0.67956556,0.67956556,-0.73361478,-156.72624,1250.7027)", + x="-1350.5394", y="-1579.3965") + textpath(xlink:href="#text-path-2") EMERGENCY + + text(style="font-weight:bold;font-size:20px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none", + transform="matrix(0.27634044,-0.96105981,0.96105981,0.27634044,-523.81801,609.02637)", + x="-754.20117", y="157.03941") + textpath(xlink:href="#text-path-1") STOP + + g.button + circle(style="fill:#b72424;filter:url(#filter5134)", + cx="173", cy="633", r="74") + + // Inner circle + circle(style="fill:#b72424;filter:url(#filter5158)", + cx="173", cy="633", r="37") + + // Arrows + g(transform="matrix(0.32737901,0,0,0.32737901,50.806169,478.96619)", style="stroke:#fff;stroke-width:26;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;filter:url(#filter5278);fill:none") + g + path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -12.91355,-13.50409 -17.38625,-24.07872") + path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") + + g(transform="matrix(-0.5,-0.8660254,0.8660254,-0.5,149.81163,1033.4478)") + path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -11.52544,-14.20559 -17.38625,-24.07872") + path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") + + g(transform="matrix(-0.5,0.8660254,-0.8660254,-0.5,971.43059,383.18517)") + path(transform="matrix(1.9461546,0,0,1.9461546,-359.98722,-383.37383)", style="stroke-width:13", d="m 411.6967,521.14701 c -10.57464,4.47269 -22.20085,6.94599 -34.40474,6.94599 -12.20389,0 -23.8301,-2.4733 -34.40474,-6.94599 -10.57463,-4.4727 -20.09769,-10.94478 -28.09526,-18.94236 -7.99757,-7.99757 -9.56206,-8.6246 -14.03476,-19.19923") + path(d="m 221.80189,582.65761 -2.99162,-35.52447 28.48213,14.16667 z") diff --git a/src/pug/templates/gcode-viewer.pug b/src/pug/templates/gcode-viewer.pug new file mode 100644 index 0000000..c79197a --- /dev/null +++ b/src/pug/templates/gcode-viewer.pug @@ -0,0 +1,33 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#gcode-viewer-template(type="text/x-template") + .gcode + .clusterize + .clusterize-scroll + ul.clusterize-content + li.clusterize-no-data.placeholder GCode displays here. diff --git a/src/pug/templates/help-view.pug b/src/pug/templates/help-view.pug new file mode 100644 index 0000000..1c0187b --- /dev/null +++ b/src/pug/templates/help-view.pug @@ -0,0 +1,61 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#help-view-template(type="text/x-template") + #help + h2 User Manual + p + | You can find a detailed user manual at docs.buildbotics.com. + + h2 Discussion Forum + p + | If you're having trouble or just want to chat with other Buildbotics + | CNC controller owners, head over to the Buildbotics forum at + | forum.buildbotics.com. Register on the site and post a message. + | We'll be happy to help. + + h2 CAD/CAM Software + p + | CAM software can be used to create GCode + | automatically from + | CAD models. Here are a few CAD/CAM resources: + ul + li: a(href="http://camotics.org/", target="_blank") + | CAMotics - Open-Source CNC Simulator + li: a(href="http://librecad.org/", target="_blank") + | LibreCAD - Open-Source 2D CAD + li: a(href="https://www.freecadweb.org/", target="_blank") + | FreeCAD - Open-Source 3D CAD + li: a(href="http://www.openscad.org/", target="_blank") + | OpenSCAD - Open-Source 3D CAD for programmers + li: a(href="http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Cam", + target="_blank") LinuxCNC CAM resources diff --git a/src/pug/templates/indicators.pug b/src/pug/templates/indicators.pug new file mode 100644 index 0000000..f9650c4 --- /dev/null +++ b/src/pug/templates/indicators.pug @@ -0,0 +1,245 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#indicators-template(type="text/x-template") + .indicators + table.legend + tr + th.header(colspan=100) Legend + + tr + td + .fa.fa-plus-circle.io + th Hi/+3.3v + th.separator + td + .fa.fa-minus-circle.io + th Lo/Gnd + th.separator + td + .fa.fa-circle.io.active + th Active + th.separator + td + .fa.fa-circle.io.inactive + th Inactive + th.separator + td + .fa.fa-circle-o.io + th Tristated/Disabled + + table.inputs + tr + th.header(colspan=7) Inputs + + tr + th State + th Pin + th Name + th.separator + th State + th Pin + th Name + + each motor in '0123' + tr + td + .fa.io(:class="get_input_class('#{motor}lw', '#{motor}ls')", + :title="get_input_tooltip('#{motor}lw', '#{motor}ls')") + td {{get_min_pin(#{motor})}} + th Motor #{motor} Min + th.separator + td + .fa.io(:class="get_input_class('#{motor}xw', '#{motor}xs')", + :title="get_input_tooltip('#{motor}xw', '#{motor}xs')") + td {{get_max_pin(#{motor})}} + th Motor #{motor} Max + + tr + td + .fa.io(:class="get_input_class('ew', 'et')", + :title="get_input_tooltip('ew', 'et')") + td 23 + th EStop + th.separator + td + .fa.io(:class="get_input_class('pw', 'pt')", + :title="get_input_tooltip('pw', 'pt')") + td 22 + th Probe + + table.outputs + tr + th.header(colspan=7) Outputs + + tr + th State + th Pin + th Name + th.separator + th State + th Pin + th Name + + tr + td + .fa.io(:class="get_output_class('e')", + :title="get_output_tooltip('e')") + td 15 + th Tool Enable + th.separator + td + .fa.io(:class="get_output_class('1')", + :title="get_output_tooltip('1')") + td 2 + th Load 1 + + tr + td + .fa.io(:class="get_output_class('d')", + :title="get_output_tooltip('d')") + td 16 + th Tool Direction + th.separator + td + .fa.io(:class="get_output_class('2')", + :title="get_output_tooltip('2')") + td 1 + th Load 2 + + tr + td {{state.pd | percent 0}} + td 17 + th Tool PWM + th.separator + td + .fa.io(:class="get_output_class('f')", + :title="get_output_tooltip('f')") + td 21 + th Fault + + table.pwr_fault + tr + th.header(colspan=5) + | Power Faults + span(v-if="state.pwr_version")  (Version {{state.pwr_version}}) + tr + th(:class="{error: state.under_voltage}") Under voltage + td(:class="{error: state.under_voltage}") + | {{state.under_voltage ? 'True' : 'False'}} + th.separator + th(:class="{error: state.over_voltage}") Over voltage + td(:class="{error: state.over_voltage}") + | {{state.over_voltage ? 'True' : 'False'}} + tr + th(:class="{error: state.over_current}") Over current + td(:class="{error: state.over_current}") + | {{state.over_current ? 'True' : 'False'}} + th.separator + th(:class="{error: state.sense_error}", :title="sense_error") + | Sense error + td(:class="{error: state.sense_error}") + | {{state.sense_error ? 'True' : 'False'}} + tr + th(:class="{error: state.shunt_overload}") Shunt overload + td(:class="{error: state.shunt_overload}") + | {{state.shunt_overload ? 'True' : 'False'}} + th.separator + th(:class="{error: state.motor_overload}") Motor overload + td(:class="{error: state.motor_overload}") + | {{state.motor_overload ? 'True' : 'False'}} + tr + th(:class="{error: state.load1_shutdown}") Load 1 shutdown + td(:class="{error: state.load1_shutdown}") + | {{state.load1_shutdown ? 'True' : 'False'}} + th.separator + th(:class="{error: state.load2_shutdown}") Load 2 shutdown + td(:class="{error: state.load2_shutdown}") + | {{state.load2_shutdown ? 'True' : 'False'}} + tr + th(:class="{error: state.motor_under_voltage}") Motor under volt + td(:class="{error: state.motor_under_voltage}") + | {{state.motor_under_voltage ? 'True' : 'False'}} + th.separator + th + td + + table.measurements + tr + th.header(colspan=5) Measurements + + tr + td {{state.vin | fixed 1}} V + th Input + th.separator + td {{state.vout | fixed 1}} V + th Output + + tr + td {{state.motor | fixed 2}} A + th Motor + th.separator + td {{state.temp | fixed 0}} ℃ + th Temp + + tr + td {{state.load1 | fixed 2}} A + th Load 1 + th.separator + td {{state.load2 | fixed 2}} A + th Load 2 + + tr + td {{state['1ai'] | percent 0}} A + th Analog 1 + th.separator + td {{state['2ai'] | percent 0}} A + th Analog 2 + + table.modbus + tr + th.header(colspan=5) Modbus VFD + + tr + td {{modbus_status}} + th Status + th.separator + td {{state.hz}} Hz + th Frequency + + tr + td {{state.s}} RPM + th Speed + th.separator + td {{state.hc}} A + th Current + + h2 DB25 breakout box + img(width=700, src="/images/DB25_breakout_box.png") + + h2 DB25-M2 breakout + img(width=400, src="/images/DB25-M2_breakout.png") diff --git a/src/pug/templates/io-view.pug b/src/pug/templates/io-view.pug new file mode 100644 index 0000000..f0c81a3 --- /dev/null +++ b/src/pug/templates/io-view.pug @@ -0,0 +1,41 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#io-view-template(type="text/x-template") + #io + h1 I/O Configuration + + .pure-form.pure-form-aligned + fieldset + h2 Switches + templated-input(v-for="templ in template.switches", :name="$key", + :model.sync="config.switches[$key]", :template="templ") + + fieldset + h2 Outputs + templated-input(v-for="templ in template.outputs", :name="$key", + :model.sync="config.outputs[$key]", :template="templ") diff --git a/src/pug/templates/message.pug b/src/pug/templates/message.pug new file mode 100644 index 0000000..dcaf93c --- /dev/null +++ b/src/pug/templates/message.pug @@ -0,0 +1,40 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#message-template(type="text/x-template") + .modal-mask(v-show="show", transition="modal") + .modal-wrapper + .modal-container + .modal-header + slot(name="header") default header + + .modal-body + slot(name="body") default body + + .modal-footer + slot(name="footer") + button.pure-button.button-success(@click="show = false") OK diff --git a/src/pug/templates/modbus-reg-view.pug b/src/pug/templates/modbus-reg-view.pug new file mode 100644 index 0000000..ac86cfd --- /dev/null +++ b/src/pug/templates/modbus-reg-view.pug @@ -0,0 +1,45 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#modbus-reg-view-template(type="text/x-template") + tr.modbus-reg + td.reg-index {{index}} + td.reg-type + select(v-model="model['reg-type']", @change="change") + option(v-for="opt in template['reg-type']['values']", :value="opt") + | {{opt}} + + td.reg-addr + input(v-model="model['reg-addr']", @change="change", type="text", + :min="template['reg-addr'].min", :max="template['reg-addr'].max", + pattern="[0-9]*", :disabled="model['reg-type'] == 'disabled'", + number) + + td.reg-value + input(v-model="model['reg-value']", @change="change", type="text", + :min="template['reg-value'].min", :max="template['reg-value'].max", + pattern="[0-9]*", :disabled="!has_user_value", number) diff --git a/src/pug/templates/motor-view.pug b/src/pug/templates/motor-view.pug new file mode 100644 index 0000000..17c52a7 --- /dev/null +++ b/src/pug/templates/motor-view.pug @@ -0,0 +1,61 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#motor-view-template(type="text/x-template") + .motor(:class="{slave: is_slave}") + h1 Motor {{index}} Configuration + + .pure-form.pure-form-aligned + fieldset(v-for="category in template.motors.template", :class="$key") + h2 {{$key}} + + templated-input(v-for="templ in category", :name="$key", + :model.sync="motor[$key]", :template="templ") + + label.extra(v-if="$key == 'microsteps'", slot="extra", + :class="{error: invalidMaxVelocity}", + title="Microsteps per second") + | ({{ustepPerSec / 1000 | fixed 1}}k µstep/sec) + + label.extra(v-if="$key == 'max-velocity'", slot="extra", + title="Revolutions Per Minute") ({{rpm | fixed 0}} RPM) + + label.extra(v-if="$key == 'max-accel' && metric", slot="extra", + title="G-force") ({{gForce | fixed 3}} g) + + label.extra(v-if="$key == 'max-jerk' && metric", slot="extra", + title="G-force per minute") ({{gForcePerMin | fixed 2}} g/min) + + label.extra(v-if="$key == 'step-angle'", slot="extra", + title="Steps per revolution") ({{stepsPerRev | fixed 0}} steps/rev) + + label.extra(v-if="$key == 'travel-per-rev' && metric", slot="extra", + title="Micrometers per step") ({{umPerStep | fixed 1}} µm/step) + + label.extra(v-if="$key == 'travel-per-rev' && !metric", slot="extra", + title="Thousandths of an inch per step") + | ({{milPerStep | fixed 2}} mil/step) diff --git a/src/pug/templates/path-viewer.pug b/src/pug/templates/path-viewer.pug new file mode 100644 index 0000000..044ac6b --- /dev/null +++ b/src/pug/templates/path-viewer.pug @@ -0,0 +1,70 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#path-viewer-template(type="text/x-template") + .path-viewer + .path-viewer-toolbar + .tool-button(title="Toggle path view size.", + @click="small = !small", :class="{active: !small}") + .fa.fa-arrows-alt + + tool-button(name="tool", :active="showTool", + @click="showTool = !showTool", title="Show/hide tool.") + tool-button(name="bbox", :active="showBBox", + @click="showBBox = !showBBox", title="Show/hide bounding box.") + tool-button(name="axes", :active="showAxes", + @click="showAxes = !showAxes", title="Show/hide axes.") + + tool-button(name="isometric", @click="snap('isometric')", + title="Snap to isometric view.") + tool-button(name="top", @click="snap('top')", + title="Snap to top view.") + tool-button(name="front", @click="snap('front')", + title="Snap to front view.") + + .path-viewer-content(:class="{small: small}") + .path-viewer-message(:class="{error: error}") + template(v-if="loading") + div(v-if="progress && progress < 1") + | Simulating run {{progress | non_zero_percent 0}}. . . + div(v-if="!progress || progress == 1") Loading. . . + | {{message}} + + table.path-viewer-messages( + v-if="typeof toolpath.messages != 'undefined' && " + + "toolpath.messages.length") + tr + th Level + th Location + th Message + + tr(v-for="msg in toolpath.messages", :class="'log-' + msg.level") + td {{msg.level}} + td + | {{msg.line}} + span(v-if="msg.column") :{{msg.column}} + td {{msg.msg}} diff --git a/src/pug/templates/settings-view.pug b/src/pug/templates/settings-view.pug new file mode 100644 index 0000000..cd3444b --- /dev/null +++ b/src/pug/templates/settings-view.pug @@ -0,0 +1,41 @@ +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#settings-view-template(type="text/x-template") + #settings + h1 Settings + + .pure-form.pure-form-aligned + fieldset + h2 Units + templated-input(name="units", :model.sync="config.settings.units", + :template="template.settings.units") + + p + | Note, units sets both the machine default units and the + | units used in motor configuration. GCode program-start, + | set below, may also change the default machine units. + + fieldset + h2 GCode + templated-input(v-for="templ in template.gcode", :name="$key", + :model.sync="config.gcode[$key]", :template="templ") diff --git a/src/pug/templates/templated-input.pug b/src/pug/templates/templated-input.pug new file mode 100644 index 0000000..0e456ac --- /dev/null +++ b/src/pug/templates/templated-input.pug @@ -0,0 +1,61 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#templated-input-template(type="text/x-template") + .pure-control-group(class="tmpl-input-{{name}}", + title="Default {{template.default}} {{template.unit || ''}}") + label(:for="name") {{name}} + + select(v-if="template.type == 'enum' || template.values", v-model="view", + :name="name", @change="change") + option(v-for="opt in template.values", :value="opt") {{opt}} + + input(v-if="template.type == 'bool'", type="checkbox", v-model="view", + :name="name", @change="change") + + input(v-if="template.type == 'float'", v-model="view", number, + :min="template.min", :max="template.max", :step="template.step || 'any'", + type="number", :name="name", @change="change") + + input(v-if="template.type == 'int' && !template.values", v-model="view", + number, :min="template.min", :max="template.max", type="number", + :name="name", @change="change") + + input(v-if="template.type == 'string'", v-model="view", type="text", + :name="name", @change="change") + + textarea(v-if="template.type == 'text'", v-model="view", :name="name", + @change="change") + + span.range(v-if="template.type == 'percent'") + input(type="range", v-model="view", :name="name", number, min="0", + max="100", step="1", @change="change") + | {{view}} + + label.units {{units}} + + slot(name="extra") diff --git a/src/pug/templates/tool-button.pug b/src/pug/templates/tool-button.pug new file mode 100644 index 0000000..8306fba --- /dev/null +++ b/src/pug/templates/tool-button.pug @@ -0,0 +1,28 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- Copyright (c) 2018, Cauldron Development LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#tool-button-template(type="text/x-template") + .tool-button(:class="{'active': active}") + img(:src="'images/' + name + '.png'") diff --git a/src/pug/templates/tool-view.pug b/src/pug/templates/tool-view.pug new file mode 100644 index 0000000..e889502 --- /dev/null +++ b/src/pug/templates/tool-view.pug @@ -0,0 +1,184 @@ +//-///////////////////////////////////////////////////////////////////////////// +//- // +//- This file is part of the Buildbotics firmware. // +//- // +//- Copyright (c) 2015 - 2018, Buildbotics LLC // +//- All rights reserved. // +//- // +//- This file ("the software") is free software: you can redistribute it // +//- and/or modify it under the terms of the GNU General Public License, // +//- version 2 as published by the Free Software Foundation. You should // +//- have received a copy of the GNU General Public License, version 2 // +//- along with the software. If not, see . // +//- // +//- The software is distributed in the hope that it will be useful, but // +//- WITHOUT ANY WARRANTY; without even the implied warranty of // +//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // +//- Lesser General Public License for more details. // +//- // +//- You should have received a copy of the GNU Lesser General Public // +//- License along with the software. If not, see // +//- . // +//- // +//- For information regarding this software email: // +//- "Joseph Coffland" // +//- // +//-///////////////////////////////////////////////////////////////////////////// + +script#tool-view-template(type="text/x-template") + #tool + h1 Tool Configuration + + .pure-form.pure-form-aligned + fieldset + templated-input(v-for="templ in template.tool", :name="$key", + :model.sync="config.tool[$key]", :template="templ", + v-if="tool_type != 'DISABLED' || $key == 'tool-type'") + + fieldset(v-if="tool_type == 'PWM SPINDLE'") + h2 PWM Spindle + templated-input(v-for="templ in template['pwm-spindle']", + :name="$key", :model.sync="config['pwm-spindle'][$key]", + :template="templ") + + fieldset(v-if="is_modbus") + h2 Modbus Configuration + .pure-control-group + label status + tt {{modbus_status}} + templated-input(v-for="templ in template['modbus-spindle']", + :name="$key", :model.sync="config['modbus-spindle'][$key]", + :template="templ", v-if="$key != 'regs'") + + fieldset.modbus-program( + v-if="is_modbus && this.tool_type != 'HUANYANG VFD'") + h2 Active Modbus Program + p + | (Click Save to activate the selected + | tool-type.) + table.modbus-regs.fixed-regs + tr + th Index + th Command + th Address + th Value + th Failures + + tr(v-for="(index, reg) in regs_tmpl.index", v-if="state[reg + 'vt']", + :class="{warn: get_reg_fails(reg)}") + td.reg-index {{index}} + td.reg-type {{get_reg_type(reg)}} + td.reg-addr {{get_reg_addr(reg)}} + td.reg-value {{get_reg_value(reg)}} + td.reg-fails {{get_reg_fails(reg)}} + + button.pure-button-secondary(@click="customize") Customize + button.pure-button-secondary(@click="clear", + v-if="tool_type == 'CUSTOM MODBUS VFD'") Clear + button.pure-button-secondary(@click="reset_failures") Reset Failures + + fieldset(v-if="tool_type == 'CUSTOM MODBUS VFD'") + h2 Edit Modbus Program + table.modbus-regs + tr + th Index + th Command + th Address + th Value + + tr(v-for="(index, reg) in config['modbus-spindle'].regs", + is="modbus-reg", :index="index", :model.sync="reg", + :template="template['modbus-spindle'].regs.template", + v-if="!index || reg['reg-type'] != 'disabled' || " + + "config['modbus-spindle'].regs[index - 1]['reg-type'] != " + + "'disabled'") + + .notes(v-if="tool_type == 'HUANYANG VFD'") + h2 Notes + p Set the following using the VFD's frontpanel. + table.modbus-regs.fixed-regs + tr + th Address + th Value + td Meaning + th Description + tr + td.reg-addr PD000 + td.reg-value 0 + td Unlock + td Unlock parameters + tr + td.reg-addr PD001 + td.reg-value 2 + td RS485 + td Command source + tr + td.reg-addr PD002 + td.reg-value 2 + td RS485 + td Speed/frequency source + tr + td.reg-addr PD163 + td.reg-value 1 + td Modbus ID + td Must match bus-id above. + tr + td.reg-addr PD164 + td.reg-value 1 + td 9600 baud + td Must match baud above. + tr + td.reg-addr PD166 + td.reg-value 3 + td 8 bit, no parity, RTU mode + td Must match parity above. + + p + | Other settings according to the Huanyang VFD manual and spindle type. + + .notes(v-if="tool_type.startsWith('DELTA VFD015M21A')") + h2 Notes + p Set the following using the VFD's frontpanel. + table.modbus-regs.fixed-regs + tr + th Address + th Value + th Meaning + th Description + tr + td.reg-addr Pr.00 + td.reg-value 3 + td RS-485 + td Source of frequency command + tr + td.reg-addr Pr.01 + td.reg-value 3 + td RS-485 with STOP + td Source of operation command + tr + td.reg-addr Pr.88 + td.reg-value 1 + td Modbus ID + td Must match bus-id above + tr + td.reg-addr Pr.89 + td.reg-value 1 + td 9600 baud + td Must match baud above + tr + td.reg-addr Pr.92 + td.reg-value 3 + td 8 bit, no parity, RTU mode + td Must match parity above + tr + td.reg-addr Pr.157 + td.reg-value 1 + td Modbus mode + td Communication mode + + p + | Other settings according to the Delta VFD015M21A VFD manual and spindle type. diff --git a/src/py/bbctrl/APIHandler.py b/src/py/bbctrl/APIHandler.py index de25a0c..64af779 100644 --- a/src/py/bbctrl/APIHandler.py +++ b/src/py/bbctrl/APIHandler.py @@ -34,6 +34,7 @@ import tornado.httpclient log = logging.getLogger('API') +log.setLevel(logging.DEBUG) class APIHandler(RequestHandler): @@ -44,6 +45,9 @@ class APIHandler(RequestHandler): # Override exception logging def log_exception(self, typ, value, tb): + if isinstance(value, HTTPError) and value.status_code == 408: + return + log.error(str(value)) trace = ''.join(traceback.format_exception(typ, value, tb)) log.debug(trace) @@ -94,5 +98,5 @@ class APIHandler(RequestHandler): def write_json(self, data, pretty = False): if pretty: data = json.dumps(data, indent = 2, separators = (',', ': ')) - else: data = json.dumps(data) + else: data = json.dumps(data, separators = (',', ':')) self.write(data) diff --git a/src/py/bbctrl/Camera.py b/src/py/bbctrl/Camera.py index 8667721..2f8ff54 100755 --- a/src/py/bbctrl/Camera.py +++ b/src/py/bbctrl/Camera.py @@ -35,7 +35,7 @@ import mmap import pyudev import base64 import socket -from tornado import gen, web +from tornado import gen, web, iostream try: import v4l2 @@ -214,8 +214,6 @@ fbNqIGgc9ldbOcdoit0COH30pqj7OYQijJxjE6Ct9PvDV4rJmYu9+dhTZFYDhd9bTFCzBEIC5db02KUC qhJEhSpcEm7f+h7/AP/Z ''' -offline_jpg = base64.b64decode(offline_jpg) - def array_to_string(a): return ''.join([chr(i) for i in a]) @@ -359,11 +357,10 @@ class VideoDevice(object): def read_frame(self): buf = self._dqbuf() - mm = self.buffers[buf.index] + frame = mm.read() mm.seek(0) - self._qbuf(buf) return frame @@ -440,6 +437,7 @@ class Camera(object): self.fps = ctrl.args.fps self.fourcc = string_to_fourcc(ctrl.args.fourcc) + self.offline_jpg = self._format_frame(base64.b64decode(offline_jpg)) self.dev = None self.clients = [] self.path = None @@ -470,21 +468,41 @@ class Camera(object): if action == 'remove' and path == self.path: self.close() - def _handler(self, fd, events): + def _format_frame(self, frame): + frame = [ + b'Content-type: image/jpeg\r\n', + b'Content-length: ', str(len(frame)).encode('utf8'), b'\r\n\r\n', + frame, VideoHandler.boundary.encode('utf8'), b'\n'] + + return b''.join(frame) + + + def _send_frame(self, frame): + frame = self._format_frame(frame) + + for client in self.clients: + try: + client.write_frame(frame) + except Exception as e: + log.warning('Failed to write frame to client: %s' % e) + + + def _fd_handler(self, fd, events): try: - frame = None - if len(self.clients): frame = self.dev.read_frame() + if len(self.clients): + frame = self.dev.read_frame() + self._send_frame(frame) + else: self.dev.flush_frame() - except: + except Exception as e: + if isinstance(e, BlockingIOError): return + log.warning('Failed to read from camera.') self.ctrl.ioloop.remove_handler(fd) self.close() return - if frame is not None: - for client in self.clients: - client.write_frame(frame) def open(self, path): @@ -505,10 +523,10 @@ class Camera(object): self.dev.set_format(self.width, self.height, fourcc = self.fourcc) self.dev.set_fps(self.fps) - self.dev.create_buffers(30) + self.dev.create_buffers(4) self.dev.start() - self.ctrl.ioloop.add_handler(self.dev, self._handler, + self.ctrl.ioloop.add_handler(self.dev, self._fd_handler, self.ctrl.ioloop.READ) log.info('Opened camera ' + path) @@ -531,8 +549,8 @@ class Camera(object): self.dev.close() for client in self.clients: - client.write_frame(offline_jpg) - client.write_frame(offline_jpg) + client.write_frame(self.offline_jpg) + client.write_frame(self.offline_jpg) log.info('Closed camera %s' % self.path) @@ -543,9 +561,10 @@ class Camera(object): def add_client(self, client): log.info('Adding camera client: %d' % len(self.clients)) self.clients.append(client) + if self.dev is None: - client.write_frame(offline_jpg) - client.write_frame(offline_jpg) + client.write_frame(self.offline_jpg) + client.write_frame(self.offline_jpg) def remove_client(self, client): @@ -557,20 +576,23 @@ class Camera(object): class VideoHandler(web.RequestHandler): + boundary = '---boundary---' + + def __init__(self, app, request, **kwargs): super().__init__(app, request, **kwargs) self.camera = app.ctrl.camera - self.boundary = '---boundary---' @web.asynchronous def get(self): + self.request.connection.stream.max_write_buffer_size = 10000 + self.set_header('Cache-Control', 'no-store, no-cache, ' + 'must-revalidate, pre-check=0, post-check=0, ' + 'max-age=0') self.set_header('Connection', 'close') - self.set_header('Content-Type', - 'multipart/x-mixed-replace;boundary=' + + self.set_header('Content-Type', 'multipart/x-mixed-replace;boundary=' + self.boundary) self.set_header('Expires', 'Mon, 3 Jan 2000 12:34:56 GMT') self.set_header('Pragma', 'no-cache') @@ -579,14 +601,17 @@ class VideoHandler(web.RequestHandler): def write_frame(self, frame): - # Drop frame if client is slow - if self.request.connection.stream.writing(): return - - self.write("Content-type: image/jpeg\r\n") - self.write("Content-length: %s\r\n\r\n" % len(frame)) - self.write(frame) - self.write(self.boundary + '\n') - self.flush() + # Don't allow too many frames to queue up + size = len(frame) + if self.request.connection.stream.max_write_buffer_size < size: + self.request.connection.stream.max_write_buffer_size = size * 2 + + try: + self.write(frame) + self.flush() + + except iostream.StreamBufferFullError: + pass # Drop frame if buffer is full def on_connection_close(self): diff --git a/src/py/bbctrl/Comm.py b/src/py/bbctrl/Comm.py index 03aa504..81c6ebc 100644 --- a/src/py/bbctrl/Comm.py +++ b/src/py/bbctrl/Comm.py @@ -140,7 +140,8 @@ class Comm(object): def _update_vars(self, msg): try: - self.ctrl.state.machine_vars(msg['variables']) + self.ctrl.state.set_machine_vars(msg['variables']) + self.ctrl.configure() self.queue_command(Cmd.DUMP) # Refresh all vars # Set axis positions @@ -192,16 +193,16 @@ class Comm(object): log.warning('%s, data: %s', e, line) continue - if 'variables' in msg: - self._update_vars(msg) - + if 'variables' in msg: self._update_vars(msg) elif 'msg' in msg: self._log_msg(msg) elif 'firmware' in msg: log.info('AVR firmware rebooted') self.connect() - else: self.ctrl.state.update(msg) + else: + self.ctrl.state.update(msg) + if 'xx' in msg: self.ctrl.ready() def _serial_handler(self, fd, events): diff --git a/src/py/bbctrl/Config.py b/src/py/bbctrl/Config.py index ad6b33c..9d353ce 100644 --- a/src/py/bbctrl/Config.py +++ b/src/py/bbctrl/Config.py @@ -174,10 +174,14 @@ class Config(object): subprocess.check_call(['sync']) + self.ctrl.preplanner.invalidate_all() log.info('Saved') - def reset(self): os.unlink('config.json') + def reset(self): + os.unlink('config.json') + self.reload() + self.ctrl.preplanner.invalidate_all() def _encode(self, name, index, config, tmpl, with_defaults): diff --git a/src/py/bbctrl/Ctrl.py b/src/py/bbctrl/Ctrl.py index c3bf7c0..69028ca 100644 --- a/src/py/bbctrl/Ctrl.py +++ b/src/py/bbctrl/Ctrl.py @@ -47,6 +47,7 @@ class Ctrl(object): self.i2c = bbctrl.I2C(args.i2c_port) self.lcd = bbctrl.LCD(self) self.mach = bbctrl.Mach(self) + self.preplanner = bbctrl.Preplanner(self) self.jog = bbctrl.Jog(self) self.pwr = bbctrl.Pwr(self) @@ -60,5 +61,14 @@ class Ctrl(object): except Exception as e: log.exception(e) - def close(self): - self.camera.close() + def configure(self): + # Indirectly configures state via calls to config() and the AVR + self.config.reload() + + + def ready(self): + # This is used to synchronize the start of the preplanner + self.preplanner.start() + + + def close(self): self.camera.close() diff --git a/src/py/bbctrl/FileHandler.py b/src/py/bbctrl/FileHandler.py index 6bff760..2367c06 100644 --- a/src/py/bbctrl/FileHandler.py +++ b/src/py/bbctrl/FileHandler.py @@ -27,21 +27,29 @@ import os import bbctrl +import glob + + +def safe_remove(path): + try: + os.unlink(path) + except OSError: pass class FileHandler(bbctrl.APIHandler): def prepare(self): pass - def delete_ok(self, path): - if not path: - if os.path.exists('upload'): - for path in os.listdir('upload'): - if os.path.isfile('upload/' + path): - os.unlink('upload/' + path) + def delete_ok(self, filename): + if not filename: + # Delete everything + for path in glob.glob('upload/*'): safe_remove(path) + self.ctrl.preplanner.delete_all_plans() + else: - path = 'upload' + path - if os.path.exists(path): os.unlink(path) + # Delete a single file + safe_remove('upload' + filename) + self.ctrl.preplanner.delete_plans(filename) def put_ok(self, path): @@ -54,6 +62,7 @@ class FileHandler(bbctrl.APIHandler): with open(path, 'wb') as f: f.write(gcode['body']) + self.ctrl.preplanner.invalidate(gcode['filename']) self.ctrl.state.set('selected', gcode['filename']) diff --git a/src/py/bbctrl/Planner.py b/src/py/bbctrl/Planner.py index 6260c1a..b1db478 100644 --- a/src/py/bbctrl/Planner.py +++ b/src/py/bbctrl/Planner.py @@ -29,6 +29,7 @@ import json import math import re import logging +import threading from collections import deque import camotics.gplan as gplan # pylint: disable=no-name-in-module,import-error import bbctrl.Cmd as Cmd @@ -44,6 +45,9 @@ class Planner(): def __init__(self, ctrl): self.ctrl = ctrl self.cmdq = CommandQueue() + self.logLock = threading.Lock() + self.logIntercept = {} + self.time = 0 ctrl.state.add_listener(self._update) @@ -56,7 +60,7 @@ class Planner(): def set_position(self, position): self.planner.set_position(position) - def update_position(self): + def get_position(self): position = {} for axis in 'xyzabc': @@ -64,7 +68,11 @@ class Planner(): value = self.ctrl.state.get(axis + 'p', None) if value is not None: position[axis] = value - self.set_position(position) + return position + + + def update_position(self): + self.set_position(self.get_position()) def _get_config_vector(self, name, scale): @@ -91,7 +99,7 @@ class Planner(): return limit - def _get_config(self, mdi, with_limits): + def get_config(self, mdi, with_limits): metric = self.ctrl.state.get('metric', True) config = { 'default-units': 'METRIC' if metric else 'IMPERIAL', @@ -153,6 +161,11 @@ class Planner(): return value + def log_intercept(self, cb): + with self.logLock: + self.logIntercept[threading.get_ident()] = cb + + def _log_cb(self, line): line = line.strip() m = reLogLine.match(line) @@ -162,6 +175,16 @@ class Planner(): msg = m.group('msg') where = m.group('where') + if where is not None: filename, line, column = where.split(':') + else: filename, line, column = None, None, None + + # Per thread log intercept + with self.logLock: + tid = threading.get_ident() + if tid in self.logIntercept: + self.logIntercept[tid](level, msg, filename, line, column) + return + if where is not None: extra = dict(where = where) else: extra = None @@ -173,7 +196,6 @@ class Planner(): else: log.error('Could not parse planner log line: ' + line) - def _enqueue_set_cmd(self, id, name, value): log.info('set(#%d, %s, %s)', id, name, value) self.cmdq.enqueue(id, self.ctrl.state.set, name, value) @@ -250,12 +272,12 @@ class Planner(): def mdi(self, cmd, with_limits = True): log.info('MDI:' + cmd) - self.planner.load_string(cmd, self._get_config(True, with_limits)) + self.planner.load_string(cmd, self.get_config(True, with_limits)) def load(self, path): log.info('GCode:' + path) - self.planner.load(path, self._get_config(False, True)) + self.planner.load(path, self.get_config(False, True)) def stop(self): diff --git a/src/py/bbctrl/Preplanner.py b/src/py/bbctrl/Preplanner.py new file mode 100644 index 0000000..09290bb --- /dev/null +++ b/src/py/bbctrl/Preplanner.py @@ -0,0 +1,304 @@ +################################################################################ +# # +# This file is part of the Buildbotics firmware. # +# # +# Copyright (c) 2015 - 2018, Buildbotics LLC # +# All rights reserved. # +# # +# This file ("the software") is free software: you can redistribute it # +# and/or modify it under the terms of the GNU General Public License, # +# version 2 as published by the Free Software Foundation. You should # +# have received a copy of the GNU General Public License, version 2 # +# along with the software. If not, see . # +# # +# The software is distributed in the hope that it will be useful, but # +# WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # +# Lesser General Public License for more details. # +# # +# You should have received a copy of the GNU Lesser General Public # +# License along with the software. If not, see # +# . # +# # +# For information regarding this software email: # +# "Joseph Coffland" # +# # +################################################################################ + +import os +import logging +import time +import json +import hashlib +import gzip +import glob +import threading +from concurrent.futures import Future, ThreadPoolExecutor, TimeoutError +from tornado import gen +import camotics.gplan as gplan # pylint: disable=no-name-in-module,import-error +import bbctrl + + +log = logging.getLogger('Preplaner') + + +# Formats floats with no more than two decimal places +def _dump_json(o): + if isinstance(o, str): yield json.dumps(o) + elif o is None: yield 'null' + elif o is True: yield 'true' + elif o is False: yield 'false' + elif isinstance(o, int): yield str(o) + + elif isinstance(o, float): + if o != o: yield 'NaN' + elif o == float('inf'): yield 'Infinity' + elif o == float('-inf'): yield '-Infinity' + else: yield format(o, '.2f') + + elif isinstance(o, (list, tuple)): + yield '[' + first = True + + for item in o: + if first: first = False + else: yield ',' + yield from _dump_json(item) + + yield ']' + + elif isinstance(o, dict): + yield '{' + first = True + + for key, value in o.items(): + if first: first = False + else: yield ',' + yield from _dump_json(key) + yield ':' + yield from _dump_json(value) + + yield '}' + + +def dump_json(o): return ''.join(_dump_json(o)) + + +def hash_dump(o): + s = json.dumps(o, separators = (',', ':'), sort_keys = True) + return s.encode('utf8') + + +def plan_hash(path, config): + h = hashlib.sha256() + h.update(hash_dump(config)) + with open('upload/' + path, 'rb') as f: h.update(f.read()) + return h.hexdigest() + + +class Preplanner(object): + def __init__(self, ctrl, threads = 4, max_plan_time = 600, + max_loop_time = 30): + self.ctrl = ctrl + self.max_plan_time = max_plan_time + self.max_loop_time = max_loop_time + + if not os.path.exists('plans'): os.mkdir('plans') + + self.started = Future() + + self.plans = {} + self.pool = ThreadPoolExecutor(threads) + self.lock = threading.Lock() + + + def start(self): + log.info('Preplanner started') + self.started.set_result(True) + + + def invalidate(self, filename): + with self.lock: + if filename in self.plans: + del self.plans[filename] + + + def invalidate_all(self): + with self.lock: self.plans = {} + + + def delete_all_plans(self): + for path in glob.glob('plans/*'): + try: + os.unlink(path) + except OSError: pass + + self.invalidate_all() + + + def delete_plans(self, filename): + for path in glob.glob('plans/' + filename + '.*'): + try: + os.unlink(path) + except OSError: pass + + self.invalidate(filename) + + + def get_plan(self, filename): + with self.lock: + if filename in self.plans: plan = self.plans[filename] + else: + plan = [self._plan(filename), 0] + self.plans[filename] = plan + + return plan[0] + + + def get_plan_progress(self, filename): + with self.lock: + if filename in self.plans: return self.plans[filename][1] + return 0 + + + @gen.coroutine + def _plan(self, filename): + # Wait until state is fully initialized + yield self.started + + # Copy state for thread + state = self.ctrl.state.snapshot() + config = self.ctrl.mach.planner.get_config(False, True) + + # Start planner thread + plan = yield self.pool.submit(self._exec_plan, filename, state, config) + return plan + + + def _clean_plans(self, filename, max = 2): + plans = glob.glob('plans/' + filename + '.*') + if len(plans) <= max: return + + # Delete oldest plans + plans = [(os.path.getmtime(path), path) for path in plans] + plans.sort() + + for mtime, path in plans[:len(plans) - max]: + try: + os.unlink(path) + except OSError: pass + + + def _progress(self, filename, progress): + with self.lock: + if not filename in self.plans: return False + self.plans[filename][1] = progress + return True + + + def _exec_plan(self, filename, state, config): + # Check if this plan was already run + hid = plan_hash(filename, config) + plan_path = 'plans/' + filename + '.' + hid + '.gz' + if os.path.exists(plan_path): + with open(plan_path, 'rb') as f: return f.read() + + # Clean up old plans + self._clean_plans(filename) + + + def get_var_cb(name, units): + value = 0 + + if len(name) and name[0] == '_': + value = state.get(name[1:], 0) + if units == 'IMPERIAL': value /= 25.4 + + return value + + + start = time.time() + moves = [] + line = 0 + totalLines = sum(1 for line in open('upload/' + filename)) + maxLine = 0 + maxLineTime = time.time() + totalTime = 0 + position = dict(x = 0, y = 0, z = 0) + rapid = False + moves = [] + messages = [] + count = 0 + + levels = dict(I = 'info', D = 'debug', W = 'warning', E = 'error', + C = 'critical') + + def log_cb(level, msg, filename, line, column): + if level in levels: level = levels[level] + messages.append(dict(level = level, msg = msg, filename = filename, + line = line, column = column)) + + + self.ctrl.mach.planner.log_intercept(log_cb) + planner = gplan.Planner() + planner.set_resolver(get_var_cb) + planner.load('upload/' + filename, config) + + try: + while planner.has_more(): + cmd = planner.next() + planner.set_active(cmd['id']) + # Cannot synchronize with actual machine so fake it + if planner.is_synchronizing(): planner.synchronize(0) + + if cmd['type'] == 'line': + totalTime += sum(cmd['times']) + + target = cmd['target'] + move = {} + + for axis in 'xyz': + if axis in target: + position[axis] = target[axis] + move[axis] = target[axis] + + if 'rapid' in cmd: move['rapid'] = cmd['rapid'] + + moves.append(move) + + elif cmd['type'] == 'set' and cmd['name'] == 'line': + line = cmd['value'] + if maxLine < line: + maxLine = line + maxLineTime = time.time() + + elif cmd['type'] == 'dwell': totalTime += cmd['seconds'] + + if not self._progress(filename, maxLine / totalLines): + raise Exception('Plan canceled.') + + if self.max_plan_time < time.time() - start: + raise Exception('Max planning time (%d sec) exceeded.' % + self.max_plan_time) + + if self.max_loop_time < time.time() - maxLineTime: + raise Exception('Max loop time (%d sec) exceeded.' % + self.max_loop_time) + + count += 1 + if count % 50 == 0: time.sleep(0.001) # Yield some time + + except Exception as e: + log_cb('error', str(e), filename, line, 0) + + self._progress(filename, 1) + + # Encode data as string + data = dict(time = totalTime, lines = totalLines, path = moves, + messages = messages) + data = gzip.compress(dump_json(data).encode('utf8')) + + # Save plan + with open(plan_path, 'wb') as f: f.write(data) + + return data diff --git a/src/py/bbctrl/State.py b/src/py/bbctrl/State.py index a91b3ba..3b34660 100644 --- a/src/py/bbctrl/State.py +++ b/src/py/bbctrl/State.py @@ -27,12 +27,47 @@ import logging import traceback +import copy import bbctrl log = logging.getLogger('State') +class StateSnapshot: + def __init__(self, state): + self.vars = copy.deepcopy(state.vars) + + for name in state.callbacks: + if not name in self.vars: + self.vars[name] = state.callbacks[name](name) + + self.motors = {} + for axis in 'xyzabc': + self.motors[axis] = state.find_motor(axis) + + + def json(self): return dict(vars = self.vars, motors = self.motors) + + + def resolve(self, name): + # Resolve axis prefixes to motor numbers + if 2 < len(name) and name[1] == '_' and name[0] in 'xyzabc': + motor = self.motors[name[0]] + if motor is not None: return str(motor) + name[2:] + + return name + + + def get(self, name, default = None): + name = self.resolve(name) + + if name in self.vars: return self.vars[name] + if default is None: log.warning('State variable "%s" not found' % name) + return default + + + class State(object): def __init__(self, ctrl): self.ctrl = ctrl @@ -68,9 +103,15 @@ class State(object): self.set_callback(str(i) + 'latch_velocity', lambda name, i = i: self.motor_latch_velocity(i)) + self.set_callback('metric', lambda name: 1 if self.is_metric() else 0) + self.set_callback('imperial', lambda name: 0 if self.is_metric() else 1) + self.reset() + def is_metric(self): return self.ctrl.config.get('units') == 'METRIC' + + def reset(self): # Unhome all motors for i in range(4): self.set('%dhomed' % i, False) @@ -135,6 +176,9 @@ class State(object): return default + def snapshot(self): return StateSnapshot(self) + + def config(self, code, value): # Set machine variables via mach, others directly if code in self.machine_var_set: self.ctrl.mach.set(code, value) @@ -149,7 +193,7 @@ class State(object): def remove_listener(self, listener): self.listeners.remove(listener) - def machine_vars(self, vars): + def set_machine_vars(self, vars): # Record all machine vars, indexed or otherwise self.machine_var_set = set() for code, spec in vars.items(): @@ -158,14 +202,6 @@ class State(object): self.machine_var_set.add(index + code) else: self.machine_var_set.add(code) - # Indirectly configure mach via calls to config() - self.ctrl.config.reload() - - # Configure units - metric = self.ctrl.config.get('units') == 'METRIC' - self.set('metric', 1 if metric else 0) - self.set('imperial', 0 if metric else 1) - def find_motor(self, axis): for motor in range(6): diff --git a/src/py/bbctrl/Web.py b/src/py/bbctrl/Web.py index 787c09e..ff68566 100644 --- a/src/py/bbctrl/Web.py +++ b/src/py/bbctrl/Web.py @@ -232,6 +232,33 @@ class UpgradeHandler(bbctrl.APIHandler): subprocess.Popen(['/usr/local/bin/upgrade-bbctrl']) +class PathHandler(bbctrl.APIHandler): + @gen.coroutine + def get(self, filename): + if not os.path.exists('upload/' + filename): + raise HTTPError(404, 'File not found') + future = self.ctrl.preplanner.get_plan(filename) + + try: + delta = datetime.timedelta(seconds = 1) + data = yield gen.with_timeout(delta, future) + + except gen.TimeoutError: + progress = self.ctrl.preplanner.get_plan_progress(filename) + self.write_json(dict(progress = progress)) + return + + if data is not None: + self.set_header('Content-Encoding', 'gzip') + + # Respond with chunks to avoid long delays + SIZE = 102400 + chunks = [data[i:i + SIZE] for i in range(0, len(data), SIZE)] + for chunk in chunks: + self.write(chunk) + yield self.flush() + + class HomeHandler(bbctrl.APIHandler): def put_ok(self, axis, action, *args): if axis is not None: axis = ord(axis[1:2].lower()) @@ -305,10 +332,6 @@ class JogHandler(bbctrl.APIHandler): def put_ok(self): self.ctrl.mach.jog(self.json) -class VideoReloadHandler(bbctrl.APIHandler): - def put_ok(self): pass #subprocess.Popen('reset-video').wait() - - # Base class for Web Socket connections class ClientConnection(object): def __init__(self, ctrl): @@ -387,7 +410,8 @@ class Web(tornado.web.Application): (r'/api/config/reset', ConfigResetHandler), (r'/api/firmware/update', FirmwareUpdateHandler), (r'/api/upgrade', UpgradeHandler), - (r'/api/file(/.+)?', bbctrl.FileHandler), + (r'/api/file(/[^/]+)?', bbctrl.FileHandler), + (r'/api/path/([^/]+)', PathHandler), (r'/api/home(/[xyzabcXYZABC]((/set)|(/clear))?)?', HomeHandler), (r'/api/start', StartHandler), (r'/api/estop', EStopHandler), @@ -404,7 +428,6 @@ class Web(tornado.web.Application): (r'/api/modbus/write', ModbusWriteHandler), (r'/api/jog', JogHandler), (r'/api/video', bbctrl.VideoHandler), - (r'/api/video/reload', VideoReloadHandler), (r'/(.*)', StaticFileHandler, {'path': bbctrl.get_resource('http/'), "default_filename": "index.html"}), diff --git a/src/py/bbctrl/__init__.py b/src/py/bbctrl/__init__.py index 75c68d0..ff0d08d 100644 --- a/src/py/bbctrl/__init__.py +++ b/src/py/bbctrl/__init__.py @@ -49,6 +49,7 @@ from bbctrl.Ctrl import Ctrl from bbctrl.Pwr import Pwr from bbctrl.I2C import I2C from bbctrl.Planner import Planner +from bbctrl.Preplanner import Preplanner from bbctrl.State import State from bbctrl.Messages import Messages from bbctrl.Comm import Comm diff --git a/src/resources/images/DB25-M2_breakout.png b/src/resources/images/DB25-M2_breakout.png index 30906c2..02929ff 100644 Binary files a/src/resources/images/DB25-M2_breakout.png and b/src/resources/images/DB25-M2_breakout.png differ diff --git a/src/resources/images/DB25_breakout_box.png b/src/resources/images/DB25_breakout_box.png index 5cfa26f..a1c1b99 100644 Binary files a/src/resources/images/DB25_breakout_box.png and b/src/resources/images/DB25_breakout_box.png differ diff --git a/src/resources/images/axes.png b/src/resources/images/axes.png new file mode 100644 index 0000000..c5539d4 Binary files /dev/null and b/src/resources/images/axes.png differ diff --git a/src/resources/images/bbox.png b/src/resources/images/bbox.png new file mode 100644 index 0000000..7f2e0d9 Binary files /dev/null and b/src/resources/images/bbox.png differ diff --git a/src/resources/images/front.png b/src/resources/images/front.png new file mode 100644 index 0000000..af3e052 Binary files /dev/null and b/src/resources/images/front.png differ diff --git a/src/resources/images/isometric.png b/src/resources/images/isometric.png new file mode 100644 index 0000000..760e276 Binary files /dev/null and b/src/resources/images/isometric.png differ diff --git a/src/resources/images/tool.png b/src/resources/images/tool.png new file mode 100644 index 0000000..e715ef2 Binary files /dev/null and b/src/resources/images/tool.png differ diff --git a/src/resources/images/top.png b/src/resources/images/top.png new file mode 100644 index 0000000..89d3a56 Binary files /dev/null and b/src/resources/images/top.png differ diff --git a/src/resources/js/smoothie.js b/src/resources/js/smoothie.js deleted file mode 100644 index f53e83a..0000000 --- a/src/resources/js/smoothie.js +++ /dev/null @@ -1,1025 +0,0 @@ -// MIT License: -// -// Copyright (c) 2010-2013, Joe Walnes -// 2013-2017, Drew Noakes -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -/** - * Smoothie Charts - http://smoothiecharts.org/ - * (c) 2010-2013, Joe Walnes - * 2013-2017, Drew Noakes - * - * v1.0: Main charting library, by Joe Walnes - * v1.1: Auto scaling of axis, by Neil Dunn - * v1.2: fps (frames per second) option, by Mathias Petterson - * v1.3: Fix for divide by zero, by Paul Nikitochkin - * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds - * v1.5: Set default frames per second to 50... smoother. - * .start(), .stop() methods for conserving CPU, by Dmitry Vyal - * options.interpolation = 'bezier' or 'line', by Dmitry Vyal - * options.maxValue to fix scale, by Dmitry Vyal - * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla - * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin - * Smooth rescaling, by Kostas Michalopoulos - * v1.8: Set max length to customize number of live points in the dataset with options.maxDataSetLength, by Krishna Narni - * v1.9: Display timestamps along the bottom, by Nick and Stev-io - * (https://groups.google.com/forum/?fromgroups#!topic/smoothie-charts/-Ywse8FCpKI%5B1-25%5D) - * Refactored by Krishna Narni, to support timestamp formatting function - * v1.10: Switch to requestAnimationFrame, removed the now obsoleted options.fps, by Gergely Imreh - * v1.11: options.grid.sharpLines option added, by @drewnoakes - * Addressed warning seen in Firefox when seriesOption.fillStyle undefined, by @drewnoakes - * v1.12: Support for horizontalLines added, by @drewnoakes - * Support for yRangeFunction callback added, by @drewnoakes - * v1.13: Fixed typo (#32), by @alnikitich - * v1.14: Timer cleared when last TimeSeries removed (#23), by @davidgaleano - * Fixed diagonal line on chart at start/end of data stream, by @drewnoakes - * v1.15: Support for npm package (#18), by @dominictarr - * Fixed broken removeTimeSeries function (#24) by @davidgaleano - * Minor performance and tidying, by @drewnoakes - * v1.16: Bug fix introduced in v1.14 relating to timer creation/clearance (#23), by @drewnoakes - * TimeSeries.append now deals with out-of-order timestamps, and can merge duplicates, by @zacwitte (#12) - * Documentation and some local variable renaming for clarity, by @drewnoakes - * v1.17: Allow control over font size (#10), by @drewnoakes - * Timestamp text won't overlap, by @drewnoakes - * v1.18: Allow control of max/min label precision, by @drewnoakes - * Added 'borderVisible' chart option, by @drewnoakes - * Allow drawing series with fill but no stroke (line), by @drewnoakes - * v1.19: Avoid unnecessary repaints, and fixed flicker in old browsers having multiple charts in document (#40), by @asbai - * v1.20: Add SmoothieChart.getTimeSeriesOptions and SmoothieChart.bringToFront functions, by @drewnoakes - * v1.21: Add 'step' interpolation mode, by @drewnoakes - * v1.22: Add support for different pixel ratios. Also add optional y limit formatters, by @copacetic - * v1.23: Fix bug introduced in v1.22 (#44), by @drewnoakes - * v1.24: Fix bug introduced in v1.23, re-adding parseFloat to y-axis formatter defaults, by @siggy_sf - * v1.25: Fix bug seen when adding a data point to TimeSeries which is older than the current data, by @Nking92 - * Draw time labels on top of series, by @comolosabia - * Add TimeSeries.clear function, by @drewnoakes - * v1.26: Add support for resizing on high device pixel ratio screens, by @copacetic - * v1.27: Fix bug introduced in v1.26 for non whole number devicePixelRatio values, by @zmbush - * v1.28: Add 'minValueScale' option, by @megawac - * Fix 'labelPos' for different size of 'minValueString' 'maxValueString', by @henryn - * v1.29: Support responsive sizing, by @drewnoakes - * v1.29.1: Include types in package, and make property optional, by @TrentHouliston - * v1.30: Fix inverted logic in devicePixelRatio support, by @scanlime - * v1.31: Support tooltips, by @Sly1024 and @drewnoakes - * v1.32: Support frame rate limit, by @dpuyosa - * v1.33: Use Date static method instead of instance, by @nnnoel - * Fix bug with tooltips when multiple charts on a page, by @jpmbiz70 - */ - -;(function(exports) { - - // Date.now polyfill - Date.now = Date.now || function() { return new Date().getTime(); }; - - var Util = { - extend: function() { - arguments[0] = arguments[0] || {}; - for (var i = 1; i < arguments.length; i++) - { - for (var key in arguments[i]) - { - if (arguments[i].hasOwnProperty(key)) - { - if (typeof(arguments[i][key]) === 'object') { - if (arguments[i][key] instanceof Array) { - arguments[0][key] = arguments[i][key]; - } else { - arguments[0][key] = Util.extend(arguments[0][key], arguments[i][key]); - } - } else { - arguments[0][key] = arguments[i][key]; - } - } - } - } - return arguments[0]; - }, - binarySearch: function(data, value) { - var low = 0, - high = data.length; - while (low < high) { - var mid = (low + high) >> 1; - if (value < data[mid][0]) - high = mid; - else - low = mid + 1; - } - return low; - } - }; - - /** - * Initialises a new TimeSeries with optional data options. - * - * Options are of the form (defaults shown): - * - *
-   * {
-   *   resetBounds: true,        // enables/disables automatic scaling of the y-axis
-   *   resetBoundsInterval: 3000 // the period between scaling calculations, in millis
-   * }
-   * 
- * - * Presentation options for TimeSeries are specified as an argument to SmoothieChart.addTimeSeries. - * - * @constructor - */ - function TimeSeries(options) { - this.options = Util.extend({}, TimeSeries.defaultOptions, options); - this.disabled = false; - this.clear(); - } - - TimeSeries.defaultOptions = { - resetBoundsInterval: 3000, - resetBounds: true - }; - - /** - * Clears all data and state from this TimeSeries object. - */ - TimeSeries.prototype.clear = function() { - this.data = []; - this.maxValue = Number.NaN; // The maximum value ever seen in this TimeSeries. - this.minValue = Number.NaN; // The minimum value ever seen in this TimeSeries. - }; - - /** - * Recalculate the min/max values for this TimeSeries object. - * - * This causes the graph to scale itself in the y-axis. - */ - TimeSeries.prototype.resetBounds = function() { - if (this.data.length) { - // Walk through all data points, finding the min/max value - this.maxValue = this.data[0][1]; - this.minValue = this.data[0][1]; - for (var i = 1; i < this.data.length; i++) { - var value = this.data[i][1]; - if (value > this.maxValue) { - this.maxValue = value; - } - if (value < this.minValue) { - this.minValue = value; - } - } - } else { - // No data exists, so set min/max to NaN - this.maxValue = Number.NaN; - this.minValue = Number.NaN; - } - }; - - /** - * Adds a new data point to the TimeSeries, preserving chronological order. - * - * @param timestamp the position, in time, of this data point - * @param value the value of this data point - * @param sumRepeatedTimeStampValues if timestamp has an exact match in the series, this flag controls - * whether it is replaced, or the values summed (defaults to false.) - */ - TimeSeries.prototype.append = function(timestamp, value, sumRepeatedTimeStampValues) { - // Rewind until we hit an older timestamp - var i = this.data.length - 1; - while (i >= 0 && this.data[i][0] > timestamp) { - i--; - } - - if (i === -1) { - // This new item is the oldest data - this.data.splice(0, 0, [timestamp, value]); - } else if (this.data.length > 0 && this.data[i][0] === timestamp) { - // Update existing values in the array - if (sumRepeatedTimeStampValues) { - // Sum this value into the existing 'bucket' - this.data[i][1] += value; - value = this.data[i][1]; - } else { - // Replace the previous value - this.data[i][1] = value; - } - } else if (i < this.data.length - 1) { - // Splice into the correct position to keep timestamps in order - this.data.splice(i + 1, 0, [timestamp, value]); - } else { - // Add to the end of the array - this.data.push([timestamp, value]); - } - - this.maxValue = isNaN(this.maxValue) ? value : Math.max(this.maxValue, value); - this.minValue = isNaN(this.minValue) ? value : Math.min(this.minValue, value); - }; - - TimeSeries.prototype.dropOldData = function(oldestValidTime, maxDataSetLength) { - // We must always keep one expired data point as we need this to draw the - // line that comes into the chart from the left, but any points prior to that can be removed. - var removeCount = 0; - while (this.data.length - removeCount >= maxDataSetLength && this.data[removeCount + 1][0] < oldestValidTime) { - removeCount++; - } - if (removeCount !== 0) { - this.data.splice(0, removeCount); - } - }; - - /** - * Initialises a new SmoothieChart. - * - * Options are optional, and should be of the form below. Just specify the values you - * need and the rest will be given sensible defaults as shown: - * - *
-   * {
-   *   minValue: undefined,                      // specify to clamp the lower y-axis to a given value
-   *   maxValue: undefined,                      // specify to clamp the upper y-axis to a given value
-   *   maxValueScale: 1,                         // allows proportional padding to be added above the chart. for 10% padding, specify 1.1.
-   *   minValueScale: 1,                         // allows proportional padding to be added below the chart. for 10% padding, specify 1.1.
-   *   yRangeFunction: undefined,                // function({min: , max: }) { return {min: , max: }; }
-   *   scaleSmoothing: 0.125,                    // controls the rate at which y-value zoom animation occurs
-   *   millisPerPixel: 20,                       // sets the speed at which the chart pans by
-   *   enableDpiScaling: true,                   // support rendering at different DPI depending on the device
-   *   yMinFormatter: function(min, precision) { // callback function that formats the min y value label
-   *     return parseFloat(min).toFixed(precision);
-   *   },
-   *   yMaxFormatter: function(max, precision) { // callback function that formats the max y value label
-   *     return parseFloat(max).toFixed(precision);
-   *   },
-   *   maxDataSetLength: 2,
-   *   interpolation: 'bezier'                   // one of 'bezier', 'linear', or 'step'
-   *   timestampFormatter: null,                 // optional function to format time stamps for bottom of chart
-   *                                             // you may use SmoothieChart.timeFormatter, or your own: function(date) { return ''; }
-   *   scrollBackwards: false,                   // reverse the scroll direction of the chart
-   *   horizontalLines: [],                      // [ { value: 0, color: '#ffffff', lineWidth: 1 } ]
-   *   grid:
-   *   {
-   *     fillStyle: '#000000',                   // the background colour of the chart
-   *     lineWidth: 1,                           // the pixel width of grid lines
-   *     strokeStyle: '#777777',                 // colour of grid lines
-   *     millisPerLine: 1000,                    // distance between vertical grid lines
-   *     sharpLines: false,                      // controls whether grid lines are 1px sharp, or softened
-   *     verticalSections: 2,                    // number of vertical sections marked out by horizontal grid lines
-   *     borderVisible: true                     // whether the grid lines trace the border of the chart or not
-   *   },
-   *   labels
-   *   {
-   *     disabled: false,                        // enables/disables labels showing the min/max values
-   *     fillStyle: '#ffffff',                   // colour for text of labels,
-   *     fontSize: 15,
-   *     fontFamily: 'sans-serif',
-   *     precision: 2,
-   *     showIntermediateLabels: false,          // shows intermediate labels between min and max values along y axis
-   *   },
-   *   tooltip: false                            // show tooltip when mouse is over the chart
-   *   tooltipLine: {                            // properties for a vertical line at the cursor position
-   *     lineWidth: 1,
-   *     strokeStyle: '#BBBBBB'
-   *   },
-   *   tooltipFormatter: SmoothieChart.tooltipFormatter, // formatter function for tooltip text
-   *   nonRealtimeData: false,                   // use time of latest data as current time
-   *   displayDataFromPercentile: 1,             // display not latest data, but data from the given percentile
-   *                                             // useful when trying to see old data saved by setting a high value for maxDataSetLength
-   *                                             // should be a value between 0 and 1 
-   *   responsive: false,                        // whether the chart should adapt to the size of the canvas
-   *   limitFPS: 0                         // maximum frame rate the chart will render at, in FPS (zero means no limit)
-   * }
-   * 
- * - * @constructor - */ - function SmoothieChart(options) { - this.options = Util.extend({}, SmoothieChart.defaultChartOptions, options); - this.seriesSet = []; - this.currentValueRange = 1; - this.currentVisMinValue = 0; - this.lastRenderTimeMillis = 0; - this.lastChartTimestamp = 0; - - this.mousemove = this.mousemove.bind(this); - this.mouseout = this.mouseout.bind(this); - } - - /** Formats the HTML string content of the tooltip. */ - SmoothieChart.tooltipFormatter = function (timestamp, data) { - var timestampFormatter = this.options.timestampFormatter || SmoothieChart.timeFormatter, - lines = [timestampFormatter(new Date(timestamp))]; - - for (var i = 0; i < data.length; ++i) { - lines.push('' + - this.options.yMaxFormatter(data[i].value, this.options.labels.precision) + ''); - } - - return lines.join('
'); - }; - - SmoothieChart.defaultChartOptions = { - millisPerPixel: 20, - enableDpiScaling: true, - yMinFormatter: function(min, precision) { - return parseFloat(min).toFixed(precision); - }, - yMaxFormatter: function(max, precision) { - return parseFloat(max).toFixed(precision); - }, - maxValueScale: 1, - minValueScale: 1, - interpolation: 'bezier', - scaleSmoothing: 0.125, - maxDataSetLength: 2, - scrollBackwards: false, - displayDataFromPercentile: 1, - grid: { - fillStyle: '#000000', - strokeStyle: '#777777', - lineWidth: 1, - sharpLines: false, - millisPerLine: 1000, - verticalSections: 2, - borderVisible: true - }, - labels: { - fillStyle: '#ffffff', - disabled: false, - fontSize: 10, - fontFamily: 'monospace', - precision: 2, - showIntermediateLabels: false, - }, - horizontalLines: [], - tooltip: false, - tooltipLine: { - lineWidth: 1, - strokeStyle: '#BBBBBB' - }, - tooltipFormatter: SmoothieChart.tooltipFormatter, - nonRealtimeData: false, - responsive: false, - limitFPS: 0 - }; - - // Based on http://inspirit.github.com/jsfeat/js/compatibility.js - SmoothieChart.AnimateCompatibility = (function() { - var requestAnimationFrame = function(callback, element) { - var requestAnimationFrame = - window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(callback) { - return window.setTimeout(function() { - callback(Date.now()); - }, 16); - }; - return requestAnimationFrame.call(window, callback, element); - }, - cancelAnimationFrame = function(id) { - var cancelAnimationFrame = - window.cancelAnimationFrame || - function(id) { - clearTimeout(id); - }; - return cancelAnimationFrame.call(window, id); - }; - - return { - requestAnimationFrame: requestAnimationFrame, - cancelAnimationFrame: cancelAnimationFrame - }; - })(); - - SmoothieChart.defaultSeriesPresentationOptions = { - lineWidth: 1, - strokeStyle: '#ffffff' - }; - - /** - * Adds a TimeSeries to this chart, with optional presentation options. - * - * Presentation options should be of the form (defaults shown): - * - *
-   * {
-   *   lineWidth: 1,
-   *   strokeStyle: '#ffffff',
-   *   fillStyle: undefined
-   * }
-   * 
- */ - SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { - this.seriesSet.push({timeSeries: timeSeries, options: Util.extend({}, SmoothieChart.defaultSeriesPresentationOptions, options)}); - if (timeSeries.options.resetBounds && timeSeries.options.resetBoundsInterval > 0) { - timeSeries.resetBoundsTimerId = setInterval( - function() { - timeSeries.resetBounds(); - }, - timeSeries.options.resetBoundsInterval - ); - } - }; - - /** - * Removes the specified TimeSeries from the chart. - */ - SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { - // Find the correct timeseries to remove, and remove it - var numSeries = this.seriesSet.length; - for (var i = 0; i < numSeries; i++) { - if (this.seriesSet[i].timeSeries === timeSeries) { - this.seriesSet.splice(i, 1); - break; - } - } - // If a timer was operating for that timeseries, remove it - if (timeSeries.resetBoundsTimerId) { - // Stop resetting the bounds, if we were - clearInterval(timeSeries.resetBoundsTimerId); - } - }; - - /** - * Gets render options for the specified TimeSeries. - * - * As you may use a single TimeSeries in multiple charts with different formatting in each usage, - * these settings are stored in the chart. - */ - SmoothieChart.prototype.getTimeSeriesOptions = function(timeSeries) { - // Find the correct timeseries to remove, and remove it - var numSeries = this.seriesSet.length; - for (var i = 0; i < numSeries; i++) { - if (this.seriesSet[i].timeSeries === timeSeries) { - return this.seriesSet[i].options; - } - } - }; - - /** - * Brings the specified TimeSeries to the top of the chart. It will be rendered last. - */ - SmoothieChart.prototype.bringToFront = function(timeSeries) { - // Find the correct timeseries to remove, and remove it - var numSeries = this.seriesSet.length; - for (var i = 0; i < numSeries; i++) { - if (this.seriesSet[i].timeSeries === timeSeries) { - var set = this.seriesSet.splice(i, 1); - this.seriesSet.push(set[0]); - break; - } - } - }; - - /** - * Instructs the SmoothieChart to start rendering to the provided canvas, with specified delay. - * - * @param canvas the target canvas element - * @param delayMillis an amount of time to wait before a data point is shown. This can prevent the end of the series - * from appearing on screen, with new values flashing into view, at the expense of some latency. - */ - SmoothieChart.prototype.streamTo = function(canvas, delayMillis) { - this.canvas = canvas; - this.delay = delayMillis; - this.start(); - }; - - SmoothieChart.prototype.getTooltipEl = function () { - // Create the tool tip element lazily - if (!this.tooltipEl) { - this.tooltipEl = document.createElement('div'); - this.tooltipEl.className = 'smoothie-chart-tooltip'; - this.tooltipEl.style.position = 'absolute'; - this.tooltipEl.style.display = 'none'; - document.body.appendChild(this.tooltipEl); - } - return this.tooltipEl; - }; - - SmoothieChart.prototype.updateTooltip = function () { - var el = this.getTooltipEl(); - - if (!this.mouseover || !this.options.tooltip) { - el.style.display = 'none'; - return; - } - - var time = this.lastChartTimestamp; - - // x pixel to time - var t = this.options.scrollBackwards - ? time - this.mouseX * this.options.millisPerPixel - : time - (this.canvas.offsetWidth - this.mouseX) * this.options.millisPerPixel; - - var data = []; - - // For each data set... - for (var d = 0; d < this.seriesSet.length; d++) { - var timeSeries = this.seriesSet[d].timeSeries; - if (timeSeries.disabled) { - continue; - } - - // find datapoint closest to time 't' - var closeIdx = Util.binarySearch(timeSeries.data, t); - if (closeIdx > 0 && closeIdx < timeSeries.data.length) { - data.push({ series: this.seriesSet[d], index: closeIdx, value: timeSeries.data[closeIdx][1] }); - } - } - - if (data.length) { - el.innerHTML = this.options.tooltipFormatter.call(this, t, data); - el.style.display = 'block'; - } else { - el.style.display = 'none'; - } - }; - - SmoothieChart.prototype.mousemove = function (evt) { - this.mouseover = true; - this.mouseX = evt.offsetX; - this.mouseY = evt.offsetY; - this.mousePageX = evt.pageX; - this.mousePageY = evt.pageY; - - var el = this.getTooltipEl(); - el.style.top = Math.round(this.mousePageY) + 'px'; - el.style.left = Math.round(this.mousePageX) + 'px'; - this.updateTooltip(); - }; - - SmoothieChart.prototype.mouseout = function () { - this.mouseover = false; - this.mouseX = this.mouseY = -1; - if (SmoothieChart.tooltipEl) - SmoothieChart.tooltipEl.style.display = 'none'; - }; - - /** - * Make sure the canvas has the optimal resolution for the device's pixel ratio. - */ - SmoothieChart.prototype.resize = function () { - var dpr = !this.options.enableDpiScaling || !window ? 1 : window.devicePixelRatio, - width, height; - if (this.options.responsive) { - // Newer behaviour: Use the canvas's size in the layout, and set the internal - // resolution according to that size and the device pixel ratio (eg: high DPI) - width = this.canvas.offsetWidth; - height = this.canvas.offsetHeight; - - if (width !== this.lastWidth) { - this.lastWidth = width; - this.canvas.setAttribute('width', (Math.floor(width * dpr)).toString()); - } - if (height !== this.lastHeight) { - this.lastHeight = height; - this.canvas.setAttribute('height', (Math.floor(height * dpr)).toString()); - } - } else if (dpr !== 1) { - // Older behaviour: use the canvas's inner dimensions and scale the element's size - // according to that size and the device pixel ratio (eg: high DPI) - width = parseInt(this.canvas.getAttribute('width')); - height = parseInt(this.canvas.getAttribute('height')); - - if (!this.originalWidth || (Math.floor(this.originalWidth * dpr) !== width)) { - this.originalWidth = width; - this.canvas.setAttribute('width', (Math.floor(width * dpr)).toString()); - this.canvas.style.width = width + 'px'; - this.canvas.getContext('2d').scale(dpr, dpr); - } - - if (!this.originalHeight || (Math.floor(this.originalHeight * dpr) !== height)) { - this.originalHeight = height; - this.canvas.setAttribute('height', (Math.floor(height * dpr)).toString()); - this.canvas.style.height = height + 'px'; - this.canvas.getContext('2d').scale(dpr, dpr); - } - } - }; - - /** - * Starts the animation of this chart. - */ - SmoothieChart.prototype.start = function() { - if (this.frame) { - // We're already running, so just return - return; - } - - this.canvas.addEventListener('mousemove', this.mousemove); - this.canvas.addEventListener('mouseout', this.mouseout); - - // Renders a frame, and queues the next frame for later rendering - var animate = function() { - this.frame = SmoothieChart.AnimateCompatibility.requestAnimationFrame(function() { - if(this.options.nonRealtimeData){ - var dateZero = new Date(0); - // find the data point with the latest timestamp - var maxTimeStamp = this.seriesSet.reduce(function(max, series){ - var dataSet = series.timeSeries.data; - var indexToCheck = Math.round(this.options.displayDataFromPercentile * dataSet.length) - 1; - indexToCheck = indexToCheck >= 0 ? indexToCheck : 0; - indexToCheck = indexToCheck <= dataSet.length -1 ? indexToCheck : dataSet.length -1; - if(dataSet && dataSet.length > 0) - { - // timestamp corresponds to element 0 of the data point - var lastDataTimeStamp = dataSet[indexToCheck][0]; - max = max > lastDataTimeStamp ? max : lastDataTimeStamp; - } - return max; - }.bind(this), dateZero); - // use the max timestamp as current time - this.render(this.canvas, maxTimeStamp > dateZero ? maxTimeStamp : null); - } else { - this.render(); - } - animate(); - }.bind(this)); - }.bind(this); - - animate(); - }; - - /** - * Stops the animation of this chart. - */ - SmoothieChart.prototype.stop = function() { - if (this.frame) { - SmoothieChart.AnimateCompatibility.cancelAnimationFrame(this.frame); - delete this.frame; - this.canvas.removeEventListener('mousemove', this.mousemove); - this.canvas.removeEventListener('mouseout', this.mouseout); - } - }; - - SmoothieChart.prototype.updateValueRange = function() { - // Calculate the current scale of the chart, from all time series. - var chartOptions = this.options, - chartMaxValue = Number.NaN, - chartMinValue = Number.NaN; - - for (var d = 0; d < this.seriesSet.length; d++) { - // TODO(ndunn): We could calculate / track these values as they stream in. - var timeSeries = this.seriesSet[d].timeSeries; - if (timeSeries.disabled) { - continue; - } - - if (!isNaN(timeSeries.maxValue)) { - chartMaxValue = !isNaN(chartMaxValue) ? Math.max(chartMaxValue, timeSeries.maxValue) : timeSeries.maxValue; - } - - if (!isNaN(timeSeries.minValue)) { - chartMinValue = !isNaN(chartMinValue) ? Math.min(chartMinValue, timeSeries.minValue) : timeSeries.minValue; - } - } - - // Scale the chartMaxValue to add padding at the top if required - if (chartOptions.maxValue != null) { - chartMaxValue = chartOptions.maxValue; - } else { - chartMaxValue *= chartOptions.maxValueScale; - } - - // Set the minimum if we've specified one - if (chartOptions.minValue != null) { - chartMinValue = chartOptions.minValue; - } else { - chartMinValue -= Math.abs(chartMinValue * chartOptions.minValueScale - chartMinValue); - } - - // If a custom range function is set, call it - if (this.options.yRangeFunction) { - var range = this.options.yRangeFunction({min: chartMinValue, max: chartMaxValue}); - chartMinValue = range.min; - chartMaxValue = range.max; - } - - if (!isNaN(chartMaxValue) && !isNaN(chartMinValue)) { - var targetValueRange = chartMaxValue - chartMinValue; - var valueRangeDiff = (targetValueRange - this.currentValueRange); - var minValueDiff = (chartMinValue - this.currentVisMinValue); - this.isAnimatingScale = Math.abs(valueRangeDiff) > 0.1 || Math.abs(minValueDiff) > 0.1; - this.currentValueRange += chartOptions.scaleSmoothing * valueRangeDiff; - this.currentVisMinValue += chartOptions.scaleSmoothing * minValueDiff; - } - - this.valueRange = { min: chartMinValue, max: chartMaxValue }; - }; - - SmoothieChart.prototype.render = function(canvas, time) { - var nowMillis = Date.now(); - - // Respect any frame rate limit. - if (this.options.limitFPS > 0 && nowMillis - this.lastRenderTimeMillis < (1000/this.options.limitFPS)) - return; - - if (!this.isAnimatingScale) { - // We're not animating. We can use the last render time and the scroll speed to work out whether - // we actually need to paint anything yet. If not, we can return immediately. - - // Render at least every 1/6th of a second. The canvas may be resized, which there is - // no reliable way to detect. - var maxIdleMillis = Math.min(1000/6, this.options.millisPerPixel); - - if (nowMillis - this.lastRenderTimeMillis < maxIdleMillis) { - return; - } - } - - this.resize(); - this.updateTooltip(); - - this.lastRenderTimeMillis = nowMillis; - - canvas = canvas || this.canvas; - time = time || nowMillis - (this.delay || 0); - - // Round time down to pixel granularity, so motion appears smoother. - time -= time % this.options.millisPerPixel; - - this.lastChartTimestamp = time; - - var context = canvas.getContext('2d'), - chartOptions = this.options, - dimensions = { top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight }, - // Calculate the threshold time for the oldest data points. - oldestValidTime = time - (dimensions.width * chartOptions.millisPerPixel), - valueToYPixel = function(value) { - var offset = value - this.currentVisMinValue; - return this.currentValueRange === 0 - ? dimensions.height - : dimensions.height - (Math.round((offset / this.currentValueRange) * dimensions.height)); - }.bind(this), - timeToXPixel = function(t) { - if(chartOptions.scrollBackwards) { - return Math.round((time - t) / chartOptions.millisPerPixel); - } - return Math.round(dimensions.width - ((time - t) / chartOptions.millisPerPixel)); - }; - - this.updateValueRange(); - - context.font = chartOptions.labels.fontSize + 'px ' + chartOptions.labels.fontFamily; - - // Save the state of the canvas context, any transformations applied in this method - // will get removed from the stack at the end of this method when .restore() is called. - context.save(); - - // Move the origin. - context.translate(dimensions.left, dimensions.top); - - // Create a clipped rectangle - anything we draw will be constrained to this rectangle. - // This prevents the occasional pixels from curves near the edges overrunning and creating - // screen cheese (that phrase should need no explanation). - context.beginPath(); - context.rect(0, 0, dimensions.width, dimensions.height); - context.clip(); - - // Clear the working area. - context.save(); - context.fillStyle = chartOptions.grid.fillStyle; - context.clearRect(0, 0, dimensions.width, dimensions.height); - context.fillRect(0, 0, dimensions.width, dimensions.height); - context.restore(); - - // Grid lines... - context.save(); - context.lineWidth = chartOptions.grid.lineWidth; - context.strokeStyle = chartOptions.grid.strokeStyle; - // Vertical (time) dividers. - if (chartOptions.grid.millisPerLine > 0) { - context.beginPath(); - for (var t = time - (time % chartOptions.grid.millisPerLine); - t >= oldestValidTime; - t -= chartOptions.grid.millisPerLine) { - var gx = timeToXPixel(t); - if (chartOptions.grid.sharpLines) { - gx -= 0.5; - } - context.moveTo(gx, 0); - context.lineTo(gx, dimensions.height); - } - context.stroke(); - context.closePath(); - } - - // Horizontal (value) dividers. - for (var v = 1; v < chartOptions.grid.verticalSections; v++) { - var gy = Math.round(v * dimensions.height / chartOptions.grid.verticalSections); - if (chartOptions.grid.sharpLines) { - gy -= 0.5; - } - context.beginPath(); - context.moveTo(0, gy); - context.lineTo(dimensions.width, gy); - context.stroke(); - context.closePath(); - } - // Bounding rectangle. - if (chartOptions.grid.borderVisible) { - context.beginPath(); - context.strokeRect(0, 0, dimensions.width, dimensions.height); - context.closePath(); - } - context.restore(); - - // Draw any horizontal lines... - if (chartOptions.horizontalLines && chartOptions.horizontalLines.length) { - for (var hl = 0; hl < chartOptions.horizontalLines.length; hl++) { - var line = chartOptions.horizontalLines[hl], - hly = Math.round(valueToYPixel(line.value)) - 0.5; - context.strokeStyle = line.color || '#ffffff'; - context.lineWidth = line.lineWidth || 1; - context.beginPath(); - context.moveTo(0, hly); - context.lineTo(dimensions.width, hly); - context.stroke(); - context.closePath(); - } - } - - // For each data set... - for (var d = 0; d < this.seriesSet.length; d++) { - context.save(); - var timeSeries = this.seriesSet[d].timeSeries; - if (timeSeries.disabled) { - continue; - } - - var dataSet = timeSeries.data, - seriesOptions = this.seriesSet[d].options; - - // Delete old data that's moved off the left of the chart. - timeSeries.dropOldData(oldestValidTime, chartOptions.maxDataSetLength); - - // Set style for this dataSet. - context.lineWidth = seriesOptions.lineWidth; - context.strokeStyle = seriesOptions.strokeStyle; - // Draw the line... - context.beginPath(); - // Retain lastX, lastY for calculating the control points of bezier curves. - var firstX = 0, lastX = 0, lastY = 0; - for (var i = 0; i < dataSet.length && dataSet.length !== 1; i++) { - var x = timeToXPixel(dataSet[i][0]), - y = valueToYPixel(dataSet[i][1]); - - if (i === 0) { - firstX = x; - context.moveTo(x, y); - } else { - switch (chartOptions.interpolation) { - case "linear": - case "line": { - context.lineTo(x,y); - break; - } - case "bezier": - default: { - // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_curves - // - // Assuming A was the last point in the line plotted and B is the new point, - // we draw a curve with control points P and Q as below. - // - // A---P - // | - // | - // | - // Q---B - // - // Importantly, A and P are at the same y coordinate, as are B and Q. This is - // so adjacent curves appear to flow as one. - // - context.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop - Math.round((lastX + x) / 2), lastY, // controlPoint1 (P) - Math.round((lastX + x)) / 2, y, // controlPoint2 (Q) - x, y); // endPoint (B) - break; - } - case "step": { - context.lineTo(x,lastY); - context.lineTo(x,y); - break; - } - } - } - - lastX = x; lastY = y; - } - - if (dataSet.length > 1) { - if (seriesOptions.fillStyle) { - // Close up the fill region. - context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY); - context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1); - context.lineTo(firstX, dimensions.height + seriesOptions.lineWidth); - context.fillStyle = seriesOptions.fillStyle; - context.fill(); - } - - if (seriesOptions.strokeStyle && seriesOptions.strokeStyle !== 'none') { - context.stroke(); - } - context.closePath(); - } - context.restore(); - } - - if (chartOptions.tooltip && this.mouseX >= 0) { - // Draw vertical bar to show tooltip position - context.lineWidth = chartOptions.tooltipLine.lineWidth; - context.strokeStyle = chartOptions.tooltipLine.strokeStyle; - context.beginPath(); - context.moveTo(this.mouseX, 0); - context.lineTo(this.mouseX, dimensions.height); - context.closePath(); - context.stroke(); - this.updateTooltip(); - } - - // Draw the axis values on the chart. - if (!chartOptions.labels.disabled && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max)) { - var maxValueString = chartOptions.yMaxFormatter(this.valueRange.max, chartOptions.labels.precision), - minValueString = chartOptions.yMinFormatter(this.valueRange.min, chartOptions.labels.precision), - maxLabelPos = chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(maxValueString).width - 2, - minLabelPos = chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(minValueString).width - 2; - context.fillStyle = chartOptions.labels.fillStyle; - context.fillText(maxValueString, maxLabelPos, chartOptions.labels.fontSize); - context.fillText(minValueString, minLabelPos, dimensions.height - 2); - } - - // Display intermediate y axis labels along y-axis to the left of the chart - if ( chartOptions.labels.showIntermediateLabels - && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max) - && chartOptions.grid.verticalSections > 0) { - // show a label above every vertical section divider - var step = (this.valueRange.max - this.valueRange.min) / chartOptions.grid.verticalSections; - var stepPixels = dimensions.height / chartOptions.grid.verticalSections; - for (var v = 0; v < chartOptions.grid.verticalSections; v++) { - var gy = dimensions.height - Math.round(v * stepPixels); - if (chartOptions.grid.sharpLines) { - gy -= 0.5; - } - var yValue = (this.valueRange.min + (v * step)).toPrecision(chartOptions.labels.precision); - context.fillStyle = chartOptions.labels.fillStyle; - context.fillText(yValue, 0, gy - chartOptions.grid.lineWidth); - } - } - - // Display timestamps along x-axis at the bottom of the chart. - if (chartOptions.timestampFormatter && chartOptions.grid.millisPerLine > 0) { - var textUntilX = chartOptions.scrollBackwards - ? context.measureText(minValueString).width - : dimensions.width - context.measureText(minValueString).width + 4; - for (var t = time - (time % chartOptions.grid.millisPerLine); - t >= oldestValidTime; - t -= chartOptions.grid.millisPerLine) { - var gx = timeToXPixel(t); - // Only draw the timestamp if it won't overlap with the previously drawn one. - if ((!chartOptions.scrollBackwards && gx < textUntilX) || (chartOptions.scrollBackwards && gx > textUntilX)) { - // Formats the timestamp based on user specified formatting function - // SmoothieChart.timeFormatter function above is one such formatting option - var tx = new Date(t), - ts = chartOptions.timestampFormatter(tx), - tsWidth = context.measureText(ts).width; - - textUntilX = chartOptions.scrollBackwards - ? gx + tsWidth + 2 - : gx - tsWidth - 2; - - context.fillStyle = chartOptions.labels.fillStyle; - if(chartOptions.scrollBackwards) { - context.fillText(ts, gx, dimensions.height - 2); - } else { - context.fillText(ts, gx - tsWidth, dimensions.height - 2); - } - } - } - } - - context.restore(); // See .save() above. - }; - - // Sample timestamp formatting function - SmoothieChart.timeFormatter = function(date) { - function pad2(number) { return (number < 10 ? '0' : '') + number } - return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds()); - }; - - exports.TimeSeries = TimeSeries; - exports.SmoothieChart = SmoothieChart; - -})(typeof exports === 'undefined' ? this : exports); diff --git a/src/resources/js/three.min.js b/src/resources/js/three.min.js new file mode 100644 index 0000000..75e5c31 --- /dev/null +++ b/src/resources/js/three.min.js @@ -0,0 +1,953 @@ +// threejs.org/license +(function(l,ea){"object"===typeof exports&&"undefined"!==typeof module?ea(exports):"function"===typeof define&&define.amd?define(["exports"],ea):ea(l.THREE={})})(this,function(l){function ea(){}function z(a,b){this.x=a||0;this.y=b||0}function J(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];0b&&(b=a[c]);return b}function I(){Object.defineProperty(this,"id",{value:Hf+=2});this.uuid=K.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}} +function Kb(a,b,c,d,e,f){M.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new mb(a,b,c,d,e,f));this.mergeVertices()}function mb(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,S,E,If){var r=f/S,O=g/E,v=f/2,y=g/2,w=l/2;g=S+1;var x=E+1,D=f=0,G,z,A=new p;for(z=0;zm;m++){if(n=d[m])if(h=n[0],k=n[1]){t&&e.addAttribute("morphTarget"+m,t[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=k;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function Uf(a,b){var c={};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function Wa(a,b,c,d,e,f,g,h,k,m){a=void 0!==a?a:[];T.call(this,a,void 0!==b?b:301,c,d,e,f, +g,h,k,m);this.flipY=!1}function Lb(a,b,c){var d=a[0];if(0>=d||0/gm,function(a,c){a=U[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return Wd(a)})}function We(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);c< +parseInt(d);c++)a+=e.replace(/\[ i \]/g,"[ "+c+" ]");return a})}function wg(a,b,c,d,e,f,g){var h=a.context,k=d.defines,m=e.vertexShader,t=e.fragmentShader,n="SHADOWMAP_TYPE_BASIC";1===f.shadowMapType?n="SHADOWMAP_TYPE_PCF":2===f.shadowMapType&&(n="SHADOWMAP_TYPE_PCF_SOFT");var q="ENVMAP_TYPE_CUBE",u="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY";if(f.envMap){switch(d.envMap.mapping){case 301:case 302:q="ENVMAP_TYPE_CUBE";break;case 306:case 307:q="ENVMAP_TYPE_CUBE_UV";break;case 303:case 304:q= +"ENVMAP_TYPE_EQUIREC";break;case 305:q="ENVMAP_TYPE_SPHERE"}switch(d.envMap.mapping){case 302:case 304:u="ENVMAP_MODE_REFRACTION"}switch(d.combine){case 0:r="ENVMAP_BLENDING_MULTIPLY";break;case 1:r="ENVMAP_BLENDING_MIX";break;case 2:r="ENVMAP_BLENDING_ADD"}}var l=0b||a.height>b){if("data"in a){console.warn("THREE.WebGLRenderer: image in DataTexture is too big ("+a.width+"x"+a.height+").");return}b/=Math.max(a.width,a.height); +var c=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");c.width=Math.floor(a.width*b);c.height=Math.floor(a.height*b);c.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,c.width,c.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+c.width+"x"+c.height);return c}return a}function k(a){return K.isPowerOfTwo(a.width)&&K.isPowerOfTwo(a.height)}function m(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function t(b, +c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function n(b,c){if(!e.isWebGL2)return b;if(b===a.RGB){if(c===a.FLOAT)return a.RGB32F;if(c===a.HALF_FLOAT)return a.RGB16F;if(c===a.UNSIGNED_BYTE)return a.RGB8}if(b===a.RGBA){if(c===a.FLOAT)return a.RGBA32F;if(c===a.HALF_FLOAT)return a.RGBA16F;if(c===a.UNSIGNED_BYTE)return a.RGBA8}return b}function q(b){return 1003===b||1004===b||1005===b?a.NEAREST:a.LINEAR}function u(b){b=b.target;b.removeEventListener("dispose",u); +a:{var c=d.get(b);if(b.image&&c.__image__webglTextureCube)a.deleteTexture(c.__image__webglTextureCube);else{if(void 0===c.__webglInit)break a;a.deleteTexture(c.__webglTexture)}d.remove(b)}b.isVideoTexture&&delete G[b.id];g.memory.textures--}function l(b){b=b.target;b.removeEventListener("dispose",l);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]), +c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function v(b,q){var l=d.get(b);if(b.isVideoTexture){var r=b.id,v=g.render.frame;G[r]!==v&&(G[r]=v,b.update())}if(0w;w++)v[w]=q||r?r?b.image[w].image:b.image[w]:h(b.image[w],e.maxCubemapSize);var y=v[0],O=k(y),x=f.convert(b.format),D=f.convert(b.type),G=n(x,D);p(a.TEXTURE_CUBE_MAP,b,O);for(w=0;6>w;w++)if(q)for(var S,z=v[w].mipmaps,A=0,B=z.length;Aq;q++)e.__webglFramebuffer[q]=a.createFramebuffer()}else e.__webglFramebuffer= +a.createFramebuffer();if(h){c.bindTexture(a.TEXTURE_CUBE_MAP,f.__webglTexture);p(a.TEXTURE_CUBE_MAP,b.texture,n);for(q=0;6>q;q++)x(e.__webglFramebuffer[q],b,a.COLOR_ATTACHMENT0,a.TEXTURE_CUBE_MAP_POSITIVE_X+q);m(b.texture,n)&&t(a.TEXTURE_CUBE_MAP,b.texture,b.width,b.height);c.bindTexture(a.TEXTURE_CUBE_MAP,null)}else c.bindTexture(a.TEXTURE_2D,f.__webglTexture),p(a.TEXTURE_2D,b.texture,n),x(e.__webglFramebuffer,b,a.COLOR_ATTACHMENT0,a.TEXTURE_2D),m(b.texture,n)&&t(a.TEXTURE_2D,b.texture,b.width,b.height), +c.bindTexture(a.TEXTURE_2D,null);if(b.depthBuffer){e=d.get(b);f=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(f)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&& +b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);v(b.depthTexture,0);e=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_ATTACHMENT,a.TEXTURE_2D,e,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.TEXTURE_2D,e,0);else throw Error("Unknown depthTexture format"); +}else if(f)for(e.__webglDepthbuffer=[],f=0;6>f;f++)a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer[f]),e.__webglDepthbuffer[f]=a.createRenderbuffer(),w(e.__webglDepthbuffer[f],b);else a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer),e.__webglDepthbuffer=a.createRenderbuffer(),w(e.__webglDepthbuffer,b);a.bindFramebuffer(a.FRAMEBUFFER,null)}};this.updateRenderTargetMipmap=function(b){var e=b.texture,f=k(b);if(m(e,f)){f=b.isWebGLRenderTargetCube?a.TEXTURE_CUBE_MAP:a.TEXTURE_2D;var g=d.get(e).__webglTexture; +c.bindTexture(f,g);t(f,e,b.width,b.height);c.bindTexture(f,null)}}}function Ze(a,b,c){return{convert:function(d){if(1E3===d)return a.REPEAT;if(1001===d)return a.CLAMP_TO_EDGE;if(1002===d)return a.MIRRORED_REPEAT;if(1003===d)return a.NEAREST;if(1004===d)return a.NEAREST_MIPMAP_NEAREST;if(1005===d)return a.NEAREST_MIPMAP_LINEAR;if(1006===d)return a.LINEAR;if(1007===d)return a.LINEAR_MIPMAP_NEAREST;if(1008===d)return a.LINEAR_MIPMAP_LINEAR;if(1009===d)return a.UNSIGNED_BYTE;if(1017===d)return a.UNSIGNED_SHORT_4_4_4_4; +if(1018===d)return a.UNSIGNED_SHORT_5_5_5_1;if(1019===d)return a.UNSIGNED_SHORT_5_6_5;if(1010===d)return a.BYTE;if(1011===d)return a.SHORT;if(1012===d)return a.UNSIGNED_SHORT;if(1013===d)return a.INT;if(1014===d)return a.UNSIGNED_INT;if(1015===d)return a.FLOAT;if(1016===d){if(c.isWebGL2)return a.HALF_FLOAT;var e=b.get("OES_texture_half_float");if(null!==e)return e.HALF_FLOAT_OES}if(1021===d)return a.ALPHA;if(1022===d)return a.RGB;if(1023===d)return a.RGBA;if(1024===d)return a.LUMINANCE;if(1025=== +d)return a.LUMINANCE_ALPHA;if(1026===d)return a.DEPTH_COMPONENT;if(1027===d)return a.DEPTH_STENCIL;if(100===d)return a.FUNC_ADD;if(101===d)return a.FUNC_SUBTRACT;if(102===d)return a.FUNC_REVERSE_SUBTRACT;if(200===d)return a.ZERO;if(201===d)return a.ONE;if(202===d)return a.SRC_COLOR;if(203===d)return a.ONE_MINUS_SRC_COLOR;if(204===d)return a.SRC_ALPHA;if(205===d)return a.ONE_MINUS_SRC_ALPHA;if(206===d)return a.DST_ALPHA;if(207===d)return a.ONE_MINUS_DST_ALPHA;if(208===d)return a.DST_COLOR;if(209=== +d)return a.ONE_MINUS_DST_COLOR;if(210===d)return a.SRC_ALPHA_SATURATE;if(33776===d||33777===d||33778===d||33779===d)if(e=b.get("WEBGL_compressed_texture_s3tc"),null!==e){if(33776===d)return e.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===d)return e.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===d)return e.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===d)return e.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===d||35841===d||35842===d||35843===d)if(e=b.get("WEBGL_compressed_texture_pvrtc"),null!==e){if(35840===d)return e.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; +if(35841===d)return e.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===d)return e.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===d)return e.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===d&&(e=b.get("WEBGL_compressed_texture_etc1"),null!==e))return e.COMPRESSED_RGB_ETC1_WEBGL;if(37808===d||37809===d||37810===d||37811===d||37812===d||37813===d||37814===d||37815===d||37816===d||37817===d||37818===d||37819===d||37820===d||37821===d)if(e=b.get("WEBGL_compressed_texture_astc"),null!==e)return d;if(103===d||104=== +d){if(c.isWebGL2){if(103===d)return a.MIN;if(104===d)return a.MAX}e=b.get("EXT_blend_minmax");if(null!==e){if(103===d)return e.MIN_EXT;if(104===d)return e.MAX_EXT}}if(1020===d){if(c.isWebGL2)return a.UNSIGNED_INT_24_8;e=b.get("WEBGL_depth_texture");if(null!==e)return e.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Mb(){B.call(this);this.type="Group"}function X(a,b,c,d){Pa.call(this);this.type="PerspectiveCamera";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3; +this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=0;this.updateProjectionMatrix()}function Ac(a){X.call(this);this.cameras=a||[]}function $e(a){function b(){return null!==e&&!0===e.isPresenting}function c(){if(b()){var c=e.getEyeParameters("left"),f=c.renderWidth;c=c.renderHeight;w=a.getPixelRatio();x=a.getSize();a.setDrawingBufferSize(2*f,c,1);D.start()}else d.enabled&&a.setDrawingBufferSize(x.width,x.height,w),D.stop()}var d=this,e=null,f=null,g=null,h=[], +k=new J,m=new J,t="stage";"undefined"!==typeof window&&"VRFrameData"in window&&(f=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var n=new J,q=new ha,u=new p,l=new X;l.bounds=new aa(0,0,.5,1);l.layers.enable(1);var v=new X;v.bounds=new aa(.5,0,.5,1);v.layers.enable(2);var y=new Ac([l,v]);y.layers.enable(1);y.layers.enable(2);var x,w,G=[];this.enabled=!1;this.getController=function(a){var b=h[a];void 0===b&&(b=new Mb,b.matrixAutoUpdate=!1,b.visible=!1,h[a]=b);return b}; +this.getDevice=function(){return e};this.setDevice=function(a){void 0!==a&&(e=a);D.setContext(a)};this.setFrameOfReferenceType=function(a){t=a};this.setPoseTarget=function(a){void 0!==a&&(g=a)};this.getCamera=function(a){var b="stage"===t?1.6:0;if(null===e)return a.position.set(0,b,0),a;e.depthNear=a.near;e.depthFar=a.far;e.getFrameData(f);if("stage"===t){var c=e.stageParameters;c?k.fromArray(c.sittingToStandingTransform):k.makeTranslation(0,b,0)}b=f.pose;c=null!==g?g:a;c.matrix.copy(k);c.matrix.decompose(c.position, +c.quaternion,c.scale);null!==b.orientation&&(q.fromArray(b.orientation),c.quaternion.multiply(q));null!==b.position&&(q.setFromRotationMatrix(k),u.fromArray(b.position),u.applyQuaternion(q),c.position.add(u));c.updateMatrixWorld();if(!1===e.isPresenting)return a;l.near=a.near;v.near=a.near;l.far=a.far;v.far=a.far;y.matrixWorld.copy(a.matrixWorld);y.matrixWorldInverse.copy(a.matrixWorldInverse);l.matrixWorldInverse.fromArray(f.leftViewMatrix);v.matrixWorldInverse.fromArray(f.rightViewMatrix);m.getInverse(k); +"stage"===t&&(l.matrixWorldInverse.multiply(m),v.matrixWorldInverse.multiply(m));a=c.parent;null!==a&&(n.getInverse(a.matrixWorld),l.matrixWorldInverse.multiply(n),v.matrixWorldInverse.multiply(n));l.matrixWorld.getInverse(l.matrixWorldInverse);v.matrixWorld.getInverse(v.matrixWorldInverse);l.projectionMatrix.fromArray(f.leftProjectionMatrix);v.projectionMatrix.fromArray(f.rightProjectionMatrix);y.projectionMatrix.copy(l.projectionMatrix);a=e.getLayers();a.length&&(a=a[0],null!==a.leftBounds&&4=== +a.leftBounds.length&&l.bounds.fromArray(a.leftBounds),null!==a.rightBounds&&4===a.rightBounds.length&&v.bounds.fromArray(a.rightBounds));a:for(a=0;af.normalMatrix.determinant();ca.setMaterial(e,h);var k=q(a,c,e,f),m=!1;if(b!==d.id||H!==k.id||U!==(!0===e.wireframe))b=d.id,H=k.id,U=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(wa.update(f,d,e,k),m=!0);h=d.index;var t= +d.attributes.position;c=1;!0===e.wireframe&&(h=sa.getWireframeAttribute(d),c=2);a=xa;if(null!==h){var n=qa.get(h);a=za;a.setIndex(n)}if(m){if(d&&d.isInstancedBufferGeometry&!va.isWebGL2&&null===ia.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{ca.initAttributes();m=d.attributes;k=k.getAttributes();var l=e.defaultAttributeValues;for(O in k){var u=k[O]; +if(0<=u){var r=m[O];if(void 0!==r){var v=r.normalized,p=r.itemSize,w=qa.get(r);if(void 0!==w){var y=w.buffer,x=w.type;w=w.bytesPerElement;if(r.isInterleavedBufferAttribute){var D=r.data,G=D.stride;r=r.offset;D&&D.isInstancedInterleavedBuffer?(ca.enableAttributeAndDivisor(u,D.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=D.meshPerAttribute*D.count)):ca.enableAttribute(u);C.bindBuffer(C.ARRAY_BUFFER,y);C.vertexAttribPointer(u,p,x,v,G*w,r*w)}else r.isInstancedBufferAttribute?(ca.enableAttributeAndDivisor(u, +r.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=r.meshPerAttribute*r.count)):ca.enableAttribute(u),C.bindBuffer(C.ARRAY_BUFFER,y),C.vertexAttribPointer(u,p,x,v,0,0)}}else if(void 0!==l&&(v=l[O],void 0!==v))switch(v.length){case 2:C.vertexAttrib2fv(u,v);break;case 3:C.vertexAttrib3fv(u,v);break;case 4:C.vertexAttrib4fv(u,v);break;default:C.vertexAttrib1fv(u,v)}}}ca.disableUnusedAttributes()}null!==h&&C.bindBuffer(C.ELEMENT_ARRAY_BUFFER,n.buffer)}n=Infinity;null!==h?n=h.count: +void 0!==t&&(n=t.count);h=d.drawRange.start*c;t=null!==g?g.start*c:0;var O=Math.max(h,t);g=Math.max(0,Math.min(n,h+d.drawRange.count*c,t+(null!==g?g.count*c:Infinity))-1-O+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)ca.setLineWidth(e.wireframeLinewidth*(null===L?W:1)),a.setMode(C.LINES);else switch(f.drawMode){case 0:a.setMode(C.TRIANGLES);break;case 1:a.setMode(C.TRIANGLE_STRIP);break;case 2:a.setMode(C.TRIANGLE_FAN)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),ca.setLineWidth(e*(null===L?W:1)), +f.isLineSegments?a.setMode(C.LINES):f.isLineLoop?a.setMode(C.LINE_LOOP):a.setMode(C.LINE_STRIP)):f.isPoints?a.setMode(C.POINTS):f.isSprite&&a.setMode(C.TRIANGLES);d&&d.isInstancedBufferGeometry?0=va.maxTextures&&console.warn("THREE.WebGLRenderer: Trying to use "+a+" texture units while this GPU supports only "+ +va.maxTextures);fa+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTarget&&(a||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);ja.setTexture2D(b,c)}}();this.setTexture=function(){var a=!1;return function(b,c){a||(console.warn("THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead."),a=!0);ja.setTexture2D(b,c)}}();this.setTextureCube=function(){var a= +!1;return function(b,c){b&&b.isWebGLRenderTargetCube&&(a||(console.warn("THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);b&&b.isCubeTexture||Array.isArray(b.image)&&6===b.image.length?ja.setTextureCube(b,c):ja.setTextureCubeDynamic(b,c)}}();this.setFramebuffer=function(a){F=a};this.getRenderTarget=function(){return L};this.setRenderTarget=function(a){(L=a)&&void 0===Ca.get(a).__webglFramebuffer&&ja.setupRenderTarget(a); +var b=F,c=!1;a?(b=Ca.get(a).__webglFramebuffer,a.isWebGLRenderTargetCube&&(b=b[a.activeCubeFace],c=!0),T.copy(a.viewport),zc.copy(a.scissor),Y=a.scissorTest):(T.copy(cb).multiplyScalar(W),zc.copy(ha).multiplyScalar(W),Y=ra);M!==b&&(C.bindFramebuffer(C.FRAMEBUFFER,b),M=b);ca.viewport(T);ca.scissor(zc);ca.setScissorTest(Y);c&&(c=Ca.get(a.texture),C.framebufferTexture2D(C.FRAMEBUFFER,C.COLOR_ATTACHMENT0,C.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,c.__webglTexture,a.activeMipMapLevel))};this.readRenderTargetPixels= +function(a,b,c,d,e,f){if(a&&a.isWebGLRenderTarget){var g=Ca.get(a).__webglFramebuffer;if(g){var h=!1;g!==M&&(C.bindFramebuffer(C.FRAMEBUFFER,g),h=!0);try{var k=a.texture,m=k.format,t=k.type;1023!==m&&ea.convert(m)!==C.getParameter(C.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):1009===t||ea.convert(t)===C.getParameter(C.IMPLEMENTATION_COLOR_READ_TYPE)||1015===t&&(va.isWebGL2||ia.get("OES_texture_float")|| +ia.get("WEBGL_color_buffer_float"))||1016===t&&(va.isWebGL2?ia.get("EXT_color_buffer_float"):ia.get("EXT_color_buffer_half_float"))?C.checkFramebufferStatus(C.FRAMEBUFFER)===C.FRAMEBUFFER_COMPLETE?0<=b&&b<=a.width-d&&0<=c&&c<=a.height-e&&C.readPixels(b,c,d,e,ea.convert(m),ea.convert(t),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&& +C.bindFramebuffer(C.FRAMEBUFFER,M)}}}else console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.")};this.copyFramebufferToTexture=function(a,b,c){var d=b.image.width,e=b.image.height,f=ea.convert(b.format);this.setTexture2D(b,0);C.copyTexImage2D(C.TEXTURE_2D,c||0,f,a.x,a.y,d,e,0)};this.copyTextureToTexture=function(a,b,c,d){var e=b.image.width,f=b.image.height,g=ea.convert(c.format),h=ea.convert(c.type);this.setTexture2D(c,0);b.isDataTexture?C.texSubImage2D(C.TEXTURE_2D, +d||0,a.x,a.y,e,f,g,h,b.image.data):C.texSubImage2D(C.TEXTURE_2D,d||0,a.x,a.y,g,h,b.image)}}function Nb(a,b){this.name="";this.color=new F(a);this.density=void 0!==b?b:2.5E-4}function Ob(a,b,c){this.name="";this.color=new F(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3}function rd(){B.call(this);this.type="Scene";this.overrideMaterial=this.fog=this.background=null;this.autoUpdate=!0}function qb(a,b){this.array=a;this.stride=b;this.count=void 0!==a?a.length/b:0;this.dynamic=!1;this.updateRange= +{offset:0,count:-1};this.version=0}function Bc(a,b,c,d){this.data=a;this.itemSize=b;this.offset=c;this.normalized=!0===d}function eb(a){H.call(this);this.type="SpriteMaterial";this.color=new F(16777215);this.map=null;this.rotation=0;this.sizeAttenuation=!0;this.lights=!1;this.transparent=!0;this.setValues(a)}function Cc(a){B.call(this);this.type="Sprite";if(void 0===Pb){Pb=new I;var b=new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]);b=new qb(b,5);Pb.setIndex([0,1,2,0,2,3]); +Pb.addAttribute("position",new Bc(b,3,0,!1));Pb.addAttribute("uv",new Bc(b,2,3,!1))}this.geometry=Pb;this.material=void 0!==a?a:new eb;this.center=new z(.5,.5)}function Dc(){B.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function Ec(a,b){a=a||[];this.bones=a.slice(0);this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton boneInverses is the wrong length."), +this.boneInverses=[],a=0,b=this.bones.length;ac;c++){var n=t[h[c]];var q=t[h[(c+1)%3]];f[0]=Math.min(n,q);f[1]=Math.max(n,q);n=f[0]+","+f[1];void 0===g[n]&&(g[n]={index1:f[0],index2:f[1]})}}for(n in g)m=g[n],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new p,null!==a.index){k=a.attributes.position;t=a.index;var l=a.groups;0===l.length&&(l=[{start:0, +count:t.count,materialIndex:0}]);a=0;for(e=l.length;ac;c++)n=t.getX(m+c),q=t.getX(m+(c+1)%3),f[0]=Math.min(n,q),f[1]=Math.max(n,q),n=f[0]+","+f[1],void 0===g[n]&&(g[n]={index1:f[0],index2:f[1]});for(n in g)m=g[n],h.fromBufferAttribute(k,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(k,m.index2),b.push(h.x,h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x, +h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new A(b,3))}function Hc(a,b,c){M.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Tb(a,b,c));this.mergeVertices()}function Tb(a,b,c){I.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new p,k=new p,m=new p,t=new p,n=new p,q,l;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter."); +var r=b+1;for(q=0;q<=c;q++){var v=q/c;for(l=0;l<=b;l++){var y=l/b;a(y,v,k);e.push(k.x,k.y,k.z);0<=y-1E-5?(a(y-1E-5,v,m),t.subVectors(k,m)):(a(y+1E-5,v,m),t.subVectors(m,k));0<=v-1E-5?(a(y,v-1E-5,m),n.subVectors(k,m)):(a(y,v+1E-5,m),n.subVectors(m,k));h.crossVectors(t,n).normalize();f.push(h.x,h.y,h.z);g.push(y,v)}}for(q=0;qd&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}I.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a, +indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new p,d=new p,g=new p,h=0;he&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",new A(h,3));this.addAttribute("normal",new A(h.slice(),3));this.addAttribute("uv",new A(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Jc(a, +b){M.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Ub(a,b));this.mergeVertices()}function Ub(a,b){la.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Kc(a,b){M.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new rb(a,b));this.mergeVertices()}function rb(a,b){la.call(this,[1,0,0, +-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Lc(a,b){M.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Vb(a,b));this.mergeVertices()}function Vb(a,b){var c=(1+Math.sqrt(5))/2;la.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5, +11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Mc(a,b){M.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Wb(a,b));this.mergeVertices()}function Wb(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;la.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c, +0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Nc(a,b,c,d,e,f){M.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d, +closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new Xb(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function Xb(a,b,c,d,e){function f(e){t=a.getPointAt(e/b,t);var f=g.normals[e];e=g.binormals[e];for(q=0;q<=d;q++){var m=q/d*Math.PI*2,n=Math.sin(m);m=-Math.cos(m);k.x=m*f.x+n*e.x;k.y=m*f.y+n*e.y;k.z=m*f.z+n*e.z;k.normalize();r.push(k.x,k.y,k.z);h.x=t.x+c*k.x;h.y=t.y+c*k.y;h.z= +t.z+c*k.z;l.push(h.x,h.y,h.z)}}I.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new p,k=new p,m=new z,t=new p,n,q,l=[],r=[],v=[],y=[];for(n=0;n=b;e-=d)f=bf(e,a[e],a[e+1],f);f&&sb(f,f.next)&&(Qc(f),f=f.next);return f}function Rc(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!sb(a,a.next)&&0!==ma(a.prev,a,a.next))a=a.next;else{Qc(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} +function Sc(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,k=h;do null===k.z&&(k.z=$d(k.x,k.y,d,e,f)),k.prevZ=k.prev,k=k.nextZ=k.next;while(k!==h);k.prevZ.nextZ=null;k.prevZ=null;h=k;var m,t,n,l,u=1;do{k=h;var r=h=null;for(t=0;k;){t++;var v=k;for(m=n=0;mn.x?t.x>u.x?t.x:u.x:n.x>u.x?n.x:u.x,G=t.y>n.y?t.y>u.y?t.y:u.y:n.y>u.y?n.y:u.y;m=$d(t.x=m;){if(p!==r.prev&&p!==r.next&&vd(t.x,t.y,n.x,n.y,u.x,u.y,p.x,p.y)&&0<=ma(p.prev,p,p.next)){r=!1;break a}p= +p.prevZ}r=!0}}else a:if(r=a,t=r.prev,n=r,u=r.next,0<=ma(t,n,u))r=!1;else{for(m=r.next.next;m!==r.prev;){if(vd(t.x,t.y,n.x,n.y,u.x,u.y,m.x,m.y)&&0<=ma(m.prev,m,m.next)){r=!1;break a}m=m.next}r=!0}if(r)b.push(k.i/c),b.push(a.i/c),b.push(v.i/c),Qc(a),h=a=v.next;else if(a=v,a===h){if(!g)Sc(Rc(a),b,c,d,e,f,1);else if(1===g){g=b;h=c;k=a;do v=k.prev,r=k.next.next,!sb(v,r)&&cf(v,k,k.next,r)&&Tc(v,r)&&Tc(r,v)&&(g.push(v.i/h),g.push(k.i/h),g.push(r.i/h),Qc(k),Qc(k.next),k=a=r),k=k.next;while(k!==a);a=k;Sc(a, +b,c,d,e,f,2)}else if(2===g)a:{g=a;do{for(h=g.next.next;h!==g.prev;){if(k=g.i!==h.i){k=g;v=h;if(r=k.next.i!==v.i&&k.prev.i!==v.i){b:{r=k;do{if(r.i!==k.i&&r.next.i!==k.i&&r.i!==v.i&&r.next.i!==v.i&&cf(r,r.next,k,v)){r=!0;break b}r=r.next}while(r!==k);r=!1}r=!r}if(r=r&&Tc(k,v)&&Tc(v,k)){r=k;t=!1;n=(k.x+v.x)/2;v=(k.y+v.y)/2;do r.y>v!==r.next.y>v&&r.next.y!==r.y&&n<(r.next.x-r.x)*(v-r.y)/(r.next.y-r.y)+r.x&&(t=!t),r=r.next;while(r!==k);r=t}k=r}if(k){a=df(g,h);g=Rc(g,g.next);a=Rc(a,a.next);Sc(g,b,c,d,e, +f);Sc(a,b,c,d,e,f);break a}h=h.next}g=g.next}while(g!==a)}break}}}}function Mg(a,b){return a.x-b.x}function Ng(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f=g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&vd(eh.x)&&Tc(c,a)&&(h=c,m=t)}c=c.next}return h}function $d(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b|b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function Og(a){var b=a,c=a;do b.xma(a.prev,a,a.next)?0<=ma(a,b,a.next)&&0<=ma(a,a.prev,b):0>ma(a,b,a.prev)||0>ma(a,a.next,b)}function df(a,b){var c=new ae(a.i,a.x,a.y),d=new ae(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev= +c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function bf(a,b,c,d){a=new ae(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function Qc(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ=a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function ae(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function ef(a){var b=a.length;2Number.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/k;b=b.y+d/k; +g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new z(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new z(f/e,d/e)}function h(a,b){for(N=a.length;0<=--N;){var c=N;var f=N-1;0>f&&(f=a.length-1);var g,h=w+2*E;for(g=0;gt;t++){var n=m[f[t]];var l=m[f[(t+1)%3]];d[0]=Math.min(n,l);d[1]=Math.max(n,l);n=d[0]+","+d[1];void 0===e[n]?e[n]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[n].face2=h}for(n in e)if(d=e[n],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2], +c.push(f.x,f.y,f.z);this.addAttribute("position",new A(c,3))}function xb(a,b,c,d,e,f,g,h){M.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new Ya(a,b,c,d,e,f,g,h));this.mergeVertices()}function Ya(a,b,c,d,e,f,g,h){function k(c){var e,f=new z,k=new p,q=0,v=!0===c?a:b,w=!0===c?1:-1;var A=r;for(e=1;e<=d;e++)n.push(0,y*w,0),l.push(0,w,0),u.push(.5,.5),r++;var B= +r;for(e=0;e<=d;e++){var P=e/d*h+g,I=Math.cos(P);P=Math.sin(P);k.x=v*P;k.y=y*w;k.z=v*I;n.push(k.x,k.y,k.z);l.push(0,w,0);f.x=.5*I+.5;f.y=.5*P*w+.5;u.push(f.x,f.y);r++}for(e=0;ethis.duration&&this.resetDuration()}function Qg(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return gc;case "vector":case "vector2":case "vector3":case "vector4":return hc; +case "color":return Id;case "quaternion":return ed;case "bool":case "boolean":return Hd;case "string":return Kd}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function Rg(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=Qg(a.type);if(void 0===a.times){var c=[],d=[];qa.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function Ld(a){this.manager=void 0!== +a?a:wa;this.textures={}}function fe(a){this.manager=void 0!==a?a:wa}function ic(){}function ge(a){"boolean"===typeof a&&(console.warn("THREE.JSONLoader: showStatus parameter has been removed from constructor."),a=void 0);this.manager=void 0!==a?a:wa;this.withCredentials=!1}function lf(a){this.manager=void 0!==a?a:wa;this.texturePath=""}function he(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported."); +this.manager=void 0!==a?a:wa;this.options=void 0}function ie(){this.type="ShapePath";this.color=new F;this.subPaths=[];this.currentPath=null}function je(a){this.type="Font";this.data=a}function mf(a){this.manager=void 0!==a?a:wa}function ke(a){this.manager=void 0!==a?a:wa}function nf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new X;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new X;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate= +!1}function fd(a,b,c){B.call(this);this.type="CubeCamera";var d=new X(90,1,a,b);d.up.set(0,-1,0);d.lookAt(new p(1,0,0));this.add(d);var e=new X(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new p(-1,0,0));this.add(e);var f=new X(90,1,a,b);f.up.set(0,0,1);f.lookAt(new p(0,1,0));this.add(f);var g=new X(90,1,a,b);g.up.set(0,0,-1);g.lookAt(new p(0,-1,0));this.add(g);var h=new X(90,1,a,b);h.up.set(0,-1,0);h.lookAt(new p(0,0,1));this.add(h);var k=new X(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new p(0,0,-1));this.add(k); +this.renderTarget=new Ib(c,c,{format:1022,magFilter:1006,minFilter:1006});this.renderTarget.texture.name="CubeCamera";this.update=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=this.renderTarget,m=c.texture.generateMipmaps;c.texture.generateMipmaps=!1;c.activeCubeFace=0;a.render(b,d,c);c.activeCubeFace=1;a.render(b,e,c);c.activeCubeFace=2;a.render(b,f,c);c.activeCubeFace=3;a.render(b,g,c);c.activeCubeFace=4;a.render(b,h,c);c.texture.generateMipmaps=m;c.activeCubeFace=5;a.render(b, +k,c);a.setRenderTarget(null)};this.clear=function(a,b,c,d){for(var e=this.renderTarget,f=0;6>f;f++)e.activeCubeFace=f,a.setRenderTarget(e),a.clear(b,c,d);a.setRenderTarget(null)}}function le(){B.call(this);this.type="AudioListener";this.context=me.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null}function jc(a){B.call(this);this.type="Audio";this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay= +!1;this.buffer=null;this.loop=!1;this.offset=this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function ne(a){jc.call(this,a);this.panner=this.context.createPanner();this.panner.connect(this.gain)}function oe(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function pe(a,b,c){this.binding=a;this.valueSize= +c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function of(a,b,c){c=c||sa.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function sa(a,b,c){this.path=b;this.parsedPath=c||sa.parseTrackName(b);this.node=sa.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function pf(){this.uuid= +K.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function qf(a,b,c){this._mixer=a;this._clip=b;this._localRoot= +c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity; +this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function qe(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function Md(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function re(){I.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function se(a,b,c){qb.call(this,a,b);this.meshPerAttribute=c||1}function te(a,b,c,d){"number"=== +typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));Q.call(this,a,b,c);this.meshPerAttribute=d||1}function rf(a,b,c,d){this.ray=new ob(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function sf(a, +b){return a.distance-b.distance}function ue(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new A(b,3));b=new V({fog:!1});this.cone=new Z(a,b);this.add(this.cone); +this.update()}function wf(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;ca?-1:0b;b++)a[b]=(16>b?"0":"")+b.toString(16); +return function(){var b=4294967295*Math.random()|0,d=4294967295*Math.random()|0,e=4294967295*Math.random()|0,f=4294967295*Math.random()|0;return(a[b&255]+a[b>>8&255]+a[b>>16&255]+a[b>>24&255]+"-"+a[d&255]+a[d>>8&255]+"-"+a[d>>16&15|64]+a[d>>24&255]+"-"+a[e&63|128]+a[e>>8&255]+"-"+a[e>>16&255]+a[e>>24&255]+a[f&255]+a[f>>8&255]+a[f>>16&255]+a[f>>24&255]).toUpperCase()}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c, +d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(a){return a*K.DEG2RAD},radToDeg:function(a){return a* +K.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(z.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(z.prototype,{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y= +this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, +b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= +a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a=new z,b=new z;return function(c,d){a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| +1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x* +a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= +this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a, +b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(J.prototype,{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,k,m,t,n,l,u,r,p){var q=this.elements; +q[0]=a;q[4]=b;q[8]=c;q[12]=d;q[1]=e;q[5]=f;q[9]=g;q[13]=h;q[2]=k;q[6]=m;q[10]=t;q[14]=n;q[3]=l;q[7]=u;q[11]=r;q[15]=p;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new J).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b= +this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a=new p;return function(b){var c=this.elements,d=b.elements,e=1/a.setFromMatrixColumn(b,0).length(),f=1/a.setFromMatrixColumn(b,1).length();b=1/a.setFromMatrixColumn(b, +2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[3]=0;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]*f;c[7]=0;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]*b;c[11]=0;c[12]=0;c[13]=0;c[14]=0;c[15]=1;return this}}(),makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a= +f*h;var k=f*e,m=c*h,t=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+m*d;b[5]=a-t*d;b[9]=-c*g;b[2]=t-a*d;b[6]=m+k*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,k=g*e,m=d*h,t=d*e,b[0]=a+t*c,b[4]=m*c-k,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=k*c-m,b[6]=t+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,k=g*e,m=d*h,t=d*e,b[0]=a-t*c,b[4]=-f*e,b[8]=m+k*c,b[1]=k+m*c,b[5]=f*h,b[9]=t-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,k=f*e,m=c*h,t=c*e,b[0]=g*h,b[4]=m*d-k,b[8]=a*d+t,b[1]=g*e,b[5]=t*d+a,b[9]=k*d-m,b[2]=-d,b[6]=c* +g,b[10]=f*g):"YZX"===a.order?(a=f*g,k=f*d,m=c*g,t=c*d,b[0]=g*h,b[4]=t-a*e,b[8]=m*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+m,b[10]=a-t*e):"XZY"===a.order&&(a=f*g,k=f*d,m=c*g,t=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+t,b[5]=f*h,b[9]=k*e-m,b[2]=m*e-k,b[6]=c*h,b[10]=t*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(){var a=new p(0,0,0),b=new p(1,1,1);return function(c){return this.compose(a,c,b)}}(),lookAt:function(){var a=new p,b=new p, +c=new p;return function(d,e,f){var g=this.elements;c.subVectors(d,e);0===c.lengthSq()&&(c.z=1);c.normalize();a.crossVectors(f,c);0===a.lengthSq()&&(1===Math.abs(f.z)?c.x+=1E-4:c.z+=1E-4,c.normalize(),a.crossVectors(f,c));a.normalize();b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."), +this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],k=c[5],m=c[9],t=c[13],n=c[2],l=c[6],u=c[10],r=c[14],p=c[3],y=c[7],x=c[11];c=c[15];var w=d[0],G=d[4],D=d[8],O=d[12],z=d[1],E=d[5],A=d[9],B=d[13],I=d[2],H=d[6],F=d[10],L=d[14],M=d[3],J=d[7],K=d[11];d=d[15];b[0]=a*w+e*z+f*I+g*M;b[4]=a*G+e*E+f*H+g*J;b[8]=a*D+e*A+f*F+ +g*K;b[12]=a*O+e*B+f*L+g*d;b[1]=h*w+k*z+m*I+t*M;b[5]=h*G+k*E+m*H+t*J;b[9]=h*D+k*A+m*F+t*K;b[13]=h*O+k*B+m*L+t*d;b[2]=n*w+l*z+u*I+r*M;b[6]=n*G+l*E+u*H+r*J;b[10]=n*D+l*A+u*F+r*K;b[14]=n*O+l*B+u*L+r*d;b[3]=p*w+y*z+x*I+c*M;b[7]=p*G+y*E+x*H+c*J;b[11]=p*D+y*A+x*F+c*K;b[15]=p*O+y*B+x*L+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(){var a= +new p;return function(b){for(var c=0,d=b.count;cthis.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.copy(this);c=1/g;f=1/h;var m=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); +var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*k;g[9]=0;g[13]=-((c+d)*k);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements; +a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});Object.assign(ha,{slerp:function(a,b,c,d){return c.copy(a).slerp(b, +d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],k=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var l=e[f+1],n=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==l||m!==n){f=1-g;var q=h*d+k*l+m*n+c*e,u=0<=q?1:-1,r=1-q*q;r>Number.EPSILON&&(r=Math.sqrt(r),q=Math.atan2(r,q*u),f=Math.sin(f*q)/r,g=Math.sin(g*q)/r);u*=g;h=h*f+d*u;k=k*f+l*u;m=m*f+n*u;c=c*f+e*u;f===1-g&&(g=1/Math.sqrt(h*h+k*k+m*m+c*c),h*=g,k*=g,m*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=m;a[b+3]=c}});Object.defineProperties(ha.prototype,{x:{get:function(){return this._x}, +set:function(a){this._x=a;this.onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this.onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this.onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this.onChangeCallback()}}});Object.assign(ha.prototype,{set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z, +this._w)},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this.onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),k=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"YXZ"===a?(this._x=c*k*f+ +h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"ZXY"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"ZYX"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"YZX"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f-c*d*e):"XZY"===a&&(this._x=c*k*f-h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f+c*d*e);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a, +b){b/=2;var c=Math.sin(b);this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= +.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a=new p,b;return function(c,d){void 0===a&&(a=new p);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;return this.normalize()}}(),angleTo:function(a){return 2*Math.acos(Math.abs(K.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, +b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a= +this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; +var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this.onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* +f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize();a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback(); +return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}});Object.assign(p.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this}, +setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."), +this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z; +return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x* +b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a=new ha;return function(b){b&&b.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a=new ha;return function(b,c){return this.applyQuaternion(a.setFromAxisAngle(b,c))}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]* +b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-m*-f;this.y=k*a+b*-f+m*-e-h*-g;this.z=m*a+b* +-g+h*-f-k*-e;return this},project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(){var a=new J;return function(b){return this.applyMatrix4(a.getInverse(b.projectionMatrix)).applyMatrix4(b.matrixWorld)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/= +a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(){var a=new p,b=new p; +return function(c,d){a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z); +return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+ +Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a, +b)):this.crossVectors(this,a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a=new p;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new p;return function(b){return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a= +this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(K.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x= +d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a, +2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."); +this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});Object.assign(na.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]= +a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(){var a=new p;return function(b){for(var c=0,d=b.count;cc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8]; +return a}});var gb={getDataURL:function(a){if(a instanceof HTMLCanvasElement)var b=a;else{b=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");b.width=a.width;b.height=a.height;var c=b.getContext("2d");a instanceof ImageData?c.putImageData(a,0,0):c.drawImage(a,0,0,a.width,a.height)}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(T.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(aa.prototype,{isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y= +a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x, +this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this}, +addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*= +a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/ +b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var k=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-k)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+k)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI;b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+k)/4;b>f&&b>m?.01>b?(k=0,c=h=.707106781):(k=Math.sqrt(b),h=c/k,c=d/k):f>m?.01>f?(k=.707106781,h=0,c=.707106781): +(h=Math.sqrt(f),k=c/h,c=g/h):.01>m?(h=k=.707106781,c=0):(c=Math.sqrt(m),k=d/c,h=g/c);this.set(k,h,c,a);return this}a=Math.sqrt((k-g)*(k-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(k-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z, +a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new aa,b=new aa);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b, +c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y): +Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},manhattanLength:function(){return Math.abs(this.x)+ +Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0=== +b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});hb.prototype=Object.assign(Object.create(ea.prototype),{constructor:hb,isWebGLRenderTarget:!0, +setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}}); +Ib.prototype=Object.create(hb.prototype);Ib.prototype.constructor=Ib;Ib.prototype.isWebGLRenderTargetCube=!0;ib.prototype=Object.create(T.prototype);ib.prototype.constructor=ib;ib.prototype.isDataTexture=!0;Object.assign(Ua.prototype,{isBox3:!0,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromArray:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.length;h +e&&(e=m);l>f&&(f=l);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.count;he&&(e=m);l>f&&(f=l);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new p);return b.set((a.x-this.min.x)/(this.max.x- +this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(){var a=new p;return function(b){this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){if(0=a.constant},intersectsTriangle:function(){function a(a){var e;var f=0;for(e=a.length-3;f<=e;f+=3){h.fromArray(a,f);var g=m.x*Math.abs(h.x)+m.y*Math.abs(h.y)+m.z*Math.abs(h.z),k=b.dot(h),l=c.dot(h), +n=d.dot(h);if(Math.max(-Math.max(k,l,n),Math.min(k,l,n))>g)return!1}return!0}var b=new p,c=new p,d=new p,e=new p,f=new p,g=new p,h=new p,k=new p,m=new p,l=new p;return function(h){if(this.isEmpty())return!1;this.getCenter(k);m.subVectors(this.max,k);b.subVectors(h.a,k);c.subVectors(h.b,k);d.subVectors(h.c,k);e.subVectors(c,b);f.subVectors(d,c);g.subVectors(b,d);h=[0,-e.z,e.y,0,-f.z,f.y,0,-g.z,g.y,e.z,0,-e.x,f.z,0,-f.x,g.z,0,-g.x,-e.y,e.x,0,-f.y,f.x,0,-g.y,g.x,0];if(!a(h))return!1;h=[1,0,0,0,1,0,0, +0,1];if(!a(h))return!1;l.crossVectors(e,f);h=[l.x,l.y,l.z];return a(h)}}(),clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new p);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new p;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new p;return function(b){void 0===b&&(console.warn("THREE.Box3: .getBoundingSphere() target is now required"),b=new Ea); +this.getCenter(b.center);b.radius=.5*this.getSize(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new p,new p,new p,new p,new p,new p,new p,new p];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b); +a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& +a.max.equals(this.max)}});Object.assign(Ea.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=new Ua;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).getCenter(d);for(var e=c=0,f=b.length;e= +this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a); +void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new p);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new Ua);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this}, +translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});Object.assign(Oa.prototype,{set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new p,b=new p;return function(c,d,e){d= +a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d,c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)- +a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new p);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(){var a=new p;return function(b,c){void 0===c&&(console.warn("THREE.Plane: .intersectLine() target is now required"),c=new p);var d=b.delta(a),e=this.normal.dot(d);if(0===e){if(0===this.distanceToPoint(b.start))return c.copy(b.start)}else if(e=-(b.start.dot(this.normal)+this.constant)/ +e,!(0>e||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],m=c[7],l=c[8],n=c[9],q=c[10],p=c[11],r=c[12],v=c[13],y=c[14];c=c[15];b[0].setComponents(f-a,m-g,p-l,c-r).normalize();b[1].setComponents(f+a,m+g,p+l,c+r).normalize();b[2].setComponents(f+d,m+h,p+n,c+v).normalize();b[3].setComponents(f-d,m-h,p-n,c- +v).normalize();b[4].setComponents(f-e,m-k,p-q,c-y).normalize();b[5].setComponents(f+e,m+k,p+q,c+y).normalize();return this},intersectsObject:function(){var a=new Ea;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSprite:function(){var a=new Ea;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(), +intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)d;d++){var e=c[d];a.x=0e.distanceToPoint(a))return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var U= +{alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n", +aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"\nvec3 transformed = vec3( position );\n",beginnormal_vertex:"\nvec3 objectNormal = vec3( normal );\n",bsdfs:"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n", +bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n", +clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif\n", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\n", +cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n", +defaultnormal_vertex:"vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n", +emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n",encodings_fragment:" gl_FragColor = linearToOutputTexel( gl_FragColor );\n",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}\n", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n", +envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n", +envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n", +fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif\n",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif\n",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n", +gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n", +lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n", +lights_pars_begin:"uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n", +lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n", +lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif\n", +lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif\n", +lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif\n", +logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif\n",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif\n",map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n", +map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n",map_particle_fragment:"#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif\n",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n", +metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", +morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n", +normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n#endif\n",normal_fragment_maps:"#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif\n", +packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n",dithering_fragment:"#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n",dithering_pars_fragment:"#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n", +skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n", +skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n", +specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n",tonemapping_pars_fragment:"#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n", +uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\n", +uv_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif", +uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n", +cube_vert:"varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}\n",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n", +depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}\n", +distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}\n", +equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n",equirect_vert:"varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n", +linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n", +meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}\n", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n", +points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}\n",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}\n", +sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n"}, +Ba={merge:function(a){for(var b={},c=0;c>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b, +c,d){b=K.euclideanModulo(b,1);c=K.clamp(c,0,1);d=K.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r= +Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){d=parseFloat(c[1])/ +360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}return function(b){this.r=a(b.r);this.g=a(b.g);this.b=a(b.b);return this}}(),copyLinearToSRGB:function(){function a(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}return function(b){this.r=a(b.r);this.g=a(b.g);this.b=a(b.b);return this}}(),convertSRGBToLinear:function(){this.copySRGBToLinear(this); +return this},convertLinearToSRGB:function(){this.copyLinearToSRGB(this);return this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){void 0===a&&(console.warn("THREE.Color: .getHSL() target is now required"),a={h:0,s:0,l:0});var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===e)f=g=0;else{var k=e-f;f=.5>=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c- +d)/k+(cMath.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-l,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.99999>Math.abs(n)? +(this._y=Math.atan2(-l,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-l,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(n,k),this._y=Math.atan2(g,a)):(this._x= +Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a=new J;return function(b,c,d){a.makeRotationFromQuaternion(b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new ha;return function(b){a.setFromEuler(this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x=== +this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new p(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}}); +Object.assign(Sd.prototype,{set:function(a){this.mask=1<g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;cthis.opacity&&(d.opacity=this.opacity); +!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&& +(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new p;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a= +new p,b=new p,c=new p;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),m=c.dot(this.direction),l=-c.dot(b),n=c.lengthSq(),q=Math.abs(1-k*k);if(0=-p?e<=p?(h=1/q,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*l)+n):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+n):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+n):e<=-p?(d=Math.max(0,-(-k*h+m)),e=0b)return null; +b=Math.sqrt(b-e);e=d-b;d+=b;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin); +return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null; +if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(){var a=new p;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a=new p,b=new p,c=new p,d=new p;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null; +g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});Object.assign(da,{getNormal:function(){var a=new p;return function(b,c,d,e){void 0===e&&(console.warn("THREE.Triangle: .getNormal() target is now required"),e=new p);e.subVectors(d,c);a.subVectors(b, +c);e.cross(a);b=e.lengthSq();return 0=a.x+a.y}}(),getUV:function(){var a=new p;return function(b,c,d,e,f,g,h,k){this.getBarycoord(b,c,d,e,a);k.set(0,0);k.addScaledVector(f,a.x);k.addScaledVector(g,a.y);k.addScaledVector(h,a.z);return k}}()});Object.assign(da.prototype,{set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this}, +clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){var a=new p,b=new p;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"),a=new p);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return da.getNormal(this.a, +this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new p);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return da.getBarycoord(a,this.a,this.b,this.c,b)},containsPoint:function(a){return da.containsPoint(a,this.a,this.b,this.c)},getUV:function(a,b,c,d,e){return da.getUV(a,this.a,this.b,this.c,b,c,d,e)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(){var a= +new p,b=new p,c=new p,d=new p,e=new p,f=new p;return function(g,h){void 0===h&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),h=new p);var k=this.a,m=this.b,l=this.c;a.subVectors(m,k);b.subVectors(l,k);d.subVectors(g,k);var n=a.dot(d),q=b.dot(d);if(0>=n&&0>=q)return h.copy(k);e.subVectors(g,m);var u=a.dot(e),r=b.dot(e);if(0<=u&&r<=u)return h.copy(m);var v=n*r-u*q;if(0>=v&&0<=n&&0>=u)return m=n/(n-u),h.copy(k).addScaledVector(a,m);f.subVectors(g,l);g=a.dot(f);var y= +b.dot(f);if(0<=y&&g<=y)return h.copy(l);n=g*q-n*y;if(0>=n&&0<=q&&0>=y)return v=q/(q-y),h.copy(k).addScaledVector(b,v);q=u*y-g*r;if(0>=q&&0<=r-u&&0<=g-y)return c.subVectors(l,m),v=(r-u)/(r-u+(g-y)),h.copy(m).addScaledVector(c,v);l=1/(q+n+v);m=n*l;v*=l;return h.copy(k).addScaledVector(a,m).addScaledVector(b,v)}}(),equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});ta.prototype=Object.assign(Object.create(B.prototype),{constructor:ta,isMesh:!0,setDrawMode:function(a){this.drawMode= +a},copy:function(a){B.prototype.copy.call(this,a);this.drawMode=a.drawMode;void 0!==a.morphTargetInfluences&&(this.morphTargetInfluences=a.morphTargetInfluences.slice());void 0!==a.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},a.morphTargetDictionary));return this},updateMorphTargets:function(){var a=this.geometry;if(a.isBufferGeometry){a=a.morphAttributes;var b=Object.keys(a);if(0c.far?null:{distance:b,point:v.clone(),object:a}}function b(b,c,d,e,k,m,l,t,p){f.fromBufferAttribute(k,l);g.fromBufferAttribute(k,t);h.fromBufferAttribute(k,p);if(b=a(b,c,d,e,f,g,h,r))m&&(n.fromBufferAttribute(m,l),q.fromBufferAttribute(m,t),u.fromBufferAttribute(m,p),b.uv=da.getUV(r,f,g,h,n,q,u,new z)),m=new Va(l,t,p),da.getNormal(f,g,h,m.normal),b.face=m;return b}var c=new J,d=new ob,e=new Ea,f=new p,g=new p, +h=new p,k=new p,m=new p,l=new p,n=new z,q=new z,u=new z,r=new p,v=new p;return function(t,p){var v=this.geometry,y=this.material,x=this.matrixWorld;if(void 0!==y&&(null===v.boundingSphere&&v.computeBoundingSphere(),e.copy(v.boundingSphere),e.applyMatrix4(x),!1!==t.ray.intersectsSphere(e)&&(c.getInverse(x),d.copy(t.ray).applyMatrix4(c),null===v.boundingBox||!1!==d.intersectsBox(v.boundingBox))))if(v.isBufferGeometry){var A=v.index,B=v.attributes.position,E=v.attributes.uv,I=v.groups;v=v.drawRange; +var H;if(null!==A)if(Array.isArray(y)){var F=0;for(H=I.length;Fe.far||f.push({distance:r,point:b.clone(),uv:da.getUV(b,h,k,m,l,n,q,new z),face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){B.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Dc.prototype=Object.assign(Object.create(B.prototype),{constructor:Dc, +copy:function(a){B.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ef||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}else for(g= +0,r=u.length/3-1;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k=g.vertices,m=k.length,g=0;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v, +point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});Z.prototype=Object.assign(Object.create(oa.prototype),{constructor:Z,isLineSegments:!0,computeLineDistances:function(){var a=new p,b=new p;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;fd.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:n.clone(),index:c,face:null,object:g}))}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);m/=(this.scale.x+this.scale.y+this.scale.z)/3;var l=m*m;m=new p;var n=new p;if(h.isBufferGeometry){var q= +h.index;h=h.attributes.position.array;if(null!==q){var u=q.array;q=0;for(var r=u.length;q=a.HAVE_CURRENT_DATA&& +(this.needsUpdate=!0)}});Rb.prototype=Object.create(T.prototype);Rb.prototype.constructor=Rb;Rb.prototype.isCompressedTexture=!0;Fc.prototype=Object.create(T.prototype);Fc.prototype.constructor=Fc;Fc.prototype.isCanvasTexture=!0;Gc.prototype=Object.create(T.prototype);Gc.prototype.constructor=Gc;Gc.prototype.isDepthTexture=!0;Sb.prototype=Object.create(I.prototype);Sb.prototype.constructor=Sb;Hc.prototype=Object.create(M.prototype);Hc.prototype.constructor=Hc;Tb.prototype=Object.create(I.prototype); +Tb.prototype.constructor=Tb;Ic.prototype=Object.create(M.prototype);Ic.prototype.constructor=Ic;la.prototype=Object.create(I.prototype);la.prototype.constructor=la;Jc.prototype=Object.create(M.prototype);Jc.prototype.constructor=Jc;Ub.prototype=Object.create(la.prototype);Ub.prototype.constructor=Ub;Kc.prototype=Object.create(M.prototype);Kc.prototype.constructor=Kc;rb.prototype=Object.create(la.prototype);rb.prototype.constructor=rb;Lc.prototype=Object.create(M.prototype);Lc.prototype.constructor= +Lc;Vb.prototype=Object.create(la.prototype);Vb.prototype.constructor=Vb;Mc.prototype=Object.create(M.prototype);Mc.prototype.constructor=Mc;Wb.prototype=Object.create(la.prototype);Wb.prototype.constructor=Wb;Nc.prototype=Object.create(M.prototype);Nc.prototype.constructor=Nc;Xb.prototype=Object.create(I.prototype);Xb.prototype.constructor=Xb;Oc.prototype=Object.create(M.prototype);Oc.prototype.constructor=Oc;Yb.prototype=Object.create(I.prototype);Yb.prototype.constructor=Yb;Pc.prototype=Object.create(M.prototype); +Pc.prototype.constructor=Pc;Zb.prototype=Object.create(I.prototype);Zb.prototype.constructor=Zb;var Tg={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=af(a,0,e,c,!0),g=[];if(!f)return g;var h;if(d){var k=c;d=[];var m;var l=0;for(m=b.length;l80*c){var p=h= +a[0];var r=d=a[1];for(k=c;kh&&(h=l),b>d&&(d=b);h=Math.max(h-p,d-r);h=0!==h?1/h:0}Sc(f,g,c,p,r,h);return g}},Xa={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;eXa.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];ef(a);ff(c,a);var f=a.length;b.forEach(ef);for(a=0;aMath.abs(g-k)?[new z(a,1-c),new z(h,1-d),new z(m,1-e),new z(n,1-b)]:[new z(g,1-c),new z(k,1-d),new z(l,1-e),new z(q,1-b)]}};Uc.prototype=Object.create(M.prototype);Uc.prototype.constructor=Uc;$b.prototype=Object.create(Qa.prototype);$b.prototype.constructor= +$b;Vc.prototype=Object.create(M.prototype);Vc.prototype.constructor=Vc;ub.prototype=Object.create(I.prototype);ub.prototype.constructor=ub;Wc.prototype=Object.create(M.prototype);Wc.prototype.constructor=Wc;ac.prototype=Object.create(I.prototype);ac.prototype.constructor=ac;Xc.prototype=Object.create(M.prototype);Xc.prototype.constructor=Xc;bc.prototype=Object.create(I.prototype);bc.prototype.constructor=bc;vb.prototype=Object.create(M.prototype);vb.prototype.constructor=vb;vb.prototype.toJSON=function(){var a= +M.prototype.toJSON.call(this);return hf(this.parameters.shapes,a)};wb.prototype=Object.create(I.prototype);wb.prototype.constructor=wb;wb.prototype.toJSON=function(){var a=I.prototype.toJSON.call(this);return hf(this.parameters.shapes,a)};cc.prototype=Object.create(I.prototype);cc.prototype.constructor=cc;xb.prototype=Object.create(M.prototype);xb.prototype.constructor=xb;Ya.prototype=Object.create(I.prototype);Ya.prototype.constructor=Ya;Yc.prototype=Object.create(xb.prototype);Yc.prototype.constructor= +Yc;Zc.prototype=Object.create(Ya.prototype);Zc.prototype.constructor=Zc;$c.prototype=Object.create(M.prototype);$c.prototype.constructor=$c;dc.prototype=Object.create(I.prototype);dc.prototype.constructor=dc;var za=Object.freeze({WireframeGeometry:Sb,ParametricGeometry:Hc,ParametricBufferGeometry:Tb,TetrahedronGeometry:Jc,TetrahedronBufferGeometry:Ub,OctahedronGeometry:Kc,OctahedronBufferGeometry:rb,IcosahedronGeometry:Lc,IcosahedronBufferGeometry:Vb,DodecahedronGeometry:Mc,DodecahedronBufferGeometry:Wb, +PolyhedronGeometry:Ic,PolyhedronBufferGeometry:la,TubeGeometry:Nc,TubeBufferGeometry:Xb,TorusKnotGeometry:Oc,TorusKnotBufferGeometry:Yb,TorusGeometry:Pc,TorusBufferGeometry:Zb,TextGeometry:Uc,TextBufferGeometry:$b,SphereGeometry:Vc,SphereBufferGeometry:ub,RingGeometry:Wc,RingBufferGeometry:ac,PlaneGeometry:wc,PlaneBufferGeometry:nb,LatheGeometry:Xc,LatheBufferGeometry:bc,ShapeGeometry:vb,ShapeBufferGeometry:wb,ExtrudeGeometry:tb,ExtrudeBufferGeometry:Qa,EdgesGeometry:cc,ConeGeometry:Yc,ConeBufferGeometry:Zc, +CylinderGeometry:xb,CylinderBufferGeometry:Ya,CircleGeometry:$c,CircleBufferGeometry:dc,BoxGeometry:Kb,BoxBufferGeometry:mb});yb.prototype=Object.create(H.prototype);yb.prototype.constructor=yb;yb.prototype.isShadowMaterial=!0;yb.prototype.copy=function(a){H.prototype.copy.call(this,a);this.color.copy(a.color);return this};ec.prototype=Object.create(ua.prototype);ec.prototype.constructor=ec;ec.prototype.isRawShaderMaterial=!0;Ra.prototype=Object.create(H.prototype);Ra.prototype.constructor=Ra;Ra.prototype.isMeshStandardMaterial= +!0;Ra.prototype.copy=function(a){H.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType= +a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin= +a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};zb.prototype=Object.create(Ra.prototype);zb.prototype.constructor=zb;zb.prototype.isMeshPhysicalMaterial=!0;zb.prototype.copy=function(a){Ra.prototype.copy.call(this,a);this.defines={PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness;return this};Ga.prototype=Object.create(H.prototype);Ga.prototype.constructor= +Ga;Ga.prototype.isMeshPhongMaterial=!0;Ga.prototype.copy=function(a){H.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap; +this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin= +a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Ab.prototype=Object.create(Ga.prototype);Ab.prototype.constructor=Ab;Ab.prototype.isMeshToonMaterial=!0;Ab.prototype.copy=function(a){Ga.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};Bb.prototype=Object.create(H.prototype);Bb.prototype.constructor=Bb;Bb.prototype.isMeshNormalMaterial=!0;Bb.prototype.copy=function(a){H.prototype.copy.call(this,a);this.bumpMap= +a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Cb.prototype=Object.create(H.prototype);Cb.prototype.constructor=Cb; +Cb.prototype.isMeshLambertMaterial=!0;Cb.prototype.copy=function(a){H.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio= +a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Db.prototype=Object.create(V.prototype);Db.prototype.constructor=Db;Db.prototype.isLineDashedMaterial=!0;Db.prototype.copy=function(a){V.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize; +return this};var Ug=Object.freeze({ShadowMaterial:yb,SpriteMaterial:eb,RawShaderMaterial:ec,ShaderMaterial:ua,PointsMaterial:Fa,MeshPhysicalMaterial:zb,MeshStandardMaterial:Ra,MeshPhongMaterial:Ga,MeshToonMaterial:Ab,MeshNormalMaterial:Bb,MeshLambertMaterial:Cb,MeshDepthMaterial:ab,MeshDistanceMaterial:bb,MeshBasicMaterial:ka,LineDashedMaterial:Db,LineBasicMaterial:V,Material:H}),Hb={enabled:!1,files:{},add:function(a,b){!1!==this.enabled&&(this.files[a]=b)},get:function(a){if(!1!==this.enabled)return this.files[a]}, +remove:function(a){delete this.files[a]},clear:function(){this.files={}}},wa=new be,Na={};Object.assign(Ha.prototype,{load:function(a,b,c,d){void 0===a&&(a="");void 0!==this.path&&(a=this.path+a);a=this.manager.resolveURL(a);var e=this,f=Hb.get(a);if(void 0!==f)return e.manager.itemStart(a),setTimeout(function(){b&&b(f);e.manager.itemEnd(a)},0),f;if(void 0!==Na[a])Na[a].push({onLoad:b,onProgress:c,onError:d});else{var g=a.match(/^data:(.*?)(;base64)?,(.*)$/);if(g){c=g[1];var h=!!g[2];g=g[3];g=window.decodeURIComponent(g); +h&&(g=window.atob(g));try{var k=(this.responseType||"").toLowerCase();switch(k){case "arraybuffer":case "blob":var m=new Uint8Array(g.length);for(h=0;hg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(K.clamp(d[k-1].dot(d[k]),-1,1)),e[k].applyMatrix4(h.makeRotationAxis(g,c))),f[k].crossVectors(d[k],e[k]);if(!0===b)for(c=Math.acos(K.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>k&&(k=e);ze.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,k);Ae.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,k);Be.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,k)}else"catmullrom"===this.curveType&&(ze.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),Ae.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Be.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(ze.calc(a), +Ae.calc(a),Be.calc(a));return b};ja.prototype.copy=function(a){L.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(kf(d,e.x,f.x,g.x,c.x),kf(d,e.y,f.y,g.y,c.y));return b};La.prototype.copy=function(a){L.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths(); +return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;c=e)break a;else{f=b[1];a=e)break b}d=c;c= +0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=qa.arraySlice(c,e,f),this.values=qa.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a= +!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times;b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e= +g}if(void 0!==b&&qa.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gm.opacity&&(m.transparent=!0);d.setTextures(k);return d.parse(m)}}()});var Ce={decodeText:function(a){if("undefined"!==typeof TextDecoder)return(new TextDecoder).decode(a);for(var b="",c=0,d=a.length;cf;f++){var D=h[u++];var B=A[2*D];D=A[2*D+1];B=new z(B,D);2!==f&&c.faceVertexUvs[e][v].push(B);0!==f&&c.faceVertexUvs[e][v+1].push(B)}}y&&(y=3*h[u++],r.normal.set(m[y++],m[y++],m[y]),w.normal.copy(r.normal));if(x)for(e=0;4>e;e++)y=3*h[u++],x=new p(m[y++], +m[y++],m[y]),2!==e&&r.vertexNormals.push(x),0!==e&&w.vertexNormals.push(x);n&&(n=h[u++],n=l[n],r.color.setHex(n),w.color.setHex(n));if(k)for(e=0;4>e;e++)n=h[u++],n=l[n],2!==e&&r.vertexColors.push(new F(n)),0!==e&&w.vertexColors.push(new F(n));c.faces.push(r);c.faces.push(w)}else{r=new Va;r.a=h[u++];r.b=h[u++];r.c=h[u++];v&&(v=h[u++],r.materialIndex=v);v=c.faces.length;if(e)for(e=0;ef;f++)D=h[u++],B=A[2*D],D=A[2*D+1],B=new z(B,D),c.faceVertexUvs[e][v].push(B); +y&&(y=3*h[u++],r.normal.set(m[y++],m[y++],m[y]));if(x)for(e=0;3>e;e++)y=3*h[u++],x=new p(m[y++],m[y++],m[y]),r.vertexNormals.push(x);n&&(n=h[u++],r.color.setHex(l[n]));if(k)for(e=0;3>e;e++)n=h[u++],r.vertexColors.push(new F(l[n]));c.faces.push(r)}}d=a;u=void 0!==d.influencesPerVertex?d.influencesPerVertex:2;if(d.skinWeights)for(g=0,h=d.skinWeights.length;g +Number.EPSILON){if(0>m&&(g=b[f],k=-k,h=b[e],m=-m),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=Xa.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new fb;h.curves=g.curves;b.push(h);return b}var k=!e(f[0].getPoints());k=a?!k:k;h=[];var m=[],l=[],n=0;m[n]=void 0;l[n]=[];for(var p= +0,u=f.length;pd&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a, +c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){ha.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});Object.assign(of.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a, +b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(sa,{Composite:of,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new sa.Composite(a,b,c):new sa(a,b,c)},sanitizeNodeName:function(){var a= +/[\[\]\.:\/]/g;return function(b){return b.replace(/\s/g,"_").replace(a,"")}}(),parseTrackName:function(){var a="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",b=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]");a=/(WCOD+)?/.source.replace("WCOD",a);var c=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),d=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),e=new RegExp("^"+b+a+c+d+"$"),f=["material","materials","bones"];return function(a){var b=e.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+ +a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==f.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b}}(),findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a; +if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var l=b++,n=a[l];c[n.uuid]=m;a[m]=n;c[k]=l;a[l]=h;h=0;for(k=e;h!==k;++h){n=d[h];var p=n[m];n[m]=n[l];n[l]=p}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k= +arguments[g].uuid,l=d[k];if(void 0!==l)if(delete d[k],lb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0];b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1=== +e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else break a;this.clampWhenFinished?this.paused=!0:this.enabled=!1;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished?this.paused=!0: +this.enabled=!1,b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:d}))}if(f&&1===(e&1))return this.time=b,c-b}return this.time=b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401: +2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}});qe.prototype=Object.assign(Object.create(ea.prototype),{constructor:qe,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0=== +k&&(k={},h[g]=k);for(h=0;h!==e;++h){var l=d[h],p=l.name,n=k[p];if(void 0===n){n=f[h];if(void 0!==n){null===n._cacheIndex&&(++n.referenceCount,this._addInactiveBinding(n,g,p));continue}n=new pe(sa.create(c,p,b&&b._propertyBindings[h].binding.parsedPath),l.ValueTypeName,l.getValueSize());++n.referenceCount;this._addInactiveBinding(n,g,p)}f[h]=n;a[h].resultBuffer=n.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid, +d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}},_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions= +[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length},get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}}, +_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"),b=new z);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y? +!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new z);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new z;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& +a.max.equals(this.max)}});Object.assign(we.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0===a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new p);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"), +a=new p);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=new p);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new p,b=new p;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);c=b.dot(b);c=b.dot(a)/c;d&& +(c=K.clamp(c,0,1));return c}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new p);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});gd.prototype=Object.create(B.prototype);gd.prototype.constructor=gd;gd.prototype.isImmediateRenderObject= +!0;hd.prototype=Object.create(Z.prototype);hd.prototype.constructor=hd;hd.prototype.update=function(){var a=new p,b=new p,c=new na;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,p=k.length;lMath.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);B.prototype.updateMatrixWorld.call(this,a)};var Od,xe;Gb.prototype= +Object.create(B.prototype);Gb.prototype.constructor=Gb;Gb.prototype.setDirection=function(){var a=new p,b;return function(c){.99999c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();Gb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()}; +Gb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};nd.prototype=Object.create(Z.prototype);nd.prototype.constructor=nd;L.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(L.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(Za.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); +a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new M,c=0,d=a.length;c