Merge remote-tracking branch 'upstream/develop' into ptsFix
|
|
@ -1,4 +1,6 @@
|
|||
node_modules/**
|
||||
content_cache
|
||||
content_cache/**
|
||||
website/client/**
|
||||
test/**
|
||||
.git/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
FROM node:12
|
||||
|
||||
ENV ADMIN_EMAIL admin@habitica.com
|
||||
ENV EMAILS_COMMUNITY_MANAGER_EMAIL admin@habitica.com
|
||||
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
|
||||
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
|
||||
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
|
||||
|
|
|
|||
|
|
@ -74,5 +74,6 @@
|
|||
"TRANSIFEX_SLACK_CHANNEL": "transifex",
|
||||
"WEB_CONCURRENCY": 1,
|
||||
"SKIP_SSL_CHECK_KEY": "key",
|
||||
"ENABLE_STACKDRIVER_TRACING": "false"
|
||||
"ENABLE_STACKDRIVER_TRACING": "false",
|
||||
"BLOCKED_IPS": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
import gulp from 'gulp';
|
||||
import babel from 'gulp-babel';
|
||||
|
||||
gulp.task('build:src', () => gulp.src('website/server/**/*.js')
|
||||
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/transpiled-babel/')));
|
||||
|
||||
gulp.task('build:common', () => gulp.src('website/common/script/**/*.js')
|
||||
gulp.task('build:babel:common', () => gulp.src('website/common/script/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/common/transpiled-babel/')));
|
||||
|
||||
gulp.task('build:server', gulp.series('build:src', 'build:common', done => done()));
|
||||
gulp.task('build:babel', gulp.parallel('build:babel:server', 'build:babel:common', done => done()));
|
||||
|
||||
gulp.task('build:prod', gulp.series(
|
||||
'build:server',
|
||||
'build:babel',
|
||||
'apidoc',
|
||||
'content:cache',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
|
|
|
|||
34
gulp/gulp-content.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import gulp from 'gulp';
|
||||
import fs from 'fs';
|
||||
|
||||
// TODO parallelize, use gulp file helpers
|
||||
gulp.task('content:cache', 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 { CONTENT_CACHE_PATH, getLocalizedContent } = require('../website/server/libs/content'); // 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(CONTENT_CACHE_PATH);
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
}
|
||||
|
||||
// clone the content for each language and save
|
||||
// localize it
|
||||
// save the result
|
||||
langCodes.forEach(langCode => {
|
||||
fs.writeFileSync(
|
||||
`${CONTENT_CACHE_PATH}${langCode}.json`,
|
||||
getLocalizedContent(langCode),
|
||||
'utf8',
|
||||
);
|
||||
});
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
10
gulpfile.js
|
|
@ -13,8 +13,16 @@ 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-build'); // eslint-disable-line global-require
|
||||
} else {
|
||||
require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-content'); // 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
|
||||
require('./gulp/gulp-start'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-tests'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-transifex-test'); // eslint-disable-line global-require
|
||||
require('gulp').task('default', gulp.series('test')); // eslint-disable-line global-require
|
||||
}
|
||||
|
|
|
|||
69
migrations/archive/2020/20200402_webhooks_add_protocol.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200402_webhooks_add_protocol';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.webhooks && user.webhooks.length > 0) {
|
||||
user.webhooks.forEach(webhook => {
|
||||
// Make sure the protocol is set and valid
|
||||
if (webhook.url.startsWith('ftp')) {
|
||||
webhook.url = webhook.url.replace('ftp', 'https');
|
||||
}
|
||||
|
||||
if (!webhook.url.startsWith('http://') && !webhook.url.startsWith('https://')) {
|
||||
// the default in got 9 was https
|
||||
// see https://github.com/sindresorhus/got/commit/92bc8082137d7d085750359bbd76c801e213d7d2#diff-0730bb7c2e8f9ea2438b52e419dd86c9L111
|
||||
webhook.url = `https://${webhook.url}`;
|
||||
}
|
||||
});
|
||||
|
||||
set.webhooks = user.webhooks;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
webhooks: { $exists: true, $not: { $size: 0 } },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
webhooks: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
63
migrations/archive/2020/20200402_webhooks_reenable.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200402_webhooks_reenable';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.webhooks && user.webhooks.length > 0) {
|
||||
user.webhooks.forEach(webhook => {
|
||||
// Re-enable webhooks disabled because of too many failures
|
||||
if (webhook.enabled === false && webhook.lastFailureAt === null) {
|
||||
webhook.enabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
set.webhooks = user.webhooks;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
webhooks: { $exists: true, $not: { $size: 0 } },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
webhooks: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
|
|
@ -18,7 +18,7 @@ function setUpServer () {
|
|||
setUpServer();
|
||||
|
||||
// Replace this with your migration
|
||||
const processUsers = require('./tasks/rewards-flip-negative-costs').default;
|
||||
const processUsers = require().default;
|
||||
|
||||
processUsers()
|
||||
.then(() => {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ async function updateUser (user) {
|
|||
each(keys(content.specialPets), pet => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.wackyPets), pet => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.mounts), mount => {
|
||||
set[`items.mounts.${mount}`] = true;
|
||||
});
|
||||
|
|
@ -54,7 +57,7 @@ async function updateUser (user) {
|
|||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.local.username': 'olson22',
|
||||
'auth.local.username': 'SabreTest',
|
||||
};
|
||||
|
||||
const fields = {
|
||||
|
|
|
|||
1109
package-lock.json
generated
13
package.json
|
|
@ -1,20 +1,20 @@
|
|||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.138.1",
|
||||
"version": "4.138.5",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"@babel/register": "^7.9.0",
|
||||
"@google-cloud/trace-agent": "^4.2.5",
|
||||
"@slack/client": "^3.8.1",
|
||||
"@slack/client": "^4.12.0",
|
||||
"accepts": "^1.3.5",
|
||||
"amazon-payments": "^0.2.8",
|
||||
"amplitude": "^3.5.0",
|
||||
"apidoc": "^0.17.5",
|
||||
"apn": "^2.2.0",
|
||||
"aws-sdk": "^2.643.0",
|
||||
"aws-sdk": "^2.648.0",
|
||||
"bcrypt": "^3.0.8",
|
||||
"body-parser": "^1.18.3",
|
||||
"compression": "^1.7.4",
|
||||
|
|
@ -30,14 +30,14 @@
|
|||
"express-basic-auth": "^1.1.5",
|
||||
"express-validator": "^5.2.0",
|
||||
"glob": "^7.1.6",
|
||||
"got": "^9.0.0",
|
||||
"got": "^10.7.0",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-imagemin": "^6.2.0",
|
||||
"gulp-nodemon": "^2.5.0",
|
||||
"gulp.spritesmith": "^6.9.0",
|
||||
"habitica-markdown": "^1.3.2",
|
||||
"helmet": "^3.21.3",
|
||||
"helmet": "^3.22.0",
|
||||
"image-size": "^0.8.3",
|
||||
"in-app-purchase": "^1.11.3",
|
||||
"js2xmlparser": "^4.0.1",
|
||||
|
|
@ -46,11 +46,10 @@
|
|||
"method-override": "^3.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.9.5",
|
||||
"mongoose": "^5.9.6",
|
||||
"morgan": "^1.10.0",
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.2",
|
||||
"pageres": "^5.1.0",
|
||||
"passport": "^0.4.1",
|
||||
"passport-facebook": "^3.0.0",
|
||||
"passport-google-oauth2": "^0.2.0",
|
||||
|
|
|
|||
17
test/api/unit/libs/content.test.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import * as contentLib from '../../../../website/server/libs/content';
|
||||
import content from '../../../../website/common/script/content';
|
||||
|
||||
describe('contentLib', () => {
|
||||
describe('CONTENT_CACHE_PATH', () => {
|
||||
it('exports CONTENT_CACHE_PATH', () => {
|
||||
expect(contentLib.CONTENT_CACHE_PATH).to.be.a.string;
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLocalizedContent', () => {
|
||||
it('clones, not modify, the original content data', () => {
|
||||
contentLib.getLocalizedContent();
|
||||
expect(typeof content.backgrounds.backgrounds062014.beach.text).to.equal('function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -121,8 +121,7 @@ describe('emails', () => {
|
|||
|
||||
sendTxnEmail(mailingInfo, emailType);
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
data: {
|
||||
emailType: sinon.match.same(emailType),
|
||||
to: sinon.match(value => Array.isArray(value) && value[0].name === mailingInfo.name, 'matches mailing info array'),
|
||||
|
|
@ -154,8 +153,7 @@ describe('emails', () => {
|
|||
|
||||
sendTxnEmail(mailingInfo, emailType);
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
data: {
|
||||
emailType: sinon.match.same(emailType),
|
||||
to: sinon.match(val => val[0]._id === mailingInfo._id),
|
||||
|
|
@ -177,8 +175,7 @@ describe('emails', () => {
|
|||
|
||||
sendTxnEmail(mailingInfo, emailType, variables);
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
data: {
|
||||
variables: sinon.match(value => value[0].name === 'BASE_URL', 'matches variables'),
|
||||
personalVariables: sinon.match(value => value[0].rcpt === mailingInfo.email
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {
|
|||
CustomError,
|
||||
NotAuthorized,
|
||||
BadRequest,
|
||||
Forbidden,
|
||||
InternalServerError,
|
||||
NotFound,
|
||||
NotificationNotFound,
|
||||
|
|
@ -113,6 +114,32 @@ describe('Custom Errors', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Forbidden', () => {
|
||||
it('is an instance of CustomError', () => {
|
||||
const forbiddenError = new Forbidden();
|
||||
|
||||
expect(forbiddenError).to.be.an.instanceOf(CustomError);
|
||||
});
|
||||
|
||||
it('it returns an http code of 401', () => {
|
||||
const forbiddenError = new Forbidden();
|
||||
|
||||
expect(forbiddenError.httpCode).to.eql(403);
|
||||
});
|
||||
|
||||
it('returns a default message', () => {
|
||||
const forbiddenError = new Forbidden();
|
||||
|
||||
expect(forbiddenError.message).to.eql('Access forbidden.');
|
||||
});
|
||||
|
||||
it('allows a custom message', () => {
|
||||
const forbiddenError = new Forbidden('Custom Error Message');
|
||||
|
||||
expect(forbiddenError.message).to.eql('Custom Error Message');
|
||||
});
|
||||
});
|
||||
|
||||
describe('InternalServerError', () => {
|
||||
it('is an instance of CustomError', () => {
|
||||
const internalServerError = new InternalServerError();
|
||||
|
|
|
|||
111
test/api/unit/libs/language.test.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import {
|
||||
getLanguageFromBrowser,
|
||||
getLanguageFromUser,
|
||||
} from '../../../../website/server/libs/language';
|
||||
import {
|
||||
generateReq,
|
||||
} from '../../../helpers/api-unit.helper';
|
||||
|
||||
describe('language lib', () => {
|
||||
let req;
|
||||
|
||||
beforeEach(() => {
|
||||
req = generateReq();
|
||||
});
|
||||
|
||||
describe('getLanguageFromUser', () => {
|
||||
it('uses the user preferred language if avalaible', () => {
|
||||
const user = {
|
||||
preferences: {
|
||||
language: 'it',
|
||||
},
|
||||
};
|
||||
|
||||
expect(getLanguageFromUser(user, req)).to.equal('it');
|
||||
});
|
||||
|
||||
it('falls back to english if the user preferred language is not avalaible', () => {
|
||||
const user = {
|
||||
preferences: {
|
||||
language: 'bla',
|
||||
},
|
||||
};
|
||||
|
||||
expect(getLanguageFromUser(user, req)).to.equal('en');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLanguageFromBrowser', () => {
|
||||
it('uses browser specificed language', () => {
|
||||
req.headers['accept-language'] = 'pt';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('pt');
|
||||
});
|
||||
|
||||
it('uses first language in series if browser specifies multiple', () => {
|
||||
req.headers['accept-language'] = 'he, pt, it';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('he');
|
||||
});
|
||||
|
||||
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', () => {
|
||||
req.headers['accept-language'] = 'blah, he, pt, it';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('he');
|
||||
});
|
||||
|
||||
it('uses normal version of language if specialized locale is passed in', () => {
|
||||
req.headers['accept-language'] = 'fr-CA';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('fr');
|
||||
});
|
||||
|
||||
it('uses normal version of language if specialized locale is passed in', () => {
|
||||
req.headers['accept-language'] = 'fr-CA';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('fr');
|
||||
});
|
||||
|
||||
it('uses es if es is passed in', () => {
|
||||
req.headers['accept-language'] = 'es';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('es');
|
||||
});
|
||||
|
||||
it('uses es_419 if applicable es-languages are passed in', () => {
|
||||
req.headers['accept-language'] = 'es-mx';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('es_419');
|
||||
});
|
||||
|
||||
it('uses es_419 if multiple es languages are passed in', () => {
|
||||
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('es_419');
|
||||
});
|
||||
|
||||
it('zh', () => {
|
||||
req.headers['accept-language'] = 'zh-TW';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('zh_TW');
|
||||
});
|
||||
|
||||
it('uses english if browser specified language is not compatible', () => {
|
||||
req.headers['accept-language'] = 'blah';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('en');
|
||||
});
|
||||
|
||||
it('uses english if browser does not specify', () => {
|
||||
req.headers['accept-language'] = '';
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('en');
|
||||
});
|
||||
|
||||
it('uses english if browser does not supply an accept-language header', () => {
|
||||
delete req.headers['accept-language'];
|
||||
|
||||
expect(getLanguageFromBrowser(req)).to.equal('en');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -101,8 +101,7 @@ describe('webhooks', () => {
|
|||
expect(WebhookSender.defaultTransformData).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
json: true,
|
||||
body,
|
||||
json: body,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -122,7 +121,7 @@ describe('webhooks', () => {
|
|||
expect(sendWebhook.attachDefaultData).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
json: true,
|
||||
json: body,
|
||||
});
|
||||
|
||||
expect(body).to.eql({
|
||||
|
|
@ -153,8 +152,7 @@ describe('webhooks', () => {
|
|||
expect(WebhookSender.defaultTransformData).to.not.be.called;
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
foo: 'bar',
|
||||
baz: 'biz',
|
||||
},
|
||||
|
|
@ -271,8 +269,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
body,
|
||||
json: true,
|
||||
json: body,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -292,8 +289,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
body,
|
||||
json: true,
|
||||
json: body,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -316,12 +312,10 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledTwice;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
body,
|
||||
json: true,
|
||||
json: body,
|
||||
});
|
||||
expect(got.post).to.be.calledWithMatch('http://other-url.com', {
|
||||
body,
|
||||
json: true,
|
||||
json: body,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -351,8 +345,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
json: true,
|
||||
body,
|
||||
json: body,
|
||||
});
|
||||
|
||||
await sleep(0.1);
|
||||
|
|
@ -368,8 +361,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
|
||||
json: true,
|
||||
body,
|
||||
json: body,
|
||||
});
|
||||
|
||||
await sleep(0.1);
|
||||
|
|
@ -459,8 +451,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
type: 'scored',
|
||||
webhookType: 'taskActivity',
|
||||
user: {
|
||||
|
|
@ -497,8 +488,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch('http://global-activity.com', {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
type: 'scored',
|
||||
webhookType: 'taskActivity',
|
||||
user: {
|
||||
|
|
@ -551,8 +541,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
type,
|
||||
webhookType: 'taskActivity',
|
||||
user: {
|
||||
|
|
@ -592,8 +581,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
webhookType: 'taskActivity',
|
||||
user: {
|
||||
_id: user._id,
|
||||
|
|
@ -633,8 +621,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[2].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
type,
|
||||
webhookType: 'userActivity',
|
||||
user: {
|
||||
|
|
@ -680,8 +667,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[1].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
type,
|
||||
webhookType: 'questActivity',
|
||||
user: {
|
||||
|
|
@ -727,8 +713,7 @@ describe('webhooks', () => {
|
|||
|
||||
expect(got.post).to.be.calledOnce;
|
||||
expect(got.post).to.be.calledWithMatch(webhooks[webhooks.length - 1].url, {
|
||||
json: true,
|
||||
body: {
|
||||
json: {
|
||||
webhookType: 'groupChatReceived',
|
||||
user: {
|
||||
_id: user._id,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ describe('analytics middleware', () => {
|
|||
next = generateNext();
|
||||
});
|
||||
|
||||
it('attaches analytics object res.locals', () => {
|
||||
it('attaches analytics object to res', () => {
|
||||
const attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
||||
|
||||
attachAnalytics(req, res, next);
|
||||
|
|
|
|||
|
|
@ -21,28 +21,11 @@ describe('cron middleware', () => {
|
|||
req;
|
||||
let user;
|
||||
|
||||
beforeEach(done => {
|
||||
beforeEach(async () => {
|
||||
res = generateRes();
|
||||
req = generateReq();
|
||||
user = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username',
|
||||
lowerCaseUsername: 'username',
|
||||
email: 'email@email.email',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
user.save()
|
||||
.then(savedUser => {
|
||||
res.locals.user = savedUser;
|
||||
res.analytics = analyticsService;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
user = await res.locals.user.save();
|
||||
res.analytics = analyticsService;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
|||
94
test/api/unit/middlewares/ipBlocker.test.js
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import nconf from 'nconf';
|
||||
import requireAgain from 'require-again';
|
||||
import {
|
||||
generateRes,
|
||||
generateReq,
|
||||
generateNext,
|
||||
} from '../../../helpers/api-unit.helper';
|
||||
import { Forbidden } from '../../../../website/server/libs/errors';
|
||||
import apiError from '../../../../website/server/libs/apiError';
|
||||
|
||||
function checkErrorThrown (next) {
|
||||
expect(next).to.have.been.calledOnce;
|
||||
const calledWith = next.getCall(0).args;
|
||||
expect(calledWith[0].message).to.equal(apiError('ipAddressBlocked'));
|
||||
expect(calledWith[0] instanceof Forbidden).to.equal(true);
|
||||
}
|
||||
|
||||
function checkErrorNotThrown (next) {
|
||||
expect(next).to.have.been.calledOnce;
|
||||
const calledWith = next.getCall(0).args;
|
||||
expect(typeof calledWith[0] === 'undefined').to.equal(true);
|
||||
}
|
||||
|
||||
describe('ipBlocker middleware', () => {
|
||||
const pathToIpBlocker = '../../../../website/server/middlewares/ipBlocker';
|
||||
|
||||
let res; let req; let next;
|
||||
|
||||
beforeEach(() => {
|
||||
res = generateRes();
|
||||
req = generateReq();
|
||||
next = generateNext();
|
||||
});
|
||||
|
||||
it('is disabled when the env var is not defined', () => {
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined);
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorNotThrown(next);
|
||||
});
|
||||
|
||||
it('is disabled when the env var is an empty string', () => {
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorNotThrown(next);
|
||||
});
|
||||
|
||||
it('is disabled when the env var contains comma separated empty strings', () => {
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , ');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorNotThrown(next);
|
||||
});
|
||||
|
||||
it('does not throw when the ip does not match', () => {
|
||||
req.headers['x-forwarded-for'] = '192.168.1.1';
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorNotThrown(next);
|
||||
});
|
||||
|
||||
it('throws when a matching ip exist in x-forwarded-for', () => {
|
||||
req.headers['x-forwarded-for'] = '192.168.1.1';
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorThrown(next);
|
||||
});
|
||||
|
||||
it('trims ips in x-forwarded-for', () => {
|
||||
req.headers['x-forwarded-for'] = '192.168.1.1';
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(', 192.168.1.1 , 192.168.1.4, ');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorThrown(next);
|
||||
});
|
||||
|
||||
it('works when multiple ips are passed in x-forwarded-for', () => {
|
||||
req.headers['x-forwarded-for'] = '192.168.1.4';
|
||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1, 192.168.1.4, 192.168.1.3');
|
||||
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
|
||||
attachIpBlocker(req, res, next);
|
||||
|
||||
checkErrorThrown(next);
|
||||
});
|
||||
});
|
||||
|
|
@ -12,6 +12,9 @@ import { model as User } from '../../../../website/server/models/user';
|
|||
|
||||
const { i18n } = common;
|
||||
|
||||
// TODO some of the checks here can be simplified to simply check
|
||||
// that the right parameters are passed to the functions in libs/language
|
||||
|
||||
describe('language middleware', () => {
|
||||
describe('res.t', () => {
|
||||
let res; let req; let
|
||||
|
|
@ -19,6 +22,8 @@ describe('language middleware', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
res = generateRes();
|
||||
// remove the defaul user
|
||||
res.locals.user = undefined;
|
||||
req = generateReq();
|
||||
next = generateNext();
|
||||
|
||||
|
|
@ -57,6 +62,8 @@ describe('language middleware', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
res = generateRes();
|
||||
// remove the defaul user
|
||||
res.locals.user = undefined;
|
||||
req = generateReq();
|
||||
next = generateNext();
|
||||
attachTranslateFunction(req, res, next);
|
||||
|
|
@ -88,7 +95,7 @@ describe('language middleware', () => {
|
|||
lang: 'es',
|
||||
};
|
||||
|
||||
req.locals = {
|
||||
res.locals = {
|
||||
user: {
|
||||
preferences: {
|
||||
language: 'it',
|
||||
|
|
@ -108,7 +115,7 @@ describe('language middleware', () => {
|
|||
|
||||
context('authorized request', () => {
|
||||
it('uses the user preferred language if avalaible', () => {
|
||||
req.locals = {
|
||||
res.locals = {
|
||||
user: {
|
||||
preferences: {
|
||||
language: 'it',
|
||||
|
|
@ -122,7 +129,7 @@ describe('language middleware', () => {
|
|||
});
|
||||
|
||||
it('falls back to english if the user preferred language is not avalaible', done => {
|
||||
req.locals = {
|
||||
res.locals = {
|
||||
user: {
|
||||
preferences: {
|
||||
language: 'bla',
|
||||
|
|
@ -138,7 +145,7 @@ describe('language middleware', () => {
|
|||
});
|
||||
|
||||
it('uses the user preferred language even if a session is included in request', () => {
|
||||
req.locals = {
|
||||
res.locals = {
|
||||
user: {
|
||||
preferences: {
|
||||
language: 'it',
|
||||
|
|
|
|||
241
website/client/package-lock.json
generated
|
|
@ -5034,160 +5034,159 @@
|
|||
"integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw=="
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
"integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
||||
"integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5"
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA=="
|
||||
},
|
||||
"@webassemblyjs/helper-api-error": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
|
||||
"integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
|
||||
"integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw=="
|
||||
},
|
||||
"@webassemblyjs/helper-buffer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
|
||||
"integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
|
||||
"integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA=="
|
||||
},
|
||||
"@webassemblyjs/helper-code-frame": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
|
||||
"integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
|
||||
"integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-fsm": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
|
||||
"integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
|
||||
"integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw=="
|
||||
},
|
||||
"@webassemblyjs/helper-module-context": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
|
||||
"integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
|
||||
"integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"mamacro": "^0.0.3"
|
||||
"@webassemblyjs/ast": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
|
||||
"integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
|
||||
"integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw=="
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
|
||||
"integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
|
||||
"integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ieee754": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
|
||||
"integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
|
||||
"integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
|
||||
"requires": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/leb128": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
|
||||
"integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
|
||||
"integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
|
||||
"requires": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/utf8": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
|
||||
"integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw=="
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
|
||||
"integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w=="
|
||||
},
|
||||
"@webassemblyjs/wasm-edit": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
|
||||
"integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
|
||||
"integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-section": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-opt": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-section": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-opt": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-gen": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
|
||||
"integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
|
||||
"integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-opt": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
|
||||
"integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
|
||||
"integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-code-frame": "1.8.5",
|
||||
"@webassemblyjs/helper-fsm": "1.8.5",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-code-frame": "1.9.0",
|
||||
"@webassemblyjs/helper-fsm": "1.9.0",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-printer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
|
||||
"integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
|
||||
"integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
|
|
@ -6546,9 +6545,9 @@
|
|||
"integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA=="
|
||||
},
|
||||
"bootstrap-vue": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.8.0.tgz",
|
||||
"integrity": "sha512-yGfiJkuU4A3tz7YbCzSvpqeZ41UcmyIoWWXjmIVzBEfv93x2HSRn9zhY4qn/kffF5BX7NNSUJOlVjaR981Gh2w==",
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.9.0.tgz",
|
||||
"integrity": "sha512-L9FOIT+nsqEk+5KtrC6XQktDG0UQo+Sk1bph9VxGUmA4Y4Yixy+dABhZNLErRuhIrFysf3FAt1JEkV0tkZfpXA==",
|
||||
"requires": {
|
||||
"@nuxt/opencollective": "^0.3.0",
|
||||
"bootstrap": ">=4.4.1 <5.0.0",
|
||||
|
|
@ -12785,11 +12784,6 @@
|
|||
"semver": "^5.6.0"
|
||||
}
|
||||
},
|
||||
"mamacro": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
|
||||
"integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA=="
|
||||
},
|
||||
"map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
|
|
@ -17900,9 +17894,9 @@
|
|||
"integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw=="
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.3.9",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz",
|
||||
"integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==",
|
||||
"version": "4.6.7",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz",
|
||||
"integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==",
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.6.1",
|
||||
|
|
@ -18827,11 +18821,11 @@
|
|||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||
"integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz",
|
||||
"integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==",
|
||||
"requires": {
|
||||
"chokidar": "^2.0.2",
|
||||
"chokidar": "^2.1.8",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"neo-async": "^2.5.0"
|
||||
}
|
||||
|
|
@ -18858,14 +18852,14 @@
|
|||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.42.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz",
|
||||
"integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==",
|
||||
"version": "4.42.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz",
|
||||
"integrity": "sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/wasm-edit": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/wasm-edit": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"acorn": "^6.2.1",
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1",
|
||||
|
|
@ -18877,7 +18871,7 @@
|
|||
"loader-utils": "^1.2.3",
|
||||
"memory-fs": "^0.4.1",
|
||||
"micromatch": "^3.1.10",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mkdirp": "^0.5.3",
|
||||
"neo-async": "^2.6.1",
|
||||
"node-libs-browser": "^2.2.1",
|
||||
"schema-utils": "^1.0.0",
|
||||
|
|
@ -18887,6 +18881,19 @@
|
|||
"webpack-sources": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
"bootstrap-vue": "^2.8.0",
|
||||
"bootstrap-vue": "^2.9.0",
|
||||
"chai": "^4.1.2",
|
||||
"core-js": "^3.6.4",
|
||||
"eslint": "^6.8.0",
|
||||
|
|
@ -61,6 +61,6 @@
|
|||
"vue2-perfect-scrollbar": "^1.4.0",
|
||||
"vuedraggable": "^2.23.1",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||
"webpack": "^4.42.0"
|
||||
"webpack": "^4.42.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
'resting': showRestingBanner
|
||||
}"
|
||||
>
|
||||
<banned-account-modal />
|
||||
<!-- <banned-account-modal /> -->
|
||||
<amazon-payments-modal v-if="!isStaticPage" />
|
||||
<payments-success-modal />
|
||||
<sub-cancel-modal-confirm v-if="isUserLoaded" />
|
||||
|
|
@ -266,7 +266,6 @@ import {
|
|||
} from '@/libs/userlocalManager';
|
||||
|
||||
import svgClose from '@/assets/svg/close.svg';
|
||||
import bannedAccountModal from '@/components/bannedAccountModal';
|
||||
|
||||
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
|
||||
|
||||
|
|
@ -281,7 +280,6 @@ export default {
|
|||
BuyModal,
|
||||
SelectMembersModal,
|
||||
amazonPaymentsModal,
|
||||
bannedAccountModal,
|
||||
paymentsSuccessModal,
|
||||
subCancelModalConfirm,
|
||||
subCanceledModal,
|
||||
|
|
@ -385,7 +383,8 @@ export default {
|
|||
return response;
|
||||
}, error => {
|
||||
if (error.response.status >= 400) {
|
||||
this.checkForBannedUser(error);
|
||||
const isBanned = this.checkForBannedUser(error);
|
||||
if (isBanned === true) return null; // eslint-disable-line consistent-return
|
||||
|
||||
// Don't show errors from getting user details. These users have delete their account,
|
||||
// but their chat message still exists.
|
||||
|
|
@ -403,7 +402,8 @@ export default {
|
|||
// TODO use a specific error like NotificationNotFound instead of checking for the string
|
||||
const invalidUserMessage = [this.$t('invalidCredentials'), 'Missing authentication headers.'];
|
||||
if (invalidUserMessage.indexOf(errorMessage) !== -1) {
|
||||
this.$store.dispatch('auth:logout');
|
||||
this.$store.dispatch('auth:logout', { redirectToLogin: true });
|
||||
return null;
|
||||
}
|
||||
|
||||
// Most server errors should return is click to dismiss errors, with some exceptions
|
||||
|
|
@ -553,7 +553,7 @@ export default {
|
|||
|
||||
// Case where user is not logged in
|
||||
if (!parseSettings) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const bannedMessage = this.$t('accountSuspended', {
|
||||
|
|
@ -561,9 +561,10 @@ export default {
|
|||
userId: parseSettings.auth.apiId,
|
||||
});
|
||||
|
||||
if (errorMessage !== bannedMessage) return;
|
||||
if (errorMessage !== bannedMessage) return false;
|
||||
|
||||
this.$root.$emit('bv::show::modal', 'banned-account');
|
||||
this.$store.dispatch('auth:logout', { redirectToLogin: true });
|
||||
return true;
|
||||
},
|
||||
initializeModalStack () {
|
||||
// Manage modals
|
||||
|
|
|
|||
|
|
@ -1,96 +1,60 @@
|
|||
.promo_achievement_CottonCandyPink {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px -740px;
|
||||
width: 204px;
|
||||
height: 102px;
|
||||
}
|
||||
.promo_armoire_backgrounds_202003 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -340px -659px;
|
||||
background-position: -445px -184px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_cosplay {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 623px;
|
||||
height: 167px;
|
||||
}
|
||||
.promo_egg_quest {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px -296px;
|
||||
background-position: 0px -500px;
|
||||
width: 354px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_hugabug_bundle {
|
||||
.promo_mystery_202004 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px -148px;
|
||||
width: 420px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_mystery_202003 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px -444px;
|
||||
background-position: -355px -500px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_pi_day {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -624px -277px;
|
||||
width: 273px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_seasonal_shop_spring {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -316px -168px;
|
||||
background-position: -638px -500px;
|
||||
width: 162px;
|
||||
height: 138px;
|
||||
}
|
||||
.promo_spring_2019 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -430px -475px;
|
||||
background-position: 0px -337px;
|
||||
width: 432px;
|
||||
height: 162px;
|
||||
}
|
||||
.promo_spring_2020 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -475px;
|
||||
background-position: -445px 0px;
|
||||
width: 429px;
|
||||
height: 183px;
|
||||
}
|
||||
.promo_spring_potions_2020 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px 0px;
|
||||
background-position: -433px -337px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_take_this {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -1235px -444px;
|
||||
background-position: -151px -648px;
|
||||
width: 96px;
|
||||
height: 69px;
|
||||
}
|
||||
.scene_dailies {
|
||||
.scene_hat_guild {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -624px 0px;
|
||||
width: 327px;
|
||||
height: 276px;
|
||||
background-position: 0px 0px;
|
||||
width: 444px;
|
||||
height: 336px;
|
||||
}
|
||||
.scene_gaining_achievement {
|
||||
.scene_meditation {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -659px;
|
||||
width: 339px;
|
||||
height: 210px;
|
||||
}
|
||||
.scene_shanaqui {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -952px -592px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.scene_tough_times {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -168px;
|
||||
width: 315px;
|
||||
height: 306px;
|
||||
background-position: 0px -648px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,33 +4,39 @@
|
|||
width: 221px;
|
||||
height: 39px;
|
||||
}
|
||||
.quest_falcon {
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -232px;
|
||||
background-position: -443px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
.quest_falcon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1323px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -663px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_frog {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -1112px;
|
||||
background-position: -1543px 0px;
|
||||
width: 221px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -232px;
|
||||
background-position: -220px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -232px;
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
|
@ -48,19 +54,19 @@
|
|||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1097px -1332px;
|
||||
background-position: -1314px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -452px;
|
||||
background-position: -220px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -452px;
|
||||
background-position: -440px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
|
@ -72,109 +78,109 @@
|
|||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -452px;
|
||||
background-position: -883px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -883px 0px;
|
||||
background-position: -883px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -883px -220px;
|
||||
background-position: -883px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1314px -1332px;
|
||||
background-position: -1097px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_lostMasterclasser1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -672px;
|
||||
background-position: -220px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -672px;
|
||||
background-position: -440px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -672px;
|
||||
background-position: -660px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px -537px;
|
||||
background-position: -1765px -688px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -672px;
|
||||
background-position: -1103px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1103px 0px;
|
||||
background-position: -1103px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1103px -220px;
|
||||
background-position: -1103px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px -651px;
|
||||
background-position: -1543px -214px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_moon2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1103px -660px;
|
||||
background-position: 0px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -892px;
|
||||
background-position: -220px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -892px;
|
||||
background-position: -440px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -892px;
|
||||
background-position: -660px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -892px;
|
||||
background-position: -880px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_nudibranch {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px -434px;
|
||||
background-position: -1543px -1082px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
|
|
@ -186,79 +192,79 @@
|
|||
}
|
||||
.quest_owl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1323px 0px;
|
||||
background-position: -1323px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_peacock {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px -217px;
|
||||
background-position: -1543px -865px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px -353px;
|
||||
background-position: -1765px -353px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -443px 0px;
|
||||
background-position: -1323px -880px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rat {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1323px -880px;
|
||||
background-position: 0px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_robot {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1112px;
|
||||
background-position: -220px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rock {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px -868px;
|
||||
background-position: -1543px -431px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_rooster {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px 0px;
|
||||
background-position: -1765px 0px;
|
||||
width: 213px;
|
||||
height: 174px;
|
||||
}
|
||||
.quest_ruby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -1112px;
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sabretooth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -1112px;
|
||||
background-position: -1100px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_seaserpent {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -1112px;
|
||||
background-position: -1320px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sheep {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -1112px;
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_silver {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -1112px;
|
||||
background-position: -440px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
|
@ -270,7 +276,7 @@
|
|||
}
|
||||
.quest_sloth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1323px -220px;
|
||||
background-position: -1323px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
|
@ -282,7 +288,7 @@
|
|||
}
|
||||
.quest_snake {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px -1085px;
|
||||
background-position: -663px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
|
|
@ -300,73 +306,73 @@
|
|||
}
|
||||
.quest_stoikalmCalamity1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px -839px;
|
||||
background-position: -1765px -839px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_stoikalmCalamity2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -892px;
|
||||
background-position: -1103px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1103px -440px;
|
||||
background-position: -880px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_taskwoodsTerror1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px -688px;
|
||||
background-position: -1765px -537px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_taskwoodsTerror2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1543px 0px;
|
||||
background-position: -1543px -648px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_taskwoodsTerror3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -672px;
|
||||
background-position: 0px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_treeling {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1546px;
|
||||
background-position: -1531px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1760px -175px;
|
||||
background-position: -1765px -175px;
|
||||
width: 204px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex_undead {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1531px -1332px;
|
||||
background-position: 0px -1546px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_triceratops {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -883px -440px;
|
||||
background-position: -660px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_turtle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -452px;
|
||||
background-position: 0px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_unicorn {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -663px -220px;
|
||||
background-position: -663px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
|
@ -378,19 +384,13 @@
|
|||
}
|
||||
.quest_vice1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -663px -1332px;
|
||||
background-position: -880px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_vice2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -663px 0px;
|
||||
background-position: 0px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_vice3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 426 KiB After Width: | Height: | Size: 426 KiB |
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 140 KiB |
|
|
@ -186,7 +186,7 @@ export default {
|
|||
return this.overrideTopPadding;
|
||||
}
|
||||
|
||||
let val = '27px';
|
||||
let val = '24px';
|
||||
|
||||
if (!this.avatarOnly) {
|
||||
if (this.member.items.currentPet) val = '24px';
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@
|
|||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="achievementsCategories[key].number > 5"
|
||||
class="btn btn-flat btn-show-more"
|
||||
|
|
@ -358,7 +359,6 @@
|
|||
$t('showAllAchievements', {category: $t(key+'Achievs')})
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="col-12">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import content from '@/../../common/script/content';
|
||||
|
||||
const specialPets = Object.keys(content.specialPets);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ export async function socialAuth (store, params) {
|
|||
localStorage.setItem(LOCALSTORAGE_AUTH_KEY, userLocalData);
|
||||
}
|
||||
|
||||
export function logout () {
|
||||
export function logout (store, options = {}) {
|
||||
localStorage.clear();
|
||||
window.location.href = '/logout-server';
|
||||
const query = options.redirectToLogin === true ? '?redirectToLogin=true' : '';
|
||||
window.location.href = `/logout-server${query}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ context('avatar.vue', () => {
|
|||
};
|
||||
});
|
||||
|
||||
it('defaults to 27px', () => {
|
||||
xit('defaults to 27px', () => {
|
||||
vm.avatarOnly = true;
|
||||
expect(vm.paddingTop).to.equal('27px');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"reachedLevel": "Dosáhl jsi úrovně <%= level %>",
|
||||
"achievementLostMasterclasser": "Dokončení výprav: Série Mistra třídy",
|
||||
"achievementLostMasterclasserText": "Splnil všech šestnáct výprav v sérii výprav Mistra třídy a vyřešil záhadu Ztraceného Mistra!",
|
||||
"achievementLostMasterclasserModalText": "Dokončil jsi všech 16 masterclass výprav a vyřešil jsi tajemství ztracené masterclass!",
|
||||
"achievementLostMasterclasserModalText": "Dokončil jsi všech šestnáct výprav Mistra třídy a vyřešil jsi tajemství Ztraceného Mistra!",
|
||||
"achievementMindOverMatter": "Mysl nad hmotou",
|
||||
"achievementMindOverMatterText": "Dokončil/a kamennou, slizovou a vlněnou mazlíčkovou výpravu.",
|
||||
"achievementMindOverMatterModalText": "Dokončil jsi kamennou, slizovou a vlněnou mazlíčkovou výpravu!",
|
||||
|
|
@ -55,5 +55,12 @@
|
|||
"achievementCreatedTask": "Vytvořte úkol",
|
||||
"earnedAchievement": "Získali jste úspěch!",
|
||||
"viewAchievements": "Zobrazit úspěchy",
|
||||
"letsGetStarted": "Začněme!"
|
||||
"letsGetStarted": "Začněme!",
|
||||
"foundNewItemsCTA": "Podívej se do Tvého Inventáře a zkus zkombinovat Tvůj nový líhnoucí lektvar a vajíčko!",
|
||||
"foundNewItemsExplanation": "Splnění úkolů Ti dá šanci najít předměty, jako vajíčka, líhnoucí lektvary a jídlo.",
|
||||
"foundNewItems": "Našel jsi nové předměty!",
|
||||
"hideAchievements": "Schovat <%= kategorie %>",
|
||||
"onboardingCompleteDesc": "Získáš <strong>5 ocenění</strong> a <strong class=\"gold-amount\">100</strong> zlaťáků za dokončení seznamu.",
|
||||
"onboardingProgress": "<%= percentage %>% postup",
|
||||
"gettingStartedDesc": "Vytvoř si úkol, splň jej a pak se podívej na své odměny. Dostaneš <strong>5 ocenění</strong> a <strong class=“gold-amount”>100 zlaťáků</strong>, jakmile budeš hotový!"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,5 +72,8 @@
|
|||
"achievementTickledPink": "Rosige Bäckchen",
|
||||
"foundNewItems": "Du hast neue Gegenstände gefunden!",
|
||||
"foundNewItemsCTA": "Schau in Dein Inventar und versuche, Dein neues Schlüpfelixier mit einem Ei zu kombinieren!",
|
||||
"foundNewItemsExplanation": "Durch das Abschließen von Aufgaben erhältst Du die Chance Gegenstände, wie etwa Eier, Schlüpfelixiere und Futter, zu finden."
|
||||
"foundNewItemsExplanation": "Durch das Abschließen von Aufgaben erhältst Du die Chance, Gegenstände wie etwa Eier, Schlüpfelixiere und Futter zu finden.",
|
||||
"achievementBugBonanza": "Kostbarer Käfer",
|
||||
"achievementBugBonanzaModalText": "Du hast die Käfer-, Schmetterling-, Schnecken- und Spinnenhaustier-Quests erfüllt!",
|
||||
"achievementBugBonanzaText": "Hat die Käfer-, Schmetterling-, Schnecken- und Spinnenhaustier-Quests erfüllt."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"armoireText": "Verzauberter Schrank",
|
||||
"armoireNotesFull": "Öffne den Schrank, um zufällig spezielle Ausrüstung, Erfahrung oder Futter zu erhalten! Verbleibende Ausrüstungsgegenstände:",
|
||||
"armoireLastItem": "Du hast das letzte Stück seltener Ausrüstung im verzauberten Schrank gefunden.",
|
||||
"armoireNotesEmpty": "Im verzauberten Schrank gibt es jeweils in der ersten Woche eines Monats neue Ausrüstung. Bis dahin, klicke weiter für Erfahrung und Futter!",
|
||||
"armoireNotesEmpty": "Im verzauberten Schrank gibt es jeweils in der ersten Woche des Monats neue Ausrüstung. Bis dahin klicke weiter für Erfahrung und Futter!",
|
||||
"dropEggWolfText": "Wolfsjunges",
|
||||
"dropEggWolfMountText": "Wolfs-Reittier",
|
||||
"dropEggWolfAdjective": "ein treues",
|
||||
|
|
@ -354,5 +354,6 @@
|
|||
"premiumPotionUnlimitedNotes": "Nicht auf Eier von Quest-Haustieren anwendbar.",
|
||||
"hatchingPotionAmber": "Bernstein",
|
||||
"hatchingPotionAurora": "Polarlicht",
|
||||
"hatchingPotionRuby": "Rubinrotes"
|
||||
"hatchingPotionRuby": "Rubinrotes",
|
||||
"hatchingPotionBirchBark": "Birkenborke"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2051,5 +2051,26 @@
|
|||
"weaponArmoireBaseballBatText": "Baseballschläger",
|
||||
"shieldArmoireBaseballGloveNotes": "Perfekt für das große Turnier oder ein freundschaftliches Fangspiel zwischen zwei Aufgaben. Erhöht Stärke um <%= str %>. Verzauberter Schrank: Baseball-Set (Gegenstand 4 von 4).",
|
||||
"armorArmoireBaseballUniformNotes": "Nadelstreifen kommen nie aus der Mode. Erhöht Ausdauer und Stärke um jeweils <%= attrs %>. Verzauberter Schrank: Baseball-Set (Gegenstand 2 von 4).",
|
||||
"weaponArmoireBaseballBatNotes": "Hol Dir einen Homerun für die guten Gewohnheiten! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Baseball-Set (Gegenstand 3 von 4)."
|
||||
"weaponArmoireBaseballBatNotes": "Hol Dir einen Homerun für die guten Gewohnheiten! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Baseball-Set (Gegenstand 3 von 4).",
|
||||
"headAccessoryMystery202004Text": "Mächtige Monarchfalterfühler",
|
||||
"backMystery202004Text": "Mächtige Monarchfalterflügel",
|
||||
"shieldSpecialSpring2020HealerText": "Duftschild",
|
||||
"shieldSpecialSpring2020WarriorText": "Irisierender Schild",
|
||||
"headSpecialSpring2020HealerText": "Iris-Fascinator",
|
||||
"headSpecialSpring2020WarriorText": "Käferhelm",
|
||||
"headSpecialSpring2020RogueText": "Lapislazuli Kabuto-Helm",
|
||||
"armorSpecialSpring2020HealerText": "Beschützendes Blütenblatt",
|
||||
"armorSpecialSpring2020MageText": "Whirlpfützenumhang",
|
||||
"armorSpecialSpring2020WarriorNotes": "Diese harte Schale kann Dich selbst vor den vernichtendsten Attacken schützen. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"armorSpecialSpring2020WarriorText": "Exoskelettrüstung",
|
||||
"armorSpecialSpring2020RogueNotes": "Die Farbe der Dämmerung, einer Vielzahl wertvoller Steine, der tiefsten Stelle des Meeres! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"armorSpecialSpring2020RogueText": "Ultramarinblaue Rüstung",
|
||||
"weaponSpecialSpring2020HealerNotes": "Eine Iris ist schön, aber ihre Blätter sind scharf wie Schwerter... lass Dich nicht von den Blumen in die Irre führen, dieser Stab ist hart wie Stahl! Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"weaponSpecialSpring2020HealerText": "Schwertlilienstab",
|
||||
"weaponSpecialSpring2020MageNotes": "Sie fallen Dir unaufhörlich auf den Kopf! Aber Du wirst sie nie aufhalten, indem Du Dich beklagst. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"weaponSpecialSpring2020MageText": "Regentropfen",
|
||||
"weaponSpecialSpring2020WarriorNotes": "Kämpfen oder Fliehen, dieser Flügel wird Dir einen guten Dienst erweisen! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"weaponSpecialSpring2020WarriorText": "Geschliffener Flügel",
|
||||
"weaponSpecialSpring2020RogueNotes": "Du wirst so schnell zuschlagen, dass sie NOCH blauer aussehen wird! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
|
||||
"weaponSpecialSpring2020RogueText": "Lapislazuli Klinge"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,45 +85,45 @@
|
|||
"scarecrowWarriorSet": "Vogelscheuchenkrieger (Krieger)",
|
||||
"stitchWitchSet": "Stichhexe (Magier)",
|
||||
"potionerSet": "Tränkebrauer (Heiler)",
|
||||
"battleRogueSet": "Kampfschurke (Schurke)",
|
||||
"battleRogueSet": "Kampf-Fleder (Schurke)",
|
||||
"springingBunnySet": "Hüpfendes Häschen (Heiler)",
|
||||
"grandMalkinSet": "Prächtiger Kater (Magier)",
|
||||
"cleverDogSet": "Schlauer Hund (Schurke)",
|
||||
"braveMouseSet": "Mutige Maus (Krieger)",
|
||||
"summer2016SharkWarriorSet": "Haifisch-Krieger (Krieger)",
|
||||
"summer2016DolphinMageSet": "Delfin-Magier (Magier)",
|
||||
"summer2016SeahorseHealerSet": "Seepferdchen-Heiler (Heiler)",
|
||||
"summer2016EelSet": "Zitteraal-Schurke (Schurke)",
|
||||
"summer2016SharkWarriorSet": "Haifisch(Krieger)",
|
||||
"summer2016DolphinMageSet": "Delfin (Magier)",
|
||||
"summer2016SeahorseHealerSet": "Seepferdchen (Heiler)",
|
||||
"summer2016EelSet": "Zitteraal (Schurke)",
|
||||
"fall2016SwampThingSet": "Das Ding aus dem Sumpf (Krieger)",
|
||||
"fall2016WickedSorcererSet": "Boshafter Zauberer (Magier)",
|
||||
"fall2016GorgonHealerSet": "Gorgonen-Heiler (Heiler)",
|
||||
"fall2016BlackWidowSet": "Schurkische Schwarze Witwe (Schurke)",
|
||||
"fall2016GorgonHealerSet": "Gorgone (Heiler)",
|
||||
"fall2016BlackWidowSet": "Schwarze Witwe (Schurke)",
|
||||
"winter2017IceHockeySet": "Eishockey (Krieger)",
|
||||
"winter2017WinterWolfSet": "Winterwolf (Magier)",
|
||||
"winter2017SugarPlumSet": "Zuckerpflaumen-Heiler (Heiler)",
|
||||
"winter2017FrostyRogueSet": "Frostiger Schurke (Schurke)",
|
||||
"spring2017FelineWarriorSet": "Katzenhafter Krieger (Krieger)",
|
||||
"winter2017SugarPlumSet": "Zuckerpflaume (Heiler)",
|
||||
"winter2017FrostyRogueSet": "Frosty (Schurke)",
|
||||
"spring2017FelineWarriorSet": "Katzenhaft (Krieger)",
|
||||
"spring2017CanineConjurorSet": "Bellender Beschwörer (Magier)",
|
||||
"spring2017FloralMouseSet": "Blumenmaus (Heiler)",
|
||||
"spring2017SneakyBunnySet": "Raffiniertes Häschen (Schurke)",
|
||||
"summer2017SandcastleWarriorSet": "Sandburg-Krieger (Krieger)",
|
||||
"summer2017WhirlpoolMageSet": "Whirlpool-Magier (Magier)",
|
||||
"summer2017SandcastleWarriorSet": "Sandburg (Krieger)",
|
||||
"summer2017WhirlpoolMageSet": "Whirlpool (Magier)",
|
||||
"summer2017SeashellSeahealerSet": "Muschel-Meeresheiler (Heiler)",
|
||||
"summer2017SeaDragonSet": "Seedrache (Schurke)",
|
||||
"fall2017HabitoweenSet": "Habitoween-Krieger (Krieger)",
|
||||
"fall2017MasqueradeSet": "Maskerade-Magier (Magier)",
|
||||
"fall2017HauntedHouseSet": "Geisterhaus-Heiler (Heiler)",
|
||||
"fall2017TrickOrTreatSet": "Süßes-oder-Saures-Schurke (Schurke)",
|
||||
"winter2018ConfettiSet": "Konfettimagier (Magier)",
|
||||
"winter2018GiftWrappedSet": "Geschenkpapierverpackter Krieger (Krieger)",
|
||||
"winter2018MistletoeSet": "Mistelzweigheiler (Heiler)",
|
||||
"winter2018ReindeerSet": "Rentier-Schurke (Schurke)",
|
||||
"spring2018SunriseWarriorSet": "Sonnenaufgang-Krieger (Krieger)",
|
||||
"spring2018TulipMageSet": "Tulpenmagier (Magier)",
|
||||
"spring2018GarnetHealerSet": "Granatheiler (Heiler)",
|
||||
"spring2018DucklingRogueSet": "Entchen-Schurke (Schurke)",
|
||||
"summer2018BettaFishWarriorSet": "Kampffisch-Krieger (Krieger)",
|
||||
"summer2018LionfishMageSet": "Feuerfisch-Magier (Magier)",
|
||||
"fall2017HabitoweenSet": "Habitoween (Krieger)",
|
||||
"fall2017MasqueradeSet": "Maskerade (Magier)",
|
||||
"fall2017HauntedHouseSet": "Geisterhaus (Heiler)",
|
||||
"fall2017TrickOrTreatSet": "Süßes oder Saures (Schurke)",
|
||||
"winter2018ConfettiSet": "Konfetti (Magier)",
|
||||
"winter2018GiftWrappedSet": "Geschenkpapierverpackt (Krieger)",
|
||||
"winter2018MistletoeSet": "Mistelzweig(Heiler)",
|
||||
"winter2018ReindeerSet": "Rentier (Schurke)",
|
||||
"spring2018SunriseWarriorSet": "Sonnenaufgang (Krieger)",
|
||||
"spring2018TulipMageSet": "Tulpe (Magier)",
|
||||
"spring2018GarnetHealerSet": "Granat (Heiler)",
|
||||
"spring2018DucklingRogueSet": "Entchen (Schurke)",
|
||||
"summer2018BettaFishWarriorSet": "Kampffisch (Krieger)",
|
||||
"summer2018LionfishMageSet": "Feuerfisch (Magier)",
|
||||
"summer2018MerfolkMonarchSet": "Meervolk-Monarch (Heiler)",
|
||||
"summer2018FisherRogueSet": "Fischdieb (Schurke)",
|
||||
"fall2018MinotaurWarriorSet": "Minotaurus (Krieger)",
|
||||
|
|
@ -173,5 +173,10 @@
|
|||
"winter2020WinterSpiceSet": "Wintergewürz (Heiler)",
|
||||
"winter2020CarolOfTheMageSet": "Weihnachtslied des Magiers (Magier)",
|
||||
"winter2020EvergreenSet": "Immergrün (Krieger)",
|
||||
"decemberYYYY": "Dezember <%= year %>"
|
||||
"decemberYYYY": "Dezember <%= year %>",
|
||||
"spring2020BeetleWarriorSet": "Nashornkäfer (Krieger)",
|
||||
"marchYYYY": "März <%= year %>",
|
||||
"spring2020LapisLazuliRogueSet": "Lapislazuli (Schurke)",
|
||||
"spring2020IrisHealerSet": "Iris (Heiler)",
|
||||
"spring2020PuddleMageSet": "Pfütze (Magier)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
"hatchingPotion": "Schlüpfelixier",
|
||||
"noHatchingPotions": "Du hast im Moment keine Schlüpfelixiere.",
|
||||
"inventoryText": "Klicke auf ein Ei um die anwendbaren Elixiere grün hervorgehoben zu sehen. Klicke dann auf ein hervorgehobenes Elixier, um Dein Haustier auszubrüten. Falls kein Elixier hervorgehoben wird, klicke auf das Ei um es abzuwählen und klicke diesmal zuerst auf das Elixier, um die Eier hervorzuheben. Du kannst überflüssige Gegenstände auch an Alexander den Händler verkaufen.",
|
||||
"haveHatchablePet": "Du hast ein <%= potion %> Schlüpfelixier und ein <%= egg %>-Ei, um dieses Haustier auszubrüten! <b>Klicke</b> auf den Pfotenabdruck, damit es schlüpft.",
|
||||
"haveHatchablePet": "Du hast ein <%= potion %> Schlüpfelixier und ein <%= egg %>-Ei, um dieses Haustier auszubrüten! <b>Klicke</b>, damit es schlüpft.",
|
||||
"quickInventory": "Schnell-Inventar",
|
||||
"foodText": "Futter",
|
||||
"food": "Futter und magische Sättel",
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@
|
|||
"questRubyCollectRubyGems": "Rubine",
|
||||
"questRubyCollectVenusRunes": "Venus-Runen",
|
||||
"questRubyCollectAquariusRunes": "Wassermann-Tierkreis-Runen",
|
||||
"questRubyText": "Die Rubinrote Lösung",
|
||||
"questRubyText": "Rubinrote Reaktion",
|
||||
"questRubyCompletion": "Nachdem die notwendigen Gegenstände sicher verstaut sind, eilen Sie drei zurück nach Habit City und treffen sich in @ beffymaroos Labor. \"Ausgezeichnete Arbeit!\" @beffymaroo sagt. \"Du hast die Zutaten für den Trank gesammelt!“ <br> <br> @beffymaroo kombiniert sorgfältig die Runen und Rubine zu einem leuchtend roten Trank und gießt einen Teil davon auf zwei Haustier-Eier. Wenn Sie die Ergebnisse beobachten, bemerken Sie, dass die beiden Haustiere völlig uninteressiert aneinander zu sein scheinen! <br> <br> \"Hat es nicht funktioniert?“ @Gully fragt. Aber bevor jemand antworten kann, merkt man plötzlich, dass es nicht der Trank ist, der Freundschaft und Liebe schafft, sondern die Erfahrung, gemeinsam auf ein gemeinsames Ziel hinzuarbeiten. Du kommst von der Suche weg, nachdem du neue Freunde gewonnen hast ... und einige auffällige neue Haustiere!",
|
||||
"questRubyNotes": "Die normalerweise geschäftigen Gipfel der Stoïkalm-Vulkane liegen still im Schnee. \"Ich nehme an, die Wanderer und Seher halten Winterschlaf?\" @gully sagt zu dir und @Aspiring_Advocate. \"Das erleichtert uns die Suche.\" <br> <br> Wenn Sie den Gipfel erreichen, verschmilzt der kühle Wind mit dem Dampf, der aus dem Krater aufsteigt. \"Dort!\" @Aspiring_Advocate ruft aus und zeigt auf eine heiße Quelle. \"Welchen besseren Ort gibt es, um kühle Runen des Wassermanns und leidenschaftliche Runen der Venus zu finden, als wo sich Eis und Feuer treffen?“ <br> <br> Sie drei beeilen sich in Richtung der heißen Quelle. \"Laut meiner Forschung\", sagt @Aspiring_Advocate, \"wird die Kombination der Runen mit herzförmigen Rubinen einen Schlupftrank erzeugen, der Freundschaft und Liebe fördern kann!\" <br> <br> Aufgeregt von der Aussicht auf eine neue Entdeckung, Sie alle Lächeln. \"In Ordnung\", sagt @gully, \"fangen wir an zu suchen!\""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@
|
|||
"goToSettings": "Gehe zu Einstellungen",
|
||||
"usernameVerifiedConfirmation": "Dein Benutzername, <%= username %>, ist bestätigt!",
|
||||
"usernameNotVerified": "Bitte bestätige Deinen Benutzernamen.",
|
||||
"changeUsernameDisclaimer": "Dieser Benutzername wird für Einladungen, @Erwähnungen im Chat und Nachrichten verwendet werden.",
|
||||
"changeUsernameDisclaimer": "Dein Benutzername wird für Einladungen, @Erwähnungen im Chat und Nachrichten verwendet. Er muss zwischen 1 und 20 Zeichen haben, darf nur Buchstaben von a bis z, Ziffern von 0 bis 9, Bindestriche oder Unterstriche beinhalten und darf keine unpassenden Ausdrücke enthalten.",
|
||||
"verifyUsernameVeteranPet": "Eines dieser Veteranen-Haustiere wartet auf Dich wenn Du die Bestätigung abgeschlossen hast!",
|
||||
"subscriptionReminders": "Abonnement-Erinnerung",
|
||||
"newPMNotificationTitle": "Neue Nachricht von <%= name %>",
|
||||
|
|
|
|||
|
|
@ -247,5 +247,6 @@
|
|||
"subMonths": "Monate abonniert",
|
||||
"subscriptionStats": "Abonnenten-Attributwerte",
|
||||
"doubleDropCap": "Verdopple die Beute",
|
||||
"mysterySet202003": "Stachliges Streitgewandset"
|
||||
"mysterySet202003": "Stachliges Streitgewandset",
|
||||
"mysterySet202004": "Mächtiger-Monarch-Set"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1984,6 +1984,8 @@
|
|||
"backMystery201912Notes": "Glide silently across sparkling snowfields and shimmering mountains with these icy wings. Confers no benefit. December 2019 Subscriber Item.",
|
||||
"backMystery202001Text": "Five Tails of Fable",
|
||||
"backMystery202001Notes": "These fluffy tails contain celestial power, and also a high level of cuteness! Confers no benefit. January 2020 Subscriber Item.",
|
||||
"backMystery202004Text": "Mighty Monarch Wings",
|
||||
"backMystery202004Notes": "Make a quick flutter to the nearest flowery meadow or migrate across the continent with these beautiful wings! Confers no benefit. April 2020 Subscriber Item.",
|
||||
|
||||
"backSpecialWonderconRedText": "Mighty Cape",
|
||||
"backSpecialWonderconRedNotes": "Swishes with strength and beauty. Confers no benefit. Special Edition Convention Item.",
|
||||
|
|
@ -2162,6 +2164,8 @@
|
|||
"headAccessoryMystery201906Notes": "Legend has it these finny ears help merfolk hear the calls and songs of all the denizens of the deep! Confers no benefit. June 2019 Subscriber Item.",
|
||||
"headAccessoryMystery201908Text": "Footloose Faun Horns",
|
||||
"headAccessoryMystery201908Notes": "If wearing horns floats your goat, you're in luck! Confers no benefit. August 2019 Subscriber Item.",
|
||||
"headAccessoryMystery202004Text": "Mighty Monarch Antennae",
|
||||
"headAccessoryMystery202004Notes": "They twitch just a bit if the scent of flowers drifts by--use them to find a pretty garden! Confers no benefit. April 2020 Subscriber Item.",
|
||||
"headAccessoryMystery301405Text": "Headwear Goggles",
|
||||
"headAccessoryMystery301405Notes": "\"Goggles are for your eyes,\" they said. \"Nobody wants goggles that you can only wear on your head,\" they said. Hah! You sure showed them! Confers no benefit. August 3015 Subscriber Item.",
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
"hatchingPotion": "hatching potion",
|
||||
"noHatchingPotions": "You don't have any hatching potions.",
|
||||
"inventoryText": "Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant.",
|
||||
"haveHatchablePet": "You have a <%= potion %> hatching potion and <%= egg %> egg to hatch this pet! <b>Click</b> the paw print to hatch.",
|
||||
"haveHatchablePet": "You have a <%= potion %> hatching potion and <%= egg %> egg to hatch this pet! <b>Click</b> to hatch!",
|
||||
"quickInventory": "Quick Inventory",
|
||||
"food": "Pet Food and Saddles",
|
||||
"noFoodAvailable": "You don't have any Pet Food.",
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@
|
|||
"mysterySet202001": "Fabled Fox Set",
|
||||
"mysterySet202002": "Stylish Sweetheart Set",
|
||||
"mysterySet202003": "Barbed Battler Set",
|
||||
"mysterySet202004": "Mighty Monarch Set",
|
||||
"mysterySet301404": "Steampunk Standard Set",
|
||||
"mysterySet301405": "Steampunk Accessories Set",
|
||||
"mysterySet301703": "Peacock Steampunk Set",
|
||||
|
|
|
|||
|
|
@ -69,5 +69,11 @@
|
|||
"achievementRosyOutlook": "Rosy Lookout",
|
||||
"achievementTickledPinkModalText": "Ye've collected all th' Cotton Candy Pink Critters!",
|
||||
"achievementTickledPinkText": "'as collected all Cotton Candy Pink Critters.",
|
||||
"achievementTickledPink": "Pickled Pink"
|
||||
"achievementTickledPink": "Pickled Pink",
|
||||
"foundNewItemsCTA": "Head t' yer inventory an' try combinin' yer new 'atchin' potion an' egg!",
|
||||
"foundNewItemsExplanation": "Completin' tasks gives ye a chance ta find new items, like eggs, 'atchin' potions, an' vittles.",
|
||||
"foundNewItems": "Ye found somethin' new!",
|
||||
"achievementBugBonanzaModalText": "Ye've kermpleted th' Beetle, Butterfly, Snail, an' Spidey pet quests!",
|
||||
"achievementBugBonanzaText": "'as kermpleted Beetle, Butterfly, Snail, an' Spidey pet quests.",
|
||||
"achievementBugBonanza": "Crawly Catcher"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1813,5 +1813,7 @@
|
|||
"weaponSpecialWinter2020MageNotes": "Wiv practice, ye kin perject this aural magic (in waves! Like th' sea!!) any way ye like: a thoughtful hum, a festive chime, er a RED TASK O'ERBOARD ALARM. Raises yer Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
|
||||
"weaponSpecialWinter2020MageText": "Ripplin' Waves o' Sound",
|
||||
"weaponSpecialWinter2020WarriorNotes": "Avast, squirrels! Ye'll get no piece o' this! ...But iffen ye wanna hang out an' 'ave cocoa, that be cool. Raises yer Strength by <%= str %>. Limited Edition 2019-2020 Winter Gear.",
|
||||
"weaponSpecialWinter2020WarriorText": "Pointy Conny-fer Cone"
|
||||
"weaponSpecialWinter2020WarriorText": "Pointy Conny-fer Cone",
|
||||
"weaponSpecialSpring2020RogueNotes": "Ye'll strike so fast it'll look e'en MORE blue! Raises yer Strength by <%= str %>. Limited Edition 2020 Spring Gear.",
|
||||
"weaponSpecialSpring2020RogueText": "Laz-yer-rite Blade"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@
|
|||
"achievementTickledPinkText": "Has collected all Cotton Candy Pink Pets.",
|
||||
"achievementTickledPink": "Tickled Pink",
|
||||
"foundNewItemsCTA": "Head to your Inventory and try combining your new hatching potion and egg!",
|
||||
"foundNewItemsExplanation": "Completing tasks gives you a chance to find items, like eggs, hatching potions, and food.",
|
||||
"foundNewItems": "You found new items!"
|
||||
"foundNewItemsExplanation": "Completing tasks gives you a chance to find items, like Eggs, Hatching Potions, and Pet Food.",
|
||||
"foundNewItems": "You found new items!",
|
||||
"achievementBugBonanzaModalText": "You completed the Beetle, Butterfly, Snail, and Spider pet quests!",
|
||||
"achievementBugBonanzaText": "Has completed Beetle, Butterfly, Snail, and Spider pet quests.",
|
||||
"achievementBugBonanza": "Bug Bonanza"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -354,5 +354,6 @@
|
|||
"questEggDolphinAdjective": "a chipper",
|
||||
"questEggDolphinMountText": "Dolphin",
|
||||
"questEggDolphinText": "Dolphin",
|
||||
"hatchingPotionRuby": "Ruby"
|
||||
"hatchingPotionRuby": "Ruby",
|
||||
"hatchingPotionBirchBark": "Birch Bark"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2051,5 +2051,37 @@
|
|||
"armorArmoireBaseballUniformNotes": "Pinstripes never go out of style. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Baseball Set (Item 2 of 4).",
|
||||
"armorArmoireBaseballUniformText": "Baseball Uniform",
|
||||
"weaponArmoireBaseballBatNotes": "Get a home run on those good habits! Increases Constitution by <%= con %>. Enchanted Armoire: Baseball Set (Item 3 of 4).",
|
||||
"weaponArmoireBaseballBatText": "Baseball Bat"
|
||||
"weaponArmoireBaseballBatText": "Baseball Bat",
|
||||
"shieldSpecialSpring2020HealerNotes": "Ward off those musty old To-Dos with this sweet-smelling shield. Increases Constitution by <%= con %>. Limited Edition 2020 Spring Gear.",
|
||||
"shieldSpecialSpring2020HealerText": "Perfumed Shield",
|
||||
"shieldSpecialSpring2020WarriorNotes": "Don't let the delicate colors fool you. This shield has got you covered! Increases Constitution by <%= con %>. Limited Edition 2020 Spring Gear.",
|
||||
"shieldSpecialSpring2020WarriorText": "Iridescent Shield",
|
||||
"headSpecialSpring2020HealerNotes": "Beguile your foes with this headpiece made of flowers! Increases Intelligence by <%= int %>. Limited Edition 2020 Spring Gear.",
|
||||
"headSpecialSpring2020HealerText": "Iris Fascinator",
|
||||
"headSpecialSpring2020MageNotes": "Is the sky clear? Humidity low? Don't worry, we've got you. Moisten your magic without dampening your spirits! Increases Perception by <%= per %>. Limited Edition 2020 Spring Gear.",
|
||||
"headSpecialSpring2020MageText": "Drip Top Cap",
|
||||
"headSpecialSpring2020WarriorNotes": "Your enemies' blows will glance off this beetle-inspired helm! Increases Strength by <%= str %>. Limited Edition 2020 Spring Gear.",
|
||||
"headSpecialSpring2020WarriorText": "Beetle Helm",
|
||||
"headSpecialSpring2020RogueNotes": "So vibrant and valuable, you'll be tempted to steal it off your own head. Increases Perception by <%= per %>. Limited Edition 2020 Spring Gear.",
|
||||
"headSpecialSpring2020RogueText": "Lapis Kabuto",
|
||||
"armorSpecialSpring2020HealerNotes": "Wrap yourself in soft iris leaves and petals to fool enemies into underestimating your healing power. Increases Constitution by <%= con %>. Limited Edition 2020 Spring Gear.",
|
||||
"armorSpecialSpring2020HealerText": "Protective Petals",
|
||||
"armorSpecialSpring2020MageNotes": "If you can't resist stomping through the leavings of rainstorms, this armour is for you! Turn a childish impulse into a display of mystic artistry. Increases Intelligence by <%= int %>. Limited Edition 2020 Spring Gear.",
|
||||
"armorSpecialSpring2020MageText": "Whirlpuddle Gown",
|
||||
"armorSpecialSpring2020WarriorNotes": "This rigid carapace can keep you safe from even the most crushing attacks. Increases Constitution by <%= con %>. Limited Edition 2020 Spring Gear.",
|
||||
"armorSpecialSpring2020WarriorText": "Exoskeleton Armour",
|
||||
"armorSpecialSpring2020RogueNotes": "The colour of twilight, of a multitude of precious stones, of the deepest sea! Increases Perception by <%= per %>. Limited Edition 2020 Spring Gear.",
|
||||
"armorSpecialSpring2020RogueText": "Ultramarine Armour",
|
||||
"weaponSpecialSpring2020HealerNotes": "An iris is beautiful, but the leaves are like swords... don't be deceived by the flowers, this staff is tough as steel! Increases Intelligence by <%= int %>. Limited Edition 2020 Spring Gear.",
|
||||
"weaponSpecialSpring2020HealerText": "Sword-Lily Staff",
|
||||
"weaponSpecialSpring2020MageNotes": "They keep falling on your head! But you'll never stop them by complaining. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2020 Spring Gear.",
|
||||
"weaponSpecialSpring2020MageText": "Raindrops",
|
||||
"weaponSpecialSpring2020WarriorNotes": "Fight or flight, this wing will serve you well! Increases Strength by <%= str %>. Limited Edition 2020 Spring Gear.",
|
||||
"weaponSpecialSpring2020WarriorText": "Sharpened Wing",
|
||||
"weaponSpecialSpring2020RogueNotes": "You'll strike so fast it'll look even MORE blue! Increases Strength by <%= str %>. Limited Edition 2020 Spring Gear.",
|
||||
"weaponSpecialSpring2020RogueText": "Lazurite Blade",
|
||||
"headAccessoryMystery202004Notes": "They twitch just a bit if the scent of flowers drifts by--use them to find a pretty garden! Confers no benefit. April 2020 Subscriber Item.",
|
||||
"headAccessoryMystery202004Text": "Mighty Monarch Antennae",
|
||||
"backMystery202004Notes": "Make a quick flutter to the nearest flowery meadow or migrate across the continent with these beautiful wings! Confers no benefit. April 2020 Subscriber Item.",
|
||||
"backMystery202004Text": "Mighty Monarch Wings"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,45 +85,45 @@
|
|||
"scarecrowWarriorSet": "Scarecrow Warrior (Warrior)",
|
||||
"stitchWitchSet": "Stitch Witch (Mage)",
|
||||
"potionerSet": "Potioner (Healer)",
|
||||
"battleRogueSet": "Bat-tle Rogue (Rogue)",
|
||||
"battleRogueSet": "Bat-tle (Rogue)",
|
||||
"springingBunnySet": "Springing Bunny (Healer)",
|
||||
"grandMalkinSet": "Grand Malkin (Mage)",
|
||||
"cleverDogSet": "Clever Dog (Rogue)",
|
||||
"braveMouseSet": "Brave Mouse (Warrior)",
|
||||
"summer2016SharkWarriorSet": "Shark Warrior (Warrior)",
|
||||
"summer2016DolphinMageSet": "Dolphin Mage (Mage)",
|
||||
"summer2016SeahorseHealerSet": "Seahorse Healer (Healer)",
|
||||
"summer2016EelSet": "Eel Rogue (Rogue)",
|
||||
"summer2016SharkWarriorSet": "Shark (Warrior)",
|
||||
"summer2016DolphinMageSet": "Dolphin (Mage)",
|
||||
"summer2016SeahorseHealerSet": "Seahorse (Healer)",
|
||||
"summer2016EelSet": "Eel (Rogue)",
|
||||
"fall2016SwampThingSet": "Swamp Thing (Warrior)",
|
||||
"fall2016WickedSorcererSet": "Wicked Sorcerer (Mage)",
|
||||
"fall2016GorgonHealerSet": "Gorgon Healer (Healer)",
|
||||
"fall2016BlackWidowSet": "Black Widow Rogue (Rogue)",
|
||||
"fall2016GorgonHealerSet": "Gorgon (Healer)",
|
||||
"fall2016BlackWidowSet": "Black Widow (Rogue)",
|
||||
"winter2017IceHockeySet": "Ice Hockey (Warrior)",
|
||||
"winter2017WinterWolfSet": "Winter Wolf (Mage)",
|
||||
"winter2017SugarPlumSet": "Sugar Plum Healer (Healer)",
|
||||
"winter2017FrostyRogueSet": "Frosty Rogue (Rogue)",
|
||||
"spring2017FelineWarriorSet": "Feline Warrior (Warrior)",
|
||||
"winter2017SugarPlumSet": "Sugar Plum (Healer)",
|
||||
"winter2017FrostyRogueSet": "Frosty (Rogue)",
|
||||
"spring2017FelineWarriorSet": "Feline (Warrior)",
|
||||
"spring2017CanineConjurorSet": "Canine Conjuror (Mage)",
|
||||
"spring2017FloralMouseSet": "Floral Mouse (Healer)",
|
||||
"spring2017SneakyBunnySet": "Sneaky Bunny (Rogue)",
|
||||
"summer2017SandcastleWarriorSet": "Sandcastle Warrior (Warrior)",
|
||||
"summer2017WhirlpoolMageSet": "Whirlpool Mage (Mage)",
|
||||
"summer2017SandcastleWarriorSet": "Sandcastle (Warrior)",
|
||||
"summer2017WhirlpoolMageSet": "Whirlpool (Mage)",
|
||||
"summer2017SeashellSeahealerSet": "Seashell Seahealer (Healer)",
|
||||
"summer2017SeaDragonSet": "Sea Dragon (Rogue)",
|
||||
"fall2017HabitoweenSet": "Habitoween Warrior (Warrior)",
|
||||
"fall2017MasqueradeSet": "Masquerade Mage (Mage)",
|
||||
"fall2017HauntedHouseSet": "Haunted House Healer (Healer)",
|
||||
"fall2017TrickOrTreatSet": "Trick or Treat Rogue (Rogue)",
|
||||
"winter2018ConfettiSet": "Confetti Mage (Mage)",
|
||||
"winter2018GiftWrappedSet": "Gift-Wrapped Warrior (Warrior)",
|
||||
"winter2018MistletoeSet": "Mistletoe Healer (Healer)",
|
||||
"winter2018ReindeerSet": "Reindeer Rogue (Rogue)",
|
||||
"spring2018SunriseWarriorSet": "Sunrise Warrior (Warrior)",
|
||||
"spring2018TulipMageSet": "Tulip Mage (Mage)",
|
||||
"spring2018GarnetHealerSet": "Garnet Healer (Healer)",
|
||||
"spring2018DucklingRogueSet": "Duckling Rogue (Rogue)",
|
||||
"summer2018BettaFishWarriorSet": "Betta Fish Warrior (Warrior)",
|
||||
"summer2018LionfishMageSet": "Lionfish Mage (Mage)",
|
||||
"fall2017HabitoweenSet": "Habitoween (Warrior)",
|
||||
"fall2017MasqueradeSet": "Masquerade (Mage)",
|
||||
"fall2017HauntedHouseSet": "Haunted House (Healer)",
|
||||
"fall2017TrickOrTreatSet": "Trick or Treat (Rogue)",
|
||||
"winter2018ConfettiSet": "Confetti (Mage)",
|
||||
"winter2018GiftWrappedSet": "Gift-Wrapped (Warrior)",
|
||||
"winter2018MistletoeSet": "Mistletoe (Healer)",
|
||||
"winter2018ReindeerSet": "Reindeer (Rogue)",
|
||||
"spring2018SunriseWarriorSet": "Sunrise (Warrior)",
|
||||
"spring2018TulipMageSet": "Tulip (Mage)",
|
||||
"spring2018GarnetHealerSet": "Garnet (Healer)",
|
||||
"spring2018DucklingRogueSet": "Duckling (Rogue)",
|
||||
"summer2018BettaFishWarriorSet": "Betta Fish (Warrior)",
|
||||
"summer2018LionfishMageSet": "Lionfish (Mage)",
|
||||
"summer2018MerfolkMonarchSet": "Merfolk Monarch (Healer)",
|
||||
"summer2018FisherRogueSet": "Fisher-Rogue (Rogue)",
|
||||
"fall2018MinotaurWarriorSet": "Minotaur (Warrior)",
|
||||
|
|
@ -173,5 +173,10 @@
|
|||
"summer2019ConchHealerSet": "Conch (Healer)",
|
||||
"summer2019WaterLilyMageSet": "Water Lily (Mage)",
|
||||
"summer2019SeaTurtleWarriorSet": "Sea Turtle (Warrior)",
|
||||
"june2018": "June 2018"
|
||||
"june2018": "June 2018",
|
||||
"marchYYYY": "March <%= year %>",
|
||||
"spring2020LapisLazuliRogueSet": "Lapis Lazuli (Rogue)",
|
||||
"spring2020IrisHealerSet": "Iris (Healer)",
|
||||
"spring2020PuddleMageSet": "Puddle (Mage)",
|
||||
"spring2020BeetleWarriorSet": "Rhinoceros Beetle (Warrior)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
"hatchingPotion": "hatching potion",
|
||||
"noHatchingPotions": "You don't have any hatching potions.",
|
||||
"inventoryText": "Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant.",
|
||||
"haveHatchablePet": "You have a <%= potion %> hatching potion and <%= egg %> egg to hatch this pet! <b>Click</b> the paw print to hatch.",
|
||||
"haveHatchablePet": "You have a <%= potion %> hatching potion and <%= egg %> egg to hatch this pet! <b>Click</b> to hatch!",
|
||||
"quickInventory": "Quick Inventory",
|
||||
"foodText": "food",
|
||||
"food": "Pet Food and Saddles",
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@
|
|||
"questGroupDilatoryDistress": "Dilatory Distress",
|
||||
"questDilatoryDistress1Text": "Dilatory Distress, Part 1: Message in a Bottle",
|
||||
"questDilatoryDistress1Notes": "A message in a bottle arrived from the newly rebuilt city of Dilatory! It reads: \"Dear Habiticans, we need your help once again. Our princess has disappeared and the city is under siege by some unknown watery demons! The mantis shrimps are holding the attackers at bay. Please aid us!\" To make the long journey to the sunken city, one must be able to breathe water. Fortunately, the alchemists @Benga and @hazel can make it all possible! You only have to find the proper ingredients.",
|
||||
"questDilatoryDistress1Completion": "You don the the finned armour and swim to Dilatory as quickly as you can. The merfolk and their mantis shrimp allies have managed to keep the monsters outside the city for the moment, but they are losing. No sooner are you within the castle walls than the horrifying siege descends!",
|
||||
"questDilatoryDistress1Completion": "You don the finned armor and swim to Dilatory as quickly as you can. The merfolk and their mantis shrimp allies have managed to keep the monsters outside the city for the moment, but they are losing. No sooner are you within the castle walls than the horrifying siege descends!",
|
||||
"questDilatoryDistress1CollectFireCoral": "Fire Coral",
|
||||
"questDilatoryDistress1CollectBlueFins": "Blue Fins",
|
||||
"questDilatoryDistress1DropArmor": "Finned Oceanic Armour (Armour)",
|
||||
|
|
@ -568,7 +568,7 @@
|
|||
"questPterodactylUnlockText": "Unlocks Pterodactyl Eggs for purchase in the Market",
|
||||
"questBadgerText": "Stop Badgering Me!",
|
||||
"questBadgerNotes": "Ah, winter in the Taskwoods. The softly falling snow, the branches sparkling with frost, the Flourishing Fairies… still not snoozing?<br><br>“Why are they still awake?” cries @LilithofAlfheim. “If they don't hibernate soon, they'll never have the energy for planting season.”<br><br>As you and @Willow the Witty hurry to investigate, a furry head pops up from the ground. Before you can yell, “It’s the Badgering Bother!” it’s back in its burrow—but not before snatching up the Fairies' “Hibernate” To-Dos and dropping a giant list of pesky tasks in their place!<br><br>“No wonder the fairies aren't resting, if they're constantly being badgered like that!” @plumilla says. Can you chase off this beast and save the Taskwood’s harvest this year?",
|
||||
"questBadgerCompletion": "You finally drive away the the Badgering Bother and hurry into its burrow. At the end of a tunnel, you find its hoard of the faeries’ “Hibernate” To-Dos. The den is otherwise abandoned, except for three eggs that look ready to hatch.",
|
||||
"questBadgerCompletion": "You finally drive away the Badgering Bother and hurry into its burrow. At the end of a tunnel, you find its hoard of the faeries’ “Hibernate” To-Dos. The den is otherwise abandoned, except for three eggs that look ready to hatch.",
|
||||
"questBadgerBoss": "The Badgering Bother",
|
||||
"questBadgerDropBadgerEgg": "Badger (Egg)",
|
||||
"questBadgerUnlockText": "Unlocks Badger Eggs for purchase in the Market",
|
||||
|
|
@ -683,5 +683,5 @@
|
|||
"questRubyCollectAquariusRunes": "Aquarius Zodiac Runes",
|
||||
"questRubyCompletion": "With the necessary items safely packed away, the three of you rush back to Habit City and meet in @beffymaroo's lab. “Excellent work!” @beffymaroo says. “You've gathered the ingredients for the potion!”<br><br>@beffymaroo carefully combines the runes and the rubies to create a brilliant red potion and pours some of it on two pet eggs. As you observe the results, you notice that the two pets seem completely uninterested in one another!<br><br>“Did it not work?” @gully asks. But before anyone can answer, you suddenly realize that it isn't the potion that creates friendship and love, but rather it is the experience of working together toward a common goal. You come away from the quest having gained some new friends...and some flashy new pets!",
|
||||
"questRubyNotes": "The normally bustling peaks of the Stoïkalm Volcanoes lie silent in the snow. “I suppose the hikers and sight-seers are hibernating?” @gully says to you and @Aspiring_Advocate. “That makes our search easier.”<br><br>As you reach the summit, the chill wind merges with the steam billowing from the crater. “There!” @Aspiring_Advocate exclaims, pointing toward a hot spring. “What better place to find cool runes of Aquarius and passionate runes of Venus than where ice and fire meet?”<br><br>The three of you hurry toward the hot spring. “According to my research,” @Aspiring_Advocate says, “combining the runes with heart-shaped rubies will create a hatching potion that can foster friendship and love!”<br><br>Excited by the prospect of a new discovery, you all smile. “All right,” @gully says, “let's start searching!”",
|
||||
"questRubyText": "The Ruby Solution"
|
||||
"questRubyText": "Ruby Rapport"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@
|
|||
"goToSettings": "Go to Settings",
|
||||
"usernameVerifiedConfirmation": "Your username, <%= username %>, is confirmed!",
|
||||
"usernameNotVerified": "Please confirm your username.",
|
||||
"changeUsernameDisclaimer": "This username will be used for invitations, @mentions in chat, and messaging.",
|
||||
"changeUsernameDisclaimer": "Your username is used for invitations, @mentions in chat, and messaging. It must be 1 to 20 characters, containing only letters a to z, numbers 0 to 9, hyphens, or underscores, and cannot include any inappropriate terms.",
|
||||
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!",
|
||||
"everywhere": "Everywhere",
|
||||
"onlyPrivateSpaces": "Only in private spaces",
|
||||
|
|
|
|||
|
|
@ -247,5 +247,6 @@
|
|||
"monthlyMysteryItems": "Monthly Mystery Items",
|
||||
"subscribersReceiveBenefits": "Subscribers receive these useful benefits!",
|
||||
"giftASubscription": "Gift a Subscription",
|
||||
"mysterySet202003": "Barbed Battler Set"
|
||||
"mysterySet202003": "Barbed Battler Set",
|
||||
"mysterySet202004": "Mighty Monarch Set"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,5 +72,8 @@
|
|||
"achievementTickledPink": "Rose bonbon",
|
||||
"foundNewItemsCTA": "Rendez-vous dans votre inventaire et essayez de combiner les nouvelles potions d'éclosion et les nouveaux œufs !",
|
||||
"foundNewItemsExplanation": "Remplir vos tâches vous donne une chance de trouver des objets, comme les œufs, les potion d'éclosion et la nourriture.",
|
||||
"foundNewItems": "Vous avez trouvé de nouveaux objets !"
|
||||
"foundNewItems": "Vous avez trouvé de nouveaux objets !",
|
||||
"achievementBugBonanzaModalText": "Vous avez achevé les quêtes des scarabées, papillons, escargots et araignées !",
|
||||
"achievementBugBonanzaText": "A achevé les quêtes des scarabées, papillons, escargots et araignées.",
|
||||
"achievementBugBonanza": "Profusion d'insectes"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -354,5 +354,6 @@
|
|||
"premiumPotionUnlimitedNotes": "Ne peut pas être utilisé sur des œufs de familiers de quête.",
|
||||
"hatchingPotionAmber": "d'ambre",
|
||||
"hatchingPotionAurora": "Aurore",
|
||||
"hatchingPotionRuby": "Rubis"
|
||||
"hatchingPotionRuby": "Rubis",
|
||||
"hatchingPotionBirchBark": "Écorce de bouleau"
|
||||
}
|
||||
|
|
|
|||