diff --git a/.travis.yml b/.travis.yml index 3262fcc22a..9b6a3feefb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,18 +16,18 @@ before_script: - npm run test:build - cp config.json.example config.json - if [ $REQUIRES_SERVER ]; then until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done; export DISPLAY=:99; fi -after_script: - - ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js -script: npm run $TEST +script: + - npm run $TEST + - if [ $COVERAGE ]; then ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js; fi env: global: - CXX=g++-4.8 - DISABLE_REQUEST_LOGGING=true matrix: - TEST="lint" - - TEST="test:api-v3" REQUIRES_SERVER=true + - TEST="test:api-v3" REQUIRES_SERVER=true COVERAGE=true - TEST="test:sanity" - - TEST="test:content" - - TEST="test:common" - - TEST="test:karma" - - TEST="client:unit" + - TEST="test:content" COVERAGE=true + - TEST="test:common" COVERAGE=true + - TEST="test:karma" COVERAGE=true + - TEST="client:unit" COVERAGE=true diff --git a/gulp/gulp-tests.js b/gulp/gulp-tests.js index cbc3d8f3e5..e8fd82b203 100644 --- a/gulp/gulp-tests.js +++ b/gulp/gulp-tests.js @@ -280,7 +280,7 @@ gulp.task('test:e2e:safe', ['test:prepare', 'test:prepare:server'], (cb) => { gulp.task('test:api-v3:unit', (done) => { let runner = exec( - testBin('mocha test/api/v3/unit --recursive --require ./test/helpers/start-server'), + testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-unit --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/unit --recursive --require ./test/helpers/start-server'), (err, stdout, stderr) => { if (err) { process.exit(1); @@ -298,7 +298,7 @@ gulp.task('test:api-v3:unit:watch', () => { gulp.task('test:api-v3:integration', (done) => { let runner = exec( - testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server'), + testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'), {maxBuffer: 500 * 1024}, (err, stdout, stderr) => { if (err) { diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 85fbd96d7d..74a2f49fe7 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -8,9 +8,9 @@ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz" }, "@slack/client": { - "version": "3.8.1", + "version": "3.9.0", "from": "@slack/client@>=3.8.1 <4.0.0", - "resolved": "https://registry.npmjs.org/@slack/client/-/client-3.8.1.tgz" + "resolved": "https://registry.npmjs.org/@slack/client/-/client-3.9.0.tgz" }, "abbrev": { "version": "1.1.0", @@ -81,9 +81,9 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz" }, "ajv": { - "version": "4.11.4", + "version": "4.11.5", "from": "ajv@>=4.9.1 <5.0.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.4.tgz" + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.5.tgz" }, "ajv-keywords": { "version": "1.5.1", @@ -187,9 +187,9 @@ "optional": true }, "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@~1.4.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" }, "oauth-sign": { "version": "0.3.0", @@ -312,6 +312,12 @@ "from": "apn@>=1.7.6 <2.0.0", "resolved": "https://registry.npmjs.org/apn/-/apn-1.7.8.tgz" }, + "append-transform": { + "version": "0.4.0", + "from": "append-transform@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "dev": true + }, "aproba": { "version": "1.1.1", "from": "aproba@>=1.0.3 <2.0.0", @@ -447,9 +453,9 @@ "dev": true }, "ast-types": { - "version": "0.9.5", + "version": "0.9.10", "from": "ast-types@>=0.0.0 <1.0.0", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.5.tgz", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.10.tgz", "dev": true }, "astw": { @@ -494,9 +500,9 @@ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz" }, "aws-sdk": { - "version": "2.34.0", + "version": "2.35.0", "from": "aws-sdk@>=2.0.25 <3.0.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.34.0.tgz", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.35.0.tgz", "dependencies": { "lodash": { "version": "3.5.0", @@ -546,14 +552,14 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz" }, "babel-core": { - "version": "6.23.1", + "version": "6.24.0", "from": "babel-core@>=6.0.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.23.1.tgz" + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.0.tgz" }, "babel-generator": { - "version": "6.23.0", - "from": "babel-generator@>=6.23.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.23.0.tgz" + "version": "6.24.0", + "from": "babel-generator@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.0.tgz" }, "babel-helper-call-delegate": { "version": "6.22.0", @@ -606,9 +612,9 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.23.0.tgz" }, "babel-loader": { - "version": "6.4.0", + "version": "6.4.1", "from": "babel-loader@>=6.0.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.0.tgz" + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz" }, "babel-messages": { "version": "6.23.0", @@ -621,9 +627,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz" }, "babel-plugin-istanbul": { - "version": "4.0.0", + "version": "4.1.1", "from": "babel-plugin-istanbul@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.1.tgz", "dev": true, "dependencies": { "find-up": { @@ -700,14 +706,14 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz" }, "babel-plugin-transform-es2015-modules-amd": { - "version": "6.22.0", - "from": "babel-plugin-transform-es2015-modules-amd@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.22.0.tgz" + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-amd@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz" }, "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.23.0", - "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.23.0.tgz" + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz" }, "babel-plugin-transform-es2015-modules-systemjs": { "version": "6.23.0", @@ -715,9 +721,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz" }, "babel-plugin-transform-es2015-modules-umd": { - "version": "6.23.0", - "from": "babel-plugin-transform-es2015-modules-umd@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.23.0.tgz" + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-umd@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz" }, "babel-plugin-transform-es2015-object-super": { "version": "6.22.0", @@ -780,14 +786,14 @@ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz" }, "babel-preset-es2015": { - "version": "6.22.0", + "version": "6.24.0", "from": "babel-preset-es2015@>=6.6.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.22.0.tgz" + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz" }, "babel-register": { - "version": "6.23.0", + "version": "6.24.0", "from": "babel-register@>=6.6.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.23.0.tgz" + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.0.tgz" }, "babel-runtime": { "version": "6.23.0", @@ -854,7 +860,7 @@ }, "basic-auth": { "version": "1.1.0", - "from": "basic-auth@>=1.1.0 <1.2.0", + "from": "basic-auth@>=1.0.4 <2.0.0", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz" }, "bcrypt": { @@ -1152,9 +1158,9 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz" }, "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@~1.4.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" }, "oauth-sign": { "version": "0.4.0", @@ -1382,9 +1388,9 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" }, "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@~1.4.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" }, "oauth-sign": { "version": "0.5.0", @@ -1456,6 +1462,11 @@ } } }, + "browser-stdout": { + "version": "1.3.0", + "from": "browser-stdout@1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz" + }, "browserify": { "version": "12.0.2", "from": "browserify@>=12.0.1 <12.1.0", @@ -1538,9 +1549,9 @@ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz" }, "browserslist": { - "version": "1.7.6", + "version": "1.7.7", "from": "browserslist@>=1.7.6 <2.0.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.6.tgz" + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz" }, "bson": { "version": "1.0.4", @@ -1830,9 +1841,9 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz" }, "chromedriver": { - "version": "2.27.3", + "version": "2.28.0", "from": "chromedriver@>=2.27.2 <3.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.27.3.tgz", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.28.0.tgz", "dev": true }, "cipher-base": { @@ -1847,9 +1858,9 @@ "dev": true }, "clap": { - "version": "1.1.2", + "version": "1.1.3", "from": "clap@>=1.0.9 <2.0.0", - "resolved": "https://registry.npmjs.org/clap/-/clap-1.1.2.tgz" + "resolved": "https://registry.npmjs.org/clap/-/clap-1.1.3.tgz" }, "clean-css": { "version": "2.2.23", @@ -1942,9 +1953,9 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz" }, "color-name": { - "version": "1.1.1", + "version": "1.1.2", "from": "color-name@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz" }, "color-string": { "version": "0.3.0", @@ -2000,6 +2011,12 @@ "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", "dev": true, "dependencies": { + "ast-types": { + "version": "0.9.6", + "from": "ast-types@0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "dev": true + }, "esprima": { "version": "3.1.3", "from": "esprima@>=3.1.0 <3.2.0", @@ -2013,9 +2030,9 @@ "dev": true }, "recast": { - "version": "0.11.22", + "version": "0.11.23", "from": "recast@>=0.11.17 <0.12.0", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.22.tgz", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", "dev": true } } @@ -2038,9 +2055,9 @@ "dev": true }, "compressible": { - "version": "2.0.9", + "version": "2.0.10", "from": "compressible@>=2.0.8 <2.1.0", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.9.tgz" + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.10.tgz" }, "compression": { "version": "1.6.2", @@ -2267,9 +2284,9 @@ "resolved": "https://registry.npmjs.org/coupon-code/-/coupon-code-0.4.5.tgz" }, "coveralls": { - "version": "2.12.0", + "version": "2.13.0", "from": "coveralls@>=2.11.2 <3.0.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.12.0.tgz", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.0.tgz", "dev": true, "dependencies": { "esprima": { @@ -2331,9 +2348,9 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.4.tgz" }, "cross-env": { - "version": "3.2.3", + "version": "3.2.4", "from": "cross-env@>=3.1.4 <4.0.0", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-3.2.3.tgz", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-3.2.4.tgz", "dev": true, "dependencies": { "is-windows": { @@ -2357,9 +2374,9 @@ "dev": true }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.2.9 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "dev": true } } @@ -2397,9 +2414,9 @@ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.26.4.tgz", "dependencies": { "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" } } }, @@ -2483,14 +2500,14 @@ "resolved": "https://registry.npmjs.org/cwait/-/cwait-1.0.1.tgz" }, "cwise": { - "version": "1.0.9", - "from": "cwise@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/cwise/-/cwise-1.0.9.tgz", + "version": "1.0.10", + "from": "cwise@>=1.0.10 <2.0.0", + "resolved": "https://registry.npmjs.org/cwise/-/cwise-1.0.10.tgz", "dependencies": { "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.6.0 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz" + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz" } } }, @@ -2552,9 +2569,9 @@ "resolved": "https://registry.npmjs.org/deap/-/deap-1.0.0.tgz" }, "debug": { - "version": "2.6.2", + "version": "2.6.3", "from": "debug@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.2.tgz" + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.3.tgz" }, "debug-fabulous": { "version": "0.0.4", @@ -2854,6 +2871,12 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "dev": true }, + "default-require-extensions": { + "version": "1.0.0", + "from": "default-require-extensions@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "dev": true + }, "defaults": { "version": "1.0.3", "from": "defaults@>=1.0.0 <2.0.0", @@ -2994,8 +3017,7 @@ "diff": { "version": "1.4.0", "from": "diff@1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz" }, "diffie-hellman": { "version": "5.0.2", @@ -3003,9 +3025,9 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz" }, "doctrine": { - "version": "1.5.0", - "from": "doctrine@>=1.2.2 <2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "version": "2.0.0", + "from": "doctrine@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", "dev": true }, "doctypes": { @@ -3183,9 +3205,9 @@ "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz" }, "easydate": { - "version": "2.1.0", + "version": "2.2.1", "from": "easydate@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/easydate/-/easydate-2.1.0.tgz" + "resolved": "https://registry.npmjs.org/easydate/-/easydate-2.2.1.tgz" }, "ecc-jsbn": { "version": "0.1.1", @@ -3211,9 +3233,9 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" }, "ejs": { - "version": "0.8.8", - "from": "ejs@>=0.8.3 <0.9.0", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-0.8.8.tgz", + "version": "0.8.3", + "from": "ejs@0.8.3", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-0.8.3.tgz", "dev": true }, "electron-to-chromium": { @@ -3327,20 +3349,35 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz" }, "es5-ext": { - "version": "0.10.12", + "version": "0.10.15", "from": "es5-ext@>=0.10.6 <0.11.0", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.12.tgz" + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.15.tgz" }, "es6-iterator": { - "version": "2.0.0", + "version": "2.0.1", "from": "es6-iterator@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz" + } + } }, "es6-map": { - "version": "0.1.4", + "version": "0.1.5", "from": "es6-map@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.4.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "dev": true, + "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "dev": true + } + } }, "es6-promise": { "version": "3.3.1", @@ -3348,15 +3385,30 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz" }, "es6-set": { - "version": "0.1.4", - "from": "es6-set@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.4.tgz", - "dev": true + "version": "0.1.5", + "from": "es6-set@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "dev": true, + "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "dev": true + } + } }, "es6-symbol": { - "version": "3.1.0", + "version": "3.1.1", "from": "es6-symbol@>=3.1.0 <3.2.0", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz" + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz" + } + } }, "es6-weak-map": { "version": "0.1.4", @@ -3419,18 +3471,24 @@ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", "dev": true, "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "dev": true + }, "es6-weak-map": { - "version": "2.0.1", + "version": "2.0.2", "from": "es6-weak-map@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "dev": true } } }, "eslint": { - "version": "3.17.1", + "version": "3.18.0", "from": "eslint@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.17.1.tgz", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.18.0.tgz", "dev": true, "dependencies": { "cli-cursor": { @@ -3504,15 +3562,15 @@ } }, "eslint-loader": { - "version": "1.6.3", + "version": "1.7.1", "from": "eslint-loader@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.7.1.tgz", "dev": true, "dependencies": { "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "dev": true } } @@ -3538,16 +3596,16 @@ } }, "eslint-plugin-lodash": { - "version": "2.3.5", + "version": "2.4.0", "from": "eslint-plugin-lodash@>=2.3.5 <3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-2.3.5.tgz", + "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-2.4.0.tgz", "dev": true, "optional": true }, "eslint-plugin-mocha": { - "version": "4.8.0", + "version": "4.9.0", "from": "eslint-plugin-mocha@>=4.7.0 <5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.8.0.tgz", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.9.0.tgz", "dev": true }, "espree": { @@ -3569,6 +3627,12 @@ "from": "esprima@>=1.0.4 <1.1.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" }, + "esquery": { + "version": "1.0.0", + "from": "esquery@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "dev": true + }, "esrecurse": { "version": "4.1.0", "from": "esrecurse@>=4.1.0 <5.0.0", @@ -3599,9 +3663,16 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz" }, "event-emitter": { - "version": "0.3.4", + "version": "0.3.5", "from": "event-emitter@>=0.3.4 <0.4.0", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz" + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "dependencies": { + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz" + } + } }, "event-stream": { "version": "3.3.4", @@ -3791,14 +3862,14 @@ "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.0.tgz", "dependencies": { "async": { - "version": "2.1.5", + "version": "2.2.0", "from": "async@>=2.1.2 <3.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz" + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz" }, "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" } } }, @@ -3899,9 +3970,9 @@ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.10.1.tgz", "dependencies": { "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" } } }, @@ -3917,9 +3988,9 @@ "dev": true }, "file-url": { - "version": "1.1.0", - "from": "file-url@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/file-url/-/file-url-1.1.0.tgz" + "version": "2.0.2", + "from": "file-url@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/file-url/-/file-url-2.0.2.tgz" }, "filename-regex": { "version": "2.0.0", @@ -3942,21 +4013,15 @@ "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz" }, "fileset": { - "version": "0.2.1", - "from": "fileset@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz", + "version": "2.0.3", + "from": "fileset@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", "dev": true, "dependencies": { "glob": { - "version": "5.0.15", - "from": "glob@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "dev": true - }, - "minimatch": { - "version": "2.0.10", - "from": "minimatch@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "version": "7.1.1", + "from": "glob@>=7.0.3 <8.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "dev": true } } @@ -4089,9 +4154,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", "dependencies": { "async": { - "version": "2.1.5", + "version": "2.2.0", "from": "async@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz" + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz" } } }, @@ -4117,9 +4182,9 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz" }, "from": { - "version": "0.1.3", + "version": "0.1.7", "from": "from@>=0.0.0 <1.0.0", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.3.tgz" + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz" }, "fs-exists-sync": { "version": "0.1.0", @@ -4342,16 +4407,16 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", "dependencies": { "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.2.12 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz" + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" } } }, "globals": { - "version": "9.16.0", + "version": "9.17.0", "from": "globals@>=9.0.0 <10.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.16.0.tgz" + "resolved": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz" }, "globby": { "version": "6.1.0", @@ -4420,8 +4485,7 @@ "growl": { "version": "1.9.2", "from": "growl@1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz" }, "grunt": { "version": "0.4.5", @@ -4757,9 +4821,9 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz" }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.4.0 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz" + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz" } } }, @@ -5006,9 +5070,9 @@ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz" }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.2.1 <1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz" + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" } } }, @@ -5371,14 +5435,14 @@ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz" }, "hooks-fixed": { - "version": "1.2.0", - "from": "hooks-fixed@1.2.0", - "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-1.2.0.tgz" + "version": "2.0.0", + "from": "hooks-fixed@2.0.0", + "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.0.tgz" }, "hosted-git-info": { - "version": "2.2.0", + "version": "2.4.1", "from": "hosted-git-info@>=2.1.4 <3.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.2.0.tgz" + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.1.tgz" }, "html-comment-regex": { "version": "1.1.1", @@ -5392,19 +5456,19 @@ "dev": true }, "html-minifier": { - "version": "3.4.0", + "version": "3.4.2", "from": "html-minifier@>=3.2.3 <4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.4.0.tgz", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.4.2.tgz", "dependencies": { "clean-css": { - "version": "4.0.8", + "version": "4.0.10", "from": "clean-css@>=4.0.0 <4.1.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.0.8.tgz" + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.0.10.tgz" }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.8.0 <2.9.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz" + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz" } } }, @@ -5535,9 +5599,9 @@ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz" }, "ignore": { - "version": "3.2.4", + "version": "3.2.6", "from": "ignore@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.4.tgz", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.6.tgz", "dev": true }, "ignore-by-default": { @@ -5738,24 +5802,24 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" }, "in-app-purchase": { - "version": "1.2.0", + "version": "1.3.0", "from": "in-app-purchase@>=1.1.6 <2.0.0", - "resolved": "https://registry.npmjs.org/in-app-purchase/-/in-app-purchase-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/in-app-purchase/-/in-app-purchase-1.3.0.tgz", "dependencies": { "form-data": { - "version": "2.0.0", - "from": "form-data@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz" + "version": "2.1.2", + "from": "form-data@>=2.1.1 <2.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" }, - "node-uuid": { - "version": "1.4.7", - "from": "node-uuid@~1.4.7", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "qs": { + "version": "6.3.2", + "from": "qs@>=6.3.0 <6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz" }, "request": { - "version": "2.75.0", - "from": "request@2.75.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz" + "version": "2.79.0", + "from": "request@2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz" } } }, @@ -5800,9 +5864,9 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" }, "inject-loader": { - "version": "3.0.0-beta4", + "version": "3.0.0", "from": "inject-loader@>=3.0.0-beta4 <4.0.0", - "resolved": "https://registry.npmjs.org/inject-loader/-/inject-loader-3.0.0-beta4.tgz", + "resolved": "https://registry.npmjs.org/inject-loader/-/inject-loader-3.0.0.tgz", "dev": true }, "inline-source-map": { @@ -5956,9 +6020,9 @@ "optional": true }, "ipaddr.js": { - "version": "1.2.0", - "from": "ipaddr.js@1.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz" + "version": "1.3.0", + "from": "ipaddr.js@1.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.3.0.tgz" }, "irregular-plurals": { "version": "1.2.0", @@ -6236,9 +6300,9 @@ "dev": true }, "isexe": { - "version": "1.1.2", - "from": "isexe@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz" + "version": "2.0.0", + "from": "isexe@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" }, "isobject": { "version": "2.1.0", @@ -6251,9 +6315,9 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" }, "istanbul": { - "version": "0.3.22", - "from": "istanbul@>=0.3.14 <0.4.0", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.3.22.tgz", + "version": "1.1.0-alpha.1", + "from": "istanbul@>=1.1.0-alpha.1 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-1.1.0-alpha.1.tgz", "dev": true, "dependencies": { "abbrev": { @@ -6364,9 +6428,9 @@ } }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "dev": true }, "wordwrap": { @@ -6377,16 +6441,36 @@ } } }, + "istanbul-api": { + "version": "1.1.7", + "from": "istanbul-api@>=1.1.0-alpha <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.7.tgz", + "dev": true, + "dependencies": { + "async": { + "version": "2.2.0", + "from": "async@>=2.1.4 <3.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz", + "dev": true + } + } + }, "istanbul-lib-coverage": { - "version": "1.0.1", - "from": "istanbul-lib-coverage@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.1.tgz", + "version": "1.0.2", + "from": "istanbul-lib-coverage@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.2.tgz", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.0.5", + "from": "istanbul-lib-hook@>=1.0.5 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.5.tgz", "dev": true }, "istanbul-lib-instrument": { - "version": "1.4.2", - "from": "istanbul-lib-instrument@>=1.4.2 <2.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.4.2.tgz", + "version": "1.7.0", + "from": "istanbul-lib-instrument@>=1.6.2 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.0.tgz", "dev": true, "dependencies": { "semver": { @@ -6397,6 +6481,62 @@ } } }, + "istanbul-lib-report": { + "version": "1.0.0", + "from": "istanbul-lib-report@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.0.0.tgz", + "dev": true, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "from": "supports-color@>=3.1.2 <4.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "dev": true + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.1.1", + "from": "istanbul-lib-source-maps@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.1.1.tgz", + "dev": true + }, + "istanbul-reports": { + "version": "1.0.2", + "from": "istanbul-reports@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.0.2.tgz", + "dev": true, + "dependencies": { + "handlebars": { + "version": "4.0.6", + "from": "handlebars@>=4.0.3 <5.0.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.6.tgz", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "from": "source-map@>=0.4.4 <0.5.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "dev": true + }, + "uglify-js": { + "version": "2.8.20", + "from": "uglify-js@>=2.6.0 <3.0.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", + "dev": true, + "optional": true, + "dependencies": { + "source-map": { + "version": "0.5.6", + "from": "source-map@~0.5.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "dev": true, + "optional": true + } + } + } + } + }, "jade": { "version": "1.11.0", "from": "jade@>=1.11.0 <1.12.0", @@ -6425,9 +6565,9 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.4.19 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", "dependencies": { "source-map": { "version": "0.5.6", @@ -6493,9 +6633,9 @@ "optional": true }, "jquery": { - "version": "3.1.1", + "version": "3.2.1", "from": "jquery@>=3.1.1 <4.0.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.1.1.tgz" + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz" }, "js-base64": { "version": "2.1.9", @@ -6503,9 +6643,9 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz" }, "js-beautify": { - "version": "1.6.11", + "version": "1.6.12", "from": "js-beautify@>=1.6.3 <2.0.0", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.6.11.tgz" + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.6.12.tgz" }, "js-stringify": { "version": "1.0.2", @@ -6573,8 +6713,7 @@ "json3": { "version": "3.3.2", "from": "json3@3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz" }, "json5": { "version": "0.5.1", @@ -6607,9 +6746,16 @@ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz" }, "jsprim": { - "version": "1.3.1", + "version": "1.4.0", "from": "jsprim@>=1.2.2 <2.0.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz" + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } }, "jstransformer": { "version": "0.0.2", @@ -6699,6 +6845,12 @@ "from": "sinon@1.17.2", "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.2.tgz", "dev": true + }, + "sinon-chai": { + "version": "2.8.0", + "from": "sinon-chai@2.8.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.8.0.tgz", + "dev": true } } }, @@ -6786,16 +6938,16 @@ "dev": true }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.6.0 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", "dev": true, "optional": true }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "dev": true }, "wordwrap": { @@ -6865,9 +7017,9 @@ } }, "karma-webpack": { - "version": "2.0.2", + "version": "2.0.3", "from": "karma-webpack@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.3.tgz", "dev": true, "dependencies": { "async": { @@ -7105,6 +7257,12 @@ "from": "load-json-file@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" }, + "loader-fs-cache": { + "version": "1.0.1", + "from": "loader-fs-cache@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", + "dev": true + }, "loader-runner": { "version": "2.3.0", "from": "loader-runner@>=2.3.0 <3.0.0", @@ -7170,8 +7328,7 @@ "lodash._basecreate": { "version": "3.0.3", "from": "lodash._basecreate@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz" }, "lodash._basefor": { "version": "3.0.3", @@ -7271,6 +7428,12 @@ "from": "lodash._shimkeys@>=2.4.1 <2.5.0", "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz" }, + "lodash._stack": { + "version": "4.1.3", + "from": "lodash._stack@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash._stack/-/lodash._stack-4.1.3.tgz", + "dev": true + }, "lodash.assign": { "version": "3.2.0", "from": "lodash.assign@>=3.0.0 <4.0.0", @@ -7288,7 +7451,7 @@ }, "lodash.clone": { "version": "3.0.3", - "from": "lodash.clone@>=3.0.3 <4.0.0", + "from": "lodash.clone@3.0.3", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz", "dev": true }, @@ -7299,9 +7462,8 @@ }, "lodash.create": { "version": "3.1.1", - "from": "lodash.create@>=3.1.1 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "dev": true + "from": "lodash.create@3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz" }, "lodash.debounce": { "version": "2.4.1", @@ -7314,10 +7476,18 @@ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz" }, "lodash.defaultsdeep": { - "version": "4.6.0", - "from": "lodash.defaultsdeep@>=4.3.2 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz", - "dev": true + "version": "4.3.2", + "from": "lodash.defaultsdeep@4.3.2", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.3.2.tgz", + "dev": true, + "dependencies": { + "lodash._baseclone": { + "version": "4.5.7", + "from": "lodash._baseclone@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-4.5.7.tgz", + "dev": true + } + } }, "lodash.escape": { "version": "3.2.0", @@ -7374,6 +7544,12 @@ "from": "lodash.keys@>=3.0.0 <4.0.0", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" }, + "lodash.keysin": { + "version": "4.2.0", + "from": "lodash.keysin@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-4.2.0.tgz", + "dev": true + }, "lodash.mapvalues": { "version": "4.6.0", "from": "lodash.mapvalues@>=4.4.0 <5.0.0", @@ -7399,6 +7575,12 @@ "from": "lodash.pick@>=4.2.1 <5.0.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" }, + "lodash.rest": { + "version": "4.0.5", + "from": "lodash.rest@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.5.tgz", + "dev": true + }, "lodash.restparam": { "version": "3.6.1", "from": "lodash.restparam@>=3.0.0 <4.0.0", @@ -7419,11 +7601,6 @@ "from": "lodash.templatesettings@>=3.0.0 <4.0.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz" }, - "lodash.throttle": { - "version": "4.1.1", - "from": "lodash.throttle@>=4.1.1 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz" - }, "lodash.uniq": { "version": "4.5.0", "from": "lodash.uniq@>=4.3.0 <5.0.0", @@ -7672,16 +7849,9 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz" }, "method-override": { - "version": "2.3.7", + "version": "2.3.8", "from": "method-override@>=2.3.5 <3.0.0", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.7.tgz", - "dependencies": { - "debug": { - "version": "2.3.3", - "from": "debug@2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz" - } - } + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.8.tgz" }, "methods": { "version": "1.1.2", @@ -7704,14 +7874,14 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" }, "mime-db": { - "version": "1.26.0", - "from": "mime-db@>=1.26.0 <1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz" + "version": "1.27.0", + "from": "mime-db@>=1.27.0 <1.28.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz" }, "mime-types": { - "version": "2.1.14", + "version": "2.1.15", "from": "mime-types@>=2.1.7 <2.2.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz" + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz" }, "mimic-fn": { "version": "1.1.0", @@ -7761,147 +7931,48 @@ "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" }, "mocha": { - "version": "2.5.3", - "from": "mocha@>=2.3.3 <3.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "dev": true, + "version": "3.2.0", + "from": "mocha@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.2.0.tgz", "dependencies": { - "commander": { - "version": "2.3.0", - "from": "commander@2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "dev": true - }, "debug": { "version": "2.2.0", "from": "debug@2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.2", - "from": "escape-string-regexp@1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" }, "glob": { - "version": "3.2.11", - "from": "glob@3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "dev": true - }, - "jade": { - "version": "0.26.3", - "from": "jade@0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "dev": true, - "dependencies": { - "commander": { - "version": "0.6.1", - "from": "commander@0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "from": "mkdirp@0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "dev": true - } - } - }, - "minimatch": { - "version": "0.3.0", - "from": "minimatch@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "dev": true + "version": "7.0.5", + "from": "glob@7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz" }, "ms": { "version": "0.7.1", "from": "ms@0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" }, "supports-color": { - "version": "1.2.0", - "from": "supports-color@1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "dev": true + "version": "3.1.2", + "from": "supports-color@3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz" } } }, "mocha-nightwatch": { - "version": "2.2.9", - "from": "mocha-nightwatch@2.2.9", - "resolved": "https://registry.npmjs.org/mocha-nightwatch/-/mocha-nightwatch-2.2.9.tgz", + "version": "3.2.1", + "from": "mocha-nightwatch@3.2.1", + "resolved": "https://registry.npmjs.org/mocha-nightwatch/-/mocha-nightwatch-3.2.1.tgz", "dev": true, "dependencies": { - "commander": { - "version": "2.3.0", - "from": "commander@2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "dev": true - }, "debug": { "version": "2.2.0", "from": "debug@2.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "dev": true }, - "escape-string-regexp": { - "version": "1.0.2", - "from": "escape-string-regexp@1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "dev": true - }, "glob": { - "version": "3.2.3", - "from": "glob@3.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz", - "dev": true - }, - "graceful-fs": { - "version": "2.0.3", - "from": "graceful-fs@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", - "dev": true - }, - "growl": { - "version": "1.8.1", - "from": "growl@1.8.1", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.8.1.tgz", - "dev": true - }, - "jade": { - "version": "0.26.3", - "from": "jade@0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "dev": true, - "dependencies": { - "commander": { - "version": "0.6.1", - "from": "commander@0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "from": "mkdirp@0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "dev": true - } - } - }, - "minimatch": { - "version": "0.2.14", - "from": "minimatch@>=0.2.11 <0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "dev": true - }, - "mkdirp": { - "version": "0.5.0", - "from": "mkdirp@0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "version": "7.0.5", + "from": "glob@7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", "dev": true }, "ms": { @@ -7911,9 +7982,9 @@ "dev": true }, "supports-color": { - "version": "1.2.0", - "from": "supports-color@1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "version": "3.1.2", + "from": "supports-color@3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", "dev": true } } @@ -7929,9 +8000,9 @@ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz" }, "moment": { - "version": "2.17.1", + "version": "2.18.1", "from": "moment@>=2.13.0 <3.0.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.17.1.tgz" + "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz" }, "moment-recur": { "version": "1.0.6", @@ -7939,9 +8010,9 @@ "resolved": "git://github.com/habitrpg/moment-recur.git#f147ef27bbc26ca67638385f3db4a44084c76626" }, "mongodb": { - "version": "2.2.24", - "from": "mongodb@2.2.24", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.24.tgz", + "version": "2.2.25", + "from": "mongodb@2.2.25", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.25.tgz", "dependencies": { "es6-promise": { "version": "3.2.1", @@ -7956,14 +8027,14 @@ } }, "mongodb-core": { - "version": "2.1.8", - "from": "mongodb-core@2.1.8", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.8.tgz" + "version": "2.1.9", + "from": "mongodb-core@2.1.9", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.9.tgz" }, "mongoose": { - "version": "4.8.6", + "version": "4.9.2", "from": "mongoose@>=4.8.6 <5.0.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.8.6.tgz", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.9.2.tgz", "dependencies": { "async": { "version": "2.1.4", @@ -8022,9 +8093,9 @@ "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz" }, "mquery": { - "version": "2.2.3", - "from": "mquery@2.2.3", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.2.3.tgz", + "version": "2.3.0", + "from": "mquery@2.3.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.0.tgz", "dependencies": { "bluebird": { "version": "2.10.2", @@ -8134,9 +8205,9 @@ "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.18.tgz" }, "ndarray-fill": { - "version": "1.0.1", + "version": "1.0.2", "from": "ndarray-fill@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/ndarray-fill/-/ndarray-fill-1.0.1.tgz" + "resolved": "https://registry.npmjs.org/ndarray-fill/-/ndarray-fill-1.0.2.tgz" }, "ndarray-pack": { "version": "1.2.1", @@ -8212,15 +8283,21 @@ } }, "nightwatch": { - "version": "0.9.12", + "version": "0.9.14", "from": "nightwatch@>=0.9.12 <0.10.0", - "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-0.9.12.tgz", + "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-0.9.14.tgz", "dev": true, "dependencies": { - "minimatch": { - "version": "0.2.14", - "from": "minimatch@>=0.2.14 <0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "mkpath": { + "version": "1.0.0", + "from": "mkpath@1.0.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", + "dev": true + }, + "q": { + "version": "1.4.1", + "from": "q@1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", "dev": true } } @@ -8241,31 +8318,66 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.49.tgz" }, "node-gcm": { - "version": "0.14.4", + "version": "0.14.5", "from": "node-gcm@>=0.14.4 <0.15.0", - "resolved": "https://registry.npmjs.org/node-gcm/-/node-gcm-0.14.4.tgz", + "resolved": "https://registry.npmjs.org/node-gcm/-/node-gcm-0.14.5.tgz", "dependencies": { + "caseless": { + "version": "0.12.0", + "from": "caseless@>=0.12.0 <0.13.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + }, "debug": { "version": "0.8.1", "from": "debug@>=0.8.1 <0.9.0", "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz" }, + "form-data": { + "version": "2.1.2", + "from": "form-data@>=2.1.1 <2.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" + }, + "har-validator": { + "version": "4.2.1", + "from": "har-validator@>=4.2.1 <4.3.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz" + }, "lodash": { "version": "3.10.1", "from": "lodash@>=3.10.1 <4.0.0", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "qs": { + "version": "6.4.0", + "from": "qs@>=6.4.0 <6.5.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz" + }, + "request": { + "version": "2.81.0", + "from": "request@>=2.81.0 <3.0.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz" + }, + "tunnel-agent": { + "version": "0.6.0", + "from": "tunnel-agent@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" } } }, "node-gyp": { - "version": "3.5.0", + "version": "3.6.0", "from": "node-gyp@>=3.3.1 <4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.5.0.tgz", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.0.tgz", "dependencies": { "glob": { "version": "7.1.1", "from": "glob@>=7.0.3 <8.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz" + }, + "semver": { + "version": "5.3.0", + "from": "semver@>=5.3.0 <5.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" } } }, @@ -8360,11 +8472,21 @@ "from": "node-sass@>=4.5.0 <5.0.0", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.2.tgz", "dependencies": { + "caseless": { + "version": "0.12.0", + "from": "caseless@>=0.12.0 <0.13.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + }, "cross-spawn": { "version": "3.0.1", "from": "cross-spawn@>=3.0.0 <4.0.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz" }, + "form-data": { + "version": "2.1.2", + "from": "form-data@>=2.1.1 <2.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" + }, "gaze": { "version": "1.1.2", "from": "gaze@>=1.0.0 <2.0.0", @@ -8380,6 +8502,11 @@ "from": "globule@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/globule/-/globule-1.1.0.tgz" }, + "har-validator": { + "version": "4.2.1", + "from": "har-validator@>=4.2.1 <4.3.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz" + }, "lodash": { "version": "4.16.6", "from": "lodash@>=4.16.4 <4.17.0", @@ -8395,10 +8522,25 @@ "from": "lru-cache@>=4.0.1 <5.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz" }, + "qs": { + "version": "6.4.0", + "from": "qs@>=6.4.0 <6.5.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz" + }, + "request": { + "version": "2.81.0", + "from": "request@>=2.79.0 <3.0.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz" + }, + "tunnel-agent": { + "version": "0.6.0", + "from": "tunnel-agent@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.2.9 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz" + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" } } }, @@ -8571,9 +8713,9 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.6.tgz" }, "normalize-path": { - "version": "2.0.1", + "version": "2.1.1", "from": "normalize-path@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz" + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" }, "normalize-range": { "version": "0.1.2", @@ -8751,9 +8893,9 @@ "optional": true }, "ora": { - "version": "1.1.0", + "version": "1.2.0", "from": "ora@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-1.1.0.tgz" + "resolved": "https://registry.npmjs.org/ora/-/ora-1.2.0.tgz" }, "orchestrator": { "version": "0.3.8", @@ -8887,10 +9029,20 @@ } }, "pageres": { - "version": "4.3.0", + "version": "4.4.0", "from": "pageres@>=4.1.1 <5.0.0", - "resolved": "https://registry.npmjs.org/pageres/-/pageres-4.3.0.tgz", + "resolved": "https://registry.npmjs.org/pageres/-/pageres-4.4.0.tgz", "dependencies": { + "filename-reserved-regex": { + "version": "2.0.0", + "from": "filename-reserved-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz" + }, + "filenamify": { + "version": "2.0.0", + "from": "filenamify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.0.0.tgz" + }, "lodash.template": { "version": "4.4.0", "from": "lodash.template@>=4.0.1 <5.0.0", @@ -8909,9 +9061,9 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz" }, "param-case": { - "version": "2.1.0", + "version": "2.1.1", "from": "param-case@>=2.1.0 <2.2.0", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.0.tgz" + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz" }, "parents": { "version": "1.0.1", @@ -8919,9 +9071,9 @@ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz" }, "parse-asn1": { - "version": "5.0.0", + "version": "5.1.0", "from": "parse-asn1@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.0.0.tgz" + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz" }, "parse-cookie-phantomjs": { "version": "1.2.0", @@ -9145,9 +9297,9 @@ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz" }, "which": { - "version": "1.2.12", + "version": "1.2.14", "from": "which@>=1.2.10 <1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz" + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" } } }, @@ -9484,9 +9636,9 @@ "resolved": "https://registry.npmjs.org/pretty-data/-/pretty-data-0.40.0.tgz" }, "pretty-error": { - "version": "2.0.2", + "version": "2.0.3", "from": "pretty-error@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.0.2.tgz" + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.0.3.tgz" }, "pretty-hrtime": { "version": "1.0.3", @@ -9534,9 +9686,9 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" }, "protocolify": { - "version": "1.0.3", - "from": "protocolify@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/protocolify/-/protocolify-1.0.3.tgz" + "version": "2.0.0", + "from": "protocolify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/protocolify/-/protocolify-2.0.0.tgz" }, "protractor": { "version": "3.3.0", @@ -9557,9 +9709,15 @@ "dev": true }, "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@~1.4.7", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "dev": true + }, + "q": { + "version": "1.4.1", + "from": "q@1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", "dev": true }, "qs": { @@ -9583,13 +9741,13 @@ } }, "proxy-addr": { - "version": "1.1.3", + "version": "1.1.4", "from": "proxy-addr@>=1.1.3 <1.2.0", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.3.tgz" + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz" }, "proxy-agent": { "version": "2.0.0", - "from": "proxy-agent@>=2.0.0", + "from": "proxy-agent@2.0.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz", "dev": true, "dependencies": { @@ -9701,9 +9859,9 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.6.1 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", "dependencies": { "source-map": { "version": "0.5.6", @@ -9784,9 +9942,9 @@ "resolved": "https://registry.npmjs.org/pusher/-/pusher-1.5.1.tgz" }, "q": { - "version": "1.4.1", + "version": "1.5.0", "from": "q@>=1.4.1 <2.0.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz" + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz" }, "qjobs": { "version": "1.1.5", @@ -9847,9 +10005,9 @@ } }, "ramda": { - "version": "0.22.1", - "from": "ramda@>=0.22.1 <0.23.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.22.1.tgz", + "version": "0.23.0", + "from": "ramda@>=0.23.0 <0.24.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.23.0.tgz", "dev": true }, "randomatic": { @@ -10063,10 +10221,15 @@ "from": "relateurl@>=0.2.0 <0.3.0", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz" }, + "remove-trailing-separator": { + "version": "1.0.1", + "from": "remove-trailing-separator@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz" + }, "renderkid": { - "version": "2.0.0", - "from": "renderkid@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.0.tgz", + "version": "2.0.1", + "from": "renderkid@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", "dependencies": { "utila": { "version": "0.3.3", @@ -10101,9 +10264,9 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz", "dependencies": { "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@>=1.4.7 <1.5.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" } } }, @@ -10203,9 +10366,9 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "dependencies": { "onetime": { - "version": "2.0.0", + "version": "2.0.1", "from": "onetime@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz" } } }, @@ -10318,14 +10481,14 @@ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.3.tgz", "dependencies": { "async": { - "version": "2.1.5", + "version": "2.2.0", "from": "async@>=2.1.5 <3.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz" + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz" }, "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" } } }, @@ -10375,9 +10538,9 @@ } }, "selenium-server": { - "version": "3.3.0", + "version": "3.3.1", "from": "selenium-server@>=3.0.1 <4.0.0", - "resolved": "https://registry.npmjs.org/selenium-server/-/selenium-server-3.3.0.tgz", + "resolved": "https://registry.npmjs.org/selenium-server/-/selenium-server-3.3.1.tgz", "dev": true }, "selenium-webdriver": { @@ -10483,9 +10646,9 @@ "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz" }, "serve-favicon": { - "version": "2.4.1", + "version": "2.4.2", "from": "serve-favicon@>=2.3.0 <3.0.0", - "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.2.tgz", "dependencies": { "etag": { "version": "1.8.0", @@ -10496,6 +10659,11 @@ "version": "0.5.0", "from": "fresh@0.5.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz" + }, + "ms": { + "version": "1.0.0", + "from": "ms@1.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-1.0.0.tgz" } } }, @@ -10629,9 +10797,9 @@ } }, "sinon-chai": { - "version": "2.8.0", + "version": "2.9.0", "from": "sinon-chai@>=2.8.0 <3.0.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.8.0.tgz", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.9.0.tgz", "dev": true }, "sinon-stub-promise": { @@ -10788,9 +10956,9 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz" }, "source-map-support": { - "version": "0.4.11", + "version": "0.4.14", "from": "source-map-support@>=0.4.2 <0.5.0", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.11.tgz" + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.14.tgz" }, "source-map-url": { "version": "0.3.0", @@ -10885,9 +11053,9 @@ } }, "stable": { - "version": "0.1.5", + "version": "0.1.6", "from": "stable@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.5.tgz", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", "dev": true }, "stack-trace": { @@ -11009,9 +11177,9 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.6.3.tgz", "dependencies": { "readable-stream": { - "version": "2.2.3", + "version": "2.2.6", "from": "readable-stream@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.3.tgz" + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz" } } }, @@ -11149,9 +11317,9 @@ "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz" }, "stripe": { - "version": "4.15.1", + "version": "4.16.1", "from": "stripe@>=4.2.0 <5.0.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-4.15.1.tgz", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-4.16.1.tgz", "dependencies": { "bluebird": { "version": "2.11.0", @@ -11215,9 +11383,9 @@ "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz" }, "superagent": { - "version": "3.5.0", + "version": "3.5.2", "from": "superagent@>=3.4.3 <4.0.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.5.0.tgz", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.5.2.tgz", "dependencies": { "form-data": { "version": "2.1.2", @@ -11388,9 +11556,9 @@ } }, "test-exclude": { - "version": "4.0.0", - "from": "test-exclude@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.0.0.tgz", + "version": "4.0.3", + "from": "test-exclude@>=4.0.3 <5.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.0.3.tgz", "dev": true }, "tether": { @@ -11420,9 +11588,9 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "dependencies": { "readable-stream": { - "version": "2.2.3", + "version": "2.2.6", "from": "readable-stream@>=2.1.5 <3.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.3.tgz" + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz" } } }, @@ -11463,9 +11631,16 @@ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz" }, "timers-ext": { - "version": "0.1.0", + "version": "0.1.1", "from": "timers-ext@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.0.tgz" + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.1.tgz", + "dependencies": { + "next-tick": { + "version": "1.0.0", + "from": "next-tick@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz" + } + } }, "tiny-lr-fork": { "version": "0.0.5", @@ -11510,12 +11685,6 @@ "from": "to-fast-properties@>=1.0.1 <2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz" }, - "to-iso-string": { - "version": "0.0.2", - "from": "to-iso-string@0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "dev": true - }, "token-stream": { "version": "0.0.1", "from": "token-stream@0.0.1", @@ -11767,9 +11936,9 @@ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "node-uuid": { - "version": "1.4.7", + "version": "1.4.8", "from": "node-uuid@1.x", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" } } }, @@ -11870,9 +12039,9 @@ "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.8.tgz", "dependencies": { "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" }, "mime": { "version": "1.3.4", @@ -11915,9 +12084,9 @@ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" }, "useragent": { - "version": "2.1.12", + "version": "2.1.13", "from": "useragent@>=2.1.9 <3.0.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.1.12.tgz", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.1.13.tgz", "dependencies": { "lru-cache": { "version": "2.2.4", @@ -11979,9 +12148,9 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-4.9.0.tgz" }, "vary": { - "version": "1.1.0", + "version": "1.1.1", "from": "vary@>=1.1.0 <1.2.0", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.0.tgz" + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz" }, "vendors": { "version": "1.0.1", @@ -12169,9 +12338,9 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz" }, "vue": { - "version": "2.2.2", + "version": "2.2.6", "from": "vue@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.2.2.tgz" + "resolved": "https://registry.npmjs.org/vue/-/vue-2.2.6.tgz" }, "vue-hot-reload-api": { "version": "2.0.11", @@ -12184,9 +12353,9 @@ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-11.3.4.tgz", "dependencies": { "loader-utils": { - "version": "1.0.3", - "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "version": "1.1.0", + "from": "loader-utils@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" }, "lru-cache": { "version": "4.0.2", @@ -12196,9 +12365,16 @@ } }, "vue-mugen-scroll": { - "version": "0.2.1", + "version": "0.2.2", "from": "vue-mugen-scroll@>=0.2.1 <0.3.0", - "resolved": "https://registry.npmjs.org/vue-mugen-scroll/-/vue-mugen-scroll-0.2.1.tgz" + "resolved": "https://registry.npmjs.org/vue-mugen-scroll/-/vue-mugen-scroll-0.2.2.tgz", + "dependencies": { + "throttleit": { + "version": "1.0.0", + "from": "throttleit@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz" + } + } }, "vue-router": { "version": "2.3.1", @@ -12211,16 +12387,16 @@ "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-2.0.5.tgz", "dependencies": { "loader-utils": { - "version": "1.0.3", + "version": "1.1.0", "from": "loader-utils@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz" } } }, "vue-template-compiler": { - "version": "2.2.2", + "version": "2.2.6", "from": "vue-template-compiler@>=2.1.10 <3.0.0", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.2.2.tgz" + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.2.6.tgz" }, "vue-template-es2015-compiler": { "version": "1.5.1", @@ -12239,40 +12415,45 @@ }, "watchpack": { "version": "1.3.1", - "from": "watchpack@>=1.2.0 <2.0.0", + "from": "watchpack@>=1.3.1 <2.0.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz", "dependencies": { "async": { - "version": "2.1.5", + "version": "2.2.0", "from": "async@>=2.1.2 <3.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz" + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz" } } }, "webpack": { - "version": "2.2.1", + "version": "2.3.2", "from": "webpack@>=2.2.1 <3.0.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.3.2.tgz", "dependencies": { "async": { - "version": "2.1.5", + "version": "2.2.0", "from": "async@>=2.1.2 <3.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz" + "resolved": "https://registry.npmjs.org/async/-/async-2.2.0.tgz" }, "camelcase": { "version": "1.2.1", "from": "camelcase@>=1.0.2 <2.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz" }, + "source-list-map": { + "version": "1.1.1", + "from": "source-list-map@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.1.tgz" + }, "supports-color": { "version": "3.2.3", "from": "supports-color@>=3.1.0 <4.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz" }, "uglify-js": { - "version": "2.8.18", + "version": "2.8.20", "from": "uglify-js@>=2.8.5 <3.0.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.18.tgz", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", "dependencies": { "yargs": { "version": "3.10.0", @@ -12281,6 +12462,11 @@ } } }, + "webpack-sources": { + "version": "0.2.3", + "from": "webpack-sources@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz" + }, "yargs": { "version": "6.6.0", "from": "yargs@>=6.0.0 <7.0.0", @@ -12540,9 +12726,9 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz" }, "yallist": { - "version": "2.0.0", + "version": "2.1.2", "from": "yallist@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" }, "yargs": { "version": "3.10.0", diff --git a/package.json b/package.json index 3d99c751e9..201e42ef6d 100644 --- a/package.json +++ b/package.json @@ -139,9 +139,9 @@ "test:api-v3:unit": "gulp test:api-v3:unit", "test:api-v3:integration": "gulp test:api-v3:integration", "test:api-v3:integration:separate-server": "NODE_ENV=test gulp test:api-v3:integration:separate-server", - "test:sanity": "mocha test/sanity --recursive", - "test:common": "mocha test/common --recursive", - "test:content": "mocha test/content --recursive", + "test:sanity": "istanbul cover --dir coverage/sanity --report lcovonly node_modules/mocha/bin/_mocha -- test/sanity --recursive", + "test:common": "istanbul cover --dir coverage/common --report lcovonly node_modules/mocha/bin/_mocha -- test/common --recursive", + "test:content": "istanbul cover --dir coverage/content --report lcovonly node_modules/mocha/bin/_mocha -- test/content --recursive", "test:karma": "karma start test/client-old/spec/karma.conf.js --single-run", "test:karma:watch": "karma start test/client-old/spec/karma.conf.js", "test:prepare:webdriver": "webdriver-manager update", @@ -183,7 +183,7 @@ "grunt-karma": "~0.12.1", "http-proxy-middleware": "^0.17.0", "inject-loader": "^3.0.0-beta4", - "istanbul": "^0.3.14", + "istanbul": "^1.1.0-alpha.1", "karma": "^1.3.0", "karma-babel-preprocessor": "^6.0.1", "karma-chai-plugins": "~0.6.0", @@ -198,7 +198,7 @@ "karma-webpack": "^2.0.2", "lcov-result-merger": "^1.0.2", "lolex": "^1.4.0", - "mocha": "^2.3.3", + "mocha": "^3.2.0", "mongodb": "^2.0.46", "mongoskin": "~2.1.0", "monk": "^4.0.0", diff --git a/test/api/v3/integration/groups/GET-groups_groupId_invites.test.js b/test/api/v3/integration/groups/GET-groups_groupId_invites.test.js index 1b7c172d94..2e6a612102 100644 --- a/test/api/v3/integration/groups/GET-groups_groupId_invites.test.js +++ b/test/api/v3/integration/groups/GET-groups_groupId_invites.test.js @@ -63,15 +63,17 @@ describe('GET /groups/:groupId/invites', () => { }); it('returns only first 30 invites', async () => { - let group = await generateGroup(user, {type: 'party', name: generateUUID()}); + let leader = await generateUser({balance: 4}); + let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()}); + let invitesToGenerate = []; for (let i = 0; i < 31; i++) { invitesToGenerate.push(generateUser()); } let generatedInvites = await Promise.all(invitesToGenerate); - await user.post(`/groups/${group._id}/invite`, {uuids: generatedInvites.map(invite => invite._id)}); + await leader.post(`/groups/${group._id}/invite`, {uuids: generatedInvites.map(invite => invite._id)}); - let res = await user.get('/groups/party/invites'); + let res = await leader.get(`/groups/${group._id}/invites`); expect(res.length).to.equal(30); res.forEach(member => { expect(member).to.have.all.keys(['_id', 'id', 'profile']); diff --git a/test/api/v3/integration/groups/POST-groups_invite.test.js b/test/api/v3/integration/groups/POST-groups_invite.test.js index 522fa12043..ecaea4c74f 100644 --- a/test/api/v3/integration/groups/POST-groups_invite.test.js +++ b/test/api/v3/integration/groups/POST-groups_invite.test.js @@ -6,6 +6,7 @@ import { import { v4 as generateUUID } from 'uuid'; const INVITES_LIMIT = 100; +const PARTY_LIMIT_MEMBERS = 30; describe('Post /groups/:groupId/invite', () => { let inviter; @@ -321,6 +322,19 @@ describe('Post /groups/:groupId/invite', () => { }); }); + it('allows 30+ members in a guild', async () => { + let invitesToGenerate = []; + // Generate 30 users to invite (30 + leader = 31 members) + for (let i = 0; i < PARTY_LIMIT_MEMBERS; i++) { + invitesToGenerate.push(generateUser()); + } + let generatedInvites = await Promise.all(invitesToGenerate); + // Invite users + expect(await inviter.post(`/groups/${group._id}/invite`, { + uuids: generatedInvites.map(invite => invite._id), + })).to.be.an('array'); + }); + // @TODO: Add this after we are able to mock the group plan route xit('returns an error when a non-leader invites to a group plan', async () => { let userToInvite = await generateUser(); @@ -410,5 +424,36 @@ describe('Post /groups/:groupId/invite', () => { }); expect((await userToInvite.get('/user')).invitations.party.id).to.equal(party._id); }); + + it('allows 30 members in a party', async () => { + let invitesToGenerate = []; + // Generate 29 users to invite (29 + leader = 30 members) + for (let i = 0; i < PARTY_LIMIT_MEMBERS - 1; i++) { + invitesToGenerate.push(generateUser()); + } + let generatedInvites = await Promise.all(invitesToGenerate); + // Invite users + expect(await inviter.post(`/groups/${party._id}/invite`, { + uuids: generatedInvites.map(invite => invite._id), + })).to.be.an('array'); + }); + + it('does not allow 30+ members in a party', async () => { + let invitesToGenerate = []; + // Generate 30 users to invite (30 + leader = 31 members) + for (let i = 0; i < PARTY_LIMIT_MEMBERS; i++) { + invitesToGenerate.push(generateUser()); + } + let generatedInvites = await Promise.all(invitesToGenerate); + // Invite users + await expect(inviter.post(`/groups/${party._id}/invite`, { + uuids: generatedInvites.map(invite => invite._id), + })) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('partyExceedsMembersLimit', {maxMembersParty: PARTY_LIMIT_MEMBERS}), + }); + }); }); }); diff --git a/test/api/v3/unit/models/group.test.js b/test/api/v3/unit/models/group.test.js index 1fa1000d9c..1ce5254461 100644 --- a/test/api/v3/unit/models/group.test.js +++ b/test/api/v3/unit/models/group.test.js @@ -4,9 +4,6 @@ import validator from 'validator'; import { sleep } from '../../../../helpers/api-unit.helper'; import { model as Group, INVITES_LIMIT } from '../../../../../website/server/models/group'; import { model as User } from '../../../../../website/server/models/user'; -import { - BadRequest, - } from '../../../../../website/server/libs/errors'; import { quests as questScrolls } from '../../../../../website/common/script/content'; import { groupChatReceivedWebhook } from '../../../../../website/server/libs/webhook'; import * as email from '../../../../../website/server/libs/email'; @@ -460,73 +457,67 @@ describe('Group Model', () => { }; }); - it('throws an error if no uuids or emails are passed in', (done) => { - try { - Group.validateInvitations(null, null, res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('canOnlyInviteEmailUuid'); - done(); - } + it('throws an error if no uuids or emails are passed in', async () => { + await expect(Group.validateInvitations(null, null, res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('canOnlyInviteEmailUuid'); }); - it('throws an error if only uuids are passed in, but they are not an array', (done) => { - try { - Group.validateInvitations({ uuid: 'user-id'}, null, res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('uuidsMustBeAnArray'); - done(); - } + it('throws an error if only uuids are passed in, but they are not an array', async () => { + await expect(Group.validateInvitations({ uuid: 'user-id'}, null, res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('uuidsMustBeAnArray'); }); - it('throws an error if only emails are passed in, but they are not an array', (done) => { - try { - Group.validateInvitations(null, { emails: 'user@example.com'}, res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('emailsMustBeAnArray'); - done(); - } + it('throws an error if only emails are passed in, but they are not an array', async () => { + await expect(Group.validateInvitations(null, { emails: 'user@example.com'}, res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('emailsMustBeAnArray'); }); - it('throws an error if emails are not passed in, and uuid array is empty', (done) => { - try { - Group.validateInvitations([], null, res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('inviteMissingUuid'); - done(); - } + it('throws an error if emails are not passed in, and uuid array is empty', async () => { + await expect(Group.validateInvitations([], null, res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('inviteMissingUuid'); }); - it('throws an error if uuids are not passed in, and email array is empty', (done) => { - try { - Group.validateInvitations(null, [], res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('inviteMissingEmail'); - done(); - } + it('throws an error if uuids are not passed in, and email array is empty', async () => { + await expect(Group.validateInvitations(null, [], res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('inviteMissingEmail'); }); - it('throws an error if uuids and emails are passed in as empty arrays', (done) => { - try { - Group.validateInvitations([], [], res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('inviteMustNotBeEmpty'); - done(); - } + it('throws an error if uuids and emails are passed in as empty arrays', async () => { + await expect(Group.validateInvitations([], [], res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('inviteMustNotBeEmpty'); }); - it('throws an error if total invites exceed max invite constant', (done) => { + it('throws an error if total invites exceed max invite constant', async () => { let uuids = []; let emails = []; @@ -537,17 +528,16 @@ describe('Group Model', () => { uuids.push('one-more-uuid'); // to put it over the limit - try { - Group.validateInvitations(uuids, emails, res); - } catch (err) { - expect(err).to.be.an.instanceof(BadRequest); - expect(res.t).to.be.calledOnce; - expect(res.t).to.be.calledWith('canOnlyInviteMaxInvites', {maxInvites: INVITES_LIMIT }); - done(); - } + await expect(Group.validateInvitations(uuids, emails, res)).to.eventually.be.rejected.and.eql({ + httpCode: 400, + message: 'Bad request.', + name: 'BadRequest', + }); + expect(res.t).to.be.calledOnce; + expect(res.t).to.be.calledWith('canOnlyInviteMaxInvites', {maxInvites: INVITES_LIMIT }); }); - it('does not throw error if number of invites matches max invite limit', () => { + it('does not throw error if number of invites matches max invite limit', async () => { let uuids = []; let emails = []; @@ -556,49 +546,33 @@ describe('Group Model', () => { emails.push(`user-${i}@example.com`); } - expect(function () { - Group.validateInvitations(uuids, emails, res); - }).to.not.throw(); - }); - - - it('does not throw an error if only user ids are passed in', () => { - expect(function () { - Group.validateInvitations(['user-id', 'user-id2'], null, res); - }).to.not.throw(); - + await Group.validateInvitations(uuids, emails, res); expect(res.t).to.not.be.called; }); - it('does not throw an error if only emails are passed in', () => { - expect(function () { - Group.validateInvitations(null, ['user1@example.com', 'user2@example.com'], res); - }).to.not.throw(); + it('does not throw an error if only user ids are passed in', async () => { + await Group.validateInvitations(['user-id', 'user-id2'], null, res); expect(res.t).to.not.be.called; }); - it('does not throw an error if both uuids and emails are passed in', () => { - expect(function () { - Group.validateInvitations(['user-id', 'user-id2'], ['user1@example.com', 'user2@example.com'], res); - }).to.not.throw(); - + it('does not throw an error if only emails are passed in', async () => { + await Group.validateInvitations(null, ['user1@example.com', 'user2@example.com'], res); expect(res.t).to.not.be.called; }); - it('does not throw an error if uuids are passed in and emails are an empty array', () => { - expect(function () { - Group.validateInvitations(['user-id', 'user-id2'], [], res); - }).to.not.throw(); - + it('does not throw an error if both uuids and emails are passed in', async () => { + await Group.validateInvitations(['user-id', 'user-id2'], ['user1@example.com', 'user2@example.com'], res); expect(res.t).to.not.be.called; }); - it('does not throw an error if emails are passed in and uuids are an empty array', () => { - expect(function () { - Group.validateInvitations([], ['user1@example.com', 'user2@example.com'], res); - }).to.not.throw(); + it('does not throw an error if uuids are passed in and emails are an empty array', async () => { + await Group.validateInvitations(['user-id', 'user-id2'], [], res); + expect(res.t).to.not.be.called; + }); + it('does not throw an error if emails are passed in and uuids are an empty array', async () => { + await Group.validateInvitations([], ['user1@example.com', 'user2@example.com'], res); expect(res.t).to.not.be.called; }); }); diff --git a/test/client-old/spec/directives/task.directive.js b/test/client-old/spec/directives/task.directive.js new file mode 100644 index 0000000000..0735d54fb8 --- /dev/null +++ b/test/client-old/spec/directives/task.directive.js @@ -0,0 +1,35 @@ +describe('task Directive', () => { + var compile, scope, directiveElem, $modal; + + beforeEach(function(){ + module(function($provide) { + $modal = { + open: sandbox.spy(), + }; + $provide.value('$modal', $modal); + }); + + inject(function($compile, $rootScope, $templateCache) { + compile = $compile; + scope = $rootScope.$new(); + + $templateCache.put('templates/task.html', '
Task
'); + }); + + + directiveElem = getCompiledElement(); + }); + + function getCompiledElement(){ + var element = angular.element(''); + var compiledElement = compile(element)(scope); + scope.$digest(); + return compiledElement; + } + + xit('opens task note modal', () => { + scope.showNoteDetails(); + + expect($modal.open).to.be.calledOnce; + }); +}) diff --git a/test/client-old/spec/karma.conf.js b/test/client-old/spec/karma.conf.js index 3cceb2404b..257da29426 100644 --- a/test/client-old/spec/karma.conf.js +++ b/test/client-old/spec/karma.conf.js @@ -81,8 +81,11 @@ module.exports = function karmaConfig (config) { }, coverageReporter: { - type: 'lcov', - dir: 'coverage/karma', + reporters: [ + { type: 'lcov', subdir: '.' }, + { type: 'text-summary' }, + ], + dir: '../../../coverage/karma', }, // Enable mocha-style reporting, for better test visibility diff --git a/test/client/unit/karma.conf.js b/test/client/unit/karma.conf.js index 7492020472..6007b6b450 100644 --- a/test/client/unit/karma.conf.js +++ b/test/client/unit/karma.conf.js @@ -28,7 +28,7 @@ module.exports = function (config) { noInfo: true, }, coverageReporter: { - dir: './coverage', + dir: '../../../coverage/client-unit', reporters: [ { type: 'lcov', subdir: '.' }, { type: 'text-summary' }, diff --git a/website/client-old/css/menu.styl b/website/client-old/css/menu.styl index 92242cc094..879499b4a9 100644 --- a/website/client-old/css/menu.styl +++ b/website/client-old/css/menu.styl @@ -178,6 +178,8 @@ hrpg-button-color-mixin(lighten($color-toolbar,32.8%)) .toolbar-subscribe-button, .toolbar-controls .toolbar-subscribe-button @extend $hrpg-button + button + min-width: 130px @media screen and (max-width: $xs-max-screen-width) .toolbar-toggle display: none diff --git a/website/client-old/js/controllers/groupsCtrl.js b/website/client-old/js/controllers/groupsCtrl.js index d6595e17ca..26870b09bc 100644 --- a/website/client-old/js/controllers/groupsCtrl.js +++ b/website/client-old/js/controllers/groupsCtrl.js @@ -2,6 +2,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '$http', '$q', 'User', 'Members', '$state', 'Notification', function($scope, $rootScope, Shared, Groups, $http, $q, User, Members, $state, Notification) { + $scope.PARTY_LIMIT_MEMBERS = Shared.constants.PARTY_LIMIT_MEMBERS; + $scope.inviteOrStartParty = Groups.inviteOrStartParty; $scope.isMemberOfPendingQuest = function (userid, group) { if (!group.quest || !group.quest.members) return false; diff --git a/website/client-old/js/directives/task.directive.js b/website/client-old/js/directives/task.directive.js index 3c692e7f54..e1f8733c76 100644 --- a/website/client-old/js/directives/task.directive.js +++ b/website/client-old/js/directives/task.directive.js @@ -1,24 +1,41 @@ -'use strict'; - -(function(){ - angular - .module('habitrpg') - .directive('task', task); - - task.$inject = [ - 'Shared', - ]; - - function task(Shared) { - return { - restrict: 'E', - templateUrl: 'templates/task.html', - scope: true, - link: function($scope, element, attrs) { - $scope.getClasses = function (task, user, list, main) { - return Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main); - } - } - } - } -}()); +'use strict'; + +(function(){ + angular + .module('habitrpg') + .directive('task', task); + + task.$inject = [ + 'Shared', + '$modal', + ]; + + function task(Shared, $modal) { + return { + restrict: 'E', + templateUrl: 'templates/task.html', + scope: true, + link: function($scope, element, attrs) { + $scope.getClasses = function (task, user, list, main) { + return Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main); + } + + $scope.showNoteDetails = function (task) { + task.popoverOpen = false; + + $modal.open({ + templateUrl: 'modals/task-extra-notes.html', + controller: ['$scope', 'task', function ($scope, task) { + $scope.task = task; + }], + resolve: { + task: function() { + return task; + } + } + }) + }; + } + } + } +}()); diff --git a/website/client-old/js/services/userServices.js b/website/client-old/js/services/userServices.js index 381cdc8bed..826774741b 100644 --- a/website/client-old/js/services/userServices.js +++ b/website/client-old/js/services/userServices.js @@ -260,6 +260,7 @@ angular.module('habitrpg') if (quest.progressDelta && userQuest.boss) { Notification.quest('questDamage', quest.progressDelta.toFixed(1)); } else if (quest.collection && userQuest.collect) { + user.party.quest.progress.collectedItems++; Notification.quest('questCollection', quest.collection); } } diff --git a/website/common/locales/en/communityGuidelines.json b/website/common/locales/en/communityGuidelines.json index b0ce73f71d..7d040a6d1c 100644 --- a/website/common/locales/en/communityGuidelines.json +++ b/website/common/locales/en/communityGuidelines.json @@ -70,7 +70,7 @@ "commGuidePara039": "The Back Corner Guild is a free public space to discuss sensitive subjects, and it is carefully moderated. It is not a place for general discussions or conversations. The Public Space Guidelines still apply, as do all of the Terms and Conditions. Just because we are wearing long cloaks and clustering in a corner doesn't mean that anything goes! Now pass me that smoldering candle, will you?", "commGuideHeadingTrello": "Trello Boards", "commGuidePara040": "Trello serves as an open forum for suggestions and discussion of site features. Habitica is ruled by the people in the form of valiant contributors -- we all build the site together. Trello lends structure to our system. Out of consideration for this, try your best to contain all your thoughts into one comment, instead of commenting many times in a row on the same card. If you think of something new, feel free to edit your original comments. Please, take pity on those of us who receive a notification for every new comment. Our inboxes can only withstand so much.", - "commGuidePara041": "Habitica uses five different Trello boards:", + "commGuidePara041": "Habitica uses four different Trello boards:", "commGuideList03A": "The Main Board is a place to request and vote on site features.", "commGuideList03B": "The Mobile Board is a place to request and vote on mobile app features.", "commGuideList03C": "The Pixel Art Board is a place to discuss and submit pixel art.", diff --git a/website/common/locales/en/groups.json b/website/common/locales/en/groups.json index 9d3e016268..87c82d5152 100644 --- a/website/common/locales/en/groups.json +++ b/website/common/locales/en/groups.json @@ -135,6 +135,7 @@ "leaderOnlyChallenges": "Only group leader can create challenges", "sendGift": "Send Gift", "inviteFriends": "Invite Friends", + "partyMembersInfo": "Your party currently has <%= memberCount %> members and <%= invitationCount %> pending invitations. The limit of members in a party is <%= limitMembers %>. Invitations above this limit cannot be sent.", "inviteByEmail": "Invite by Email", "inviteByEmailExplanation": "If a friend joins Habitica via your email, they'll automatically be invited to your party!", "inviteFriendsNow": "Invite Friends Now", @@ -154,6 +155,7 @@ "sendGiftPurchase": "Purchase", "sendGiftMessagePlaceholder": "Personal message (optional)", "sendGiftSubscription": "<%= months %> Month(s): $<%= price %> USD", + "gemGiftsAreOptional": "Please note that Habitica will never require you to gift gems to other players. Begging people for gems is a violation of the Community Guidelines, and all such instances should be reported to <%= hrefTechAssistanceEmail %>.", "battleWithFriends": "Battle Monsters With Friends", "startPartyWithFriends": "Start a Party with your friends!", "startAParty": "Start a Party", @@ -201,6 +203,7 @@ "uuidsMustBeAnArray": "User ID invites must be an array.", "emailsMustBeAnArray": "Email address invites must be an array.", "canOnlyInviteMaxInvites": "You can only invite \"<%= maxInvites %>\" at a time", + "partyExceedsMembersLimit": "Party size is limited to <%= maxMembersParty %> members", "onlyCreatorOrAdminCanDeleteChat": "Not authorized to delete this message!", "onlyGroupLeaderCanEditTasks": "Not authorized to manage tasks!", "onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned", diff --git a/website/common/locales/en/tasks.json b/website/common/locales/en/tasks.json index d10959dc2a..ae697e369e 100644 --- a/website/common/locales/en/tasks.json +++ b/website/common/locales/en/tasks.json @@ -164,6 +164,7 @@ "confirmScoreNotes": "Confirm task scoring with notes", "taskScoreNotesTooLong": "Task score notes must be less than 256 characters", "groupTasksByChallenge": "Group tasks by challenge title", + "taskNotes": "Task Notes", "monthlyRepeatHelpContent": "This task will be due every X months", "yearlyRepeatHelpContent": "This task will be due every X years" } diff --git a/website/common/script/constants.js b/website/common/script/constants.js index b09edc627b..7381d2cf23 100644 --- a/website/common/script/constants.js +++ b/website/common/script/constants.js @@ -12,4 +12,6 @@ export const SUPPORTED_SOCIAL_NETWORKS = [ {key: 'google', name: 'Google'}, ]; -export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination \ No newline at end of file +export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination + +export const PARTY_LIMIT_MEMBERS = 30; diff --git a/website/common/script/index.js b/website/common/script/index.js index 816ddfb7be..dd5590149a 100644 --- a/website/common/script/index.js +++ b/website/common/script/index.js @@ -27,6 +27,7 @@ import { LARGE_GROUP_COUNT_MESSAGE_CUTOFF, SUPPORTED_SOCIAL_NETWORKS, GUILDS_PER_PAGE, + PARTY_LIMIT_MEMBERS, } from './constants'; api.constants = { @@ -34,6 +35,7 @@ api.constants = { LARGE_GROUP_COUNT_MESSAGE_CUTOFF, SUPPORTED_SOCIAL_NETWORKS, GUILDS_PER_PAGE, + PARTY_LIMIT_MEMBERS, }; // TODO Move these under api.constants api.maxLevel = MAX_LEVEL; diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js index 1a0d6445a1..cc4997384e 100644 --- a/website/server/controllers/api-v3/groups.js +++ b/website/server/controllers/api-v3/groups.js @@ -1038,6 +1038,7 @@ async function _inviteByEmail (invite, group, inviter, req, res) { * @apiError (400) {BadRequest} MustBeArray The `uuids` or `emails` body param was not an array. * @apiError (400) {BadRequest} TooManyInvites A max of 100 invites (combined emails and user ids) can * be sent out at a time. + * @apiError (400) {BadRequest} ExceedsMembersLimit A max of 30 members can join a party. * * @apiError (401) {NotAuthorized} UserAlreadyInvited The user has already been invited to the group. * @apiError (401) {NotAuthorized} UserAlreadyInGroup The user is already a member of the group. @@ -1066,7 +1067,7 @@ api.inviteToGroup = { let uuids = req.body.uuids; let emails = req.body.emails; - Group.validateInvitations(uuids, emails, res); + await Group.validateInvitations(uuids, emails, res, group); let results = []; diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js index 9903d007d3..c0418264ba 100644 --- a/website/server/controllers/api-v3/user.js +++ b/website/server/controllers/api-v3/user.js @@ -27,8 +27,39 @@ let api = {}; * @apiName UserGet * @apiGroup User * + * @apiDescription The user profile contains data related to the authenticated user including (but not limited to); + * Achievements + * Authentications (including types and timestamps) + * Challenges + * Flags (including armoire, tutorial, tour etc...) + * Guilds + * History (including timestamps and values) + * Inbox (includes message history) + * Invitations (to parties/guilds) + * Items (character's full inventory) + * New Messages (flags for groups/guilds that have new messages) + * Notifications + * Party (includes current quest information) + * Preferences (user selected prefs) + * Profile (name, photo url, blurb) + * Purchased (includes purchase history, gem purchased items, plans) + * PushDevices (identifiers for mobile devices authorized) + * Stats (standard RPG stats, class, buffs, xp, etc..) + * Tags + * TasksOrder (list of all ids for dailys, habits, rewards and todos) + * * @apiSuccess {Object} data The user object - */ + * + * @apiSuccessExample {json} Result: + * { + * "success": true, + * "data": { + * -- User data included here, for details of the user model see: + * -- https://github.com/HabitRPG/habitica/tree/develop/website/server/models/user + * } + * } + * +*/ api.getUser = { method: 'GET', middlewares: [authWithHeaders()], @@ -46,11 +77,30 @@ api.getUser = { }; /** - * @api {get} /api/v3/user/inventory/buy Get the gear items available for purchase for the current user + * @api {get} /api/v3/user/inventory/buy Get the gear items available for purchase for the authenticated user * @apiName UserGetBuyList * @apiGroup User * - * @apiSuccess {Object} data The buy list + * @apiSuccessExample {json} Success-Response: + * { + * "success": true, + * "data": [ + * { + * "text": "Training Sword", + * "notes": "Practice weapon. Confers no benefit.", + * "value": 1, + * "type": "weapon", + * "key": "weapon_warrior_0", + * "set": "warrior-0", + * "klass": "warrior", + * "index": "0", + * "str": 0, + * "int": 0, + * "per": 0, + * "con": 0 + * } + * ] + * } */ api.getBuyList = { method: 'GET', @@ -142,11 +192,31 @@ let checkPreferencePurchase = (user, path, item) => { /** * @api {put} /api/v3/user Update the user - * @apiDescription Example body: {'stats.hp':50, 'preferences.background': 'beach'} * @apiName UserUpdate * @apiGroup User * - * @apiSuccess {Object} data The updated user object + * @apiDescription Some of the user items can be updated, such as preferences, flags and stats. + ^ + * @apiParamExample {json} Request-Example: + * { + * "achievements.habitBirthdays": 2, + * "profile.name": "MadPink", + * "stats.hp": 53, + * "flags.warnedLowHealth":false, + * "preferences.allocationMode":"flat", + * "preferences.hair.bangs": 3 + * } + * + * @apiSuccess {Object} data The updated user object, the result is identical to the get user call + * + * @apiError (401) {NotAuthorized} messageUserOperationProtected Returned if the change is not allowed. + * + * @apiErrorExample {json} Error-Response: + * { + * "success": false, + * "error": "NotAuthorized", + * "message": "path `stats.class` was not saved, as it's a protected path." + * } */ api.updateUser = { method: 'PUT', @@ -179,9 +249,32 @@ api.updateUser = { * @apiName UserDelete * @apiGroup User * - * @apiParam {String} password The user's password (unless it's a Facebook account) + * @apiParam {String} password The user's password if the account uses local authentication * * @apiSuccess {Object} data An empty Object + * + * @apiSuccessExample {json} Result: + * { + * "success": true, + * "data": {} + * } + * + * @apiError {BadRequest} MissingPassword The password was not included in the request + * @apiError {BadRequest} NotAuthorized There is no account that uses those credentials. + * + * @apiErrorExample {json} + * { + * "success": false, + * "error": "BadRequest", + * "message": "Invalid request parameters.", + * "errors": [ + * { + * "message": "Missing password.", + * "param": "password" + * } + * ] + * } + * */ api.deleteUser = { method: 'DELETE', @@ -240,8 +333,17 @@ function _cleanChecklist (task) { * @apiName UserGetAnonymized * @apiGroup User * + * @apiDescription Returns the user's data without: + * Authentication information + * NewMessages/Invitations/Inbox + * Profile + * Purchased information + * Contributor information + * Special items + * Webhooks + * * @apiSuccess {Object} data.user - * @apiSuccess {Array} data.tasks + * @apiSuccess {Object} data.tasks **/ api.getUserAnonymized = { method: 'GET', @@ -306,11 +408,15 @@ const partyMembersFields = 'profile.name stats achievements items.special'; * @apiGroup User * * @apiParam {String=fireball, mpHeal, earth, frost, smash, defensiveStance, valorousPresence, intimidate, pickPocket, backStab, toolsOfTrade, stealth, heal, protectAura, brightness, healAll} spellId The skill to cast. - * @apiParam {UUID} targetId Optional query parameter, the id of the target when casting a skill on a party member or a task + * @apiParam (Body) {UUID} targetId Query parameter, necessary if the spell is cast on a party member or task. Not used if the spell is case on onesself or the user's current party. + * @apiParamExample {json} Query example: + * { + * "targetId":"fd427623-9a69-4aac-9852-13deb9c190c3" + * } * * @apiSuccess data Will return the modified targets. For party members only the necessary fields will be populated. The user is always returned. * - * @apiExample Skill Key to Name Mapping + * @apiDescription Skill Key to Name Mapping * Mage * fireball: "Burst of Flames" * mpHeal: "Ethereal Surge" @@ -335,10 +441,10 @@ const partyMembersFields = 'profile.name stats achievements items.special'; * brightness: "Searing Brightness" * healAll: "Blessing" * + * @apiError (400) {NotAuthorized} Not enough mana. * @apiUse TaskNotFound * @apiUse PartyNotFound * @apiUse UserNotFound - * */ api.castSpell = { method: 'POST', @@ -501,7 +607,15 @@ api.castSpell = { * @apiName UserSleep * @apiGroup User * + * @apiDescription Toggles the sleep key under user preference true and false. + * * @apiSuccess {boolean} data user.preferences.sleep + * + * @apiSuccessExample {json} Return-example + * { + * "success": true, + * "data": false + * } */ api.sleep = { method: 'POST', @@ -516,13 +630,25 @@ api.sleep = { }; /** - * @api {post} /api/v3/user/allocate Allocate an attribute point + * @api {post} /api/v3/user/allocate Allocate a single attribute point * @apiName UserAllocate * @apiGroup User * - * @apiParam {String} stat Query parameter - Defaults to 'str', mast be one of be of str, con, int or per + * @apiParam (Body) {String="str","con","int","per"} stat Query parameter - Default ='str' * - * @apiSuccess {Object} data user.stats + * @apiParamExample {json} Example request + * {"stat":"int"} + * + * @apiSuccess {Object} data Returns stats from the user profile + * + * @apiError {NotAuthorized} NoPoints Not enough attribute points to increment a stat. + * + * @apiErrorExample {json} + * { + * "success": false, + * "error": "NotAuthorized", + * "message": "You don't have enough attribute points." + * } */ api.allocate = { method: 'POST', @@ -538,10 +664,46 @@ api.allocate = { /** * @api {post} /api/v3/user/allocate-now Allocate all attribute points - * @apiDescription Uses the user's chosen automatic allocation method, or if none, assigns all to STR. + * @apiDescription Uses the user's chosen automatic allocation method, or if none, assigns all to STR. Note: will return success, even if there are 0 points to allocate. * @apiName UserAllocateNow * @apiGroup User * + * @apiSuccessExample {json} Success-Response: + * { + * "success": true, + * "data": { + * "hp": 50, + * "mp": 38, + * "exp": 7, + * "gp": 284.8637271160258, + * "lvl": 10, + * "class": "rogue", + * "points": 0, + * "str": 2, + * "con": 2, + * "int": 3, + * "per": 3, + * "buffs": { + * "str": 0, + * "int": 0, + * "per": 0, + * "con": 0, + * "stealth": 0, + * "streaks": false, + * "snowball": false, + * "spookySparkles": false, + * "shinySeed": false, + * "seafoam": false + * }, + * "training": { + * "int": 0, + * "per": 0, + * "str": 0, + * "con": 0 + * } + * } + * } + * * @apiSuccess {Object} data user.stats */ api.allocateNow = { @@ -563,6 +725,27 @@ api.allocateNow = { * @apiGroup User * * @apiParam {String} key The item to buy + * + * @apiSuccess data User's data profile + * @apiSuccess message Item purchased + * + * @apiSuccessExample {json} Purchased a rogue short sword for example: + * { + * "success": true, + * "data": { + * ---TRUNCATED USER RECORD--- + * }, + * "message": "Bought Short Sword" + * } + * + * @apiError (400) {NotAuthorized} messageAlreadyOwnGear Already own equipment + * @apiError (400) {NotAuthorized} messageNotEnoughGold Not enough gold for the purchase + * + * @apiErrorExample {json} NotAuthorized Already own + * {"success":false,"error":"NotAuthorized","message":"You already own that piece of equipment"} + * + * @apiErrorExample {json} NotAuthorized Not enough gold + * {"success":false,"error":"NotAuthorized","message":"Not Enough Gold"} */ api.buy = { method: 'POST', diff --git a/website/server/models/group.js b/website/server/models/group.js index 7a81904d1f..2400243284 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -300,7 +300,7 @@ schema.statics.toJSONCleanChat = function groupToJSONCleanChat (group, user) { * @param res Express res object for use with translations * @throws BadRequest An error describing the issue with the invitations */ -schema.statics.validateInvitations = function getInvitationError (uuids, emails, res) { +schema.statics.validateInvitations = async function getInvitationError (uuids, emails, res, group = null) { let uuidsIsArray = Array.isArray(uuids); let emailsIsArray = Array.isArray(emails); let emptyEmails = emailsIsArray && emails.length < 1; @@ -339,6 +339,27 @@ schema.statics.validateInvitations = function getInvitationError (uuids, emails, if (totalInvites > INVITES_LIMIT) { throw new BadRequest(res.t('canOnlyInviteMaxInvites', {maxInvites: INVITES_LIMIT})); } + + // If party, check the limit of members + if (group && group.type === 'party') { + let memberCount = 0; + + // Counting the members that already joined the party + memberCount += group.memberCount; + + // Count how many invitations currently exist in the party + let query = {}; + query['invitations.party.id'] = group._id; + let groupInvites = await User.count(query).exec(); + memberCount += groupInvites; + + // Counting the members that are going to be invited by email and uuids + memberCount += totalInvites; + + if (memberCount > shared.constants.PARTY_LIMIT_MEMBERS) { + throw new BadRequest(res.t('partyExceedsMembersLimit', {maxMembersParty: shared.constants.PARTY_LIMIT_MEMBERS})); + } + } }; schema.methods.getParticipatingQuestMembers = function getParticipatingQuestMembers () { diff --git a/website/views/options/profile/profile.jade b/website/views/options/profile/profile.jade index efa9bb9679..3e7113eba8 100644 --- a/website/views/options/profile/profile.jade +++ b/website/views/options/profile/profile.jade @@ -1,55 +1,55 @@ -script(id='partials/options.profile.profile.html', type='text/ng-template') - .container-fluid - .row - .col-md-12(ng-show='!_editing.profile') - button.btn.btn-default(ng-click='_editing.profile = true', ng-show='!_editing.profile')= env.t('edit') - h4=env.t('displayName') - span(ng-show='profile.profile.name') {{profile.profile.name}} - p - small.muted=env.t('displayNameDescription1') - |  - a(href='/#/options/settings/settings')=env.t('displayNameDescription2') - |  - =env.t('displayNameDescription3') - span.muted(ng-hide='profile.profile.name') -  - =env.t('none') - |  - - - h4=env.t('displayPhoto') - img.img-rendering-auto(ng-show='profile.profile.imageUrl', ng-src='{{profile.profile.imageUrl}}') - span.muted(ng-hide='profile.profile.imageUrl') -  - =env.t('none') - |  - - - h4=env.t('displayBlurb') - markdown(ng-show='profile.profile.blurb', text='profile.profile.blurb') - span.muted(ng-hide='profile.profile.blurb') -  - =env.t('none') - |  - - //{{profile.profile.blurb | linky:'_blank'}} - .row - .col-md-6 - h4=env.t('totalCheckinsTitle') - span {{env.t('totalCheckins', {count: user.loginIncentives})}} - .col-md-6 - h4 - | {{::getProgressDisplay()}} - .progress - .progress-bar(role='progressbar', aria-valuenow='{{::incentivesProgress()}}', aria-valuemin='0', aria-valuemax='100', style='width: {{::incentivesProgress()}}%;') - span.sr-only {{::incentivesProgress()}}% Complete - - form.col-md-4(ng-show='_editing.profile', ng-submit='save()') - .alert.alert-info.alert-sm - !=env.t("communityGuidelinesWarning") - input.btn.btn-primary(type='submit', value=env.t('save')) - // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak - .form-group - label=env.t('displayName') - input.form-control(type='text', placeholder=env.t('fullName'), ng-model='editingProfile.name') - .form-group - label=env.t('photoUrl') - input.form-control(type='url', ng-model='editingProfile.imageUrl', placeholder=env.t('imageUrl')) - .form-group - label=env.t('displayBlurb') - textarea.form-control(rows=5, placeholder=env.t('displayBlurbPlaceholder'), ng-model='editingProfile.blurb') - include ../../shared/formatting-help +script(id='partials/options.profile.profile.html', type='text/ng-template') + .container-fluid + .row + .col-md-12(ng-show='!_editing.profile') + button.btn.btn-default(ng-click='_editing.profile = true', ng-show='!_editing.profile')= env.t('edit') + h4=env.t('displayName') + span(ng-show='profile.profile.name') {{profile.profile.name}} + p + small.muted=env.t('displayNameDescription1') + |  + a(href='/#/options/settings/settings')=env.t('displayNameDescription2') + |  + =env.t('displayNameDescription3') + span.muted(ng-hide='profile.profile.name') -  + =env.t('none') + |  - + + h4=env.t('displayPhoto') + img.img-rendering-auto(ng-show='profile.profile.imageUrl', ng-src='{{profile.profile.imageUrl}}') + span.muted(ng-hide='profile.profile.imageUrl') -  + =env.t('none') + |  - + + h4=env.t('displayBlurb') + markdown(ng-show='profile.profile.blurb', text='profile.profile.blurb') + span.muted(ng-hide='profile.profile.blurb') -  + =env.t('none') + |  - + //{{profile.profile.blurb | linky:'_blank'}} + .row + .col-md-6 + h4=env.t('totalCheckinsTitle') + span {{env.t('totalCheckins', {count: user.loginIncentives})}} + .col-md-6 + h4 + | {{::getProgressDisplay()}} + .progress + .progress-bar(role='progressbar', aria-valuenow='{{::incentivesProgress()}}', aria-valuemin='0', aria-valuemax='100', style='width: {{::incentivesProgress()}}%;') + span.sr-only {{::incentivesProgress()}}% Complete + + form.col-md-4(ng-show='_editing.profile', ng-submit='save()') + .alert.alert-info.alert-sm + !=env.t("communityGuidelinesWarning", { hrefBlankCommunityManagerEmail : '' + env.EMAILS.COMMUNITY_MANAGER_EMAIL + ''}) + input.btn.btn-primary(type='submit', value=env.t('save')) + // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak + .form-group + label=env.t('displayName') + input.form-control(type='text', placeholder=env.t('fullName'), ng-model='editingProfile.name') + .form-group + label=env.t('photoUrl') + input.form-control(type='url', ng-model='editingProfile.imageUrl', placeholder=env.t('imageUrl')) + .form-group + label=env.t('displayBlurb') + textarea.form-control(rows=5, placeholder=env.t('displayBlurbPlaceholder'), ng-model='editingProfile.blurb') + include ../../shared/formatting-help diff --git a/website/views/options/settings/api.jade b/website/views/options/settings/api.jade index d275c9da27..c14bbdff33 100644 --- a/website/views/options/settings/api.jade +++ b/website/views/options/settings/api.jade @@ -1,57 +1,57 @@ -script(type='text/ng-template', id='partials/options.settings.api.html') - .container-fluid - .row - .col-md-6 - h2=env.t('API') - small=env.t('APIText') - h6=env.t('userId') - pre.prettyprint {{user.id}} - h6=env.t('APIToken') - pre.prettyprint {{User.settings.auth.apiToken}} - small!=env.t("APITokenWarning") - br - h3=env.t('thirdPartyApps') - ul - li - a(target='_blank' href='https://www.beeminder.com/habitica')=env.t('beeminder') - br - =env.t('beeminderDesc') - li - a(target='_blank' href='https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb')=env.t('chromeChatExtension') - br - =env.t('chromeChatExtensionDesc') - li - a(target='_blank' ng-href='http://data.habitrpg.com?uuid={{user._id}}')=env.t('dataTool') - br - =env.t('dataToolDesc') - li - !=env.t('otherExtensions') - br - =env.t('otherDesc') - - hr - - h2=env.t('webhooks') - table.table.table-striped - thead(ng-if='user.webhooks.length') - tr - th=env.t('enabled') - th=env.t('webhookURL') - th - tbody - tr(ng-repeat="webhook in user.webhooks track by $index") - td - input(type='checkbox', ng-model='webhook.enabled', ng-change='saveWebhook(webhook, $index)') - td - input.form-control(type='url', ng-model='webhook.url', ng-change='webhook._editing=true', ui-keyup="{13:'saveWebhook(webhook, $index)'}") - td - span.pull-left(ng-show='webhook._editing') * - a.checklist-icons(ng-click='deleteWebhook(webhook, $index)') - span.glyphicon.glyphicon-trash(tooltip=env.t('delete')) - tr - td(colspan=2) - form.form-horizontal(ng-submit='addWebhook(_newWebhook.url)') - .form-group.col-sm-10 - input.form-control(type='url', ng-model='_newWebhook.url', placeholder=env.t('webhookURL')) - .col-sm-2 - button.btn.btn-sm.btn-primary(type='submit')=env.t('add') +script(type='text/ng-template', id='partials/options.settings.api.html') + .container-fluid + .row + .col-md-6 + h2=env.t('API') + small=env.t('APIText') + h6=env.t('userId') + pre.prettyprint {{user.id}} + h6=env.t('APIToken') + pre.prettyprint {{User.settings.auth.apiToken}} + small!=env.t("APITokenWarning", { hrefTechAssistanceEmail : '' + env.EMAILS.TECH_ASSISTANCE_EMAIL + '' }) + br + h3=env.t('thirdPartyApps') + ul + li + a(target='_blank' href='https://www.beeminder.com/habitica')=env.t('beeminder') + br + =env.t('beeminderDesc') + li + a(target='_blank' href='https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb')=env.t('chromeChatExtension') + br + =env.t('chromeChatExtensionDesc') + li + a(target='_blank' ng-href='http://data.habitrpg.com?uuid={{user._id}}')=env.t('dataTool') + br + =env.t('dataToolDesc') + li + !=env.t('otherExtensions') + br + =env.t('otherDesc') + + hr + + h2=env.t('webhooks') + table.table.table-striped + thead(ng-if='user.webhooks.length') + tr + th=env.t('enabled') + th=env.t('webhookURL') + th + tbody + tr(ng-repeat="webhook in user.webhooks track by $index") + td + input(type='checkbox', ng-model='webhook.enabled', ng-change='saveWebhook(webhook, $index)') + td + input.form-control(type='url', ng-model='webhook.url', ng-change='webhook._editing=true', ui-keyup="{13:'saveWebhook(webhook, $index)'}") + td + span.pull-left(ng-show='webhook._editing') * + a.checklist-icons(ng-click='deleteWebhook(webhook, $index)') + span.glyphicon.glyphicon-trash(tooltip=env.t('delete')) + tr + td(colspan=2) + form.form-horizontal(ng-submit='addWebhook(_newWebhook.url)') + .form-group.col-sm-10 + input.form-control(type='url', ng-model='_newWebhook.url', placeholder=env.t('webhookURL')) + .col-sm-2 + button.btn.btn-sm.btn-primary(type='submit')=env.t('add') diff --git a/website/views/options/social/group.jade b/website/views/options/social/group.jade index d782b1740a..fc2e82398b 100644 --- a/website/views/options/social/group.jade +++ b/website/views/options/social/group.jade @@ -87,7 +87,9 @@ a.pull-right.gem-wallet(ng-if='group.type!="party"', popover-trigger='mouseenter h3.panel-title =env.t('members') span(ng-if='group.type=="party" && (group.onlineUsers || group.onlineUsers == 0)')= ' (' + env.t('onlineCount', {count: "{{group.onlineUsers}}"}) + ')' - button.pull-right.btn.btn-primary(ng-click="inviteOrStartParty(group)")=env.t("inviteFriends") + button.pull-right.btn.btn-primary(ng-if='group.type=="party" ? (group.memberCount + group.invites.length < PARTY_LIMIT_MEMBERS) : true' ng-click="inviteOrStartParty(group)")=env.t("inviteFriends") + .panel-heading(ng-if='group.type=="party"') + p=env.t('partyMembersInfo', {memberCount: "{{group.memberCount}}", invitationCount:"{{group.invites.length}}", limitMembers:"{{PARTY_LIMIT_MEMBERS}}"}) .panel-body.modal-fixed-height h4(ng-show='::group.memberCount === 1 && group.type === "party"')=env.t('partyEmpty') diff --git a/website/views/shared/footer.jade b/website/views/shared/footer.jade index aec92fc3c3..7e5b5acc90 100644 --- a/website/views/shared/footer.jade +++ b/website/views/shared/footer.jade @@ -36,6 +36,8 @@ footer.footer(ng-controller='FooterCtrl') a(href='/static/privacy')=env.t('companyPrivacy') li a(href='/static/terms')=env.t('companyTerms') + li + a(href='/static/press-kit')=env.t('presskit') li a(href='/static/contact')=env.t('contactUs') li diff --git a/website/views/shared/modals/index.jade b/website/views/shared/modals/index.jade index 83d434351e..afd31bb60e 100644 --- a/website/views/shared/modals/index.jade +++ b/website/views/shared/modals/index.jade @@ -26,6 +26,7 @@ include ./login-incentives-reward-unlocked.jade include ./generic.jade include ./tasks-edit.jade include ./task-notes.jade +include ./task-extra-notes.jade //- Settings script(type='text/ng-template', id='modals/change-day-start.html') diff --git a/website/views/shared/modals/members.jade b/website/views/shared/modals/members.jade index bd45fa87d6..1e761661af 100644 --- a/website/views/shared/modals/members.jade +++ b/website/views/shared/modals/members.jade @@ -79,6 +79,9 @@ script(type='text/ng-template', id='modals/send-gift.html') .btn-group a.btn.btn-default(ng-class="{active:gift.gems.fromBalance}", ng-click="gift.gems.fromBalance=true")=env.t('sendGiftFromBalance') a.btn.btn-default(ng-class="{active:!gift.gems.fromBalance}", ng-click="gift.gems.fromBalance=false")=env.t('sendGiftPurchase') + .row + .col-md-12 + p.small.muted!=env.t('gemGiftsAreOptional', { hrefTechAssistanceEmail : '' + env.EMAILS.TECH_ASSISTANCE_EMAIL + ''}) .panel.panel-default(class="{{gift.type=='subscription' ? 'panel-primary' : 'transparent'}}", ng-click='gift.type="subscription"') .panel-heading=env.t('subscription') diff --git a/website/views/shared/modals/task-extra-notes.jade b/website/views/shared/modals/task-extra-notes.jade new file mode 100644 index 0000000000..330623a068 --- /dev/null +++ b/website/views/shared/modals/task-extra-notes.jade @@ -0,0 +1,10 @@ +script(id='modals/task-extra-notes.html', type='text/ng-template') + .modal-header + h4=env.t('taskNotes') + + .modal-body + div + markdown(text='task.notes') + + .modal-footer + .btn.btn-primary(ng-click="$close()")=env.t('close') diff --git a/website/views/shared/tasks/meta_controls.jade b/website/views/shared/tasks/meta_controls.jade index 6cfd07586d..61828a814d 100644 --- a/website/views/shared/tasks/meta_controls.jade +++ b/website/views/shared/tasks/meta_controls.jade @@ -4,14 +4,14 @@ span(ng-if='showDoubleTaskCounter(task, obj)') span(tooltip=env.t('habitCounterUp')) +{{task.counterUp}}| span(tooltip=env.t('habitCounterDown')) -{{task.counterDown}}  - + span(ng-if='showSingleTaskCounter(task, obj)') span(tooltip=env.t('habitCounter')) {{task.up ? task.counterUp : task.counterDown}}  - + // Due Date span(ng-if='task.type=="todo" && task.date') span(ng-class='{"label label-danger":(moment(task.date).isBefore(_today, "days") && !task.completed)}') {{task.date | date:(user.preferences.dateFormat.indexOf('yyyy') == 0 ? user.preferences.dateFormat.substr(5) : user.preferences.dateFormat.substr(0,5))}} - + // Approval requested |   span(ng-show='task.group.approval.requested && !task.group.approval.approved') @@ -29,7 +29,7 @@ // Icons only available if you own the tasks (aka, hidden from challenge stats) span(ng-if='!obj._locked') group-task-meta-actions(ng-if="!obj.auth && obj.purchased && obj.purchased.active", task='task', group='obj') - + a(ng-click='pushTask(task,$index,"top")', tooltip=env.t('pushTaskToTop'), ng-class="{'push-down': ctrlPressed}") span(ng-hide="ctrlPressed").glyphicon.glyphicon-open span(ng-show="ctrlPressed").glyphicon.glyphicon-save @@ -39,13 +39,13 @@ a.badge(ng-if='task.checklist[0]', ng-class='{"badge-success":checklistCompletion(task.checklist) == task.checklist.length}', ng-click='collapseChecklist(task)', tooltip=env.t('expandCollapse')) |{{checklistCompletion(task.checklist)}}/{{task.checklist.length}} span.glyphicon.glyphicon-tags(tooltip='{{Shared.appliedTags(user.tags, task.tags)}}', ng-hide='Shared.noTags(task.tags)') - + // edit a(ng-hide='checkGroupAccess && !checkGroupAccess(obj)', ng-click='editTask(task, user, Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main))', tooltip=env.t('edit')) |   span.glyphicon.glyphicon-pencil |   - + //challenges span(ng-if='task.challenge.id') span(ng-if='task.challenge.broken') @@ -54,7 +54,7 @@ span(ng-if='!task.challenge.broken') span.glyphicon.glyphicon-bullhorn(tooltip=env.t('challenge')) |   - + // delete a(ng-if='!task.challenge.id || (obj.leader && obj.leader.id === user._id)', ng-hide="(checkGroupAccess && !checkGroupAccess(obj))" ng-click='removeTask(task, obj)', tooltip=env.t('delete')) span.glyphicon.glyphicon-trash @@ -67,6 +67,6 @@ // notes // Make this icon available regardless of task ownership - a.task-notes(ng-show='task.notes && !task._editing', ng-click='task.popoverOpen = !task.popoverOpen', popover-trigger='click', data-popover-html="{{task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}') + a.task-notes(ng-show='task.notes && !task._editing', ng-click='showNoteDetails(task);', popover-trigger='hover', data-popover-html="{{task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}') span.glyphicon.glyphicon-comment |   diff --git a/website/views/static/community-guidelines.jade b/website/views/static/community-guidelines.jade index e9f535b170..9356259e27 100644 --- a/website/views/static/community-guidelines.jade +++ b/website/views/static/community-guidelines.jade @@ -28,8 +28,8 @@ block content p.pagemeta =env.t('lastUpdated') |  - =env.t('February') - | 28, 2016 + =env.t('March') + | 30, 2017 h2#welcome=env.t('commGuideHeadingWelcome') .clearfix img.pull-left(src='/community-guidelines-images/intro.png', alt='')