mkdir -p $(shell dirname $@)
$(STYLUS) < $< > $@ || (rm -f $@; exit 1)
+pylint:
+ pylint3 -E $(shell find src/py -name \*.py)
+
+jshint:
+ ./node_modules/jshint/bin/jshint --config jshint.json src/js/*.js
+
+lint: pylint jshint
+
watch:
@clear
$(MAKE)
rm -rf node_modules
.PHONY: all install html css static templates clean tidy copy mount umount pkg
-.PHONY: gplan
+.PHONY: gplan lint pylint jshint
--- /dev/null
+{
+ "asi": true,
+ "browser": true,
+ "devel": true,
+ "strict": "global",
+ "globals": {
+ "$": false,
+ "require": false,
+ "module": false,
+ "Vue": false,
+ "SockJS": false,
+ "Gauge": false
+ }
+}
--- /dev/null
+{
+ "name": "bbctrl",
+ "version": "0.3.4",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@browserify/acorn5-object-spread": {
+ "version": "5.0.1",
+ "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"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
+ "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug=="
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "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=",
+ "requires": {
+ "acorn": "2.7.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
+ "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "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==",
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw="
+ },
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI="
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "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="
+ },
+ "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"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "requires": {
+ "util": "0.10.3"
+ }
+ },
+ "astw": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz",
+ "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=",
+ "requires": {
+ "acorn": "4.0.13"
+ }
+ },
+ "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"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base64-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+ "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw=="
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ },
+ "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",
+ "concat-map": "0.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "browser-pack": {
+ "version": "6.0.2",
+ "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"
+ }
+ },
+ "browser-resolve": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz",
+ "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=",
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
+ }
+ }
+ },
+ "browserify": {
+ "version": "15.1.0",
+ "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"
+ }
+ },
+ "browserify-aes": {
+ "version": "1.1.1",
+ "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"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.0",
+ "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-des": {
+ "version": "1.0.0",
+ "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"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "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"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "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"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "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"
+ }
+ },
+ "buffer": {
+ "version": "5.0.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"
+ }
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
+ },
+ "cached-path-relative": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz",
+ "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc="
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "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"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "clean-css": {
+ "version": "3.4.28",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
+ "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=",
+ "requires": {
+ "commander": "2.8.1",
+ "source-map": "0.4.4"
+ },
+ "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=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "requires": {
+ "exit": "0.1.2",
+ "glob": "7.1.2"
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "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",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
+ }
+ }
+ },
+ "color-convert": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "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"
+ },
+ "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.6.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
+ "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "concat-stream": {
+ "version": "1.5.2",
+ "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"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "constantinople": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz",
+ "integrity": "sha1-S5RdmTeQe82Y7ldRIsOBdRZUQUE=",
+ "requires": {
+ "acorn": "2.7.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
+ "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
+ }
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
+ },
+ "convert-source-map": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "create-ecdh": {
+ "version": "4.0.0",
+ "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"
+ }
+ },
+ "create-hash": {
+ "version": "1.1.3",
+ "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"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.6",
+ "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"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "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"
+ }
+ },
+ "css": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz",
+ "integrity": "sha1-k4aBHKgrzMnuf7WnMrHioxfIo+c=",
+ "requires": {
+ "css-parse": "1.0.4",
+ "css-stringify": "1.0.5"
+ }
+ },
+ "css-parse": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz",
+ "integrity": "sha1-OLBQP7+dqfVOnB29pg4UXHcRe90="
+ },
+ "css-stringify": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz",
+ "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE="
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
+ },
+ "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"
+ }
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "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"
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
+ "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug=="
+ }
+ }
+ },
+ "diffie-hellman": {
+ "version": "5.0.2",
+ "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"
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
+ },
+ "entities": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
+ }
+ }
+ },
+ "domain-browser": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
+ "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw="
+ },
+ "domelementtype": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "requires": {
+ "domelementtype": "1.3.0"
+ }
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "elliptic": {
+ "version": "6.4.0",
+ "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"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
+ },
+ "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="
+ },
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "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"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "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"
+ }
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
+ },
+ "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"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "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"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "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"
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "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"
+ }
+ },
+ "htmlescape": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E="
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "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"
+ },
+ "dependencies": {
+ "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": "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",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
+ },
+ "ieee754": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+ },
+ "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"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "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"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "insert-module-globals": {
+ "version": "7.0.1",
+ "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"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "json-stable-stringify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "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"
+ }
+ },
+ "labeled-stream-splicer": {
+ "version": "2.0.0",
+ "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"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ }
+ }
+ },
+ "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.2.0"
+ }
+ },
+ "lodash": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz",
+ "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU="
+ },
+ "lodash.memoize": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8="
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+ },
+ "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"
+ },
+ "dependencies": {
+ "hash-base": {
+ "version": "3.0.4",
+ "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"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+ "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ }
+ }
+ },
+ "module-deps": {
+ "version": "5.0.1",
+ "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"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.6.0",
+ "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"
+ }
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI="
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "optimist": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+ "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
+ "requires": {
+ "wordwrap": "0.0.3"
+ }
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
+ },
+ "pako": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
+ },
+ "parents": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
+ "requires": {
+ "path-platform": "0.11.15"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.0",
+ "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"
+ }
+ },
+ "path-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
+ },
+ "path-platform": {
+ "version": "0.11.15",
+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I="
+ },
+ "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"
+ }
+ },
+ "postcss": {
+ "version": "6.0.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
+ "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
+ "requires": {
+ "chalk": "2.3.0",
+ "source-map": "0.6.1",
+ "supports-color": "5.1.0"
+ }
+ },
+ "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="
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "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"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.3",
+ "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"
+ }
+ },
+ "read-only-stream": {
+ "version": "2.0.0",
+ "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": {
+ "version": "2.3.3",
+ "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"
+ }
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.1",
+ "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"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "sax": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
+ "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE="
+ },
+ "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"
+ }
+ },
+ "shasum": {
+ "version": "1.0.2",
+ "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"
+ }
+ },
+ "shell-quote": {
+ "version": "1.6.1",
+ "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"
+ }
+ },
+ "shelljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E="
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "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"
+ }
+ },
+ "stream-combiner2": {
+ "version": "1.1.1",
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "stream-splicer": {
+ "version": "2.0.0",
+ "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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "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"
+ }
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E="
+ },
+ "stylus": {
+ "version": "0.54.5",
+ "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"
+ },
+ "dependencies": {
+ "css-parse": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
+ "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs="
+ },
+ "glob": {
+ "version": "7.0.6",
+ "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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "subarg": {
+ "version": "1.0.0",
+ "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"
+ }
+ },
+ "syntax-error": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz",
+ "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=",
+ "requires": {
+ "acorn": "4.0.13"
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "requires": {
+ "readable-stream": "2.3.3",
+ "xtend": "4.0.1"
+ }
+ },
+ "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"
+ }
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "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=",
+ "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"
+ }
+ }
+ }
+ },
+ "tty-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "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=",
+ "requires": {
+ "source-map": "0.5.7",
+ "uglify-to-browserify": "1.0.2",
+ "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="
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "optional": true
+ },
+ "umd": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz",
+ "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4="
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+ }
+ }
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "requires": {
+ "inherits": "2.0.1"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "vm-browserify": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+ "requires": {
+ "indexof": "0.0.1"
+ }
+ },
+ "void-elements": {
+ "version": "2.0.1",
+ "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="
+ },
+ "with": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz",
+ "integrity": "sha1-7v0VTp550sjTQXtkeo8U2f7M4U4=",
+ "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="
+ }
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "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",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+}
{
"name": "bbctrl",
- "version": "0.3.4",
- "homepage": "https://github.com/buildbotics/bbctrl-firmware",
- "license": "GPL 3+",
+ "version": "0.3.3",
+ "homepage": "http://buildbotics.com/",
+ "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"
+ "browserify": ">=8.1.1",
+ "jshint": ""
}
}
.title
span.left Build
span.right botics
- .subtitle Machine Controller
+ .subtitle
+ | Machine Controller v{{config.version}}
+ a.upgrade-version(v-if="show_upgrade()", href="#admin")
+ | Upgrade to v{{latestVersion}}
+ .fa.fa-check(v-if="!show_upgrade() && latestVersion",
+ title="Firmware up to date")
.content(class="{{currentView}}-view")
component(:is="currentView + '-view'", :index="index",
:config="config", :template="template", :state="state", keep-alive)
+ message.error-message(:show.sync="errorShow")
+ div(slot="header")
+ .estop(:class="{active: state.es}"): estop(@click="estop")
+ h3 ERROR: {{errorMessage}}
+
+ div(slot="body")
+ console
+
+ message(:show.sync="confirmUpgrade")
+ h3(slot="header") Upgrade Firmware?
+ div(slot="body")
+ p
+ | Are you sure you want to upgrade the firmware to version
+ | {{latestVersion}}?
+
+ p.pure-control-group
+ label(for="pass") Password
+ input(name="pass", v-model="password", type="password")
+
+ div(slot="footer")
+ button.pure-button(@click="confirmUpgrade=false") Cancel
+ button.pure-button.pure-button-primary(@click="upgrade_confirmed")
+ | Upgrade
+
+ message(:show.sync="firmwareUpgrading")
+ h3(slot="header") Firmware upgrading
+ p(slot="body") Please wait...
+
#templates
include ../../build/templates.jade
button.pure-button.pure-button-primary(@click="upgrade") Upgrade
p
- table.pure-table
- tr
- th Current version
- td {{config.version}}
-
- tr(v-if="latest")
- th Latest version
- td {{latest}}
-
- message(:show.sync="firmwareUpgrading")
- h3(slot="header") Firmware upgrading
- p(slot="body") Please wait...
+ input(type="checkbox", v-model="autoCheckUpgrade",
+ @change="change_auto_check_upgrade")
+ label(for="auto-check-upgrade") Automatically check for upgrades
message(:show.sync="hostnameSet")
h3(slot="header") Hostname Set
--- /dev/null
+script#console-template(type="text/x-template")
+ .console
+ .toolbar
+ button.pure-button(title="Clear console.", @click="clear")
+ .fa.fa-trash
+
+ table
+ tr
+ th Level
+ th Source
+ th Location
+ th Repeat
+ th Message
+
+ tr(v-for="msg in messages.reverse()", :class="msg.level || 'info'")
+ td {{msg.level || 'info'}}
+ td {{msg.source || ''}}
+ td {{msg.where || ''}}
+ td {{msg.repeat}}
+ td {{msg.msg}}
center Jogging speed is set by the ring that is clicked.
section#content4.tab-content
- .toolbar
- button.pure-button(title="Clear console.", @click="clear_console")
- .fa.fa-trash
-
- table.console
- tr
- th Level
- th Location
- th Code
- th Repeat
- th Message
-
- tr(v-for="msg in console", :class="msg.level || 'info'")
- td {{msg.level || 'info'}}
- td {{msg.where || ''}}
- td {{msg.code || '0'}}
- td {{msg.repeat}}
- td {{msg.msg}}
+ console
section#content5.tab-content
- component(is="indicators", :state="state")
+ indicators(:state="state")
section#content6.tab-content
.video
module.exports = {
template: '#admin-view-template',
- props: ['config'],
+ props: ['config', 'state'],
data: function () {
configRestored: false,
confirmReset: false,
configReset: false,
- firmwareUpgrading: false,
hostnameSet: false,
usernameSet: false,
passwordSet: false,
username: '',
current: '',
password: '',
- password2: ''
+ password2: '',
+ autoCheckUpgrade: true,
}
},
events: {
connected: function () {
if (this.firmwareUpgrading) location.reload(true);
- }
+ },
+
+ latest_version: function (version) {this.latest = version}
},
ready: function () {
+ this.autoCheckUpgrade = this.config.admin['auto-check-upgrade']
+
api.get('hostname').done(function (hostname) {
this.hostname = hostname;
}.bind(this));
try {
config = JSON.parse(e.target.result);
- } catch (e) {
+ } catch (ex) {
alert("Invalid config file");
return;
}
},
- check: function () {
- $.ajax({
- type: 'GET',
- url: 'https://buildbotics.com/bbctrl/latest.txt',
- cache: false
-
- }).done(function (data) {
- this.latest = data;
-
- }.bind(this)).fail(function (error) {
- alert('Failed to get latest version information');
- });
- },
+ check: function () {this.$dispatch('check')},
+ upgrade: function () {this.$dispatch('upgrade')},
- upgrade: function () {
- this.firmwareUpgrading = true;
- api.put('upgrade');
+ change_auto_check_upgrade: function () {
+ this.config.admin['auto-check-upgrade'] = this.autoCheckUpgrade;
+ this.$dispatch('config-changed');
}
}
}
var Sock = require('./sock');
+function compare_versions(a, b) {
+ var reStripTrailingZeros = /(\.0+)+$/;
+ var segsA = a.replace(reStripTrailingZeros, '').split('.');
+ var segsB = b.replace(reStripTrailingZeros, '').split('.');
+ var l = Math.min(segsA.length, segsB.length);
+
+ for (var i = 0; i < l; i++) {
+ var diff = parseInt(segsA[i], 10) - parseInt(segsB[i], 10);
+ if (diff) return diff;
+ }
+
+ return segsA.length - segsB.length;
+}
+
+
module.exports = new Vue({
el: 'body',
modified: false,
template: {motors: {}, axes: {}},
config: {motors: [{}]},
- state: {}
+ state: {},
+ messages: [],
+ errorShow: false,
+ errorMessage: '',
+ confirmUpgrade: false,
+ firmwareUpgrading: false,
+ checkedUpgrade: false,
+ latestVersion: '',
+ password: ''
}
},
connected: function () {this.update()},
- update: function () {this.update()}
+ update: function () {this.update()},
+
+
+ check: function () {
+ this.latestVersion = '';
+
+ $.ajax({
+ type: 'GET',
+ url: 'https://buildbotics.com/bbctrl/latest.txt',
+ data: {hid: this.state.hid},
+ cache: false
+
+ }).done(function (data) {
+ this.latestVersion = data;
+ this.$broadcast('latest_version', data);
+ }.bind(this))
+ },
+
+
+ upgrade: function () {
+ this.password = '';
+ this.confirmUpgrade = true;
+ },
+
+
+ error: function (msg) {
+ this.errorShow = true;
+ this.errorMessage = msg.msg;
+ }
},
},
+ upgrade_confirmed: function () {
+ this.confirmUpgrade = false;
+
+ api.put('upgrade', {password: this.password}).done(function () {
+ this.firmwareUpgrading = true;
+
+ }.bind(this)).fail(function () {
+ alert('Invalid password');
+ }.bind(this));
+ },
+
+
+ show_upgrade: function () {
+ if (!this.latestVersion) return false;
+ return compare_versions(this.config.version, this.latestVersion) < 0;
+ },
+
+
update: function () {
$.ajax({type: 'GET', url: '/config-template.json', cache: false})
.success(function (data, status, xhr) {
api.get('config/load').done(function (data) {
this.config = data;
this.parse_hash();
+
+ if (!this.checkedUpgrade) {
+ this.checkedUpgrade = true;
+
+ var check = this.config.admin['auto-check-upgrade'];
+ if (typeof check == 'undefined' || check)
+ this.$emit('check');
+ }
}.bind(this))
}.bind(this))
},
this.sock.onmessage = function (e) {
var msg = e.data;
- if (typeof msg == 'object') {
- for (var key in msg)
- Vue.set(this.state, key, msg[key]);
-
- if ('msg' in msg) this.$broadcast('message', msg);
- }
+ if (typeof msg == 'object')
+ for (var key in msg) {
+ if (key == 'msg') this.$broadcast('message', msg.msg);
+ else Vue.set(this.state, key, msg[key]);
+ }
}.bind(this);
this.sock.onopen = function (e) {
this.status = 'disconnected';
this.$broadcast(this.status);
}.bind(this);
-
- console.debug('Hello');
},
--- /dev/null
+'use strict'
+
+
+function _msg_equal(a, b) {
+ return a.level == b.level && a.location == b.location && a.code == b.code &&
+ a.msg == b.msg;
+}
+
+
+// Shared among all instances
+var messages = [];
+
+
+module.exports = {
+ template: '#console-template',
+
+
+ data: function () {
+ return {messages: messages}
+ },
+
+
+ events: {
+ message: function (msg) {
+ // There may be multiple instances of this module so ignore messages
+ // that have already been processed.
+ if (msg.logged) return;
+ msg.logged = true;
+
+ // Make sure we have a message level
+ msg.level = msg.level || 'info';
+
+ // Add to message log and count and collapse repeats
+ if (messages.length && _msg_equal(msg, messages[messages.length - 1]))
+ messages[messages.length - 1].repeat++;
+
+ else {
+ msg.repeat = 1;
+ messages.push(msg);
+ }
+
+ // Write message to browser console for debugging
+ var text = JSON.stringify(msg);
+ if (msg.level == 'error' || msg.level == 'critical') console.error(text);
+ else if (msg.level == 'warning') console.warn(text);
+ else if (msg.level == 'debug' && console.debug) console.debug(text);
+ else console.log(text);
+
+ // Event on errors
+ if (msg.level == 'error' || msg.level == 'critical')
+ this.$dispatch('error', msg);
+ }
+ },
+
+
+ methods: {
+ clear: function () {messages.length = 0;},
+ }
+}
}
-function _msg_equal(a, b) {
- return a.level == b.level && a.location == b.location && a.code == b.code &&
- a.msg == b.msg;
-}
-
-
function escapeHTML(s) {
var entityMap = {'&': '&', '<': '<', '>': '>'};
return String(s).replace(/[&<>]/g, function (s) {return entityMap[s];});
axes: 'xyzabc',
gcode: [],
history: [],
- console: [],
speed_override: 1,
feed_override: 1,
manual_home: {x: false, y: false, z: false, a: false, b: false, c: false},
var data = {};
data[axis] = power;
api.put('jog', data);
- },
-
-
- message: function (msg) {
- if (this.console.length &&
- _msg_equal(msg, this.console[this.console.length - 1]))
- this.console[this.console.length - 1].repeat++;
-
- else {
- msg.repeat = 1;
- this.console.push(msg);
- }
}
},
- ready: function () {
- this.update();
- },
+ ready: function () {this.update()},
methods: {
get_axis_motor_id: function (axis) {
- var axis = axis.toLowerCase();
+ axis = axis.toLowerCase();
for (var i = 0; i < this.config.motors.length; i++) {
var motor = this.config.motors[i];
if (typeof motor == 'undefined') return;
if (typeof motor[name] != 'undefined') return motor[name];
- for (var section in this.template['motors']) {
- var sec = this.template['motors'][section];
+ for (var section in this.template.motors) {
+ var sec = this.template.motors[section];
if (typeof sec[name] != 'undefined') return sec[name]['default'];
}
},
},
- clear_console: function () {this.console = [];},
-
-
load_video: function () {
this.video_url = '//' + document.location.hostname + ':8000/stream/0?=' +
Math.random();
+'use strict';
+
+
module.exports = Vue.extend({
template: '<div class="gauge"><canvas></canvas><span></span></div>',
this.outputs = this.config.outputs;
else this.outputs = {};
- var template = this.template.outputs;
- for (var key in template)
+ template = this.template.outputs;
+ for (key in template)
if (!this.outputs.hasOwnProperty(key))
this.$set('outputs["' + key + '"]', template[key].default);
}.bind(this));
+'use strict';
+
+
$(function() {
// Vue debugging
Vue.config.debug = true;
- Vue.util.warn = function (msg) {console.debug('[Vue warn]: ' + msg)}
+ //Vue.util.warn = function (msg) {console.debug('[Vue warn]: ' + msg)}
// Register global components
Vue.component('templated-input', require('./templated-input'));
Vue.component('message', require('./message'));
Vue.component('indicators', require('./indicators'));
+ Vue.component('console', require('./console'));
Vue.filter('percent', function (value, precision) {
if (typeof precision == 'undefined') precision = 2;
slave_update: function () {
var slave = false;
for (var i = 0; i < this.index; i++)
- if (this.motor['axis'] == this.config.motors[i]['axis'])
+ if (this.motor.axis == this.config.motors[i].axis)
slave = true;
var el = $(this.$el);
+++ /dev/null
-module.exports = new Vue({
- template: '<input type="range" v-model="value">',
- replace: true,
-
-
- props: {
- value: Number,
- min: Number,
- max: Number,
- step: Number
- },
-
-
- data: function () {
- return {
- }
- },
-
-
- compiled: function () {
- this.$el.attributes.min = this.min;
- this.$el.attributes.max = this.max;
- this.$el.attributes.step = this.step;
- }
-}
-'use strict'
+'use strict';
module.exports = {
import json
-import tornado.web
+from tornado.web import RequestHandler, HTTPError
import tornado.httpclient
-class APIHandler(tornado.web.RequestHandler):
+class APIHandler(RequestHandler):
def __init__(self, app, request, **kwargs):
super(APIHandler, self).__init__(app, request, **kwargs)
self.ctrl = app.ctrl
self.write_json('ok')
- def delete_ok(self): raise tornado.httpclient.HTTPError(405)
+ def delete_ok(self): raise HTTPError(405)
def put(self, *args, **kwargs):
self.write_json('ok')
- def put_ok(self): raise tornado.httpclient.HTTPError(405)
+ def put_ok(self): raise HTTPError(405)
def prepare(self):
try:
self.json = tornado.escape.json_decode(self.request.body)
except ValueError:
- self.send_error(400, message = 'Unable to parse JSON.')
+ raise HTTPError(400, 'Unable to parse JSON.')
def set_default_headers(self):
self.lcd_page = ctrl.lcd.add_new_page()
self.install_page = True
- ctrl.state.add_listener(lambda x: self._update_state(x))
+ ctrl.state.add_listener(self._update_state)
try:
self.sp = serial.Serial(ctrl.args.serial, ctrl.args.baud,
retry -= 1
if retry:
- log.error('AVR I2C communication failed, retrying: %s' % e)
+ log.warning('AVR I2C failed, retrying: %s' % e)
time.sleep(0.1)
continue
else:
- log.error('AVR I2C communication failed: %s' % e)
+ log.error('AVR I2C failed: %s' % e)
raise
if self.ctrl.ioloop.READ & events: self._serial_read()
if self.ctrl.ioloop.WRITE & events: self._serial_write()
except Exception as e:
- log.error('Serial handler error: %s', traceback.format_exc())
+ log.warning('Serial handler error: %s', traceback.format_exc())
def _serial_write(self):
msg = json.loads(line)
except Exception as e:
- log.error('%s, data: %s', e, line)
+ log.warning('%s, data: %s', e, line)
continue
if 'variables' in msg:
if update:
if 'firmware' in update:
- log.error('AVR rebooted')
+ log.warning('firmware rebooted')
self.connect()
self.ctrl.state.update(update)
return data
-def seek(switch, open, error):
- flags = (SEEK_OPEN if open else 0) | (SEEK_ERROR if error else 0)
- return '%c%x%x' % (SEEK, switch, flags)
-
-
def line_number(line): return '#ln=%d' % line
"outputs": {},
"tool": {},
"gcode": {},
+ "admin": {},
}
self.args = args
self.ioloop = ioloop
+ self.msgs = bbctrl.Messages(self)
self.state = bbctrl.State(self)
self.planner = bbctrl.Planner(self)
self.i2c = bbctrl.I2C(args.i2c_port)
axes = {}
for i in range(len(self.v)): axes["xyzabc"[i]] = self.v[i]
self.ctrl.avr.jog(axes)
- except Exception as e: log.error('Jog: %s', e)
+ except Exception as e: log.warning('Jog: %s', e)
self.ctrl.ioloop.call_later(0.25, self.callback)
self.load_page(LCDPage(self, msg))
self._update()
except IOError as e:
- log.error('LCD communication failed: %s' % e)
+ log.warning('LCD communication failed: %s' % e)
def new_screen(self):
self.addr = self.addrs[self.addr_num]
self.lcd = None
- log.error('LCD communication failed, ' +
- 'retrying on address 0x%02x: %s' % (self.addr, e))
+ log.warning('LCD communication failed, ' +
+ 'retrying on address 0x%02x: %s' % (self.addr, e))
self.reset = True
self.timeout = self.ctrl.ioloop.call_later(1, self._update)
--- /dev/null
+import os
+import logging
+import bbctrl
+
+
+log = logging.getLogger('Msgs')
+
+
+class Messages(logging.Handler):
+ def __init__(self, ctrl):
+ logging.Handler.__init__(self, logging.WARNING)
+
+ self.ctrl = ctrl
+ self.listeners = []
+
+ logging.getLogger().addHandler(self)
+
+
+ def add_listener(self, listener): self.listeners.append(listener)
+ def remove_listener(self, listener): self.listeners.remove(listener)
+
+
+ # From logging.Handler
+ def emit(self, record):
+ msg = dict(
+ level = record.levelname.lower(),
+ source = record.name,
+ msg = record.getMessage())
+
+ if hasattr(record, 'where'): msg['where'] = record.where
+ else: msg['where'] = '%s:%d' % (record.filename, record.lineno)
+
+ for listener in self.listeners:
+ listener(msg)
import json
+import re
import logging
-import camotics.gplan as gplan
+import camotics.gplan as gplan # pylint: disable=no-name-in-module,import-error
import bbctrl.Cmd as Cmd
log = logging.getLogger('Planner')
+reLogLine = re.compile(
+ r'^(?P<level>[A-Z])[0-9 ]:((?P<where>[^:]+:\d+:\d+):)?(?P<msg>.*)$')
class Planner():
self.lastID = -1
self.mode = 'idle'
- ctrl.state.add_listener(lambda x: self.update(x))
+ ctrl.state.add_listener(self.update)
self.reset()
def log(self, line):
line = line.strip()
- if len(line) < 3: return
-
- if line[0] == 'I': log.info(line[3:])
- elif line[0] == 'D': log.debug(line[3:])
- # TODO send these to the LCD and Web
- elif line[0] == 'W': log.warning(line[3:])
- elif line[0] == 'E': log.error(line[3:])
- elif line[0] == 'C': log.critical(line[3:])
- else: raise Exception('Could not parse planner log line: ' + line)
+ m = reLogLine.match(line)
+ if not m: return
+
+ level = m.group('level')
+ msg = m.group('msg')
+ where = m.group('where')
+
+ if where is not None: extra = dict(where = where)
+ else: extra = None
+
+ if level == 'I': log.info (msg, extra = extra)
+ elif level == 'D': log.debug (msg, extra = extra)
+ elif level == 'W': log.warning (msg, extra = extra)
+ elif level == 'E': log.error (msg, extra = extra)
+ elif level == 'C': log.critical(msg, extra = extra)
+ else: log.error('Could not parse planner log line: ' + line)
def mdi(self, cmd):
flags = self.regs[FLAGS_REG]
errors = []
- if flags & UNDER_VOLTAGE_FLAG: errors.push('under voltage')
- if flags & OVER_VOLTAGE_FLAG: errors.push('over voltage')
- if flags & OVER_CURRENT_FLAG: errors.push('over current')
- if flags & MEASUREMENT_ERROR_FLAG: errors.push('measurement error')
- if flags & SHUNT_OVERLOAD_FLAG: errors.push('shunt overload')
+ # Decode error flags
+ if flags & UNDER_VOLTAGE_FLAG: errors.append('under voltage')
+ if flags & OVER_VOLTAGE_FLAG: errors.append('over voltage')
+ if flags & OVER_CURRENT_FLAG: errors.append('over current')
+ if flags & MEASUREMENT_ERROR_FLAG: errors.append('measurement error')
+ if flags & SHUNT_OVERLOAD_FLAG: errors.append('shunt overload')
# Report errors
- self.ctrl.state.set('pwr_errors', errors)
+ if errors: log.error('Power fault: ' + ', '.join(errors))
def _update(self):
import logging
+import traceback
import bbctrl
self.vars = {}
self.callbacks = {}
self.changes = {}
- self.next_id = 1
- self.listeners = {}
+ self.listeners = []
self.timeout = None
self.machine_vars = {}
self.machine_var_set = set()
def _notify(self):
if not self.changes: return
- for listener in self.listeners.values():
+ for listener in self.listeners:
try:
listener(self.changes)
except Exception as e:
- log.error('Updating listener: %s', traceback.format_exc())
+ log.warning('Updating state listener: %s',
+ traceback.format_exc())
self.changes = {}
self.timeout = None
if name in self.vars: return self.vars[name]
if name in self.callbacks: return self.callbacks[name](name)
- if default is None: log.error('State variable "%s" not found' % name)
+ if default is None: log.warning('State variable "%s" not found' % name)
return default
def add_listener(self, listener):
- sid = self.next_id
- self.next_id += 1
-
- self.listeners[sid] = listener
+ self.listeners.append(listener)
if self.vars: listener(self.vars)
- return sid
-
- def remove_listener(self, sid): del self.listeners[sid]
+ def remove_listener(self, listener): self.listeners.remove(listener)
def machine_cmds_and_vars(self, data):
import tarfile
import subprocess
import socket
+from tornado.web import HTTPError
import bbctrl
def call_get_output(cmd):
p = subprocess.Popen(cmd, stdout = subprocess.PIPE)
s = p.communicate()[0].decode('utf-8')
- if p.returncode: raise Exception('Command failed')
+ if p.returncode: raise HTTPError(400, 'Command failed')
return s
+def get_username():
+ return call_get_output(['getent', 'passwd', '1001']).split(':')[0]
+
+
+def set_username(username):
+ if subprocess.call(['usermod', '-l', username, get_username()]):
+ raise HTTPError(400, 'Failed to set username to "%s"' % username)
+
+
+def check_password(password):
+ # Get current password
+ s = call_get_output(['getent', 'shadow', get_username()])
+ current = s.split(':')[1].split('$')
+
+ # Check password type
+ if current[1] != '1':
+ raise HTTPError(400, "Don't know how to update non-MD5 password")
+
+ # Check current password
+ cmd = ['openssl', 'passwd', '-salt', current[2], '-1', password]
+ s = call_get_output(cmd).strip()
+
+ if s.split('$') != current: raise HTTPError(401, 'Wrong password')
+
+
+
class RebootHandler(bbctrl.APIHandler):
def put_ok(self): subprocess.Popen('reboot')
self.write_json('ok')
return
- self.send_error(400, message = 'Failed to set hostname: %s' % self.json)
-
-
-def get_username():
- return call_get_output(['getent', 'passwd', '1001']).split(':')[0]
+ raise HTTPError(400, 'Failed to set hostname')
class UsernameHandler(bbctrl.APIHandler):
def get(self): self.write_json(get_username())
- def put(self):
- if 'username' in self.json:
- username = get_username()
-
- if subprocess.call(['usermod', '-l', self.json['username'],
- username]) == 0:
- self.write_json('ok')
- return
-
- self.send_error(400, message = 'Failed to set username: %s' % self.json)
+ def put_ok(self):
+ if 'username' in self.json: set_username(self.json['username'])
+ else: raise HTTPError(400, 'Missing "username"')
class PasswordHandler(bbctrl.APIHandler):
def put(self):
if 'current' in self.json and 'password' in self.json:
- # Get current user name
- username = get_username()
-
- # Get current password
- s = call_get_output(['getent', 'shadow', username])
- password = s.split(':')[1].split('$')
-
- # Check password type
- if password[1] != '1':
- self.send_error(400, message =
- "Don't know how to update non-MD5 password")
- return
-
- # Check current password
- cmd = ['openssl', 'passwd', '-salt', password[2], '-1',
- self.json['current']]
- s = call_get_output(cmd).strip()
- if s.split('$') != password:
- print('%s != %s' % (s.split('$'), password))
- self.send_error(401, message = 'Wrong password')
- return
+ check_password(self.json['current'])
# Set password
s = '%s:%s' % (username, self.json['password'])
self.write_json('ok')
return
- self.send_error(400, message = 'Failed to set password')
+ raise HTTPError(401, 'Failed to set password')
class ConfigLoadHandler(bbctrl.APIHandler):
def prepare(self): pass
- def put(self):
+ def put_ok(self):
# Only allow this function in dev mode
if not os.path.exists('/etc/bbctrl-dev-mode'):
- self.send_error(403, message = 'Not in dev mode')
- return
+ raise HTTPError(403, 'Not in dev mode')
firmware = self.request.files['firmware'][0]
subprocess.Popen(['/usr/local/bin/update-bbctrl'])
- self.write_json('ok')
-
class UpgradeHandler(bbctrl.APIHandler):
- def put_ok(self): subprocess.Popen(['/usr/local/bin/upgrade-bbctrl'])
+ def put_ok(self):
+ check_password(self.json['password'])
+ subprocess.Popen(['/usr/local/bin/upgrade-bbctrl'])
class HomeHandler(bbctrl.APIHandler):
if set_home:
if not 'position' in self.json:
- raise Exception('Missing "position"')
+ raise HTTPError(400, 'Missing "position"')
self.ctrl.avr.home(axis, self.json['position'])
def put_ok(self): self.ctrl.avr.jog(self.json)
-# Used by CAMotics
-class WSConnection(tornado.websocket.WebSocketHandler):
- def __init__(self, app, request, **kwargs):
- super(WSConnection, self).__init__(app, request, **kwargs)
- self.ctrl = app.ctrl
- self.timer = None
+# Base class for Web Socket connections
+class ClientConnection(object):
+ def __init__(self, ctrl):
+ self.ctrl = ctrl
+ self.count = 0
def heartbeat(self):
- self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat)
- self.write_message({'heartbeat': self.count})
+ self.ctrl.ioloop.call_later(3, self.heartbeat)
+ self.send({'heartbeat': self.count})
self.count += 1
- def open(self):
- self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat)
- self.count = 0;
- self.sid = self.ctrl.state.add_listener(lambda x: self.write_message(x))
+ def notify(self, msg): self.send(dict(msg = msg))
+ def send(self, msg): raise HTTPError(400, 'Not implemented')
- def on_close(self):
- if self.timer is not None: self.ctrl.ioloop.remove_timeout(self.timer)
- self.ctrl.state.remove_listener(self.sid)
+ def on_open(self, *args, **kwargs):
+ self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat)
+ self.ctrl.state.add_listener(self.send)
+ self.ctrl.msgs.add_listener(self.notify)
+ self.is_open = True
- def on_message(self, msg): pass
+ def on_close(self):
+ self.ctrl.ioloop.remove_timeout(self.timer)
+ self.ctrl.state.remove_listener(self.send)
+ self.ctrl.msgs.remove_listener(self.notify)
-# Used by Web frontend
-class SockJSConnection(sockjs.tornado.SockJSConnection):
- def heartbeat(self):
- self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat)
- self.send({'heartbeat': self.count})
- self.count += 1
+ def on_message(self, data): self.ctrl.avr.mdi(data)
- def on_open(self, info):
- self.ctrl = self.session.server.ctrl
+# Used by CAMotics
+class WSConnection(ClientConnection, tornado.websocket.WebSocketHandler):
+ def __init__(self, app, request, **kwargs):
+ ClientConnection.__init__(self, app.ctrl)
+ tornado.websocket.WebSocketHandler.__init__(
+ self, app, request, **kwargs)
- self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat)
- self.count = 0;
- self.sid = self.ctrl.state.add_listener(lambda x: self.send(x))
+ def send(self, msg): self.write_message(msg)
+ def open(self): self.on_open()
- def on_close(self):
- self.ctrl.ioloop.remove_timeout(self.timer)
- self.ctrl.state.remove_listener(self.sid)
+# Used by Web frontend
+class SockJSConnection(ClientConnection, sockjs.tornado.SockJSConnection):
+ def __init__(self, session):
+ ClientConnection.__init__(self, session.server.ctrl)
+ sockjs.tornado.SockJSConnection.__init__(self, session)
- def on_message(self, data):
- self.ctrl.avr.mdi(data)
+ def send(self, msg): sockjs.tornado.SockJSConnection.send(self, msg)
class StaticFileHandler(tornado.web.StaticFileHandler):
from bbctrl.I2C import I2C
from bbctrl.Planner import Planner
from bbctrl.State import State
+from bbctrl.Messages import Messages
import bbctrl.Cmd as Cmd
try:
ioloop.start()
- except KeyboardInterrupt:
- on_exit()
-
- except: log.exception('')
+ except KeyboardInterrupt: on_exit()
+ except SystemExit: raise
+ except: logging.getLogger().exception('')
if __name__ == "__main__": run()
The output is packed into a string. It is unlikely that this function
will be required, but it might as well be here.
"""
- tint = long(self.time)
- tfrac = long((self.time - tint) * 1000000)
+ tsec = int(self.time)
+ tfrac = int((self.time - tsec) * 1000000)
return struct.pack(_format, tsec, tfrac, self.type, self.code, self.value)
return self
- def next(self):
+ def __next__(self):
"""
Returns the next waiting event.
firstLine)
if not match:
- log.warning("Do not understand device ID:", line)
+ log.warning("Do not understand device ID: %s", firstLine)
self.bus = 0
self.vendor = 0
self.product = 0
def __str__(self):
return (
- "%s\n"
- "Bus: %s Vendor: %s Product: %s Version: %s\n"
- "Phys: %s\n"
- "Sysfs: %s\n"
- "Uniq: %s\n"
- "Handlers: %s Event Index: %s\n"
- "Keyboard: %s Mouse: %s Joystick: %s\n"
- "Events: %s" % (
- self.name, self.bus. self.vendor, self.product, self.version, self.phys,
+ ("%s\n"
+ "Bus: %s Vendor: %s Product: %s Version: %s\n"
+ "Phys: %s\n"
+ "Sysfs: %s\n"
+ "Uniq: %s\n"
+ "Handlers: %s Event Index: %s\n"
+ "Keyboard: %s Mouse: %s Joystick: %s\n"
+ "Events: %s") % (
+ self.name, self.bus, self.vendor, self.product, self.version, self.phys,
self.sysfs, self.uniq, self.handlers, self.eventIndex, self.isKeyboard,
self.isMouse, self.isJoystick, EvToStr(self.eventTypes)))
"type": "text",
"default": "M2 (End program)\n"
}
+ },
+
+ "admin": {
+ "auto-check-upgrade": {
+ "type": "bool",
+ "default": true
+ }
}
}
+++ /dev/null
-/*\r
- Sample tooltip code. Only works on grade A browsers (so no IE6, 7 or 8).\r
- \r
- See: http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/ \r
- for full info on how to style generated content & the associated pitfalls. \r
-*/\r
-\r
-.fd-slider-handle:before,\r
-.fd-slider-handle:after\r
- {\r
- content:"";\r
- /* Remove from screen */\r
- opacity:0;\r
- -webkit-transition-property: all;\r
- -moz-transition-property: all;\r
- -ms-transition-property: all;\r
- -o-transition-property: all;\r
- transition-property: all; \r
- -webkit-transition-duration: 0.3s;\r
- -moz-transition-duration: 0.3s;\r
- -ms-transition-duration: 0.3s;\r
- -o-transition-duration: 0.3s;\r
- transition-duration: 0.3s; \r
- -webkit-transition-delay: 0.2s;\r
- -moz-transition-delay: 0.2s;\r
- -ms-transition-delay: 0.2s;\r
- -o-transition-delay: 0.2s;\r
- transition-delay: 0.2s;\r
- }\r
-/* \r
- The tooltip body - as we position it above the slider and position the \r
- tooltip arrow below it, we need to know the height of the body. This means \r
- that multi-line tooltips are not supported.\r
- \r
- To support multi-line tooltips, you will need to position the tooltip below \r
- the slider and the tooltip pointer above the tooltip body. Additionally, you \r
- will have to set the tooltip body "height" to auto\r
-*/\r
-.fd-slider-handle:before\r
- {\r
- display:block;\r
- position:absolute;\r
- top:-30px;\r
- left:-25px;\r
- margin:0;\r
- width:60px;\r
- padding:5px;\r
- height:14px;\r
- line-height:12px;\r
- font-size:10px;\r
- text-shadow:0 1px 0 #000;\r
- color:#fff;\r
- background:#222;\r
- z-index:1;\r
- /* Use the ARIA valuetext property, set by the script, to generate the \r
- tooltip content */ \r
- content:attr(aria-valuetext); \r
- -webkit-border-radius:3px;\r
- -moz-border-radius:3px;\r
- border-radius:3px;\r
- -webkit-box-shadow: 0 0 4px #aaa;\r
- -moz-box-shadow: 0 0 4px #aaa;\r
- box-shadow: 0 0 4px #aaa; \r
- }\r
-.fd-slider-handle:after\r
- {\r
- outline:none;\r
- content:""; \r
- display:block; \r
- position:absolute;\r
- top:-14px;\r
- left:50%;\r
- margin:0 0 0 -5px;\r
- background:#222;\r
- z-index:2;\r
- width:10px;\r
- height:10px;\r
- overflow:hidden;\r
- /* Rotate element by 45 degress to get the "\/" pointer effect */\r
- -webkit-transform: rotate(45deg); \r
- -moz-transform: rotate(45deg);\r
- -ms-transform: rotate(45deg);\r
- -o-transform: rotate(45deg);\r
- -webkit-box-shadow: 0 0 4px #aaa;\r
- -moz-box-shadow: 0 0 4px #aaa;\r
- box-shadow: 0 0 4px #aaa;\r
- clip:rect(4px, 14px, 14px, 4px); \r
- }\r
-/* Change opacity and position to kick in the transitions */ \r
-.fd-slider-focused .fd-slider-handle:before,\r
-.fd-slider-hover .fd-slider-handle:before,\r
-.fd-slider-active .fd-slider-handle:before\r
- {\r
- top:-25px; \r
- opacity:1; \r
- }\r
-.fd-slider-focused .fd-slider-handle:after,\r
-.fd-slider-hover .fd-slider-handle:after,\r
-.fd-slider-active .fd-slider-handle:after\r
- {\r
- top:-9px; \r
- opacity:1; \r
- }\r
-/* Remove completely for IE 6, 7 and 8 */\r
-.oldie .fd-slider-handle:before,\r
-.oldie .fd-slider-handle:after\r
- {\r
- display:none;\r
- }
\ No newline at end of file
+++ /dev/null
-/* \r
-\r
- Don't use this version of the file in a production environment. A minified \r
- version tailored specifically to your needs can be generated in-browser by\r
- using the /css-generator/index.html file.\r
- \r
- Notes for the adventurous:\r
- \r
- 1. The script automagically adds the classname "oldie" to IE6, 7 & 8.\r
- \r
- 2. A combination of the .oldie class and "safe css hacks" are used to target \r
- specific IE versions. See: http://mathiasbynens.be/notes/safe-css-hacks\r
- \r
- 3. MSHTML has been used to base64 encode the various png images used for the \r
- drag handle in IE6 and 7. IE7 gets served one base64 encoded image sprite \r
- whereas IE6 gets served individual base64 encoded images.\r
- \r
- See: http://www.phpied.com/the-proper-mhtml-syntax/ for more info on MHTML\r
- \r
- The base64 encoded images have been placed into their own .mht file. This\r
- means only IE6 and 7 will ever be burdened with downloading the file.\r
- \r
- A Microsoft security update in July 2011 means that .mht files now have to\r
- be delivered with the mimetype "message/rfc822". If using IIS, there is \r
- nothing to do as IIS appears to default to using the required \r
- "message/rfc822" mimetype, if using Apache, there are two ways in which to\r
- configure this behaviour:\r
- \r
- A. You have Admin rights and can restart the Apache server\r
- \r
- Update the apache_root/httpd/conf/Srm.conf file and add the following \r
- line:\r
- \r
- AddType message/rfc822 mht\r
- \r
- This method requires that you restart Apache.\r
- \r
- B. You can simply use an htaccess directive \r
- \r
- You can add the following to an .htaccess file that sits in the same \r
- directory as the .mht file (or to an htaccess file at the root of your\r
- website if one exists already): \r
- \r
- AddType message/rfc822 mht\r
- \r
- You do not need to restart Apache for the change to take effect.\r
- \r
- Yikes - I cant do either of the above!\r
- \r
- Don't worry, using the .mht file isn't compulsory - just replace the \r
- various mhtml: references (found within the .oldie classes) to point to \r
- the correct image file on your server (not forgetting to actually upload \r
- the image files to your server of course). \r
- \r
- All of the relevant rules have further instructions embedded within them.\r
- \r
- 4. All browsers but IE6 get one "normal" base64 encoded image sprite. IE6 has\r
- to use separate images for each animation state.\r
- \r
- 5. The drag handle is only 20px in width & height, most probably not suitable \r
- for touch screen devices. \r
- \r
- 6. It's painless to base64 encode your own images, use an online encoder. \r
- See: http://www.google.com/search?q=base+64+encoder - the only problem is \r
- that IE6 needs each frame of the handle sprite to be encoded individually.\r
- \r
- 7. If you want to use a different image for vertical slider drag handles,\r
- uncomment the relevant classes below (easy to spot as they all have the \r
- classname ".fd-slider-vertical" somewhere within the declaration).\r
- \r
- 8. As a reminder, the following HTML is being targetted by the CSS:\r
- \r
-<span class="fd-slider[-vertical]" \r
- id="fd-slider-[the associated form element id]" \r
- role="application" \r
- aria-disabled="false">\r
- <span class="fd-slider-wrapper (fd-slider-[focus|hover|no-value|disabled|active])">\r
- <span class="fd-slider-inner"></span>\r
- <span class="fd-slider-range"></span>\r
- <span class="fd-slider-bar"></span>\r
- <span class="fd-slider-handle" \r
- tabindex="0" \r
- role="slider" \r
- aria-valuemin="-10" \r
- aria-valuemax="10" \r
- aria-labelledby="[the associated form element label id]" \r
- id="fd-slider-handle-[the associated form element id]" \r
- aria-describedby="fd-slider-describedby" \r
- aria-valuenow="-3.50" \r
- aria-valuetext="-3.50"> </span>\r
- </span>\r
-</span>\r
-\r
-*/\r
-\r
-/*\r
- Element: Form element associated with the slider\r
- Notes: The styles given to the associated form element in order to hide \r
- it within the display\r
-*/ \r
-.fd-form-element-hidden\r
- {\r
- display:none;\r
- } \r
-/*\r
- Element: Outer wrapper\r
- Orientation: Horizontal \r
-*/ \r
-.fd-slider\r
- { \r
- width:100%;\r
- height:20px;\r
- margin:0 0 10px 0;\r
- }\r
-/*\r
- Element: Outer wrapper\r
- Orientation: Vertical\r
- Notes: You may wish to float the vertical sliders left or use\r
- display:inline-block (inline-block should work even in IE6 as the slider\r
- is constructed from span elements but don't quote me on that)\r
-*/ \r
-.fd-slider-vertical\r
- { \r
- width:20px;\r
- height:100%; \r
- margin:0 10px 10px 0; \r
- }\r
-/*\r
- Element: Outer wrapper\r
- Orientation: Both horizontal & vertical\r
-*/ \r
-.fd-slider,\r
-.fd-slider-vertical\r
- {\r
- text-align:center;\r
- display:block;\r
- position:relative;\r
- cursor:pointer; \r
- text-decoration:none;\r
- border:0 none;\r
- -webkit-user-select: none;\r
- -khtml-user-select: none;\r
- -moz-user-select: none;\r
- -ms-user-select: none;\r
- -o-user-select: none;\r
- user-select: none;\r
- }\r
-/*\r
- Element: Outer Wrapper \r
- Orientation: Both horizontal & vertical\r
- Notes: IE6 & 7 need a transparent gif as a background in order for\r
- hover events to work. This has been base64 encoded within the .mht file.\r
- As it's not a png, no AlphaImageLoader filter is required for IE6. \r
-*/\r
-.oldie .fd-slider,\r
-.oldie .fd-slider-vertical\r
- {\r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- *background:transparent url(mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!blank) repeat;\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the blank.gif file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- *background:transparent url(http://www.your-domain.com/the/path/to/blank.gif) repeat;\r
- \r
- */ \r
- } \r
-/*\r
- Element: Inner wrapper\r
- Notes: All other DOM elements added as children to this element.\r
-*/\r
-.fd-slider-wrapper\r
- {\r
- position:absolute;\r
- top:0;\r
- left:0;\r
- width:100%;\r
- height:100%;\r
- }\r
-/*\r
- Element: Inner wrapper\r
- Notes: IE6 needs an expression as it cannot do a height:100% on \r
- absolutely positioned elements and it also can't position on four \r
- corners - so we are left with a "one time evaluated" self-deleting \r
- expression to do the dirty work.\r
-*/\r
-\r
-.oldie .fd-slider-vertical .fd-slider-wrapper\r
- {\r
- *clear:expression(style.height=parentNode.offsetHeight+'px',style.clear='none', 0);\r
- }\r
-/*\r
- Element: ieBlur shiv\r
- Notes: Used only by IE for the onfocus "Blur" effect\r
-*/ \r
-.fd-slider-inner\r
- {\r
- display:none;\r
- }\r
-/*\r
- Element: ieBlur shiv\r
- Orientation: Horizontal\r
- Notes: IE6, 7 & 8 only.\r
- Use the "Blur" filter to simulate the box-shadow - not brilliant but the \r
- best we can do for IE. IE6 can't absolutely position on 4 sides so we \r
- reset the right to "auto" and use a nasty expression to calculate the \r
- width dynamically. \r
-*/ \r
-.oldie .fd-slider-inner\r
- { \r
- position:absolute; \r
- height:2px;\r
- border:1px solid #bbf;\r
- background:#bbf; \r
- top:4px; \r
- bottom:auto;\r
- left:4px;\r
- right:12px; \r
- z-index:2; \r
- margin:0;\r
- padding:0;\r
- overflow:hidden;\r
- line-height:4px; \r
- _right:auto;\r
- _width:expression((this.parentNode.offsetWidth - 12) + "px");\r
- filter:progid:DXImageTransform.Microsoft.Blur(pixelradius=3.5); \r
- }\r
-/*\r
- Element: ieBlur shiv\r
- Orientation: Vertical\r
- Notes: Reposition the "Blur" filter for the vertical slider for IE6, \r
- 7 & 8. The "Blur" filter rule cascades from the rule above so no need to \r
- redeclare here, we just reposition.\r
-*/ \r
-.oldie .fd-slider-vertical .fd-slider-inner\r
- { \r
- width:2px;\r
- height:auto; \r
- bottom:12px;\r
- right:auto; \r
- _bottom:auto;\r
- *clear:expression(style.height=(parentNode.offsetHeight - 8)+'px',style.clear='none', 0);\r
- }\r
-/*\r
- Element: ieBlur shiv\r
- Orientation: Horizontal & Vertical\r
- Notes: Display the "Blurred" inner div for IE6, 7 & 8 when the slider \r
- gains focus\r
-*/ \r
-.oldie .fd-slider-focused .fd-slider-inner\r
- { \r
- display:block;\r
- } \r
-/*\r
- Element: Inner track bar\r
- Orientation: Horizontal \r
-*/\r
-.fd-slider-bar\r
- {\r
- display:block;\r
- position:absolute;\r
- top:8px;\r
- right:10px; \r
- left:10px; \r
- z-index:2;\r
- height:2px;\r
- margin:0;\r
- padding:0;\r
- overflow:hidden;\r
- border:1px solid #bbb;\r
- border-bottom:1px solid #aaa;\r
- border-right:1px solid #aaa;\r
- border:1px solid rgba(187, 187, 187, .8);\r
- border-bottom:1px solid rgba(170, 170, 170, .8);\r
- border-right:1px solid rgba(170, 170, 170, .8); \r
- line-height:4px;\r
- background-color:#ddd;\r
- background-image: -webkit-gradient(linear, left top, left bottom, from(#ececec), to(#ccc)); \r
- background-image: -webkit-linear-gradient(top, #ececec, #ccc); \r
- background-image: -moz-linear-gradient(top, #ececec, #ccc); \r
- background-image: -ms-linear-gradient(top, #ececec, #ccc); \r
- background-image: -o-linear-gradient(top, #ececec, #ccc); \r
- background-image: linear-gradient(to bottom, #ececec, #ccc);\r
- border-radius:2px;\r
- -webkit-background-clip: padding-box; \r
- -moz-background-clip: padding; \r
- background-clip: padding-box;\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Horizontal\r
- Notes: For IE6 & 7 & 8. IE6 does not recognise absolute positioning on \r
- four sides (top, right, bottom & left) so we use an expression to \r
- dynamically calculate the track bar size. Yes, it is horrible - you \r
- don't need to remind me.\r
-*/\r
-.oldie .fd-slider-bar\r
- {\r
- _right:auto; \r
- _width:expression((this.parentNode.offsetWidth - 20) + "px");\r
- filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffececec',endColorstr='#ffcccccc');\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Vertical\r
-*/\r
-.fd-slider-vertical .fd-slider-bar\r
- { \r
- width:2px; \r
- top:10px;\r
- right:auto;\r
- bottom:10px;\r
- left:8px; \r
- height:auto;\r
- background-color:#ddd;\r
- background-image: -webkit-gradient(linear, left top, right top, from(#ececec), to(#ccc)); \r
- background-image: -webkit-linear-gradient(left, #ececec, #ccc); \r
- background-image: -moz-linear-gradient(left, #ececec, #ccc); \r
- background-image: -ms-linear-gradient(left, #ececec, #ccc); \r
- background-image: -o-linear-gradient(left, #ececec, #ccc); \r
- background-image: linear-gradient(to right, #ececec, #ccc);\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Vertical\r
- Notes: For IE6 & 7 & 8. The gradient filter colour strings in AARRGGBB \r
- format (to save you one less google). IE6 gets repositioned and alas,\r
- an expression to calculate the height.\r
-*/\r
-.oldie .fd-slider-vertical .fd-slider-bar\r
- { \r
- _bottom:auto;\r
- *clear:expression(style.height=(parentNode.offsetHeight - 20)+'px',style.clear='none', 0);\r
- filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ffececec',endColorstr='#ffcccccc');\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Horizontal & Vertical\r
- State: Focused\r
- Notes: Drop shadow on the inner bar when focused - newer browsers get \r
- an animation. IE6, 7 & 8 get a "Blur" filter on an inner SPAN \r
- .fd-slider-inner instead \r
-*/\r
-.fd-slider-focused .fd-slider-bar\r
- {\r
- box-shadow: 0 0 6px rgba(10, 130, 170, 0.7);\r
- -webkit-animation:fd-pulse 2s infinite;\r
- -moz-animation:fd-pulse 2s infinite;\r
- -o-animation:fd-pulse 2s infinite;\r
- animation:fd-pulse 2s infinite;\r
- } \r
-/*\r
- Element: Inner animated range bar \r
- Orientation: Horizontal\r
-*/\r
-.fd-slider-range\r
- {\r
- display:block;\r
- position:absolute;\r
- top:9px;\r
- left:11px; \r
- z-index:3;\r
- height:2px; \r
- margin:0;\r
- padding:0;\r
- overflow:hidden;\r
- line-height:2px;\r
- background-color:#4cc;\r
- background-image: -webkit-gradient(linear, left top, right top, from(#6cc), to(#3cf)); \r
- background-image: -webkit-linear-gradient(left, #6cc, #3cf); \r
- background-image: -moz-linear-gradient(left, #6cc, #3cf); \r
- background-image: -ms-linear-gradient(left, #6cc, #3cf); \r
- background-image: -o-linear-gradient(left, #6cc, #3cf); \r
- background-image: linear-gradient(to right, #6cc, #3cf);\r
- border-radius:2px;\r
- -webkit-background-clip: padding-box; \r
- -moz-background-clip: padding; \r
- background-clip: padding-box;\r
- }\r
-/*\r
- Element: Inner range bar \r
- Orientation: Horizontal\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-range\r
- {\r
- /* IE6 - is this needed? To test. */ \r
- _left:10px;\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff66cccc',endColorstr='#ff33ccff');\r
- }\r
-/*\r
- Element: Inner range bar \r
- Orientation: Vertical\r
-*/\r
-.fd-slider-vertical .fd-slider-range\r
- {\r
- height:auto;\r
- width:2px;\r
- top:auto; \r
- right:auto;\r
- bottom:11px;\r
- left:9px; \r
- background-image: -webkit-gradient(linear, left top, left bottom, from(#3cf), to(#6cc)); \r
- background-image: -webkit-linear-gradient(top, #3cf, #6cc); \r
- background-image: -moz-linear-gradient(top, #3cf, #6cc); \r
- background-image: -ms-linear-gradient(top, #3cf, #6cc); \r
- background-image: -o-linear-gradient(top, #3cf, #6cc); \r
- background-image: linear-gradient(to bottom, #3cf, #6cc); \r
- }\r
-/*\r
- Element: Inner range bar \r
- Orientation: Vertical\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-vertical .fd-slider-range\r
- {\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff66cccc',endColorstr='#ff33ccff');\r
- } \r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal\r
- State: Default.\r
- Notes: The image sprite used for the handle is base64 encoded below. IE7\r
- gets its own version within the .mht file, IE6 does not use an image\r
- sprite and it is necessary to base64 encode individual animation frames\r
- within the .mht file.\r
-*/\r
-.fd-slider-handle\r
- {\r
- position:absolute;\r
- display:block;\r
- padding:0;\r
- border:0 none;\r
- margin:0;\r
- z-index:3;\r
- top:0;\r
- left:0;\r
- width:20px;\r
- height:20px;\r
- outline:0 none;\r
- background-color:transparent;\r
- background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjFFRDg4NEVDNENDODExRTFCMTZDREIyQTZDMjlDNTQ2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjFFRDg4NEVENENDODExRTFCMTZDREIyQTZDMjlDNTQ2Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MUVEODg0RUE0Q0M4MTFFMUIxNkNEQjJBNkMyOUM1NDYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MUVEODg0RUI0Q0M4MTFFMUIxNkNEQjJBNkMyOUM1NDYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz68iMNZAAAIQElEQVR42uxYW28b1xGes7tckiIp3iRboi6mbollya5DF4VsVWpaw42ABCmaogWSFH3oDyjQoijQP2AUyFOLFshbn4SqsYFabowmdaW4NhDJiKXaUuwotm6UKJK6kKIkipfl7p7OWR3aa5kiVdQoEjQLDM7u2TPfnss3MztDKKXwPC8BnvP1xQeUSnUSvGBwshl8R18Fq70PZOtx44WSn4F89hYkV6/B26ElWuIAyP4+xBKd70311tXV/bzb7+oLOcDaYiWSTSAkR0EfT9P8UDj1j8Rq/Lfw1ukx1NcOnKExs4tDbT6f75e9tc6+c05q90gEtwWRdAoyblG/k4jeVvcr76qKZePi0K9Q5ZF5pvuXLENj6xv1Pvc5n6DJyQJAQgGdjWZCuFQRwTLQ7P/W6PaLb0YBfoNd+YMAq8BR/TIpFCzhDECEgK5SeGafJAJEA0FqO+L7LgL+rhygEwE7FrMFWMqAVvY4CX6I2hoMHYDNg5es60I8Z9xXNiHd2A25PG3WInFPY9BfLRFiwePQS8AKuJEFHWA3Fl1PVOChArPT96Gp5YRDJMSFoExZ1Z8cisQ/sqOBroRnZgydMoBpGLk8mm9uDemdJzs8kkA8FgZKQMSXbFN1ZEiqQGl26eFS4cbwiKFTxvQyMPbhZPb9weHl6bsL4ZymZzRKXSKBADKbtew5+vDB8vKVwb8kPrh029A5yFIMYgO4UNrh1Nl+6H/9PBwPtUMg6DcGRBcTMDM5CzevjsDU2E3smUXZMRO7pOlh40AJoAR56+KvdxgsyiJvd/ebHinlYPlMZYPoezyTHx/a3p6xZSqHcg5fCn9ITC0xPRcvapJnLEoqASQUOczvRdM7WqQjisqfdTOwtA9M5GLhByHzMSJ/r3EghUuB92kcg5pnKHJlK4qdSxV/Lo5Tuatip5zlkjd9zBhITEtjyg5FUdx/iuVeuJQi35lTxZc2QGpkg2tAjbRJ2r9+6KGjb9bbHsqyLOzbV53RhnAwG+NcMpn0vxPVvz2pWn/sc9i6TlcRyzErCDbkZhY94CdpWhhPZO72yvnBXzeI/8RwkeDcZE5Pk0wHIOfz+ao/r6RP3M67ftLhtXb3OInFKyFXGV9xAnZ0qn0ukL2iPfS3mCri2PWfOhwTVqtV4duhC6Yly/F43H0lBa8QW1WnX6TSlqqTRQx1KHRhT/BeJw6BSl0+58mPdoXXmA4/PAOrOEPjQGKxmHtRD4aaqS5G8wRWC0B1YFvyhDXovigOpgWKftZq/0Ys9sh97Nix9SK9zLQRNzY2XEnP8QDJaSReIFTECIpbR83cZaaqUZ1q6GUF3eJnOmauPmUpu7u7FnDrwpqigygKCMimAcRMazZDjYmGY3R1T6eEpRgWUCgUVM/uZlLx1Lp8shFTCC6YFBHZwRi+hAqQ1yhYt7ZSTIdz8LGlFM1JxeXt1iUjC2FPbbMVuzFQ4SzxJX0SU9g3VJzdFm7u0VQszHT4CWtFSynao+JwOBKdCzMfp1w1L6iB5oATQ4nXQowoZwDrBMEpwSCsy4n4Wmv8848dDd4EN0N9b+57gIZ9NjU1JTvU7YmWR7dv5FcWV8NZVUurGrXjXtYiH1mbVnWajUc2XA/GP2rKbNxmOhxQNdsyAy20tbVtz8/Pz21PTV1zfBLfnm/s6rlzpKVxq7q2mg1yb69v16wtRFoj98fbIXsreOrUHNPhTuKpPWTT1TweT66rq2sdN3oaPvts2zf19xm0ngAeqpOHhjRaRRTNba6zszOMYxNMx+TSaDEEPOW+kFvyxMSEc2VlpZqRXVVVm/F1ScrV19dvNTQ0bJ85cyZdU1OjmNwXmAGfu4M1u3Ld1P5XIWA/MP1CRL0vcZ5y4cKFZuTcq6Io9qEYeYqmaTMot5Cb165fv374PGVgYOAckvdntbW1fdjKaOMicpABUuSoMjs7O5pKpX6PoJXzlJ6enrbq6upfIIG/iYA2FtlYIEMww9lin4h9F6anpy04dq1inoKzeQMBe1HJiksTstnsfgrhDy2Rg8FgP5roj/D5nbJ5isVieRk/aNnZ2SHpdFo/4HePNRa/338e2z+UzVMQsAPBBASrRGzCf0jL5yk4o1LLLHnx2ZfPUxAs7na7fThT/iN7MBiuZK0SD5Wtra37CNiJ3COMKgx034+98YwujSLgg4p5SiQSGXW5XCGkTTueNEF5Csj4qqIA8nB+aWnpmTxlP2AGfy0m7Xb7MN7/AEGDgiAQm80GbAuQJjSXywGOCSO5h8Ph8J1D5ylIif5AIHDe6/W2V1VVGXlKJpNJbG5uzkaj0ZFEIvFVnvJ/67H/p6WqWvAd/TpY7V0gWxt5qSoC+ex9SK7egbdD64cNAYLzvakTdXV13+v2u7pCDrC0WInAS1V0HNOKoXDqbmI1fhXeOj2D+nqlUlU9xpHv99Y6u845qeyRGCcfl6pIv5NYva3u0LuqIm1cHPojqkTLhQAJGlvP1vvcnT5Bk3ipipYoVYkDzf7u0e0X+9FcLvPfuZKAVnBUn0QvIPJSFS1TqhLbjvheQsC/lgO0IWCAl6r0Q5Sq/DylSx8EaPkPS1XAU+GypapNT2PQdchS1ValUlUBZqeXoKmliZeqoEypiirhmYh5/0oB5mDk8r18c2ub3nkyUKFUtVa4MXyPp7UHml4exj6cy74/OL48fTcezmnUVKoCU6lqY/nK4Fjig0ufm4P8QSGAlQbq4dTZbuh//WtwPFQPgaCLl6p2YGYyBjev3oOpsU+xJ8Yib6UQIHAq+FCO8tZeDNsoLNFZ5W1uv+mVCwHFgobNRI0C3zO2TPWrEGBc/xZgAJyadcoLu6zuAAAAAElFTkSuQmCC);\r
- background-position:0 0;\r
- cursor:W-resize; \r
- line-height:20px;\r
- font-size:10px; \r
- -moz-outline:0 none;\r
- -webkit-touch-callout: none; \r
- -webkit-user-select: none;\r
- -khtml-user-select: none;\r
- -moz-user-select: none;\r
- -ms-user-select: none;\r
- -o-user-select: none;\r
- user-select: none; \r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal\r
- State: Default\r
- Notes: IE6, 7 & 8 use a nasty expression in order to not draw focus \r
- outline on drag handle. \r
-*/\r
-.oldie .fd-slider-handle\r
- {\r
- /* IE6 & 7 - set the handle sprite as the background image */ \r
- \r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- *background-image:url(mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!fullsprite);\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the fd-slider-sprite.png \r
- file on your server (replace "www.your-domain.com/the/path/to/") \r
- */\r
- \r
- /* \r
- \r
- *background-image:url(http://www.your-domain.com/the/path/to/fd-slider-sprite.png);\r
- \r
- */ \r
- \r
- /**********************************************************************/\r
- \r
- /* IE6 - reset the background image sprite stipulated above. */\r
- _background-image:none;\r
-\r
- /* \r
- IE6 - use the AlphaImageLoader to either load a base64 encoded image \r
- from the .mht file or a normal png image from the server \r
- */\r
- \r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handlenormal');\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the fd-handle-normal.png\r
- file on your server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-normal.png');\r
- \r
- */\r
- \r
- /* IE6, 7 & 8 */\r
- outline:expression(hideFocus='true');\r
- } \r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal & Vertical\r
- State: Focused\r
- Notes: Attempts to remove the focus outline, remove the rule if it\r
- offends your sensibilities.\r
-*/\r
-.fd-slider-handle:focus\r
- {\r
- outline:0 none;\r
- border:0 none;\r
- -moz-user-focus:normal;\r
- }\r
-.fd-slider-handle:focus::-moz-focus-inner \r
- { \r
- border-color: transparent; \r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal\r
- State: Focused and Hovered and also while handle is animating into \r
- position or being dragged.\r
- Notes: I'm using the same image for focused, hover and active states\r
- but you can, of course, go wild.\r
-*/\r
-.fd-slider-focused .fd-slider-handle,\r
-.fd-slider-hover .fd-slider-handle,\r
-.fd-slider-active .fd-slider-handle\r
- {\r
- background-position:0 -20px;\r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal\r
- State: Focused and Hovered and also while handle is animating into \r
- position or being dragged.\r
- Notes: IE6 only.\r
-*/\r
-.oldie .fd-slider-focused .fd-slider-handle,\r
-.oldie .fd-slider-hover .fd-slider-handle,\r
-.oldie .fd-slider-active .fd-slider-handle\r
- {\r
- /* \r
- IE6 - use the AlphaImageLoader to either load a base64 encoded image \r
- from the .mht file or a normal png image from the server \r
- */\r
- \r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handleglow');\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the fd-handle-glow.png\r
- file on your server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-glow.png');\r
-\r
- */\r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Vertical\r
- Notes: Change the cursor to the correct icon.\r
-*/\r
-.fd-slider-vertical .fd-slider-handle\r
- {\r
- cursor:N-resize;\r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Vertical\r
- Notes: IE6, 7 & 8\r
- \r
-.oldie .fd-slider-vertical .fd-slider-handle\r
- {\r
- }\r
-*/\r
-/*\r
- Element: Drag handle \r
- Orientation: Vertical\r
- State: Focused and Hovered and also while handle is animating into \r
- position or being dragged.\r
- \r
-.fd-slider-vertical .fd-slider-focused .fd-slider-handle,\r
-.fd-slider-vertical .fd-slider-hover .fd-slider-handle,\r
-.fd-slider-vertical .fd-slider-active .fd-slider-handle\r
- {\r
- }\r
-*/\r
-/*\r
- Element: Drag handle \r
- Orientation: Vertical\r
- State: Focused and Hovered and also while handle is animating into \r
- position or being dragged.\r
- Notes: IE6, 7 & 8\r
- \r
-.oldie .fd-slider-vertical .fd-slider-focused .fd-slider-handle,\r
-.oldie .fd-slider-vertical .fd-slider-hover .fd-slider-handle,\r
-.oldie .fd-slider-vertical .fd-slider-active .fd-slider-handle\r
- {\r
- }\r
-*/\r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal & Vertical\r
- State: User has not yet used the slider to set a value\r
- Notes: I screwed the positioning of the image sprite by 1px which is why\r
- it's -59px and not -60px. Yeah - I suck at Photoshop. \r
-*/\r
-.fd-slider-no-value .fd-slider-handle\r
- {\r
- background-position:0 -59px;\r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Horizontal\r
- State: User has not yet used the slider to set a value\r
- Notes: IE6 only\r
-*/\r
-.oldie .fd-slider-no-value .fd-slider-handle\r
- {\r
- /* \r
- IE6 - use the AlphaImageLoader to either load a base64 encoded image \r
- from the .mht file or a normal png image from the server \r
- */\r
- \r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handlenovalue');\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the fd-handle-no-value.png\r
- file on your server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-no-value.png');\r
-\r
- */\r
- }\r
-/*\r
- Element: Drag handle \r
- Orientation: Vertical\r
- State: User has not yet used the slider to set a value\r
- Notes: IE6, 7 & 8. Only required should you use a different image for\r
- vertical sliders.\r
- \r
-.oldie .fd-slider-vertical .fd-slider-no-value .fd-slider-handle\r
- {\r
- } \r
-*/ \r
-/*\r
- Element: document.body\r
- Orientation: Horizontal and Vertical\r
- Notes: Class given to body to change cursor style when dragging. It also\r
- attempts to stop text selection while dragging. \r
-*/\r
-body.fd-slider-drag-horizontal,\r
-body.fd-slider-drag-horizontal *,\r
-body.fd-slider-drag-vertical,\r
-body.fd-slider-drag-vertical *\r
- {\r
- cursor:N-resize !important;\r
- -webkit-user-select: none;\r
- -moz-user-select: none;\r
- -ms-user-select: none;\r
- -o-user-select: none;\r
- user-select: none;\r
- }\r
-/*\r
- Element: document.body\r
- Orientation: Horizontal\r
- Notes: Class given to body to change cursor style when dragging \r
-*/\r
-body.fd-slider-drag-horizontal,\r
-body.fd-slider-drag-horizontal *\r
- {\r
- cursor:W-resize !important;\r
- }\r
-/*\r
- Element: Inner wrapper\r
- Orientation: Horizontal & Vertical\r
- State: disabled\r
- Notes: Class given to slider when disabled\r
-*/ \r
-.fd-slider-disabled\r
- {\r
- opacity:.8;\r
- cursor:default;\r
- }\r
-/*\r
- Element: Drag handle\r
- Orientation: Horizontal\r
- State: disabled\r
- Notes: Class given to slider when disabled\r
-*/ \r
-.fd-slider-disabled .fd-slider-handle\r
- {\r
- cursor:default !important;\r
- background-position:0 -40px;\r
- opacity:1;\r
- }\r
-/*\r
- Element: Drag handle\r
- Orientation: Horizontal\r
- State: disabled\r
- Notes: IE6 only\r
-*/ \r
-.oldie .fd-slider-disabled .fd-slider-handle\r
- {\r
- /* \r
- IE6 - use the AlphaImageLoader to either load a base64 encoded image \r
- from the .mht file or a normal png image from the server \r
- */\r
- \r
- /* \r
- If using the .mht file then uncomment the following rule and edit the \r
- filepath to match the absolute path to the fd-slider.mht file on your \r
- server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handledisabled');\r
- \r
- */\r
- \r
- /* \r
- If not using the .mht file then uncomment the following rule and edit \r
- the filepath to match the absolute path to the fd-handle-disabled.png\r
- file on your server (replace "www.your-domain.com/the/path/to/") \r
- */ \r
- \r
- /*\r
- \r
- _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-disabled.png');\r
-\r
- */\r
- }\r
-/*\r
- Element: Drag handle\r
- Orientation: Vertical\r
- State: disabled\r
- \r
-.fd-slider-vertical .fd-slider-disabled .fd-slider-handle\r
- {\r
- }\r
-.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-handle\r
- {\r
- }\r
-*/ \r
-/*\r
- Element: Inner track bar\r
- Orientation: Horizontal\r
- State: disabled\r
-*/ \r
-.fd-slider-disabled .fd-slider-bar\r
- {\r
- cursor:auto !important;\r
- border:1px solid #888;\r
- border-bottom:1px solid #999;\r
- border-right:1px solid #999;\r
- border:1px solid rgba(136,136,136,.8);\r
- border-bottom:1px solid rgba(153,153,153,.8);\r
- border-right:1px solid rgba(153,153,153,.8);\r
- background-color:#555;\r
- background-image: -webkit-gradient(linear, left top, right top, from(#666), to(#333)); \r
- background-image: -webkit-linear-gradient(left, #666, #333); \r
- background-image: -moz-linear-gradient(left, #666, #333); \r
- background-image: -ms-linear-gradient(left, #666, #333); \r
- background-image: -o-linear-gradient(left, #666, #333); \r
- background-image: linear-gradient(to right, #666, #333);\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Vertical\r
- State: disabled\r
-*/ \r
-.fd-slider-vertical .fd-slider-disabled .fd-slider-bar\r
- {\r
- background-image: -webkit-gradient(linear, left top, right bottom, from(#333), to(#666)); \r
- background-image: -webkit-linear-gradient(top, #333, #666); \r
- background-image: -moz-linear-gradient(top, #333, #666); \r
- background-image: -ms-linear-gradient(top, #333, #666); \r
- background-image: -o-linear-gradient(top, #333, #666); \r
- background-image: linear-gradient(to bottom, #333, #666);\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Horizontal\r
- State: disabled\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-disabled .fd-slider-bar\r
- {\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff666666',endColorstr='#ff333333');\r
- }\r
-/*\r
- Element: Inner track bar\r
- Orientation: Vertical\r
- State: disabled\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-bar\r
- {\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff666666',endColorstr='#ff333333');\r
- }\r
-/*\r
- Element: Range bar\r
- Orientation: Horizontal\r
- State: disabled\r
-*/\r
-.fd-slider-disabled .fd-slider-range\r
- {\r
- cursor:auto !important;\r
- background-color:#222;\r
- background-image: -webkit-gradient(linear, left top, right top, from(#222), to(#000)); \r
- background-image: -webkit-linear-gradient(left, #222, #000); \r
- background-image: -moz-linear-gradient(left, #222, #000); \r
- background-image: -ms-linear-gradient(left, #222, #000); \r
- background-image: -o-linear-gradient(left, #222, #000); \r
- background-image: linear-gradient(to right, #222, #000);\r
- }\r
-/*\r
- Element: Range bar\r
- Orientation: Horizontal\r
- State: disabled\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-disabled .fd-slider-range\r
- {\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff222222',endColorstr='#ff000000');\r
- }\r
-/*\r
- Element: Range bar\r
- Orientation: Vertical\r
- State: disabled\r
-*/\r
-.fd-slider-vertical .fd-slider-disabled .fd-slider-range\r
- {\r
- background-image: -webkit-gradient(linear, left top, right bottom, from(#000), to(#222)); \r
- background-image: -webkit-linear-gradient(top, #000, #222); \r
- background-image: -moz-linear-gradient(top, #000, #222); \r
- background-image: -ms-linear-gradient(top, #000, #222); \r
- background-image: -o-linear-gradient(top, #000, #222); \r
- background-image: linear-gradient(to bottom, #000, #222); \r
- }\r
-/*\r
- Element: Range bar\r
- Orientation: Vertical\r
- State: disabled\r
- Notes: IE6, 7 & 8\r
-*/\r
-.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-range\r
- {\r
- filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff222222',endColorstr='#ff000000');\r
- }\r
-/* \r
- The various prefixed keyframe rules for the glow effect used whenever\r
- the slider gains keyboard focus\r
-*/\r
-@-webkit-keyframes fd-pulse {\r
-0% {\r
- box-shadow:0 0 3px rgba(100, 130, 170, 0.55);\r
- }\r
-20% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-40% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-60% {\r
- box-shadow:0 0 6px rgba(10, 130, 170, 0.7);\r
- }\r
-80% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-100% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-}\r
-@-moz-keyframes fd-pulse {\r
-0% {\r
- box-shadow:0 0 3px rgba(100, 130, 170, 0.55);\r
- }\r
-20% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-40% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-60% {\r
- box-shadow:0 0 6px rgba(10, 130, 170, 0.7);\r
- }\r
-80% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-100% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-}\r
-@-o-keyframes fd-pulse {\r
-0% {\r
- box-shadow:0 0 3px rgba(100, 130, 170, 0.55);\r
- }\r
-20% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-40% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-60% {\r
- box-shadow:0 0 6px rgba(10, 130, 170, 0.7);\r
- }\r
-80% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-100% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-}\r
-@keyframes fd-pulse {\r
-0% {\r
- box-shadow:0 0 3px rgba(100, 130, 170, 0.55);\r
- }\r
-20% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-40% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-60% {\r
- box-shadow:0 0 6px rgba(10, 130, 170, 0.7);\r
- }\r
-80% {\r
- box-shadow:0 0 5px rgba(40, 130, 170, 0.65);\r
- }\r
-100% {\r
- box-shadow:0 0 4px rgba(70, 130, 170, 0.6);\r
- }\r
-}\r
+++ /dev/null
-/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */
-var fdSlider=function(){function ut(n){function nf(n){n=!!n,n!=ft&&(ft=n,pt(kt()))}function nu(){if(!p||d=="select")return;var n=g(e);if(n.min==tt&&n.max==st&&n.step==nt)return;tt=+n.min,st=+n.max,ut=tt,it=st,nt=+n.step,ir=Math.abs(st-tt),li=nt*2,bi=Math.ceil(ir/nt),ft=!1,ar(tt,st)}function gr(n){if(oi&&!n)return;try{di(l,-1),i(l,"focus",fu),i(l,"blur",su),o?i(l,"keypress",yi):(i(l,"keydown",yi),i(l,"keypress",ou)),i(a,"mouseover",br),i(a,"mouseout",sr),i(a,"mousedown",fi),i(a,"touchstart",fi),c&&(window.addEventListener&&!window.devicePixelRatio?window.removeEventListener("DOMMouseScroll",at,!1):(i(document,"mousewheel",at),i(window,"mousewheel",at)))}catch(t){}u(v,"fd-slider-focused"),u(v,"fd-slider-active"),f(v,"fd-slider-disabled"),a.setAttribute("aria-disabled",!0),e.disabled=oi=!0,clearTimeout(ht),n||ot("disable")}function hu(n){if(!oi&&!n)return;di(l,0),t(l,"focus",fu),t(l,"blur",su),o?t(l,"keypress",yi):(t(l,"keydown",yi),t(l,"keypress",ou)),t(a,"touchstart",fi),t(a,"mousedown",fi),t(a,"mouseover",br),t(a,"mouseout",sr),u(v,"fd-slider-disabled"),a.setAttribute("aria-disabled",!1),e.disabled=oi=gt=!1,n||ot("enable")}function ku(){clearTimeout(ht),ri=vt=l=a=v=ht=null,ot("destroy"),ki=null}function ii(){wr();try{var t=a.offsetWidth,n=a.offsetHeight,r=l.offsetWidth,i=l.offsetHeight,o=vt.offsetHeight,s=vt.offsetWidth,u=b?n-i:t-r;ct=u/bi,ni=Math.max(et?er(tr(ut)):Math.abs((ut-tt)/nt)*ct,0),bt=Math.min(et?er(tr(it)):Math.abs((it-tt)/nt)*ct,Math.floor(b?n-i:t-r)),ru=t,dr=n,pt(nr?kt():d=="select"?e.selectedIndex:parseFloat(e.value),!1)}catch(f){}ot("redraw")}function ot(n){var r,i,u,t;if(wt){if(n.match(/^(blur|focus|change)$/i))if(typeof document.createEvent!="undefined")t=document.createEvent("HTMLEvents"),t.initEvent(n,!0,!0),e.dispatchEvent(t);else if(typeof document.createEventObject!="undefined")try{t=document.createEventObject(),e.fireEvent("on"+n.toLowerCase(),t)}catch(f){}}else if(ki.hasOwnProperty(n))for(r={userSet:ft,disabled:oi,elem:e,value:d=="select"?e.options[e.selectedIndex].value:e.value},i=0;u=ki[n][i];i++)u.call(e,r)}function fu(){return f(v,"fd-slider-focused"),h.onfocus&&(ft=!0,pt(kt())),c&&(t(window,"DOMMouseScroll",at),t(document,"mousewheel",at),o||t(window,"mousewheel",at)),ot("focus"),!0}function su(){u(v,"fd-slider-focused"),c&&(i(document,"mousewheel",at),i(window,"DOMMouseScroll",at),o||i(window,"mousewheel",at)),lt=!0,ot("blur")}function at(n){if(!lt)return;n=n||window.event;var t=0,i;n.wheelDelta?(t=n.wheelDelta/120,o&&window.opera.version()<9.2&&(t=-t)):n.detail&&(t=-n.detail/3),b&&(t=-t),t&&(i=kt(),i+=t<0?-nt:nt,ft=!0,pt(hi(i))),s(n)}function ou(n){return n=n||window.event,n.keyCode>=33&&n.keyCode<=40||!lt||n.keyCode==45||n.keyCode==46?k(n):!0}function yi(n){if(!lt)return!0;n=n||window.event;var t=n.keyCode!==null?n.keyCode:n.charCode,i;if(t<33||t>40&&t!=45&&t!=46)return!0;i=kt(),t==37||t==40||t==46||t==34?i-=n.ctrlKey||t==34?+li:+nt:t==39||t==38||t==45||t==33?i+=n.ctrlKey||t==33?+li:+nt:t==35?i=it:t==36&&(i=ut),ft=!0,pt(hi(i)),ot("update"),s(n)}function br(){f(v,"fd-slider-hover")}function sr(){u(v,"fd-slider-hover")}function fi(n){var u,r;n=n||window.event,s(n),n.target?u=n.target:n.srcElement&&(u=n.srcElement),u&&u.nodeType==3&&(u=u.parentNode);if(n.touches){if(n.targetTouches&&n.targetTouches.length!=1)return!1;n=n.touches[0],gt=!0}return clearTimeout(ht),ht=null,lt=!1,ft=!0,u.className.search("fd-slider-handle")!=-1?(rr=b?n.clientY:n.clientX,tu=parseInt(b?l.offsetTop:l.offsetLeft)||0,ci(n),gt?(t(document,"touchmove",ci),t(document,"touchend",vi),i(a,"mousedown",fi)):(t(document,"mousemove",ci),t(document,"mouseup",vi)),f(v,"fd-slider-active"),f(document.body,"fd-slider-drag-"+(b?"vertical":"horizontal")),ot("dragstart")):(wr(),r=0,n.pageX||n.pageY?r=b?n.pageY:n.pageX:(n.clientX||n.clientY)&&(r=b?n.clientY+document.body.scrollTop+document.documentElement.scrollTop:n.clientX+document.body.scrollLeft+document.documentElement.scrollLeft),r-=b?hr+Math.round(l.offsetHeight/2):iu+Math.round(l.offsetWidth/2),r=pi(r),pr=="tween"?(f(v,"fd-slider-active"),bu(r)):pr=="timed"?(f(v,"fd-slider-active"),t(document,gt?"touchend":"mouseup",cr),ui=r,yr()):ai(r)),!1}function cr(n){return n=n||window.event,s(n),i(document,gt?"touchend":"mouseup",cr),u(v,"fd-slider-active"),clearTimeout(ht),ht=null,lt=!0,!1}function vi(n){return n=n||window.event,s(n),gt?(i(document,"touchmove",ci),i(document,"touchend",vi)):(i(document,"mousemove",ci),i(document,"mouseup",vi)),lt=!0,u(document.body,"fd-slider-drag-"+(b?"vertical":"horizontal")),u(v,"fd-slider-active"),ot("dragend"),!1}function ci(n){n=n||window.event,s(n);if(n.touches){if(n.targetTouches&&n.targetTouches.length!=1)return!1;n=n.touches[0]}return ai(pi(tu+(b?n.clientY-rr:n.clientX-rr))),!1}function ei(n){var t=kt();ft=!0,t+=n*nt,pt(hi(t))}function wr(){var i=0,t=0,n=a;try{do i+=n.offsetLeft,t+=n.offsetTop;while(n=n.offsetParent)}catch(r){}iu=i,hr=t}function yr(){var n=parseInt(b?l.offsetTop:l.offsetLeft,10);n=Math.round(ui<n?Math.max(ui,Math.floor(n-ct)):Math.min(ui,Math.ceil(n+ct))),ai(pi(n)),n!=ui?ht=setTimeout(yr,bi>20?50:100):(lt=!0,u(v,"fd-slider-active"),ot("finalise"))}function bu(n){lt=!1,or=parseInt(n,10),fr=parseInt(b?l.offsetTop:l.offsetLeft,10),uu=or-fr,lu=20,ur=0,ht||(ht=setTimeout(gi,20))}function si(n){return isNaN(n)||n===""||typeof n=="undefined"?(ft=!1,yt):n<Math.min(ut,it)?(ft=!1,Math.min(ut,it)):n>Math.max(ut,it)?(ft=!1,Math.max(ut,it)):(ft=!0,n)}function kt(){return hi(d=="input"?parseFloat(e.value):e.selectedIndex)}function hi(n){return isNaN(n)||n===""||typeof n=="undefined"?yt:Math.min(Math.max(n,Math.min(ut,it)),Math.max(ut,it))}function ai(n){var t=hi(et?du(tf(n)):b?st-Math.round(n/ct)*nt:tt+Math.round(n/ct)*nt);l.style[b?"top":"left"]=(n||0)+"px",lr(),vr(d=="select"||nt==1?Math.round(t):t)}function pt(n,t){var r=!1,i;(typeof n=="undefined"||isNaN(n)||n==="")&&d=="input"&&!nr?(i=yt,r=!0,ft=!1):i=si(n),l.style[b?"top":"left"]=(et?er(tr(i)):b?Math.round((st-i)/nt*ct):Math.round((i-tt)/nt*ct))+"px",lr(),!0&&vr(r?"":i)}function pi(n){if(et)return Math.max(Math.min(bt,n),ni);var t=n%ct;return t&&t>=ct/2?n+=ct-t:n-=t,n<Math.min(Math.abs(ni),Math.abs(bt))?n=Math.min(Math.abs(ni),Math.abs(bt)):n>Math.max(Math.abs(ni),Math.abs(bt))&&(n=Math.max(Math.abs(ni),Math.abs(bt))),Math.min(Math.max(n,0),bt)}function du(n){var i=0,r=tt,u,t;for(t in et){if(!et.hasOwnProperty(t))continue;n<i||n>+t||(u=r+(n-i)*(+et[t]-r)/(+t-i)),i=+t,r=+et[t]}return u}function tr(n){var r=0,i=tt,u=0,t;for(t in et){if(!et.hasOwnProperty(t))continue;n<i||n>+et[t]||(u=r+(n-i)*(+t-r)/(+et[t]-i)),r=+t,i=+et[t]}return u}function er(n){return(a[b?"offsetHeight":"offsetWidth"]-l[b?"offsetHeight":"offsetWidth"])/100*n}function tf(n){return n/((a[b?"offsetHeight":"offsetWidth"]-a[l?"offsetHeight":"offsetWidth"])/100)}function vr(n){ot("update"),ft?u(v,"fd-slider-no-value"):f(v,"fd-slider-no-value");if(d=="select")try{n=parseInt(n,10);if(e.selectedIndex===n){dt();return}e.options[n].selected=!0}catch(t){}else{n===""||wi||(n=(tt+Math.round((+n-tt)/nt)*nt).toFixed(yu));if(e.value===n){dt();return}e.value=n}dt(),ot("change")}function ar(n,t){ut>it?(n=Math.min(tt,Math.max(n,t)),t=Math.max(st,Math.min(n,t)),ut=Math.max(n,t),it=Math.min(n,t)):(n=Math.max(tt,Math.min(n,t)),t=Math.min(st,Math.max(n,t)),ut=Math.min(n,t),it=Math.max(n,t)),yt<Math.min(ut,it)?yt=Math.min(ut,it):yt>Math.max(ut,it)&&(yt=Math.max(ut,it)),l.setAttribute("aria-valuemin",ut),l.setAttribute("aria-valuemax",it),si(d=="input"?parseFloat(e.value):e.selectedIndex),ii()}function lr(){if(y)return;b?ti.style.height=Math.max(1,vt.offsetHeight-l.offsetTop)+"px":ti.style.width=Math.max(1,l.offsetLeft)+"px"}function cu(){for(var t=!1,r=document.getElementsByTagName("label"),n,i=0;n=r[i];i++)if(n.htmlFor&&n.htmlFor==e.id||n.getAttribute("for")==e.id){t=n;break}return t&&!t.id&&(t.id=e.id+"_label"),t}function dt(){var n=d=="select"?e.options[e.selectedIndex].value:e.value,t=kr?kr(n):d=="select"?e.options[e.selectedIndex].text?e.options[e.selectedIndex].text:n:n;l.setAttribute("aria-valuenow",n),l.setAttribute("aria-valuetext",t)}function wu(){ft=!0,wi=gu,pt(d=="input"?parseFloat(e.value):e.selectedIndex),dt(),wi=!1}function pu(){d=="input"?e.value=e.defaultValue:e.selectedIndex=au,si(d=="select"?e.options[e.selectedIndex].value:e.value),ii(),dt()}function di(n,t){n.setAttribute("tabIndex",t),n.tabIndex=t}var e=n.inp,oi=!1,d=e.tagName.toLowerCase(),tt=+n.min,st=+n.max,ut=+n.min,it=+n.max,ir=Math.abs(st-tt),nt=d=="select"?1:+n.step,li=n.maxStep?+n.maxStep:nt*2,yu=n.precision||0,bi=Math.ceil(ir/nt),et=n.scale||!1,rf=!!n.hideInput,pr=n.animation||"",b=!!n.vertical,ki=n.callbacks||{},vu=n.classNames||"",wt=!!n.html5Shim,yt=st<tt?tt:tt+(st-tt)/2,au=d=="select"?e.selectedIndex:e.defaultValue||yt,nr=wt||!!n.forceValue,eu=wt&&b&&"inpHeight"in n?n.inpHeight:!1,kr=!wt&&n.ariaFormat?n.ariaFormat:!1,gu=!wt&&!(d=="select")&&"userSnap"in n?!!n.userSnap:!1,wi=!1,ht=null,lt=!0,ff=d=="select"?e.selectedIndex:e.value,dr=0,ru=0,or=0,fr=0,uu=0,lu=0,ur=0,iu=0,hr=0,bt=0,ni=0,tu=0,ui=0,rr=0,ct=0,ft=!1,gt=!1,a,v,ri,l,ti,vt,gi;return d=="input"&&nr&&!e.defaultValue&&(e.defaultValue=kt()),st<tt&&(nt=-Math.abs(nt),li=-Math.abs(li)),et&&(et[100]=st),gi=function(){ur++;var r=uu,n=20,t=ur,i=fr,f=Math.ceil(t==n?i+r:r*(-Math.pow(2,-10*t/n)+1)+i);ai(t==n?or:f),t!=n?(ot("move"),ht=setTimeout(gi,20)):(clearTimeout(ht),ht=null,lt=!0,u(v,"fd-slider-focused"),u(v,"fd-slider-active"),ot("finalise"))},(function(){if(wt||rf){f(e,"fd-form-element-hidden");try{e.type!="range"&&r(e,"type")=="range"&&document.defaultView.getComputedStyle(e,null).getPropertyValue("display")=="inline-block"&&(e.type="number")}catch(i){}}else t(e,"change",wu);wt&&(e.setAttribute("fd-range-enabled",1),e.stepUp=function(n){ei(n||1)},e.stepDown=function(n){ei(n||-1)},p&&t(e,typeof e.onpropertychange=="object"?"propertychange":"DOMAttrModified",nu)),a=document.createElement("span"),a.className="fd-slider"+(b?"-vertical ":" ")+vu,a.id="fd-slider-"+e.id,b&&eu&&(a.style.height=eu+"px"),v=document.createElement("span"),v.className="fd-slider-wrapper"+(wt?"":" fd-slider-no-value"),ri=document.createElement("span"),ri.className="fd-slider-inner",vt=document.createElement("span"),vt.className="fd-slider-bar",rt?l=document.createElement("span"):(l=document.createElement("a"),l.setAttribute("href","#"),t(l,"click",k)),di(l,0),l.className="fd-slider-handle",l.appendChild(document.createTextNode(String.fromCharCode(160))),v.appendChild(ri),y||(ti=document.createElement("span"),ti.className="fd-slider-range",v.appendChild(ti)),v.appendChild(vt),v.appendChild(l),a.appendChild(v),e.parentNode.insertBefore(a,e),o&&(l.unselectable="on",vt.unselectable="on",ri.unselectable="on",a.unselectable="on",v.unselectable="on",y||(ti.unselectable="on")),a.setAttribute("role","application"),l.setAttribute("role","slider"),l.setAttribute("aria-valuemin",d=="select"?e.options[0].value:tt),l.setAttribute("aria-valuemax",d=="select"?e.options[e.options.length-1].value:st);var n=cu();if(n){l.setAttribute("aria-labelledby",n.id),l.id="fd-slider-handle-"+e.id;/*@if(@_win32)n.setAttribute("htmlFor",l.id);@else@*/n.setAttribute("for",l.id);/*@end@*/}document.getElementById(w)&&l.setAttribute("aria-describedby",w),e.getAttribute("disabled")==!0||e.getAttribute("disabled")=="disabled"?gr(!0):hu(!0),h.onvalue&&(ft=!0,si(d=="input"?parseFloat(e.value):e.selectedIndex)),e.form&&t(e.form,"reset",pu),dt(),ot("create"),ii()})(),{onResize:function(){(a.offsetHeight!=dr||a.offsetWidth!=ru)&&ii()},destroy:function(){ku()},reset:function(){pt(d=="input"?parseFloat(e.value):e.selectedIndex)},stepUp:function(n){ei(Math.abs(n)||1)},stepDown:function(n){ei(-Math.abs(n)||-1)},increment:function(n){ei(n)},disable:function(){gr()},enable:function(){hu()},setRange:function(n,t){ar(n,t)},getValueSet:function(){return!!ft},setValueSet:function(n){nf(n)},rescan:function(){nu()},checkValue:function(){h.onvalue&&(ft=!0,si(d=="input"?parseFloat(e.value):e.selectedIndex)),dt(),ii()}}}var n={},lt=0,c=!0,rt=!0,w="fd-slider-describedby",h={onfocus:!0,onvalue:!0},y=!1,ft="jump",p=!1,o=Object.prototype.toString.call(window.opera)==="[object Opera]",v=/^([\-]{0,1}[0-9]+(\.[0-9]+){0,1})$/,b=/^([0-9]+(\.[0-9]+){0,1})$/,ot=function(n){if(typeof n!="string"||n==="")return{};try{if(typeof JSON=="object"&&typeof JSON.parse=="function")return JSON.parse(n);if(/mousewheelenabled|fullaria|describedby|norangebar|html5animation|varsetrules/.test(n.toLowerCase())){var t=Function(["var document,top,self,window,parent,Number,Date,Object,Function,","Array,String,Math,RegExp,Image,ActiveXObject;","return (",n.replace(/<\!--.+-->/gim,"").replace(/\bfunction\b/g,"function-"),");"].join(""));return t()}}catch(i){}return{err:"Could not parse the JSON object"}},it=function(n){if(typeof n!="object")return;for(var t in n){value=n[t];switch(t.toLowerCase()){case"mousewheelenabled":c=!!value;break;case"fullaria":rt=!!value;break;case"describedby":w=String(value);break;case"norangebar":y=!!value;break;case"html5animation":ft=String(value).search(/^(jump|tween|timed)$/i)!=-1?String(value).toLowerCase():"jump";break;case"watchattributes":p=!!value;break;case"varsetrules":"onfocus"in value&&(h.onfocus=!!value.onfocus),"onvalue"in value&&(h.onvalue=!!value.onvalue)}}},t=function(n,t,i){n.addEventListener?n.addEventListener(t,i,!0):n.attachEvent&&n.attachEvent("on"+t,i)},i=function(n,t,i){try{n.removeEventListener?n.removeEventListener(t,i,!0):n.detachEvent&&n.detachEvent("on"+t,i)}catch(r){}},k=function(n){n=n||window.event,n.stopPropagation&&(n.stopPropagation(),n.preventDefault());/*@cc_on@if(@_win32)n.cancelBubble=!0,n.returnValue=!1;@end@*/return!1},s=function(n){n=n||window.event;if(n.preventDefault){n.preventDefault();return}n.returnValue=!1},f=function(n,t){if(new RegExp("(^|\\s)"+t+"(\\s|$)").test(n.className))return;n.className+=(n.className?" ":"")+t},u=function(n,t){n.className=t?n.className.replace(new RegExp("(^|\\s)"+t+"(\\s|$)")," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""):""},ct=function(){var i={},t;for(t in n)i[t]=n[t].getValueSet();return i},st=function(t,i){n[t].setValueSet(!!i)},e=function(t){return!!(t in n&&n.hasOwnProperty(t))},vt=function(t){if(!t||!t.inp||!t.inp.tagName||t.inp.tagName.search(/^input|select/i)==-1)return!1;t.html5Shim=!1;if(t.inp.tagName.toLowerCase()=="select"){if(t.inp.options.length<2)return!1;t.min=0,t.max=t.inp.options.length-1,t.step=1,t.precision=0,t.scale=!1,t.forceValue=!0}else{if(String(t.inp.type).search(/^(text|range)$/i)==-1)return!1;t.min=t.min&&String(t.min).search(v)!=-1?+t.min:0,t.max=t.max&&String(t.max).search(v)!=-1?+t.max:100,t.step=t.step&&String(t.step).search(b)!=-1?t.step:1,t.precision=t.precision&&String(t.precision).search(/^[0-9]+$/)!=-1?t.precision:String(t.step).search(/\.([0-9]+)$/)!=-1?String(t.step).match(/\.([0-9]+)$/)[1].length:0,t.scale=t.scale||!1,t.forceValue="forceValue"in t?!!t.forceValue:!1,t.userSnap="userSnap"in t?!!t.userSnap:!1}return t.ariaFormat="ariaFormat"in t&&typeof t.ariaFormat=="function"?t.ariaFormat:!1,t.maxStep=t.maxStep&&String(t.maxStep).search(b)!=-1?+t.maxStep:+t.step*2,t.classNames=t.classNames||"",t.callbacks=t.callbacks||!1,a(t.inp.id),n[t.inp.id]=new ut(t),!0},r=function(n,t){return n.getAttribute(t)||""},l=function(){for(var e=document.getElementsByTagName("input"),i,u,t,f=0;t=e[f];f++)if(t.tagName.toLowerCase()=="input"&&r(t,"type")&&r(t,"type").toLowerCase()=="range"&&(r(t,"min")&&r(t,"min").search(v)!=-1||r(t,"max")&&r(t,"max").search(v)!=-1||r(t,"step")&&r(t,"step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i)!=-1)){if(t.id&&document.getElementById("fd-slider-"+t.id))continue;else t.id&&!document.getElementById("fd-slider-"+t.id)&&a(t.id);t.id||(t.id="fd-slider-form-elem-"+lt++),i={inp:t,callbacks:[],animation:ft,vertical:r(t,"data-fd-slider-vertical")?!0:t.offsetHeight>t.offsetWidth,classNames:r(t,"data-fd-slider-vertical"),html5Shim:!0},i.vertical&&!r(t,"data-fd-slider-vertical")&&(i.inpHeight=t.offsetHeight),u=g(t),i.min=u.min,i.max=u.max,i.step=u.step,i.precision=String(i.step).search(/\.([0-9]+)$/)!=-1?String(i.step).match(/\.([0-9]+)$/)[1].length:0,i.maxStep=i.step*2,a(i.inp.id),n[i.inp.id]=new ut(i)}return!0},g=function(n){return{min:+(r(n,"min")||0),max:+(r(n,"max")||100),step:+(r(n,"step").search(b)!=-1?n.getAttribute("step"):1)}},a=function(t){return t in n&&n.hasOwnProperty(t)?(n[t].destroy(),delete n[t],!0):!1},tt=function(){for(var i in n)n.hasOwnProperty(i)&&n[i].destroy();n=[]},at=function(){tt(),n=null},d=function(){for(var i in n)n.hasOwnProperty(i)&&n[i].onResize()},et=function(){for(var t in n)n.hasOwnProperty(t)&&n[t].rescan()},ht=function(){nt(),l()},nt=function(){i(window,"load",l)};t(window,"load",l),t(window,"load",function(){setTimeout(function(){var t;for(t in n)n[t].checkValue()},0)}),t(window,"resize",d),t(window,"unload",at),(function(){var t=document.getElementsByTagName("script"),n=ot(String(t[t.length-1].innerHTML).replace(/[\n\r\s\t]+/g," ").replace(/^\s+/,"").replace(/\s+$/,""));typeof n!="object"||"err"in n||it(n)})();/*@if(@_jscript_version<9)f(document.documentElement,"oldie");@end@*/return{rescanDocument:l,createSlider:function(n){return vt(n)},onDomReady:function(){ht()},destroyAll:function(){tt()},destroySlider:function(n){return a(n)},redrawAll:function(){d()},addEvent:t,removeEvent:i,stopEvent:k,increment:function(t,i){if(!e(t))return!1;n[t].increment(i)},stepUp:function(t,i){if(!e(t))return!1;n[t].stepUp(Math.abs(i)||1)},stepDown:function(t,i){if(!e(t))return!1;n[t].stepDown(-Math.abs(i)||-1)},setRange:function(t,i,r){if(!e(t))return!1;n[t].setRange(i,r)},updateSlider:function(t){if(!e(t))return!1;n[t].onResize(),n[t].reset()},disable:function(t){if(!e(t))return!1;n[t].disable()},enable:function(t){if(!e(t))return!1;n[t].enable()},getValueSet:function(){return ct()},setValueSet:function(n,t){if(!e(id))return!1;st(n,t)},setGlobalVariables:function(n){it(n)},removeOnload:function(){nt()},rescanAttributes:et}}()
\ No newline at end of file
50%
fill #ff9d00
-.header-content .estop
+.estop
width 130px
transition 250ms
> svg
margin 1em
- .console
+.console
+ table
width 100%
+ margin 0.5em 0
+ border-collapse collapse
+
+ td, th
+ border 1px solid #ddd
tr
> td
&.debug td
color green
- .indicators
- table
- display inline-block
- vertical-align top
- margin 0.5em
- empty-cells show
+.indicators
+ table
+ display inline-block
+ vertical-align top
+ margin 0.5em
+ empty-cells show
- td, th
- padding 4px
+ td, th
+ padding 4px
- tr:nth-child(odd)
- background #f7f7f7
+ tr:nth-child(odd)
+ background #f7f7f7
- td:nth-child(1), td:nth-child(3)
- text-align center
+ td:nth-child(1), td:nth-child(3)
+ text-align center
- th:nth-child(2), th:nth-child(4)
- text-align left
+ th:nth-child(2), th:nth-child(4)
+ text-align left
- &.inputs, &.outputs
- td:nth-child(1), td:nth-child(4)
- text-align center
+ &.inputs, &.outputs
+ td:nth-child(1), td:nth-child(4)
+ text-align center
- th:nth-child(2), th:nth-child(5)
- text-align right
+ th:nth-child(2), th:nth-child(5)
+ text-align right
- th:nth-child(3), th:nth-child(6)
- text-align left
+ th:nth-child(3), th:nth-child(6)
+ text-align left
- .logic-lo
- color black
+ .logic-lo
+ color black
- .logic-hi
- color green
+ .logic-hi
+ color green
- .warn
- background-color transparent
- color orange
+ .warn
+ background-color transparent
+ color orange
- .video
- text-align center
- line-height 0
+.video
+ text-align center
+ line-height 0
.tabs
border 1px solid #ddd
padding 0.5em
+
+.upgrade-version
+ display inline-block
+ border-radius 4px
+ padding 2px
+ margin-left 0.5em
+ color #555
+ background-color #e5aa3d
+ text-decoration none
+
+ &:hover
+ color #fff
+
.modal-mask
position fixed
z-index 9998
position fixed
top -1000px
+.error-message
+ &.modal-mask .modal-wrapper .modal-container
+ width auto
+ max-width 800px
+
+ .modal-header h3
+ white-space nowrap
+ overflow hidden
+ text-overflow ellipsis
+
+ .estop
+ float right
+ transform scale(0.75)
+ margin-top -30px
+
+
@media only screen and (max-width 48em)
.header
height auto