diff --git a/.babelrc b/.babelrc index 6f6f27bfe..57750d503 100644 --- a/.babelrc +++ b/.babelrc @@ -12,9 +12,7 @@ "resource/react-dom.js", "resource/bluebird.js", "resource/bluebird/*.js", - "test/resource/httpd.js", - "test/resource/mocha.js", - "test/resource/co-mocha.js" + "test/resource/*.js" ], "plugins": [ "syntax-flow", diff --git a/.gitignore b/.gitignore index 10114b175..323a4f034 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules -build \ No newline at end of file +build +.signatures.json \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 99fd43041..5d35d2d0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - npm i - - node_modules/.bin/gulp build + - npm run build - if [ $FX_VERSION = "54.0b" ] && [ $TRAVIS_REPO_SLUG = "zotero/zotero" ] && [ $TRAVIS_BRANCH = "master" ] && diff --git a/gulp/babel-worker.js b/gulp/babel-worker.js deleted file mode 100644 index d77f01b1f..000000000 --- a/gulp/babel-worker.js +++ /dev/null @@ -1,55 +0,0 @@ -/* global onmessage: true, postMessage: false */ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const babel = require('babel-core'); -const minimatch = require('minimatch') -const mkdirp = require('mkdirp'); -const options = JSON.parse(fs.readFileSync('.babelrc')); - -/* exported onmessage */ -onmessage = (ev) => { - const t1 = Date.now(); - const sourcefile = path.normalize(ev.data); - let error = null; - let isSkipped = false; - - fs.readFile(sourcefile, 'utf8', (err, data) => { - var transformed; - if(sourcefile === 'resource/react-dom.js') { - transformed = data.replace(/ownerDocument\.createElement\((.*?)\)/gi, 'ownerDocument.createElementNS(DOMNamespaces.html, $1)'); - } else if('ignore' in options && options.ignore.some(ignoreGlob => minimatch(sourcefile, ignoreGlob))) { - transformed = data; - isSkipped = true; - } else { - try { - transformed = babel.transform(data, options).code; - } catch(c) { - transformed = data; - isSkipped = true; - error = c.message; - } - } - - const outfile = path.join('build', sourcefile); - error = error || err; - - mkdirp(path.dirname(outfile), err => { - error = error || err; - - fs.writeFile(outfile, transformed, err => { - error = error || err; - - const t2 = Date.now(); - postMessage({ - isSkipped, - sourcefile, - outfile, - error, - processingTime: t2 - t1 - }); - }); - }); - }); -}; \ No newline at end of file diff --git a/gulp/gulp-react-patcher.js b/gulp/gulp-react-patcher.js deleted file mode 100644 index 26b9b4fbe..000000000 --- a/gulp/gulp-react-patcher.js +++ /dev/null @@ -1,34 +0,0 @@ -const path = require('path'); -const gutil = require('gulp-util'); -const through = require('through2'); -const PluginError = gutil.PluginError; - -const PLUGIN_NAME = 'gulp-react-patcher'; - -module.exports = function() { - return through.obj(function(file, enc, callback) { - if (file.isNull()) { - this.push(file); - return callback(); - } - - if(file.isStream()) { - this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!')); - return callback(); - } - - try { - - let filename = path.basename(file.path); - - if(filename === 'react-dom.js') { - file.contents = Buffer.from(file.contents.toString().replace(/ownerDocument\.createElement\((.*?)\)/gi, 'ownerDocument.createElementNS(DOMNamespaces.html, $1)'), enc); - } - } catch(e) { - this.emit('error', new PluginError(PLUGIN_NAME, e)); - } - - this.push(file); - callback(); - }); -}; diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index db5594a14..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,263 +0,0 @@ -'use strict'; - -const gulp = require('gulp'); -const del = require('del'); -const vfs = require('vinyl-fs'); -const gutil = require('gulp-util'); -const babel = require('gulp-babel'); -const sass = require('gulp-sass'); -const os = require('os'); -const glob = require('glob'); -const Worker = require('tiny-worker'); -const merge = require('merge-stream'); -const tap = require('gulp-tap'); -const rename = require('gulp-rename'); -const browserify = require('browserify'); -const reactPatcher = require('./gulp/gulp-react-patcher'); -const isWindows = /^win/.test(process.platform); -const NODE_ENV = process.env.NODE_ENV; -const workers = []; -var isExiting = false; - -const formatDirsforMatcher = dirs => { - return dirs.length > 1 ? `{${dirs.join(',')}}` : dirs[0]; -}; - -const killAllWorkers = () => { - for(let worker of workers) { - worker.terminate(); - } -}; - -// list of folders from where .js files are compiled and non-js files are symlinked -const dirs = [ - 'chrome', - 'components', - 'defaults', - 'resource', - 'resource/web-library', - 'test', - 'test/resource/chai', - 'test/resource/chai-as-promised', - 'test/resource/mocha' -]; - -// list of folders from which all files are symlinked -const symlinkDirs = [ - 'styles', - 'translators', -]; - -// list of folders which are copied to the build folder -const copyDirs = [ - 'test/tests/data' // browser follows symlinks when loading test data - // triggering false-positive test results with mismatched URIs -]; - -// list of files from root folder to symlink -const symlinkFiles = [ - 'chrome.manifest', 'install.rdf', 'update.rdf' -]; - -// these files will be browserified during the build -const browserifyConfigs = [ - { - src: 'node_modules/sinon/lib/sinon.js', - dest: 'test/resource/sinon.js', - config: { - standalone: 'sinon' - } - }, - { - src: 'node_modules/chai-as-promised/lib/chai-as-promised.js', - dest: 'test/resource/chai-as-promised.js', - config: { - standalone: 'chaiAsPromised' - } - } -]; - -const jsGlob = `./\{${dirs.join(',')}\}/**/*.js`; -const jsGlobIgnore = `./\{${symlinkDirs.concat(copyDirs).join(',')}\}/**/*.js`; - -function onError(shouldExit, err) { - if(shouldExit) { - isExiting = true; - killAllWorkers(); - throw new Error(err); - } else { - gutil.log(gutil.colors.red('Error:'), err); - this.emit('end'); - } -} - -function onSuccess(msg) { - if(!isExiting) { - gutil.log(gutil.colors.green('Build:'), msg); - } -} - -function getBrowserify(exitOnError = true) { - const streams = browserifyConfigs.map(config => { - return gulp - .src(config.src) - .pipe(tap(file => { - file.contents = browserify(file.path, config.config).bundle(); - })) - .pipe(rename(config.dest)) - .on('error', function(err) { onError.bind(this)(exitOnError, err); }) - .on('data', file => { - onSuccess(`[browserify] ${file.path}`); - }) - .pipe(gulp.dest('build')); - }); - - return merge.apply(merge, streams); -} - -function getJS(source, sourceIgnore, exitOnError = true) { - if (sourceIgnore) { - source = [source, '!' + sourceIgnore]; - } - - return gulp.src(source, { base: '.' }) - .pipe(babel()) - .on('error', function(err) { onError.bind(this)(exitOnError, err); }) - .on('data', file => { - onSuccess(`[js] ${file.path}`); - }) - .pipe(reactPatcher()) - .pipe(gulp.dest('./build')); -} - -function getJSParallel(source, sourceIgnore, exitOnError = true) { - const jsFiles = glob.sync(source, { ignore: sourceIgnore }); - const cpuCount = os.cpus().length; - const threadCount = Math.min(cpuCount, jsFiles.length); - let threadsActive = threadCount; - let isError = false; - - return new Promise((resolve, reject) => { - for(let i = 0; i < threadCount; i++) { - let worker = new Worker('gulp/babel-worker.js'); - workers[i] = worker; - worker.onmessage = ev => { - if(ev.data.error) { - isError = true; - let errorMsg = `Failed while processing ${ev.data.sourcefile}: ${ev.data.error}`; - NODE_ENV == 'debug' && console.log(`process ${i}: ${errorMsg}`); - onError(exitOnError, errorMsg); - reject(errorMsg); - } - - NODE_ENV == 'debug' && console.log(`process ${i} took ${ev.data.processingTime} ms to process ${ev.data.sourcefile}`); - NODE_ENV != 'debug' && onSuccess(`[js] ${ev.data.sourcefile}`); - - if(ev.data.isSkipped) { - NODE_ENV == 'debug' && console.log(`process ${i} SKIPPED ${ev.data.sourcefile}`); - } - let nextFile = jsFiles.pop(); - - if(!isError && nextFile) { - NODE_ENV == 'debug' && console.log(`process ${i} scheduled to process ${nextFile}`); - worker.postMessage(nextFile); - } else { - NODE_ENV == 'debug' && console.log(`process ${i} has terminated`); - worker.terminate(); - workers.splice(i, 1); - if(!--threadsActive) { - resolve(); - } - } - }; - worker.postMessage(jsFiles.pop()); - } - - NODE_ENV == 'debug' && console.log(`Started ${threadCount} processes for processing JS`); - }); -} - -function getSymlinks(exitOnError = true) { - const match = symlinkFiles - .concat(dirs.map(d => `${d}/**`)) - .concat(symlinkDirs.map(d => `${d}/**`)) - .concat([`!./${formatDirsforMatcher(dirs)}/**/*.js`]) - .concat([`!./${formatDirsforMatcher(copyDirs)}/**`]); - - return gulp - .src(match, { nodir: true, base: '.', read: isWindows }) - .on('error', function(err) { onError.bind(this)(exitOnError, err); }) - .on('data', file => { - onSuccess(`[ln] ${file.path.substr(__dirname.length + 1)}`); - }) - .pipe(isWindows ? gulp.dest('build/') : vfs.symlink('build/')); -} - -function getCopy(exitOnError = true) { - return gulp - .src(copyDirs.map(d => `${d}/**`), { base: '.' }) - .on('data', file => { - onSuccess(`[cp] ${file.path.substr(__dirname.length + 1)}`); - }) - .on('error', function(err) { onError.bind(this)(exitOnError, err); }) - .pipe(gulp.dest('build/')); -} - -function getSass(exitOnError = true) { - return gulp - .src('scss/*.scss') - .on('error', function(err) { onError.bind(this)(exitOnError, err); }) - .pipe(sass()) - .pipe(gulp.dest('./build/chrome/skin/default/zotero/components/')); -} - - -gulp.task('clean', () => { - return del('build'); -}); - -gulp.task('symlink', () => { - return getSymlinks(); -}); - -gulp.task('js', done => { - getJSParallel(jsGlob, jsGlobIgnore) - .then(done) - .catch(errorMsg => { - onError(errorMsg); - }); -}); - -gulp.task('browserify', () => { - getBrowserify(); -}); - -gulp.task('copy', () => { - getCopy(); -}); - -gulp.task('sass', () => { - return getSass(); -}); - -gulp.task('build', ['js', 'sass', 'symlink', 'browserify', 'copy']); - -gulp.task('build-clean', ['clean'], () => { - gulp.start('build'); -}); - -gulp.task('dev', ['clean'], () => { - var interval = 750; - - gulp.watch(jsGlob, { interval }).on('change', event => { - getJS(event.path, jsGlobIgnore, false); - }); - - gulp.watch('src/styles/*.scss', { interval }).on('change', () => { - getSass(false); - }); - - gulp.start('build'); -}); - -gulp.task('default', ['dev']); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 595b335f9..e37059e49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,12 @@ "version": "5.0.0", "lockfileVersion": 1, "dependencies": { + "abbrev": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", + "dev": true + }, "acorn": { "version": "4.0.13", "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", @@ -53,12 +59,6 @@ "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", "dev": true }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, "are-we-there-yet": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", @@ -209,15 +209,15 @@ "dev": true }, "babel-core": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.1.tgz", - "integrity": "sha1-jEKFZNzh4fQfszfsNPTDsCK1rYM=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", + "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", "dev": true }, "babel-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.1.tgz", - "integrity": "sha1-5xX0hsWN7SVknYiJRNUqoHxdlJc=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", + "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", "dev": true }, "babel-helper-builder-react-jsx": { @@ -329,9 +329,9 @@ "dev": true }, "babel-plugin-transform-react-display-name": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz", - "integrity": "sha1-Q5iRDDWEQdxM7xh4cmTQQS7Tazc=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", "dev": true }, "babel-plugin-transform-react-jsx": { @@ -399,33 +399,33 @@ } }, "babel-template": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.24.1.tgz", - "integrity": "sha1-BK5RTx+Ts6JTfyoPYKWkX7gwgzM=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", + "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", "dev": true }, "babel-traverse": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.24.1.tgz", - "integrity": "sha1-qzZnP9NW+aCUhlnnszjV/q2zFpU=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", + "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", "dev": true }, "babel-types": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.24.1.tgz", - "integrity": "sha1-oTaHncFbNga9oNkMH8dDBML/CXU=", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", + "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", "dev": true }, "babylon": { - "version": "6.17.2", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.2.tgz", - "integrity": "sha1-IB0l71+JLEG65JSIsI2w3Udun1w=", + "version": "6.17.4", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", + "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", "dev": true }, "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base64-js": { @@ -441,22 +441,22 @@ "dev": true, "optional": true }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, "binary-extensions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", "dev": true }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true + }, "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" }, "bn.js": { "version": "4.11.6", @@ -476,9 +476,9 @@ "integrity": "sha1-ZZbHq0D2Y3OTMjqwvIDQZPxjBJg=" }, "brace-expansion": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true }, "braces": { @@ -651,18 +651,6 @@ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true }, - "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -681,6 +669,12 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, "combine-source-map": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", @@ -787,23 +781,15 @@ "dev": true }, "create-react-class": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.5.4.tgz", - "integrity": "sha1-GIh1yxXi++TKWVtvQ+sOSh8A/lA=" + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.0.tgz", + "integrity": "sha1-q0SEl8JlZuHilBPogyB9V8/nvtQ=" }, "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "dev": true, - "dependencies": { - "lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "dev": true - } - } + "dev": true }, "cryptiles": { "version": "2.0.5", @@ -843,12 +829,6 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, - "dateformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", - "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", - "dev": true - }, "debug": { "version": "2.6.8", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", @@ -885,24 +865,12 @@ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true - }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -915,12 +883,6 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true - }, "deps-sort": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", @@ -933,12 +895,6 @@ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true }, - "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true - }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -963,6 +919,12 @@ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "dev": true }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true + }, "domain-browser": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", @@ -975,26 +937,6 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true }, - "duplexify": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz", - "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=", - "dev": true, - "dependencies": { - "end-of-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", - "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=", - "dev": true - }, - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true - } - } - }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -1013,20 +955,6 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=" }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "dev": true, - "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true - } - } - }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -1044,6 +972,12 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint-plugin-react": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.1.0.tgz", + "integrity": "sha1-J3cKzzn1/UnNCvQIPOWBBOs5DUw=", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", @@ -1074,24 +1008,12 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", - "dev": true - }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "dev": true }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true - }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", @@ -1104,12 +1026,6 @@ "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", "dev": true }, - "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", - "dev": true - }, "fbjs": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.12.tgz", @@ -1127,50 +1043,12 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true }, - "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", - "dev": true - }, - "fined": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz", - "integrity": "sha1-WyhCS3YNdZiWC374SA3/itNmDpc=", - "dev": true, - "dependencies": { - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - } - } - }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true - }, - "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", - "dev": true - }, "floatthead": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/floatthead/-/floatthead-1.4.0.tgz", @@ -1211,10 +1089,10 @@ "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", "dev": true }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", "dev": true }, "fs.realpath": { @@ -1224,9 +1102,9 @@ "dev": true }, "fsevents": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.1.tgz", - "integrity": "sha1-8Z/Sj0Pur3YWgOUZogPE0LPTGv8=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", + "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", "dev": true, "optional": true, "dependencies": { @@ -1236,17 +1114,17 @@ "dev": true, "optional": true }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true + }, "ansi-regex": { "version": "2.1.1", "bundled": true, "dev": true }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "optional": true - }, "aproba": { "version": "1.1.1", "bundled": true, @@ -1254,7 +1132,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.2", + "version": "1.1.4", "bundled": true, "dev": true, "optional": true @@ -1311,7 +1189,7 @@ "dev": true }, "brace-expansion": { - "version": "1.1.6", + "version": "1.1.7", "bundled": true, "dev": true }, @@ -1321,13 +1199,13 @@ "dev": true }, "caseless": { - "version": "0.11.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true }, - "chalk": { - "version": "1.1.3", + "co": { + "version": "4.6.0", "bundled": true, "dev": true, "optional": true @@ -1342,12 +1220,6 @@ "bundled": true, "dev": true }, - "commander": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true - }, "concat-map": { "version": "0.0.1", "bundled": true, @@ -1384,13 +1256,13 @@ } }, "debug": { - "version": "2.2.0", + "version": "2.6.8", "bundled": true, "dev": true, "optional": true }, "deep-extend": { - "version": "0.4.1", + "version": "0.4.2", "bundled": true, "dev": true, "optional": true @@ -1412,14 +1284,8 @@ "dev": true, "optional": true }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, "extend": { - "version": "3.0.0", + "version": "3.0.1", "bundled": true, "dev": true, "optional": true @@ -1436,7 +1302,7 @@ "optional": true }, "form-data": { - "version": "2.1.2", + "version": "2.1.4", "bundled": true, "dev": true, "optional": true @@ -1447,7 +1313,7 @@ "dev": true }, "fstream": { - "version": "1.0.10", + "version": "1.0.11", "bundled": true, "dev": true }, @@ -1458,25 +1324,13 @@ "optional": true }, "gauge": { - "version": "2.7.3", - "bundled": true, - "dev": true, - "optional": true - }, - "generate-function": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "generate-object-property": { - "version": "1.2.0", + "version": "2.7.4", "bundled": true, "dev": true, "optional": true }, "getpass": { - "version": "0.1.6", + "version": "0.1.7", "bundled": true, "dev": true, "optional": true, @@ -1490,7 +1344,7 @@ } }, "glob": { - "version": "7.1.1", + "version": "7.1.2", "bundled": true, "dev": true }, @@ -1499,20 +1353,14 @@ "bundled": true, "dev": true }, - "graceful-readlink": { - "version": "1.0.1", + "har-schema": { + "version": "1.0.5", "bundled": true, "dev": true, "optional": true }, "har-validator": { - "version": "2.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "has-ansi": { - "version": "2.0.0", + "version": "4.2.1", "bundled": true, "dev": true, "optional": true @@ -1561,18 +1409,6 @@ "bundled": true, "dev": true }, - "is-my-json-valid": { - "version": "2.15.0", - "bundled": true, - "dev": true, - "optional": true - }, - "is-property": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, "is-typedarray": { "version": "1.0.0", "bundled": true, @@ -1608,36 +1444,50 @@ "dev": true, "optional": true }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, "json-stringify-safe": { "version": "5.0.1", "bundled": true, "dev": true, "optional": true }, - "jsonpointer": { - "version": "4.0.1", + "jsonify": { + "version": "0.0.0", "bundled": true, "dev": true, "optional": true }, "jsprim": { - "version": "1.3.1", + "version": "1.4.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } }, "mime-db": { - "version": "1.26.0", + "version": "1.27.0", "bundled": true, "dev": true }, "mime-types": { - "version": "2.1.14", + "version": "2.1.15", "bundled": true, "dev": true }, "minimatch": { - "version": "3.0.3", + "version": "3.0.4", "bundled": true, "dev": true }, @@ -1652,25 +1502,25 @@ "dev": true }, "ms": { - "version": "0.7.1", + "version": "2.0.0", "bundled": true, "dev": true, "optional": true }, "node-pre-gyp": { - "version": "0.6.33", + "version": "0.6.36", "bundled": true, "dev": true, "optional": true }, "nopt": { - "version": "3.0.6", + "version": "4.0.1", "bundled": true, "dev": true, "optional": true }, "npmlog": { - "version": "4.0.2", + "version": "4.1.0", "bundled": true, "dev": true, "optional": true @@ -1697,19 +1547,31 @@ "bundled": true, "dev": true }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true + }, "path-is-absolute": { "version": "1.0.1", "bundled": true, "dev": true }, - "pinkie": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "pinkie-promise": { - "version": "2.0.1", + "performance-now": { + "version": "0.2.0", "bundled": true, "dev": true, "optional": true @@ -1726,13 +1588,13 @@ "optional": true }, "qs": { - "version": "6.3.1", + "version": "6.4.0", "bundled": true, "dev": true, "optional": true }, "rc": { - "version": "1.1.7", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, @@ -1746,19 +1608,23 @@ } }, "readable-stream": { - "version": "2.2.2", + "version": "2.2.9", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "request": { - "version": "2.79.0", + "version": "2.81.0", "bundled": true, "dev": true, "optional": true }, "rimraf": { - "version": "2.5.4", + "version": "2.6.1", + "bundled": true, + "dev": true + }, + "safe-buffer": { + "version": "5.0.1", "bundled": true, "dev": true }, @@ -1787,7 +1653,7 @@ "optional": true }, "sshpk": { - "version": "1.10.2", + "version": "1.13.0", "bundled": true, "dev": true, "optional": true, @@ -1801,7 +1667,7 @@ } }, "string_decoder": { - "version": "0.10.31", + "version": "1.0.1", "bundled": true, "dev": true }, @@ -1827,36 +1693,16 @@ "dev": true, "optional": true }, - "supports-color": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, "tar": { "version": "2.2.1", "bundled": true, "dev": true }, "tar-pack": { - "version": "3.3.0", + "version": "3.4.0", "bundled": true, "dev": true, - "optional": true, - "dependencies": { - "once": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "2.1.5", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "tough-cookie": { "version": "2.3.2", @@ -1865,7 +1711,7 @@ "optional": true }, "tunnel-agent": { - "version": "0.4.3", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -1900,7 +1746,7 @@ "optional": true }, "wide-align": { - "version": "1.1.0", + "version": "1.1.2", "bundled": true, "dev": true, "optional": true @@ -1909,15 +1755,15 @@ "version": "1.0.2", "bundled": true, "dev": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true } } }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true + }, "function-bind": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", @@ -1931,9 +1777,9 @@ "dev": true }, "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", "dev": true }, "get-caller-file": { @@ -1980,134 +1826,28 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "dev": true - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true - }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", - "dev": true - }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", - "dev": true - }, "globals": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", - "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true }, "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true - } - } - }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", "dev": true }, "graceful-fs": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", - "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "graceful-readlink": { @@ -2122,138 +1862,6 @@ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "dev": true, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true - } - } - }, - "gulp-babel": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-6.1.2.tgz", - "integrity": "sha1-fAF25Lo/JExgWIoMSzIKRdGt784=", - "dev": true - }, - "gulp-rename": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", - "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", - "dev": true - }, - "gulp-sass": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz", - "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=", - "dev": true - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true - } - } - }, - "gulp-tap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gulp-tap/-/gulp-tap-1.0.1.tgz", - "integrity": "sha1-5nESThJZtM6iGe0cqXt/WFwzRpA=", - "dev": true - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true - }, "har-schema": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", @@ -2284,12 +1892,6 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -2303,9 +1905,9 @@ "dev": true }, "hash.js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", - "integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.1.tgz", + "integrity": "sha512-I2TYCUjYQMmqmRMCp6jKMC5bvdXxGIZ/heITRR/0F1u0OP920ImEj/cXt3WgcTKBnNYGn7enxUzdai3db829JA==", "dev": true }, "hawk": { @@ -2342,12 +1944,6 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true - }, "hosted-git-info": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", @@ -2373,9 +1969,9 @@ "dev": true }, "iconv-lite": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.17.tgz", - "integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0=" + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" }, "ieee754": { "version": "1.1.8", @@ -2413,12 +2009,6 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "dev": true - }, "inline-source-map": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", @@ -2431,12 +2021,6 @@ "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", "dev": true }, - "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", - "dev": true - }, "invariant": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", @@ -2448,12 +2032,6 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "dev": true - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2532,24 +2110,6 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true - }, - "is-path-inside": { - "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 - }, "is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", @@ -2562,12 +2122,6 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "dev": true - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -2579,30 +2133,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "dev": true - }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, - "is-valid-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", - "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", - "dev": true - }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2632,13 +2168,6 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, - "jodid25519": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", - "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", - "dev": true, - "optional": true - }, "jquery": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", @@ -2698,6 +2227,12 @@ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, + "jsonfile": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.0.tgz", + "integrity": "sha1-kufHRE5f/V+jLmqa6LhQNN+DR9A=", + "dev": true + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -2730,6 +2265,12 @@ } } }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -2750,12 +2291,6 @@ } } }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true - }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -2780,39 +2315,11 @@ } } }, - "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", - "dev": true, - "dependencies": { - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - } - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true - } - } + "dev": true }, "lodash": { "version": "4.17.4", @@ -2847,18 +2354,6 @@ "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=" }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", @@ -2871,42 +2366,12 @@ "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, - "lodash.assignwith": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", - "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", - "dev": true - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -2919,12 +2384,6 @@ "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", "dev": true }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true - }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -2935,29 +2394,11 @@ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" }, - "lodash.isempty": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", - "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, "lodash.isplainobject": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz", "integrity": "sha1-moI4rhayAEMpYM1zRlEtASP79MU=" }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -2969,12 +2410,6 @@ "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-3.0.8.tgz", "integrity": "sha1-IsRJPrvtsUJ5YqVLRFssinZ/tH8=" }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -2987,30 +2422,6 @@ "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", "dev": true }, - "lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true - }, "lolex": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", @@ -3029,15 +2440,9 @@ "dev": true }, "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", "dev": true }, "map-obj": { @@ -3060,12 +2465,6 @@ } } }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true - }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -3164,37 +2563,11 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true }, "nan": { "version": "2.6.2", @@ -3208,12 +2581,6 @@ "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", "dev": true }, - "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", - "dev": true - }, "node-fetch": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz", @@ -3223,47 +2590,19 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", - "dev": true, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - } - } + "dev": true }, "node-sass": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.3.tgz", "integrity": "sha1-0JydEXlkEjnRuX/8YjH9zsU+FWg=", - "dev": true, - "dependencies": { - "gaze": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", - "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", - "dev": true - }, - "globule": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.1.0.tgz", - "integrity": "sha1-xJNS5NwYPYWJPuglOF65lLtt9F8=", - "dev": true - }, - "lodash": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.6.tgz", - "integrity": "sha1-0iyaxmAojzhD4Wun0rXQbMon13c=", - "dev": true - } - } + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true }, "normalize-package-data": { "version": "2.3.8", @@ -3312,18 +2651,6 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, "os-browserify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", @@ -3348,10 +2675,10 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "outpipe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", - "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", "dev": true }, "pako": { @@ -3372,12 +2699,6 @@ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "dev": true }, - "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", - "dev": true - }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -3390,24 +2711,12 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -3420,12 +2729,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -3438,18 +2741,6 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -3468,15 +2759,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - } - } + "dev": true }, "pbkdf2": { "version": "3.0.12", @@ -3514,12 +2797,6 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, "private": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", @@ -3539,9 +2816,9 @@ "dev": true }, "promise": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz", - "integrity": "sha1-SJZUxpJha4qlWwck+oCbt9tJxb8=" + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==" }, "prop-types": { "version": "15.5.10", @@ -3590,26 +2867,48 @@ "dev": true }, "randomatic": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", - "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", - "dev": true + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true + } + } }, "randombytes": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.4.tgz", - "integrity": "sha1-lVHfIIQiyPgOtY4jJt0LhA/yLv0=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", "dev": true }, "react": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/react/-/react-15.5.4.tgz", - "integrity": "sha1-+oPrAVBqsjfNwcjDsc6o3gEr8Ec=" + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react/-/react-15.6.1.tgz", + "integrity": "sha1-uqhDTsZ4C96ZfNw4C3nNM7ljk98=" }, "react-dom": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.5.4.tgz", - "integrity": "sha1-ugwoeG/VLtfk8hNf4CiNRirvk9o=" + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.1.tgz", + "integrity": "sha1-LLDtQZEDjlPCCes6eaI+Kkz5lHA=" }, "react-redux": { "version": "4.4.8", @@ -3647,29 +2946,15 @@ "dev": true }, "readable-stream": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", - "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.0.tgz", + "integrity": "sha512-c7KMXGd4b48nN3OJ1U9qOsn6pXNzf6kLd3kdZCkg2sxAcoiufInqF0XckwEnlrcwuaYwonlNK8GQUIOC/WC7sg==", "dev": true }, "readdirp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true }, "redent": { @@ -3679,9 +2964,9 @@ "dev": true }, "redux": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.6.0.tgz", - "integrity": "sha1-iHwrPQub2G7KK+cFccJ2VMGeGI0=" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.0.tgz", + "integrity": "sha512-GHjaOkEQtQnnuLoYPFkRKHIqs1i1tdTlisu/xUHfk2juzCobSy4STxs4Lz5bPkc07Owb6BeGKx/r76c9IVTkOw==" }, "redux-logger": { "version": "2.10.2", @@ -3716,9 +3001,9 @@ "dev": true }, "remove-trailing-separator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", - "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", "dev": true }, "repeat-element": { @@ -3739,12 +3024,6 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, "request": { "version": "2.81.0", "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", @@ -3769,12 +3048,6 @@ "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", "dev": true }, - "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", - "dev": true - }, "rimraf": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", @@ -3820,15 +3093,9 @@ } }, "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, "set-blocking": { @@ -3866,12 +3133,6 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -3879,9 +3140,9 @@ "dev": true }, "sinon": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.2.tgz", - "integrity": "sha1-xDqcVw8yuqwRWVBc/u0ZEIhV34k=", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.5.tgz", + "integrity": "sha1-mi/A/41SbacW8wlTqixl1RiRf2w=", "dev": true, "dependencies": { "type-detect": { @@ -3921,12 +3182,6 @@ "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz", "integrity": "sha1-N7djhHdjrn56zvLKUjPQHmSaeLc=" }, - "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", - "dev": true - }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -3946,9 +3201,9 @@ "dev": true }, "sshpk": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", - "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "dev": true, "dependencies": { "assert-plus": { @@ -3977,22 +3232,10 @@ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, "stream-http": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.1.tgz", - "integrity": "sha1-VGpRdBrVprB+njGwsQRBqRffUoo=", - "dev": true - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", "dev": true }, "stream-splicer": { @@ -4007,10 +3250,18 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, "string_decoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", - "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "dev": true, + "dependencies": { + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + } + } }, "string-width": { "version": "1.0.2", @@ -4031,25 +3282,11 @@ "dev": true }, "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true - } - } - }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", @@ -4092,6 +3329,12 @@ "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", "dev": true }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true + }, "text-encoding": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", @@ -4110,42 +3353,12 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true }, - "through2-filter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", - "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", - "dev": true - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, "timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true }, - "tiny-worker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.1.1.tgz", - "integrity": "sha1-BUbxQ35Dud4lPvqtI1BHZ31zVls=", - "dev": true - }, - "to-absolute-glob": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", - "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", - "dev": true - }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -4218,16 +3431,10 @@ "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", "dev": true }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "universalify": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.0.tgz", + "integrity": "sha1-nrHEZR3rzGcMyU8adXYjMruWd3g=", "dev": true }, "url": { @@ -4244,12 +3451,6 @@ } } }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -4271,21 +3472,9 @@ "dev": true }, "uuid": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true - }, - "vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", "dev": true }, "validate-npm-package-license": { @@ -4300,118 +3489,6 @@ "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", "dev": true }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true - }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -4428,12 +3505,6 @@ "resolved": "https://registry.npmjs.org/warning/-/warning-2.1.0.tgz", "integrity": "sha1-ISINnGOvx3qMkhEeARr3Bc4MaQE=" }, - "watchify": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.9.0.tgz", - "integrity": "sha1-8HX9LoqGrN6Eztum5cKgvt1SPZ4=", - "dev": true - }, "whatwg-fetch": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", diff --git a/package.json b/package.json index 65f78bd0d..3e13c7aa3 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,13 @@ "description": "Zotero", "main": "", "scripts": { - "start": "./node_modules/.bin/gulp", - "build": "./node_modules/.bin/gulp build-clean", - "sass": "./node_modules/.bin/gulp sass", - "clean": "./node_modules/.bin/gulp clean" + "start": "node ./scripts/build.js && node ./scripts/watch.js", + "build": "node ./scripts/build.js", + "sass": "node ./scripts/sass.js", + "js": "node ./scripts/js.js", + "clean": "node ./scripts/clean.js", + "clean-build": "node ./scripts/clean.js && node ./scripts/build.js", + "clean-start": "node ./scripts/clean.js && node ./scripts/build.js && node ./scripts/watch.js" }, "license": "", "dependencies": { @@ -33,22 +36,16 @@ "browserify": "^14.3.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", + "chokidar": "^1.7.0", "co-mocha": "^1.2.0", - "del": "^2.2.2", - "glob": "^7.1.2", - "gulp": "^3.9.1", - "gulp-babel": "^6.1.2", - "gulp-rename": "^1.2.2", - "gulp-sass": "^3.1.0", - "gulp-tap": "^1.0.1", - "gulp-util": "^3.0.7", - "merge-stream": "^1.0.1", - "minimatch": "^3.0.4", + "colors": "^1.1.2", + "eslint-plugin-react": "^7.1.0", + "fs-extra": "^3.0.1", + "globby": "^6.1.0", "mocha": "^3.4.2", + "multimatch": "^2.1.0", + "node-sass": "^4.5.3", "sinon": "^2.3.1", - "through2": "^2.0.1", - "tiny-worker": "^2.1.1", - "vinyl-fs": "^2.4.4", - "watchify": "^3.7.0" + "universalify": "^0.1.0" } } diff --git a/scripts/babel-worker.js b/scripts/babel-worker.js new file mode 100644 index 000000000..19754ffb9 --- /dev/null +++ b/scripts/babel-worker.js @@ -0,0 +1,56 @@ +/* global onmessage: true, postMessage: false */ +'use strict'; + +const fs = require('fs-extra'); +const path = require('path'); +const babel = require('babel-core'); +const multimatch = require('multimatch'); +const options = JSON.parse(fs.readFileSync('.babelrc')); +const cluster = require('cluster'); + +/* exported onmessage */ +async function babelWorker(ev) { + const t1 = Date.now(); + const sourcefile = ev.file; + const outfile = path.join('build', sourcefile); + const postError = (error) => { + process.send({ + sourcefile, + outfile, + error + }); + }; + + var isSkipped = false; + var transformed; + + try { + let contents = await fs.readFile(sourcefile, 'utf8'); + if (sourcefile === 'resource/react-dom.js') { + // patch react + transformed = contents.replace(/ownerDocument\.createElement\((.*?)\)/gi, 'ownerDocument.createElementNS(DOMNamespaces.html, $1)'); + } else if ('ignore' in options && options.ignore.some(ignoreGlob => multimatch(sourcefile, ignoreGlob).length)) { + transformed = contents; + isSkipped = true; + } else { + try { + transformed = babel.transform(contents, options).code; + } catch (error) { return postError(`Babel error: ${error}`);} + } + + await fs.outputFile(outfile, transformed); + const t2 = Date.now(); + process.send({ + isSkipped, + sourcefile, + outfile, + processingTime: t2 - t1 + }); + } catch (error) { return postError(`I/O error: ${error}`); } +} + +module.exports = babelWorker; + +if (cluster.isWorker) { + process.on('message', babelWorker); +} \ No newline at end of file diff --git a/scripts/browserify.js b/scripts/browserify.js new file mode 100644 index 000000000..9328e36d8 --- /dev/null +++ b/scripts/browserify.js @@ -0,0 +1,78 @@ +'use strict'; + +const browserify = require('browserify'); +const globby = require('globby'); +const path = require('path'); +const fs = require('fs-extra'); +const { getSignatures, writeSignatures, cleanUp, compareSignatures, getFileSignature, onSuccess, onError, onProgress } = require('./utils'); + +const { browserifyConfigs } = require('./config'); +const ROOT = path.resolve(__dirname, '..'); + +async function getBrowserify(signatures) { + const t1 = Date.now(); + var count = 0; + var config, f, totalCount; + + while ((config = browserifyConfigs.pop()) != null) { + let files = await globby(config.src, { cwd: ROOT }); + totalCount += files.length; + + while ((f = files.pop()) != null) { + let newFileSignature = await getFileSignature(f); + const dest = path.join('build', config.dest); + + if (f in signatures) { + if (compareSignatures(newFileSignature, signatures[f])) { + try { + await fs.access(dest, fs.constants.F_OK); + continue; + } catch (_) { + // file does not exists in build, fallback to browserifing + } + } + } + try { + await fs.mkdirp(path.dirname(dest)); + const bundleFs = fs.createWriteStream(dest); + await new Promise((resolve, reject) => { + bundleFs + .on('error', reject) + .on('finish', resolve); + browserify(f, config.config).bundle().pipe(bundleFs); + }); + + onProgress(f, dest, 'browserify'); + signatures[f] = newFileSignature; + count++; + } catch (err) { + throw new Error(`Failed on ${f}: ${err}`); + } + } + } + + const t2 = Date.now(); + return { + action: 'browserify', + count, + totalCount, + processingTime: t2 - t1 + }; +} + +module.exports = getBrowserify; + +if (require.main === module) { + (async () => { + try { + const signatures = await getSignatures(); + onSuccess(await getBrowserify(signatures)); + onSuccess(await cleanUp(signatures)); + await writeSignatures(signatures); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 000000000..0386ac08d --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,44 @@ +const colors = require('colors/safe'); + +const getBrowserify = require('./browserify'); +const getCopy = require('./copy'); +const getJS = require('./js'); +const getSass = require('./sass'); +const getSymlinks = require('./symlinks'); +const { formatDirsForMatcher, getSignatures, writeSignatures, cleanUp, onSuccess, onError} = require('./utils'); +const { dirs, symlinkDirs, copyDirs, symlinkFiles, jsFiles, ignoreMask } = require('./config'); + +if (require.main === module) { + (async () => { + try { + const t1 = Date.now(); + global.isError = false; // used to prevent further output to avoid concealing errors + const symlinks = symlinkFiles + .concat(dirs.map(d => `${d}/**`)) + .concat([`!${formatDirsForMatcher(dirs)}/**/*.js`]) + .concat([`!${formatDirsForMatcher(copyDirs)}/**`]) + + const signatures = await getSignatures(); + const results = await Promise.all([ + getBrowserify(signatures), + getCopy(copyDirs.map(d => `${d}/**`), { ignore: ignoreMask }, signatures), + getJS(jsFiles, { ignore: ignoreMask }, signatures), + getSass('scss/*.scss', { root: 'scss', ignore: ignoreMask }, signatures), + getSymlinks(symlinks, { nodir: true, ignore: ignoreMask }, signatures), + getSymlinks(symlinkDirs, { ignore: ignoreMask }, signatures), + cleanUp(signatures) + ]); + + await writeSignatures(signatures); + for (const result of results) { + onSuccess(result); + } + const t2 = Date.now(); + console.log(colors.yellow(`Total build time ${t2 - t1}ms`)); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 000000000..09a2f938a --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,26 @@ +'use strict'; + +const path = require('path'); +const fs = require('fs-extra'); +const { onError } = require('./utils'); + +const ROOT = path.resolve(__dirname, '..'); + +async function getClean(source) { + await fs.remove(source); +} + +module.exports = getClean; + +if (require.main === module) { + (async () => { + try { + await getClean(path.join(ROOT, 'build')); + await getClean(path.join(ROOT, '.signatures.json')); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/config.js b/scripts/config.js new file mode 100644 index 000000000..990c34f69 --- /dev/null +++ b/scripts/config.js @@ -0,0 +1,60 @@ +// list of folders from where .js files are compiled and non-js files are symlinked +const dirs = [ + 'chrome', + 'components', + 'defaults', + 'resource', + 'resource/web-library', + 'test', + 'test/resource/chai', + 'test/resource/chai-as-promised', + 'test/resource/mocha' +]; + +// list of folders from which all files are symlinked +const symlinkDirs = [ + 'styles', + 'translators' +]; + +// list of folders which are copied to the build folder +const copyDirs = [ + 'test/tests/data' // browser follows symlinks when loading test data + // triggering false-positive test results with mismatched URIs +]; + +// list of files from root folder to symlink +const symlinkFiles = [ + 'chrome.manifest', 'install.rdf', 'update.rdf' +]; + + +// these files will be browserified during the build +const browserifyConfigs = [ + { + src: 'node_modules/sinon/lib/sinon.js', + dest: 'test/resource/sinon.js', + config: { + standalone: 'sinon' + } + }, + { + src: 'node_modules/chai-as-promised/lib/chai-as-promised.js', + dest: 'test/resource/chai-as-promised.js', + config: { + standalone: 'chaiAsPromised' + } + } +]; + +// exclude mask used for js, copy, symlink and sass tasks +const ignoreMask = ['**/#*.*']; + +const jsFiles = [ + `{${dirs.join(',')}}/**/*.js`, + `!{${symlinkDirs.concat(copyDirs).join(',')}}/**/*.js` +]; + +module.exports = { + dirs, symlinkDirs, copyDirs, symlinkFiles, browserifyConfigs, jsFiles, ignoreMask +}; \ No newline at end of file diff --git a/scripts/copy.js b/scripts/copy.js new file mode 100644 index 000000000..329a2288e --- /dev/null +++ b/scripts/copy.js @@ -0,0 +1,67 @@ +'use strict'; + +const globby = require('globby'); +const path = require('path'); +const fs = require('fs-extra'); +const { getSignatures, writeSignatures, cleanUp, compareSignatures, getFileSignature, onSuccess, onError, onProgress } = require('./utils'); +const { copyDirs, ignoreMask } = require('./config'); + +const ROOT = path.resolve(__dirname, '..'); + +async function getCopy(source, options, signatures) { + const t1 = Date.now(); + const files = await globby(source, Object.assign({ cwd: ROOT }, options )); + const totalCount = files.length; + var count = 0; + var f; + + while ((f = files.pop()) != null) { + let newFileSignature = await getFileSignature(f); + const dest = path.join('build', f); + + if (f in signatures) { + if (compareSignatures(newFileSignature, signatures[f])) { + try { + await fs.access(dest, fs.constants.F_OK); + continue; + } catch (_) { + // file does not exists in build, fallback to browserifing + } + } + } + try { + await fs.mkdirp(path.dirname(dest)); + await fs.copy(f, dest); + onProgress(f, dest, 'cp'); + signatures[f] = newFileSignature; + count++; + } catch (err) { + throw new Error(`Failed on ${f}: ${err}`); + } + } + + const t2 = Date.now(); + return { + action: 'copy', + count, + totalCount, + processingTime: t2 - t1 + }; +} + +module.exports = getCopy; + +if (require.main === module) { + (async () => { + try { + const signatures = await getSignatures(); + onSuccess(await getCopy(copyDirs.map(d => `${d}/**`), { ignore: ignoreMask }, signatures)); + onSuccess(await cleanUp(signatures)); + await writeSignatures(signatures); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/js.js b/scripts/js.js new file mode 100644 index 000000000..3fc752efa --- /dev/null +++ b/scripts/js.js @@ -0,0 +1,130 @@ +const globby = require('globby'); +const path = require('path'); +const os = require('os'); +const fs = require('fs-extra'); +const cluster = require('cluster'); +const { getSignatures, compareSignatures, getFileSignature, writeSignatures, cleanUp, onSuccess, onError, onProgress } = require('./utils'); +const { jsFiles, ignoreMask } = require('./config'); + +const NODE_ENV = process.env.NODE_ENV; +const ROOT = path.resolve(__dirname, '..'); + +async function getJS(source, options, signatures) { + const t1 = Date.now(); + const matchingJSFiles = await globby(source, Object.assign({ cwd: ROOT }, options)); + const cpuCount = os.cpus().length; + const totalCount = matchingJSFiles.length; + var count = 0; + var isError = false; + + cluster.setupMaster({ + exec: path.join(__dirname, 'babel-worker.js') + }); + + // check signatures, collect signatures for files to be processes + const newFilesSignatures = {}; + const filesForProcessing = []; + var f; + while ((f = matchingJSFiles.pop()) != null) { + const newFileSignature = await getFileSignature(f); + const dest = path.join('build', f); + f = path.normalize(f); + if (f in signatures) { + if (compareSignatures(newFileSignature, signatures[f])) { + try { + await fs.access(dest, fs.constants.F_OK); + continue; + } catch (_) { + // file does not exists in build, fallback to browserifing + } + } + } + filesForProcessing.push(f); + newFilesSignatures[f] = newFileSignature; + } + + // shortcut if no files need rebuilding + if (Object.keys(filesForProcessing).length === 0) { + const t2 = Date.now(); + return Promise.resolve({ + action: 'js', + count, + totalCount, + processingTime: t2 - t1 + }); + } + + // distribute processing among workers + const workerCount = Math.min(cpuCount, filesForProcessing.length); + var workersActive = workerCount; + NODE_ENV == 'debug' && console.log(`Will process ${filesForProcessing.length} files using ${workerCount} processes`); + return new Promise((resolve, reject) => { + for (let i = 0; i < workerCount; i++) { + var worker = cluster.fork(); + + worker.on('message', function(ev) { + if (ev.error) { + isError = true; + let errorMsg = `Failed while processing ${ev.sourcefile}: ${ev.error}`; + reject(errorMsg); + } else { + signatures[ev.sourcefile] = newFilesSignatures[ev.sourcefile]; + + if (ev.isSkipped) { + NODE_ENV == 'debug' && console.log(`process ${this.id} SKIPPED ${ev.sourcefile}`); + } else { + NODE_ENV == 'debug' && console.log(`process ${this.id} took ${ev.processingTime} ms to process ${ev.sourcefile} into ${ev.outfile}`); + NODE_ENV != 'debug' && onProgress(ev.sourcefile, ev.outfile, 'js'); + count++; + } + } + + let nextFile = filesForProcessing.pop(); + + if (!isError && nextFile) { + NODE_ENV == 'debug' && console.log(`process ${this.id} scheduled to process ${nextFile}`); + this.send({ + file: nextFile + }); + } else { + if (this.isConnected()) { + this.kill(); + } + NODE_ENV == 'debug' && console.log(`process ${this.id} has terminated`); + if (!--workersActive) { + const t2 = Date.now(); + resolve({ + action: 'js', + count, + totalCount, + processingTime: t2 - t1 + }); + } + } + }); + + let nextFile = filesForProcessing.pop(); + NODE_ENV == 'debug' && console.log(`process ${worker.id} scheduled to process ${nextFile}`); + worker.send({ + file: nextFile + }); + } + }); +} + +module.exports = getJS; + +if (require.main === module) { + (async () => { + try { + const signatures = await getSignatures(); + onSuccess(await getJS(jsFiles, { ignore: ignoreMask }, signatures)); + onSuccess(await cleanUp(signatures)); + await writeSignatures(signatures); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/sass.js b/scripts/sass.js new file mode 100644 index 000000000..fbb02fba3 --- /dev/null +++ b/scripts/sass.js @@ -0,0 +1,73 @@ +'use strict'; + +const universalify = require('universalify'); +const sass = require('node-sass'); +const globby = require('globby'); +const path = require('path'); +const fs = require('fs-extra'); +const { getSignatures, writeSignatures, cleanUp, compareSignatures, getFileSignature, onSuccess, onError, onProgress, getPathRelativeTo } = require('./utils'); +const { ignoreMask } = require('./config'); +const sassRender = universalify.fromCallback(sass.render); + +const ROOT = path.resolve(__dirname, '..'); + +async function getSass(source, options, signatures) { + const t1 = Date.now(); + const files = await globby(source, Object.assign({ cwd: ROOT }, options )); + const totalCount = files.length; + var count = 0; + var f; + + while ((f = files.pop()) != null) { + let newFileSignature = await getFileSignature(f); + const dest = path.join.apply(this, ['build', 'chrome', 'skin', 'default', 'zotero', 'components', getPathRelativeTo(f, 'scss')]); + + if (f in signatures) { + if (compareSignatures(newFileSignature, signatures[f])) { + try { + await fs.access(dest, fs.constants.F_OK); + continue; + } catch (_) { + // file does not exists in build, fallback to browserifing + } + } + } + try { + const sass = await sassRender({ + file: f + }); + + await fs.outputFile(dest, sass); + onProgress(f, dest, 'sass'); + signatures[f] = newFileSignature; + count++; + } catch (err) { + throw new Error(`Failed on ${f}: ${err}`); + } + } + + const t2 = Date.now(); + return { + action: 'sass', + count, + totalCount, + processingTime: t2 - t1 + }; +} + +module.exports = getSass; + +if (require.main === module) { + (async () => { + try { + const signatures = await getSignatures(); + onSuccess(await getSass('scss/*.scss', { root: 'scss', ignore: ignoreMask }, signatures)); + onSuccess(await cleanUp(signatures)); + await writeSignatures(signatures); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/symlinks.js b/scripts/symlinks.js new file mode 100644 index 000000000..a0c2d158c --- /dev/null +++ b/scripts/symlinks.js @@ -0,0 +1,86 @@ +'use strict'; + +const path = require('path'); +const fs = require('fs-extra'); +const globby = require('globby'); + +const { isWindows, formatDirsForMatcher, getSignatures, writeSignatures, cleanUp, onSuccess, onError, onProgress } = require('./utils'); +const { dirs, symlinkDirs, copyDirs, symlinkFiles, ignoreMask } = require('./config'); +const ROOT = path.resolve(__dirname, '..'); + + +//@TODO: change signature to getSymlinks(source, options, signatures) +// here and elsewhere +// +// run symlinks twice, once for files (with nodir: true) +// once for dirs +async function getSymlinks(source, options, signatures) { + const t1 = Date.now(); + const files = await globby(source, Object.assign({ cwd: ROOT }, options )); + const filesDonePreviously = []; + for (const [f, signature] of Object.entries(signatures)) { + if ('isSymlinked' in signature && signature.isSymlinked) { + try { + await fs.access(path.join('build', f), fs.constants.F_OK); + // file found in signatures and build/ dir, skip + filesDonePreviously.push(f); + } catch (_) { + // file not found, needs symlinking + } + } + } + + const filesToProcess = files.filter(f => !filesDonePreviously.includes(f)); + const filesProcessedCount = filesToProcess.length; + + var f; + while ((f = filesToProcess.pop()) != null) { + const dest = path.join('build', f); + try { + if (isWindows) { + await fs.copy(f, dest); + } else { + await fs.ensureSymlink(f, dest); + } + signatures[f] = { + isSymlinked: true + }; + onProgress(f, dest, 'ln'); + } catch (err) { + throw new Error(`Failed on ${f}: ${err}`); + } + } + + const t2 = Date.now(); + + return { + action: 'symlink', + count: filesProcessedCount, + totalCount: files.length, + processingTime: t2 - t1 + }; +} + + +module.exports = getSymlinks; + +if (require.main === module) { + (async () => { + try { + const source = symlinkFiles + .concat(dirs.map(d => `${d}/**`)) + .concat([`!${formatDirsForMatcher(dirs)}/**/*.js`]) + .concat([`!${formatDirsForMatcher(copyDirs)}/**`]); + + const signatures = await getSignatures(); + onSuccess(await getSymlinks(source, { nodir: true, ignore: ignoreMask }, signatures)); + onSuccess(await getSymlinks(symlinkDirs, {}, signatures)); + onSuccess(await cleanUp(signatures)); + await writeSignatures(signatures); + } catch (err) { + process.exitCode = 1; + global.isError = true; + onError(err); + } + })(); +} \ No newline at end of file diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644 index 000000000..c2a884215 --- /dev/null +++ b/scripts/utils.js @@ -0,0 +1,126 @@ +const path = require('path'); +const fs = require('fs-extra'); +const colors = require('colors/safe'); +const green = colors.green; +const blue = colors.blue; +const yellow = colors.yellow; +const isWindows = /^win/.test(process.platform); + +const ROOT = path.resolve(__dirname, '..'); +const NODE_ENV = process.env.NODE_ENV; + + +function onError(err) { + console.log(colors.red('Error:'), err); +} + +function onSuccess(result) { + var msg = `${green('Success:')} ${blue(`[${result.action}]`)} ${result.count} files processed`; + if (result.totalCount) { + msg += ` (out of total ${result.totalCount} matched)`; + } + + msg += ` [${yellow(`${result.processingTime}ms`)}]`; + + console.log(msg); +} + +function onProgress(sourcefile, outfile, operation) { + if ('isError' in global && global.isError) { + return; + } + if (NODE_ENV == 'debug') { + console.log(`${colors.blue(`[${operation}]`)} ${sourcefile} -> ${outfile}`); + } else { + console.log(`${colors.blue(`[${operation}]`)} ${sourcefile}`); + } +} + +async function getSignatures() { + let signaturesFile = path.resolve(ROOT, '.signatures.json'); + var signatures = {}; + try { + signatures = await fs.readJson(signaturesFile); + } catch (_) { + // if signatures files doesn't exist, return empty object istead + } + return signatures; +} + +async function writeSignatures(signatures) { + let signaturesFile = path.resolve(ROOT, '.signatures.json'); + NODE_ENV == 'debug' && console.log('writing signatures to .signatures.json'); + await fs.outputJson(signaturesFile, signatures); +} + +async function cleanUp(signatures) { + const t1 = Date.now(); + var removedCount = 0, invalidCount = 0; + + for (let f of Object.keys(signatures)) { + try { + // check if file from signatures exists in source + await fs.access(f, fs.constants.F_OK); + } catch (_) { + invalidCount++; + NODE_ENV == 'debug' && console.log(`File ${f} found in signatures but not in src, deleting from build`); + try { + await fs.remove(path.join('build', f)); + removedCount++; + } catch (_) { + // file wasn't in the build either + } + delete signatures[f]; + } + } + + const t2 = Date.now(); + return { + action: 'cleanup', + count: removedCount, + totalCount: invalidCount, + processingTime: t2 - t1 + }; +} + +async function getFileSignature(file) { + let stats = await fs.stat(file); + return { + mode: stats.mode, + mtime: stats.mtimeMs || stats.mtime.getTime(), + isDirectory: stats.isDirectory(), + isFile: stats.isFile() + }; +} + +function compareSignatures(a, b) { + return typeof a === 'object' + && typeof b === 'object' + && a != null + && b != null + && ['mode', 'mtime', 'isDirectory', 'isFile'].reduce((acc, k) => { + return acc ? k in a && k in b && a[k] == b[k] : false; + }, true); +} + +function getPathRelativeTo(f, dirName) { + return path.relative(path.join(ROOT, dirName), path.join(ROOT, f)); +} + +const formatDirsForMatcher = dirs => { + return dirs.length > 1 ? `{${dirs.join(',')}}` : dirs[0]; +}; + +module.exports = { + isWindows, + onError, + onProgress, + onSuccess, + cleanUp, + getSignatures, + getFileSignature, + compareSignatures, + writeSignatures, + getPathRelativeTo, + formatDirsForMatcher +}; \ No newline at end of file diff --git a/scripts/watch.js b/scripts/watch.js new file mode 100644 index 000000000..17e0a3f9d --- /dev/null +++ b/scripts/watch.js @@ -0,0 +1,81 @@ +const path = require('path'); +const chokidar = require('chokidar'); +const multimatch = require('multimatch'); +const { dirs, jsGlob, jsGlobIgnore, copyDirs, symlinkFiles } = require('./config'); +const { onSuccess, onError, getSignatures, writeSignatures, cleanUp, formatDirsForMatcher } = require('./utils'); +const getJS = require('./js'); +const getSass = require('./sass'); +const getCopy = require('./copy'); +const getSymlinks = require('./symlinks'); + + +const ROOT = path.resolve(__dirname, '..'); +const source = [ + 'chrome', + 'components', + 'defaults', + 'resource', + 'scss', + 'test', + 'styles', + 'translators', + 'scss', + 'chrome/**', + 'components/**', + 'defaults/**', + 'resource/**', + 'scss/**', + 'test/**', + 'styles/**', + 'translators/**', + 'scss/**' +]; + +const symlinks = symlinkFiles + .concat(dirs.map(d => `${d}/**`)) + .concat([`!${formatDirsForMatcher(dirs)}/**/*.js`]) + .concat([`!${formatDirsForMatcher(copyDirs)}/**`]); + +var signatures; + +process.on('SIGINT', () => { + writeSignatures(signatures); + process.exit(); +}); + +function getWatch() { + let watcher = chokidar.watch(source, { cwd: ROOT }) + .on('change', async (path) => { + try { + if (multimatch(path, jsGlob).length && !multimatch(path, jsGlobIgnore).length) { + onSuccess(await getJS(path, { ignore: jsGlobIgnore }, signatures)); + } else if (multimatch(path, 'scss/*.scss').length) { + onSuccess(await getSass(path, {}, signatures)); + } else if (multimatch(path, copyDirs.map(d => `${d}/**`)).length) { + onSuccess(await getCopy(path, {}, signatures)); + } else if (multimatch(path, symlinks).length) { + onSuccess(await getSymlinks(path, { nodir: true }, signatures)); + } + onSuccess(await cleanUp(signatures)); + } catch (err) { + onError(err); + } + + }) + .on('unlink', async () => { + const signatures = await getSignatures(); + onSuccess(await cleanUp(signatures)); + }); + + watcher.add(source); + console.log('Watching files for changes...'); +} + +module.exports = getWatch; + +if (require.main === module) { + (async () => { + signatures = await getSignatures(); + getWatch(); + })(); +} \ No newline at end of file