diff --git a/README.md b/README.md index e0fe3c2ca7..1c905a8b2b 100755 --- a/README.md +++ b/README.md @@ -64,9 +64,9 @@ You can use as many operations as you like in simple or complex ways. Some examp - Highlighting - When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][10]). - Save to file and load from file - - You can save the output to a file at any time or load a file by dragging and dropping it into the input field (note that files larger than about 500kb may cause your browser to hang or even crash due to the way that browsers handle large amounts of textual data). + - You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 500MB are supported (depending on your browser), however some operations may take a very long time to run over this much data. - CyberChef is entirely client-side - - It should be noted that none of your input or recipe configuration is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer. + - It should be noted that none of your recipe configuration or input (either text or files) is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer. - Due to this feature, CyberChef can be compiled into a single HTML file. You can download this file and drop it into a virtual machine, share it with other people, or use it independently on your desktop. diff --git a/package-lock.json b/package-lock.json index 5821d84a50..8370224bb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,21 +36,21 @@ } }, "access-sniff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.1.0.tgz", - "integrity": "sha512-m8w34KtU7jD89lJ8jMUFoyy9VInfROR/0sKEkfVfcMqVRSGG3I2Y34XNBmz2ROPZK96x1ue5PET5H6gJ79BN7Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.0.1.tgz", + "integrity": "sha1-IJ4W63DAlaA79/yCnsrLfHeS9e4=", "dev": true, "requires": { "HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0", "axios": "0.9.1", - "bluebird": "3.5.1", + "bluebird": "3.5.0", "chalk": "1.1.3", - "commander": "2.12.2", + "commander": "2.11.0", "glob": "7.1.2", "jsdom": "9.12.0", "mkdirp": "0.5.1", - "phantomjs-prebuilt": "2.1.16", - "rc": "1.2.2", + "phantomjs-prebuilt": "2.1.15", + "rc": "1.2.1", "underscore": "1.8.3", "unixify": "0.2.1", "validator": "5.7.0" @@ -120,21 +120,21 @@ } }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", + "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", "dev": true, "requires": { "co": "4.6.0", "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" } }, "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", "dev": true }, "align-text": { @@ -312,9 +312,9 @@ "dev": true }, "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", "dev": true, "requires": { "lodash": "4.17.4" @@ -339,10 +339,10 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000784", + "caniuse-db": "1.0.30000741", "normalize-range": "0.1.2", "num2fraction": "1.2.2", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" }, "dependencies": { @@ -352,8 +352,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000784", - "electron-to-chromium": "1.3.29" + "caniuse-db": "1.0.30000741", + "electron-to-chromium": "1.3.24" } } } @@ -406,13 +406,13 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "convert-source-map": "1.5.1", + "convert-source-map": "1.5.0", "debug": "2.6.9", "json5": "0.5.1", "lodash": "4.17.4", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", - "private": "0.1.8", + "private": "0.1.7", "slash": "1.0.0", "source-map": "0.5.7" } @@ -898,7 +898,7 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.3", + "core-js": "2.5.1", "regenerator-runtime": "0.10.5" } }, @@ -935,7 +935,7 @@ "babel-plugin-transform-es2015-unicode-regex": "6.24.1", "babel-plugin-transform-exponentiation-operator": "6.24.1", "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.10.0", + "browserslist": "2.5.1", "invariant": "2.2.2", "semver": "5.4.1" } @@ -948,7 +948,7 @@ "requires": { "babel-core": "6.26.0", "babel-runtime": "6.26.0", - "core-js": "2.5.3", + "core-js": "2.5.1", "home-or-tmp": "2.0.0", "lodash": "4.17.4", "mkdirp": "0.5.1", @@ -960,14 +960,14 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" }, "dependencies": { "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" } } }, @@ -1060,9 +1060,9 @@ "dev": true }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", "dev": true }, "bn.js": { @@ -1234,13 +1234,13 @@ } }, "browserslist": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz", - "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz", + "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000784", - "electron-to-chromium": "1.3.29" + "caniuse-lite": "1.0.30000751", + "electron-to-chromium": "1.3.24" } }, "buffer": { @@ -1332,7 +1332,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000784", + "caniuse-db": "1.0.30000741", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1343,22 +1343,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000784", - "electron-to-chromium": "1.3.29" + "caniuse-db": "1.0.30000741", + "electron-to-chromium": "1.3.24" } } } }, "caniuse-db": { - "version": "1.0.30000784", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000784.tgz", - "integrity": "sha1-G+lQEtlInHcZB0+BruV9vf/mNhs=", + "version": "1.0.30000741", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000741.tgz", + "integrity": "sha1-C+WREdQiHyH2ErUO5dZ4caLEp6U=", "dev": true }, "caniuse-lite": { - "version": "1.0.30000784", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz", - "integrity": "sha1-EpztdOmhKApEGIC2zSvOMO9Z5sA=", + "version": "1.0.30000751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000751.tgz", + "integrity": "sha1-KYrTQYLKQ1l1e0qTr8aBt7kX41g=", "dev": true }, "caseless": { @@ -1399,12 +1399,6 @@ "supports-color": "2.0.0" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -1496,9 +1490,9 @@ } }, "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", "dev": true }, "co": { @@ -1513,7 +1507,7 @@ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", "dev": true, "requires": { - "q": "1.5.1" + "q": "1.5.0" } }, "code-point-at": { @@ -1534,15 +1528,15 @@ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "dev": true, "requires": { - "clone": "1.0.3", - "color-convert": "1.9.1", + "clone": "1.0.2", + "color-convert": "1.9.0", "color-string": "0.3.0" } }, "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", "dev": true, "requires": { "color-name": "1.1.3" @@ -1589,9 +1583,9 @@ } }, "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "commondir": { @@ -1675,15 +1669,15 @@ "dev": true }, "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", + "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", "dev": true }, "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", "dev": true }, "cookie": { @@ -1699,9 +1693,9 @@ "dev": true }, "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" }, "core-util-is": { "version": "1.0.2", @@ -1847,7 +1841,7 @@ "loader-utils": "1.1.0", "lodash.camelcase": "4.3.0", "object-assign": "4.1.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-modules-extract-imports": "1.1.0", "postcss-modules-local-by-default": "1.2.0", "postcss-modules-scope": "1.1.0", @@ -1915,7 +1909,7 @@ "defined": "1.0.0", "has": "1.0.1", "object-assign": "4.1.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-calc": "5.3.1", "postcss-colormin": "2.2.2", "postcss-convert-values": "2.6.1", @@ -2003,7 +1997,7 @@ "dev": true, "requires": { "image-size": "0.3.5", - "mimer": "0.2.3", + "mimer": "0.2.1", "semver": "5.4.1" }, "dependencies": { @@ -2101,14 +2095,6 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "rimraf": "2.2.8" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } } }, "delayed-stream": { @@ -2196,12 +2182,13 @@ } }, "doctrine": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", - "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "2.0.2", + "isarray": "1.0.0" } }, "dom-converter": { @@ -2313,9 +2300,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.29.tgz", - "integrity": "sha1-elgja5VGjD52YAkTSFItZddzazY=", + "version": "1.3.24", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz", + "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=", "dev": true }, "elliptic": { @@ -2373,12 +2360,12 @@ "dev": true }, "errno": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", - "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", "dev": true, "requires": { - "prr": "1.0.1" + "prr": "0.0.0" } }, "error-ex": { @@ -2450,9 +2437,9 @@ } }, "es6-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", - "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", + "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=", "dev": true }, "es6-set": { @@ -2537,33 +2524,33 @@ } }, "eslint": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", - "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.8.0.tgz", + "integrity": "sha1-Ip7w41Tg5h2DfHqA/fuoJeGZgV4=", "dev": true, "requires": { - "ajv": "5.5.2", + "ajv": "5.2.3", "babel-code-frame": "6.26.0", - "chalk": "2.3.0", + "chalk": "2.1.0", "concat-stream": "1.6.0", "cross-spawn": "5.1.0", "debug": "3.1.0", - "doctrine": "2.0.2", + "doctrine": "2.0.0", "eslint-scope": "3.7.1", - "espree": "3.5.2", + "espree": "3.5.1", "esquery": "1.0.0", "estraverse": "4.2.0", "esutils": "2.0.2", "file-entry-cache": "2.0.0", "functional-red-black-tree": "1.0.1", "glob": "7.1.2", - "globals": "11.1.0", - "ignore": "3.3.7", + "globals": "9.18.0", + "ignore": "3.3.5", "imurmurhash": "0.1.4", "inquirer": "3.3.0", - "is-resolvable": "1.0.1", + "is-resolvable": "1.0.0", "js-yaml": "3.10.0", - "json-stable-stringify-without-jsonify": "1.0.1", + "json-stable-stringify": "1.0.1", "levn": "0.3.0", "lodash": "4.17.4", "minimatch": "3.0.4", @@ -2593,18 +2580,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "debug": { @@ -2630,12 +2617,6 @@ "path-is-absolute": "1.0.1" } }, - "globals": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", - "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", - "dev": true - }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", @@ -2668,9 +2649,9 @@ } }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -2772,19 +2753,19 @@ } }, "espree": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", - "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", + "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", "dev": true, "requires": { - "acorn": "5.2.1", + "acorn": "5.1.2", "acorn-jsx": "3.0.1" }, "dependencies": { "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", "dev": true } } @@ -3000,13 +2981,13 @@ "dev": true }, "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", + "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", "dev": true, "requires": { - "chardet": "0.4.2", "iconv-lite": "0.4.19", + "jschardet": "1.5.1", "tmp": "0.0.33" } }, @@ -3025,24 +3006,33 @@ "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", "dev": true, "requires": { - "async": "2.6.0", + "async": "2.5.0", "loader-utils": "1.1.0", "schema-utils": "0.3.0", - "webpack-sources": "1.1.0" + "webpack-sources": "1.0.1" } }, "extract-zip": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", - "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", + "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", "dev": true, "requires": { "concat-stream": "1.6.0", - "debug": "2.6.9", + "debug": "2.2.0", "mkdirp": "0.5.0", "yauzl": "2.4.1" }, "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, "mkdirp": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", @@ -3051,6 +3041,12 @@ "requires": { "minimist": "0.0.8" } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true } } }, @@ -3066,12 +3062,6 @@ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", "dev": true }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -3130,6 +3120,11 @@ "schema-utils": "0.3.0" } }, + "file-saver": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", + "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI=" + }, "file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -3188,7 +3183,7 @@ "dev": true, "requires": { "commondir": "1.0.1", - "make-dir": "1.1.0", + "make-dir": "1.0.0", "pkg-dir": "2.0.0" } }, @@ -4320,14 +4315,6 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } } }, "google-code-prettify": { @@ -4401,7 +4388,7 @@ "integrity": "sha1-/uK+5WHjPOl8lfk/7ogEPfFFokk=", "dev": true, "requires": { - "access-sniff": "3.1.0" + "access-sniff": "3.0.1" } }, "grunt-chmod": { @@ -4476,8 +4463,8 @@ "integrity": "sha512-VZlDOLrB2KKefDDcx/wR8rEEz7smDwDKVblmooa+itdt/2jWw3ee2AiZB5Ap4s4AoRY0pbHRjZ3HHwY8uKR9Rw==", "dev": true, "requires": { - "chalk": "2.3.0", - "eslint": "4.13.1" + "chalk": "2.1.0", + "eslint": "4.8.0" }, "dependencies": { "ansi-styles": { @@ -4486,18 +4473,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -4507,9 +4494,9 @@ "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -4659,7 +4646,7 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "5.5.2", + "ajv": "5.2.3", "har-schema": "2.0.0" } }, @@ -4725,7 +4712,7 @@ "boom": "4.3.1", "cryptiles": "3.1.2", "hoek": "4.2.0", - "sntp": "2.1.0" + "sntp": "2.0.2" } }, "he": { @@ -4792,12 +4779,12 @@ "dev": true }, "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", + "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", "dev": true, "requires": { - "whatwg-encoding": "1.0.3" + "whatwg-encoding": "1.0.1" } }, "html-entities": { @@ -4807,19 +4794,19 @@ "dev": true }, "html-minifier": { - "version": "3.5.7", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.7.tgz", - "integrity": "sha512-GISXn6oKDo7+gVpKOgZJTbHMCUI2TSGfpg/8jgencWhWJsvEmsvp3M8emX7QocsXsYznWloLib3OeSfeyb/ewg==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.5.tgz", + "integrity": "sha512-g+1+NBycQI0fGnggd52JM8TRUweG7+9W2wrtjGitMAqc4G7maweAHvVAAjz9veHseIH3tYKE2lk2USGSoewIrQ==", "dev": true, "requires": { "camel-case": "3.0.0", "clean-css": "4.1.9", - "commander": "2.12.2", + "commander": "2.11.0", "he": "1.1.1", "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.2.2" + "uglify-js": "3.1.3" } }, "html-webpack-plugin": { @@ -4828,8 +4815,8 @@ "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", "dev": true, "requires": { - "bluebird": "3.5.1", - "html-minifier": "3.5.7", + "bluebird": "3.5.0", + "html-minifier": "3.5.5", "loader-utils": "0.2.17", "lodash": "4.17.4", "pretty-error": "2.1.1", @@ -5003,7 +4990,7 @@ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", "dev": true, "requires": { - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -5012,18 +4999,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -5033,26 +5020,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -5067,9 +5048,9 @@ "dev": true }, "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", "dev": true }, "image-size": { @@ -5143,9 +5124,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", "dev": true }, "ink-docstrap": { @@ -5155,7 +5136,7 @@ "dev": true, "requires": { "moment": "2.20.1", - "sanitize-html": "1.16.3" + "sanitize-html": "1.15.0" } }, "inquirer": { @@ -5165,10 +5146,10 @@ "dev": true, "requires": { "ansi-escapes": "3.0.0", - "chalk": "2.3.0", + "chalk": "2.1.0", "cli-cursor": "2.1.0", "cli-width": "2.2.0", - "external-editor": "2.1.0", + "external-editor": "2.0.5", "figures": "2.0.0", "lodash": "4.17.4", "mute-stream": "0.0.7", @@ -5192,18 +5173,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -5222,9 +5203,9 @@ } }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -5400,13 +5381,13 @@ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "1.0.0" } }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", "dev": true, "requires": { "path-is-inside": "1.0.2" @@ -5455,10 +5436,13 @@ } }, "is-resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } }, "is-stream": { "version": "1.1.0", @@ -5575,9 +5559,9 @@ "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=" }, "js-base64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz", - "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", + "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", "dev": true }, "js-crc": { @@ -5628,6 +5612,12 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=" }, + "jschardet": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", + "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", + "dev": true + }, "jsdoc": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz", @@ -5635,12 +5625,12 @@ "dev": true, "requires": { "babylon": "7.0.0-beta.19", - "bluebird": "3.5.1", + "bluebird": "3.5.0", "catharsis": "0.8.9", "escape-string-regexp": "1.0.5", "js2xmlparser": "3.0.0", "klaw": "2.0.0", - "marked": "0.3.7", + "marked": "0.3.6", "mkdirp": "0.5.1", "requizzle": "0.2.1", "strip-json-comments": "2.0.1", @@ -5690,11 +5680,11 @@ "acorn": "4.0.13", "acorn-globals": "3.1.0", "array-equal": "1.0.0", - "content-type-parser": "1.0.2", + "content-type-parser": "1.0.1", "cssom": "0.3.2", "cssstyle": "0.2.37", "escodegen": "1.9.0", - "html-encoding-sniffer": "1.0.2", + "html-encoding-sniffer": "1.0.1", "nwmatcher": "1.4.3", "parse5": "1.5.1", "request": "2.83.0", @@ -5702,7 +5692,7 @@ "symbol-tree": "3.2.2", "tough-cookie": "2.3.3", "webidl-conversions": "4.0.2", - "whatwg-encoding": "1.0.3", + "whatwg-encoding": "1.0.1", "whatwg-url": "4.8.0", "xml-name-validator": "2.0.1" } @@ -5736,17 +5726,10 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, - "optional": true, "requires": { "jsonify": "0.0.0" } }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5778,8 +5761,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true, - "optional": true + "dev": true }, "jsonpath": { "version": "1.0.0", @@ -5867,10 +5849,10 @@ "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", "dev": true, "requires": { - "errno": "0.1.6", + "errno": "0.1.4", "graceful-fs": "4.1.11", "image-size": "0.5.5", - "mime": "1.6.0", + "mime": "1.4.1", "mkdirp": "0.5.1", "promise": "7.3.1", "request": "2.81.0", @@ -6055,12 +6037,6 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true } } }, @@ -6089,14 +6065,6 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "strip-bom": "2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } } }, "loader-runner": { @@ -6137,12 +6105,6 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", @@ -6155,12 +6117,6 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.mergewith": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", - "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", - "dev": true - }, "lodash.unescape": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", @@ -6227,12 +6183,12 @@ "dev": true }, "make-dir": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", - "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "2.3.0" } }, "map-obj": { @@ -6242,9 +6198,9 @@ "dev": true }, "marked": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.7.tgz", - "integrity": "sha512-zBEP4qO1YQp5aXHt8S5wTiOv9i2X74V/LQL0zhUNvVaklt6Ywa6lChxIvS+ibYlCGgADwKwZFhjC3+XfpsvQvQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz", + "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=", "dev": true }, "math-expression-evaluator": { @@ -6296,7 +6252,7 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.6", + "errno": "0.1.4", "readable-stream": "2.3.3" } }, @@ -6370,9 +6326,9 @@ } }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true }, "mime-db": { @@ -6391,9 +6347,9 @@ } }, "mimer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.3.tgz", - "integrity": "sha512-cICHJPMZUdZMqWaOQ+Eh0hHo1R6IUCiBee7WvIGGUJsZyjdMUInxQVmyu8hKj5uCy+Bi+Wlp/EsdUR61yOdWOw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.1.tgz", + "integrity": "sha1-xjxaF/6GQj9RYahdVcPtUYm6r/w=", "dev": true }, "mimic-fn": { @@ -6950,14 +6906,6 @@ "graceful-fs": "4.1.11", "pify": "2.3.0", "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } } }, "pbkdf2": { @@ -6986,119 +6934,268 @@ "dev": true }, "phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz", + "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=", "dev": true, "requires": { - "es6-promise": "4.1.1", - "extract-zip": "1.6.6", + "es6-promise": "4.0.5", + "extract-zip": "1.6.5", "fs-extra": "1.0.0", "hasha": "2.2.0", "kew": "0.7.0", "progress": "1.1.8", - "request": "2.83.0", + "request": "2.81.0", "request-progress": "2.0.1", "which": "1.2.14" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "2.1.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "portfinder": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", - "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", - "dev": true, - "requires": { - "async": "1.5.2", - "debug": "2.6.9", - "mkdirp": "0.5.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "1.1.3", - "js-base64": "2.4.0", - "source-map": "0.5.7", - "supports-color": "3.2.3" }, "dependencies": { - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "co": "4.6.0", + "json-stable-stringify": "1.0.1" } - } - } - }, - "postcss-calc": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", - "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-message-helpers": "2.0.0", - "reduce-css-calc": "1.3.0" - } - }, - "postcss-colormin": { - "version": "2.2.2", + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "portfinder": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", + "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "dev": true, + "requires": { + "async": "1.5.2", + "debug": "2.6.9", + "mkdirp": "0.5.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "postcss": { + "version": "5.2.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", + "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "js-base64": "2.3.2", + "source-map": "0.5.7", + "supports-color": "3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + } + }, + "postcss-colormin": { + "version": "2.2.2", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", "dev": true, "requires": { "colormin": "1.1.2", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7108,7 +7205,7 @@ "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7120,7 +7217,7 @@ "requires": { "escape-string-regexp": "1.0.5", "extend": "3.0.1", - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -7129,18 +7226,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7150,26 +7247,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7183,7 +7274,7 @@ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-discard-duplicates": { @@ -7192,7 +7283,7 @@ "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-discard-empty": { @@ -7201,7 +7292,7 @@ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-discard-overridden": { @@ -7210,7 +7301,7 @@ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-discard-unused": { @@ -7219,7 +7310,7 @@ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "uniqs": "2.0.0" } }, @@ -7229,7 +7320,7 @@ "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "uniqid": "4.1.1" } }, @@ -7239,7 +7330,7 @@ "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=", "dev": true, "requires": { - "postcss": "6.0.14", + "postcss": "6.0.12", "postcss-value-parser": "3.3.0", "read-cache": "1.0.0", "resolve": "1.1.7" @@ -7251,18 +7342,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7272,26 +7363,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7349,7 +7434,7 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { @@ -7404,7 +7489,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7414,7 +7499,7 @@ "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-merge-rules": { @@ -7425,7 +7510,7 @@ "requires": { "browserslist": "1.7.7", "caniuse-api": "1.6.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-selector-parser": "2.2.3", "vendors": "1.0.1" }, @@ -7436,8 +7521,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000784", - "electron-to-chromium": "1.3.29" + "caniuse-db": "1.0.30000741", + "electron-to-chromium": "1.3.24" } } } @@ -7455,7 +7540,7 @@ "dev": true, "requires": { "object-assign": "4.1.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7465,7 +7550,7 @@ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7476,7 +7561,7 @@ "dev": true, "requires": { "alphanum-sort": "1.0.2", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0", "uniqs": "2.0.0" } @@ -7489,7 +7574,7 @@ "requires": { "alphanum-sort": "1.0.2", "has": "1.0.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-selector-parser": "2.2.3" } }, @@ -7499,7 +7584,7 @@ "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", "dev": true, "requires": { - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -7508,18 +7593,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7529,26 +7614,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7563,7 +7642,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -7572,18 +7651,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7593,26 +7672,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7627,7 +7700,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -7636,18 +7709,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7657,26 +7730,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7691,7 +7758,7 @@ "dev": true, "requires": { "icss-replace-symbols": "1.1.0", - "postcss": "6.0.14" + "postcss": "6.0.12" }, "dependencies": { "ansi-styles": { @@ -7700,18 +7767,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -7721,26 +7788,20 @@ "dev": true }, "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", + "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", "dev": true, "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" + "chalk": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7754,7 +7815,7 @@ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-normalize-url": { @@ -7765,7 +7826,7 @@ "requires": { "is-absolute-url": "2.1.0", "normalize-url": "1.9.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7775,7 +7836,7 @@ "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7785,7 +7846,7 @@ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7795,7 +7856,7 @@ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { - "postcss": "5.2.18" + "postcss": "5.2.17" } }, "postcss-reduce-transforms": { @@ -7805,7 +7866,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0" } }, @@ -7827,7 +7888,7 @@ "dev": true, "requires": { "is-svg": "2.1.0", - "postcss": "5.2.18", + "postcss": "5.2.17", "postcss-value-parser": "3.3.0", "svgo": "0.7.2" } @@ -7839,7 +7900,7 @@ "dev": true, "requires": { "alphanum-sort": "1.0.2", - "postcss": "5.2.18", + "postcss": "5.2.17", "uniqs": "2.0.0" } }, @@ -7856,7 +7917,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.18", + "postcss": "5.2.17", "uniqs": "2.0.0" } }, @@ -7888,9 +7949,9 @@ } }, "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", "dev": true }, "process": { @@ -7932,9 +7993,9 @@ } }, "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", "dev": true }, "pseudomap": { @@ -7957,9 +8018,9 @@ } }, "pump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", - "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", + "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", "dev": true, "requires": { "end-of-stream": "1.4.0", @@ -7974,7 +8035,7 @@ "requires": { "duplexify": "3.5.1", "inherits": "2.0.3", - "pump": "1.0.3" + "pump": "1.0.2" } }, "punycode": { @@ -7984,9 +8045,9 @@ "dev": true }, "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", "dev": true }, "qs": { @@ -8102,13 +8163,13 @@ } }, "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", "dev": true, "requires": { "deep-extend": "0.4.2", - "ini": "1.3.5", + "ini": "1.3.4", "minimist": "1.2.0", "strip-json-comments": "2.0.1" }, @@ -8128,14 +8189,6 @@ "dev": true, "requires": { "pify": "2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } } }, "read-pkg": { @@ -8272,7 +8325,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "private": "0.1.8" + "private": "0.1.7" } }, "regex-cache": { @@ -8557,40 +8610,17 @@ "dev": true }, "sanitize-html": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.16.3.tgz", - "integrity": "sha512-XpAJGnkMfNM7AzXLRw225blBB/pE4dM4jzRn98g4r88cfxwN6g+5IsRmCAh/gbhYGm6u6i97zsatMOM7Lr8wyw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.15.0.tgz", + "integrity": "sha512-1jWLToWx8ZV53Z1Jg+2fHl8dNFsxvQt2Cmrk4o/z1+MUdB5EXSU0QVuzlGGhfp7cQrYbEEfMO/TUWHfkBUqujQ==", "dev": true, "requires": { "htmlparser2": "3.9.2", - "lodash.clonedeep": "4.5.0", "lodash.escaperegexp": "4.1.2", - "lodash.mergewith": "4.6.0", - "postcss": "6.0.14", "srcset": "1.0.0", "xtend": "4.0.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, "domhandler": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", @@ -8600,12 +8630,6 @@ "domelementtype": "1.3.0" } }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, "htmlparser2": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", @@ -8619,32 +8643,6 @@ "inherits": "2.0.3", "readable-stream": "2.3.3" } - }, - "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", - "dev": true, - "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } } } }, @@ -8660,7 +8658,7 @@ "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", "dev": true, "requires": { - "ajv": "5.5.2" + "ajv": "5.2.3" } }, "select-hose": { @@ -8703,14 +8701,6 @@ "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" - }, - "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - } } }, "serve-index": { @@ -8822,9 +8812,9 @@ } }, "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", + "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", "dev": true, "requires": { "hoek": "4.2.0" @@ -9199,9 +9189,9 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.3.0", + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "chalk": "2.1.0", "lodash": "4.17.4", "slice-ansi": "1.0.0", "string-width": "2.1.1" @@ -9213,18 +9203,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.0" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "4.4.0" } }, "has-flag": { @@ -9234,9 +9224,9 @@ "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -9364,6 +9354,12 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -9411,21 +9407,13 @@ "dev": true }, "uglify-js": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz", - "integrity": "sha512-++1NO/zZIEdWf6cDIGceSJQPX31SqIpbVAHwFG5+240MtZqPG/NIPoinj8zlXQtAfMBqEt1Jyv2FiLP3n9gVhQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.3.tgz", + "integrity": "sha512-5ZUOgufCHjN2mBBLfz63UtWTP6va2sSzBpNCM+/iqI6RnPzEhANmB0EKiKBYdQbc3v7KeomXJ2DJx0Xq9gvUvA==", "dev": true, "requires": { - "commander": "2.12.2", - "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "commander": "2.11.0", + "source-map": "0.5.7" } }, "uglify-to-browserify": { @@ -9443,7 +9431,7 @@ "requires": { "source-map": "0.5.7", "uglify-js": "2.8.29", - "webpack-sources": "1.1.0" + "webpack-sources": "1.0.1" }, "dependencies": { "camelcase": { @@ -9572,7 +9560,7 @@ "dev": true, "requires": { "loader-utils": "1.1.0", - "mime": "1.6.0", + "mime": "1.4.1", "schema-utils": "0.3.0" } }, @@ -9594,6 +9582,11 @@ } } }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -9709,7 +9702,7 @@ "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", "dev": true, "requires": { - "async": "2.6.0", + "async": "2.5.0", "chokidar": "1.7.0", "graceful-fs": "4.1.11" } @@ -9729,7 +9722,7 @@ "integrity": "sha512-NvLvZzKvnNAB3LXG5c12WwUx5ZA7ZfNMYq82GnbhFyBLuu3jtamW4tQ40M02XiQzkFsyDuWG6Y2TOq9yywaxlg==", "dev": true, "requires": { - "async": "2.6.0", + "async": "2.5.0", "chalk": "1.1.3", "datauri": "1.0.5", "htmlparser2": "3.9.2", @@ -9778,9 +9771,9 @@ "requires": { "acorn": "5.2.1", "acorn-dynamic-import": "2.0.2", - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "async": "2.6.0", + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "async": "2.5.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", "interpret": "1.1.0", @@ -9796,7 +9789,7 @@ "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", "watchpack": "1.4.0", - "webpack-sources": "1.1.0", + "webpack-sources": "1.0.1", "yargs": "8.0.2" }, "dependencies": { @@ -9846,6 +9839,14 @@ "path-is-absolute": "1.0.1", "range-parser": "1.2.0", "time-stamp": "2.0.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } } }, "webpack-dev-server": { @@ -9968,6 +9969,12 @@ "lcid": "1.0.0" } }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -10033,21 +10040,13 @@ "dev": true }, "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", + "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", "dev": true, "requires": { "source-list-map": "2.0.0", - "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "source-map": "0.5.7" } }, "websocket-driver": { @@ -10067,12 +10066,20 @@ "dev": true }, "whatwg-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", - "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", + "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", "dev": true, "requires": { - "iconv-lite": "0.4.19" + "iconv-lite": "0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + } } }, "whatwg-url": { @@ -10309,12 +10316,6 @@ "pify": "2.3.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", diff --git a/package.json b/package.json index c8616b62e5..3319e9fab8 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "esmangle": "^1.0.1", "esprima": "^4.0.0", "exif-parser": "^0.1.12", + "file-saver": "^1.3.3", "google-code-prettify": "^1.0.5", "jquery": "^3.2.1", "js-crc": "^0.2.0", @@ -94,6 +95,7 @@ "sladex-blowfish": "^0.8.1", "sortablejs": "^1.7.0", "split.js": "^1.3.5", + "utf8": "^3.0.0", "vkbeautify": "^0.99.3", "xmldom": "^0.1.27", "xpath": "0.0.27", diff --git a/src/core/Chef.js b/src/core/Chef.js index 4e7c042a91..8df6d5235f 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -19,7 +19,7 @@ const Chef = function() { /** * Runs the recipe over the input. * - * @param {string} inputText - The input data as a string + * @param {string|ArrayBuffer} input - The input data as a string or ArrayBuffer * @param {Object[]} recipeConfig - The recipe configuration object * @param {Object} options - The options object storing various user choices * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting @@ -33,7 +33,7 @@ const Chef = function() { * @returns {number} response.duration - The number of ms it took to execute the recipe * @returns {number} response.error - The error object thrown by a failed operation (false if no error) */ -Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) { +Chef.prototype.bake = async function(input, recipeConfig, options, progress, step) { let startTime = new Date().getTime(), recipe = new Recipe(recipeConfig), containsFc = recipe.containsFlowControl(), @@ -62,7 +62,8 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, // If starting from scratch, load data if (progress === 0) { - this.dish.set(inputText, Dish.STRING); + const type = input instanceof ArrayBuffer ? Dish.ARRAY_BUFFER : Dish.STRING; + this.dish.set(input, type); } try { @@ -75,10 +76,16 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, progress = err.progress; } + // Depending on the size of the output, we may send it back as a string or an ArrayBuffer. + // This can prevent unnecessary casting as an ArrayBuffer can be easily downloaded as a file. + // The threshold is specified in KiB. + const threshold = (options.outputFileThreshold || 1024) * 1024; + const returnType = this.dish.size() > threshold ? Dish.ARRAY_BUFFER : Dish.STRING; + return { result: this.dish.type === Dish.HTML ? this.dish.get(Dish.HTML) : - this.dish.get(Dish.STRING), + this.dish.get(returnType), type: Dish.enumLookup(this.dish.type), progress: progress, duration: new Date().getTime() - startTime, diff --git a/src/core/Dish.js b/src/core/Dish.js index 26cf5ea155..4a16919a1c 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -8,11 +8,11 @@ import Utils from "./Utils.js"; * @license Apache-2.0 * * @class - * @param {byteArray|string|number} value - The value of the input data. + * @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {number} type - The data type of value, see Dish enums. */ const Dish = function(value, type) { - this.value = value || typeof value == "string" ? value : null; + this.value = value || typeof value === "string" ? value : null; this.type = type || Dish.BYTE_ARRAY; }; @@ -41,6 +41,12 @@ Dish.NUMBER = 2; * @enum */ Dish.HTML = 3; +/** + * Dish data type enum for ArrayBuffers. + * @readonly + * @enum + */ +Dish.ARRAY_BUFFER = 4; /** @@ -64,6 +70,9 @@ Dish.typeEnum = function(typeStr) { case "html": case "HTML": return Dish.HTML; + case "arrayBuffer": + case "ArrayBuffer": + return Dish.ARRAY_BUFFER; default: throw "Invalid data type string. No matching enum."; } @@ -87,6 +96,8 @@ Dish.enumLookup = function(typeEnum) { return "number"; case Dish.HTML: return "html"; + case Dish.ARRAY_BUFFER: + return "ArrayBuffer"; default: throw "Invalid data type enum. No matching type."; } @@ -96,7 +107,7 @@ Dish.enumLookup = function(typeEnum) { /** * Sets the data value and type and then validates them. * - * @param {byteArray|string|number} value - The value of the input data. + * @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {number} type - The data type of value, see Dish enums. */ Dish.prototype.set = function(value, type) { @@ -114,7 +125,7 @@ Dish.prototype.set = function(value, type) { * Returns the value of the data in the type format specified. * * @param {number} type - The data type of value, see Dish enums. - * @returns {byteArray|string|number} The value of the output data. + * @returns {byteArray|string|number|ArrayBuffer} The value of the output data. */ Dish.prototype.get = function(type) { if (this.type !== type) { @@ -134,20 +145,23 @@ Dish.prototype.translate = function(toType) { switch (this.type) { case Dish.STRING: this.value = this.value ? Utils.strToByteArray(this.value) : []; - this.type = Dish.BYTE_ARRAY; break; case Dish.NUMBER: this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : []; - this.type = Dish.BYTE_ARRAY; break; case Dish.HTML: this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : []; - this.type = Dish.BYTE_ARRAY; + break; + case Dish.ARRAY_BUFFER: + // Array.from() would be nicer here, but it's slightly slower + this.value = Array.prototype.slice.call(new Uint8Array(this.value)); break; default: break; } + this.type = Dish.BYTE_ARRAY; + // Convert from byteArray to toType switch (toType) { case Dish.STRING: @@ -159,6 +173,10 @@ Dish.prototype.translate = function(toType) { this.value = this.value ? parseFloat(Utils.byteArrayToUtf8(this.value)) : 0; this.type = Dish.NUMBER; break; + case Dish.ARRAY_BUFFER: + this.value = new Uint8Array(this.value).buffer; + this.type = Dish.ARRAY_BUFFER; + break; default: break; } @@ -180,7 +198,7 @@ Dish.prototype.valid = function() { // Check that every value is a number between 0 - 255 for (let i = 0; i < this.value.length; i++) { - if (typeof this.value[i] != "number" || + if (typeof this.value[i] !== "number" || this.value[i] < 0 || this.value[i] > 255) { return false; @@ -189,18 +207,38 @@ Dish.prototype.valid = function() { return true; case Dish.STRING: case Dish.HTML: - if (typeof this.value == "string") { - return true; - } - return false; + return typeof this.value === "string"; case Dish.NUMBER: - if (typeof this.value == "number") { - return true; - } - return false; + return typeof this.value === "number"; + case Dish.ARRAY_BUFFER: + return this.value instanceof ArrayBuffer; default: return false; } }; + +/** + * Determines how much space the Dish takes up. + * Numbers in JavaScript are 64-bit floating point, however for the purposes of the Dish, + * we measure how many bytes are taken up when the number is written as a string. + * + * @returns {number} +*/ +Dish.prototype.size = function() { + switch (this.type) { + case Dish.BYTE_ARRAY: + case Dish.STRING: + case Dish.HTML: + return this.value.length; + case Dish.NUMBER: + return this.value.toString().length; + case Dish.ARRAY_BUFFER: + return this.value.byteLength; + default: + return -1; + } +}; + + export default Dish; diff --git a/src/core/Utils.js b/src/core/Utils.js index e724320150..f9e5a3b804 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -1,4 +1,4 @@ -import CryptoJS from "crypto-js"; +import utf8 from "utf8"; /** @@ -64,58 +64,6 @@ const Utils = { }, - /** - * Adds leading zeros to strings - * - * @param {string} str - String to add leading characters to. - * @param {number} max - Maximum width of the string. - * @param {char} [chr='0'] - The character to pad with. - * @returns {string} - * - * @example - * // returns "0a" - * Utils.padLeft("a", 2); - * - * // returns "000a" - * Utils.padLeft("a", 4); - * - * // returns "xxxa" - * Utils.padLeft("a", 4, "x"); - * - * // returns "bcabchello" - * Utils.padLeft("hello", 10, "abc"); - */ - padLeft: function(str, max, chr) { - chr = chr || "0"; - let startIndex = chr.length - (max - str.length); - startIndex = startIndex < 0 ? 0 : startIndex; - return str.length < max ? - Utils.padLeft(chr.slice(startIndex, chr.length) + str, max, chr) : str; - }, - - - /** - * Adds trailing spaces to strings. - * - * @param {string} str - String to add trailing characters to. - * @param {number} max - Maximum width of the string. - * @param {char} [chr='0'] - The character to pad with. - * @returns {string} - * - * @example - * // returns "a " - * Utils.padRight("a", 4); - * - * // returns "axxx" - * Utils.padRight("a", 4, "x"); - */ - padRight: function(str, max, chr) { - chr = chr || " "; - return str.length < max ? - Utils.padRight(str + chr.slice(0, max-str.length), max, chr) : str; - }, - - /** * Adds trailing bytes to a byteArray. * @@ -152,14 +100,6 @@ const Utils = { }, - /** - * @alias Utils.padLeft - */ - pad: function(str, max, chr) { - return Utils.padLeft(str, max, chr); - }, - - /** * Truncates a long string to max length and adds suffix. * @@ -201,7 +141,7 @@ const Utils = { hex: function(c, length) { c = typeof c == "string" ? Utils.ord(c) : c; length = length || 2; - return Utils.pad(c.toString(16), length); + return c.toString(16).padStart(length, "0"); }, @@ -222,7 +162,7 @@ const Utils = { bin: function(c, length) { c = typeof c == "string" ? Utils.ord(c) : c; length = length || 8; - return Utils.pad(c.toString(2), length); + return c.toString(2).padStart(length, "0"); }, @@ -340,6 +280,39 @@ const Utils = { }, + /** + * Coverts data of varying types to a byteArray. + * Accepts hex, Base64, UTF8 and Latin1 strings. + * + * @param {string} str + * @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1" + * @returns {byteArray} + * + * @example + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("Привет", "utf8"); + * + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("d097d0b4d180d0b0d0b2d181d182d0b2d183d0b9d182d0b5", "hex"); + * + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); + */ + convertToByteArray: function(str, type) { + switch (type.toLowerCase()) { + case "hex": + return Utils.fromHex(str); + case "base64": + return Utils.fromBase64(str, null, "byteArray"); + case "utf8": + return Utils.strToUtf8ByteArray(str); + case "latin1": + default: + return Utils.strToByteArray(str); + } + }, + + /** * Converts a string to a byte array. * Treats the string as UTF-8 if any values are over 255. @@ -381,17 +354,17 @@ const Utils = { * Utils.strToUtf8ByteArray("你好"); */ strToUtf8ByteArray: function(str) { - let wordArray = CryptoJS.enc.Utf8.parse(str), - byteArray = Utils.wordArrayToByteArray(wordArray); + const utf8Str = utf8.encode(str); - if (str.length !== wordArray.sigBytes) { + if (str.length !== utf8Str.length) { if (ENVIRONMENT_IS_WORKER()) { self.setOption("attemptHighlight", false); } else if (ENVIRONMENT_IS_WEB()) { window.app.options.attemptHighlight = false; } } - return byteArray; + + return Utils.strToByteArray(utf8Str); }, @@ -443,26 +416,21 @@ const Utils = { * Utils.byteArrayToUtf8([228,189,160,229,165,189]); */ byteArrayToUtf8: function(byteArray) { + const str = Utils.byteArrayToChars(byteArray); try { - // Try to output data as UTF-8 string - const words = []; - for (let i = 0; i < byteArray.length; i++) { - words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8); - } - let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length), - str = CryptoJS.enc.Utf8.stringify(wordArray); + const utf8Str = utf8.decode(str); - if (str.length !== wordArray.sigBytes) { + if (str.length !== utf8Str.length) { if (ENVIRONMENT_IS_WORKER()) { self.setOption("attemptHighlight", false); } else if (ENVIRONMENT_IS_WEB()) { window.app.options.attemptHighlight = false; } } - return str; + return utf8Str; } catch (err) { // If it fails, treat it as ANSI - return Utils.byteArrayToChars(byteArray); + return str; } }, @@ -470,7 +438,7 @@ const Utils = { /** * Converts a charcode array to a string. * - * @param {byteArray} byteArray + * @param {byteArray|Uint8Array} byteArray * @returns {string} * * @example @@ -491,33 +459,25 @@ const Utils = { /** - * Converts a CryptoJS.lib.WordArray to a byteArray. - * - * @param {CryptoJS.lib.WordArray} wordArray - * @returns {byteArray} - * + * Converts an ArrayBuffer to a string. + * + * @param {ArrayBuffer} arrayBuffer + * @returns {string} + * * @example - * // returns [84, 101, 115, 116] - * Utils.wordArrayToByteArray(CryptoJS.enc.Hex.parse("54657374")); + * // returns "hello" + * Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer); */ - wordArrayToByteArray: function(wordArray) { - if (wordArray.sigBytes <= 0) return []; - - let words = wordArray.words, - byteArray = []; - - for (let i = 0; i < wordArray.sigBytes; i++) { - byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); - } - - return byteArray; + arrayBufferToStr: function(arrayBuffer) { + const byteArray = Array.prototype.slice.call(new Uint8Array(arrayBuffer)); + return Utils.byteArrayToUtf8(byteArray); }, /** * Base64's the input byte array using the given alphabet, returning a string. * - * @param {byteArray|string} data + * @param {byteArray|Uint8Array|string} data * @param {string} [alphabet] * @returns {string} * @@ -636,7 +596,7 @@ const Utils = { /** * Convert a byte array into a hex string. * - * @param {byteArray} data + * @param {Uint8Array|byteArray} data * @param {string} [delim=" "] * @param {number} [padding=2] * @returns {string} @@ -656,7 +616,7 @@ const Utils = { let output = ""; for (let i = 0; i < data.length; i++) { - output += Utils.pad(data[i].toString(16), padding) + delim; + output += data[i].toString(16).padStart(padding, "0") + delim; } // Add \x or 0x to beginning @@ -1248,21 +1208,6 @@ const Utils = { "None": /\s+/g // Included here to remove whitespace when there shouldn't be any }, - - /** - * A mapping of string formats to their classes in the CryptoJS library. - * @constant - */ - format: { - "Hex": CryptoJS.enc.Hex, - "Base64": CryptoJS.enc.Base64, - "UTF8": CryptoJS.enc.Utf8, - "UTF16": CryptoJS.enc.Utf16, - "UTF16LE": CryptoJS.enc.Utf16LE, - "UTF16BE": CryptoJS.enc.Utf16BE, - "Latin1": CryptoJS.enc.Latin1, - }, - }; export default Utils; @@ -1376,29 +1321,43 @@ String.prototype.count = function(chr) { }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Library overrides /////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse - * the hex string. - * - * @param {string} hexStr - * @returns {CryptoJS.lib.WordArray} +/* + * Polyfills */ -CryptoJS.enc.Hex.parse = function (hexStr) { - // Remove whitespace - hexStr = hexStr.replace(/\s/g, ""); - // Shortcut - const hexStrLength = hexStr.length; - - // Convert - const words = []; - for (let i = 0; i < hexStrLength; i += 2) { - words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); - } - - return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2); -}; +// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart +if (!String.prototype.padStart) { + String.prototype.padStart = function padStart(targetLength, padString) { + targetLength = targetLength>>0; //floor if number or convert non-number to 0; + padString = String((typeof padString !== "undefined" ? padString : " ")); + if (this.length > targetLength) { + return String(this); + } else { + targetLength = targetLength-this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed + } + return padString.slice(0, targetLength) + String(this); + } + }; +} + + +// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd +if (!String.prototype.padEnd) { + String.prototype.padEnd = function padEnd(targetLength, padString) { + targetLength = targetLength>>0; //floor if number or convert non-number to 0; + padString = String((typeof padString !== "undefined" ? padString : " ")); + if (this.length > targetLength) { + return String(this); + } else { + targetLength = targetLength-this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0, targetLength); + } + }; +} diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 2f1d678157..dbac0bfed1 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -245,7 +245,7 @@ const OperationConfig = { description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.

This operation encodes data in an ASCII Base64 string.

e.g. hello becomes aGVsbG8=", highlight: "func", highlightReverse: "func", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { @@ -631,7 +631,7 @@ const OperationConfig = { description: "Converts the input string to hexadecimal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a", highlight: "func", highlightReverse: "func", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { @@ -782,7 +782,7 @@ const OperationConfig = { description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.", highlight: "func", highlightReverse: "func", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { @@ -3287,7 +3287,7 @@ const OperationConfig = { "Frequency distribution": { module: "Default", description: "Displays the distribution of bytes in the data as a graph.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "html", args: [ { @@ -3300,7 +3300,7 @@ const OperationConfig = { "Chi Square": { module: "Default", description: "Calculates the Chi Square distribution of values.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "number", args: [] }, @@ -3379,14 +3379,14 @@ const OperationConfig = { "Detect File Type": { module: "Default", description: "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.

Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [] }, "Scan for Embedded Files": { module: "Default", description: "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.

WARNING: Files over about 100KB in size will take a VERY long time to process.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { @@ -3740,7 +3740,7 @@ const OperationConfig = { "

", "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.", ].join("\n"), - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [], }, diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 4fb76887b1..b36e00aa69 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -38,7 +38,6 @@ import UUID from "../../operations/UUID.js"; * * Libraries: * - Utils.js - * - CryptoJS * - otp * - crypto * diff --git a/src/core/operations/BCD.js b/src/core/operations/BCD.js index 63c0cda374..d3efbc718d 100755 --- a/src/core/operations/BCD.js +++ b/src/core/operations/BCD.js @@ -134,11 +134,11 @@ const BCD = { switch (outputFormat) { case "Nibbles": return nibbles.map(n => { - return Utils.padLeft(n.toString(2), 4); + return n.toString(2).padStart(4, "0"); }).join(" "); case "Bytes": return bytes.map(b => { - return Utils.padLeft(b.toString(2), 8); + return b.toString(2).padStart(8, "0"); }).join(" "); case "Raw": default: diff --git a/src/core/operations/Base64.js b/src/core/operations/Base64.js index c6d9ce6c72..31c7e2a164 100755 --- a/src/core/operations/Base64.js +++ b/src/core/operations/Base64.js @@ -40,13 +40,13 @@ const Base64 = { /** * To Base64 operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runTo: function(input, args) { const alphabet = args[0] || Base64.ALPHABET; - return Utils.toBase64(input, alphabet); + return Utils.toBase64(new Uint8Array(input), alphabet); }, diff --git a/src/core/operations/BitwiseOp.js b/src/core/operations/BitwiseOp.js index 7512aa32da..f2551cba5f 100755 --- a/src/core/operations/BitwiseOp.js +++ b/src/core/operations/BitwiseOp.js @@ -67,7 +67,7 @@ const BitwiseOp = { * @constant * @default */ - KEY_FORMAT: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"], + KEY_FORMAT: ["Hex", "Base64", "UTF8", "Latin1"], /** * XOR operation. @@ -77,12 +77,10 @@ const BitwiseOp = { * @returns {byteArray} */ runXor: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), + const key = Utils.convertToByteArray(args[0].string || "", args[0].option), scheme = args[1], nullPreserving = args[2]; - key = Utils.wordArrayToByteArray(key); - return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme); }, @@ -200,8 +198,7 @@ const BitwiseOp = { * @returns {byteArray} */ runAnd: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._and); }, @@ -215,8 +212,7 @@ const BitwiseOp = { * @returns {byteArray} */ runOr: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._or); }, @@ -230,8 +226,7 @@ const BitwiseOp = { * @returns {byteArray} */ runAdd: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._add); }, @@ -245,8 +240,7 @@ const BitwiseOp = { * @returns {byteArray} */ runSub: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._sub); }, diff --git a/src/core/operations/ByteRepr.js b/src/core/operations/ByteRepr.js index 87a543ffdf..986926ca84 100755 --- a/src/core/operations/ByteRepr.js +++ b/src/core/operations/ByteRepr.js @@ -31,13 +31,13 @@ const ByteRepr = { /** * To Hex operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runToHex: function(input, args) { const delim = Utils.charRep[args[0] || "Space"]; - return Utils.toHex(input, delim, 2); + return Utils.toHex(new Uint8Array(input), delim, 2); }, @@ -266,7 +266,7 @@ const ByteRepr = { padding = 8; for (let i = 0; i < input.length; i++) { - output += Utils.pad(input[i].toString(2), padding) + delim; + output += input[i].toString(2).padStart(padding, "0") + delim; } if (delim.length) { diff --git a/src/core/operations/Cipher.js b/src/core/operations/Cipher.js index 465c3e9e13..227c2735d4 100755 --- a/src/core/operations/Cipher.js +++ b/src/core/operations/Cipher.js @@ -61,9 +61,9 @@ const Cipher = { * @returns {string} */ _enc: function (algo, input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), - iv = Utils.format[args[1].option].parse(args[1].string || ""), - salt = Utils.format[args[2].option].parse(args[2].string || ""), + let key = Cipher._format[args[0].option].parse(args[0].string || ""), + iv = Cipher._format[args[1].option].parse(args[1].string || ""), + salt = Cipher._format[args[2].option].parse(args[2].string || ""), mode = CryptoJS.mode[args[3]], padding = CryptoJS.pad[args[4]], resultOption = args[5].toLowerCase(), @@ -83,12 +83,12 @@ const Cipher = { let result = ""; if (resultOption === "show all") { - result += "Key: " + encrypted.key.toString(Utils.format[outputFormat]); - result += "\nIV: " + encrypted.iv.toString(Utils.format[outputFormat]); - if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Utils.format[outputFormat]); - result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Utils.format[outputFormat]); + result += "Key: " + encrypted.key.toString(Cipher._format[outputFormat]); + result += "\nIV: " + encrypted.iv.toString(Cipher._format[outputFormat]); + if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Cipher._format[outputFormat]); + result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Cipher._format[outputFormat]); } else { - result = encrypted[resultOption].toString(Utils.format[outputFormat]); + result = encrypted[resultOption].toString(Cipher._format[outputFormat]); } return result; @@ -105,9 +105,9 @@ const Cipher = { * @returns {string} */ _dec: function (algo, input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), - iv = Utils.format[args[1].option].parse(args[1].string || ""), - salt = Utils.format[args[2].option].parse(args[2].string || ""), + let key = Cipher._format[args[0].option].parse(args[0].string || ""), + iv = Cipher._format[args[1].option].parse(args[1].string || ""), + salt = Cipher._format[args[2].option].parse(args[2].string || ""), mode = CryptoJS.mode[args[3]], padding = CryptoJS.pad[args[4]], inputFormat = args[5], @@ -118,7 +118,7 @@ const Cipher = { return "No input"; } - const ciphertext = Utils.format[inputFormat].parse(input); + const ciphertext = Cipher._format[inputFormat].parse(input); if (iv.sigBytes === 0) { // Use passphrase rather than key. Need to convert it to a string. @@ -136,7 +136,7 @@ const Cipher = { let result; try { - result = decrypted.toString(Utils.format[outputFormat]); + result = decrypted.toString(Cipher._format[outputFormat]); } catch (err) { result = "Decrypt error: " + err.message; } @@ -260,7 +260,7 @@ const Cipher = { * @returns {string} */ runBlowfishEnc: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1), + let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1), mode = args[1], outputFormat = args[2]; @@ -272,7 +272,7 @@ const Cipher = { }), enc = CryptoJS.enc.Hex.parse(encHex); - return enc.toString(Utils.format[outputFormat]); + return enc.toString(Cipher._format[outputFormat]); }, @@ -284,13 +284,13 @@ const Cipher = { * @returns {string} */ runBlowfishDec: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1), + let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1), mode = args[1], inputFormat = args[2]; if (key.length === 0) return "Enter a key"; - input = Utils.format[inputFormat].parse(input); + input = Cipher._format[inputFormat].parse(input); return Blowfish.decrypt(input.toString(CryptoJS.enc.Base64), key, { outputType: 0, // This actually means inputType. The library is weird. @@ -329,14 +329,14 @@ const Cipher = { salt = CryptoJS.enc.Hex.parse(args[3] || ""), inputFormat = args[4], outputFormat = args[5], - passphrase = Utils.format[inputFormat].parse(input), + passphrase = Cipher._format[inputFormat].parse(input), key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize, hasher: CryptoJS.algo[hasher], iterations: iterations, }); - return key.toString(Utils.format[outputFormat]); + return key.toString(Cipher._format[outputFormat]); }, @@ -354,14 +354,14 @@ const Cipher = { salt = CryptoJS.enc.Hex.parse(args[3] || ""), inputFormat = args[4], outputFormat = args[5], - passphrase = Utils.format[inputFormat].parse(input), + passphrase = Cipher._format[inputFormat].parse(input), key = CryptoJS.EvpKDF(passphrase, salt, { keySize: keySize, hasher: CryptoJS.algo[hasher], iterations: iterations, }); - return key.toString(Utils.format[outputFormat]); + return key.toString(Cipher._format[outputFormat]); }, @@ -373,11 +373,11 @@ const Cipher = { * @returns {string} */ runRc4: function (input, args) { - let message = Utils.format[args[1]].parse(input), - passphrase = Utils.format[args[0].option].parse(args[0].string), + let message = Cipher._format[args[1]].parse(input), + passphrase = Cipher._format[args[0].option].parse(args[0].string), encrypted = CryptoJS.RC4.encrypt(message, passphrase); - return encrypted.ciphertext.toString(Utils.format[args[2]]); + return encrypted.ciphertext.toString(Cipher._format[args[2]]); }, @@ -395,12 +395,12 @@ const Cipher = { * @returns {string} */ runRc4drop: function (input, args) { - let message = Utils.format[args[1]].parse(input), - passphrase = Utils.format[args[0].option].parse(args[0].string), + let message = Cipher._format[args[1]].parse(input), + passphrase = Cipher._format[args[0].option].parse(args[0].string), drop = args[3], encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop }); - return encrypted.ciphertext.toString(Utils.format[args[2]]); + return encrypted.ciphertext.toString(Cipher._format[args[2]]); }, @@ -783,6 +783,23 @@ const Cipher = { return output; }, + + /** + * A mapping of string formats to their classes in the CryptoJS library. + * + * @private + * @constant + */ + _format: { + "Hex": CryptoJS.enc.Hex, + "Base64": CryptoJS.enc.Base64, + "UTF8": CryptoJS.enc.Utf8, + "UTF16": CryptoJS.enc.Utf16, + "UTF16LE": CryptoJS.enc.Utf16LE, + "UTF16BE": CryptoJS.enc.Utf16BE, + "Latin1": CryptoJS.enc.Latin1, + }, + }; export default Cipher; @@ -827,3 +844,27 @@ CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) { // Return params return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt }); }; + + +/** + * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse + * the hex string. + * + * @param {string} hexStr + * @returns {CryptoJS.lib.WordArray} + */ +CryptoJS.enc.Hex.parse = function (hexStr) { + // Remove whitespace + hexStr = hexStr.replace(/\s/g, ""); + + // Shortcut + const hexStrLength = hexStr.length; + + // Convert + const words = []; + for (let i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2); +}; diff --git a/src/core/operations/Compress.js b/src/core/operations/Compress.js index 639b89c659..57b0102777 100755 --- a/src/core/operations/Compress.js +++ b/src/core/operations/Compress.js @@ -418,9 +418,9 @@ const Compress = { } }; - const fileSize = Utils.padLeft(input.length.toString(8), 11, "0"); + const fileSize = input.length.toString(8).padStart(11, "0"); const currentUnixTimestamp = Math.floor(Date.now() / 1000); - const lastModTime = Utils.padLeft(currentUnixTimestamp.toString(8), 11, "0"); + const lastModTime = currentUnixTimestamp.toString(8).padStart(11, "0"); const file = { fileName: Utils.padBytesRight(args[0], 100), @@ -452,7 +452,7 @@ const Compress = { } }); } - checksum = Utils.padBytesRight(Utils.padLeft(checksum.toString(8), 7, "0"), 8); + checksum = Utils.padBytesRight(checksum.toString(8).padStart(7, "0"), 8); file.checksum = checksum; const tarball = new Tarball(); diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index aa9ed0bc37..baf9edb384 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -81,22 +81,23 @@ const Entropy = { /** * Frequency distribution operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {html} */ runFreqDistrib: function (input, args) { - if (!input.length) return "No data"; + const data = new Uint8Array(input); + if (!data.length) return "No data"; let distrib = new Array(256).fill(0), percentages = new Array(256), - len = input.length, + len = data.length, showZeroes = args[0], i; // Count bytes for (i = 0; i < len; i++) { - distrib[input[i]]++; + distrib[data[i]]++; } // Calculate percentages @@ -126,7 +127,7 @@ const Entropy = { for (i = 0; i < 256; i++) { if (distrib[i] || showZeroes) { output += " " + Utils.hex(i, 2) + " (" + - Utils.padRight(percentages[i].toFixed(2).replace(".00", "") + "%)", 8) + + (percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") + Array(Math.ceil(percentages[i])+1).join("|") + "\n"; } } @@ -138,21 +139,22 @@ const Entropy = { /** * Chi Square operation. * - * @param {byteArray} data + * @param {ArrayBuffer} data * @param {Object[]} args * @returns {number} */ runChiSq: function(input, args) { + const data = new Uint8Array(input); let distArray = new Array(256).fill(0), total = 0; - for (let i = 0; i < input.length; i++) { - distArray[input[i]]++; + for (let i = 0; i < data.length; i++) { + distArray[data[i]]++; } for (let i = 0; i < distArray.length; i++) { if (distArray[i] > 0) { - total += Math.pow(distArray[i] - input.length / 256, 2) / (input.length / 256); + total += Math.pow(distArray[i] - data.length / 256, 2) / (data.length / 256); } } diff --git a/src/core/operations/FileType.js b/src/core/operations/FileType.js index ad3e5ba747..715f820576 100755 --- a/src/core/operations/FileType.js +++ b/src/core/operations/FileType.js @@ -15,12 +15,13 @@ const FileType = { /** * Detect File Type operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runDetect: function(input, args) { - const type = FileType.magicType(input); + const data = new Uint8Array(input), + type = FileType.magicType(data); if (!type) { return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?"; @@ -46,20 +47,21 @@ const FileType = { /** * Scan for Embedded Files operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runScanForEmbeddedFiles: function(input, args) { let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n", type, - ignoreCommon = args[0], - commonExts = ["ico", "ttf", ""], numFound = 0, numCommonFound = 0; + const ignoreCommon = args[0], + commonExts = ["ico", "ttf", ""], + data = new Uint8Array(input); - for (let i = 0; i < input.length; i++) { - type = FileType.magicType(input.slice(i)); + for (let i = 0; i < data.length; i++) { + type = FileType.magicType(data.slice(i)); if (type) { if (ignoreCommon && commonExts.indexOf(type.ext) > -1) { numCommonFound++; @@ -96,7 +98,7 @@ const FileType = { * Given a buffer, detects magic byte sequences at specific positions and returns the * extension and mime type. * - * @param {byteArray} buf + * @param {Uint8Array} buf * @returns {Object} type * @returns {string} type.ext - File extension * @returns {string} type.mime - Mime type diff --git a/src/core/operations/HTML.js b/src/core/operations/HTML.js index 30eda63ec6..b1f7e0655d 100755 --- a/src/core/operations/HTML.js +++ b/src/core/operations/HTML.js @@ -215,9 +215,9 @@ const HTML = { k = k.toFixed(2); let hex = "#" + - Utils.padLeft(Math.round(r).toString(16), 2) + - Utils.padLeft(Math.round(g).toString(16), 2) + - Utils.padLeft(Math.round(b).toString(16), 2), + Math.round(r).toString(16).padStart(2, "0") + + Math.round(g).toString(16).padStart(2, "0") + + Math.round(b).toString(16).padStart(2, "0"), rgb = "rgb(" + r + ", " + g + ", " + b + ")", rgba = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")", hsl = "hsl(" + h + ", " + s + "%, " + l + "%)", diff --git a/src/core/operations/Hexdump.js b/src/core/operations/Hexdump.js index a9ed7a10f8..fc907d9e41 100755 --- a/src/core/operations/Hexdump.js +++ b/src/core/operations/Hexdump.js @@ -31,18 +31,19 @@ const Hexdump = { /** * To Hexdump operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runTo: function(input, args) { + const data = new Uint8Array(input); const length = args[0] || Hexdump.WIDTH; const upperCase = args[1]; const includeFinalLength = args[2]; let output = "", padding = 2; - for (let i = 0; i < input.length; i += length) { - const buff = input.slice(i, i+length); + for (let i = 0; i < data.length; i += length) { + const buff = data.slice(i, i+length); let hexa = ""; for (let j = 0; j < buff.length; j++) { hexa += Utils.hex(buff[j], padding) + " "; @@ -56,10 +57,10 @@ const Hexdump = { } output += lineNo + " " + - Utils.padRight(hexa, (length*(padding+1))) + - " |" + Utils.padRight(Utils.printable(Utils.byteArrayToChars(buff)), buff.length) + "|\n"; + hexa.padEnd(length*(padding+1), " ") + + " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n"; - if (includeFinalLength && i+buff.length === input.length) { + if (includeFinalLength && i+buff.length === data.length) { output += Utils.hex(i+buff.length, 8) + "\n"; } } diff --git a/src/core/operations/Image.js b/src/core/operations/Image.js index 2dd72df508..afab21c181 100644 --- a/src/core/operations/Image.js +++ b/src/core/operations/Image.js @@ -20,14 +20,13 @@ const Image = { * * Extracts EXIF data from a byteArray, representing a JPG or a TIFF image. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runExtractEXIF(input, args) { try { - const bytes = Uint8Array.from(input); - const parser = ExifParser.create(bytes.buffer); + const parser = ExifParser.create(input); const result = parser.parse(); let lines = []; @@ -53,7 +52,7 @@ const Image = { * @author David Moodie [davidmoodie12@gmail.com] * @param {byteArray} input * @param {Object[]} args - * @returns {string} + * @returns {byteArray} */ runRemoveEXIF(input, args) { // Do nothing if input is empty diff --git a/src/core/operations/PublicKey.js b/src/core/operations/PublicKey.js index 295a5bf419..66b177a59f 100755 --- a/src/core/operations/PublicKey.js +++ b/src/core/operations/PublicKey.js @@ -121,8 +121,7 @@ const PublicKey = { // Format Public Key fields for (let i = 0; i < pkFields.length; i++) { pkStr += " " + pkFields[i].key + ":" + - Utils.padLeft( - pkFields[i].value + "\n", + (pkFields[i].value + "\n").padStart( 18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1, " " ); @@ -286,9 +285,9 @@ ${extensions}`; key = fields[i].split("=")[0]; value = fields[i].split("=")[1]; - str = Utils.padRight(key, maxKeyLen) + " = " + value + "\n"; + str = key.padEnd(maxKeyLen, " ") + " = " + value + "\n"; - output += Utils.padLeft(str, indent + str.length, " "); + output += str.padStart(indent + str.length, " "); } return output.slice(0, -1); @@ -314,7 +313,7 @@ ${extensions}`; if (i === 0) { output += str; } else { - output += Utils.padLeft(str, indent + str.length, " "); + output += str.padStart(indent + str.length, " "); } } diff --git a/src/core/operations/SeqUtils.js b/src/core/operations/SeqUtils.js index 3272e706d1..fa900cf9ef 100755 --- a/src/core/operations/SeqUtils.js +++ b/src/core/operations/SeqUtils.js @@ -158,7 +158,7 @@ const SeqUtils = { width = lines.length.toString().length; for (let n = 0; n < lines.length; n++) { - output += Utils.pad((n+1).toString(), width, " ") + " " + lines[n] + "\n"; + output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n"; } return output.slice(0, output.length-1); }, diff --git a/src/core/operations/Tidy.js b/src/core/operations/Tidy.js index 881508cfd8..41f0561dd1 100755 --- a/src/core/operations/Tidy.js +++ b/src/core/operations/Tidy.js @@ -1,6 +1,3 @@ -import Utils from "../Utils.js"; - - /** * Tidy operations. * @@ -229,11 +226,11 @@ const Tidy = { if (position === "Start") { for (i = 0; i < lines.length; i++) { - output += Utils.padLeft(lines[i], lines[i].length+len, chr) + "\n"; + output += lines[i].padStart(lines[i].length+len, chr) + "\n"; } } else if (position === "End") { for (i = 0; i < lines.length; i++) { - output += Utils.padRight(lines[i], lines[i].length+len, chr) + "\n"; + output += lines[i].padEnd(lines[i].length+len, chr) + "\n"; } } diff --git a/src/core/operations/URL.js b/src/core/operations/URL.js index 25526f0e14..2f30c952c5 100755 --- a/src/core/operations/URL.js +++ b/src/core/operations/URL.js @@ -1,5 +1,4 @@ /* globals unescape */ -import Utils from "../Utils.js"; import url from "url"; @@ -78,7 +77,7 @@ const URL_ = { output += "Arguments:\n"; for (let key in uri.query) { - output += "\t" + Utils.padRight(key, padding); + output += "\t" + key.padEnd(padding, " "); if (uri.query[key].length) { output += " = " + uri.query[key] + "\n"; } else { diff --git a/src/web/HighlighterWaiter.js b/src/web/HighlighterWaiter.js index c650e6ba12..6e4ca599b5 100755 --- a/src/web/HighlighterWaiter.js +++ b/src/web/HighlighterWaiter.js @@ -1,6 +1,3 @@ -import Utils from "../core/Utils.js"; - - /** * Waiter to handle events related to highlighting in CyberChef. * @@ -312,9 +309,9 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) { HighlighterWaiter.prototype.selectionInfo = function(start, end) { const len = end.toString().length; const width = len < 2 ? 2 : len; - const startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, " "); - const endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, " "); - const lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, " "); + const startStr = start.toString().padStart(width, " ").replace(/ /g, " "); + const endStr = end.toString().padStart(width, " ").replace(/ /g, " "); + const lenStr = (end-start).toString().padStart(width, " ").replace(/ /g, " "); return "start: " + startStr + "
end: " + endStr + "
length: " + lenStr; }; @@ -402,7 +399,7 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) { // Check if there is a carriage return in the output dish as this will not // be displayed by the HTML textarea and will mess up highlighting offsets. - if (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false; + if (this.manager.output.containsCR()) return false; const startPlaceholder = "[startHighlight]"; const startPlaceholderRegex = /\[startHighlight\]/g; diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index aba57334a8..af3f72ee83 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -1,4 +1,4 @@ -import Utils from "../core/Utils.js"; +import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker.js"; /** @@ -33,6 +33,9 @@ const InputWaiter = function(app, manager) { 144, //Num 145, //Scroll ]; + + this.loaderWorker = null; + this.fileBuffer = null; }; @@ -42,20 +45,47 @@ const InputWaiter = function(app, manager) { * @returns {string} */ InputWaiter.prototype.get = function() { - return document.getElementById("input-text").value; + return this.fileBuffer || document.getElementById("input-text").value; }; /** - * Sets the input in the input textarea. + * Sets the input in the input area. * - * @param {string} input + * @param {string|File} input * * @fires Manager#statechange */ InputWaiter.prototype.set = function(input) { - document.getElementById("input-text").value = input; - window.dispatchEvent(this.manager.statechange); + const inputText = document.getElementById("input-text"); + if (input instanceof File) { + this.setFile(input); + inputText.value = ""; + } else { + inputText.value = input; + window.dispatchEvent(this.manager.statechange); + } +}; + + +/** + * Shows file details. + * + * @param {File} file + */ +InputWaiter.prototype.setFile = function(file) { + // Display file overlay in input area with details + const fileOverlay = document.getElementById("input-file"), + fileName = document.getElementById("input-file-name"), + fileSize = document.getElementById("input-file-size"), + fileType = document.getElementById("input-file-type"), + fileLoaded = document.getElementById("input-file-loaded"); + + fileOverlay.style.display = "block"; + fileName.textContent = file.name; + fileSize.textContent = file.size.toLocaleString() + " bytes"; + fileType.textContent = file.type || "unknown"; + fileLoaded.textContent = "0%"; }; @@ -69,8 +99,8 @@ InputWaiter.prototype.setInputInfo = function(length, lines) { let width = length.toString().length; width = width < 2 ? 2 : width; - const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); - const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); + const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); document.getElementById("input-info").innerHTML = "length: " + lengthStr + "
lines: " + linesStr; }; @@ -118,7 +148,7 @@ InputWaiter.prototype.inputDragover = function(e) { e.stopPropagation(); e.preventDefault(); - e.target.classList.add("dropping-file"); + e.target.closest("#input-text,#input-file").classList.add("dropping-file"); }; @@ -131,7 +161,8 @@ InputWaiter.prototype.inputDragover = function(e) { InputWaiter.prototype.inputDragleave = function(e) { e.stopPropagation(); e.preventDefault(); - e.target.classList.remove("dropping-file"); + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); }; @@ -149,55 +180,57 @@ InputWaiter.prototype.inputDrop = function(e) { e.stopPropagation(); e.preventDefault(); - const el = e.target; const file = e.dataTransfer.files[0]; const text = e.dataTransfer.getData("Text"); - const reader = new FileReader(); - let inputCharcode = ""; - let offset = 0; - const CHUNK_SIZE = 20480; // 20KB - - const setInput = function() { - const recipeConfig = this.app.getRecipeConfig(); - if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") { - recipeConfig.unshift({op: "From Hex", args: ["Space"]}); - this.app.setRecipeConfig(recipeConfig); - } - - this.set(inputCharcode); - - el.classList.remove("loadingFile"); - }.bind(this); - - const seek = function() { - if (offset >= file.size) { - setInput(); - return; - } - el.value = "Processing... " + Math.round(offset / file.size * 100) + "%"; - const slice = file.slice(offset, offset + CHUNK_SIZE); - reader.readAsArrayBuffer(slice); - }; - - reader.onload = function(e) { - const data = new Uint8Array(reader.result); - inputCharcode += Utils.toHexFast(data); - offset += CHUNK_SIZE; - seek(); - }; - - - el.classList.remove("dropping-file"); - if (file) { - el.classList.add("loadingFile"); - seek(); - } else if (text) { + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); + + if (text) { + this.closeFile(); this.set(text); + return; + } + + if (file) { + this.closeFile(); + this.loaderWorker = new LoaderWorker(); + this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); + this.loaderWorker.postMessage({"file": file}); + this.set(file); } }; +/** + * Handler for messages sent back by the LoaderWorker. + * + * @param {MessageEvent} e + */ +InputWaiter.prototype.handleLoaderMessage = function(e) { + const r = e.data; + if (r.hasOwnProperty("progress")) { + const fileLoaded = document.getElementById("input-file-loaded"); + fileLoaded.textContent = r.progress + "%"; + } + + if (r.hasOwnProperty("fileBuffer")) { + this.fileBuffer = r.fileBuffer; + window.dispatchEvent(this.manager.statechange); + } +}; + + +/** + * Handler for file close events. + */ +InputWaiter.prototype.closeFile = function() { + if (this.loaderWorker) this.loaderWorker.terminate(); + this.fileBuffer = null; + document.getElementById("input-file").style.display = "none"; +}; + + /** * Handler for clear IO events. * Resets the input, output and info areas. @@ -205,6 +238,8 @@ InputWaiter.prototype.inputDrop = function(e) { * @fires Manager#statechange */ InputWaiter.prototype.clearIoClick = function() { + this.closeFile(); + this.manager.output.closeFile(); this.manager.highlighter.removeHighlights(); document.getElementById("input-text").value = ""; document.getElementById("output-text").value = ""; diff --git a/src/web/LoaderWorker.js b/src/web/LoaderWorker.js new file mode 100644 index 0000000000..b841c096e3 --- /dev/null +++ b/src/web/LoaderWorker.js @@ -0,0 +1,50 @@ +/** + * Web Worker to load large amounts of data without locking up the UI. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + + +/** + * Respond to message from parent thread. + */ +self.addEventListener("message", function(e) { + const r = e.data; + if (r.hasOwnProperty("file")) { + self.loadFile(r.file); + } +}); + + +/** + * Loads a file object into an ArrayBuffer, then transfers it back to the parent thread. + * + * @param {File} file + */ +self.loadFile = function(file) { + const reader = new FileReader(); + let data = new Uint8Array(file.size); + let offset = 0; + const CHUNK_SIZE = 10485760; // 10MiB + + const seek = function() { + if (offset >= file.size) { + self.postMessage({"progress": 100}); + self.postMessage({"fileBuffer": data.buffer}, [data.buffer]); + return; + } + self.postMessage({"progress": Math.round(offset / file.size * 100)}); + const slice = file.slice(offset, offset + CHUNK_SIZE); + reader.readAsArrayBuffer(slice); + }; + + reader.onload = function(e) { + data.set(new Uint8Array(reader.result), offset); + offset += CHUNK_SIZE; + seek(); + }; + + seek(); +}; diff --git a/src/web/Manager.js b/src/web/Manager.js index 2b44e6d23e..39aaf409ec 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -135,13 +135,14 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#input-text", "keyup paste", this.input.inputChange, this.input); document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app)); document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input)); - document.getElementById("input-text").addEventListener("dragover", this.input.inputDragover.bind(this.input)); - document.getElementById("input-text").addEventListener("dragleave", this.input.inputDragleave.bind(this.input)); - document.getElementById("input-text").addEventListener("drop", this.input.inputDrop.bind(this.input)); + this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input); + this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input); + this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input); document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter)); document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter)); document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter)); this.addMultiEventListener("#input-text", "mousedown dblclick select", this.highlighter.inputMousedown, this.highlighter); + document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input)); // Output document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); @@ -157,6 +158,9 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter); this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output); + this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); + this.addDynamicListener("#output-file-slice", "click", this.output.displayFileSlice, this.output); + document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output)); // Options document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index a5576f3150..42742734c0 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -1,4 +1,5 @@ import Utils from "../core/Utils.js"; +import FileSaver from "file-saver"; /** @@ -15,6 +16,9 @@ import Utils from "../core/Utils.js"; const OutputWaiter = function(app, manager) { this.app = app; this.manager = manager; + + this.dishBuffer = null; + this.dishStr = null; }; @@ -31,47 +35,150 @@ OutputWaiter.prototype.get = function() { /** * Sets the output in the output textarea. * - * @param {string} dataStr - The output string/HTML + * @param {string|ArrayBuffer} data - The output string/HTML/ArrayBuffer * @param {string} type - The data type of the output * @param {number} duration - The length of time (ms) it took to generate the output + * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer */ -OutputWaiter.prototype.set = function(dataStr, type, duration) { +OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { const outputText = document.getElementById("output-text"); const outputHtml = document.getElementById("output-html"); + const outputFile = document.getElementById("output-file"); const outputHighlighter = document.getElementById("output-highlighter"); const inputHighlighter = document.getElementById("input-highlighter"); + let scriptElements, lines, length; - if (type === "html") { - outputText.style.display = "none"; - outputHtml.style.display = "block"; - outputHighlighter.display = "none"; - inputHighlighter.display = "none"; - - outputText.value = ""; - outputHtml.innerHTML = dataStr; - - // Execute script sections - const scriptElements = outputHtml.querySelectorAll("script"); - for (let i = 0; i < scriptElements.length; i++) { - try { - eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval - } catch (err) { - console.error(err); - } - } - } else { - outputText.style.display = "block"; - outputHtml.style.display = "none"; - outputHighlighter.display = "block"; - inputHighlighter.display = "block"; + if (!preserveBuffer) { + this.closeFile(); + document.getElementById("show-file-overlay").style.display = "none"; + } - outputText.value = Utils.printable(dataStr, true); - outputHtml.innerHTML = ""; + switch (type) { + case "html": + outputText.style.display = "none"; + outputHtml.style.display = "block"; + outputFile.style.display = "none"; + outputHighlighter.display = "none"; + inputHighlighter.display = "none"; + + outputText.value = ""; + outputHtml.innerHTML = data; + this.dishStr = Utils.stripHtmlTags(data, true); + length = data.length; + lines = this.dishStr.count("\n") + 1; + + // Execute script sections + scriptElements = outputHtml.querySelectorAll("script"); + for (let i = 0; i < scriptElements.length; i++) { + try { + eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval + } catch (err) { + console.error(err); + } + } + break; + case "ArrayBuffer": + outputText.style.display = "block"; + outputHtml.style.display = "none"; + outputHighlighter.display = "none"; + inputHighlighter.display = "none"; + + outputText.value = ""; + outputHtml.innerHTML = ""; + this.dishStr = ""; + length = data.byteLength; + + this.setFile(data); + break; + case "string": + default: + outputText.style.display = "block"; + outputHtml.style.display = "none"; + outputFile.style.display = "none"; + outputHighlighter.display = "block"; + inputHighlighter.display = "block"; + + outputText.value = Utils.printable(data, true); + outputHtml.innerHTML = ""; + + lines = data.count("\n") + 1; + length = data.length; + this.dishStr = data; + break; } this.manager.highlighter.removeHighlights(); - const lines = dataStr.count("\n") + 1; - this.setOutputInfo(dataStr.length, lines, duration); + this.setOutputInfo(length, lines, duration); +}; + + +/** + * Shows file details. + * + * @param {ArrayBuffer} buf + */ +OutputWaiter.prototype.setFile = function(buf) { + this.dishBuffer = buf; + const file = new File([buf], "output.dat"); + + // Display file overlay in output area with details + const fileOverlay = document.getElementById("output-file"), + fileSize = document.getElementById("output-file-size"); + + fileOverlay.style.display = "block"; + fileSize.textContent = file.size.toLocaleString() + " bytes"; +}; + + +/** + * Removes the output file and nulls its memory. + */ +OutputWaiter.prototype.closeFile = function() { + this.dishBuffer = null; + document.getElementById("output-file").style.display = "none"; +}; + + +/** + * Handler for file download events. + */ +OutputWaiter.prototype.downloadFile = function() { + this.filename = window.prompt("Please enter a filename:", this.filename || "download.dat"); + const file = new File([this.dishBuffer], this.filename); + + if (this.filename) FileSaver.saveAs(file, this.filename, false); +}; + + +/** + * Handler for file slice display events. + */ +OutputWaiter.prototype.displayFileSlice = function() { + const startTime = new Date().getTime(), + showFileOverlay = document.getElementById("show-file-overlay"), + sliceFromEl = document.getElementById("output-file-slice-from"), + sliceToEl = document.getElementById("output-file-slice-to"), + sliceFrom = parseInt(sliceFromEl.value, 10), + sliceTo = parseInt(sliceToEl.value, 10), + str = Utils.arrayBufferToStr(this.dishBuffer.slice(sliceFrom, sliceTo)); + + showFileOverlay.style.display = "block"; + this.set(str, "string", new Date().getTime() - startTime, true); +}; + + +/** + * Handler for show file overlay events. + * + * @param {Event} e + */ +OutputWaiter.prototype.showFileOverlayClick = function(e) { + const outputFile = document.getElementById("output-file"), + showFileOverlay = e.target; + + outputFile.style.display = "block"; + showFileOverlay.style.display = "none"; + this.setOutputInfo(this.dishBuffer.byteLength, null, 0); }; @@ -86,13 +193,17 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { let width = length.toString().length; width = width < 4 ? 4 : width; - const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); - const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); - const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " "); + const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); + const timeStr = (duration.toString() + "ms").padStart(width, " ").replace(/ /g, " "); + + let msg = "time: " + timeStr + "
length: " + lengthStr; + + if (typeof lines === "number") { + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); + msg += "
lines: " + linesStr; + } - document.getElementById("output-info").innerHTML = "time: " + timeStr + - "
length: " + lengthStr + - "
lines: " + linesStr; + document.getElementById("output-info").innerHTML = msg; document.getElementById("input-selection-info").innerHTML = ""; document.getElementById("output-selection-info").innerHTML = ""; }; @@ -129,24 +240,13 @@ OutputWaiter.prototype.adjustWidth = function() { /** * Handler for save click events. - * Saves the current output to a file, downloaded as a URL octet stream. + * Saves the current output to a file. */ OutputWaiter.prototype.saveClick = function() { - const data = Utils.toBase64(this.app.dishStr); - const filename = window.prompt("Please enter a filename:", "download.dat"); - - if (filename) { - const el = document.createElement("a"); - el.setAttribute("href", "data:application/octet-stream;base64;charset=utf-8," + data); - el.setAttribute("download", filename); - - // Firefox requires that the element be added to the DOM before it can be clicked - el.style.display = "none"; - document.body.appendChild(el); - - el.click(); - el.remove(); + if (!this.dishBuffer) { + this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.dishStr)).buffer; } + this.downloadFile(); }; @@ -165,14 +265,14 @@ OutputWaiter.prototype.copyClick = function() { textarea.style.height = 0; textarea.style.border = "none"; - textarea.value = this.app.dishStr; + textarea.value = this.dishStr; document.body.appendChild(textarea); // Select and copy the contents of this textarea let success = false; try { textarea.select(); - success = document.execCommand("copy"); + success = this.dishStr && document.execCommand("copy"); } catch (err) { success = false; } @@ -195,7 +295,17 @@ OutputWaiter.prototype.copyClick = function() { OutputWaiter.prototype.switchClick = function() { this.switchOrigData = this.manager.input.get(); document.getElementById("undo-switch").disabled = false; - this.app.setInput(this.app.dishStr); + if (this.dishBuffer) { + this.manager.input.setFile(new File([this.dishBuffer], "output.dat")); + this.manager.input.handleLoaderMessage({ + data: { + progress: 100, + fileBuffer: this.dishBuffer + } + }); + } else { + this.app.setInput(this.dishStr); + } }; @@ -210,7 +320,7 @@ OutputWaiter.prototype.undoSwitchClick = function() { /** * Handler for file switch click events. - * Moves a files data for items created via Utils.displayFilesAsHTML to the input. + * Moves a file's data for items created via Utils.displayFilesAsHTML to the input. */ OutputWaiter.prototype.fileSwitch = function(e) { e.preventDefault(); @@ -282,4 +392,14 @@ OutputWaiter.prototype.setStatusMsg = function(msg) { el.textContent = msg; }; + +/** + * Returns true if the output contains carriage returns + * + * @returns {boolean} + */ +OutputWaiter.prototype.containsCR = function() { + return this.dishStr.indexOf("\r") >= 0; +}; + export default OutputWaiter; diff --git a/src/web/WorkerWaiter.js b/src/web/WorkerWaiter.js index 6fc69e407d..402b56b03f 100644 --- a/src/web/WorkerWaiter.js +++ b/src/web/WorkerWaiter.js @@ -1,4 +1,3 @@ -import Utils from "../core/Utils.js"; import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js"; /** @@ -111,7 +110,6 @@ WorkerWaiter.prototype.bakingComplete = function(response) { this.app.handleError(response.error); } - this.app.dishStr = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result; this.app.progress = response.progress; this.manager.recipe.updateBreakpointIndicator(response.progress); this.manager.output.set(response.result, response.type, response.duration); diff --git a/src/web/html/index.html b/src/web/html/index.html index b628977251..ea5fec36d1 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -181,6 +181,20 @@
+
+
+
+ +
+ + Name:
+ Size:
+ Type:
+ Loaded: +
+
+
+
@@ -202,6 +216,26 @@
+ +
+
+
+ +
+ Size:
+ +
+ + + + +
to
+ +
+
+
+
+
@@ -308,31 +342,35 @@
- +
- +
- +
- +
- +
- +
- + +
+
+ +
diff --git a/src/web/index.js b/src/web/index.js index 5964b1e80d..a915eae776 100755 --- a/src/web/index.js +++ b/src/web/index.js @@ -38,15 +38,16 @@ function main() { ]; const defaultOptions = { - updateUrl: true, - showHighlighter: true, - treatAsUtf8: true, - wordWrap: true, - showErrors: true, - errorTimeout: 4000, - attemptHighlight: true, - theme: "classic", - useMetaKey: false + updateUrl: true, + showHighlighter: true, + treatAsUtf8: true, + wordWrap: true, + showErrors: true, + errorTimeout: 4000, + attemptHighlight: true, + theme: "classic", + useMetaKey: false, + outputFileThreshold: 1024 }; document.removeEventListener("DOMContentLoaded", main, false); diff --git a/src/web/static/images/file-128x128.png b/src/web/static/images/file-128x128.png new file mode 100644 index 0000000000..005c504dd3 Binary files /dev/null and b/src/web/static/images/file-128x128.png differ diff --git a/src/web/static/images/file-32x32.png b/src/web/static/images/file-32x32.png new file mode 100644 index 0000000000..884bf4851c Binary files /dev/null and b/src/web/static/images/file-32x32.png differ diff --git a/src/web/stylesheets/components/_pane.css b/src/web/stylesheets/components/_pane.css index 7246a24a2a..fb8f309b6c 100644 --- a/src/web/stylesheets/components/_pane.css +++ b/src/web/stylesheets/components/_pane.css @@ -28,3 +28,56 @@ margin: 0; padding: 0; } + +.card { + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.3s; + width: 400px; + height: 150px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-family: var(--primary-font-family); + color: var(--primary-font-colour); + line-height: 30px; + background-color: var(--primary-background-colour); +} + +.card:hover { + box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); +} + +.card>img { + float: left; + width: 128px; + height: 128px; + margin-left: 10px; + margin-top: 11px; +} + +.card-body .close { + position: absolute; + right: 10px; + top: 10px; +} + +.card-body { + float: left; + padding: 16px; + width: 250px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + user-select: text; +} + +.card-body>.btn { + margin-bottom: 15px; + margin-top: 5px; +} + +.card input[type=number] { + padding-right: 6px; + padding-left: 6px; +} diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 997af92ed7..c93c800b26 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -39,7 +39,7 @@ } .textarea-wrapper textarea, -.textarea-wrapper div { +.textarea-wrapper>div { font-family: var(--fixed-width-font-family); font-size: var(--fixed-width-font-size); color: var(--fixed-width-font-colour); @@ -77,6 +77,25 @@ transition: all 0.5s ease; } +#input-file, +#output-file { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: var(--title-background-colour); + display: none; +} + +#show-file-overlay { + position: absolute; + right: 15px; + top: 15px; + cursor: pointer; + display: none; +} + .io-btn-group { float: right; margin-top: -4px; @@ -92,6 +111,8 @@ font-family: var(--fixed-width-font-family); font-weight: normal; font-size: 8pt; + display: flex; + align-items: center; } #input-info { diff --git a/src/web/stylesheets/utils/_overrides.css b/src/web/stylesheets/utils/_overrides.css index 36069cd5e8..23f83bd887 100755 --- a/src/web/stylesheets/utils/_overrides.css +++ b/src/web/stylesheets/utils/_overrides.css @@ -64,7 +64,8 @@ a:focus { .alert, .modal-content, .tooltip-inner, -.dropdown-menu { +.dropdown-menu, +.input-group-addon { border-radius: 0 !important; } @@ -187,6 +188,15 @@ optgroup { color: var(--primary-font-colour); } +.input-group-addon:not(:first-child):not(:last-child) { + border-left: 0; + border-right: 0; +} + +.input-group-btn:first-child>.btn { + border-right: 0; +} + /* Bootstrap-switch */