Compare commits
154 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79f83d87d0 | |||
| c9bf157c23 | |||
| e54425f947 | |||
| d953ea14da | |||
| 0c179fee2f | |||
| 05e229ccb0 | |||
| b29d937806 | |||
| 670b6a1563 | |||
| 08f1e2b273 | |||
| ca80f4ee33 | |||
| 65cbee9e75 | |||
| 0f8563c14e | |||
| c4117f99ed | |||
| 27aca19c8c | |||
| 80c18ffadd | |||
| bf2c4eb501 | |||
| ab1828c914 | |||
| b32f79f682 | |||
| 7b69289069 | |||
| a1fb80868f | |||
| 9d4fb80d15 | |||
| 43392f4952 | |||
| 6e46794822 | |||
| 43cad86201 | |||
| 734eae64a5 | |||
| 032c95d5c8 | |||
| b40411e219 | |||
| 86410f6bb7 | |||
| 8d2ada1463 | |||
| 95a3c932c5 | |||
| 51d1f6b86a | |||
| 809bacd10b | |||
| b0f29211a8 | |||
| 26f5bf554e | |||
| a1ec42c0b2 | |||
| 8674ea55f9 | |||
| c421da34cc | |||
| fb79b9e128 | |||
| 375b6719e9 | |||
| c9bed96077 | |||
| 1ccff7f1dd | |||
| 36461cbbdf | |||
| 427f73f664 | |||
| d796848887 | |||
| 80a2e31c8e | |||
| 85d290a1fa | |||
| 1bc756ee93 | |||
| ea44af0929 | |||
| 739963762e | |||
| b02ae35b28 | |||
| ace8e2f0bd | |||
| e90175b5d6 | |||
| 403fa18511 | |||
| 7dd6227845 | |||
| 4c7306491b | |||
| 1164f5e5f5 | |||
| c6937a0409 | |||
| 092d6726b8 | |||
| 2a67de698b | |||
| cfc8620865 | |||
| 714a18ce5c | |||
| 41e22640f5 | |||
| 8747a2d1b6 | |||
| 721ae0872f | |||
| 6658abbcd9 | |||
| 68099626eb | |||
| ff9780c5e5 | |||
| 56aaca5c0c | |||
| c22a2ef9a8 | |||
| a3ba1d19ee | |||
| 3c5a7b65c5 | |||
| 1ebe57b114 | |||
| c218b8d56c | |||
| ef99943646 | |||
| 29f6bf7dc6 | |||
| f7af8ec910 | |||
| f4ba6b2186 | |||
| a3b59d9254 | |||
| e813428472 | |||
| db0009ebad | |||
| be622e8b10 | |||
| a7c3c10ff4 | |||
| 1831c0dd79 | |||
| 8fe563aa37 | |||
| e5f1f3b279 | |||
| 446122d7b8 | |||
| 93335352ec | |||
| 6e24cf0fe1 | |||
| 378325a8a2 | |||
| f60b50d6fa | |||
| 785da1391f | |||
| adff828c91 | |||
| 5cdcbc5310 | |||
| 84a52002c8 | |||
| 671c90a593 | |||
| 261da70274 | |||
| c87803caca | |||
| c1705550c7 | |||
| 119102ff61 | |||
| 933fc4d882 | |||
| 31a83097be | |||
| 6cdc59d913 | |||
| ca4efa21cf | |||
| aeba14f2e9 | |||
| 1c94c1a968 | |||
| 26767f598b | |||
| 5d202c7617 | |||
| 643d3802cc | |||
| 5ee33f219a | |||
| 4e93874483 | |||
| 8bf44ce47a | |||
| 458bde1d13 | |||
| 6899731937 | |||
| 3101abbb08 | |||
| 537313a21e | |||
| 453383af9f | |||
| a19db5798d | |||
| ea1569e23e | |||
| 58aa1ac2f3 | |||
| a979fc3843 | |||
| 9f91775e78 | |||
| 61ca931e66 | |||
| 2888f843e3 | |||
| b947c714f0 | |||
| 783b8995b8 | |||
| 8db2fb8015 | |||
| 1bcf2dfe80 | |||
| 805641b6cf | |||
| 5b0584fc5e | |||
| 99429d9d48 | |||
| ec5de91123 | |||
| 6ffc28f04e | |||
| b1a348aee3 | |||
| 66ed0a350b | |||
| 6b2e9f16e2 | |||
| 7f6a2a0700 | |||
| 05008b20d3 | |||
| 6cae168adb | |||
| 72a9506b9f | |||
| af96cd0488 | |||
| 60204bef06 | |||
| 4c21d9e560 | |||
| fa38b22003 | |||
| be86812900 | |||
| d03e5e93b0 | |||
| c879560445 | |||
| dc9800d88a | |||
| 39fcb3e876 | |||
| 188023b197 | |||
| e47b0982c8 | |||
| 92f217775b | |||
| daf2c354d6 | |||
| 2ba6e972c3 | |||
| 6bacb89271 |
@@ -10,6 +10,7 @@ dist/
|
||||
dist-client/
|
||||
apidoc_build/
|
||||
content_cache/
|
||||
i18n_cache/
|
||||
node_modules/
|
||||
|
||||
# Old migrations, disabled
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
# Requesting a feature
|
||||
|
||||
Habitica uses [Trello](https://trello.com/b/EpoYEYod/habitica) to track feature requests. [Read more](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents).
|
||||
Habitica uses [this Google form](https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link) to track feature requests. Please post there rather than creating an issue.
|
||||
|
||||
# Contributing Code
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ website/transpiled-babel/
|
||||
website/common/transpiled-babel/
|
||||
node_modules
|
||||
content_cache
|
||||
i18n_cache
|
||||
apidoc_build
|
||||
*.swp
|
||||
.idea*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
* Code is GPL v3 licensed:
|
||||
This Source Code is subject to the terms of the GNU General Public License, v. 3.0.
|
||||
If a copy of the GPL was not distributed with this file, You can obtain one at http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
If a copy of the GPL was not distributed with this file, you can obtain one at http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
|
||||
* Assets and content designed for Mozilla BrowserQuest are licensed under CC-BY-SA 3.0:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
@@ -79,5 +79,6 @@
|
||||
"APPLE_TEAM_ID": "",
|
||||
"APPLE_AUTH_CLIENT_ID": "",
|
||||
"APPLE_AUTH_KEY_ID": "",
|
||||
"BLOCKED_IPS": ""
|
||||
"BLOCKED_IPS": "",
|
||||
"LOG_AMPLITUDE_EVENTS": "false"
|
||||
}
|
||||
|
||||
@@ -11,10 +11,16 @@ gulp.task('build:babel:common', () => gulp.src('website/common/script/**/*.js')
|
||||
|
||||
gulp.task('build:babel', gulp.parallel('build:babel:server', 'build:babel:common', done => done()));
|
||||
|
||||
gulp.task('build:cache', gulp.parallel(
|
||||
'cache:content',
|
||||
'cache:i18n',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
gulp.task('build:prod', gulp.series(
|
||||
'build:babel',
|
||||
'apidoc',
|
||||
'content:cache',
|
||||
'build:cache',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import gulp from 'gulp';
|
||||
import fs from 'fs';
|
||||
|
||||
// TODO parallelize, use gulp file helpers
|
||||
gulp.task('content:cache', done => {
|
||||
gulp.task('cache:content', done => {
|
||||
// Requiring at runtime because these files access `common`
|
||||
// code which in production works only if transpiled so after
|
||||
// gulp build:babel:common has run
|
||||
@@ -32,3 +32,32 @@ gulp.task('content:cache', done => {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('cache:i18n', done => {
|
||||
// Requiring at runtime because these files access `common`
|
||||
// code which in production works only if transpiled so after
|
||||
// gulp build:babel:common has run
|
||||
const { BROWSER_SCRIPT_CACHE_PATH, geti18nBrowserScript } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
|
||||
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
|
||||
|
||||
try {
|
||||
// create the cache folder (if it doesn't exist)
|
||||
try {
|
||||
fs.mkdirSync(BROWSER_SCRIPT_CACHE_PATH);
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
}
|
||||
|
||||
// create and save the i18n browser script for each language
|
||||
langCodes.forEach(languageCode => {
|
||||
fs.writeFileSync(
|
||||
`${BROWSER_SCRIPT_CACHE_PATH}${languageCode}.js`,
|
||||
geti18nBrowserScript(languageCode),
|
||||
'utf8',
|
||||
);
|
||||
});
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
@@ -161,4 +161,4 @@ gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprite
|
||||
done();
|
||||
}));
|
||||
|
||||
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions', done => done()));
|
||||
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:checkCompiledDimensions', done => done()));
|
||||
|
||||
@@ -13,11 +13,11 @@ const gulp = require('gulp');
|
||||
|
||||
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
|
||||
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-content'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-cache'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-build'); // eslint-disable-line global-require
|
||||
} else {
|
||||
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-content'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-cache'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-build'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-console'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-sprites'); // eslint-disable-line global-require
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"version": "4.140.9",
|
||||
"version": "4.143.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -13,28 +13,28 @@
|
||||
}
|
||||
},
|
||||
"@babel/compat-data": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz",
|
||||
"integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz",
|
||||
"integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==",
|
||||
"requires": {
|
||||
"browserslist": "^4.9.1",
|
||||
"browserslist": "^4.11.1",
|
||||
"invariant": "^2.2.4",
|
||||
"semver": "^5.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz",
|
||||
"integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz",
|
||||
"integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@babel/generator": "^7.9.0",
|
||||
"@babel/generator": "^7.9.6",
|
||||
"@babel/helper-module-transforms": "^7.9.0",
|
||||
"@babel/helpers": "^7.9.0",
|
||||
"@babel/parser": "^7.9.0",
|
||||
"@babel/helpers": "^7.9.6",
|
||||
"@babel/parser": "^7.9.6",
|
||||
"@babel/template": "^7.8.6",
|
||||
"@babel/traverse": "^7.9.0",
|
||||
"@babel/types": "^7.9.0",
|
||||
"@babel/traverse": "^7.9.6",
|
||||
"@babel/types": "^7.9.6",
|
||||
"convert-source-map": "^1.7.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.1",
|
||||
@@ -54,28 +54,24 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz",
|
||||
"integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
|
||||
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.9.0",
|
||||
"@babel/types": "^7.9.6",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-module-transforms": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz",
|
||||
"integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==",
|
||||
"@babel/helper-function-name": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
|
||||
"integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
|
||||
"requires": {
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/helper-replace-supers": "^7.8.6",
|
||||
"@babel/helper-simple-access": "^7.8.3",
|
||||
"@babel/helper-split-export-declaration": "^7.8.3",
|
||||
"@babel/template": "^7.8.6",
|
||||
"@babel/types": "^7.9.0",
|
||||
"lodash": "^4.17.13"
|
||||
"@babel/helper-get-function-arity": "^7.8.3",
|
||||
"@babel/template": "^7.8.3",
|
||||
"@babel/types": "^7.9.5"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
@@ -89,9 +85,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz",
|
||||
"integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A=="
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
|
||||
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q=="
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.8.6",
|
||||
@@ -104,29 +100,36 @@
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz",
|
||||
"integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
|
||||
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@babel/generator": "^7.9.0",
|
||||
"@babel/helper-function-name": "^7.8.3",
|
||||
"@babel/generator": "^7.9.6",
|
||||
"@babel/helper-function-name": "^7.9.5",
|
||||
"@babel/helper-split-export-declaration": "^7.8.3",
|
||||
"@babel/parser": "^7.9.0",
|
||||
"@babel/types": "^7.9.0",
|
||||
"@babel/parser": "^7.9.6",
|
||||
"@babel/types": "^7.9.6",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz",
|
||||
"integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.0",
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
@@ -150,11 +153,11 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz",
|
||||
"integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
|
||||
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.9.5",
|
||||
"@babel/types": "^7.9.6",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
@@ -166,9 +169,9 @@
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
|
||||
"integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
@@ -195,12 +198,12 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-compilation-targets": {
|
||||
"version": "7.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz",
|
||||
"integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz",
|
||||
"integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==",
|
||||
"requires": {
|
||||
"@babel/compat-data": "^7.8.6",
|
||||
"browserslist": "^4.9.1",
|
||||
"@babel/compat-data": "^7.9.6",
|
||||
"browserslist": "^4.11.1",
|
||||
"invariant": "^2.2.4",
|
||||
"levenary": "^1.1.1",
|
||||
"semver": "^5.5.0"
|
||||
@@ -503,13 +506,13 @@
|
||||
}
|
||||
},
|
||||
"@babel/helpers": {
|
||||
"version": "7.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz",
|
||||
"integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz",
|
||||
"integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==",
|
||||
"requires": {
|
||||
"@babel/template": "^7.8.3",
|
||||
"@babel/traverse": "^7.9.0",
|
||||
"@babel/types": "^7.9.0"
|
||||
"@babel/traverse": "^7.9.6",
|
||||
"@babel/types": "^7.9.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
@@ -521,16 +524,26 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz",
|
||||
"integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
|
||||
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.9.0",
|
||||
"@babel/types": "^7.9.6",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
|
||||
"integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
|
||||
"requires": {
|
||||
"@babel/helper-get-function-arity": "^7.8.3",
|
||||
"@babel/template": "^7.8.3",
|
||||
"@babel/types": "^7.9.5"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
|
||||
@@ -542,34 +555,41 @@
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz",
|
||||
"integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A=="
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
|
||||
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q=="
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz",
|
||||
"integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
|
||||
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@babel/generator": "^7.9.0",
|
||||
"@babel/helper-function-name": "^7.8.3",
|
||||
"@babel/generator": "^7.9.6",
|
||||
"@babel/helper-function-name": "^7.9.5",
|
||||
"@babel/helper-split-export-declaration": "^7.8.3",
|
||||
"@babel/parser": "^7.9.0",
|
||||
"@babel/types": "^7.9.0",
|
||||
"@babel/parser": "^7.9.6",
|
||||
"@babel/types": "^7.9.6",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz",
|
||||
"integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.0",
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
@@ -658,9 +678,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-object-rest-spread": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz",
|
||||
"integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz",
|
||||
"integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
|
||||
@@ -832,9 +852,9 @@
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
|
||||
"integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
@@ -919,35 +939,35 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-amd": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz",
|
||||
"integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz",
|
||||
"integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==",
|
||||
"requires": {
|
||||
"@babel/helper-module-transforms": "^7.9.0",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0"
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-commonjs": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz",
|
||||
"integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz",
|
||||
"integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==",
|
||||
"requires": {
|
||||
"@babel/helper-module-transforms": "^7.9.0",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/helper-simple-access": "^7.8.3",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0"
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-systemjs": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz",
|
||||
"integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz",
|
||||
"integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==",
|
||||
"requires": {
|
||||
"@babel/helper-hoist-variables": "^7.8.3",
|
||||
"@babel/helper-module-transforms": "^7.9.0",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0"
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-umd": {
|
||||
@@ -1069,12 +1089,12 @@
|
||||
}
|
||||
},
|
||||
"@babel/preset-env": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.5.tgz",
|
||||
"integrity": "sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz",
|
||||
"integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==",
|
||||
"requires": {
|
||||
"@babel/compat-data": "^7.9.0",
|
||||
"@babel/helper-compilation-targets": "^7.8.7",
|
||||
"@babel/compat-data": "^7.9.6",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/plugin-proposal-async-generator-functions": "^7.8.3",
|
||||
@@ -1082,7 +1102,7 @@
|
||||
"@babel/plugin-proposal-json-strings": "^7.8.3",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.8.3",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.9.5",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.9.6",
|
||||
"@babel/plugin-proposal-optional-catch-binding": "^7.8.3",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||
"@babel/plugin-proposal-unicode-property-regex": "^7.8.3",
|
||||
@@ -1109,9 +1129,9 @@
|
||||
"@babel/plugin-transform-function-name": "^7.8.3",
|
||||
"@babel/plugin-transform-literals": "^7.8.3",
|
||||
"@babel/plugin-transform-member-expression-literals": "^7.8.3",
|
||||
"@babel/plugin-transform-modules-amd": "^7.9.0",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.9.0",
|
||||
"@babel/plugin-transform-modules-amd": "^7.9.6",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.9.6",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.9.6",
|
||||
"@babel/plugin-transform-modules-umd": "^7.9.0",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
|
||||
"@babel/plugin-transform-new-target": "^7.8.3",
|
||||
@@ -1127,8 +1147,8 @@
|
||||
"@babel/plugin-transform-typeof-symbol": "^7.8.4",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.8.3",
|
||||
"@babel/preset-modules": "^0.1.3",
|
||||
"@babel/types": "^7.9.5",
|
||||
"browserslist": "^4.9.1",
|
||||
"@babel/types": "^7.9.6",
|
||||
"browserslist": "^4.11.1",
|
||||
"core-js-compat": "^3.6.2",
|
||||
"invariant": "^2.2.2",
|
||||
"levenary": "^1.1.1",
|
||||
@@ -1141,9 +1161,9 @@
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
|
||||
"integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
@@ -1177,9 +1197,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
|
||||
"integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
|
||||
"integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
@@ -1227,16 +1247,16 @@
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz",
|
||||
"integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
|
||||
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@babel/generator": "^7.9.5",
|
||||
"@babel/generator": "^7.9.6",
|
||||
"@babel/helper-function-name": "^7.9.5",
|
||||
"@babel/helper-split-export-declaration": "^7.8.3",
|
||||
"@babel/parser": "^7.9.0",
|
||||
"@babel/types": "^7.9.5",
|
||||
"@babel/parser": "^7.9.6",
|
||||
"@babel/types": "^7.9.6",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
@@ -1271,14 +1291,14 @@
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz",
|
||||
"integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA=="
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
|
||||
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
|
||||
"integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
|
||||
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.5",
|
||||
"lodash": "^4.17.13",
|
||||
@@ -2170,9 +2190,9 @@
|
||||
}
|
||||
},
|
||||
"apple-auth": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/apple-auth/-/apple-auth-1.0.5.tgz",
|
||||
"integrity": "sha512-EbMm0rqWyUANxHJfiNGrvLkS3acdBfAj0TJ1hnA/jxq7+l9GTd2br5ajgjBjcHT5bbN6CsvuZFAdYofzn1J/6A==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/apple-auth/-/apple-auth-1.0.6.tgz",
|
||||
"integrity": "sha512-dICsYIHBTX+7/1xdJZ4y4U08zOxEnL67GQ77l/HSKqEx9uC1wsY5dNjgbZf2F/1QnzAxDbAAHo0DgUCrA1k7zQ==",
|
||||
"requires": {
|
||||
"axios": "^0.19.0",
|
||||
"express": "^4.17.1",
|
||||
@@ -2543,9 +2563,9 @@
|
||||
}
|
||||
},
|
||||
"babel-plugin-dynamic-import-node": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
|
||||
"integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==",
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
|
||||
"integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
|
||||
"requires": {
|
||||
"object.assign": "^4.1.0"
|
||||
}
|
||||
@@ -3207,20 +3227,20 @@
|
||||
"dev": true
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.11.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz",
|
||||
"integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==",
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
|
||||
"integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001038",
|
||||
"electron-to-chromium": "^1.3.390",
|
||||
"caniuse-lite": "^1.0.30001043",
|
||||
"electron-to-chromium": "^1.3.413",
|
||||
"node-releases": "^1.1.53",
|
||||
"pkg-up": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
|
||||
"integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg=="
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
|
||||
"integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q=="
|
||||
},
|
||||
"buffer-alloc": {
|
||||
"version": "1.2.0",
|
||||
@@ -3370,9 +3390,9 @@
|
||||
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001041",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz",
|
||||
"integrity": "sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA=="
|
||||
"version": "1.0.30001050",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001050.tgz",
|
||||
"integrity": "sha512-OvGZqalCwmapci76ISq5q4kuAskb1ebqF3FEQBv1LE1kWht0pojlDDqzFlmk5jgYkuZN7MNZ1n+ULwe/7MaDNQ=="
|
||||
},
|
||||
"capture-stack-trace": {
|
||||
"version": "1.0.1",
|
||||
@@ -4139,9 +4159,9 @@
|
||||
}
|
||||
},
|
||||
"csv-stringify": {
|
||||
"version": "5.3.6",
|
||||
"resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.3.6.tgz",
|
||||
"integrity": "sha512-kPcRbMvo5NLLD71TAqW5K+g9kbM2HpIZJLAzm73Du8U+5TXmDp9YtXKCBLyxEh0q3Jbg8QhNFBz3b5VJzjZ/jw=="
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.5.0.tgz",
|
||||
"integrity": "sha512-G05575DSO/9vFzQxZN+Srh30cNyHk0SM0ePyiTChMD5WVt7GMTVPBQf4rtgMF6mqhNCJUPw4pN8LDe8MF9EYOA=="
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
@@ -4788,9 +4808,9 @@
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.403",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.403.tgz",
|
||||
"integrity": "sha512-JaoxV4RzdBAZOnsF4dAlZ2ijJW72MbqO5lNfOBHUWiBQl3Rwe+mk2RCUMrRI3rSClLJ8HSNQNqcry12H+0ZjFw=="
|
||||
"version": "1.3.427",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz",
|
||||
"integrity": "sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A=="
|
||||
},
|
||||
"emitter-listener": {
|
||||
"version": "1.1.2",
|
||||
@@ -7359,14 +7379,33 @@
|
||||
}
|
||||
},
|
||||
"habitica-markdown": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-1.3.2.tgz",
|
||||
"integrity": "sha512-IyiS583DfqE+KvW4NQAB4K2HjJZ1oF50L0EDz7KaixyK7C41s47wsbN81QtNMB8LnRqbMHFDesD2xEzdicjFXw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-2.0.0.tgz",
|
||||
"integrity": "sha512-70Kl/d7v1d2Rz6TFkQQ9hYcBYGAHnIPbRgS3PrW/dD/GGpN42q6gT3sCLsIpLqEXbN0EWjVscGs2qKWYLc6BMQ==",
|
||||
"requires": {
|
||||
"habitica-markdown-emoji": "1.2.4",
|
||||
"markdown-it": "8.4.2",
|
||||
"markdown-it-link-attributes": "1.0.0",
|
||||
"markdown-it": "10.0.0",
|
||||
"markdown-it-link-attributes": "3.0.0",
|
||||
"markdown-it-linkify-images": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
|
||||
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"habitica-markdown-emoji": {
|
||||
@@ -8724,9 +8763,9 @@
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz",
|
||||
"integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
|
||||
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
},
|
||||
@@ -9245,9 +9284,9 @@
|
||||
"integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw="
|
||||
},
|
||||
"markdown-it-link-attributes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-1.0.0.tgz",
|
||||
"integrity": "sha1-jaHKFynw+hbGVhWwsQdbecg3Gi4="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.0.tgz",
|
||||
"integrity": "sha512-B34ySxVeo6MuEGSPCWyIYryuXINOvngNZL87Mp7YYfKIf6DcD837+lXA8mo6EBbauKsnGz22ZH0zsbOiQRWTNg=="
|
||||
},
|
||||
"markdown-it-linkify-images": {
|
||||
"version": "1.1.1",
|
||||
@@ -9639,9 +9678,9 @@
|
||||
"integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
|
||||
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
|
||||
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
|
||||
},
|
||||
"moment-recur": {
|
||||
"version": "1.0.7",
|
||||
@@ -9652,10 +9691,9 @@
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.5.6",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.6.tgz",
|
||||
"integrity": "sha512-sh3q3GLDLT4QmoDLamxtAECwC3RGjq+oNuK1ENV8+tnipIavss6sMYt77hpygqlMOCt0Sla5cl7H4SKCVBCGEg==",
|
||||
"dev": true,
|
||||
"version": "3.5.7",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.7.tgz",
|
||||
"integrity": "sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ==",
|
||||
"requires": {
|
||||
"bl": "^2.2.0",
|
||||
"bson": "^1.1.4",
|
||||
@@ -9669,28 +9707,21 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
|
||||
"integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
|
||||
"integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mongoose": {
|
||||
"version": "5.9.9",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.9.tgz",
|
||||
"integrity": "sha512-pLkIkM7XQwfbQ+xK1l57Zv0DYPH190/I6Cv5+PbJGfAU0HvX0atMlp+vly8zcjNTEvTkVM80qA5eBYBvZyLYXw==",
|
||||
"version": "5.9.15",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.15.tgz",
|
||||
"integrity": "sha512-dGIDqaQkAJoLl7lsRLy70mDg+VcL1IPOHr/0f23MLF45PtnM5exRdmienfyVjdrSVGgTus+1sMUKef6vSnrDZg==",
|
||||
"requires": {
|
||||
"bson": "~1.1.1",
|
||||
"bson": "^1.1.4",
|
||||
"kareem": "2.3.1",
|
||||
"mongodb": "3.5.5",
|
||||
"mongodb": "3.5.7",
|
||||
"mongoose-legacy-pluralize": "1.0.2",
|
||||
"mpath": "0.7.0",
|
||||
"mquery": "3.2.2",
|
||||
@@ -9699,30 +9730,6 @@
|
||||
"safe-buffer": "5.1.2",
|
||||
"sift": "7.0.1",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
|
||||
"integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.5.tgz",
|
||||
"integrity": "sha512-GCjDxR3UOltDq00Zcpzql6dQo1sVry60OXJY3TDmFc2SWFY6c8Gn1Ardidc5jDirvJrx2GC3knGOImKphbSL3A==",
|
||||
"requires": {
|
||||
"bl": "^2.2.0",
|
||||
"bson": "^1.1.1",
|
||||
"denque": "^1.4.1",
|
||||
"require_optional": "^1.0.1",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"saslprep": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mongoose-legacy-pluralize": {
|
||||
@@ -9731,9 +9738,9 @@
|
||||
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
||||
},
|
||||
"monk": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/monk/-/monk-7.2.0.tgz",
|
||||
"integrity": "sha512-PdCTlPhmUH5ULg80CS0Dgn9LQ7omldNQg+kVn7wtQF1cA/me/Kd5YmiRDxUeTUukpNFkrM3qEYP5oC5AqVjSgw==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/monk/-/monk-7.3.0.tgz",
|
||||
"integrity": "sha512-WqyCLjz32Q3OybOT+fleYHRz5DuG5/E0XKWvrmlHt0vPzTrNZ/BRQ+f2vzWi4apethuvblGTKsOtuDciM018dQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "*",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.140.9",
|
||||
"version": "4.143.1",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/preset-env": "^7.9.5",
|
||||
"@babel/core": "^7.9.6",
|
||||
"@babel/preset-env": "^7.9.6",
|
||||
"@babel/register": "^7.9.0",
|
||||
"@google-cloud/trace-agent": "^4.2.5",
|
||||
"@slack/client": "^4.12.0",
|
||||
@@ -14,13 +14,13 @@
|
||||
"amplitude": "^3.5.0",
|
||||
"apidoc": "^0.17.5",
|
||||
"apn": "^2.2.0",
|
||||
"apple-auth": "^1.0.5",
|
||||
"apple-auth": "^1.0.6",
|
||||
"bcrypt": "^3.0.8",
|
||||
"body-parser": "^1.18.3",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-session": "^1.4.0",
|
||||
"coupon-code": "^0.4.5",
|
||||
"csv-stringify": "^5.3.6",
|
||||
"csv-stringify": "^5.5.0",
|
||||
"cwait": "^1.1.1",
|
||||
"domain-middleware": "~0.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
@@ -36,7 +36,7 @@
|
||||
"gulp-imagemin": "^6.2.0",
|
||||
"gulp-nodemon": "^2.5.0",
|
||||
"gulp.spritesmith": "^6.9.0",
|
||||
"habitica-markdown": "^1.3.2",
|
||||
"habitica-markdown": "^2.0.0",
|
||||
"helmet": "^3.22.0",
|
||||
"image-size": "^0.8.3",
|
||||
"in-app-purchase": "^1.11.3",
|
||||
@@ -46,9 +46,9 @@
|
||||
"lodash": "^4.17.15",
|
||||
"merge-stream": "^2.0.0",
|
||||
"method-override": "^3.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment": "^2.26.0",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.9.9",
|
||||
"mongoose": "^5.9.15",
|
||||
"morgan": "^1.10.0",
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.2",
|
||||
@@ -100,6 +100,7 @@
|
||||
"client:build": "cd website/client && npm run build",
|
||||
"client:unit": "cd website/client && npm run test:unit",
|
||||
"start": "gulp nodemon",
|
||||
"debug": "gulp nodemon --inspect",
|
||||
"postinstall": "gulp build && cd website/client && npm install",
|
||||
"apidoc": "gulp apidoc"
|
||||
},
|
||||
@@ -111,7 +112,7 @@
|
||||
"expect.js": "^0.3.1",
|
||||
"istanbul": "^1.1.0-alpha.1",
|
||||
"mocha": "^5.1.1",
|
||||
"monk": "^7.2.0",
|
||||
"monk": "^7.3.0",
|
||||
"require-again": "^2.0.0",
|
||||
"sinon": "^7.2.4",
|
||||
"sinon-chai": "^3.5.0",
|
||||
|
||||
@@ -879,6 +879,11 @@ describe('cron', () => {
|
||||
tasksByType.todos.push(task);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
tasksByType.todos = [];
|
||||
user.tasksOrder.todos = [];
|
||||
});
|
||||
|
||||
it('should make uncompleted todos redder', () => {
|
||||
const valueBefore = tasksByType.todos[0].value;
|
||||
cron({
|
||||
@@ -887,6 +892,15 @@ describe('cron', () => {
|
||||
expect(tasksByType.todos[0].value).to.be.lessThan(valueBefore);
|
||||
});
|
||||
|
||||
it('should not make completed todos redder', () => {
|
||||
tasksByType.todos[0].completed = true;
|
||||
const valueBefore = tasksByType.todos[0].value;
|
||||
cron({
|
||||
user, tasksByType, daysMissed, analytics,
|
||||
});
|
||||
expect(tasksByType.todos[0].value).to.equal(valueBefore);
|
||||
});
|
||||
|
||||
it('should add history of completed todos to user history', () => {
|
||||
tasksByType.todos[0].completed = true;
|
||||
|
||||
@@ -898,17 +912,13 @@ describe('cron', () => {
|
||||
});
|
||||
|
||||
it('should remove completed todos from users taskOrder list', () => {
|
||||
tasksByType.todos = [];
|
||||
user.tasksOrder.todos = [];
|
||||
const todo = {
|
||||
text: 'test todo',
|
||||
type: 'todo',
|
||||
value: 0,
|
||||
};
|
||||
|
||||
let task = new Tasks.todo(Tasks.Task.sanitize(todo)); // eslint-disable-line new-cap
|
||||
tasksByType.todos.push(task);
|
||||
task = new Tasks.todo(Tasks.Task.sanitize(todo)); // eslint-disable-line new-cap
|
||||
const task = new Tasks.todo(Tasks.Task.sanitize(todo)); // eslint-disable-line new-cap
|
||||
tasksByType.todos.push(task);
|
||||
tasksByType.todos[0].completed = true;
|
||||
|
||||
@@ -930,8 +940,6 @@ describe('cron', () => {
|
||||
});
|
||||
|
||||
it('should preserve todos order in task list', () => {
|
||||
tasksByType.todos = [];
|
||||
user.tasksOrder.todos = [];
|
||||
const todo = {
|
||||
text: 'test todo',
|
||||
type: 'todo',
|
||||
|
||||
@@ -64,6 +64,51 @@ describe('highlightMentions', () => {
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
describe('link interactions', async () => {
|
||||
it('doesn\'t highlight users in link', async () => {
|
||||
const text = 'http://www.medium.com/@user/blog';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
it('doesn\'t highlight user in link between brackets', async () => {
|
||||
const text = '(http://www.medium.com/@user/blog)';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
it('doesn\'t highlight user in an autolink', async () => {
|
||||
const text = '<http://www.medium.com/@user/blog>';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
it('doesn\'t highlight users in link text', async () => {
|
||||
const text = '[Check awesome blog written by @user](http://www.medium.com/@user/blog)';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
it('doesn\'t highlight users in link with newlines and markup', async () => {
|
||||
const text = '[Check `awesome` \nblog **written** by @user](http://www.medium.com/@user/blog)';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
it('doesn\'t highlight users in link when followed by same @user mention', async () => {
|
||||
const text = 'http://www.medium.com/@user/blog @user';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal('http://www.medium.com/@user/blog [@user](/profile/111)');
|
||||
});
|
||||
|
||||
// https://github.com/HabitRPG/habitica/issues/12217
|
||||
it('doesn\'t highlight user in link with url-escapable characters', async () => {
|
||||
const text = '[test](https://habitica.fandom.com/ru/@wiki/Снаряжение)';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exceptions in code blocks', () => {
|
||||
it('doesn\'t highlight user in inline code block', async () => {
|
||||
const text = '`@user`';
|
||||
@@ -104,5 +149,41 @@ describe('highlightMentions', () => {
|
||||
|
||||
expect(result[0]).to.equal('[@user](/profile/111) `@user`');
|
||||
});
|
||||
|
||||
it('matches a link in between two the same links', async () => {
|
||||
const text = '[here](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)\n@user\n[hier](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)';
|
||||
|
||||
const result = await highlightMentions(text);
|
||||
|
||||
expect(result[0]).to.equal('[here](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)\n[@user](/profile/111)\n[hier](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)');
|
||||
});
|
||||
});
|
||||
|
||||
it('github issue 12118, method crashes when square brackets are used', async () => {
|
||||
const text = '[test]';
|
||||
|
||||
let err;
|
||||
|
||||
try {
|
||||
await highlightMentions(text);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
expect(err).to.be.undefined;
|
||||
});
|
||||
|
||||
it('github issue 12138, method crashes when regex chars are used in code block', async () => {
|
||||
const text = '`[test]`';
|
||||
|
||||
let err;
|
||||
|
||||
try {
|
||||
await highlightMentions(text);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
expect(err).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import moment from 'moment';
|
||||
import { calculateSubscriptionTerminationDate } from '../../../../../../website/server/libs/payments/util';
|
||||
import calculateSubscriptionTerminationDate from '../../../../../../website/server/libs/payments/calculateSubscriptionTerminationDate';
|
||||
import api from '../../../../../../website/server/libs/payments/payments';
|
||||
|
||||
const groupPlanId = api.constants.GROUP_PLAN_CUSTOMER_ID;
|
||||
|
||||
describe('#calculateSubscriptionTerminationDate', () => {
|
||||
let plan;
|
||||
let nextBill;
|
||||
@@ -13,52 +15,75 @@ describe('#calculateSubscriptionTerminationDate', () => {
|
||||
};
|
||||
nextBill = moment();
|
||||
});
|
||||
|
||||
it('should extend date to the exact amount of days left before the next bill will occur', () => {
|
||||
nextBill = moment()
|
||||
.add(5, 'days');
|
||||
const expectedTerminationDate = moment()
|
||||
.add(5, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('if nextBill is null, add 30 days to termination date', () => {
|
||||
nextBill = null;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(30, 'days');
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('if nextBill is null and it\'s a group plan, add 2 days instead of 30', () => {
|
||||
nextBill = null;
|
||||
plan.customerId = api.constants.GROUP_PLAN_CUSTOMER_ID;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(2, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('should add 30.5 days for each extraMonth', () => {
|
||||
plan.extraMonths = 4;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(30.5 * 4, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('should round up if total days gained by extraMonth is a decimal number', () => {
|
||||
plan.extraMonths = 5;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(Math.ceil(30.5 * 5), 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('behaves like extraMonths is 0 if it\'s set to a negative number', () => {
|
||||
plan.extraMonths = -5;
|
||||
const expectedTerminationDate = moment();
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
|
||||
it('returns current terminated date if it exists and is later than newly calculated date', () => {
|
||||
const expectedTerminationDate = moment().add({ months: 5 }).toDate();
|
||||
plan.dateTerminated = expectedTerminationDate;
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
|
||||
expect(terminationDate).to.equal(expectedTerminationDate);
|
||||
});
|
||||
|
||||
it('returns the calculated termination date if the plan does not have one', () => {
|
||||
nextBill = moment().add(5, 'days');
|
||||
const expectedTerminationDate = moment().add(5, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, groupPlanId);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { getMatchesByWordArray } from '../../../../website/server/libs/stringUtils';
|
||||
import bannedWords from '../../../../website/server/libs/bannedWords';
|
||||
|
||||
describe('stringUtils', () => {
|
||||
describe('getMatchesByWordArray', () => {
|
||||
it('check all banned words are matched', async () => {
|
||||
const message = bannedWords.join(',').replace(/\\/g, '');
|
||||
const matches = getMatchesByWordArray(message, bannedWords);
|
||||
expect(matches.length).to.equal(bannedWords.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -14,8 +14,6 @@ import {
|
||||
TAVERN_ID,
|
||||
} from '../../../../../website/server/models/group';
|
||||
import { CHAT_FLAG_FROM_SHADOW_MUTE, MAX_MESSAGE_LENGTH } from '../../../../../website/common/script/constants';
|
||||
import { getMatchesByWordArray } from '../../../../../website/server/libs/stringUtils';
|
||||
import bannedWords from '../../../../../website/server/libs/bannedWords';
|
||||
import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
|
||||
import * as email from '../../../../../website/server/libs/email';
|
||||
|
||||
@@ -292,12 +290,6 @@ describe('POST /chat', () => {
|
||||
.that.includes(testBannedWords.join(', '));
|
||||
});
|
||||
|
||||
it('check all banned words are matched', async () => {
|
||||
const message = bannedWords.join(',').replace(/\\/g, '');
|
||||
const matches = getMatchesByWordArray(message, bannedWords);
|
||||
expect(matches.length).to.equal(bannedWords.length);
|
||||
});
|
||||
|
||||
it('does not error when bad word is suffix of a word', async () => {
|
||||
const wordAsSuffix = `prefix${testBannedWordMessage}`;
|
||||
const message = await user.post('/groups/habitrpg/chat', { message: wordAsSuffix });
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
import {
|
||||
each,
|
||||
} from 'lodash';
|
||||
import each from 'lodash/each';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
generateChallenge,
|
||||
@@ -13,7 +11,7 @@ import {
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import { model as User } from '../../../../../website/server/models/user';
|
||||
import payments from '../../../../../website/server/libs/payments/payments';
|
||||
import { calculateSubscriptionTerminationDate } from '../../../../../website/server/libs/payments/util';
|
||||
import calculateSubscriptionTerminationDate from '../../../../../website/server/libs/payments/calculateSubscriptionTerminationDate';
|
||||
|
||||
describe('POST /groups/:groupId/leave', () => {
|
||||
const typesOfGroups = {
|
||||
@@ -359,6 +357,7 @@ describe('POST /groups/:groupId/leave', () => {
|
||||
'purchased.plan.extraMonths': extraMonths,
|
||||
});
|
||||
});
|
||||
|
||||
it('calculates dateTerminated and sets extraMonths to zero after user leaves the group', async () => {
|
||||
const userBeforeLeave = await User.findById(member._id).exec();
|
||||
|
||||
@@ -373,7 +372,7 @@ describe('POST /groups/:groupId/leave', () => {
|
||||
const expectedTerminationDate = calculateSubscriptionTerminationDate(null, {
|
||||
customerId: payments.constants.GROUP_PLAN_CUSTOMER_ID,
|
||||
extraMonths,
|
||||
}, payments.constants);
|
||||
}, payments.constants.GROUP_PLAN_CUSTOMER_ID);
|
||||
|
||||
expect(extraMonthsBefore).to.gte(12);
|
||||
expect(extraMonthsAfter).to.equal(0);
|
||||
|
||||
@@ -10,6 +10,9 @@ describe('GET /hall/heroes', () => {
|
||||
const nonHero = await generateUser();
|
||||
const hero1 = await generateUser({
|
||||
contributor: { level: 1 },
|
||||
secret: {
|
||||
text: 'Super-Hero',
|
||||
},
|
||||
});
|
||||
const hero2 = await generateUser({
|
||||
contributor: { level: 3 },
|
||||
@@ -21,6 +24,8 @@ describe('GET /hall/heroes', () => {
|
||||
expect(heroes[1]._id).to.equal(hero1._id);
|
||||
|
||||
expect(heroes[0]).to.have.all.keys(['_id', 'contributor', 'backer', 'profile']);
|
||||
|
||||
// should not contain the secret
|
||||
expect(heroes[1]).to.have.all.keys(['_id', 'contributor', 'backer', 'profile']);
|
||||
|
||||
expect(heroes[0].profile).to.have.all.keys(['name']);
|
||||
@@ -28,5 +33,6 @@ describe('GET /hall/heroes', () => {
|
||||
|
||||
expect(heroes[0].profile.name).to.equal(hero2.profile.name);
|
||||
expect(heroes[1].profile.name).to.equal(hero1.profile.name);
|
||||
expect(heroes[1].secret).to.equal(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,15 +43,19 @@ describe('GET /heroes/:heroId', () => {
|
||||
it('returns only necessary hero data given user id', async () => {
|
||||
const hero = await generateUser({
|
||||
contributor: { tier: 23 },
|
||||
secret: {
|
||||
text: 'Super Hero',
|
||||
},
|
||||
});
|
||||
const heroRes = await user.get(`/hall/heroes/${hero._id}`);
|
||||
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items',
|
||||
'contributor', 'auth', 'items', 'secret',
|
||||
]);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
expect(heroRes.secret.text).to.be.eq('Super Hero');
|
||||
});
|
||||
|
||||
it('returns only necessary hero data given username', async () => {
|
||||
@@ -62,7 +66,7 @@ describe('GET /heroes/:heroId', () => {
|
||||
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items',
|
||||
'contributor', 'auth', 'items', 'secret',
|
||||
]);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
@@ -7,6 +7,12 @@ import {
|
||||
describe('PUT /heroes/:heroId', () => {
|
||||
let user;
|
||||
|
||||
const heroFields = [
|
||||
'_id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items', 'flags',
|
||||
'secret',
|
||||
];
|
||||
|
||||
before(async () => {
|
||||
user = await generateUser({
|
||||
contributor: { admin: true },
|
||||
@@ -51,10 +57,8 @@ describe('PUT /heroes/:heroId', () => {
|
||||
});
|
||||
|
||||
// test response
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items', 'flags',
|
||||
]);
|
||||
// works as: object has all and only these keys
|
||||
expect(heroRes).to.have.all.keys(heroFields);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
@@ -130,10 +134,8 @@ describe('PUT /heroes/:heroId', () => {
|
||||
});
|
||||
|
||||
// test response
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items', 'flags',
|
||||
]);
|
||||
// works as: object has all and only these keys
|
||||
expect(heroRes).to.have.all.keys(heroFields);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
@@ -157,10 +159,8 @@ describe('PUT /heroes/:heroId', () => {
|
||||
});
|
||||
|
||||
// test response
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items', 'flags',
|
||||
]);
|
||||
// works as: object has all and only these keys
|
||||
expect(heroRes).to.have.all.keys(heroFields);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
@@ -173,6 +173,40 @@ describe('PUT /heroes/:heroId', () => {
|
||||
expect(hero.contributor.text).to.equal('Astronaut');
|
||||
});
|
||||
|
||||
it('updates contributor secret', async () => {
|
||||
const secretText = 'my super hero';
|
||||
|
||||
const hero = await generateUser({
|
||||
contributor: { level: 5 },
|
||||
secret: {
|
||||
text: 'supr hro typo',
|
||||
},
|
||||
});
|
||||
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
|
||||
contributor: { text: 'Astronaut' },
|
||||
secret: {
|
||||
text: secretText,
|
||||
},
|
||||
});
|
||||
|
||||
// test response
|
||||
// works as: object has all and only these keys
|
||||
expect(heroRes).to.have.all.keys(heroFields);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
// test response values
|
||||
expect(heroRes.contributor.level).to.equal(5); // doesn't modify previous values
|
||||
expect(heroRes.contributor.text).to.equal('Astronaut');
|
||||
expect(heroRes.secret.text).to.equal(secretText);
|
||||
|
||||
// test hero values
|
||||
await hero.sync();
|
||||
expect(hero.contributor.level).to.equal(5); // doesn't modify previous values
|
||||
expect(hero.contributor.text).to.equal('Astronaut');
|
||||
expect(hero.secret.text).to.equal(secretText);
|
||||
});
|
||||
|
||||
it('updates items', async () => {
|
||||
const hero = await generateUser();
|
||||
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
|
||||
@@ -181,10 +215,8 @@ describe('PUT /heroes/:heroId', () => {
|
||||
});
|
||||
|
||||
// test response
|
||||
expect(heroRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
'_id', 'balance', 'profile', 'purchased',
|
||||
'contributor', 'auth', 'items', 'flags',
|
||||
]);
|
||||
// works as: object has all and only these keys
|
||||
expect(heroRes).to.have.all.keys(heroFields);
|
||||
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||
expect(heroRes.profile).to.have.all.keys(['name']);
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ describe('GET /members/:memberId', () => {
|
||||
costume: false,
|
||||
background: 'volcano',
|
||||
},
|
||||
secret: {
|
||||
text: 'Clark Kent',
|
||||
},
|
||||
});
|
||||
const memberRes = await user.get(`/members/${member._id}`);
|
||||
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||
@@ -46,6 +49,29 @@ describe('GET /members/:memberId', () => {
|
||||
expect(memberRes.stats.toNextLevel).to.equal(common.tnl(memberRes.stats.lvl));
|
||||
expect(memberRes.inbox.optOut).to.exist;
|
||||
expect(memberRes.inbox.messages).to.not.exist;
|
||||
expect(memberRes.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not return secret for the own account', async () => {
|
||||
// make sure user has all the fields that can be returned by the getMember call
|
||||
const member = await generateUser({
|
||||
contributor: { level: 1 },
|
||||
backer: { tier: 3 },
|
||||
preferences: {
|
||||
costume: false,
|
||||
background: 'volcano',
|
||||
},
|
||||
secret: {
|
||||
text: 'Clark Kent',
|
||||
},
|
||||
});
|
||||
const memberRes = await member.get(`/members/${member._id}`);
|
||||
expect(memberRes).to.have.keys([ // works as: object has all and only these keys
|
||||
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
|
||||
'backer', 'contributor', 'auth', 'items', 'inbox', 'loginIncentives', 'flags',
|
||||
]);
|
||||
|
||||
expect(memberRes.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('handles non-existing members', async () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import range from 'lodash/range';
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
@@ -26,6 +27,7 @@ describe('GET /user', () => {
|
||||
expect(returnedUser.auth.local.passwordHashMethod).to.not.exist;
|
||||
expect(returnedUser.auth.local.salt).to.not.exist;
|
||||
expect(returnedUser.apiToken).to.not.exist;
|
||||
expect(returnedUser.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('returns only user properties requested', async () => {
|
||||
@@ -38,4 +40,30 @@ describe('GET /user', () => {
|
||||
expect(returnedUser.notifications).to.exist;
|
||||
expect(returnedUser.stats).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not return requested private properties', async () => {
|
||||
const returnedUser = await user.get('/user?userFields=apiToken,secret.text');
|
||||
|
||||
expect(returnedUser.apiToken).to.not.exist;
|
||||
expect(returnedUser.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('returns the full inbox', async () => {
|
||||
const otherUser = await generateUser();
|
||||
const amountOfMessages = 12;
|
||||
|
||||
const allMessagesPromise = range(amountOfMessages)
|
||||
.map(i => otherUser.post('/members/send-private-message', {
|
||||
toUserId: user.id,
|
||||
message: `Message Num: ${i}`,
|
||||
}));
|
||||
|
||||
await Promise.all(allMessagesPromise);
|
||||
|
||||
const returnedUser = await user.get('/user');
|
||||
|
||||
expect(returnedUser._id).to.equal(user._id);
|
||||
expect(returnedUser.inbox).to.exist;
|
||||
expect(Object.keys(returnedUser.inbox.messages)).to.have.a.lengthOf(amountOfMessages);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,11 @@ describe('GET /user/anonymized', () => {
|
||||
const endpoint = '/user/anonymized';
|
||||
|
||||
before(async () => {
|
||||
user = await generateUser();
|
||||
user = await generateUser({
|
||||
secret: {
|
||||
text: 'Clark Kent',
|
||||
},
|
||||
});
|
||||
await user.update({
|
||||
newMessages: ['some', 'new', 'messages'],
|
||||
'profile.name': 'profile',
|
||||
@@ -100,5 +104,7 @@ describe('GET /user/anonymized', () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
expect(returnedUser.secret).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,4 +117,24 @@ describe('POST /user/reset', () => {
|
||||
expect(userChallengeTask).to.exist;
|
||||
expect(syncedGroupTask).to.exist;
|
||||
});
|
||||
|
||||
it('does not delete secret', async () => {
|
||||
const admin = await generateUser({
|
||||
contributor: { admin: true },
|
||||
});
|
||||
|
||||
const hero = await generateUser({
|
||||
contributor: { level: 1 },
|
||||
secret: {
|
||||
text: 'Super-Hero',
|
||||
},
|
||||
});
|
||||
|
||||
await hero.post('/user/reset');
|
||||
|
||||
const heroRes = await admin.get(`/hall/heroes/${hero.auth.local.username}`);
|
||||
|
||||
expect(heroRes.secret).to.exist;
|
||||
expect(heroRes.secret.text).to.be.eq('Super-Hero');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
describe('POST /user/unlock', () => {
|
||||
let user;
|
||||
const unlockPath = 'shirt.convict,shirt.cross,shirt.fire,shirt.horizon,shirt.ocean,shirt.purple,shirt.rainbow,shirt.redblue,shirt.thunder,shirt.tropical,shirt.zombie';
|
||||
const unlockGearSetPath = 'items.gear.owned.headAccessory_special_bearEars,items.gear.owned.headAccessory_special_cactusEars,items.gear.owned.headAccessory_special_foxEars,items.gear.owned.headAccessory_special_lionEars,items.gear.owned.headAccessory_special_pandaEars,items.gear.owned.headAccessory_special_pigEars,items.gear.owned.headAccessory_special_tigerEars,items.gear.owned.headAccessory_special_wolfEars';
|
||||
const unlockCost = 1.25;
|
||||
const usersStartingGems = 5;
|
||||
|
||||
@@ -34,4 +35,25 @@ describe('POST /user/unlock', () => {
|
||||
expect(response.message).to.equal(t('unlocked'));
|
||||
expect(user.balance).to.equal(usersStartingGems - unlockCost);
|
||||
});
|
||||
|
||||
it('does not reduce a user\'s balance twice', async () => {
|
||||
await user.update({
|
||||
balance: usersStartingGems,
|
||||
});
|
||||
const response = await user.post(`/user/unlock?path=${unlockGearSetPath}`);
|
||||
await user.sync();
|
||||
|
||||
expect(response.message).to.equal(t('unlocked'));
|
||||
expect(user.balance).to.equal(usersStartingGems - unlockCost);
|
||||
|
||||
expect(user.post(`/user/unlock?path=${unlockGearSetPath}`))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('alreadyUnlocked'),
|
||||
});
|
||||
await user.sync();
|
||||
|
||||
expect(user.balance).to.equal(usersStartingGems - unlockCost);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,6 +107,7 @@ describe('PUT /user', () => {
|
||||
'customization gem purchases': { 'purchased.background.tavern': true, 'purchased.skin.bear': true },
|
||||
notifications: [{ type: 123 }],
|
||||
webhooks: { webhooks: [{ url: 'https://foobar.com' }] },
|
||||
secret: { secret: { text: 'Some new text' } },
|
||||
};
|
||||
|
||||
each(protectedOperations, (data, testName) => {
|
||||
@@ -129,6 +130,7 @@ describe('PUT /user', () => {
|
||||
webhooks: { 'preferences.webhooks': [1, 2, 3] },
|
||||
sleep: { 'preferences.sleep': true },
|
||||
'disable classes': { 'preferences.disableClasses': true },
|
||||
secret: { secret: { text: 'Some new text' } },
|
||||
};
|
||||
|
||||
each(protectedOperations, (data, testName) => {
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('GET /inbox/conversations', () => {
|
||||
expect(messages[4].text).to.equal('first');
|
||||
});
|
||||
|
||||
it('returns four messages when using page-query ', async () => {
|
||||
it('returns five messages when using page-query ', async () => {
|
||||
const promises = [];
|
||||
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ describe('GET /user', () => {
|
||||
expect(returnedUser.auth.local.passwordHashMethod).to.not.exist;
|
||||
expect(returnedUser.auth.local.salt).to.not.exist;
|
||||
expect(returnedUser.apiToken).to.not.exist;
|
||||
expect(returnedUser.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('returns only user properties requested', async () => {
|
||||
@@ -39,6 +40,13 @@ describe('GET /user', () => {
|
||||
expect(returnedUser.stats).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not return requested private properties', async () => {
|
||||
const returnedUser = await user.get('/user?userFields=apiToken,secret.text');
|
||||
|
||||
expect(returnedUser.apiToken).to.not.exist;
|
||||
expect(returnedUser.secret).to.not.exist;
|
||||
});
|
||||
|
||||
it('does not return new inbox messages', async () => {
|
||||
const otherUser = await generateUser();
|
||||
|
||||
|
||||
@@ -117,4 +117,25 @@ describe('POST /user/reset', () => {
|
||||
expect(userChallengeTask).to.exist;
|
||||
expect(syncedGroupTask).to.exist;
|
||||
});
|
||||
|
||||
it('does not delete secret', async () => {
|
||||
const admin = await generateUser({
|
||||
contributor: { admin: true },
|
||||
});
|
||||
|
||||
const hero = await generateUser({
|
||||
contributor: { level: 1 },
|
||||
secret: {
|
||||
text: 'Super-Hero',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
await hero.post('/user/reset');
|
||||
|
||||
const heroRes = await admin.get(`/hall/heroes/${hero.auth.local.username}`);
|
||||
|
||||
expect(heroRes.secret).to.exist;
|
||||
expect(heroRes.secret.text).to.be.eq('Super-Hero');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,6 +91,7 @@ describe('PUT /user', () => {
|
||||
'customization gem purchases': { 'purchased.background.tavern': true, 'purchased.skin.bear': true },
|
||||
notifications: [{ type: 123 }],
|
||||
webhooks: { webhooks: [{ url: 'https://foobar.com' }] },
|
||||
secret: { secret: { text: 'Some new text' } },
|
||||
};
|
||||
|
||||
each(protectedOperations, (data, testName) => {
|
||||
@@ -113,6 +114,7 @@ describe('PUT /user', () => {
|
||||
webhooks: { 'preferences.webhooks': [1, 2, 3] },
|
||||
sleep: { 'preferences.sleep': true },
|
||||
'disable classes': { 'preferences.disableClasses': true },
|
||||
secret: { secret: { text: 'Some new text' } },
|
||||
};
|
||||
|
||||
each(protectedOperations, (data, testName) => {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"test": {
|
||||
plugins: [
|
||||
["istanbul"],
|
||||
],
|
||||
},
|
||||
},
|
||||
"presets": [
|
||||
["es2015", { modules: false }],
|
||||
],
|
||||
"plugins": [
|
||||
"transform-object-rest-spread",
|
||||
],
|
||||
"comments": false,
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// TODO verify if it's needed, added because Axios require Promise in the global scope
|
||||
// and babel-runtime doesn't affect external libraries
|
||||
require('babel-polyfill');
|
||||
|
||||
// Automatically setup SinonJS' sandbox for each test
|
||||
beforeEach(() => {
|
||||
global.sandbox = sinon.createSandbox();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.sandbox.restore();
|
||||
});
|
||||
|
||||
// require all test files
|
||||
const testsContext = require.context('./specs', true, /\.js$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
// require all .vue and .js files except main.js for coverage.
|
||||
const srcContext = require.context('../../../website/client', true, /^\.\/(?=(?!main(\.js)?$))(?=(.*\.(vue|js)$))/);
|
||||
srcContext.keys().forEach(srcContext);
|
||||
@@ -1,40 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// This is a karma config file. For more details see
|
||||
// http://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
// we are also using it with karma-webpack
|
||||
// https://github.com/webpack/karma-webpack
|
||||
|
||||
// Necessary for babel to respect the env version of .babelrc which is necessary
|
||||
// Because inject-loader does not work with ["es2015", { modules: false }] that we use
|
||||
// in order to let webpack2 handle the imports
|
||||
process.env.CHROME_BIN = require('puppeteer').executablePath();
|
||||
// eslint-disable-line no-process-env
|
||||
process.env.BABEL_ENV = process.env.NODE_ENV; // eslint-disable-line no-process-env
|
||||
const webpackConfig = require('../../../webpack/webpack.test.conf');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
// to run in additional browsers:
|
||||
// 1. install corresponding karma launcher
|
||||
// http://karma-runner.github.io/0.13/config/browsers.html
|
||||
// 2. add it to the `browsers` array below.
|
||||
browsers: ['ChromeHeadless'],
|
||||
frameworks: ['mocha', 'sinon-stub-promise', 'sinon-chai', 'chai-as-promised', 'chai'],
|
||||
reporters: ['spec', 'coverage'],
|
||||
files: ['./index.js'],
|
||||
preprocessors: {
|
||||
'./index.js': ['webpack', 'sourcemap'],
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
noInfo: true,
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: '../../../coverage/client-unit',
|
||||
reporters: [
|
||||
{ type: 'lcov', subdir: '.' },
|
||||
{ type: 'text-summary' },
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -119,7 +119,7 @@ describe('shared.ops.buyGem', () => {
|
||||
buyGem(user, { params: { type: 'gems', key: 'gem' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('reachedGoldToGemCap', { convCap: planGemLimits.convCap }));
|
||||
expect(err.message).to.equal(i18n.t('maxBuyGems', { convCap: planGemLimits.convCap }));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -88,7 +88,14 @@ describe('shared.ops.buyMysterySet', () => {
|
||||
expect(user.items.gear.owned).to.have.property('armor_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('head_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('eyewear_mystery_301404', true);
|
||||
expect(analytics.track).to.be.called;
|
||||
expect(analytics.track).to.be.calledOnce;
|
||||
expect(analytics.track).to.be.calledWithMatch('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: '301404',
|
||||
itemType: 'Subscriber Gear',
|
||||
acquireMethod: 'Hourglass',
|
||||
category: 'behavior',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +52,22 @@ describe('shared.ops.reset', () => {
|
||||
expect(user.stats.lvl).to.equal(1);
|
||||
});
|
||||
|
||||
it('resets user\'s stat points (str, con, int, per, points)', () => {
|
||||
user.stats.str = 2;
|
||||
user.stats.con = 2;
|
||||
user.stats.int = 2;
|
||||
user.stats.per = 2;
|
||||
user.stats.points = 2;
|
||||
|
||||
reset(user);
|
||||
|
||||
expect(user.stats.str).to.equal(0);
|
||||
expect(user.stats.con).to.equal(0);
|
||||
expect(user.stats.int).to.equal(0);
|
||||
expect(user.stats.per).to.equal(0);
|
||||
expect(user.stats.points).to.equal(1);
|
||||
});
|
||||
|
||||
it('resets user\'s gold', () => {
|
||||
user.stats.gp = 20;
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import unlock from '../../../website/common/script/ops/unlock';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import {
|
||||
NotAuthorized,
|
||||
BadRequest,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import { generateUser } from '../../helpers/common.helper';
|
||||
import { NotAuthorized, BadRequest } from '../../../website/common/script/libs/errors';
|
||||
|
||||
describe('shared.ops.unlock', () => {
|
||||
let user;
|
||||
@@ -31,6 +26,15 @@ describe('shared.ops.unlock', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('does not unlock lost gear', done => {
|
||||
user.items.gear.owned.headAccessory_special_bearEars = false;
|
||||
|
||||
unlock(user, { query: { path: 'items.gear.owned.headAccessory_special_bearEars' } });
|
||||
|
||||
expect(user.balance).to.equal(usersStartingGems);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns an error when user balance is too low', done => {
|
||||
user.balance = 0;
|
||||
|
||||
@@ -50,18 +54,30 @@ describe('shared.ops.unlock', () => {
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
|
||||
expect(user.balance).to.equal(3.75);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
// disabled until fully implemente
|
||||
xit('returns an error when user already owns items in a full set', done => {
|
||||
it('returns an error when user already owns a full set of gear', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
unlock(user, { query: { path: unlockGearSetPath } });
|
||||
unlock(user, { query: { path: unlockGearSetPath } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
|
||||
expect(user.balance).to.equal(3.75);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
xit('returns an error when user already owns items in a full set', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: unlockPath.split(',').splice(2).join(',') } });
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('alreadyUnlockedPart'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -78,7 +94,7 @@ describe('shared.ops.unlock', () => {
|
||||
expect(user.preferences.background).to.equal('giant_florals');
|
||||
});
|
||||
|
||||
it('un-equips an item already equipped', () => {
|
||||
it('un-equips a background already equipped', () => {
|
||||
expect(user.purchased.background.giant_florals).to.not.exist;
|
||||
|
||||
unlock(user, { query: { path: backgroundUnlockPath } }); // unlock
|
||||
@@ -105,7 +121,7 @@ describe('shared.ops.unlock', () => {
|
||||
expect(user.items.gear.owned.headAccessory_special_wolfEars).to.be.true;
|
||||
});
|
||||
|
||||
it('unlocks a an item', () => {
|
||||
it('unlocks an item', () => {
|
||||
const [, message] = unlock(user, { query: { path: backgroundUnlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
|
||||
@@ -13,38 +13,38 @@
|
||||
"test:unit": "vue-cli-service test:unit --require ./tests/unit/helpers.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addon-actions": "^5.3.19",
|
||||
"@storybook/addon-knobs": "^5.3.19",
|
||||
"@storybook/addon-links": "^5.3.19",
|
||||
"@storybook/addon-notes": "^5.3.19",
|
||||
"@storybook/vue": "^5.3.19",
|
||||
"@vue/cli-plugin-babel": "^4.3.1",
|
||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
||||
"@vue/cli-plugin-router": "^4.3.1",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.3.1",
|
||||
"@vue/cli-service": "^4.3.1",
|
||||
"@storybook/addon-actions": "^5.3.18",
|
||||
"@storybook/addon-knobs": "^5.3.18",
|
||||
"@storybook/addon-links": "^5.3.18",
|
||||
"@storybook/addon-notes": "^5.3.18",
|
||||
"@storybook/vue": "^5.3.18",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"amplitude-js": "^5.11.0",
|
||||
"axios": "^0.19.2",
|
||||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
"bootstrap-vue": "^2.11.0",
|
||||
"bootstrap": "^4.5.0",
|
||||
"bootstrap-vue": "^2.15.0",
|
||||
"chai": "^4.1.2",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-habitrpg": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"habitica-markdown": "^1.3.2",
|
||||
"habitica-markdown": "^2.0.0",
|
||||
"hellojs": "^1.18.4",
|
||||
"inspectpack": "^4.4.0",
|
||||
"inspectpack": "^4.5.2",
|
||||
"intro.js": "^2.9.3",
|
||||
"jquery": "^3.5.0",
|
||||
"jquery": "^3.5.1",
|
||||
"lodash": "^4.17.15",
|
||||
"moment": "^2.24.0",
|
||||
"moment": "^2.26.0",
|
||||
"nconf": "^0.10.0",
|
||||
"sass": "^1.26.3",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
"smartbanner.js": "^1.15.0",
|
||||
"svg-inline-loader": "^0.8.2",
|
||||
@@ -56,10 +56,10 @@
|
||||
"vue": "^2.6.11",
|
||||
"vue-cli-plugin-storybook": "^0.6.1",
|
||||
"vue-mugen-scroll": "^0.2.6",
|
||||
"vue-router": "^3.1.6",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuedraggable": "^2.23.1",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||
"webpack": "^4.42.1"
|
||||
"webpack": "^4.43.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<meta name="smartbanner:button-url-apple" content="https://itunes.apple.com/us/app/habitica-gamified-taskmanager/id994882113">
|
||||
<meta name="smartbanner:button-url-google" content="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica">
|
||||
<meta name="smartbanner:enabled-platforms" content="android,ios">
|
||||
<meta name="smartbanner:hide-ttl" content="2592000000">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,400i,700,700i|Roboto:400,400i,700,700i" rel="stylesheet">
|
||||
<link rel="shortcut icon" sizes="48x48" href="/static/icons/favicon.ico">
|
||||
<link rel="shortcut icon" sizes="192x192" href="/static/icons/favicon_192x192.png">
|
||||
|
||||
@@ -297,7 +297,7 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneOffset', 'isUserLoaded']),
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneOffset', 'isUserLoaded', 'notificationsRemoved']),
|
||||
...mapState({ user: 'user.data' }),
|
||||
isStaticPage () {
|
||||
return this.$route.meta.requiresLogin === false;
|
||||
@@ -361,13 +361,55 @@ export default {
|
||||
showSpinner: false,
|
||||
});
|
||||
|
||||
// Set up Error interceptors
|
||||
axios.interceptors.response.use(response => {
|
||||
if (this.user && response.data && response.data.notifications) {
|
||||
this.$set(this.user, 'notifications', response.data.notifications);
|
||||
axios.interceptors.response.use(response => { // Set up Response interceptors
|
||||
// Verify that the user was not updated from another browser/app/client
|
||||
// If it was, sync
|
||||
const { url } = response.config;
|
||||
const { method } = response.config;
|
||||
|
||||
const isApiCall = url.indexOf('api/v4') !== -1;
|
||||
const userV = response.data && response.data.userV;
|
||||
const isCron = url.indexOf('/api/v4/cron') === 0 && method === 'post';
|
||||
|
||||
if (this.isUserLoaded && isApiCall && userV) {
|
||||
const oldUserV = this.user._v;
|
||||
this.user._v = userV;
|
||||
|
||||
// Do not sync again if already syncing
|
||||
const isUserSync = url.indexOf('/api/v4/user') === 0 && method === 'get';
|
||||
const isTasksSync = url.indexOf('/api/v4/tasks/user') === 0 && method === 'get';
|
||||
// exclude chat seen requests because with real time chat they would be too many
|
||||
const isChatSeen = url.indexOf('/chat/seen') !== -1 && method === 'post';
|
||||
// exclude POST /api/v4/cron because the user is synced automatically after cron runs
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (userV - oldUserV > 1 && !isCron && !isChatSeen && !isUserSync && !isTasksSync) {
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch', { forceLoad: true }),
|
||||
this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true }),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the app version from the server
|
||||
const serverAppVersion = response.data && response.data.appVersion;
|
||||
|
||||
if (serverAppVersion && this.$store.state.serverAppVersion !== response.data.appVersion) {
|
||||
this.$store.state.serverAppVersion = serverAppVersion;
|
||||
}
|
||||
|
||||
// Store the notifications, filtering those that have already been read
|
||||
// See store/index.js on why this is necessary
|
||||
if (this.user && response.data && response.data.notifications) {
|
||||
const filteredNotifications = response.data.notifications.filter(serverNotification => {
|
||||
if (this.notificationsRemoved.includes(serverNotification.id)) return false;
|
||||
return true;
|
||||
});
|
||||
this.$set(this.user, 'notifications', filteredNotifications);
|
||||
}
|
||||
|
||||
return response;
|
||||
}, error => {
|
||||
}, error => { // Set up Error interceptors
|
||||
if (error.response.status >= 400) {
|
||||
const isBanned = this.checkForBannedUser(error);
|
||||
if (isBanned === true) return null; // eslint-disable-line consistent-return
|
||||
@@ -425,51 +467,6 @@ export default {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(response => {
|
||||
// Verify that the user was not updated from another browser/app/client
|
||||
// If it was, sync
|
||||
const { url } = response.config;
|
||||
const { method } = response.config;
|
||||
|
||||
const isApiCall = url.indexOf('api/v4') !== -1;
|
||||
const userV = response.data && response.data.userV;
|
||||
const isCron = url.indexOf('/api/v4/cron') === 0 && method === 'post';
|
||||
|
||||
if (this.isUserLoaded && isApiCall && userV) {
|
||||
const oldUserV = this.user._v;
|
||||
this.user._v = userV;
|
||||
|
||||
// Do not sync again if already syncing
|
||||
const isUserSync = url.indexOf('/api/v4/user') === 0 && method === 'get';
|
||||
const isTasksSync = url.indexOf('/api/v4/tasks/user') === 0 && method === 'get';
|
||||
// exclude chat seen requests because with real time chat they would be too many
|
||||
const isChatSeen = url.indexOf('/chat/seen') !== -1 && method === 'post';
|
||||
// exclude POST /api/v4/cron because the user is synced automatically after cron runs
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (userV - oldUserV > 1 && !isCron && !isChatSeen && !isUserSync && !isTasksSync) {
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch', { forceLoad: true }),
|
||||
this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true }),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the client is updated
|
||||
// const serverAppVersion = response.data.appVersion;
|
||||
// let serverAppVersionState = this.$store.state.serverAppVersion;
|
||||
// if (isApiCall && !serverAppVersionState) {
|
||||
// this.$store.state.serverAppVersion = serverAppVersion;
|
||||
// } else if (isApiCall && serverAppVersionState !== serverAppVersion) {
|
||||
// if (document.activeElement.tagName !== 'INPUT'
|
||||
// || confirm(this.$t('habiticaHasUpdated'))) {
|
||||
// location.reload(true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
// Setup listener for title
|
||||
this.$store.watch(state => state.title, title => {
|
||||
document.title = title;
|
||||
|
||||
@@ -1,96 +1,60 @@
|
||||
.promo_april_fools_2020 {
|
||||
.promo_armoire_backgrounds_202005 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -445px -184px;
|
||||
background-position: -391px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_armoire_backgrounds_202004 {
|
||||
.promo_fairy_sunshine_potions {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -433px -337px;
|
||||
background-position: -391px -148px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_egg_quest {
|
||||
.promo_jungle_buddies_bundle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -648px;
|
||||
width: 354px;
|
||||
background-position: 0px -434px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_mystery_202004 {
|
||||
.promo_mystery_202005 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -796px;
|
||||
background-position: -424px -434px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_pastel_skin_hair {
|
||||
.promo_mystery_202006 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -355px -648px;
|
||||
width: 354px;
|
||||
height: 147px;
|
||||
}
|
||||
.customize-option.promo_pastel_skin_hair {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -380px -663px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.promo_seasonal_shop_spring {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -875px -524px;
|
||||
width: 162px;
|
||||
height: 138px;
|
||||
}
|
||||
.promo_shiny_seeds {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -424px -500px;
|
||||
width: 360px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_spring_2019 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -337px;
|
||||
width: 432px;
|
||||
height: 162px;
|
||||
}
|
||||
.promo_spring_2020 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -445px 0px;
|
||||
width: 429px;
|
||||
height: 183px;
|
||||
}
|
||||
.promo_spring_potions_2020 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -500px;
|
||||
width: 423px;
|
||||
background-position: -241px -582px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_take_this {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -875px -663px;
|
||||
background-position: -815px -179px;
|
||||
width: 96px;
|
||||
height: 69px;
|
||||
}
|
||||
.scene_citrusella {
|
||||
.scene_casting_spells {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -875px -196px;
|
||||
width: 152px;
|
||||
height: 176px;
|
||||
background-position: 0px -211px;
|
||||
width: 312px;
|
||||
height: 222px;
|
||||
}
|
||||
.scene_hat_guild {
|
||||
.scene_pets_resting {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 444px;
|
||||
height: 336px;
|
||||
width: 390px;
|
||||
height: 210px;
|
||||
}
|
||||
.scene_meditation {
|
||||
.scene_todos {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -875px -373px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.scene_tasks {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -875px 0px;
|
||||
background-position: 0px -582px;
|
||||
width: 240px;
|
||||
height: 195px;
|
||||
}
|
||||
.scene_vikte {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -815px 0px;
|
||||
width: 157px;
|
||||
height: 178px;
|
||||
}
|
||||
|
||||
@@ -1,51 +1,87 @@
|
||||
.quest_TEMPLATE_FOR_MISSING_IMAGE {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -502px -1519px;
|
||||
background-position: -502px -1546px;
|
||||
width: 221px;
|
||||
height: 39px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
.quest_cow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px 0px;
|
||||
background-position: -1762px 0px;
|
||||
width: 174px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_dilatory {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dustbunnies {
|
||||
.quest_dilatoryDistress1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
background-position: -220px -1332px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.quest_egg {
|
||||
.quest_dilatoryDistress2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -362px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
background-position: -1762px -875px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -1023px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
.quest_dilatoryDistress3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
.quest_dilatory_derby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
.quest_dustbunnies {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -214px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -1026px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_frog {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px 0px;
|
||||
@@ -54,19 +90,19 @@
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px 0px;
|
||||
background-position: -660px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -220px;
|
||||
background-position: -880px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1519px;
|
||||
background-position: 0px -1546px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
@@ -78,91 +114,91 @@
|
||||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -443px -1332px;
|
||||
background-position: -1091px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -452px;
|
||||
background-position: -220px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -452px;
|
||||
background-position: -440px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_hedgehog {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1332px;
|
||||
background-position: -431px -1332px;
|
||||
width: 219px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -452px;
|
||||
background-position: -880px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -452px;
|
||||
background-position: -1100px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px 0px;
|
||||
background-position: -220px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -1332px;
|
||||
background-position: -874px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_lostMasterclasser1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -220px;
|
||||
background-position: -1100px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -440px;
|
||||
background-position: 0px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -672px;
|
||||
background-position: -220px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -570px;
|
||||
background-position: -1762px -573px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -672px;
|
||||
background-position: -660px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -672px;
|
||||
background-position: -880px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -672px;
|
||||
background-position: -1100px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -174,49 +210,49 @@
|
||||
}
|
||||
.quest_moon2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -672px;
|
||||
background-position: -1320px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px 0px;
|
||||
background-position: -1320px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -220px;
|
||||
background-position: -1320px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -440px;
|
||||
background-position: -1320px -880px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -660px;
|
||||
background-position: 0px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_nudibranch {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -431px;
|
||||
background-position: -1540px -1082px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_octopus {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -1332px;
|
||||
background-position: -651px -1332px;
|
||||
width: 222px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_owl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -892px;
|
||||
background-position: -440px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -228,25 +264,25 @@
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -178px;
|
||||
background-position: 0px -1697px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -892px;
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rat {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -892px;
|
||||
background-position: -1100px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_robot {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -892px;
|
||||
background-position: -440px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -258,139 +294,109 @@
|
||||
}
|
||||
.quest_rooster {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1528px -1332px;
|
||||
background-position: -1525px -1332px;
|
||||
width: 213px;
|
||||
height: 174px;
|
||||
}
|
||||
.quest_ruby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -892px;
|
||||
background-position: -1320px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sabretooth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -892px;
|
||||
background-position: -220px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_seaserpent {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px 0px;
|
||||
background-position: -1100px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sheep {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -220px;
|
||||
background-position: -660px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_silver {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -440px;
|
||||
background-position: 0px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_slime {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -660px;
|
||||
background-position: -880px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sloth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -880px;
|
||||
background-position: -1100px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_snail {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -1112px;
|
||||
background-position: 0px -1332px;
|
||||
width: 219px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_snake {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -877px -1332px;
|
||||
background-position: -1308px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_spider {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -251px -1519px;
|
||||
background-position: -251px -1546px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_squirrel {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1112px;
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -721px;
|
||||
background-position: -1762px -422px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_stoikalmCalamity2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -1112px;
|
||||
background-position: -880px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -1112px;
|
||||
background-position: -660px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_taskwoodsTerror1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -872px;
|
||||
background-position: -1762px -724px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_taskwoodsTerror2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -1082px;
|
||||
background-position: -1540px -431px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_taskwoodsTerror3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_treeling {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1094px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px 0px;
|
||||
width: 204px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex_undead {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1311px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_triceratops {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_turtle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -1112px;
|
||||
background-position: -440px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 470 KiB |
|
Before Width: | Height: | Size: 643 KiB After Width: | Height: | Size: 615 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 431 KiB |
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 215 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 152 KiB |
@@ -4,23 +4,47 @@
|
||||
line-height: 1.33;
|
||||
color: $gray-200;
|
||||
padding: 4px 8px;
|
||||
box-shadow: 0 1px 1px 0 rgba($black, 0.12);
|
||||
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
|
||||
}
|
||||
|
||||
.badge-pill {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.badge-round {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.badge-default {
|
||||
background: $gray-500;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.badge-dialog {
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
top: -16px;
|
||||
|
||||
.badge-pin {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-item {
|
||||
position: absolute;
|
||||
top: -9px;
|
||||
}
|
||||
|
||||
.badge-top {
|
||||
position: absolute;
|
||||
left: calc((100% - 24px) / 2);
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.badge-purple {
|
||||
position: absolute;
|
||||
color: $white;
|
||||
|
||||