Compare commits
20 Commits
qa/turtle
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7296c8f16c | ||
|
|
2029739a1b | ||
|
|
5cef106ea5 | ||
|
|
e096d7ac42 | ||
|
|
6db998e726 | ||
|
|
29c658b042 | ||
|
|
66710b8f38 | ||
|
|
c77db3d625 | ||
|
|
c947fa97d9 | ||
|
|
b2b9702797 | ||
|
|
e92503f032 | ||
|
|
8faa5b0582 | ||
|
|
95494c685b | ||
|
|
10978d46ab | ||
|
|
447eb6a0c4 | ||
|
|
3dec49b72c | ||
|
|
472d03f276 | ||
|
|
fd9a27c3ab | ||
|
|
a5c1423837 | ||
|
|
e9829b8b60 |
109
package-lock.json
generated
@@ -1,18 +1,17 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"version": "5.40.2",
|
||||
"version": "5.41.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "habitica",
|
||||
"version": "5.40.2",
|
||||
"version": "5.41.3",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
"@babel/preset-env": "^7.22.10",
|
||||
"@babel/register": "^7.22.15",
|
||||
"@google-analytics/data": "^4.12.1",
|
||||
"@google-cloud/trace-agent": "^7.1.2",
|
||||
"@parse/node-apn": "^5.2.3",
|
||||
"@slack/webhook": "^6.1.0",
|
||||
@@ -1975,17 +1974,6 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/@google-analytics/data": {
|
||||
"version": "4.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@google-analytics/data/-/data-4.12.1.tgz",
|
||||
"integrity": "sha512-LzyrkVrnVUTYTmdmHayOZoroc+YA9GHEUrkSSuiXSmMSNbesuWy/MoTXugC1V7+8PCGqb2eQ1UtVVv/2BCAQYA==",
|
||||
"dependencies": {
|
||||
"google-gax": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@google-cloud/common": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-4.0.3.tgz",
|
||||
@@ -2329,6 +2317,7 @@
|
||||
"version": "1.10.8",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.8.tgz",
|
||||
"integrity": "sha512-vYVqYzHicDqyKB+NQhAc54I1QWCBLCrYG6unqOIcBTHx+7x8C9lcoLj3KVJXs2VB4lUbpWY+Kk9NipcbXYWmvg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "^0.7.13",
|
||||
"@js-sdsl/ordered-map": "^4.4.2"
|
||||
@@ -2341,6 +2330,7 @@
|
||||
"version": "0.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz",
|
||||
"integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
@@ -2358,6 +2348,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -2372,6 +2363,7 @@
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
@@ -2385,6 +2377,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -2395,12 +2388,14 @@
|
||||
"node_modules/@grpc/proto-loader/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@grpc/proto-loader/node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
@@ -2409,6 +2404,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
@@ -2425,6 +2421,7 @@
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@@ -2433,6 +2430,7 @@
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
@@ -2450,6 +2448,7 @@
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@@ -2620,6 +2619,7 @@
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
|
||||
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/js-sdsl"
|
||||
@@ -2932,27 +2932,32 @@
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
@@ -2961,27 +2966,32 @@
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/inquire": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
@@ -3116,7 +3126,8 @@
|
||||
"node_modules/@types/caseless": {
|
||||
"version": "0.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz",
|
||||
"integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg=="
|
||||
"integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
@@ -3219,7 +3230,8 @@
|
||||
"node_modules/@types/long": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
||||
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
|
||||
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
@@ -3269,6 +3281,7 @@
|
||||
"version": "2.48.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz",
|
||||
"integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/caseless": "*",
|
||||
"@types/node": "*",
|
||||
@@ -3280,6 +3293,7 @@
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
@@ -3319,7 +3333,8 @@
|
||||
"node_modules/@types/tough-cookie": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
|
||||
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="
|
||||
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/triple-beam": {
|
||||
"version": "1.3.5",
|
||||
@@ -3529,6 +3544,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
},
|
||||
@@ -6070,9 +6086,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -9346,6 +9363,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -11431,9 +11449,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -11597,6 +11616,7 @@
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.3.tgz",
|
||||
"integrity": "sha512-f4F2Y9X4+mqsrJuLZsuTljYuQpcBnQsCt9ScvZpdM8jGjqrcxyJi5JUiqtq0jtpdHVPzyit0N7f5t07e+kH5EA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "~1.10.3",
|
||||
"@grpc/proto-loader": "^0.7.0",
|
||||
@@ -11619,6 +11639,7 @@
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
@@ -11630,6 +11651,7 @@
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz",
|
||||
"integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
@@ -11645,6 +11667,7 @@
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||
"integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
@@ -11657,6 +11680,7 @@
|
||||
"version": "9.10.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz",
|
||||
"integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
@@ -11673,6 +11697,7 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"jws": "^4.0.0"
|
||||
@@ -11685,6 +11710,7 @@
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
|
||||
"integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"agent-base": "^7.0.2",
|
||||
"debug": "4"
|
||||
@@ -11698,6 +11724,7 @@
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz",
|
||||
"integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
@@ -11720,6 +11747,7 @@
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz",
|
||||
"integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/request": "^2.48.8",
|
||||
"extend": "^3.0.2",
|
||||
@@ -11733,6 +11761,7 @@
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz",
|
||||
"integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
@@ -11748,6 +11777,7 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
@@ -11759,6 +11789,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
@@ -14237,7 +14268,8 @@
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/lodash.clonedeep": {
|
||||
"version": "4.5.0",
|
||||
@@ -16660,6 +16692,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@@ -17882,6 +17915,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz",
|
||||
"integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"protobufjs": "^7.2.5"
|
||||
},
|
||||
@@ -17894,6 +17928,7 @@
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz",
|
||||
"integrity": "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
@@ -20494,9 +20529,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
|
||||
"integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
|
||||
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "5.40.2",
|
||||
"version": "5.41.3",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
"@babel/preset-env": "^7.22.10",
|
||||
"@babel/register": "^7.22.15",
|
||||
"@google-analytics/data": "^4.12.1",
|
||||
"@google-cloud/trace-agent": "^7.1.2",
|
||||
"@parse/node-apn": "^5.2.3",
|
||||
"@slack/webhook": "^6.1.0",
|
||||
|
||||
@@ -150,7 +150,7 @@ describe('emails', () => {
|
||||
|
||||
sendTxn(mailingInfo, emailType);
|
||||
expect(got.post).to.be.called;
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
expect(got.post).to.be.calledWith('http://example.com/job', sinon.match({
|
||||
json: {
|
||||
data: {
|
||||
emailType: sinon.match.same(emailType),
|
||||
@@ -234,7 +234,7 @@ describe('emails', () => {
|
||||
|
||||
sendTxn(mailingInfo, emailType);
|
||||
expect(got.post).to.be.called;
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
expect(got.post).to.be.calledWith('http://example.com/job', sinon.match({
|
||||
json: {
|
||||
data: {
|
||||
emailType: sinon.match.same(emailType),
|
||||
@@ -254,7 +254,7 @@ describe('emails', () => {
|
||||
|
||||
sendTxn(mailingInfo, emailType, variables);
|
||||
expect(got.post).to.be.called;
|
||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||
expect(got.post).to.be.calledWith('http://example.com/job', sinon.match({
|
||||
json: {
|
||||
data: {
|
||||
variables: sinon.match(value => value[0].name === 'BASE_URL', 'matches variables'),
|
||||
|
||||
@@ -47,6 +47,12 @@ describe('highlightMentions', () => {
|
||||
expect(result[0]).to.equal('[@user-dash](/profile/444): message [@user_underscore](/profile/555)');
|
||||
});
|
||||
|
||||
it('highlights users with case-insensitive matching', async () => {
|
||||
const text = '@USER: message @User2 @USER3';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal('[@USER](/profile/111): message [@User2](/profile/222) [@USER3](/profile/333)');
|
||||
});
|
||||
|
||||
it('doesn\'t highlight nonexisting users', async () => {
|
||||
const text = '@nouser message';
|
||||
const result = await highlightMentions(text);
|
||||
|
||||
@@ -12,11 +12,33 @@ const { i18n } = common;
|
||||
describe('Apple Payments', () => {
|
||||
const subKey = 'basic_3mo';
|
||||
|
||||
let iapSetupStub;
|
||||
let iapValidateStub;
|
||||
let iapIsValidatedStub;
|
||||
let iapIsCanceledStub;
|
||||
let iapIsExpiredStub;
|
||||
let paymentBuySkuStub;
|
||||
let iapGetPurchaseDataStub;
|
||||
let validateGiftMessageStub;
|
||||
let paymentsCreateSubscritionStub;
|
||||
|
||||
beforeEach(() => {
|
||||
iapSetupStub = sinon.stub(iap, 'setup').resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate').resolves({});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.isExpired.restore();
|
||||
iap.isCanceled.restore();
|
||||
iap.getPurchaseData.restore();
|
||||
});
|
||||
|
||||
describe('verifyPurchase', () => {
|
||||
let sku; let user; let token; let receipt; let
|
||||
headers;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let paymentBuySkuStub; let
|
||||
iapGetPurchaseDataStub; let validateGiftMessageStub;
|
||||
|
||||
beforeEach(() => {
|
||||
token = 'testToken';
|
||||
@@ -25,13 +47,9 @@ describe('Apple Payments', () => {
|
||||
receipt = `{"token": "${token}", "productId": "${sku}"}`;
|
||||
headers = {};
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate')
|
||||
.resolves({});
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated').returns(true);
|
||||
sinon.stub(iap, 'isExpired').returns(false);
|
||||
sinon.stub(iap, 'isCanceled').returns(false);
|
||||
iapIsCanceledStub = sinon.stub(iap, 'isCanceled').returns(false);
|
||||
iapIsExpiredStub = sinon.stub(iap, 'isExpired').returns(false);
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{
|
||||
productId: 'com.habitrpg.ios.Habitica.21gems',
|
||||
@@ -42,12 +60,6 @@ describe('Apple Payments', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.isExpired.restore();
|
||||
iap.isCanceled.restore();
|
||||
iap.getPurchaseData.restore();
|
||||
payments.buySkuItem.restore();
|
||||
gems.validateGiftMessage.restore();
|
||||
});
|
||||
@@ -209,9 +221,6 @@ describe('Apple Payments', () => {
|
||||
describe('subscribe', () => {
|
||||
let sub; let sku; let user; let token; let receipt; let headers; let
|
||||
nextPaymentProcessing;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub;
|
||||
let paymentsCreateSubscritionStub; let
|
||||
iapGetPurchaseDataStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sub = common.content.subscriptionBlocks[subKey];
|
||||
@@ -223,12 +232,10 @@ describe('Apple Payments', () => {
|
||||
nextPaymentProcessing = moment.utc().add({ days: 2 });
|
||||
user = new User();
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate')
|
||||
.resolves({});
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||
.returns(true);
|
||||
iapIsCanceledStub = sinon.stub(iap, 'isCanceled').returns(false);
|
||||
iapIsExpiredStub = sinon.stub(iap, 'isExpired').returns(false);
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{
|
||||
expirationDate: moment.utc().subtract({ day: 1 }).toDate(),
|
||||
@@ -250,10 +257,6 @@ describe('Apple Payments', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.getPurchaseData.restore();
|
||||
if (payments.createSubscription.restore) payments.createSubscription.restore();
|
||||
});
|
||||
|
||||
@@ -270,6 +273,29 @@ describe('Apple Payments', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error if no active subscription is found', async () => {
|
||||
iap.isCanceled.restore();
|
||||
iapIsCanceledStub = sinon.stub(iap, 'isCanceled')
|
||||
.returns(true);
|
||||
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{
|
||||
expirationDate: moment.utc().add({ day: -2 }).toDate(),
|
||||
purchaseDate: new Date(),
|
||||
productId: 'subscription1month',
|
||||
transactionId: token,
|
||||
originalTransactionId: token,
|
||||
}]);
|
||||
|
||||
await expect(applePayments.subscribe(user, receipt, headers, nextPaymentProcessing))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
httpCode: 401,
|
||||
name: 'NotAuthorized',
|
||||
message: applePayments.constants.RESPONSE_NO_ITEM_PURCHASED,
|
||||
});
|
||||
});
|
||||
|
||||
const subOptions = [
|
||||
{
|
||||
sku: 'subscription1month',
|
||||
@@ -574,8 +600,7 @@ describe('Apple Payments', () => {
|
||||
describe('cancelSubscribe ', () => {
|
||||
let user; let token; let receipt; let headers; let customerId; let
|
||||
expirationDate;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let iapGetPurchaseDataStub; let
|
||||
paymentCancelSubscriptionSpy;
|
||||
let paymentCancelSubscriptionSpy;
|
||||
|
||||
beforeEach(async () => {
|
||||
token = 'test-token';
|
||||
@@ -584,8 +609,7 @@ describe('Apple Payments', () => {
|
||||
customerId = 'test-customerId';
|
||||
expirationDate = moment.utc();
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub.restore();
|
||||
iapValidateStub = sinon.stub(iap, 'validate')
|
||||
.resolves({
|
||||
expirationDate,
|
||||
@@ -593,8 +617,8 @@ describe('Apple Payments', () => {
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ expirationDate: expirationDate.toDate() }]);
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated').returns(true);
|
||||
sinon.stub(iap, 'isCanceled').returns(false);
|
||||
sinon.stub(iap, 'isExpired').returns(true);
|
||||
iapIsCanceledStub = sinon.stub(iap, 'isCanceled').returns(false);
|
||||
iapIsExpiredStub = sinon.stub(iap, 'isExpired').returns(true);
|
||||
user = new User();
|
||||
user.profile.name = 'sender';
|
||||
user.purchased.plan.paymentMethod = applePayments.constants.PAYMENT_METHOD_APPLE;
|
||||
@@ -606,13 +630,7 @@ describe('Apple Payments', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.isExpired.restore();
|
||||
iap.isCanceled.restore();
|
||||
iap.getPurchaseData.restore();
|
||||
payments.cancelSubscription.restore();
|
||||
paymentCancelSubscriptionSpy.restore();
|
||||
});
|
||||
|
||||
it('should throw an error if we are missing a subscription', async () => {
|
||||
@@ -695,6 +713,8 @@ describe('Apple Payments', () => {
|
||||
expect(iapIsValidatedStub).to.be.calledWith({
|
||||
expirationDate,
|
||||
});
|
||||
expect(iapIsCanceledStub).to.be.calledOnce;
|
||||
expect(iapIsExpiredStub).to.be.calledOnce;
|
||||
expect(iapGetPurchaseDataStub).to.be.calledOnce;
|
||||
|
||||
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
||||
|
||||
@@ -11,12 +11,36 @@ const { i18n } = common;
|
||||
|
||||
describe('Google Payments', () => {
|
||||
const subKey = 'basic_3mo';
|
||||
let iapSetupStub;
|
||||
let iapValidateStub;
|
||||
let iapIsValidatedStub;
|
||||
let paymentBuySkuStub;
|
||||
let validateGiftMessageStub;
|
||||
|
||||
beforeEach(() => {
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||
.returns(true);
|
||||
sinon.stub(iap, 'isCanceled').returns(false);
|
||||
sinon.stub(iap, 'isExpired').returns(false);
|
||||
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
|
||||
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.isCanceled.restore();
|
||||
iap.isExpired.restore();
|
||||
payments.buySkuItem.restore();
|
||||
gems.validateGiftMessage.restore();
|
||||
});
|
||||
|
||||
describe('verifyPurchase', () => {
|
||||
let sku; let user; let token; let receipt; let signature; let
|
||||
headers;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
|
||||
paymentBuySkuStub; let validateGiftMessageStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sku = 'com.habitrpg.android.habitica.iap.21gems';
|
||||
@@ -25,21 +49,7 @@ describe('Google Payments', () => {
|
||||
signature = '';
|
||||
headers = {};
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate').resolves({ productId: sku });
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||
.returns(true);
|
||||
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
|
||||
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
payments.buySkuItem.restore();
|
||||
gems.validateGiftMessage.restore();
|
||||
});
|
||||
|
||||
it('should throw an error if receipt is invalid', async () => {
|
||||
@@ -160,8 +170,7 @@ describe('Google Payments', () => {
|
||||
describe('subscribe', () => {
|
||||
let sub; let sku; let user; let token; let receipt; let signature; let headers; let
|
||||
nextPaymentProcessing;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
|
||||
paymentsCreateSubscritionStub;
|
||||
let paymentsCreateSubscritionStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sub = common.content.subscriptionBlocks[subKey];
|
||||
@@ -173,19 +182,12 @@ describe('Google Payments', () => {
|
||||
signature = '';
|
||||
nextPaymentProcessing = moment.utc().add({ days: 2 });
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate')
|
||||
.resolves({});
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||
.returns(true);
|
||||
paymentsCreateSubscritionStub = sinon.stub(payments, 'createSubscription').resolves({});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
payments.createSubscription.restore();
|
||||
});
|
||||
|
||||
@@ -243,7 +245,7 @@ describe('Google Payments', () => {
|
||||
describe('cancelSubscribe ', () => {
|
||||
let user; let token; let receipt; let signature; let headers; let customerId; let
|
||||
expirationDate;
|
||||
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let iapGetPurchaseDataStub; let
|
||||
let iapGetPurchaseDataStub; let
|
||||
paymentCancelSubscriptionSpy;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -253,17 +255,12 @@ describe('Google Payments', () => {
|
||||
signature = '';
|
||||
customerId = 'test-customerId';
|
||||
expirationDate = moment.utc();
|
||||
|
||||
iapSetupStub = sinon.stub(iap, 'setup')
|
||||
.resolves();
|
||||
iapValidateStub = sinon.stub(iap, 'validate')
|
||||
.resolves({
|
||||
expirationDate,
|
||||
});
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ expirationDate: expirationDate.toDate(), autoRenewing: false }]);
|
||||
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||
.returns(true);
|
||||
|
||||
user = new User();
|
||||
user.profile.name = 'sender';
|
||||
@@ -276,9 +273,6 @@ describe('Google Payments', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
iap.setup.restore();
|
||||
iap.validate.restore();
|
||||
iap.isValidated.restore();
|
||||
iap.getPurchaseData.restore();
|
||||
payments.cancelSubscription.restore();
|
||||
});
|
||||
@@ -308,6 +302,8 @@ describe('Google Payments', () => {
|
||||
});
|
||||
|
||||
it('should cancel a user subscription', async () => {
|
||||
iap.isCanceled.restore();
|
||||
iap.isCanceled = sinon.stub(iap, 'isCanceled').returns(true);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
|
||||
expect(iapSetupStub).to.be.calledOnce;
|
||||
@@ -332,11 +328,20 @@ describe('Google Payments', () => {
|
||||
});
|
||||
|
||||
it('should cancel a user subscription with multiple inactive subscriptions', async () => {
|
||||
iap.isCanceled.restore();
|
||||
iap.isCanceled = sinon.stub(iap, 'isCanceled').returns(true);
|
||||
const laterDate = moment.utc().add(7, 'days');
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ expirationDate, autoRenewing: false },
|
||||
{ expirationDate: laterDate, autoRenewing: false },
|
||||
.returns([{
|
||||
startTimeMillis: expirationDate.valueOf(),
|
||||
expirationDate,
|
||||
autoRenewing: false,
|
||||
}, {
|
||||
startTimeMillis: laterDate.valueOf(),
|
||||
expirationDate: laterDate,
|
||||
autoRenewing: false,
|
||||
},
|
||||
]);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
|
||||
@@ -365,7 +370,12 @@ describe('Google Payments', () => {
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ autoRenewing: true }]);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
await expect(googlePayments.cancelSubscribe(user, headers))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
httpCode: 401,
|
||||
name: 'NotAuthorized',
|
||||
message: googlePayments.constants.RESPONSE_STILL_VALID,
|
||||
});
|
||||
|
||||
expect(iapSetupStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledOnce;
|
||||
@@ -388,8 +398,12 @@ describe('Google Payments', () => {
|
||||
.returns([{ expirationDate, autoRenewing: false },
|
||||
{ autoRenewing: true },
|
||||
{ expirationDate, autoRenewing: false }]);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
|
||||
await expect(googlePayments.cancelSubscribe(user, headers))
|
||||
.to.eventually.be.rejected.and.to.eql({
|
||||
httpCode: 401,
|
||||
name: 'NotAuthorized',
|
||||
message: googlePayments.constants.RESPONSE_STILL_VALID,
|
||||
});
|
||||
expect(iapSetupStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledWith(iap.GOOGLE, {
|
||||
|
||||
@@ -238,6 +238,18 @@ describe('POST /chat', () => {
|
||||
expect(groupMessages[0].id).to.exist;
|
||||
});
|
||||
|
||||
it('creates a chat with case-insensitive mentions', async () => {
|
||||
const originalUsername = member.auth.local.username;
|
||||
const uppercaseUsername = originalUsername.toUpperCase();
|
||||
const messageWithMentions = `hi @${uppercaseUsername}`;
|
||||
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: messageWithMentions });
|
||||
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
|
||||
|
||||
expect(newMessage.message.id).to.exist;
|
||||
expect(newMessage.message.text).to.include(`[@${uppercaseUsername}](/profile/${member._id})`);
|
||||
expect(groupMessages[0].id).to.exist;
|
||||
});
|
||||
|
||||
it('creates a chat with a max length of 3000 chars', async () => {
|
||||
const veryLongMessage = `
|
||||
123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789.
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('POST /user/auth/local/login', () => {
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('accountSuspended', { communityManagerEmail: nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL'), userId: user._id }),
|
||||
message: t('accountSuspended', { communityManagerEmail: nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL'), userId: user._id, username: user.auth.local.username }),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
44
website/client/package-lock.json
generated
@@ -23,7 +23,6 @@
|
||||
"eslint-config-habitrpg": "6.2.0",
|
||||
"eslint-plugin-mocha": "5.3.0",
|
||||
"eslint-plugin-vue": "7.20.0",
|
||||
"ga-gtag": "^1.2.0",
|
||||
"habitica-markdown": "^3.0.0",
|
||||
"hellojs": "^1.20.0",
|
||||
"intro.js": "^7.2.0",
|
||||
@@ -38,7 +37,7 @@
|
||||
"timers-browserify": "^2.0.12",
|
||||
"uuid": "^9.0.1",
|
||||
"validator": "^13.9.0",
|
||||
"vite": "^6.0.0",
|
||||
"vite": "^6.3.6",
|
||||
"vite-plugin-compression2": "^1.3.3",
|
||||
"vue": "^2.7.10",
|
||||
"vue-fragment": "^1.6.0",
|
||||
@@ -5123,6 +5122,20 @@
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
@@ -5161,11 +5174,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/ga-gtag": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ga-gtag/-/ga-gtag-1.2.0.tgz",
|
||||
"integrity": "sha512-j9gxutMdpGMdwaX1SzOG31Ddm+IGFjeNf+N3Z5g+BBpS8FSXOALlrM+ORIGc/QKszGJEDlw+6PfIsJZICsqsGQ=="
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@@ -7126,6 +7134,21 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright/node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/popper.js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||
@@ -8528,9 +8551,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.3.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
||||
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
|
||||
"version": "6.3.6",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz",
|
||||
"integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.4.4",
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
"eslint-config-habitrpg": "6.2.0",
|
||||
"eslint-plugin-mocha": "5.3.0",
|
||||
"eslint-plugin-vue": "7.20.0",
|
||||
"ga-gtag": "^1.2.0",
|
||||
"habitica-markdown": "^3.0.0",
|
||||
"hellojs": "^1.20.0",
|
||||
"intro.js": "^7.2.0",
|
||||
@@ -42,7 +41,7 @@
|
||||
"timers-browserify": "^2.0.12",
|
||||
"uuid": "^9.0.1",
|
||||
"validator": "^13.9.0",
|
||||
"vite": "^6.0.0",
|
||||
"vite": "^6.3.6",
|
||||
"vite-plugin-compression2": "^1.3.3",
|
||||
"vue": "^2.7.10",
|
||||
"vue-fragment": "^1.6.0",
|
||||
|
||||
@@ -203,6 +203,9 @@ export default {
|
||||
|
||||
return response;
|
||||
}, error => { // Set up Error interceptors
|
||||
if (!error.response) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (error.response.status >= 400) {
|
||||
const isBanned = this.checkForBannedUser(error);
|
||||
if (isBanned === true) return null; // eslint-disable-line consistent-return
|
||||
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 11 KiB |
9
website/client/src/assets/images/gifts_bg.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="378" height="176" viewBox="0 0 378 176" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0H378V174C378 175.105 377.105 176 376 176H1.99999C0.895423 176 0 175.105 0 174V0Z" fill="url(#paint0_linear_2257_239)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2257_239" x1="378" y1="0" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#925CF3"/>
|
||||
<stop offset="1" stop-color="#34B5C1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 448 B |
37
website/client/src/assets/images/gifts_start.svg
Normal file
@@ -0,0 +1,37 @@
|
||||
<svg width="48" height="96" viewBox="0 0 48 96" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-3.10104 12.0483C-2.82088 9.43721 -3.53422 6.57214 -5.6115 5.24584C-7.68877 3.91954 -9.89543 4.92709 -10.1422 6.808C-10.3891 8.68891 -9.06061 9.83066 -4.97737 13.9337C-3.81821 15.0985 -3.3812 14.6594 -3.10104 12.0483Z" stroke="#FFA624" stroke-width="4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.34089 15.2054C4.45116 13.6561 7.27707 12.8443 9.45877 13.9889C11.6405 15.1334 11.8754 17.5575 10.3778 18.7127C8.88016 19.868 7.23193 19.2828 1.65411 17.781C0.0706697 17.3546 0.230624 16.7548 2.34089 15.2054Z" stroke="#FFBE5D" stroke-width="4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.549002 12.0098C-3.61871 9.59194 -3.87667 15.8322 -2.20457 16.8023C-0.532473 17.7724 4.71671 14.4277 0.549002 12.0098Z" fill="#EE9109"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-1.76917 16.0445L13.637 24.9825L9.18965 32.7229L-6.21656 23.785L-1.76917 16.0445Z" fill="#F8F9F9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-6.90457 13.0652L3.36623 19.0238L-1.08116 26.7643L-11.352 20.8057L-6.90457 13.0652Z" fill="#FFBE5D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-1.76917 16.0445L3.36623 19.0238L1.88377 21.604L-3.25163 18.6247L-1.76917 16.0445Z" fill="#FFA624"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-6.21656 23.785L6.62195 31.2333L-3.75529 49.2944L-16.5938 41.8461L-6.21656 23.785Z" fill="#F8F9F9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-3.64886 25.2747L6.62195 31.2333L5.13948 33.8134L-5.13132 27.8548L-3.64886 25.2747Z" fill="#DDF3F3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.401307 24.1842L10.6721 30.1428L9.18965 32.7229L-1.08116 26.7643L0.401307 24.1842Z" fill="#DDF3F3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.7924 38.4607L17.9387 42.0519L21.31 40.5834L24.8838 41.4413L23.4225 38.0537L24.2762 34.4625L20.9049 35.9309L17.3311 35.0731L18.7924 38.4607Z" fill="white" fill-opacity="0.5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-3.93867 71.2331L-4.79238 74.8243L-1.42111 73.3559L2.15271 74.2137L0.691383 70.8261L1.54509 67.2349L-1.82618 68.7033L-5.4 67.8455L-3.93867 71.2331Z" fill="white" fill-opacity="0.5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.8949 25.3807L35.0583 29.8802L37.9424 26.2452L42.4202 25.0761L38.8028 22.178L37.6393 17.6786L34.7552 21.3135L30.2775 22.4826L33.8949 25.3807Z" fill="white" fill-opacity="0.5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.2596 71.999L40.579 68.1435L45.9507 88.2881L31.6312 92.1436L26.2596 71.999Z" fill="#F8F9F9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9401 75.8545L26.2589 71.9966L31.6273 92.1421L17.3084 96L11.9401 75.8545Z" fill="#DDF3F3"/>
|
||||
<rect width="2.96589" height="20.8485" transform="matrix(0.965611 -0.25999 0.257652 0.966238 23.3957 72.7701)" fill="#FFA624"/>
|
||||
<rect width="2.96589" height="20.8485" transform="matrix(0.965611 -0.25999 0.257652 0.966238 26.2596 71.999)" fill="#FFBE5D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.9999 90.0369L30.8638 89.2658L31.6312 92.1436L28.7673 92.9147L27.9999 90.0369Z" fill="#EE9109"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3957 72.7701L26.2596 71.999L27.0269 74.8768L24.163 75.6479L23.3957 72.7701Z" fill="#EE9109"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9401 75.8545L23.3951 72.7682L24.162 75.6461L12.707 78.7325L11.9401 75.8545Z" fill="#C1E9E9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5443 93.1213L27.9999 90.0369L28.7673 92.9147L17.3117 95.9991L16.5443 93.1213Z" fill="#C1E9E9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.1235 71.2279L40.579 68.1435L41.3464 71.0213L29.8908 74.1057L29.1235 71.2279Z" fill="#DDF3F3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.7277 88.4947L45.1833 85.4103L45.9507 88.2881L34.4951 91.3725L33.7277 88.4947Z" fill="#DDF3F3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.8638 89.2658L33.7277 88.4947L34.4951 91.3725L31.6312 92.1436L30.8638 89.2658Z" fill="#FFA624"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.2596 71.999L29.1235 71.2279L29.8908 74.1057L27.0269 74.8768L26.2596 71.999Z" fill="#FFA624"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5224 56.3076C25.8087 53.7812 24.0792 51.3933 21.6588 50.9455C19.2383 50.4977 17.5679 52.2625 18.0403 54.0994C18.5126 55.9363 20.17 56.4948 25.4855 58.7621C26.9945 59.4057 27.236 58.834 26.5224 56.3076Z" stroke="#FFA624" stroke-width="4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.745 57.1864C34.124 54.9555 36.4415 53.1391 38.8911 53.3791C41.3406 53.6191 42.4621 55.7782 41.5042 57.413C40.5463 59.0479 38.7999 59.1258 33.0684 59.8329C31.4413 60.0337 31.366 59.4173 32.745 57.1864Z" stroke="#FFBE5D" stroke-width="4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.8923 54.898C25.1267 54.225 27.2139 60.108 29.1258 60.378C31.0378 60.648 34.6579 55.571 29.8923 54.898Z" fill="#EE9109"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.247 59.5115L46.8635 61.9994L45.6255 70.8503L28.0091 68.3625L29.247 59.5115Z" fill="#F8F9F9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6306 57.0236L29.247 59.5114L28.0091 68.3624L10.3927 65.8745L11.6306 57.0236Z" fill="#DDF3F3"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3749 58.6822L35.1192 60.3408L33.8813 69.1917L22.137 67.5332L23.3749 58.6822Z" fill="#FFBE5D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3749 58.6822L29.247 59.5115L28.0091 68.3625L22.137 67.5332L23.3749 58.6822Z" fill="#FFA624"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.247 59.5115L35.1192 60.3408L34.7065 63.2911L28.8344 62.4618L29.247 59.5115Z" fill="#FFA624"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.3749 58.6822L29.247 59.5115L28.8344 62.4618L22.9622 61.6326L23.3749 58.6822Z" fill="#EE9109"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8053 62.9241L22.5496 64.5827L22.137 67.533L10.3927 65.8745L10.8053 62.9241Z" fill="#C1E9E9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.2939 66.2414L46.0382 67.9L45.6255 70.8503L33.8813 69.1917L34.2939 66.2414Z" fill="#DDF3F3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -30,12 +30,23 @@
|
||||
cursor: default;
|
||||
color: $gray-200;
|
||||
opacity: 1;
|
||||
box-shadow: none;
|
||||
background-color: $gray-700;
|
||||
background-color: transparent;
|
||||
border: 2px solid transparent;
|
||||
|
||||
box-shadow:
|
||||
0 1px 3px 0 rgba($black, 0.12),
|
||||
0 1px 2px 0 rgba($black, 0.24);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
padding: 4px 12px;
|
||||
min-height: 32px;
|
||||
max-height: 32px;
|
||||
gap: 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
.svg {
|
||||
color: $gray-300;
|
||||
color: $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,10 @@ h4 {
|
||||
background-color: $purple-300 !important;
|
||||
}
|
||||
|
||||
.bg-yellow-50 {
|
||||
background-color: $yellow-50 !important;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: $white !important;
|
||||
}
|
||||
|
||||
8
website/client/src/assets/svg/close-white.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g fill="#FFFFFF" fill-rule="nonzero">
|
||||
<polygon points="12.1973467 2 14 3.80265326 9.80187117 8 14 12.1973467 12.1973467 14 8 9.80187117 3.80265326 14 2 12.1973467 6.19812883 8 2 3.80265326 3.80265326 2 8 6.19812883"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 504 B |
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.1792 31.6843L46.8536 22.3769L23.918 28.6988L18.861 42.5218L44.341 58.5813L58.1792 31.6843Z" fill="#FF944C"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M46.6218 34.5148L46.1108 26.1328L36.2812 28.8422L46.6218 34.5148Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M30.2393 39.0304L26.4518 31.5515L36.2813 28.8422L30.2393 39.0304Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M46.6218 34.5148L36.2813 28.8422L30.2393 39.0304L46.6218 34.5148Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M53.8301 32.5279L46.1108 26.1328L46.6218 34.5148L53.8301 32.5279Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M23.0309 41.0173L26.4518 31.5516L30.2393 39.0304L23.0309 41.0173Z" fill="#FA8537"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M53.8301 32.5279L46.6218 34.5148L43.0424 53.79L53.8301 32.5279Z" fill="#FA8537"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M23.0309 41.0173L30.2393 39.0304L43.0425 53.79L23.0309 41.0173Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M46.6218 34.5148L30.2393 39.0304L43.0425 53.79L46.6218 34.5148Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M50.555 4.15937L47.026 0.420004L38.7773 1.59601L36.4144 6.17539L44.5675 12.8919L50.555 4.15937Z" fill="#FFBE5D"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M46.414 4.62854L46.6034 1.6924L43.0682 2.1964L46.414 4.62854Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M40.5221 5.46854L39.5331 2.7004L43.0682 2.1964L40.5221 5.46854Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M46.414 4.62854L43.0683 2.1964L40.5221 5.46855L46.414 4.62854Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M49.0064 4.25894L46.6034 1.6924L46.414 4.62854L49.0064 4.25894Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M37.9296 5.83815L39.5331 2.70041L40.5221 5.46855L37.9296 5.83815Z" fill="#FFA624"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M49.0064 4.25893L46.414 4.62853L44.3259 11.1688L49.0064 4.25893Z" fill="#FFA624"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M37.9297 5.83815L40.5221 5.46855L44.326 11.1688L37.9297 5.83815Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M46.414 4.62854L40.5221 5.46855L44.326 11.1688L46.414 4.62854Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.2986 16.7775L24.6513 8.36623L11.1016 3.94533L4.07056 9.19883L11.614 25.6769L27.2986 16.7775Z" fill="#FF6165"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M20.5864 14.3719L23.0573 10.0026L17.2502 8.10789L20.5864 14.3719Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M10.908 11.2141L11.4432 6.21322L17.2502 8.10789L10.908 11.2141Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M20.5864 14.3719L17.2502 8.10789L10.9081 11.2141L20.5864 14.3719Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M24.8449 15.7613L23.0573 10.0026L20.5864 14.3719L24.8449 15.7613Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M6.64955 9.82464L11.4432 6.21321L10.908 11.2141L6.64955 9.82464Z" fill="#F23035"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M24.8449 15.7613L20.5864 14.3719L12.5221 22.8464L24.8449 15.7613Z" fill="#F23035"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M6.64959 9.82464L10.9081 11.2141L12.5221 22.8463L6.64959 9.82464Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M20.5864 14.3719L10.9081 11.2141L12.5221 22.8463L20.5864 14.3719Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.82083 31.6843L17.1464 22.3769L40.082 28.6988L45.139 42.5218L19.659 58.5813L5.82083 31.6843Z" fill="#24CC8F"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M17.3782 34.5148L17.8892 26.1328L27.7188 28.8422L17.3782 34.5148Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M33.7607 39.0304L37.5482 31.5515L27.7187 28.8422L33.7607 39.0304Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M17.3782 34.5148L27.7187 28.8422L33.7607 39.0304L17.3782 34.5148Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M10.1699 32.5279L17.8892 26.1328L17.3782 34.5148L10.1699 32.5279Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M40.9691 41.0173L37.5482 31.5516L33.7607 39.0304L40.9691 41.0173Z" fill="#1CA372"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M10.1699 32.5279L17.3782 34.5148L20.9576 53.79L10.1699 32.5279Z" fill="#1CA372"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M40.9691 41.0173L33.7607 39.0304L20.9575 53.79L40.9691 41.0173Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M17.3782 34.5148L33.7607 39.0304L20.9575 53.79L17.3782 34.5148Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.445 4.15937L16.974 0.420004L25.2227 1.59601L27.5856 6.17539L19.4325 12.8919L13.445 4.15937Z" fill="#925CF3"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M17.586 4.62854L17.3966 1.6924L20.9318 2.1964L17.586 4.62854Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M23.4779 5.46854L24.4669 2.7004L20.9318 2.1964L23.4779 5.46854Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M17.586 4.62854L20.9317 2.1964L23.4779 5.46855L17.586 4.62854Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M14.9936 4.25894L17.3966 1.6924L17.586 4.62854L14.9936 4.25894Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M26.0704 5.83815L24.4669 2.70041L23.4779 5.46855L26.0704 5.83815Z" fill="#4F2A93"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M14.9936 4.25893L17.586 4.62853L19.6741 11.1688L14.9936 4.25893Z" fill="#4F2A93"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M26.0703 5.83815L23.4779 5.46855L19.674 11.1688L26.0703 5.83815Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M17.586 4.62854L23.4779 5.46855L19.674 11.1688L17.586 4.62854Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.7014 16.7775L39.3487 8.36623L52.8984 3.94533L59.9294 9.19883L52.386 25.6769L36.7014 16.7775Z" fill="#50B5E9"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M43.4136 14.3719L40.9427 10.0026L46.7498 8.10789L43.4136 14.3719Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M53.092 11.2141L52.5568 6.21322L46.7498 8.10789L53.092 11.2141Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M43.4136 14.3719L46.7498 8.10789L53.0919 11.2141L43.4136 14.3719Z" fill="white"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M39.1551 15.7613L40.9427 10.0026L43.4136 14.3719L39.1551 15.7613Z" fill="white"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M57.3504 9.82464L52.5568 6.21321L53.092 11.2141L57.3504 9.82464Z" fill="#46A7D9"/>
|
||||
<path opacity="0.35" fill-rule="evenodd" clip-rule="evenodd" d="M39.1551 15.7613L43.4136 14.3719L51.4779 22.8464L39.1551 15.7613Z" fill="#46A7D9"/>
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M57.3504 9.82464L53.0919 11.2141L51.4779 22.8463L57.3504 9.82464Z" fill="white"/>
|
||||
<path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M43.4136 14.3719L53.0919 11.2141L51.4779 22.8463L43.4136 14.3719Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -117,7 +117,7 @@ export default {
|
||||
closeWithAction () {
|
||||
this.close();
|
||||
setTimeout(() => {
|
||||
this.$router.push({ name: 'achievements' });
|
||||
this.$router.push(`/profile/${this.$store.state.user.data._id}#achievements`);
|
||||
}, 200);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
watch: {
|
||||
userIdentifier () {
|
||||
this.isSearching = true;
|
||||
this.$store.dispatch('adminPanel:searchUsers', { userIdentifier: this.userIdentifier }).then(users => {
|
||||
this.$store.dispatch('admin:searchUsers', { userIdentifier: this.userIdentifier }).then(users => {
|
||||
this.isSearching = false;
|
||||
if (users.length === 1) {
|
||||
this.loadUser(users[0]._id);
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
class="row"
|
||||
>
|
||||
<div class="form col-12">
|
||||
<button
|
||||
class="btn btn-danger mt-3 float-right"
|
||||
@click="confirmDeleteHero"
|
||||
>
|
||||
Begin Member deletion
|
||||
</button>
|
||||
<basic-details
|
||||
:user-id="hero._id"
|
||||
:auth="hero.auth"
|
||||
@@ -96,6 +102,53 @@
|
||||
:reset-counter="resetCounter"
|
||||
@clear-data="clearData"
|
||||
/>
|
||||
<b-modal
|
||||
id="delete-member-modal"
|
||||
title="Delete Member"
|
||||
ok-title="Delete"
|
||||
ok-variant="danger"
|
||||
cancel-title="Cancel"
|
||||
@ok="deleteHero"
|
||||
>
|
||||
<b-modal-body>
|
||||
<p>
|
||||
Are you sure you want to delete this member?
|
||||
</p>
|
||||
<p class="errorMessage">
|
||||
Please note: This action cannot be undone!
|
||||
</p>
|
||||
<div class="ml-4">
|
||||
<div class="form-check">
|
||||
<input
|
||||
id="deleteAccountCheck"
|
||||
v-model="deleteHabiticaAccount"
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="deleteAccountCheck"
|
||||
>
|
||||
Delete Habitica account
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input
|
||||
id="deleteAmplitudeCheck"
|
||||
v-model="deleteAmplitudeData"
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="deleteAmplitudeCheck"
|
||||
>
|
||||
Delete Amplitude data
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</b-modal-body>
|
||||
</b-modal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,6 +237,8 @@ export default {
|
||||
hasParty: false,
|
||||
partyNotExistError: false,
|
||||
adminHasPrivForParty: true,
|
||||
deleteHabiticaAccount: true,
|
||||
deleteAmplitudeData: true,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -249,6 +304,25 @@ export default {
|
||||
|
||||
this.resetCounter += 1; // tell child components to reinstantiate from scratch
|
||||
},
|
||||
confirmDeleteHero () {
|
||||
if (this.hero._id === this.user._id) {
|
||||
window.alert('You cannot delete your own account.');
|
||||
return;
|
||||
}
|
||||
this.$root.$emit('bv::show::modal', 'delete-member-modal');
|
||||
},
|
||||
deleteHero () {
|
||||
this.$store.dispatch('hall:deleteHero', {
|
||||
uuid: this.hero._id,
|
||||
deleteHabiticaAccount: this.deleteHabiticaAccount,
|
||||
deleteAmplitudeData: this.deleteAmplitudeData,
|
||||
}).then(() => {
|
||||
this.$root.$emit('bv::hide::modal', 'delete-member-modal');
|
||||
this.$router.push({ name: 'adminPanel' });
|
||||
}).catch(err => {
|
||||
window.alert(err);
|
||||
});
|
||||
},
|
||||
hasUnsavedChanges (...comparisons) {
|
||||
for (const index in comparisons) {
|
||||
if (index && comparisons[index]) {
|
||||
|
||||
@@ -37,7 +37,11 @@
|
||||
Party ID
|
||||
</label>
|
||||
<strong class="col-sm-9 col-form-label">
|
||||
{{ groupPartyData._id }}
|
||||
<router-link
|
||||
:to="{'name': 'groupAdminGroup', 'params': {'groupId': groupPartyData._id}}"
|
||||
>
|
||||
{{ groupPartyData._id }}
|
||||
</router-link>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
||||
@@ -15,6 +15,25 @@
|
||||
:class="{ 'open': expand }"
|
||||
>
|
||||
Subscription, Monthly Perks
|
||||
<span
|
||||
v-if="isSubscribed() && !isCancelled()"
|
||||
class="text-success float-right ml-3"
|
||||
>
|
||||
Active
|
||||
</span>
|
||||
<span
|
||||
v-else-if="isSubscribed() && isCancelled()"
|
||||
class="text-success float-right ml-3"
|
||||
>
|
||||
Active until {{ dateFormat(hero.purchased.plan.dateTerminated) }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="hero.purchased.plan.customerId && hero.purchased.plan.dateTerminated"
|
||||
class="text-warning float-right ml-3"
|
||||
>
|
||||
Inactive
|
||||
</span>
|
||||
|
||||
<b
|
||||
v-if="hasUnsavedChanges && !expand"
|
||||
class="text-warning float-right"
|
||||
@@ -46,7 +65,7 @@
|
||||
class="form-control"
|
||||
type="text"
|
||||
>
|
||||
<option value="groupPlan">
|
||||
<option value="Group Plan">
|
||||
Group Plan
|
||||
</option>
|
||||
<option value="Stripe">
|
||||
@@ -154,7 +173,11 @@
|
||||
>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
{{ group.name }}
|
||||
<router-link
|
||||
:to="{ name: 'groupAdminGroup', params: { groupId: group._id } }"
|
||||
>
|
||||
{{ group.name }}
|
||||
</router-link>
|
||||
<small class="float-right">{{ group._id }}</small>
|
||||
</h6>
|
||||
<p class="card-text">
|
||||
@@ -245,8 +268,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<small
|
||||
v-if="!hero.purchased.plan.dateTerminated
|
||||
&& hero.purchased.plan.planId"
|
||||
v-if="isSubscribed() && !isCancelled()"
|
||||
class="text-success"
|
||||
>
|
||||
The subscription does not have a termination date and is active.
|
||||
@@ -419,6 +441,79 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<h2>Payment Details</h2>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="offset-sm-3 col-sm-9 mb-3">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary btn-sm"
|
||||
@click="getSubscriptionPaymentDetails"
|
||||
>
|
||||
Get Subscription Payment Details
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="paymentDetails"
|
||||
>
|
||||
<div
|
||||
v-for="(value, key) in paymentDetails"
|
||||
:key="key"
|
||||
class="form-group row"
|
||||
>
|
||||
<label class="col-sm-3 col-form-label">
|
||||
{{ getHumanReadablePaymentDetails(key).label }}:
|
||||
<span
|
||||
:id="`${key}_tooltip`"
|
||||
v-b-tooltip.hover.right="getHumanReadablePaymentDetails(key).help"
|
||||
class="info-icon"
|
||||
>?</span>
|
||||
</label>
|
||||
<strong class="col-sm-9 col-form-label">
|
||||
<span v-if="value === true">Yes</span>
|
||||
<span v-else-if="value === false">No</span>
|
||||
<span
|
||||
v-else-if="value instanceof String && isDate(value)"
|
||||
v-b-tooltip.hover="value"
|
||||
>
|
||||
{{ formatDate(value) }}
|
||||
</span>
|
||||
<span v-else-if="value === null">---</span>
|
||||
<span v-else>{{ value }}</span>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="offset-sm-3 col-sm-9">
|
||||
<a
|
||||
v-if="hero.purchased.plan.paymentMethod === 'Google'"
|
||||
class="btn btn-primary btn-sm"
|
||||
target="_blank"
|
||||
:href="playOrdersUrl"
|
||||
>
|
||||
Play Console
|
||||
</a>
|
||||
<a
|
||||
v-else-if="hero.purchased.plan.paymentMethod === 'Paypal'"
|
||||
class="btn btn-primary btn-sm"
|
||||
target="_blank"
|
||||
:href="'https://www.paypal.com/billing/subscriptions/' + paymentDetails.customerId"
|
||||
>
|
||||
PayPal Dashboard
|
||||
</a>
|
||||
<a
|
||||
v-else-if="hero.purchased.plan.paymentMethod === 'Stripe'"
|
||||
class="btn btn-primary btn-sm"
|
||||
target="_blank"
|
||||
:href="'https://dashboard.stripe.com/customers/' + paymentDetails.customerId"
|
||||
>
|
||||
Stripe Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="expand"
|
||||
@@ -474,17 +569,36 @@
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/scss/colors.scss';
|
||||
|
||||
.input-group-append {
|
||||
width: auto;
|
||||
|
||||
.input-group-text {
|
||||
border-bottom-right-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
font-weight: 600;
|
||||
font-size: 0.8rem;
|
||||
color: $gray-200;
|
||||
.form-group {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.input-group-append {
|
||||
width: auto;
|
||||
|
||||
.input-group-text {
|
||||
border-bottom-right-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
font-weight: 600;
|
||||
font-size: 0.8rem;
|
||||
color: $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
font-size: 0.8rem;
|
||||
color: $purple-400;
|
||||
cursor: pointer;
|
||||
margin-left: 0.2rem;
|
||||
background-color: $gray-500;
|
||||
padding: 0.1rem 0.3rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.info-icon:hover {
|
||||
background-color: $purple-400;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -495,6 +609,55 @@ import subscriptionBlocks from '@/../../common/script/content/subscriptionBlocks
|
||||
import saveHero from '../mixins/saveHero';
|
||||
import LoadingSpinner from '@/components/ui/loadingSpinner';
|
||||
|
||||
const PLAY_CONSOLE_ORDERS_BASE_URL = import.meta.env.PLAY_CONSOLE_ORDERS_BASE_URL;
|
||||
|
||||
const humanReadablePaymentDetails = {
|
||||
customerId: {
|
||||
label: 'Customer ID',
|
||||
help: 'The unique identifier for the customer in the payment system.',
|
||||
},
|
||||
purchaseDate: {
|
||||
label: 'Purchase Date',
|
||||
help: 'The date when the subscription was purchased or renewed.',
|
||||
},
|
||||
originalPurchaseDate: {
|
||||
label: 'Original Purchase Date',
|
||||
help: 'The date when the subscription was first purchased.',
|
||||
},
|
||||
productId: {
|
||||
label: 'Product ID',
|
||||
help: 'The identifier for the product associated with the subscription.',
|
||||
},
|
||||
transactionId: {
|
||||
label: 'Transaction ID',
|
||||
help: 'The unique identifier for the last transaction in the payment system.',
|
||||
},
|
||||
isCanceled: {
|
||||
label: 'Is Canceled',
|
||||
help: 'Indicates whether the subscription has been canceled by the user or the system.',
|
||||
},
|
||||
isExpired: {
|
||||
label: 'Is Expired',
|
||||
help: 'Indicates whether the subscription has expired. A cancelled subscription may still be active until the end of the billing cycle.',
|
||||
},
|
||||
expirationDate: {
|
||||
label: 'Termination Date',
|
||||
help: 'The date when the subscription will expire or has expired.',
|
||||
},
|
||||
nextPaymentDate: {
|
||||
label: 'Next Payment Date',
|
||||
help: 'The date when the next payment is due. If the subscription is canceled or expired, this may be null.',
|
||||
},
|
||||
lastPaymentDate: {
|
||||
label: 'Last Payment Date',
|
||||
help: 'The date when the lastpayment was made for the subscription.',
|
||||
},
|
||||
failedPayments: {
|
||||
label: 'Failed Payments',
|
||||
help: 'Number of times the payment failed for this subscription.',
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LoadingSpinner,
|
||||
@@ -520,6 +683,7 @@ export default {
|
||||
isConvertingToGroupPlan: false,
|
||||
groupPlanID: '',
|
||||
subscriptionBlocks,
|
||||
paymentDetails: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -553,6 +717,9 @@ export default {
|
||||
}
|
||||
return terminationDate;
|
||||
},
|
||||
playOrdersUrl () {
|
||||
return `${PLAY_CONSOLE_ORDERS_BASE_URL}${this.paymentDetails?.transactionId || ''}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
dateFormat (date) {
|
||||
@@ -583,6 +750,20 @@ export default {
|
||||
this.isConvertingToGroupPlan = true;
|
||||
this.hero.purchased.plan.owner = '';
|
||||
},
|
||||
getSubscriptionPaymentDetails () {
|
||||
this.$store.dispatch('admin:getSubscriptionPaymentDetails', { userIdentifier: this.hero._id })
|
||||
.then(details => {
|
||||
if (details) {
|
||||
this.paymentDetails = details;
|
||||
} else {
|
||||
alert('No payment details found.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching subscription payment details:', error);
|
||||
alert(`Failed to fetch payment details: ${error.message || 'Unknown error'}`);
|
||||
});
|
||||
},
|
||||
saveClicked (e) {
|
||||
e.preventDefault();
|
||||
if (this.isConvertingToGroupPlan) {
|
||||
@@ -601,6 +782,31 @@ export default {
|
||||
this.$emit('changeUserIdentifier', id);
|
||||
}
|
||||
},
|
||||
getHumanReadablePaymentDetails (key) {
|
||||
return humanReadablePaymentDetails[key] || { label: key, help: '' };
|
||||
},
|
||||
isDate (date) {
|
||||
return moment(date).isValid();
|
||||
},
|
||||
formatDate (date) {
|
||||
return date ? moment(date).format('MM/DD/YYYY') : '---';
|
||||
},
|
||||
isSubscribed () {
|
||||
console.log(this.hero.purchased.plan.customerId, this.hero.purchased.plan.dateTerminated);
|
||||
return this.hero.purchased.plan
|
||||
&& this.hero.purchased.plan.customerId
|
||||
&& this.hero.purchased.plan.planId
|
||||
&& this.hero.purchased.plan.paymentMethod
|
||||
&& (
|
||||
!this.hero.purchased.plan.dateTerminated
|
||||
|| moment(this.hero.purchased.plan.dateTerminated).isAfter(moment())
|
||||
);
|
||||
},
|
||||
isCancelled () {
|
||||
return this.hero.purchased.plan
|
||||
&& this.hero.purchased.plan.dateTerminated
|
||||
&& this.hero.purchased.plan.dateTerminated !== '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -226,7 +226,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async retrieveUserHistory () {
|
||||
const history = await this.$store.dispatch('adminPanel:getUserHistory', { userIdentifier: this.hero._id });
|
||||
const history = await this.$store.dispatch('admin:getUserHistory', { userIdentifier: this.hero._id });
|
||||
this.armoire = history.armoire;
|
||||
this.questInviteResponses = history.questInviteResponses;
|
||||
this.cron = history.cron;
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
>
|
||||
{{ $t('adminPanel') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
v-if="hasPermission(user, 'groupSupport')"
|
||||
class="nav-link"
|
||||
:to="{name: 'groupAdmin'}"
|
||||
>
|
||||
{{ $t('groupAdmin') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
v-if="hasPermission(user, 'accessControl')"
|
||||
class="nav-link"
|
||||
|
||||
47
website/client/src/components/admin/formRow.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label"><slot name="label">{{ label }}</slot></label>
|
||||
<div class="col-sm-9">
|
||||
<slot>
|
||||
<textarea
|
||||
v-if="inputType === 'textarea'"
|
||||
:value="value"
|
||||
class="form-control"
|
||||
:rows="rows"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
></textarea>
|
||||
<input
|
||||
v-else
|
||||
:value="value"
|
||||
class="form-control"
|
||||
:type="inputType"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'input',
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
},
|
||||
value: {
|
||||
type: [String, Boolean],
|
||||
},
|
||||
inputType: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
rows: {
|
||||
default: 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<form>
|
||||
<form-row
|
||||
v-model="group.name"
|
||||
:label="$t('groupName')"
|
||||
/>
|
||||
<form-row
|
||||
v-model="group.summary"
|
||||
:label="$t('guildSummary')"
|
||||
input-type="textarea"
|
||||
/>
|
||||
<form-row
|
||||
v-model="group.description"
|
||||
:label="$t('groupDescription')"
|
||||
input-type="textarea"
|
||||
rows="6"
|
||||
/>
|
||||
<form-row
|
||||
v-model="group.bannedWordsAllowed"
|
||||
:label="$t('bannedWordsAllowed')"
|
||||
input-type="checkbox"
|
||||
/>
|
||||
<form-row
|
||||
v-model="group.leaderOnly.challenges"
|
||||
:label="$t('leaderOnlyChallenges')"
|
||||
input-type="checkbox"
|
||||
/>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import formRow from '@/components/admin/formRow.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
formRow,
|
||||
},
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div v-if="hasPermission(user, 'groupSupport')">
|
||||
<h2>{{ group.name }}</h2>
|
||||
<supportContainer
|
||||
:title="$t('groupData')"
|
||||
>
|
||||
<groupData
|
||||
:group="group"
|
||||
/>
|
||||
</supportContainer>
|
||||
<supportContainer
|
||||
:title="$t('groupPlanSubscription')"
|
||||
/>
|
||||
<supportContainer
|
||||
v-if="group.type === 'party'"
|
||||
:title="$t('questDetails')"
|
||||
/>
|
||||
<supportContainer
|
||||
:title="$t('members')"
|
||||
>
|
||||
<members
|
||||
:group="group"
|
||||
/>
|
||||
</supportContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { userStateMixin } from '../../../../mixins/userState';
|
||||
import supportContainer from '../../supportContainer.vue';
|
||||
import groupData from './groupData.vue';
|
||||
import members from './members.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
supportContainer,
|
||||
groupData,
|
||||
members,
|
||||
},
|
||||
mixins: [userStateMixin],
|
||||
data () {
|
||||
return {
|
||||
groupId: '',
|
||||
group: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
groupId () {
|
||||
this.loadGroup(this.groupId);
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.groupId = this.$route.params.groupId;
|
||||
},
|
||||
methods: {
|
||||
clearData () {
|
||||
this.group = {};
|
||||
},
|
||||
async loadGroup (groupId) {
|
||||
this.$emit('changeGroupId', groupId);
|
||||
this.group = await this.$store.dispatch('admin:getGroup', { groupId });
|
||||
},
|
||||
async updateGroup () {
|
||||
await this.$store.dispatch('admin:updateGroup', { group: this.group });
|
||||
this.$emit('groupSaved', this.group);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<form-row
|
||||
:label="$t('groupLeader')"
|
||||
>
|
||||
<strong class="col-form-label">
|
||||
<router-link
|
||||
:to="{'name': 'adminPanelUser', 'params': {'userIdentifier': group.leader }}"
|
||||
>
|
||||
{{ group.leader }}
|
||||
</router-link>
|
||||
</strong>
|
||||
</form-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import formRow from '@/components/admin/formRow.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
formRow,
|
||||
},
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
93
website/client/src/components/admin/groups/index.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="row standard-page col-12 d-flex justify-content-center">
|
||||
<div class="group-admin-content">
|
||||
<h1>{{ $t("groupAdmin") }}</h1>
|
||||
<form
|
||||
class="form-inline"
|
||||
@submit.prevent="loadGroup(groupID)"
|
||||
>
|
||||
<div class="input-group col pl-0 pr-0">
|
||||
<input
|
||||
v-model="groupID"
|
||||
class="form-control"
|
||||
type="text"
|
||||
placeholder="Group ID"
|
||||
>
|
||||
<div class="input-group-append">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
:disabled="!groupID"
|
||||
@click="loadGroup(groupID)"
|
||||
>
|
||||
Load
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<router-view
|
||||
class="mt-3"
|
||||
@changeGroupId="changeGroupId"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uidField {
|
||||
min-width: 45ch;
|
||||
}
|
||||
|
||||
.input-group-append {
|
||||
width:auto;
|
||||
}
|
||||
|
||||
.group-admin-content {
|
||||
flex: 0 0 800px;
|
||||
max-width: 800px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import VueRouter from 'vue-router';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
const { isNavigationFailure, NavigationFailureType } = VueRouter;
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
groupID: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('groupAdmin'),
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
changeGroupId (id) {
|
||||
this.groupID = id;
|
||||
},
|
||||
async loadGroup (groupId) {
|
||||
if (this.$router.currentRoute.name === 'groupAdminGroup') {
|
||||
await this.$router.push({
|
||||
name: 'groupAdmin',
|
||||
});
|
||||
}
|
||||
await this.$router.push({
|
||||
name: 'groupAdminGroup',
|
||||
params: { groupId },
|
||||
}).catch(failure => {
|
||||
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
|
||||
this.$router.go();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
53
website/client/src/components/admin/supportContainer.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h3
|
||||
class="mb-0 mt-0"
|
||||
:class="{'open': expand}"
|
||||
@click="expand = !expand"
|
||||
>
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
</h3>
|
||||
</div>
|
||||
<div
|
||||
v-if="expand"
|
||||
class="card-body"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div
|
||||
v-if="expand && onSave"
|
||||
class="card-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary mt-1"
|
||||
@click="onSave"
|
||||
>
|
||||
{{ $t('save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
onSave: {
|
||||
type: Function,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
expand: false,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -43,9 +43,11 @@ export default {
|
||||
const AUTH_SETTINGS = localStorage.getItem(LOCALSTORAGE_AUTH_KEY);
|
||||
const parseSettings = JSON.parse(AUTH_SETTINGS);
|
||||
const userId = parseSettings ? parseSettings.auth.apiId : '';
|
||||
const username = this.$store?.state?.user?.data?.auth?.local?.username || '';
|
||||
|
||||
return this.$t('accountSuspended', {
|
||||
userId,
|
||||
username,
|
||||
communityManagerEmail: COMMUNITY_MANAGER_EMAIL,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -72,32 +72,40 @@
|
||||
</div>
|
||||
<div class="col-12 col-md-6 text-right">
|
||||
<div
|
||||
class="box member-count"
|
||||
class="box member-count p-2"
|
||||
@click="showMemberModal()"
|
||||
>
|
||||
<div
|
||||
class="svg-icon member-icon"
|
||||
v-html="icons.memberIcon"
|
||||
></div>
|
||||
{{ challenge.memberCount }}
|
||||
<div
|
||||
v-once
|
||||
class="details"
|
||||
>
|
||||
{{ $t('participantsTitle') }}
|
||||
<div class="box-content">
|
||||
<div class="icon-number-row">
|
||||
<div
|
||||
class="svg-icon member-icon"
|
||||
v-html="icons.memberIcon"
|
||||
></div>
|
||||
<span class="number">{{ challenge.memberCount }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-once
|
||||
class="details"
|
||||
>
|
||||
{{ $t('participantsTitle') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div
|
||||
class="svg-icon gem-icon"
|
||||
v-html="icons.gemIcon"
|
||||
></div>
|
||||
{{ challenge.prize || 0 }}
|
||||
<div
|
||||
v-once
|
||||
class="details"
|
||||
>
|
||||
{{ $t('prize') }}
|
||||
<div class="box prize-count p-2">
|
||||
<div class="box-content">
|
||||
<div class="icon-number-row">
|
||||
<div
|
||||
class="svg-icon gem-icon"
|
||||
v-html="icons.gemIcon"
|
||||
></div>
|
||||
<span class="number">{{ challenge.prize || 0 }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-once
|
||||
class="details"
|
||||
>
|
||||
{{ $t('prize') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -304,7 +312,6 @@
|
||||
|
||||
.box {
|
||||
display: inline-block;
|
||||
padding: 1em;
|
||||
border-radius: 2px;
|
||||
background-color: $white;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
@@ -314,22 +321,88 @@
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
vertical-align: bottom;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&.member-count:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.box-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.icon-number-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 0.1em;
|
||||
|
||||
.number {
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
margin-right: .2em;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.details {
|
||||
font-size: 12px;
|
||||
margin-top: 0.4em;
|
||||
color: $gray-200;
|
||||
width: 100%;
|
||||
padding: 0 4px;
|
||||
line-height: 1.15;
|
||||
word-break: break-word;
|
||||
max-height: 2.3em;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
&.member-count {
|
||||
.icon-number-row {
|
||||
.svg-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.number {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
font-size: 11px;
|
||||
line-height: 1.1;
|
||||
max-height: 2.2em;
|
||||
}
|
||||
}
|
||||
|
||||
&.prize-count {
|
||||
.icon-number-row {
|
||||
.svg-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.number {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
font-size: 11px;
|
||||
line-height: 1.1;
|
||||
max-height: 2.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
id="close-challenge-modal"
|
||||
:title="$t('endChallenge')"
|
||||
size="md"
|
||||
:hide-header="false"
|
||||
>
|
||||
<div
|
||||
slot="modal-header"
|
||||
@@ -15,6 +16,9 @@
|
||||
>
|
||||
{{ $t('endChallenge') }}
|
||||
</h2>
|
||||
<close-x
|
||||
@close="$root.$emit('bv::hide::modal', 'close-challenge-modal')"
|
||||
/>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<span
|
||||
@@ -28,28 +32,67 @@
|
||||
class="col-12"
|
||||
>
|
||||
<div class="col-12">
|
||||
<div class="support-habitica">
|
||||
<!-- @TODO: Add challenge achievement badge here-->
|
||||
<div class="badge-section">
|
||||
<div
|
||||
class="gems-left"
|
||||
v-html="icons.gemsOrange"
|
||||
></div>
|
||||
<div
|
||||
class="challenge-badge"
|
||||
v-html="icons.endChallengeBadge"
|
||||
></div>
|
||||
<div
|
||||
class="gems-right"
|
||||
v-html="icons.gemsPurple"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<strong v-once>{{ $t('selectChallengeWinnersDescription') }}</strong>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<member-search-dropdown
|
||||
:text="winnerText"
|
||||
:members="members"
|
||||
:challenge-id="challengeId"
|
||||
@member-selected="selectMember"
|
||||
/>
|
||||
<div class="col-12 search-input-container">
|
||||
<div class="search-input-wrapper">
|
||||
<div
|
||||
class="search-icon"
|
||||
v-html="icons.search"
|
||||
></div>
|
||||
<input
|
||||
v-model="searchTerm"
|
||||
class="search-input"
|
||||
type="text"
|
||||
placeholder="@Username"
|
||||
@input="searchMembers"
|
||||
@focus="showResults = true"
|
||||
@blur="handleBlur"
|
||||
>
|
||||
<div
|
||||
v-if="showResults && filteredMembers.length > 0"
|
||||
class="search-results"
|
||||
>
|
||||
<div
|
||||
v-for="member in filteredMembers"
|
||||
:key="member._id"
|
||||
class="search-result-item"
|
||||
@mousedown="selectMember(member)"
|
||||
>
|
||||
{{ getMemberDisplayName(member) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button
|
||||
v-once
|
||||
class="btn btn-primary"
|
||||
class="btn award-winner-btn"
|
||||
:class="{'has-winner': winner._id}"
|
||||
:disabled="!winner._id"
|
||||
@click="closeChallenge"
|
||||
>
|
||||
{{ $t('awardWinners') }}
|
||||
<span>{{ $t('awardWinners') }}</span>
|
||||
<div
|
||||
class="gem-icon"
|
||||
v-html="icons.gem"
|
||||
></div>
|
||||
<span>{{ prize }} {{ prize === 1 ? $t('gem') : $t('gems') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</span>
|
||||
@@ -60,14 +103,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<strong v-once>{{ $t('doYouWantedToDeleteChallenge') }}</strong>
|
||||
<strong
|
||||
v-once
|
||||
class="delete-challenge-text"
|
||||
>{{ $t('doYouWantedToDeleteChallenge') }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-once
|
||||
class="col-12 refund-text"
|
||||
>
|
||||
{{ $t('deleteChallengeRefundDescription') }}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button
|
||||
v-once
|
||||
class="btn btn-danger"
|
||||
class="btn btn-danger delete-challenge-btn"
|
||||
@click="deleteChallenge()"
|
||||
>
|
||||
<div
|
||||
class="svg-icon color delete-icon"
|
||||
v-html="icons.deleteIcon"
|
||||
></div>
|
||||
{{ $t('deleteChallenge') }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -82,6 +138,7 @@
|
||||
|
||||
<style lang='scss'>
|
||||
@import '@/assets/scss/colors.scss';
|
||||
@import '@/assets/scss/button.scss';
|
||||
|
||||
#close-challenge-modal {
|
||||
h2 {
|
||||
@@ -94,26 +151,190 @@
|
||||
|
||||
.header-wrap {
|
||||
width: 100%;
|
||||
padding-top: 2em;
|
||||
padding-top: 32px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.support-habitica {
|
||||
background-image: url('@/assets/svg/for-css/support-habitica-gems.svg?raw');
|
||||
width: 325px;
|
||||
height: 89px;
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.search-input-container {
|
||||
margin-top: 1em !important;
|
||||
}
|
||||
|
||||
.search-input-wrapper {
|
||||
position: relative;
|
||||
width: 384px;
|
||||
margin: 0 auto;
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-55%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: $gray-200;
|
||||
pointer-events: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
padding-left: 36px;
|
||||
padding-right: 12px;
|
||||
border: 1px solid $gray-400;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
transition: border-color 0.2s ease, border-width 0.2s ease;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: 2px solid $purple-400;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: $gray-300;
|
||||
}
|
||||
}
|
||||
|
||||
.search-results {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: $white;
|
||||
border: 1px solid $gray-400;
|
||||
border-top: none;
|
||||
border-radius: 0 0 4px 4px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.search-result-item {
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background-color: $purple-600;
|
||||
color: $purple-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delete-challenge-text {
|
||||
color: $maroon-50;
|
||||
}
|
||||
|
||||
.refund-text {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
color: $gray-50;
|
||||
margin-top: 0.5em !important;
|
||||
}
|
||||
|
||||
.delete-challenge-btn {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: 24px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.delete-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
.award-winner-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 32px;
|
||||
padding: 4px 12px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:not(:disabled) {
|
||||
background-color: $white;
|
||||
color: $gray-200;
|
||||
border: 1px solid $gray-400;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
|
||||
&.has-winner {
|
||||
background-color: $purple-200;
|
||||
color: $white;
|
||||
border-color: $purple-200;
|
||||
}
|
||||
|
||||
&:hover:not(.has-winner) {
|
||||
background-color: $gray-700;
|
||||
}
|
||||
}
|
||||
|
||||
.gem-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: $gems-color;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.5rem;
|
||||
margin: -24px auto 0;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
.gems-left, .gems-right {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.challenge-badge {
|
||||
width: 48px;
|
||||
height: 52px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer, .modal-header {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.footer-wrap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
margin-top: 2em;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.col-12:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.or {
|
||||
@@ -123,21 +344,39 @@
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
font-weight: bold;
|
||||
color: $gray-100;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import memberSearchDropdown from '@/components/members/memberSearchDropdown';
|
||||
import searchIcon from '@/assets/svg/for-css/search.svg?raw';
|
||||
import deleteIcon from '@/assets/svg/delete.svg?raw';
|
||||
import gemIcon from '@/assets/svg/gem.svg?raw';
|
||||
import endChallengeBadge from '@/assets/svg/for-css/end_challenge_badge.svg?raw';
|
||||
import gemsOrange from '@/assets/svg/for-css/orange100_red100_yellow100_gems.svg?raw';
|
||||
import gemsPurple from '@/assets/svg/for-css/purple200_green10_blue100_gems.svg?raw';
|
||||
import closeX from '@/components/ui/closeX';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
memberSearchDropdown,
|
||||
closeX,
|
||||
},
|
||||
props: ['challengeId', 'members', 'prize', 'flagCount'],
|
||||
data () {
|
||||
return {
|
||||
winner: {},
|
||||
searchTerm: '',
|
||||
showResults: false,
|
||||
filteredMembers: [],
|
||||
icons: Object.freeze({
|
||||
search: searchIcon,
|
||||
deleteIcon,
|
||||
gem: gemIcon,
|
||||
endChallengeBadge,
|
||||
gemsOrange,
|
||||
gemsPurple,
|
||||
}),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -150,8 +389,35 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
searchMembers () {
|
||||
if (!this.searchTerm) {
|
||||
this.filteredMembers = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const searchLower = this.searchTerm.toLowerCase().replace('@', '');
|
||||
this.filteredMembers = this.members.filter(member => {
|
||||
const username = member.auth?.local?.username || '';
|
||||
const displayName = member.profile?.name || '';
|
||||
return username.toLowerCase().includes(searchLower)
|
||||
|| displayName.toLowerCase().includes(searchLower);
|
||||
}).slice(0, 10);
|
||||
},
|
||||
getMemberDisplayName (member) {
|
||||
if (member.auth?.local?.username) {
|
||||
return `@${member.auth.local.username}`;
|
||||
}
|
||||
return member.profile?.name || '';
|
||||
},
|
||||
selectMember (member) {
|
||||
this.winner = member;
|
||||
this.searchTerm = this.getMemberDisplayName(member);
|
||||
this.showResults = false;
|
||||
},
|
||||
handleBlur () {
|
||||
setTimeout(() => {
|
||||
this.showResults = false;
|
||||
}, 200);
|
||||
},
|
||||
async closeChallenge () {
|
||||
this.challenge = await this.$store.dispatch('challenges:selectChallengeWinner', {
|
||||
|
||||
@@ -1,37 +1,43 @@
|
||||
<template>
|
||||
<div
|
||||
class="notification d-flex flex-column justify-content-center text-center"
|
||||
class="notification d-flex justify-content-center align-items-center"
|
||||
>
|
||||
<strong
|
||||
v-once
|
||||
class="mx-auto mb-2"
|
||||
<img
|
||||
src="@/assets/images/gifts_start.svg"
|
||||
class="gift-start"
|
||||
alt=""
|
||||
>
|
||||
{{ $t('g1g1') }}
|
||||
</strong>
|
||||
<small
|
||||
v-once
|
||||
class="mx-4 mb-3"
|
||||
>
|
||||
{{ $t('g1g1Details') }}
|
||||
</small>
|
||||
<div
|
||||
class="btn-secondary mx-auto d-flex"
|
||||
@click="showSelectUser()"
|
||||
>
|
||||
<div
|
||||
<div class="content-wrapper d-flex flex-column justify-content-center text-center">
|
||||
<strong
|
||||
v-once
|
||||
class="m-auto"
|
||||
class="mx-auto mb-2"
|
||||
>
|
||||
{{ $t('g1g1') }}
|
||||
</strong>
|
||||
<small
|
||||
v-once
|
||||
class="mx-4 mb-3"
|
||||
>
|
||||
{{ $t('g1g1Details') }}
|
||||
</small>
|
||||
<button
|
||||
class="btn btn-secondary mx-auto"
|
||||
@click="showSelectUser()"
|
||||
>
|
||||
{{ $t('sendGift') }}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<img
|
||||
src="@/assets/images/gifts_start.svg"
|
||||
class="gift-end"
|
||||
alt=""
|
||||
>
|
||||
<div
|
||||
class="notification-remove"
|
||||
@click.stop="remove()"
|
||||
class="close-x"
|
||||
@click="remove()"
|
||||
>
|
||||
<div
|
||||
v-once
|
||||
class="svg-icon"
|
||||
class="svg-icon svg-close"
|
||||
v-html="icons.close"
|
||||
></div>
|
||||
</div>
|
||||
@@ -41,51 +47,89 @@
|
||||
<style lang='scss' scoped>
|
||||
@import '@/assets/scss/colors.scss';
|
||||
|
||||
small, strong {
|
||||
small {
|
||||
color: $white;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
line-height: 1.714;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: $white;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
line-height: 1.714;
|
||||
}
|
||||
|
||||
.notification {
|
||||
background-image: url('@/assets/images/g1g1-notif.png');
|
||||
background-image: url('@/assets/images/gifts_bg.svg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
height: 10rem;
|
||||
padding: 3rem;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.notification-remove {
|
||||
position: absolute;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
padding: 4px;
|
||||
right: 24px;
|
||||
top: 24px;
|
||||
|
||||
.svg-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
.content-wrapper {
|
||||
flex: 1;
|
||||
padding: 2rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
width: 5.75rem;
|
||||
min-height: 1.5rem;
|
||||
border-radius: 2px;
|
||||
border-color: $white;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
.gift-start {
|
||||
height: 96px;
|
||||
width: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.gift-end {
|
||||
height: 96px;
|
||||
width: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) scaleX(-1);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.close-x {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
|
||||
&:hover .svg-close {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.svg-close {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import closeIcon from '@/assets/svg/close-teal.svg?raw';
|
||||
import { mapActions } from '@/libs/store';
|
||||
import closeIcon from '@/assets/svg/close-white.svg?raw';
|
||||
|
||||
export default {
|
||||
props: ['notification'],
|
||||
props: ['notification', 'eventKey'],
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
@@ -94,11 +138,11 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
readNotification: 'notifications:readNotification',
|
||||
}),
|
||||
remove () {
|
||||
this.readNotification({ notificationId: this.notification.id });
|
||||
if (this.eventKey) {
|
||||
window.sessionStorage.setItem(`hide-g1g1-${this.eventKey}`, 'true');
|
||||
}
|
||||
this.$emit('notification-removed');
|
||||
},
|
||||
showSelectUser () {
|
||||
this.$root.$emit('bv::show::modal', 'select-user-modal');
|
||||
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
props: ['notification', 'canRemove'],
|
||||
methods: {
|
||||
action () {
|
||||
this.$router.push({ name: 'achievements' });
|
||||
this.$router.push(`/profile/${this.$store.state.user.data._id}#achievements`);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
action () {
|
||||
this.$router.push({ name: 'stats' });
|
||||
this.$router.push(`/profile/${this.$store.state.user.data._id}#stats`);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -49,6 +49,12 @@
|
||||
v-if="showOnboardingGuide"
|
||||
:never-seen="hasSpecialBadge"
|
||||
/>
|
||||
<gift-one-get-one-notification
|
||||
v-if="shouldShowG1g1"
|
||||
:notification="g1g1Notification"
|
||||
:event-key="g1g1EventKey"
|
||||
@notification-removed="handleG1g1Removed"
|
||||
/>
|
||||
<component
|
||||
:is="notification.type"
|
||||
v-for="notification in notifications"
|
||||
@@ -114,6 +120,7 @@
|
||||
<script>
|
||||
import * as quests from '@/../../common/script/content/quests';
|
||||
import { hasCompletedOnboarding } from '@/../../common/script/libs/onboarding';
|
||||
import find from 'lodash/find';
|
||||
import { mapState, mapActions } from '@/libs/store';
|
||||
import notificationsIcon from '@/assets/svg/notifications.svg?raw';
|
||||
import MenuDropdown from '../ui/customMenuDropdown';
|
||||
@@ -151,6 +158,7 @@ export default {
|
||||
CARD_RECEIVED,
|
||||
CHALLENGE_INVITATION,
|
||||
GIFT_ONE_GET_ONE,
|
||||
GiftOneGetOneNotification: GIFT_ONE_GET_ONE,
|
||||
GROUP_TASK_ASSIGNED,
|
||||
GROUP_TASK_CLAIMED,
|
||||
GROUP_TASK_NEEDS_WORK,
|
||||
@@ -178,17 +186,14 @@ export default {
|
||||
hasSpecialBadge: false,
|
||||
quests,
|
||||
openStatus: undefined,
|
||||
g1g1Hidden: false,
|
||||
actionableNotifications: [
|
||||
'GUILD_INVITATION', 'PARTY_INVITATION', 'CHALLENGE_INVITATION',
|
||||
'QUEST_INVITATION',
|
||||
],
|
||||
// A list of notifications handled by this component,
|
||||
// listed in the order they should appear in the notifications panel.
|
||||
// NOTE: Those not listed here won't be shown in the notification panel!
|
||||
handledNotifications: [
|
||||
'NEW_STUFF',
|
||||
'ITEM_RECEIVED',
|
||||
'GIFT_ONE_GET_ONE',
|
||||
'GROUP_TASK_NEEDS_WORK',
|
||||
'GUILD_INVITATION',
|
||||
'PARTY_INVITATION',
|
||||
@@ -207,7 +212,10 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
...mapState({
|
||||
user: 'user.data',
|
||||
currentEventList: 'worldState.data.currentEventList',
|
||||
}),
|
||||
notificationsOrder () {
|
||||
// Returns a map of NOTIFICATION_TYPE -> POSITION
|
||||
const orderMap = {};
|
||||
@@ -286,9 +294,9 @@ export default {
|
||||
|
||||
return notifications;
|
||||
},
|
||||
// The total number of notification, shown inside the dropdown
|
||||
notificationsCount () {
|
||||
return this.notifications.length;
|
||||
const g1g1Count = this.shouldShowG1g1 ? 1 : 0;
|
||||
return this.notifications.length + g1g1Count;
|
||||
},
|
||||
hasUnseenNotifications () {
|
||||
return this.notifications.some(notification => (notification.seen === false));
|
||||
@@ -299,6 +307,30 @@ export default {
|
||||
showOnboardingGuide () {
|
||||
return !hasCompletedOnboarding(this.user);
|
||||
},
|
||||
currentG1g1Event () {
|
||||
return find(this.currentEventList, event => event.promo === 'g1g1');
|
||||
},
|
||||
g1g1EventKey () {
|
||||
if (!this.currentG1g1Event || !this.currentG1g1Event.start) return null;
|
||||
const startDate = new Date(this.currentG1g1Event.start);
|
||||
return `${startDate.getFullYear()}-${startDate.getMonth()}`;
|
||||
},
|
||||
shouldShowG1g1 () {
|
||||
if (!this.currentG1g1Event) return false;
|
||||
const eventKey = this.g1g1EventKey;
|
||||
if (eventKey && window.sessionStorage.getItem(`hide-g1g1-${eventKey}`) === 'true') {
|
||||
return false;
|
||||
}
|
||||
return !this.g1g1Hidden;
|
||||
},
|
||||
g1g1Notification () {
|
||||
return {
|
||||
type: 'GIFT_ONE_GET_ONE',
|
||||
id: `g1g1-event-${this.currentG1g1Event?.start || 'default'}`,
|
||||
data: {},
|
||||
seen: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
const onboardingPanelState = getLocalSetting(CONSTANTS.keyConstants.ONBOARDING_PANEL_STATE);
|
||||
@@ -364,6 +396,9 @@ export default {
|
||||
isActionable (notification) {
|
||||
return this.actionableNotifications.indexOf(notification.type) !== -1;
|
||||
},
|
||||
handleG1g1Removed () {
|
||||
this.g1g1Hidden = true;
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@@ -176,7 +176,12 @@ export default {
|
||||
}
|
||||
},
|
||||
showProfile (startingPage) {
|
||||
this.$router.push({ name: startingPage });
|
||||
const userId = this.$store.state.user.data._id;
|
||||
let path = `/profile/${userId}`;
|
||||
if (startingPage !== 'profile') {
|
||||
path += `#${startingPage}`;
|
||||
}
|
||||
this.$router.push(path);
|
||||
},
|
||||
toLearnMore () {
|
||||
this.$router.push({ name: 'subscription' });
|
||||
|
||||
@@ -454,17 +454,14 @@ export default {
|
||||
},
|
||||
isUserMentioned () {
|
||||
const message = this.msg;
|
||||
|
||||
if (message.highlight) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const { user } = this;
|
||||
const displayName = user.profile.name;
|
||||
const { username } = user.auth.local;
|
||||
const pattern = `@(${escapeRegExp(displayName)}|${escapeRegExp(username)})(\\b)`;
|
||||
message.highlight = new RegExp(pattern, 'i').test(message.text);
|
||||
|
||||
if (!username) return false;
|
||||
const usernamePattern = new RegExp(`@${escapeRegExp(username)}(?:\\b|(?=[^a-zA-Z0-9_]))`, 'i');
|
||||
message.highlight = usernamePattern.test(message.text);
|
||||
return message.highlight;
|
||||
},
|
||||
flagCountDescription () {
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
class="staff col-6 p-0"
|
||||
>
|
||||
<div class="d-flex">
|
||||
<router-link
|
||||
<div
|
||||
class="title"
|
||||
:to="{'name': 'userProfile', 'params': {'userId': user.uuid}}"
|
||||
>
|
||||
{{ user.name }}
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
v-if="user.type === 'Staff'"
|
||||
class="svg-icon staff-icon ml-1"
|
||||
v-html="icons.tierStaff"
|
||||
></div>
|
||||
|
||||
@@ -851,7 +851,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
if (this.genericPurchase) {
|
||||
this.makeGenericPurchase(this.item, 'buyModal', this.selectedAmountToBuy);
|
||||
await this.makeGenericPurchase(this.item, 'buyModal', this.selectedAmountToBuy);
|
||||
await this.purchased(this.item.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,9 +120,9 @@
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'heyeilatan', realName: 'Natalie'}) }}
|
||||
({{ $t('commGuideOnGitHub', {gitHubName: 'CuriousMagpie'}) }})
|
||||
- Web Developer
|
||||
{{ $t('commGuideAKA', {habitName: 'Viirus', realName: 'Phillip'}) }}
|
||||
({{ $t('commGuideOnGitHub', {gitHubName: 'phillipthelen'}) }})
|
||||
- Developer
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'redphoenix', realName: 'Vicky'}) }}
|
||||
@@ -133,10 +133,6 @@
|
||||
{{ $t('commGuideAKA', {habitName: 'Beffymaroo', realName: 'Beth'}) }}
|
||||
- Art, Community Management, Many Hats
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'SabreCat', realName: 'Sabe'}) }}
|
||||
- Web Developer
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'Apollo', realName: 'Tressley'}) }}
|
||||
- Designer
|
||||
@@ -146,8 +142,13 @@
|
||||
- Mobile Designer
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'Viirus', realName: 'Phillip'}) }}
|
||||
- Mobile Developer
|
||||
{{ $t('commGuideAKA', {habitName: 'SabreCat', realName: 'Kalista'}) }}
|
||||
- Web Developer
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {habitName: 'fizself', realName: 'Hafiz'}) }}
|
||||
({{ $t('commGuideOnGitHub', {gitHubName: 'hafizzle'}) }})
|
||||
- Developer
|
||||
</li>
|
||||
</ul>
|
||||
<p v-html="$t('commGuidePara013')"></p>
|
||||
@@ -156,7 +157,7 @@
|
||||
<em>
|
||||
Lemoness, lefnire, Slappybag, litenull, Shaner, Bobbyroberts99, wc8,
|
||||
Breadstrings, Megan, Blade, Daniel the Bard, deilann, shanaqui, Nakonana,
|
||||
Dewines, Alys, Fox_town, MaybeSteveRogers, and Cantras.
|
||||
Dewines, Alys, Fox_town, MaybeSteveRogers, Cantras, and heyeilatan.
|
||||
</em>
|
||||
</p>
|
||||
<h2 id="final">
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary d-flex align-items-center justify-content-center"
|
||||
:class="{disabled: !canSave}"
|
||||
:class="{'btn-disabled': !canSave}"
|
||||
type="button"
|
||||
@click="submit()"
|
||||
>
|
||||
@@ -162,13 +162,13 @@
|
||||
>
|
||||
<div
|
||||
class="habit-option-icon svg-icon no-transition"
|
||||
:class="task.up ? '' : 'disabled'"
|
||||
:class="task.up ? '' : 'icon-disabled'"
|
||||
v-html="icons.positive"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="habit-option-label no-transition"
|
||||
:class="task.up ? cssClass('icon') : 'disabled'"
|
||||
:class="task.up ? cssClass('icon') : 'label-disabled'"
|
||||
>
|
||||
{{ $t('positive') }}
|
||||
</div>
|
||||
@@ -188,13 +188,13 @@
|
||||
>
|
||||
<div
|
||||
class="habit-option-icon no-transition svg-icon negative mx-auto"
|
||||
:class="task.down ? '' : 'disabled'"
|
||||
:class="task.down ? '' : 'icon-disabled'"
|
||||
v-html="icons.negative"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="habit-option-label no-transition"
|
||||
:class="task.down ? cssClass('icon') : 'disabled'"
|
||||
:class="task.down ? cssClass('icon') : 'label-disabled'"
|
||||
>
|
||||
{{ $t('negative') }}
|
||||
</div>
|
||||
@@ -592,7 +592,7 @@
|
||||
<button
|
||||
class="btn btn-primary btn-footer
|
||||
d-flex align-items-center justify-content-center"
|
||||
:class="{disabled: !canSave}"
|
||||
:class="{'btn-disabled': !canSave}"
|
||||
type="button"
|
||||
@click="submit()"
|
||||
>
|
||||
@@ -881,12 +881,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
.btn-disabled {
|
||||
background-color: $white;
|
||||
border: 2px solid transparent;
|
||||
color: $gray-200;
|
||||
line-height: 1.714;
|
||||
box-shadow: 0px 1px 3px 0px rgba(26, 24, 29, 0.12), 0px 1px 2px 0px rgba(26, 24, 29, 0.24);
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
|
||||
&:focus {
|
||||
background-color: $white;
|
||||
@@ -948,7 +950,7 @@
|
||||
height: 10px;
|
||||
color: $white;
|
||||
|
||||
&.disabled {
|
||||
&.icon-disabled {
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
@@ -962,7 +964,7 @@
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
&.disabled {
|
||||
&.label-disabled {
|
||||
color: $gray-100;
|
||||
font-weight: normal;
|
||||
}
|
||||
@@ -1018,7 +1020,7 @@
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.disabled .input-group-text {
|
||||
.input-group-outer.disabled .input-group-text {
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
.toggle-switch-inner:before {
|
||||
content: "";
|
||||
padding-left: 10px;
|
||||
background-color: $green-10;
|
||||
background-color: $green-50;
|
||||
}
|
||||
|
||||
.toggle-switch-inner:after {
|
||||
|
||||
@@ -1126,7 +1126,12 @@ export default {
|
||||
this.loadUser();
|
||||
this.oldTitle = this.$store.state.title;
|
||||
this.handleExternalLinks();
|
||||
this.selectPage(this.startingPage);
|
||||
// Check if there's a hash in the URL to determine the starting page
|
||||
let pageToSelect = this.startingPage;
|
||||
if (window.location.hash && (window.location.hash === '#stats' || window.location.hash === '#achievements')) {
|
||||
pageToSelect = window.location.hash.substring(1);
|
||||
}
|
||||
this.selectPage(pageToSelect);
|
||||
this.$root.$on('habitica:report-profile-result', () => {
|
||||
this.loadUser();
|
||||
});
|
||||
@@ -1211,10 +1216,15 @@ export default {
|
||||
},
|
||||
selectPage (page) {
|
||||
this.selectedPage = page || 'profile';
|
||||
window.history.replaceState(null, null, '');
|
||||
const profileUserId = this.userId || this.userLoggedIn._id;
|
||||
let newPath = `/profile/${profileUserId}`;
|
||||
if (page !== 'profile') {
|
||||
newPath += `#${page}`;
|
||||
}
|
||||
window.history.replaceState(null, null, newPath);
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('user'),
|
||||
subSection: this.$t(this.startingPage),
|
||||
subSection: this.$t(page),
|
||||
});
|
||||
},
|
||||
getNextIncentive () {
|
||||
|
||||
@@ -3,14 +3,10 @@ import isEqual from 'lodash/isEqual';
|
||||
import keys from 'lodash/keys';
|
||||
import pick from 'lodash/pick';
|
||||
import amplitude from 'amplitude-js';
|
||||
import { gtag, install } from 'ga-gtag';
|
||||
import Vue from 'vue';
|
||||
import getStore from '@/store';
|
||||
|
||||
const AMPLITUDE_KEY = import.meta.env.AMPLITUDE_KEY;
|
||||
const DEBUG_ENABLED = import.meta.env.DEBUG_ENABLED === 'true';
|
||||
const GA_ID = import.meta.env.GA_ID;
|
||||
const IS_PRODUCTION = import.meta.env.NODE_ENV === 'production';
|
||||
const REQUIRED_FIELDS = ['eventCategory', 'eventAction'];
|
||||
|
||||
let analyticsLoading = false;
|
||||
@@ -19,7 +15,7 @@ let analyticsReady = false;
|
||||
function _getConsentedUser () {
|
||||
const store = getStore();
|
||||
const user = store.state.user.data;
|
||||
if (!user?.preferences?.analyticsConsent || navigator.globalPrivacyControl) {
|
||||
if (!user?.preferences?.analyticsConsent) {
|
||||
return false;
|
||||
}
|
||||
return user;
|
||||
@@ -69,10 +65,6 @@ function _gatherUserStats (properties) {
|
||||
export function safeSetup (userId) {
|
||||
if (analyticsLoading || analyticsReady) return;
|
||||
analyticsLoading = true;
|
||||
install(GA_ID, {
|
||||
debug_mode: DEBUG_ENABLED || !IS_PRODUCTION,
|
||||
user_id: userId,
|
||||
});
|
||||
amplitude.getInstance().init(AMPLITUDE_KEY, userId);
|
||||
analyticsReady = true;
|
||||
analyticsLoading = false;
|
||||
@@ -90,7 +82,6 @@ export function track (properties, options = {}) {
|
||||
// Track events on the server by default
|
||||
if (trackOnClient === true) {
|
||||
amplitude.getInstance().logEvent(properties.eventAction, properties);
|
||||
gtag('event', properties.eventAction, properties);
|
||||
} else {
|
||||
const store = getStore();
|
||||
store.dispatch('analytics:trackEvent', properties);
|
||||
@@ -105,7 +96,6 @@ export function updateUser (properties = {}) {
|
||||
// Use nextTick to avoid blocking the UI
|
||||
Vue.nextTick(() => {
|
||||
_gatherUserStats(properties);
|
||||
gtag('set', 'user_properties', properties);
|
||||
forEach(properties, (value, key) => {
|
||||
const identify = new amplitude.Identify().set(key, value);
|
||||
amplitude.getInstance().identify(identify);
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import habiticaMarkdown from 'habitica-markdown/withMentions';
|
||||
import escapeRegExp from 'lodash/escapeRegExp';
|
||||
|
||||
export default function renderWithMentions (text, user) {
|
||||
if (!text) return null;
|
||||
const env = { userName: user.auth.local.username, displayName: user.profile.name };
|
||||
return habiticaMarkdown.render(String(text), env);
|
||||
const env = { userName: user.auth.local.username };
|
||||
let html = habiticaMarkdown.render(String(text), env);
|
||||
|
||||
if (user.auth.local.username) {
|
||||
const username = escapeRegExp(user.auth.local.username);
|
||||
const regex = new RegExp(`(<span class="at-text">@)(${username})(</span>)`, 'gi');
|
||||
html = html.replace(regex, (match, p1, p2, p3) => `${p1.replace('at-text', 'at-text at-highlight')}${p2}${p3}`);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ export default [
|
||||
uuid: '61b2c855-0a30-444c-bcc6-1cac876460b0',
|
||||
},
|
||||
{
|
||||
name: 'heyeilatan',
|
||||
name: 'fizself',
|
||||
type: 'Staff',
|
||||
uuid: 'f4e5c6da-0617-48bf-b3bd-9f97636774a8',
|
||||
uuid: 'e39ea3eb-28d2-48da-8568-7a5b0e64498e',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
flex: 0 0 732px;
|
||||
flex: 0 0 751px;
|
||||
max-width: unset;
|
||||
|
||||
::v-deep {
|
||||
|
||||
@@ -33,6 +33,21 @@
|
||||
v-html="$t('privacySettingsOverview') + ' ' + $t('learnMorePrivacy')"
|
||||
>
|
||||
</p>
|
||||
<div
|
||||
v-if="gpcEnabled"
|
||||
class="mx-4 px-3 py-2 mb-4 gpc-alert d-flex align-items-center black bg-yellow-50"
|
||||
>
|
||||
<div
|
||||
class="svg svg-icon mr-2"
|
||||
v-html="icons.alert"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="gpc-message"
|
||||
v-html="gpcInfo"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex justify-content-center"
|
||||
>
|
||||
@@ -91,6 +106,29 @@
|
||||
line-height: 1.33;
|
||||
}
|
||||
|
||||
.gpc-alert {
|
||||
border-radius: 4px;
|
||||
line-height: 1.714;
|
||||
|
||||
.gpc-message {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
::v-deep a {
|
||||
color: $black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 16px;
|
||||
opacity: 0.75;
|
||||
|
||||
::v-deep svg path {
|
||||
fill: $black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mb-28p {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
@@ -110,6 +148,7 @@ import ToggleSwitch from '@/components/ui/toggleSwitch.vue';
|
||||
import { GenericUserPreferencesMixin } from '@/pages/settings/components/genericUserPreferencesMixin';
|
||||
import { InlineSettingMixin } from '../components/inlineSettingMixin';
|
||||
import { mapState } from '@/libs/store';
|
||||
import alert from '@/assets/svg/for-css/alert.svg?raw';
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
@@ -120,14 +159,32 @@ export default {
|
||||
SaveCancelButtons,
|
||||
ToggleSwitch,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
alert,
|
||||
}),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
user: 'user.data',
|
||||
}),
|
||||
gpcEnabled () {
|
||||
return navigator.globalPrivacyControl;
|
||||
},
|
||||
gpcInfo () {
|
||||
const gpcUrl = 'https://globalprivacycontrol.org/';
|
||||
if (this.user.preferences.analyticsConsent) {
|
||||
return this.$t('gpcPlusAnalytics', { url: gpcUrl });
|
||||
}
|
||||
return this.$t('gpcWarning', { url: gpcUrl });
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
finalize () {
|
||||
this.setUserPreference('analyticsConsent');
|
||||
localStorage.setItem('analyticsConsent', this.user.preferences.analyticsConsent);
|
||||
this.mixinData.inlineSettingMixin.sharedState.inlineSettingUnsavedValues = false;
|
||||
},
|
||||
prefToggled () {
|
||||
@@ -135,7 +192,10 @@ export default {
|
||||
this.mixinData.inlineSettingMixin.sharedState.inlineSettingUnsavedValues = newVal;
|
||||
},
|
||||
resetControls () {
|
||||
this.user.preferences.analyticsConsent = !this.user.preferences.analyticsConsent;
|
||||
if (this.mixinData.inlineSettingMixin.sharedState.inlineSettingUnsavedValues) {
|
||||
this.user.preferences.analyticsConsent = !this.user.preferences.analyticsConsent;
|
||||
this.mixinData.inlineSettingMixin.sharedState.inlineSettingUnsavedValues = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -263,11 +263,12 @@ export default {
|
||||
this.$store.dispatch('tasks:fetchUserTasks'),
|
||||
]).then(() => {
|
||||
this.$store.state.isUserLoaded = true;
|
||||
const analyticsConsent = localStorage.getItem('analyticsConsent');
|
||||
if (analyticsConsent !== null
|
||||
&& analyticsConsent !== this.user.preferences.analyticsConsent
|
||||
) {
|
||||
this.$store.dispatch('user:set', { 'preferences.analyticsConsent': analyticsConsent });
|
||||
let analyticsConsent = localStorage.getItem('analyticsConsent');
|
||||
if (analyticsConsent !== null) {
|
||||
analyticsConsent = analyticsConsent === 'true';
|
||||
if (analyticsConsent !== this.user.preferences.analyticsConsent) {
|
||||
this.$store.dispatch('user:set', { 'preferences.analyticsConsent': analyticsConsent });
|
||||
}
|
||||
}
|
||||
if (window && window['habitica-i18n']) {
|
||||
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
|
||||
|
||||
@@ -24,6 +24,8 @@ const AdminContainerPage = () => import(/* webpackChunkName: "admin-panel" */'@/
|
||||
const AdminPanelPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/admin-panel');
|
||||
const AdminPanelUserPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/admin-panel/user-support');
|
||||
const AdminPanelSearchPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/admin-panel/search');
|
||||
const GroupAdminPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/groups');
|
||||
const GroupAdminGroupPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/groups/group-support');
|
||||
const BlockerPage = () => import(/* webpackChunkName: "admin-panel" */'@/components/admin/blocker');
|
||||
|
||||
// Tasks
|
||||
@@ -88,6 +90,9 @@ const router = new VueRouter({
|
||||
path: '/profile/:userId',
|
||||
props: true,
|
||||
},
|
||||
{ name: 'profile', path: '/user/profile' },
|
||||
{ name: 'stats', path: '/user/stats' },
|
||||
{ name: 'achievements', path: '/user/achievements' },
|
||||
{
|
||||
path: '/inventory',
|
||||
component: InventoryContainer,
|
||||
@@ -216,6 +221,28 @@ const router = new VueRouter({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'groupAdmin',
|
||||
path: 'groups',
|
||||
component: GroupAdminPage,
|
||||
meta: {
|
||||
privilegeNeeded: [ // any one of these is enough to give access
|
||||
'groupSupport',
|
||||
],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'groupAdminGroup',
|
||||
path: ':groupId',
|
||||
component: GroupAdminGroupPage,
|
||||
meta: {
|
||||
privilegeNeeded: [
|
||||
'groupsSupport',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'blockers',
|
||||
path: 'blockers',
|
||||
@@ -345,6 +372,10 @@ router.beforeEach(async (to, from, next) => {
|
||||
if (to.params.startingPage !== undefined) {
|
||||
startingPage = to.params.startingPage;
|
||||
}
|
||||
// Check if there's a hash in the URL for stats or achievements
|
||||
if (to.hash === '#stats' || to.hash === '#achievements') {
|
||||
startingPage = to.hash.substring(1);
|
||||
}
|
||||
if (from.name === null) {
|
||||
store.state.postLoadModal = `profile/${to.params.userId}`;
|
||||
return next({ name: 'tasks' });
|
||||
@@ -365,10 +396,18 @@ router.beforeEach(async (to, from, next) => {
|
||||
}
|
||||
|
||||
if ((to.name === 'stats' || to.name === 'achievements' || to.name === 'profile') && from.name !== null) {
|
||||
const userId = store.state.user.data._id;
|
||||
let redirectPath = `/profile/${userId}`;
|
||||
if (to.name === 'stats') {
|
||||
redirectPath += '#stats';
|
||||
} else if (to.name === 'achievements') {
|
||||
redirectPath += '#achievements';
|
||||
}
|
||||
router.app.$emit('habitica:show-profile', {
|
||||
userId,
|
||||
startingPage: to.name,
|
||||
fromPath: from.path,
|
||||
toPath: to.path,
|
||||
toPath: redirectPath,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
31
website/client/src/store/actions/admin.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export async function searchUsers (store, payload) {
|
||||
const url = `/api/v4/admin/search/${payload.userIdentifier}`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function getUserHistory (store, payload) {
|
||||
const url = `/api/v4/admin/user/${payload.userIdentifier}/history`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function getSubscriptionPaymentDetails (store, payload) {
|
||||
const url = `/api/v4/admin/user/${payload.userIdentifier}/subscription-payment-details`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function getGroup (store, payload) {
|
||||
const url = `/api/v4/admin/groups/${payload.groupId}`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function updateGroup (store, payload) {
|
||||
const url = `/api/v4/admin/groups/${payload.groupId || payload.group._id}`;
|
||||
const response = await axios.put(url, payload.group);
|
||||
return response.data.data;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export async function searchUsers (store, payload) {
|
||||
const url = `/api/v4/admin/search/${payload.userIdentifier}`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function getUserHistory (store, payload) {
|
||||
const url = `/api/v4/admin/user/${payload.userIdentifier}/history`;
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import { authAsCredentialsState, LOCALSTORAGE_AUTH_KEY } from '@/libs/auth';
|
||||
|
||||
const GA_ID = import.meta.env.GA_ID;
|
||||
|
||||
function saveLocalDataAuth (store, apiId, apiToken) {
|
||||
const credentialsObj = {
|
||||
auth: {
|
||||
@@ -123,9 +121,6 @@ export async function appleAuth (store, params) {
|
||||
export function logout (store, options = {}) {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
if (window.gtag) {
|
||||
window.gtag('config', GA_ID, { user_id: null });
|
||||
}
|
||||
const query = options.redirectToLogin === true ? '?redirectToLogin=true' : '';
|
||||
window.location.href = `/logout-server${query}`;
|
||||
}
|
||||
|
||||
@@ -38,3 +38,9 @@ export async function getHeroGroupPlans (store, payload) {
|
||||
const response = await axios.get(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function deleteHero (store, payload) {
|
||||
const url = `/api/v4/members/${payload.uuid}?deleteAccount=${payload.deleteHabiticaAccount}&deleteAmplitude=${payload.deleteAmplitudeData}`;
|
||||
const response = await axios.delete(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { flattenAndNamespace } from '@/libs/store/helpers/internals';
|
||||
|
||||
import * as adminPanel from './adminPanel';
|
||||
import * as admin from './admin';
|
||||
import * as common from './common';
|
||||
import * as user from './user';
|
||||
import * as tasks from './tasks';
|
||||
@@ -26,7 +26,7 @@ import * as blockers from './blockers';
|
||||
// Example: fetch in user.js -> 'user:fetch'
|
||||
|
||||
const actions = flattenAndNamespace({
|
||||
adminPanel,
|
||||
admin,
|
||||
common,
|
||||
user,
|
||||
tasks,
|
||||
|
||||
@@ -12,12 +12,12 @@ describe('renderWithMentions', () => {
|
||||
expect(result).to.be.null;
|
||||
});
|
||||
|
||||
test('highlights displayname', () => {
|
||||
test('does not highlight displayname to prevent impersonation', () => {
|
||||
const text = 'hello @displayedUser with text after';
|
||||
|
||||
const result = renderMarkdown(text, user('user', 'displayedUser'));
|
||||
|
||||
expect(result).to.contain('<span class="at-text at-highlight">@displayedUser</span>');
|
||||
expect(result).to.contain('<span class="at-text">@displayedUser</span>');
|
||||
expect(result).to.not.contain('<span class="at-text at-highlight">@displayedUser</span>');
|
||||
});
|
||||
|
||||
test('highlights username', () => {
|
||||
@@ -56,7 +56,8 @@ describe('renderWithMentions', () => {
|
||||
|
||||
const result = renderMarkdown(plainText, user('use', 'mentions'));
|
||||
|
||||
expect(result).to.contain('<span class="at-text at-highlight">@mentions</span>');
|
||||
expect(result).to.contain('<span class="at-text">@mentions</span>');
|
||||
expect(result).to.not.contain('<span class="at-text at-highlight">@mentions</span>');
|
||||
expect(result).to.contain('<span class="at-text at-highlight">@use</span>');
|
||||
expect(result).to.contain('<span class="at-text">@mail</span>');
|
||||
expect(result).to.not.contain('<span class="at-text at-highlight">@mentions</span>.com');
|
||||
|
||||
@@ -26,7 +26,6 @@ const envVars = [
|
||||
'EMAILS_COMMUNITY_MANAGER_EMAIL',
|
||||
'EMAILS_TECH_ASSISTANCE_EMAIL',
|
||||
'EMAILS_PRESS_ENQUIRY_EMAIL',
|
||||
'GA_ID',
|
||||
'STRIPE_PUB_KEY',
|
||||
'GOOGLE_CLIENT_ID',
|
||||
'APPLE_AUTH_CLIENT_ID',
|
||||
@@ -36,7 +35,7 @@ const envVars = [
|
||||
'TIME_TRAVEL_ENABLED',
|
||||
'DEBUG_ENABLED',
|
||||
'CONTENT_SWITCHOVER_TIME_OFFSET',
|
||||
// TODO necessary? if yes how not to mess up with vue cli? 'NODE_ENV'
|
||||
'PLAY_CONSOLE_ORDERS_BASE_URL',
|
||||
];
|
||||
|
||||
const envObject = {};
|
||||
|
||||
@@ -108,5 +108,6 @@
|
||||
"resetFlagCount": "Markierungszähler zurücksetzen",
|
||||
"cannotClone": "Diese Herausforderung kann nicht dupliziert werden, weil einer oder mehrere Spieler sie als unangemessen gemeldet haben. Einer der Mitarbeiter wird dich in Kürze mit Anweisungen kontaktieren. Wenn mehr als 48 Stunden vergangen sind, und du nichts von ihnen gehört hast, schicke bitte eine Email an admin@habitica.com, um Unterstützung zu erhalten.",
|
||||
"resetFlags": "Markierungen zurücksetzen",
|
||||
"messageChallengeFlagOfficial": "Offizielle Herausforderungen können nicht gemeldet werden."
|
||||
"messageChallengeFlagOfficial": "Offizielle Herausforderungen können nicht gemeldet werden.",
|
||||
"deleteChallengeRefundDescription": "Wenn du diese Herausforderung löschst, bekommst du den Preis in Edelsteinen erstattet und die Aufgaben der Herausforderung verbleiben auf der Aufgabentafel der Teilnehmer."
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
"marketing1Lead1Title": "Mache dein Leben zum Spiel",
|
||||
"marketing1Lead1": "Habitica ist die perfekte App, für alle die Probleme mit ToDo-Listen haben. Wir verwenden bekannte Spiel-Mechaniken wie Belohnungen in Gold, XP und Gegenstände, die dir dabei helfen, dich produktiver zu fühlen und dein Erfolgserlebnis zu steigern, wenn du Aufgaben vollendest. Je besser Du Dich dabei anstellst, umso weiter kommst Du im Spiel.",
|
||||
"marketing1Lead2Title": "Rüsten dich mit Stil aus",
|
||||
"marketing1Lead2": "Sammele Schwerter, Rüstungen und vieles mehr mit Gold, welches du beim Vollenden von Aufgaben verdienst. Mit hunderten von Ausrüstungsstücken, die du sammeln und auswählen kannst, werden dir nie Kombinationen zum Ausprobieren ausgehen. Optimiere deine Statistik, deinen Style oder beides zusammen! ",
|
||||
"marketing1Lead2": "Sammele Schwerter, Rüstungen und vieles mehr mit dem Gold, das du beim Vollenden von Aufgaben verdienst. Mit hunderten von Stücken zum Sammeln, aus denen du auswählen kannst, werden dir die Kombinationen zum Ausprobieren nie ausgehen. Optimiere deine Werte, deinen Style oder beides! ",
|
||||
"marketing1Lead3Title": "Verdiene Belohnungen für deine Bemühungen",
|
||||
"marketing1Lead3": "Etwas zu haben, auf das man sich freuen kann, mag den Unterschied ausmachen, ob man eine Aufgabe erledigt oder ob sie einen wochenlang quält. Wenn das Leben keine Belohnung bietet ist Habitica für dich da! Du wirst für jede Aufgabe belohnt, aber Überraschungen gibt es an jeder Ecke - also mach weiter so! ",
|
||||
"marketing2Header": "Schließe dich mit Freunden zusammen",
|
||||
"marketing2Header": "Verbünde dich mit Freunden",
|
||||
"marketing2Lead1Title": "Soziale Produktivität",
|
||||
"marketing2Lead1": "Hole dir einen Motivationsschub, indem du mit anderen zusammenarbeitest, konkurrierst und interagierst! Habitica wurde entwickelt, um den effektivsten Teil eines jeden Selbstverbesserungsprogramms zu nutzen: soziale Verantwortung.",
|
||||
"marketing2Lead2Title": "Bekämpfe Monster in Quests",
|
||||
|
||||
@@ -2215,9 +2215,9 @@
|
||||
"armorSpecialWinter2021RogueText": "Efeu-Grünes Gewand",
|
||||
"weaponSpecialWinter2021HealerNotes": "Dirigiere deine Kämpfe mit unvorhersehbarem Schwung, wie ein Schneegestöber! Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021HealerText": "Flocken Flanken Rute",
|
||||
"weaponSpecialWinter2021MageNotes": "Diese mächtige Waffe ist nicht nur eine Phase! Konzentriere deine Kräfte, fokussiere den Verlauf eines Monates und studiere den Lauf von Zeit und Raum. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021MageNotes": "Diese mächtige Waffe ist definitiv mehr als nur eine Phase! Konzentriere deine Kräfte, fokussiere auf den Verlauf des Monates und studiere den Lauf von Zeit und Raum. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021MageText": "Magischer Mond-Phaser",
|
||||
"weaponSpecialWinter2021WarriorNotes": "Hiermit kannst Du die größten Frische an Land ziehen! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021WarriorNotes": "Hiermit kannst Du die größten Fische an Land ziehen! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021WarriorText": "Mächtige Angelrute",
|
||||
"weaponSpecialWinter2021RogueNotes": "Tarnung und Waffe in einem, die giftigen Früchte der Stechpalme helfen dir mit den schwierigsten Aufgaben umzugehen. Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020-2021 Winterausrüstung.",
|
||||
"weaponSpecialWinter2021RogueText": "Ilex-Beeren Morgenstern",
|
||||
@@ -3413,5 +3413,31 @@
|
||||
"headSpecialFall2025MageNotes": "Ätherisch und glühend - diese Maske bedeckt deinen Kopf, während du alle deine wichtigen Aufgaben abdeckst. Erhöht Wahrnehmung um <%= per %>. Limitierte Herbstausrüstung 2025.",
|
||||
"armorArmoireRedWaistcoatNotes": "Sieh elegant und umwerfend aus, während du deine Aufgaben bewältigst. In der Westentasche ist etwas geheimes versteckt — was denkst du, könnte es sein? Erhöht Ausdauer und Stärke um jeweils <%= attrs %>. Verzauberter Schrank: Rote Weste Set (Gegenstand 2 von 2)",
|
||||
"armorArmoireSoftOrangeSuitNotes": "Orange ist eine lebhafte Farbe. Zieh dies an, wenn du zu Bett gehst und in allen Abenteuern, denen du in deinen Träumen begegnest, wirst du sicher Erfolg haben. Erhöht Ausdauer und Stärke um jeweils <%= attrs %> . Verzauberter Schrank: Oranges Loungewear-Set (Gegenstand 2 von 3).",
|
||||
"headSpecialFall2025HealerNotes": "Markant und gehörnt - diese Maske bedeckt deinen Kopf, während du alle deine wichtigen Aufgaben abdeckst. Erhöht Intelligenz um <%= int %>. Limitierte Herbstausrüstung 2025."
|
||||
"headSpecialFall2025HealerNotes": "Markant und gehörnt - diese Maske bedeckt deinen Kopf, während du alle deine wichtigen Aufgaben abdeckst. Erhöht Intelligenz um <%= int %>. Limitierte Herbstausrüstung 2025.",
|
||||
"headArmoireRedNewsieHatText": "Rote Zeitungsjungenmütze",
|
||||
"headArmoireRedNewsieHatNotes": "Extra! Extra! Lesen Sie alles darüber: Diese Mütze ist bequem, modisch und praktisch. Erhöht die Wahrnehmung und Intelligenz um jeweils <%= attrs %>. Verzauberter Kleiderschrank: Rotes Weste-Set (Item 1 von 2)",
|
||||
"headArmoireFloppyOrangeHatText": "Orangener Schlapphut",
|
||||
"headArmoireFloppyOrangeHatNotes": "In diesen simplen Hut wurden zahlreiche Zauber eingearbeitet, die ihm eine auffällige orange Farbe verleihen. Erhöht alle Werte um jeweils <%= attrs %>. Verzauberter Kleiderschrank: Orangenes Loungewear-Set (Item 1 von 3).",
|
||||
"headArmoireBlackHairbowText": "Schwarze Haarschleife",
|
||||
"headArmoireBlackHairbowNotes": "Werde stark, klug und herzhaft, während du diese wunderschöne schwarze Haarschleife trägst! Erhöht Stärke, Intelligenz und Konstitution um jeweils <%= attrs %>. Verzauberter Kleiderschrank: Schwarzes Haarschleifen-Set (Item 1 von 2).",
|
||||
"headArmoireBlacksmithsGogglesText": "Schmiedebrille",
|
||||
"shieldSpecialFall2025RogueNotes": "Eine mächtige Waffe, mit der Sie Ihre To-Do's um die Hälfte reduzieren können. Erhöht Stärke um <%= str %>. Limitierte Ausgabe Herbst 2025 Ausrüstung.",
|
||||
"shieldSpecialFall2025HealerText": "Koboldschild",
|
||||
"shieldMystery202508Text": "Brillante Cyan-Klinge",
|
||||
"shieldMystery202508Notes": "Wenn Sie schon eine rotierende Klinge cool fanden, probieren Sie doch mal zwei! Bietet keinen Vorteil. August 2025 Abonnentengegenstand.",
|
||||
"shieldMystery202511Text": "Frostschild",
|
||||
"shieldMystery202511Notes": "Dieser robuste Schild aus eisigem Gestein schützt dich vor schlechten Gewohnheiten, ohne deine Hände zu vereisen. Verleiht keinen Vorteil. November 2025 Abonnentengegenstand.",
|
||||
"shieldArmoireSoftOrangePillowText": "Weiches orangenes Kissen",
|
||||
"backMystery202510Text": "Gleitende Ghulflügel",
|
||||
"backMystery202510Notes": "Fliege mit diesen riesigen Flügeln lautlos durch den heimgesuchten Himmel. Verleiht keinen Vorteil. Oktober 2025 Abonnentengegenstand.",
|
||||
"bodyMystery202509Notes": "Dieser Schal schützt dein Gesicht vor Wind und sieht auch noch verdammt cool aus. Bietet keinen Vorteil. September 2025 Abonnentengegenstand.",
|
||||
"eyewearMystery202510Text": "Gleitende Ghul-Augen",
|
||||
"eyewearMystery202510Notes": "Diese gruseligen Augen leuchten wie der Erntemond. Verleiht keinen Vorteil. Oktober 2025 Abonnentengegenstand.",
|
||||
"headArmoireBlacksmithsGogglesNotes": "Bei der Arbeit in einer Schmiede benötigen Sie einen bruchsicheren und hitzebeständigen Augenschutz. Erhöht die Wahrnehmung um <%= per %>. Verzauberter Schrank: Schmiedeset (Item 1 von 3).",
|
||||
"shieldSpecialFall2025WarriorText": "Sasquatch Schild",
|
||||
"shieldSpecialFall2025WarriorNotes": "Verschaffe dir etwas mehr Zeit zum Nachdenken und Planen, indem du dich vor deinen nächsten Tagesaufgaben abschirmst. Erhöht die Konstitution um <%= con %>. Limitierte Auflage Herbst 2025 Ausrüstung.",
|
||||
"shieldSpecialFall2025HealerNotes": "Verschaffe dir etwas mehr Zeit, um Vorräte zu sammeln, indem du dich vor deinen Aufgaben abschirmst. Erhöht die Konstitution um <%= con %>. Limitierte Ausgabe Herbst 2025 Ausrüstung.",
|
||||
"shieldArmoireSoftOrangePillowNotes": "Der vorbereitete Krieger packt für jede Expedition ein Kissen ein. Mach dich bereit, neue Verpflichtungen zu übernehmen ... sogar während du ein Nickerchen machst. Erhöht Intelligenz und Wahrnehmung um jeweils <%= attrs %>. Verzauberter Kleiderschrank: Orangenes Loungewear-Set (Gegenstand 3 von 3).",
|
||||
"bodyMystery202509Text": "Schal des windgepeitschten Wanderers",
|
||||
"armorSpecialFall2025RogueNotes": "Ein hartes und schmales Ziel in dieser saisonalen Rüstung ist am schwersten zu treffen. Erhöht die Wahrnehmung um <%= per %>. Limitierte Ausgabe Herbst 2025 Ausrüstung."
|
||||
}
|
||||
|
||||
@@ -241,5 +241,6 @@
|
||||
"titleCustomizations": "Individualisierungen",
|
||||
"targetUserNotExist": "Zielbenutzer: '<%= userName %>' existiert nicht.",
|
||||
"newMessage": "Neue Nachricht",
|
||||
"rememberToBeKind": "Bitte sei freundlich, respektvoll, und folge den <a href='/static/community-guidelines' target='_blank'>Community-Richtlinien</a>."
|
||||
"rememberToBeKind": "Bitte sei freundlich, respektvoll, und folge den <a href='/static/community-guidelines' target='_blank'>Community-Richtlinien</a>.",
|
||||
"gem": "Edelstein"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"stable": "Haus- und Reittiere",
|
||||
"stable": "Haustiere und Reittiere",
|
||||
"pets": "Haustiere",
|
||||
"activePet": "Aktives Haustier",
|
||||
"noActivePet": "Kein aktives Haustier",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"settings": "Einstellungen",
|
||||
"language": "Sprache",
|
||||
"americanEnglishGovern": "Im Fall von Bedeutungsunterschieden gilt die englische Version.",
|
||||
"helpWithTranslation": "Hast du Interesse, bei der Übersetzung von Habitica helfen? Toll! Dann besuche doch die <a href=\"/groups/guild/7732f64c-33ee-4cce-873c-fc28f147a6f7\">Aspiring Linguists Guild</a>!",
|
||||
"helpWithTranslation": "Hast du Interesse, bei der Übersetzung von Habitica helfen? Toll! Dann besuche doch die <a href=\"https://translate.habitica.com\"> Habitica's Weblate Seite</a>!",
|
||||
"stickyHeader": "Kopfzeile anheften",
|
||||
"newTaskEdit": "Neue Aufgaben im Bearbeiten-Modus öffnen",
|
||||
"reverseChatOrder": "Zeige die Chat-Nachrichten in umgekehrter Reihenfolge",
|
||||
|
||||
@@ -3,5 +3,9 @@
|
||||
"siteBlockers": "Site Blockers",
|
||||
"newsroom": "Newsroom",
|
||||
"adminBlockerTypeDescription": "<b>IP-Address</b> - Block access for a specific IP-Address\n\nClient - Block access for a client based on the \"x-client\" header.\n\nE-Mail - Blocks e-mails from being used for signup.",
|
||||
"adminBlockerAreaDescription": "A blocker can either apply to the full site, completely blocking any access. Or it can apply to purchases, which still allows the site to be accessed."
|
||||
"adminBlockerAreaDescription": "A blocker can either apply to the full site, completely blocking any access. Or it can apply to purchases, which still allows the site to be accessed.",
|
||||
"groupAdmin": "Group Admin",
|
||||
"groupSupportDescription": "Manage groups and their members. You can search for groups by ID, or load your own group by leaving the field blank.",
|
||||
"groupData": "Group Data",
|
||||
"groupPlanSubscription": "Group Plan Subscription"
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"awardWinners": "Award Winner",
|
||||
"doYouWantedToDeleteChallenge": "Do you want to delete this Challenge?",
|
||||
"deleteChallenge": "Delete Challenge",
|
||||
"deleteChallengeRefundDescription": "If you delete this Challenge, you will be refunded the Gem prize and the Challenge tasks will remain on the participants' task boards.",
|
||||
"challengeNamePlaceholder": "What is your Challenge name?",
|
||||
"challengeSummary": "Summary",
|
||||
"challengeSummaryPlaceholder": "Write a short description advertising your Challenge to other Habiticans. What is the main purpose of your Challenge and why should people join it? Try to include useful keywords in the description so that Habiticans can easily find it when they search!",
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
"passwordReset": "If we have your email or username on file, instructions for setting a new password have been sent to your email.",
|
||||
"invalidLoginCredentialsLong": "Your email, username, or password are incorrect. Please try again or use \"Forgot Password.\"",
|
||||
"invalidCredentials": "There is no account that uses those credentials.",
|
||||
"accountSuspended": "This account, User ID \"<%= userId %>\", has been blocked for breaking the Community Guidelines (https://habitica.com/static/community-guidelines) or Terms of Service (https://habitica.com/static/terms). For details or to ask to be unblocked, please email our Community Manager at <%= communityManagerEmail %> or ask your parent or guardian to email them. Please include your @Username in the email.",
|
||||
"accountSuspended": "Your account @<%= username %> has been blocked. For additional information, or to request an appeal, email admin@habitica.com with your Habitica username or User ID.",
|
||||
"accountSuspendedTitle": "Account has been suspended",
|
||||
"unsupportedNetwork": "This network is not currently supported.",
|
||||
"cantDetachSocial": "Account lacks another authentication method; can't detach this authentication method.",
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"notEnoughGems": "Not enough Gems",
|
||||
"alreadyHave": "Whoops! You already have this item. No need to buy it again!",
|
||||
"delete": "Delete",
|
||||
"gem": "Gem",
|
||||
"gems": "Gems",
|
||||
"needMoreGems": "Need More Gems?",
|
||||
"needMoreGemsInfo": "Purchase Gems now, or become a subscriber to buy Gems with Gold, get monthly mystery items, enjoy increased drop caps and more!",
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"needsTextPlaceholder": "Type your message here.",
|
||||
"messageCopiedToClipboard": "Message copied to clipboard.",
|
||||
"leaderOnlyChallenges": "Only group leader can create challenges",
|
||||
"sendGift": "Send a Gift",
|
||||
"sendGift": "Send Gift",
|
||||
"selectGift": "Select Gift",
|
||||
"selectSubscription": "Select Subscription",
|
||||
"sendGiftToWhom": "Who would you like to send a gift to?",
|
||||
|
||||
@@ -271,5 +271,7 @@
|
||||
"performanceAnalytics": "Performance and Analytics",
|
||||
"usedForSupport": "These are used to improve the user experience, performance, and services of our website and apps. This data is used by our support team when handling requests and bug reports.",
|
||||
"savePreferences": "Save Preferences",
|
||||
"habiticaPrivacyPolicy": "Habitica's Privacy Policy"
|
||||
"habiticaPrivacyPolicy": "Habitica's Privacy Policy",
|
||||
"gpcWarning": "<a href='<%= url %>' target='_blank'>GPC</a> is on. Turning on tracking below will override this and send data to our analytics partners.",
|
||||
"gpcPlusAnalytics": "<a href='<%= url %>' target='_blank'>GPC</a> is on. You have opted in to tracking and sending data to our analytics partners."
|
||||
}
|
||||
|
||||
@@ -901,13 +901,25 @@
|
||||
"backgrounds0420205": "SET 131: Released April 2025",
|
||||
"backgroundGardenWithFlowerBedsText": "Garden with Flower Beds",
|
||||
"backgroundGardenWithFlowerBedsNotes": "Enjoy the blooms of spring in a Garden with Flower Beds.",
|
||||
"backgrounds062025": "第 133 组:由2025 年 6 月发布",
|
||||
"backgroundSummerSeashoreText": "夏日海滨",
|
||||
"backgroundSummerSeashoreNotes": "在夏日海滨乘风破浪.",
|
||||
"backgrounds052025": "第 132 组:于2025 年 5 月发布",
|
||||
"backgroundTrailThroughAForestText": "穿越森林的小径",
|
||||
"backgroundTrailThroughAForestNotes": "沿着穿过森林的小径漫步。",
|
||||
"backgrounds062025": "SET 133: Released June 2025",
|
||||
"backgroundSummerSeashoreText": "Summer Seashore",
|
||||
"backgroundSummerSeashoreNotes": "Catch a wave at a Summer Seashore.",
|
||||
"backgrounds052025": "SET 132: Released May 2025",
|
||||
"backgroundTrailThroughAForestText": "Trail Through a Forest",
|
||||
"backgroundTrailThroughAForestNotes": "Wander down a Trail Through a Forest.",
|
||||
"backgrounds072025": "SET 134: Released July 2025",
|
||||
"backgroundSirensLairText": "Siren's Lair",
|
||||
"backgroundSirensLairNotes": "Dare to dive into a Siren’s Lair."
|
||||
"backgroundSirensLairNotes": "Dare to dive into a Siren’s Lair.",
|
||||
"backgrounds082025": "SET 135: Released August 2025",
|
||||
"backgroundSunnyStreetWithShopsText": "Sunny Street with Shops",
|
||||
"backgroundSunnyStreetWithShopsNotes": "Enjoy the sights and sounds of a Sunny Street with Shops.",
|
||||
"backgrounds092025": "SET 136: Released September 2025",
|
||||
"backgroundAutumnSwampText": "Autumn Swamp",
|
||||
"backgroundAutumnSwampNotes": "Take in the haunting vibes of an Autumn Swamp.",
|
||||
"backgrounds102025": "SET 137: Released October 2025",
|
||||
"backgroundInsideForestWitchsCottageText": "Forest Witch's Cottage",
|
||||
"backgroundInsideForestWitchsCottageNotes": "Weave spells inside a Forest Witch's Cottage.",
|
||||
"backgrounds112025": "SET 138: Released November 2025",
|
||||
"backgroundCastleKeepWithBannersText": "Castle Hall with Banners",
|
||||
"backgroundCastleKeepWithBannersNotes": "Sing tales of heroic deeds in a Castle Hall with Banners."
|
||||
}
|
||||
|
||||
@@ -108,5 +108,6 @@
|
||||
"resetFlags": "Reiniciar marcas",
|
||||
"cannotClose": "Este Desafío no puede cerrarse porque uno o más jugadores lo han marcado como inapropiado. Un miembro del Personal te contactará pronto con instrucciones. Si han pasado más de 48 horas y no has recibido noticias de ellos, envía un correo a admin@habitica.com para solicitar ayuda.",
|
||||
"cannotMakeChallenge": "No puedes crear un Desafío público porque tu cuenta no tiene privilegios de chat en este momento. Envía un mensaje a admin@habitica.com para obtener más información.",
|
||||
"messageChallengeFlagOfficial": "Los Desafíos Oficiales no se pueden notificar."
|
||||
"messageChallengeFlagOfficial": "Los Desafíos Oficiales no se pueden notificar.",
|
||||
"deleteChallengeRefundDescription": "Si cancelas este Desafío, recuperarás las Gemas de la recompensa y las tareas del Desafío permanecerán en los listados de tareas de los participantes."
|
||||
}
|
||||
|
||||
@@ -3389,7 +3389,7 @@
|
||||
"weaponSpecialFall2025MageNotes": "Una poderosa arma capaz de trazar una senda segura a través de los terrores del Bosque Negro. Aumenta la Inteligencia en <%= int %> y la Percepción en <%= per %>. Equipamiento de Edición Limitada Otoño 2025.",
|
||||
"weaponSpecialFall2025WarriorText": "Hacha de Bigfoot",
|
||||
"weaponSpecialFall2025HealerText": "Hacha Kobold",
|
||||
"weaponSpecialFall2025HealerNotes": "Una poderosa arma capaz de trazar una senda segura a través de los obstáculos del Bosque Negro. Aumenta la Fuerza en <%= str %>. Equipamiento de Edición Limitada Otoño 2025.",
|
||||
"weaponSpecialFall2025HealerNotes": "Una poderosa arma capaz de trazar una senda segura a través de los obstáculos del Bosque Negro. Aumenta la Inteligencia en <%= int %>. Equipamiento de Edición Limitada Otoño 2025.",
|
||||
"weaponSpecialFall2025MageText": "Hacha de Fantasma Enmascarado",
|
||||
"weaponMystery202511Text": "Espada Escarcha",
|
||||
"weaponMystery202511Notes": "El halo helado de esta espada te permitirá realizar con rapidez incluso las tareas rojas más oscuras. No otorga ningún beneficio. Artículo de Suscriptor Noviembre 2025.",
|
||||
|
||||
@@ -241,5 +241,6 @@
|
||||
"playerReportModalBody": "Solo deberías informar de un jugador que de alguna forma quebrantara las <%= firstLinkStart %>Normas de la Comunidad<%= linkEnd %> y/o <%= secondLinkStart %>los Terminos de Servicio<%= linkEnd %>. Enviar un informe falso es una clara violación de la Normas de la Comunidad de Habitica.",
|
||||
"newMessage": "Nuevo Mensaje",
|
||||
"targetUserNotExist": "Usuario objetivo: '<%= userName %>' no existe.",
|
||||
"rememberToBeKind": "Por favor recuerda ser bondadoso, respetuoso y seguir las <a href='/static/community-guidelines' target='_blank'>Normas de la Comunidad</a>."
|
||||
"rememberToBeKind": "Por favor recuerda ser bondadoso, respetuoso y seguir las <a href='/static/community-guidelines' target='_blank'>Normas de la Comunidad</a>.",
|
||||
"gem": "Gema"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
"optional": "Opcional",
|
||||
"needsTextPlaceholder": "Escribe tu mensaje aquí.",
|
||||
"leaderOnlyChallenges": "Sólo el Líder del Grupo puede crear desafíos",
|
||||
"sendGift": "Enviar un regalo",
|
||||
"sendGift": "Enviar regalo",
|
||||
"inviteFriends": "Invitar Amigos",
|
||||
"inviteByEmail": "Invita por correo electrónico",
|
||||
"inviteMembersHowTo": "Invita gente a través de un correo electrónico válido o el ID de usuario de 36 dígitos. Si el correo electrónico no ha sido registrado aún, le invitaremos a unirse a Habitica.",
|
||||
|
||||
@@ -271,5 +271,7 @@
|
||||
"privacySettingsOverview": "Habitica usa las cookies para analizar el rendimiento, gestionar solicitudes de soporte y brindarle la mejor experiencia de juego posible. Para eso, necesitamos pedirte los siguientes permisos. Puedes cambiar tus preferencias en cualquier momento desde los ajustes de tu cuenta.",
|
||||
"usedForSupport": "Estás se usan para mejorar la experiencia del usuario, el rendimiento, y los servicios de nuestra página web y nuestras aplicaciones. Estos datos se usan para ayudar a nuestro equipo de soporte cuando tienen que gestionar tanto solicitudes como informes de error.",
|
||||
"privacyOverview": "En el mundo en el que vivimos, parece que todas las compañías buscan obtener beneficios de los datos que recopilan acerca de nosotros. Esto nos dificulta la búsqueda de una aplicación que nos ayude a mejorar nuestros hábitos y estilo de vida. Habitica usa cookies que almacenan nuestros datos solo para analizar el rendimiento, gestionar solicitudes de soporte y brindarnos la mejor experiencia de juego posible. Aún así puedes cambiar tus preferencias en cualquier momento desde los ajustes de tu cuenta.",
|
||||
"acceptAllCookies": "Aceptar Todas las Cookies"
|
||||
"acceptAllCookies": "Aceptar Todas las Cookies",
|
||||
"gpcWarning": "<a href='<%= url %>' target='_blank'>GPC</a>está activado. Al activar el seguimiento de abajo, se anulará esto y se enviarán datos a nuestros socios analíticos.",
|
||||
"gpcPlusAnalytics": "<a href='<%= url %>' target='_blank'>GPC</a>está activado. Ha aceptado el seguimiento y envío de datos a nuestros socios analíticos."
|
||||
}
|
||||
|
||||
@@ -108,5 +108,6 @@
|
||||
"cannotClone": "Ce Défi ne peut être dupliqué car un·e ou plusieurs joueu·r·se·s l'ont signalé comme inapproprié. Un·e membre de l'équipe va vous contacter sous peu avec des instructions. Si vous n'avez pas de nouvelles après 48 heures, merci d'envoyer un courriel à admin@habitica.com.",
|
||||
"resetFlags": "Réinitialiser les Signalements",
|
||||
"cannotMakeChallenge": "Vous ne pouvez pas créer de Défis publics car votre compte n'a pour le moment pas les accès aux discussions. Merci de contacter admin@habitica.com pour plus d'informations.",
|
||||
"messageChallengeFlagOfficial": "Les Défis Officiels ne peuvent pas être signalés."
|
||||
"messageChallengeFlagOfficial": "Les Défis Officiels ne peuvent pas être signalés.",
|
||||
"deleteChallengeRefundDescription": "Si vous supprimez ce Défi, les Gemmes investies vous seront restituées et les Tâches du Défis ne disparaîtront pas des Tâches des participant·e·s."
|
||||
}
|
||||
|
||||
@@ -241,5 +241,6 @@
|
||||
"titleCustomizations": "Personnalisations",
|
||||
"rememberToBeKind": "N'oubliez pas d'être bienveillant·e, respectueu·x·se, et de suivre le <a href='/static/community-guidelines' target='_blank'>Guide de la Communauté</a>.",
|
||||
"newMessage": "Nouveau Message",
|
||||
"targetUserNotExist": "L'Utilisat·eur·rice '<%= userName %>' n'existe pas."
|
||||
"targetUserNotExist": "L'Utilisat·eur·rice '<%= userName %>' n'existe pas.",
|
||||
"gem": "Gemme"
|
||||
}
|
||||
|
||||
@@ -271,5 +271,7 @@
|
||||
"habiticaPrivacyPolicy": "Politique de Confidentialité d'Habitica",
|
||||
"privacyOverview": "Dans le monde actuel, on peut avoir l'impression que toutes les entreprises veulent exploiter nos données, ce qui peut rendre la recherche d'application pour améliorer ses habitudes compliquée. Habitica n'utilise les cookies que pour enregistrer des données permettant l'analyse de performance, répondre aux requêtes du support, et vous faire profiter de la meilleure expérience ludique possible. Vous pouvez changer vos préférences à tout moment dans les paramètres de votre compte.",
|
||||
"usedForSupport": "Sont utilisés pour améliorer l'expérience utilisat·eur·rice, les performances et les services pour notre site et nos applications. Ces données sont utilisées par l'équipe du support pour la résolution de requêtes et rapports de bug.",
|
||||
"privacySettingsOverview": "Habitica utilise les cookies pour enregistrer des données permettant l'analyse de performance, répondre aux requêtes du support, et vous faire profiter de la meilleure expérience ludique possible. Pour cela, nous devons vous demander quelques autorisations. Vous pouvez changer vos préférences à tout moment dans les paramètres de votre compte."
|
||||
"privacySettingsOverview": "Habitica utilise les cookies pour enregistrer des données permettant l'analyse de performance, répondre aux requêtes du support, et vous faire profiter de la meilleure expérience ludique possible. Pour cela, nous devons vous demander quelques autorisations. Vous pouvez changer vos préférences à tout moment dans les paramètres de votre compte.",
|
||||
"gpcWarning": "<a href='<%= url %>' target='_blank'>La GPC (Prise en charge du contrôle Global de la vie Privée)</a> est activée. Activer la traçabilité ci-dessous annulera la GPC et enverra des données à nos partenaires analytiques.",
|
||||
"gpcPlusAnalytics": "<a href='<%= url %>' target='_blank'>La GPC (Prise en charge du contrôle Global de la vie Privée)</a> est activée. Vous avez activé la traçabilité pour que vous données soient transférées à nos partenaires analytiques."
|
||||
}
|
||||
|
||||
@@ -14,18 +14,18 @@
|
||||
"yourProgress": "Tvoj napredak",
|
||||
"yourRewards": "Tvoje nagrade",
|
||||
"onboardingCompleteDescSmall": "Ako želiš još više, pogledaj Postignuća i počni skupljati!",
|
||||
"achievementAridAuthorityText": "Ukrotio/la je sve pustinjske životinje za jahanje.",
|
||||
"achievementAridAuthorityText": "Pripitomio/la je sve pustinjske jahače životinje.",
|
||||
"onboardingProgress": "<%= percentage %>% napredak",
|
||||
"achievementAridAuthorityModalText": "Ukrotio/la si sve pustinjske životinje za jahanje!",
|
||||
"achievementAridAuthorityModalText": "Ukrotila/ukrotio si sve pustinjske životinje za jahanje!",
|
||||
"earnedAchievement": "Zaslužio/la si postignuće!",
|
||||
"gettingStartedDesc": "Dovršite ove početne zadatke i osvojit ćete <strong>5 postignuća</strong> i <strong class=\"gold-amount\">100 zlata</strong> kada završite!",
|
||||
"achievementLostMasterclasserModalText": "Završio/la si svih šesnaest pustolovina iz serije Masterclasser Quest i riješio/la misterij Nestalog majistora!",
|
||||
"achievementAllYourBaseModalText": "Ukrotio/la si sve bazne životinje za jahanje!",
|
||||
"achievementLostMasterclasserModalText": "Završio/la si svih šesnaest pustolovina iz serije Masterclasser Quest i riješio/la misterij nestalog majistora!",
|
||||
"achievementAllYourBaseModalText": "Ukrotila/ukrotio si sve temeljne životinje za jahanje!",
|
||||
"achievementBackToBasicsModalText": "Skupio/la si sve osnovne ljubimce!",
|
||||
"achievementDustDevilText": "Sakupio/la je sve pustinjske ljubimce.",
|
||||
"achievementBackToBasicsText": "Prikupio/la je sve osnovne ljubimce.",
|
||||
"achievementBackToBasicsText": "Sakupio/la je sve osnovni ljubimci.",
|
||||
"achievementMindOverMatter": "Um Nad Materijom",
|
||||
"achievementAllYourBaseText": "Ukrotio/la je sve bazne životinje za jahanje.",
|
||||
"achievementAllYourBaseText": "Ukrotila/ukrotio je sve temeljne životinje za jahanje.",
|
||||
"achievementDustDevilModalText": "Skupio/la si sve pustinjske ljubimce!",
|
||||
"achievementJustAddWater": "Samo Dodaj Vode",
|
||||
"onboardingComplete": "Dovršili ste svoje zadatke za početnike!",
|
||||
@@ -36,119 +36,134 @@
|
||||
"achievementGroupsBeta2022": "Interaktivni Beta Ispitivač",
|
||||
"achievementGroupsBeta2022Text": "Vi i vaša grupa pružili ste neprocjenjive povratne informacije kako biste pomogli testiranju Habitice.",
|
||||
"achievementGroupsBeta2022ModalText": "Vi i vaše grupe pomogli ste Habitici testiranjem i pružanjem povratnih informacija!",
|
||||
"foundNewItemsCTA": "Krenite u svoj inventar i pokušajte kombinirati svoj novi napitak za izlijganje i jaje!",
|
||||
"achievementMindOverMatterText": "Završio/la je zadatke za kućne ljubimce u Kamenu, Sluzi i Pređi.",
|
||||
"achievementJustAddWaterModalText": "Završili ste zadatke kućnih ljubimaca hobotnice, morskog konjica, sipe, kita, kornjače, golobradne grane, morske zmije i dupina!",
|
||||
"achievementAllYourBase": "Sve Vaše Bazično",
|
||||
"achievementKickstarter2019Text": "Podržao projekt Pin Kickstarter 2019",
|
||||
"achievementPartyUp": "Udružio si se s članom družbe!",
|
||||
"achievementPartyOn": "Vaša družba je narasla na 4 člana!",
|
||||
"achievementMonsterMagus": "Čudovišni čarobnjak",
|
||||
"achievementUndeadUndertakerModalText": "Ukrotio/la sisve Zombie životinje za jahanje!",
|
||||
"achievementUndeadUndertaker": "Neumorni Pogrebnik",
|
||||
"achievementCreatedTaskText": "Izradili su svoj prvi zadatak.",
|
||||
"achievementCreatedTaskModalText": "Dodajte zadatak za nešto što biste željeli postići ovaj tjedan",
|
||||
"achievementCompletedTaskText": "Izvršili su svoj prvi zadatak.",
|
||||
"achievementCompletedTaskModalText": "Označite bilo koji od svojih zadataka kako biste zaradili nagrade",
|
||||
"achievementHatchedPetText": "Izlegli su svog prvog ljubimca.",
|
||||
"achievementHatchedPetModalText": "Prijeđite na svoj inventar i pokušajte kombinirati napitak za izleganje i jaje",
|
||||
"achievementFedPetText": "Nahranili svog prvog ljubimca.",
|
||||
"achievementFedPetModalText": "Postoji mnogo različitih vrsta hrane, ali kućni ljubimci mogu biti izbirljivi",
|
||||
"achievementPurchasedEquipmentModalText": "Oprema je način da prilagodite svog avatara i poboljšate svoju statistiku",
|
||||
"achievementPrimedForPaintingModalText": "Prikupio/la si sve Bijele ljubimce!",
|
||||
"achievementPearlyProModalText": "Ukrotio/la si sve bijele životinje za jahanje!",
|
||||
"achievementTickledPinkText": "Sakupio/la je sve Cotton Candy Roze Ljubimce.",
|
||||
"achievementTickledPinkModalText": "Sakupio/la si sve Cotton Candy Roze Ljubimce!",
|
||||
"achievementRosyOutlookText": "Ukrotio/la je sve Cotton Candy Roze životinje za jahanje.",
|
||||
"achievementBugBonanzaModalText": "Dovršio/la simisije za kućne ljubimce Bube, Leptira, Puža i Pauka!",
|
||||
"achievementBareNecessities": "Najpotrebnije",
|
||||
"foundNewItemsCTA": "Krenite u svoj inventar i pokušajte kombinirati svoj novi napitak za izlijeganje i jaje!",
|
||||
"achievementMindOverMatterText": "Završio/la je zadatke za kućne ljubimce 'Rock', 'Slime' i 'Yarn'.",
|
||||
"achievementJustAddWaterModalText": "Završio/la si zadatke ljubimaca hobotnice, morskog konjica, sipe, kita, kornjače, golobrade, morske zmije i dupina.",
|
||||
"achievementAllYourBase": "Sve vaše baze",
|
||||
"achievementKickstarter2019Text": "Podržao/la je Pin Kickstarter projekt iz 2019. godine.",
|
||||
"achievementPartyUp": "Udružio/la si se s članom družbine!",
|
||||
"achievementPartyOn": "Vaša grupa se proširila na 4 člana!",
|
||||
"achievementMonsterMagus": "Čarobnjak čudovišta",
|
||||
"achievementUndeadUndertakerModalText": "Ukrotila/ukrotio si sve zombi životinje za jahanje!",
|
||||
"achievementUndeadUndertaker": "Nedoumorni pogrebnik",
|
||||
"achievementCreatedTaskText": "Kreirao/Kreirala je svoj prvi zadatak.",
|
||||
"achievementCreatedTaskModalText": "Dodaj zadatak za nešto što želiš postići ove sedmice.",
|
||||
"achievementCompletedTaskText": "Završio/la je svoj prvi zadatak.",
|
||||
"achievementCompletedTaskModalText": "Označite svoje zadatke kako biste dobili nagrade.",
|
||||
"achievementHatchedPetText": "Izlegao/la je svog prvog ljubimca.",
|
||||
"achievementHatchedPetModalText": "Otiđite u svoj inventar i pokušajte kombinirati napitak za izleganje i jaje.",
|
||||
"achievementFedPetText": "Nahranio/la je svog prvog ljubimca.",
|
||||
"achievementFedPetModalText": "Postoji mnogo različitih vrsta hrane, ali ljubimci mogu biti izbirljivi.",
|
||||
"achievementPurchasedEquipmentModalText": "Oprema je način za prilagođavanje svog avatara i poboljšanje svojih statistika.",
|
||||
"achievementPrimedForPaintingModalText": "Sakupio/la si sve bijele ljubimce!",
|
||||
"achievementPearlyProModalText": "Pripitomio/la si sve Bijele životinje za jahanje!",
|
||||
"achievementTickledPinkText": "Prikupio/la je sve kućne ljubimce boje roza vate!",
|
||||
"achievementTickledPinkModalText": "Prikupio/la si sve kućne ljubimce boje roza vate!",
|
||||
"achievementRosyOutlookText": "Ukrotio/la je sve bijele i životinje boje roze vate.",
|
||||
"achievementBugBonanzaModalText": "Završio/la si zadatke za kućne ljubimce: kukci - buba, leptir, puž i pauk!",
|
||||
"achievementBareNecessities": "Najosnovnije Stvari",
|
||||
"achievementAllThatGlittersText": "Ukrotio/la je sve zlatne životinje za jahanje.",
|
||||
"achievementAllThatGlittersModalText": "Ukrotio/la si sve zlatne životinje za jahanje!",
|
||||
"achievementBoneCollectorModalText": "Sakupio/la sisve Kosturske Ljubimce!",
|
||||
"achievementRedLetterDay": "Dan crvenih slova",
|
||||
"achievementLegendaryBestiaryText": "Izlegao je sve standardne boje mitskih ljubimaca: zmaj, leteća svinja, grifon, morska zmija i jednorog!",
|
||||
"achievementAllThatGlittersModalText": "Ukrotio/la si sve zlatne životinje za jahanjhe!",
|
||||
"achievementBoneCollectorModalText": "Sakupio/la si sve Kosturske ljubimce!",
|
||||
"achievementRedLetterDay": "Dan Crvenih Slova",
|
||||
"achievementLegendaryBestiaryText": "Izlegao/la je sve standardne boje mitskih kućnih ljubimaca: zmaj, leteća svinja, grifon, morsku zmiju i jednoroga!",
|
||||
"achievementSeasonalSpecialistText": "Završio/la je sve proljetne i zimske sezonske zadatke: Lov na jaja, Trapper Djed Božićnjak i Pronađi mladunče!",
|
||||
"achievementVioletsAreBlue": "Ljubičice su Plave",
|
||||
"achievementVioletsAreBlueText": "Sakupio/la je sve Cotton Candy Plave ljubimce.",
|
||||
"achievementVioletsAreBlueModalText": "Sakupio/la si sve Cotton Candy Plave ljubimce!",
|
||||
"achievementWildBlueYonderText": "Ukrotio/la je sve Cotton Candy Plave životinje za jahanje.",
|
||||
"achievementWildBlueYonderModalText": "Ukrotio/la si sve Cotton Candy Plave životinje za jahanje!",
|
||||
"achievementVioletsAreBlueText": "Sakupio/la je sve ljubimve plave boje vune!",
|
||||
"achievementVioletsAreBlueModalText": "Sakupio/la si sve ljubimve plave boje vune!",
|
||||
"achievementWildBlueYonderText": "Ukrotio/la je sve životinje za jahanje plave boje vune!",
|
||||
"achievementWildBlueYonderModalText": "Ukrotio/la si sve životinje za jahanje plave boje vune!",
|
||||
"achievementShadeOfItAllText": "Ukrotio/la je sve životinje za jahanje boje sjene.",
|
||||
"achievementZodiacZookeeperText": "Izlegao/la je sve standardne boje kućnih ljubimaca zodijaka: štakor, krava, zeko, zmija, konj, ovca, majmun, pijetao, vuk, tigar, leteće prase i zmaj!",
|
||||
"achievementPrimedForPainting": "Spremno za bojanje",
|
||||
"achievementRosyOutlookModalText": "Ukrotio/la si sve Cotton Candy Roze životinje za jahanje!",
|
||||
"achievementPrimedForPainting": "Temelj za bojanje",
|
||||
"achievementRosyOutlookModalText": "Ukrotio/la si sve životinje za jahanje boje roze vate!",
|
||||
"achievementPolarPro": "Polarni Profesionalac",
|
||||
"achievementPolarProText": "Izlegao je sve standardne boje polarnih ljubimaca: medvjeda, lisicu, pingvina, kita i vuka!",
|
||||
"achievementPolarProModalText": "Skupili ste sve Polarne Ljubimce!",
|
||||
"achievementPolarProText": "Izlegao/la je sve standardne boje polarnih ljubimaca: medvjeda, lisicu, pingvina, kita i vuka!",
|
||||
"achievementPolarProModalText": "Sakupili ste sve polarne ljubimce!",
|
||||
"achievementWoodlandWizard": "Šumski Čarobnjak",
|
||||
"achievementWoodlandWizardText": "Izlegao/la je sve standardne boje šumskih stvorenja: jazavca, medvjeda, jelena, lisice, žabe, ježa, sove, puža, vjeverice i drvca!",
|
||||
"achievementWoodlandWizardModalText": "Skupili ste sve šumske ljubimce!",
|
||||
"achievementWoodlandWizardModalText": "Prikupili ste sve šumske ljubimce!",
|
||||
"achievementPlantParent": "Roditelj Biljke",
|
||||
"achievementPlantParentText": "Izlegao/la je sve standardne boje biljnih ljubimaca: Kaktus i Drvo!",
|
||||
"achievementPlantParentModalText": "Sakupili ste sve Biljne ljubimce!",
|
||||
"achievementPlantParentModalText": "Sakupili ste sve biljne ljubimce!",
|
||||
"achievementReptacularRumble": "Reptilska Tutnjava",
|
||||
"achievementReptacularRumbleText": "Izlegao/la je sve standardne boje kućnih ljubimaca reptila: Aligator, Pterodaktil, Zmija, Triceratops, Kornjača, Tiranosaurus Rex i Velociraptor!",
|
||||
"achievementReptacularRumbleModalText": "Skupili ste sve kućne ljubimce reptile!",
|
||||
"achievementReptacularRumbleText": "Izlegao/la je sve standardne boje kućnih ljubimaca reptila: Aligator, Pterodaktil, Zmija, Triceratops, Kornjača, Tiranosaurusa Rex i Velociraptora!",
|
||||
"achievementReptacularRumbleModalText": "Sakupili ste sve reptilske ljubimce!",
|
||||
"achievementLegendaryBestiary": "Legendarni Ukrotitelj Zvijeri",
|
||||
"achievementUndeadUndertakerText": "Ukrotio/la je sve Zombie životinje za jahanje.",
|
||||
"achievementUndeadUndertakerText": "Ukrotila/ukrotio je sve zombi životinje za jahanje.",
|
||||
"achievementDomesticatedText": "Izlegao/la je sve standardne boje pripitomljenih kućnih ljubimaca: tvor, zamorac, pijetao, leteće prase, štakor, zeko, konj i krava!",
|
||||
"achievementTickledPink": "Zagolican do Rumenjenja",
|
||||
"achievementDomesticated": "IJA-IJA-O",
|
||||
"achievementBareNecessitiesModalText": "Završio/la si zadatke majmuna, ljenjivca i stabla!",
|
||||
"achievementHatchedPet": "Izleći ljubimca",
|
||||
"achievementMindOverMatterModalText": "Završili ste zadatke kućnih ljubimaca Kamen, Sluz i Pređa!",
|
||||
"achievementGoodAsGold": "Dobar kao Zlato",
|
||||
"achievementLegendaryBestiaryModalText": "Sakupili ste sve mitske ljubimce!",
|
||||
"achievementSkeletonCrewModalText": "Ukrotio/la si sve Kosturske životinje za jahanje!",
|
||||
"achievementTickledPink": "Iznimno Sretan",
|
||||
"achievementDomesticated": "IJA-IJA-JO",
|
||||
"achievementBareNecessitiesModalText": "Završio/la si zadatak za kućne ljubimce: majmun, lenjivac i drvo-čedo.",
|
||||
"achievementHatchedPet": "Izlegni ljubimca.",
|
||||
"achievementMindOverMatterModalText": "Završio/la si zadatke za kućne ljubimce 'Rock', 'Slime' i 'Yarn'!",
|
||||
"achievementGoodAsGold": "Dobar Kao Zlato",
|
||||
"achievementLegendaryBestiaryModalText": "Sakupio/la si sve mitske ljubimce!",
|
||||
"achievementSkeletonCrewModalText": "Ukrotio/la si sve Kosturske životinje za jahanje.",
|
||||
"achievementSeeingRed": "Vidiš Crveno",
|
||||
"achievementFedPet": "Nahrani ljubimca",
|
||||
"achievementBugBonanza": "Tulum Kukaca",
|
||||
"achievementPearlyPro": "Biserni Profesionalac",
|
||||
"achievementFedPet": "Nahranite ljubimca.",
|
||||
"achievementBugBonanza": "Festival Kukaca",
|
||||
"achievementPearlyPro": "Biseran Profesionalac",
|
||||
"achievementWildBlueYonder": "Daleka Divlja Plava",
|
||||
"achievementRedLetterDayText": "Ukrotio/la je sve Crvene životinje za jahanje.",
|
||||
"achievementPurchasedEquipment": "Kupite dio opreme",
|
||||
"achievementRedLetterDayText": "Ukrotio/la je sve crvene životinje za jahanje.",
|
||||
"achievementPurchasedEquipment": "Kupite komad opreme.",
|
||||
"achievementSkeletonCrewText": "Ukrotio/la je sve Kosturske životinje za jahanje.",
|
||||
"achievementMonsterMagusModalText": "Sakupio/la si sve zombi ljubimce!",
|
||||
"achievementBugBonanzaText": "Dovršio/la je misije za kućne ljubimce Bube, Leptira, Puža i Pauka.",
|
||||
"achievementMonsterMagusModalText": "Sakupio/sakupila si sve kućne ljubimce zombija!",
|
||||
"achievementBugBonanzaText": "Završio/la je zadatke za kućne ljubimce: kukci - buba, leptir, puž i pauk.",
|
||||
"achievementSkeletonCrew": "Kosturska Družina",
|
||||
"achievementFreshwaterFriends": "Slatkovodni prijatelji",
|
||||
"achievementMonsterMagusText": "Sakupio/la je sve zombi ljubimce.",
|
||||
"achievementFreshwaterFriendsModalText": "Završio/la sizadatke kućnih ljubimaca Axolotla, Žabe i Nilskog konja!",
|
||||
"achievementFreshwaterFriends": "Slatkovodni Prijatelji",
|
||||
"achievementMonsterMagusText": "Sakupio/sakupila je sve kućne ljubimce zombija.",
|
||||
"achievementFreshwaterFriendsModalText": "Završio/la si zadatak kućnih ljubimaca Axolotla, Žabe i Nilskog konja.",
|
||||
"achievementGoodAsGoldText": "Sakupio/la je sve zlatne ljubimce.",
|
||||
"achievementBoneCollector": "Sakupljač Kostiju",
|
||||
"achievementGoodAsGoldModalText": "Sakupio/la si sve zlatne ljubimce!",
|
||||
"achievementRosyOutlook": "Ružičasti Izgled",
|
||||
"achievementSeeingRedModalText": "Sakupio/la si sve Crvene ljubimce!",
|
||||
"achievementGoodAsGoldModalText": "Sakupio/la si sve zlatne ljubimce.",
|
||||
"achievementRosyOutlook": "Ružičasti pogled",
|
||||
"achievementSeeingRedModalText": "Sakupio/la si sve crvene ljubimce.",
|
||||
"achievementKickstarter2019": "Pristalica Pin Kickstartera",
|
||||
"achievementAllThatGlitters": "Sve što Svjetluca",
|
||||
"achievementSeeingRedText": "Sakupio/la je sve Crvene ljubimce.",
|
||||
"achievementCreatedTask": "Kreirajte svoj prvi zadatak",
|
||||
"achievementFreshwaterFriendsText": "Završio/la je zadatke kućnih ljubimaca Axolotla, Žabe i Nilskog konja.",
|
||||
"achievementCompletedTask": "Izvršite zadatak",
|
||||
"achievementBoneCollectorText": "Sakupio/la je sve Kosturske Ljubimce.",
|
||||
"achievementPurchasedEquipmentText": "Kupili prvi komad opreme.",
|
||||
"achievementJustAddWaterText": "Završio/la je zadatke ljubimaca hobotnice, morskog konjica, sipe, kita, kornjače, golobrade, morske zmije i dupina.",
|
||||
"achievementPrimedForPaintingText": "Prikupio/la je sve Bijele ljubimce.",
|
||||
"achievementRedLetterDayModalText": "Ukrotio/la si sve Crvene životinje za jahanje!",
|
||||
"achievementPearlyProText": "Ukrotio/la je sve bijele životinje za jahanje.",
|
||||
"achievementSeasonalSpecialistModalText": "Završili ste sve sezonske misije!",
|
||||
"achievementBareNecessitiesText": "Završio/la je zadatke majmuna, ljenjivca i stabla.",
|
||||
"achievementAllThatGlitters": "Sve Što Svjetluca",
|
||||
"achievementSeeingRedText": "Sakupio/la je sve crvene ljubimce.",
|
||||
"achievementCreatedTask": "Kreiraj svoj prvi zadatak",
|
||||
"achievementFreshwaterFriendsText": "Završio/la je zadatak kućnih ljubimaca Axolotla, Žabe i Nilskog konja.",
|
||||
"achievementCompletedTask": "Završi zadatak.",
|
||||
"achievementBoneCollectorText": "Sakupio/la je sve Kosturske ljubimce.",
|
||||
"achievementPurchasedEquipmentText": "Kupio/la je svoj prvi komad opreme.",
|
||||
"achievementJustAddWaterText": "Završio/la je zadatke za kućne ljubimce 'Octopus', 'Seahorse', 'Cuttlefish', 'Whale', 'Turtle', 'Nudibranch', 'Sea Serpent' i 'Dolphin'.",
|
||||
"achievementPrimedForPaintingText": "Prikupio/la je sve bijele ljubimce.",
|
||||
"achievementRedLetterDayModalText": "Ukrotio/la si sve crvene životinje za jahanje!",
|
||||
"achievementPearlyProText": "Pripitomio/la sve bijele životinje za jahanje.",
|
||||
"achievementSeasonalSpecialistModalText": "Završio/la si sve sezonske zadatke!",
|
||||
"achievementBareNecessitiesText": "Završio/la je zadatke za kućne ljubimce: majmun, lenjivac i drvo-čedo.",
|
||||
"achievementDomesticatedModalText": "Prikupili ste sve pripitomljene ljubimce!",
|
||||
"achievementSeasonalSpecialist": "Sezonski Specijalist",
|
||||
"achievementBirdsOfAFeather": "Ptice istog Pera",
|
||||
"achievementBirdsOfAFeatherModalText": "Skupili ste sve leteće ljubimce!",
|
||||
"achievementBirdsOfAFeather": "Ptice Istog Pera",
|
||||
"achievementBirdsOfAFeatherModalText": "Prikupili ste sve leteće ljubimce!",
|
||||
"achievementBirdsOfAFeatherText": "Izlegao/la je sve standardne boje letećih ljubimaca: Leteću svinju, Sovu, Papigu, Pterodaktila, Grifona, Sokola, Pauna i Pijetla!",
|
||||
"achievementBoneToPick": "Nemirne Kosti",
|
||||
"achievementBoneToPickText": "Izlegao/la je sve klasične i Quest Kostur Ljubimce!",
|
||||
"achievementBoneToPickModalText": "Izlegao/la si sve klasične i Quest Kostur Ljubimce!",
|
||||
"achievementZodiacZookeeper": "Zodijak Čuvar Zoo-a",
|
||||
"achievementZodiacZookeeperModalText": "Prikupili ste sve zodijak ljubimce!",
|
||||
"achievementBoneToPick": "Nedovršena Posla",
|
||||
"achievementBoneToPickText": "Izlegao/la je sve klasične i kosturske ljubimce iz zadatka!",
|
||||
"achievementBoneToPickModalText": "Prikupili ste sve klasične i kućne ljubimce kosture iz zadatka!",
|
||||
"achievementZodiacZookeeper": "Zodiac Čuvar Zoo Vrta",
|
||||
"achievementZodiacZookeeperModalText": "Prikupili ste sve horoskopske ljubimce!",
|
||||
"achievementShadyCustomer": "Sumnjiva Mušterija",
|
||||
"achievementShadyCustomerText": "Prikupio/la je sve ljubimce sjene.",
|
||||
"achievementShadyCustomerModalText": "Prikupio/la si sve ljubimce sjene!",
|
||||
"achievementShadeOfItAll": "Nijansa svega",
|
||||
"achievementShadeOfItAllModalText": "Ukrotio/la si sve životinje za jahanje boje sjene!",
|
||||
"achievementShadyCustomerText": "Prikuio/la je sve ljubimce boje sjene.",
|
||||
"achievementShadyCustomerModalText": "Prikuio/la si sve ljubimce boje sjene.",
|
||||
"achievementShadeOfItAll": "Nijansa Svega",
|
||||
"achievementShadeOfItAllModalText": "Ukrotio/la si sve životinje za jahanje boje sjene.",
|
||||
"achievementDinosaurDynasty": "Dinastija dinosaura",
|
||||
"achievementDinosaurDynastyText": "Izlegao/la je sve standardne boje ljubimaca ptica i dinosaura: sokol, sova, papiga, paun, pingvin, pijetao, pterodaktil, t-rex, triceratops i velociraptor!",
|
||||
"achievementDinosaurDynastyModalText": "Sakupio/la si sve ljubimce ptica i dinosaura!"
|
||||
"achievementDinosaurDynastyModalText": "Sakupio/la si sve ljubimce ptica i dinosaura!",
|
||||
"achievementRoughRiderModalText": "Skupili ste sve osnovne boje neudobnih ljubimaca i jahaćih životinja!",
|
||||
"achievementRodentRuler": "Vladar glodavaca",
|
||||
"achievementRodentRulerModalText": "Skupili ste sve ljubimce glodavce!",
|
||||
"achievementRoughRider": "Neustrašivi jahač",
|
||||
"achievementRoughRiderText": "Izlegli ste sve osnovne boje neudobnih ljubimaca i jahaćih životinja: Kaktus, Jež i Kamen!",
|
||||
"achievementCatsModalText": "Skupili ste sve ljubimce mačke!",
|
||||
"achievementCats": "Gonič Mačaka",
|
||||
"achievementDuneBuddyModalText": "Skupili ste sve ljubimce iz pustinje!",
|
||||
"achievementRodentRulerText": "Izlegli ste sve standardne boje ljubimaca glodavaca: Zamorac, Štakor i Vjeverica!",
|
||||
"achievementCatsText": "Izlegli ste sve standardne boje ljubimaca iz porodice mačaka: Gepard, Lav, Sabljozubi tigar i Tigar!",
|
||||
"achievementBonelessBoss": "Bezkostni Šef",
|
||||
"achievementBonelessBossText": "Izlegli ste sve standardne boje kućnih ljubimaca beskralješnjaka: Buba, Leptir, Sipa, Puž golać, Hobotnica, Puž i Pauk!",
|
||||
"achievementBonelessBossModalText": "Sakupio si sve ljubimce beskralješnjake!",
|
||||
"achievementDuneBuddy": "Pustinjski prijatelj",
|
||||
"achievementDuneBuddyText": "Izlegli ste sve standardne boje ljubimaca iz pustinje: Armadillo, Kaktus, Lisica, Žaba, Zmija i Pauk!"
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
"backgroundStormyRooftopsNotes": "Šuljaj se po olujnim krovovima.",
|
||||
"backgroundWindyAutumnText": "Vjetrovita jesen",
|
||||
"backgroundWindyAutumnNotes": "Lovi lišće tijekom vjetrovite jeseni.",
|
||||
"incentiveBackgrounds": "Komplet običnih pozadina",
|
||||
"incentiveBackgrounds": "Standardne pozadine",
|
||||
"backgroundVioletText": "Purpurna",
|
||||
"backgroundVioletNotes": "Prpošna purpurna pozadina.",
|
||||
"backgroundBlueText": "Plava",
|
||||
@@ -765,10 +765,10 @@
|
||||
"backgroundSnowyVillageNotes": "Divite se snježnom selu.",
|
||||
"timeTravelBackgrounds": "Steampunk pozadine",
|
||||
"backgroundAirshipText": "Cepelin",
|
||||
"backgroundUnderwaterAmongKoiText": "Pod vodom Među Koi Ribama",
|
||||
"backgroundAmongCattailsText": "Među rogozima",
|
||||
"backgroundAmongCattailsNotes": "Diviti se divljini močvare među rogozima.",
|
||||
"backgroundUnderwaterAmongKoiNotes": "Zabljesni i budi zaslijepljen od sjajnih šarana, pod vodom među koi ribama.",
|
||||
"backgroundUnderwaterAmongKoiText": "Podvodni među Koi",
|
||||
"backgroundAmongCattailsText": "Među Mačjim Repovima",
|
||||
"backgroundAmongCattailsNotes": "Divite se močvarnim divljim životinjama među Cattails.",
|
||||
"backgroundUnderwaterAmongKoiNotes": "Zaslijepite i budite zaslijepljeni svjetlucavim šaranima, Underwater Among Koi.",
|
||||
"backgrounds052023": "SET 108: Izašlo u svibnju 2023.",
|
||||
"backgroundInAPaintingText": "U slici",
|
||||
"backgroundInAPaintingNotes": "Uživaj u kreativnim potragama unutar slike.",
|
||||
@@ -796,5 +796,47 @@
|
||||
"backgroundColorfulCoralNotes": "Zaronite među raznobojne koralje.",
|
||||
"backgroundBoardwalkIntoSunsetText": "Prošetajte molom u zalazak sunca",
|
||||
"backgrounds072023": "SET 110: Objavljen u srpnju 2023",
|
||||
"backgroundBoardwalkIntoSunsetNotes": "Prošećite molom u zalazak sunca."
|
||||
"backgroundBoardwalkIntoSunsetNotes": "Prošećite molom u zalazak sunca.",
|
||||
"backgrounds112023": "SET 114: Izašlo u studenom 2023",
|
||||
"backgroundGiantCatText": "Divovska mačka",
|
||||
"backgroundGiantCatNotes": "Odmorite uz Divovsku Mačku.",
|
||||
"backgroundBarrelCellarText": "Podrum s bačvama",
|
||||
"backgroundAutumnTreeTunnelText": "Tunel jesenskog drveća",
|
||||
"backgroundAutumnTreeTunnelNotes": "Uživajte u ljepoti tunela jesenskog drveća.",
|
||||
"backgrounds082023": "SET 111: Izašlo u kolovozu 2023",
|
||||
"backgroundBonsaiCollectionText": "Bonsai Kolekcija",
|
||||
"backgroundBonsaiCollectionNotes": "Divite se predivnoj Bonsai kolekciji.",
|
||||
"backgroundDreamyIslandText": "Otok iz snova",
|
||||
"backgroundDreamyIslandNotes": "Uživajte u pogledu na Otoku iz snova.",
|
||||
"backgroundRockGardenText": "Kameni vrt",
|
||||
"backgroundRockGardenNotes": "Opustite se u Kamenom vrtu.",
|
||||
"backgrounds122023": "SET 115: Izašlo u prosincu 2023",
|
||||
"backgroundHolidayTreeForestText": "Šuma božićnog drveća",
|
||||
"backgroundHolidayTreeForestNotes": "Ukrasite božićno drvce u šumi.",
|
||||
"backgroundIceSculptureFestivalText": "Festival skulptura od leda",
|
||||
"backgroundIceSculptureFestivalNotes": "Obiđite Festival skulptura od leda.",
|
||||
"backgroundWinterFullMoonText": "Zimski puni mjesec",
|
||||
"backgroundWinterFullMoonNotes": "Pogledajte zimski puni mjesec.",
|
||||
"backgrounds012024": "SET 116: Izašlo u siječnju 2024",
|
||||
"backgroundWinterMountainRangeText": "Zimski planinski lanac",
|
||||
"backgroundWinterMountainRangeNotes": "Popnite se na zimski planinski lanac.",
|
||||
"backgroundFrozenBluePondText": "Zaleđeno plavo jezerce",
|
||||
"backgroundIceBubbleLakeText": "Jezero ledenih mjehurića",
|
||||
"backgroundIceBubbleLakeNotes": "Pažljivo stojte na Jezeru ledenih mjehurića.",
|
||||
"backgroundBarrelCellarNotes": "Potražite kulinarske poslastice u Podrumu s bačvama.",
|
||||
"backgroundFrozenBluePondNotes": "Opustite se uz zaleđeno plavo jezerce.",
|
||||
"backgrounds092023": "SET 112: Izašlo u rujnu 2023",
|
||||
"backgroundMovingDayText": "Dan selidbe",
|
||||
"backgroundMovingDayNotes": "Spakirajte se za Dan selidbe.",
|
||||
"backgroundCoveredBridgeInAutumnText": "Prekriveni most u jesen",
|
||||
"backgroundCoveredBridgeInAutumnNotes": "Prijeđite prekriveni most u jesen.",
|
||||
"backgroundBaobabForestText": "Šuma Baobaba",
|
||||
"backgroundBaobabForestNotes": "S divljenjem promatrajte Šumu Baobaba.",
|
||||
"backgrounds102023": "SET 113: Izašlo u listopadu 2023",
|
||||
"backgroundSpectralCandleRoomText": "Soba Spektralnih Svijeća",
|
||||
"backgroundSpectralCandleRoomNotes": "Komunicirajte s duhovima u Sobi Spektralnih Svijeća.",
|
||||
"backgroundMonstrousCaveText": "Čudovišna špilja",
|
||||
"backgroundMonstrousCaveNotes": "Zagledajte se u ždrijelo Čudovišne špilje.",
|
||||
"backgroundJackOLanternStacksText": "Gomile Jack O'Lantern bundeva",
|
||||
"backgroundJackOLanternStacksNotes": "Divite se polju gomile Jack O'Lantern bundeva."
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
"profile": "Profil",
|
||||
"avatar": "Prilagodi Avatar",
|
||||
"editAvatar": "Uredi avatara",
|
||||
"noDescription": "Ovaj Habitičan nije dodao/la opis.",
|
||||
"noPhoto": "Ovaj Habitičan nije dodao/la sliku.",
|
||||
"noDescription": "Ovaj Habitičanin nije dodao opis.",
|
||||
"noPhoto": "Ovaj Habitičanin nije dodao sliku.",
|
||||
"other": "Ostalo",
|
||||
"fullName": "Puno Ime",
|
||||
"fullName": "Puno ime",
|
||||
"displayName": "Ime za prikazivanje",
|
||||
"changeDisplayName": "Promijeni ime za prikazivanje",
|
||||
"newDisplayName": "Novo ime za prikazivanje",
|
||||
"displayBlurbPlaceholder": "Možeš li nam se predstaviti?",
|
||||
"displayBlurbPlaceholder": "Molimo te da se predstaviš",
|
||||
"photoUrl": "URL fotografije",
|
||||
"imageUrl": "URL slike",
|
||||
"inventory": "Inventar",
|
||||
"social": "Društveno",
|
||||
"lvl": "lvl",
|
||||
"buffed": "Ojačan/a",
|
||||
"buffed": "Ojačan",
|
||||
"bodyBody": "Tijelo",
|
||||
"size": "Veličina",
|
||||
"locked": "zaključano",
|
||||
@@ -34,8 +34,8 @@
|
||||
"beard": "Brada",
|
||||
"mustache": "Brkovi",
|
||||
"flower": "Cvijet",
|
||||
"accent": "Akcenti",
|
||||
"headband": "Obruč za kosu",
|
||||
"accent": "Naglasak",
|
||||
"headband": "Traka za glavu",
|
||||
"wheelchair": "Invalidska kolica",
|
||||
"extra": "Dodatno",
|
||||
"rainbowSkins": "Teme u duginim bojama",
|
||||
@@ -56,13 +56,13 @@
|
||||
"autoEquipBattleGear": "Automatski opremi novu opremu",
|
||||
"costume": "Kostim",
|
||||
"useCostume": "Koristi Kostim",
|
||||
"costumePopoverText": "Odaberi \"Koristi kostim\" kako bi opremio/la artikle za svog avatara bez utjecanja na Statistiku svoje Ratne Opreme! Ovo znači da svog avatara možeš obući kako god hoćeš, a da pritom i dalje imaš opremljenu najbolju Ratnu Opremu.",
|
||||
"autoEquipPopoverText": "Odaberi ovu opciju za automatsko opremanje komada opreme kad ga kupiš.",
|
||||
"costumeDisabled": "Uklonio/la si svoj kosim.",
|
||||
"gearAchievement": "Zaradio/la si Postignuće \"Ultimativna Oprema\" za nadograđivanje svoje opreme do najvišeg kompleta opreme za svoju klasu! Skupio/la si sljedeće potpune komplete:",
|
||||
"gearAchievementNotification": "Zaradio/la si Postignuće \"Ultimativna Oprema\" za nadograđivanje svoje opreme do najvišeg kompleta opreme za svoju klasu!",
|
||||
"costumePopoverText": "Odaberi \"Koristi kostim\" kako bi odjenuo svog avatara bez utjecaja na bonuse svoje ratne opreme! Ovo znači da svog avatara možeš obući kako god želiš, a da pritom i dalje na sebi imaš najbolju ratnu opremu.",
|
||||
"autoEquipPopoverText": "Odaberi ovu opciju za automatsko opremanje opreme kad ju kupiš.",
|
||||
"costumeDisabled": "Uklonio si svoj kostim.",
|
||||
"gearAchievement": "Zaradili ste postignuće \"Ultimativna Oprema\" za nadograđivanje svoje opreme do najjačeg kompleta za svoju klasu! Postigli ste sljedeće potpune komplete:",
|
||||
"gearAchievementNotification": "Zaradili ste postignuće \"Ultimativna Oprema\" za nadograđivanje svoje opreme do najjačeg seta opreme za svoju klasu!",
|
||||
"moreGearAchievements": "Kako bi dobio/la više znački za Ultimativnu Opremu, promijeni klasu pod <a href='/user/settings/site' target='_blank'>Postavke > Stranica</a> i počni kupovati opremu svoje nove klase!",
|
||||
"armoireUnlocked": "Za više opreme, poviri u <strong>Začarani Ormar!</strong> Klikni na Začarani Ormar u stupcu Nagrada za nasumičnu priliku da dobiješ komad posebne Opreme! Ovo ti također može donijeti nasumični XP ili artikle hrane.",
|
||||
"armoireUnlocked": "Za više opreme baci pogled u <strong>Začarani Ormar!</strong> Klikni na Začarani Ormar u stupcu Nagrada za nasumičnu priliku da dobiješ dio posebne Opreme! Ovo ti također može donijeti nasumični XP ili artikle hrane.",
|
||||
"ultimGearName": "Ultimativna Oprema - <%= ultClass %>",
|
||||
"ultimGearText": "je maksimalno nadogradio/la komplet oružja i oklopa za klasu <%= ultClass %>.",
|
||||
"level": "Level",
|
||||
@@ -90,7 +90,7 @@
|
||||
"constitution": "Konstitucija",
|
||||
"conText": "Konstitucija smanjuje štetu koju dobiješ od loših Navika i neizvršenih Svakodnevnih zadataka.",
|
||||
"perception": "Percepcija",
|
||||
"perText": "Percepcija povečava količinu Zlatnika koju zaradiš,a nakon što otključaš Tržnicu, povečava ti šansu da nađeš artikle prilikom obavljanja zadataka.",
|
||||
"perText": "Percepcija uvećava količinu Zlata koje zaradiš, a nakon što otključaš Tržnicu ti povećava šansu da pronađeš nove stvari prilikom rješavanja zadataka.",
|
||||
"intelligence": "Inteligencija",
|
||||
"intText": "Inteligencija povećava količinu Iskustva koju dobivaš, a nakon što otključaš Klase, ona određuje maksimalnu količinu dostupne Mane za sposobnosti Klase.",
|
||||
"levelBonus": "Bonus za Level",
|
||||
@@ -167,8 +167,8 @@
|
||||
"photo": "Slika",
|
||||
"info": "Informacije",
|
||||
"joined": "Pridružio/la se",
|
||||
"totalLogins": "Ukupno Prijava",
|
||||
"latestCheckin": "Posljednja Prijava",
|
||||
"totalLogins": "Ukupne prijave",
|
||||
"latestCheckin": "Posljednja prijava",
|
||||
"editProfile": "Uredi Profil",
|
||||
"challengesWon": "Dobiveni Izazovi",
|
||||
"questsCompleted": "Dovršene Pustolovine",
|
||||
@@ -185,5 +185,6 @@
|
||||
"chatCastSpellUser": "<%= username %> baca <%= spell%> na <%= target%>.",
|
||||
"purchaseForGold": "Kupnja za <%= cost %> Zlata?",
|
||||
"chatCastSpellPartyTimes": "<%= username %> koristi <%= spell %> za družinu <%= times %> puta.",
|
||||
"chatCastSpellUserTimes": "<%= username %> koristi <%= spell %> za <%= target %> <%= times %> puta."
|
||||
"chatCastSpellUserTimes": "<%= username %> koristi <%= spell %> za <%= target %> <%= times %> puta.",
|
||||
"nextReward": "Nagrada za slijedeću prijavu"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"frequentlyAskedQuestions": "Često postavljena pitanja",
|
||||
"iosFaqStillNeedHelp": "Ako imaš pitanje koje nije navedeno na ovom popisu ili pod [Wiki ČPP](http://habitica.wikia.com/wiki/FAQ), dođi ga postaviti u chat Krčme pod Izbornik > Krčma! Rado ćemo ti pomoći.",
|
||||
"androidFaqStillNeedHelp": "Ako imaš pitanje koje nije navedeno na ovom popisu ili pod [Wiki ČPP](http://habitica.wikia.com/wiki/FAQ), dođi ga postaviti u chat Krčme pod Izbornik > Krčma! Rado ćemo ti pomoći.",
|
||||
"webFaqStillNeedHelp": "Ako imaš pitanje koje nije navedeno na ovom popisu ili pod [Wiki ČPP](http://habitica.wikia.com/wiki/FAQ), dođi ga postaviti u [Habitičinom cehu za Pomoć](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! Rado ćemo ti pomoći.",
|
||||
"iosFaqStillNeedHelp": "Ako imate pitanje koje nije na ovom popisu ili na [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), dođite pitati u Tavern chat pod Menu > Tavern! Rado ćemo pomoći.",
|
||||
"androidFaqStillNeedHelp": "Ako imate pitanje koje nije na ovom popisu ili na [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), dođite pitati u Tavern chat pod Menu > Tavern! Rado ćemo pomoći.",
|
||||
"webFaqStillNeedHelp": "Ako imate pitanje koje nije na ovom popisu ili na [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), dođite pitati u [Habitica Help guild](https://habitica .com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! Rado ćemo pomoći.",
|
||||
"commonQuestions": "Uobičajena pitanja",
|
||||
"faqQuestion25": "Što su različite vrste zadataka?",
|
||||
"faqQuestion26": "Koji su neki jednostavni zadatci?",
|
||||
@@ -11,5 +11,23 @@
|
||||
"faqQuestion33": "Što je plava traka koja se pojavljuje nakon razine 10?",
|
||||
"faqQuestion34": "Kakvu hranu moj ljubimac voli?",
|
||||
"faqQuestion36": "Kako da promijenim izgled svog Avatara?",
|
||||
"faqQuestion37": "Zašto se moja Oprema ne prikazuje na mom Avataru?"
|
||||
"faqQuestion37": "Zašto se moja Oprema ne prikazuje na mom Avataru?",
|
||||
"faqQuestion29": "Kako mogu oporaviti HP?",
|
||||
"webFaqAnswer29": "Možete oporaviti 15 HP kupnjom napitka za zdravlje iz stupca Nagrade za 25 zlata. Osim toga, uvijek ćete oporaviti puni HP kada se popnete na višu razinu!",
|
||||
"faqQuestion30": "Što se događa kada mi ponestane HP-a?",
|
||||
"webFaqAnswer30": "Ako vam HP dosegne nulu, izgubit ćete jednu razinu, svo svoje zlato i komad opreme koji se može ponovno kupiti.",
|
||||
"faqQuestion31": "Zašto sam gubio HP prilikom interakcije s nenegativnim zadatkom?",
|
||||
"faqQuestion32": "Kako mogu odabrati razred?",
|
||||
"webFaqAnswer33": "Nakon što otključate Klasni Sustav, otključavate i Vještine za koje je potrebna Mana. Mana je određena vašom INT statistikom i može se prilagoditi vještinama i opremom.",
|
||||
"faqQuestion35": "Nahranio sam svog ljubimca i nestao je! Što se dogodilo?",
|
||||
"faqQuestion38": "Zašto ne mogu kupiti određene artikle?",
|
||||
"faqQuestion39": "Gdje mogu nabaviti više opreme?",
|
||||
"faqQuestion40": "Što su dragulji i kako ih mogu dobiti?",
|
||||
"faqQuestion41": "Što su Mistični pješčani satovi i kako ih mogu dobiti?",
|
||||
"faqQuestion42": "Što mogu učiniti kako bih povećao odgovornost?",
|
||||
"faqQuestion43": "Kako mogu prihvatiti zadatke?",
|
||||
"faqQuestion44": "Kako mogu izbrisati zadatke Izazova?",
|
||||
"faqQuestion45": "Moj avatar se transformirao u snjegovića, morsku zvijezdu, cvijet ili duha. Kako se mogu vratiti u to stanje?",
|
||||
"webFaqAnswer26": "Pozitivne navike (Ponašanja koja želiš potaknuti; trebaju imati gumb s plusom)\n\n Uzeti vitamine\n Koristiti zubni konac\n Jedan sat učenja\n\nNegativne navike (Ponašanja koja želiš ograničiti ili izbjegavati; trebaju imati gumb s minusom)\n\n Pušenje\n Beskrajno \"skrolanje\" (doom scrolling)\n Grizenje noktiju\n\nDvostruke navike (Navike koje uključuju pozitivnu i negativnu opciju; trebaju imati i plus i minus gumb)\n\n Piti vodu vs. piti gazirano piće\n Učiti vs. odugovlačiti\n\nPrimjeri dnevnih zadataka (Zadaci koje želiš ponavljati po redovnom rasporedu)\n Oprati suđe\n Zaliti biljke\n 30 minuta tjelesne aktivnosti\n\nPrimjeri zadataka za obaviti (Zadaci koje trebaš napraviti samo jednom)\n\n Zakazati termin\n Organizirati ormar\n Završiti esej",
|
||||
"webFaqAnswer25": "Habitica koristi tri različite vrste zadataka kako bi se prilagodila tvojim potrebama: Navike (Habits), Dnevne zadatke (Dailies) i Zadatke za obaviti (To Do's).\n\nNavike mogu biti pozitivne ili negativne i predstavljaju nešto što želiš pratiti više puta dnevno ili po nepredviđenom rasporedu. Pozitivne navike donose nagrade, poput zlata i iskustva (Exp), dok te negativne navike koštaju zdravlja (HP).\n\nDnevni zadaci su ponavljajući zadaci koje želiš obavljati po strukturiranom rasporedu. Na primjer, jednom dnevno, tri puta tjedno ili četiri puta mjesečno. Neizvršeni dnevni zadaci uzrokuju gubitak HP-a, ali što su teži, to su nagrade bolje!\n\nZadaci za obaviti su jednokratni zadaci koji ti daju nagrade nakon što ih završiš. Mogu imati rok, ali nećeš izgubiti HP ako ga propustiš.\n\nOdaberi vrstu zadatka koja najbolje odgovara onome što želiš postići!"
|
||||
}
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
{
|
||||
"oldNews": "Novosti",
|
||||
"footerMobile": "Mobilni",
|
||||
"oldNews": "Vijesti",
|
||||
"footerMobile": "Za mobitel",
|
||||
"history": "Povijest",
|
||||
"FAQ": "Pitanja",
|
||||
"companyDonate": "Donirajte Habitici",
|
||||
"FAQ": "Često postavljena pitanja",
|
||||
"companyDonate": "Doniraj Habitici",
|
||||
"footerProduct": "Proizvod",
|
||||
"footerSocial": "Društveni",
|
||||
"free": "Pridružite se besplatno",
|
||||
"logout": "Odjavite se",
|
||||
"marketing1Header": "Unaprijedite svoje navike igrajući igru",
|
||||
"marketing1Lead1Title": "Vaš život, igra uloga",
|
||||
"marketing1Lead2Title": "Nabavite Zakon Opremu",
|
||||
"marketing1Lead3Title": "Pronađite nasumične nagrade",
|
||||
"marketing2Header": "Natječite se s prijateljima, pridružite se interesnim grupama",
|
||||
"marketing2Lead1Title": "Društvena produktivnost",
|
||||
"marketing2Lead2Title": "Borba protiv čudovišta",
|
||||
"marketing2Lead2": "Što je igranje uloga bez bitaka? Borite se protiv čudovišta sa svojom družinom. Čudovišta su \"način super odgovornosti\" - dan kada propustite teretanu je dan kada čudovište povrijedi *sve!*",
|
||||
"footerSocial": "Društveno",
|
||||
"free": "Pridruži se besplatno",
|
||||
"logout": "Odjava",
|
||||
"marketing1Header": "Igrom poboljšajte svoje navike",
|
||||
"marketing1Lead1Title": "Tvoj život, Igra igranja uloga",
|
||||
"marketing1Lead2Title": "Osvoji fora opremu",
|
||||
"marketing1Lead3Title": "Pronađi nasumične nagrade",
|
||||
"marketing2Header": "Natječi se s prijateljima i pridruži se zanimljivim grupama",
|
||||
"marketing2Lead1Title": "Društvena Produktivnost",
|
||||
"marketing2Lead2Title": "Bori se s čudovištima na misijama",
|
||||
"marketing2Lead2": "Što je igranje uloga bez bitaka? Borite se protiv čudovišta sa svojom družinom. Čudovišta su \"način super odgovornosti\" - dan kada propustite teretanu je dan kada čudovište ozlijede *sve!*",
|
||||
"marketing2Lead3Title": "Izazovite jedni druge",
|
||||
"marketing2Lead3": "Izazovi vam omogućuju da se natječete s prijateljima i strancima. Tko bude najbolji na kraju izazova, osvaja posebne nagrade.",
|
||||
"marketing3Lead1": "Aplikacije za **iPhone i Android** omogućuju vam da vodite računa o poslu dok ste u pokretu. Shvaćamo da prijava na web mjesto radi klikanja gumba može biti naporna.",
|
||||
"marketing3Lead2Title": "Integracije",
|
||||
"marketing3Lead2Title": "Integracija",
|
||||
"marketing4Header": "Organizacijska upotreba",
|
||||
"marketing4Lead1Title": "Gamifikacija u obrazovanju",
|
||||
"marketing4Lead2": "Troškovi zdravstvene zaštite su u porastu i nešto se mora promjeniti. Izrađene su stotine programa za smanjenje troškova i poboljšanje dobrobiti. Vjerujemo da Habitica može utrti značajan put prema zdravim stilovima života.",
|
||||
"marketing4Lead2": "Troškovi zdravstvene zaštite su u porastu i nešto mora popustiti. Izrađene su stotine programa za smanjenje troškova i poboljšanje dobrobiti. Vjerujemo da Habitica može utrti značajan put prema zdravim stilovima života.",
|
||||
"marketing4Lead2Title": "Gamifikacija u zdravlju i dobrobiti",
|
||||
"marketing4Lead3-1": "Želite gamificirati svoj život?",
|
||||
"marketing4Lead3-2": "Zainteresirani ste za vođenje grupe u obrazovanju, wellnessu i još mnogo toga?",
|
||||
"marketing4Lead3Title": "Gamificiraj Sve",
|
||||
"mobileAndroid": "Android aplikacija",
|
||||
"mobileIOS": "aplikacija za iOS",
|
||||
"marketing4Lead3Title": "Gamificirajte Sve",
|
||||
"mobileAndroid": "Android Aplikacija",
|
||||
"mobileIOS": "iOS Aplikacija",
|
||||
"setNewPass": "Postavite novu lozinku",
|
||||
"playButton": "Igraj",
|
||||
"enterHabitica": "Uđite u Habiticu",
|
||||
"presskitText": "Hvala na interesu za Habiticu! Sljedeće slike mogu se koristiti za članke ili video zapise o Habitici. Za više informacija kontaktirajte nas na <%= pressEnquiryEmail %>.",
|
||||
"pkQuestion1": "Što je inspiriralo Habiticu? Kako je počelo?",
|
||||
"pkQuestion1": "Što je inspiriralo Habiticu? Kako je sve počelo?",
|
||||
"pkQuestion2": "Zašto Habitica djeluje?",
|
||||
"pkQuestion3": "Zašto ste dodali društvene značajke?",
|
||||
"pkQuestion4": "Zašto preskakanje zadataka smanjuje zdravlje vašeg avatara?",
|
||||
"pkQuestion5": "Po čemu se Habitica razlikuje od ostalih gamifikacijskih programa?",
|
||||
"pkAnswer5": "Jedan od načina na koji je Habitica bila najuspješnija u korištenju gamifikacije jest to što smo uložili puno truda u razmišljanje o aspektima igre kako bismo osigurali da su one zapravo zabavne. Također smo uključili mnoge društvene komponente jer smatramo da vam neke od najmotivirajućih igara omogućuju igranje s prijateljima i jer je istraživanje pokazalo da je lakše stvoriti navike kada imate odgovornost prema drugim ljudima.",
|
||||
"pkQuestion6": "Tko je tipični korisnik Habitice?",
|
||||
"login": "Prijaviti se",
|
||||
"marketing3Header": "Aplikacije i proširenja",
|
||||
"marketing1Lead1": "Habitica je videoigra koja vam pomaže poboljšati navike u stvarnom životu. Ono \"gamificira\" vaš život pretvarajući sve vaše zadatke (navike, svakodnevne poslove i obaveze) u mala čudovišta koja morate pobijediti. Što ste bolji u ovome, to više napredujete u igri. Ako pogriješite u životu, vaš lik počinje nazadovati u igri.",
|
||||
"pkAnswer1": "Ako ste ikada uložili vrijeme u podizanju levela lika u igrici, teško je ne zapitati se kako bi vaš život bio sjajan da sav taj trud uložite u poboljšanje sebe u stvarnom životu umjesto svog avatara. Počinjemo s izgradnjom Habitice kako bismo odgovorili na to pitanje. <br /> Habitica je službeno pokrenuta s Kickstarterom 2013. i ideja je doista zaživjela. Od tada je prerastao u ogroman projekt, koji podržavaju naši sjajni volonteri otvorenog koda i naši velikodušni korisnici.",
|
||||
"pkAnswer2": "Stvaranje nove navike je teško jer ljudi stvarno trebaju tu očitu, trenutnu nagradu. Na primjer, teško je početi koristiti zubni konac, jer iako nam stomatolog kaže da je to dugoročno zdravije, u trenu samo zaboli desni. <br /> Habitičina gamifikacija dodaje osjećaj trenutnog zadovoljstva svakodnevnim ciljevima nagrađujući težak zadatak iskustvom, zlatom... a možda čak i nasumičnim izborom, poput zmajevog jajeta! To pomaže da ljudi ostanu motivirani čak i kada sam zadatak nema intrinzičnu nagradu, a vidjeli smo kako ljudi preokreću svoje živote kao rezultat toga.",
|
||||
"pkAnswer3": "Društveni pritisak veliki je motivirajući faktor za mnoge ljude, pa smo znali da želimo imati snažnu zajednicu koja će jedni druge smatrati odgovornima za svoje ciljeve i navijati za njihove uspjehe. Srećom, jedna od stvari koje videoigre za više igrača rade najbolje jest poticanje osjećaja zajedništva među svojim korisnicima! Habitičina struktura zajednice posuđuje od ovih vrsta igara; možete osnovati malu grupu bliskih prijatelja, ali se također možete pridružiti većim grupama zajedničkih interesa poznatim kao Guild. Iako neki korisnici odluče igrati solo, većina odluči formirati mrežu podrške koja potiče društvenu odgovornost kroz značajke kao što su misije, gdje članovi grupe udružuju svoju produktivnost kako bi se zajedno borili protiv čudovišta.",
|
||||
"companyContribute": "Doprinos Habitici",
|
||||
"pkAnswer4": "Ako preskočite jedan od svojih dnevnih ciljeva, vaš će avatar sljedeći dan izgubiti zdravlje. Ovo služi kao važan motivirajući čimbenik za poticanje ljudi da slijede svoje ciljeve jer ljudi stvarno mrze povrijediti svog malog avatara! Osim toga, društvena odgovornost ključna je za mnoge ljude: ako se s prijateljima borite protiv čudovišta, preskakanje zadataka šteti i njihovim avatarima.",
|
||||
"emailNewPass": "Pošaljite e-poštom vezu za ponovno postavljanje lozinke",
|
||||
"sendLink": "Pošalji Poveznicu",
|
||||
"login": "Prijava",
|
||||
"marketing3Header": "Aplikacije i Proširenja",
|
||||
"marketing1Lead1": "Habitica je video igra koja će ti pomoći da poboljšaš svoje navike. Habitica tvoje obveze (Navike, Dnevne zadatke i Zadatke) pretvara u mala čudovišta koja trebaš pobijediti. Što si u tome bolji, to brže napreduješ. Ako, pak, ne izvršavaš svoje obveze, tvom liku ide loše, Tvoj lik u igri odraz je tebe u stvarnom životu.",
|
||||
"pkAnswer1": "Ako ste ikada uložili vrijeme u podizanje razine lika u igrici, teško je ne zapitati se kako bi vaš život bio sjajan da sav taj trud uložite u poboljšanje sebe u stvarnom životu umjesto svog avatara. Počinjemo s izgradnjom Habitice kako bismo odgovorili na to pitanje. <br /> Habitica je službeno pokrenuta s Kickstarterom 2013. i ideja je doista zaživjela. Od tada je prerastao u ogroman projekt, koji podržavaju naši sjajni open source volonteri i naši velikodušni korisnici.",
|
||||
"pkAnswer2": "Stvaranje nove navike je teško jer ljudi stvarno trebaju tu očitu, trenutnu nagradu. Na primjer, teško je početi koristiti zubni konac, jer iako nam stomatolog kaže da je to dugoročno zdravije, u trenu samo zaboli desni. <br /> Habiticina igrivost dodaje osjećaj trenutnog zadovoljstva svakodnevnim ciljevima nagrađujući težak zadatak iskustvom, zlatom... a možda čak i nasumičnim izborom, poput zmajevog jajeta! To pomaže da ljudi ostanu motivirani čak i kada sam zadatak nema intrinzičnu nagradu, a vidjeli smo kako ljudi preokreću svoje živote kao rezultat toga.",
|
||||
"pkAnswer3": "Društveni pritisak veliki je motivirajući faktor za mnoge ljude, pa smo znali da želimo imati snažnu zajednicu koja će jedni druge smatrati odgovornima za svoje ciljeve i navijati za njihove uspjehe. Srećom, jedna od stvari koje videoigre za više igrača rade najbolje jest poticanje osjećaja zajedništva među svojim korisnicima! Habiticina struktura zajednice posuđuje od ovih vrsta igara; možete osnovati malu grupu bliskih prijatelja, ali se također možete pridružiti većim grupama zajedničkih interesa poznatim kao ceh. Iako neki korisnici odluče igrati solo, većina odluči formirati mrežu podrške koja potiče društvenu odgovornost kroz značajke kao što su misije, gdje članovi stranke udružuju svoju produktivnost kako bi se zajedno borili protiv čudovišta.",
|
||||
"companyContribute": "Pridonesi Habitici",
|
||||
"pkAnswer4": "Ako preskočite jedan od svojih dnevnih ciljeva, vaš će avatar sljedeći dan izgubiti zdravlje. Ovo služi kao važan motivirajući čimbenik za poticanje ljudi da slijede svoje ciljeve jer ljudi stvarno mrze povrijediti svojeg malog avatara! Osim toga, društvena odgovornost ključna je za mnoge ljude: ako se s prijateljima borite protiv čudovišta, preskakanje zadataka šteti i njihovim avatarima.",
|
||||
"emailNewPass": "Pošaljite mi poveznicu za promjenu lozinke",
|
||||
"sendLink": "Pošalji mi poveznicu",
|
||||
"footerCommunity": "Zajednica",
|
||||
"invalidEmail": "Potrebna je valjana adresa e-pošte kako bi se izvršilo ponovno postavljanje lozinke.",
|
||||
"marketing1Lead2": "Poboljšajte svoje navike kako biste izgradili svoj avatar. Pokažite zakon opremu koju ste zaradili!",
|
||||
"marketing1Lead3": "Neke motivira kockanje: sustav koji se zove \"stohastičke nagrade\". Habitica se prilagođava svim stilovima potkrepljivanja i kažnjavanja: pozitivnim, negativnim, predvidljivim i nasumičnim.",
|
||||
"marketing2Lead1": "Iako možete igrati Habiticu solo, svjetla se stvarno pale kada počnete surađivati, natjecati se i držati jedni druge odgovornima. Najučinkovitiji dio svakog programa samousavršavanja je društvena odgovornost, a koje je bolje okruženje za odgovornost i natjecanje od videoigre?",
|
||||
"marketing4Lead1": "Obrazovanje je jedan od najboljih sektora za gamifikaciju. Svi znamo koliko su studenti ovih dana zalijepljeni za telefone i igre; iskoristi tu moć! Suprotstavite svoje učenike u prijateljskom natjecanju. Nagradite dobro ponašanje nagradama. Gledajte kako im ocjene i ponašanje rastu.",
|
||||
"invalidEmail": "Za promjenu lozinke potrebna je važeća email adresa",
|
||||
"marketing1Lead2": "Skupljaj mačeve, oklope i još mnogo toga uz zlato koje zaradiš ispunjavanjem zadataka. S obzirom na to da možeš skupiti stotine predmeta, nikad ti neće ponestati kombinacija koje možeš isprobati. Optimiziraj za statistiku, stil ili oboje! ",
|
||||
"marketing1Lead3": "Neke motivira kockanje: sustav zvan \"stohastičke nagrade.\" Habitica sadrži sve oblike nagrade i kazne: pozitivne, negativne, predvidljive i nasumične. ",
|
||||
"marketing2Lead1": "Potakni svoju motivaciju suradnjom, natjecanjem i interakcijom s drugima! Habitica je osmišljena tako da iskoristi najučinkovitiji dio svakog programa za samopoboljšanje: društvenu odgovornost.",
|
||||
"marketing4Lead1": "Obrazovanje je jedan od najboljih sektora za gamifikaciju. Svi znamo koliko su studenti ovih dana zalijepljeni za telefone i igre; iskoristi tu moć! Suprotstavite svoje učenike u prijateljskom natjecanju. Nagradite dobro ponašanje rijetkim nagradama. Gledajte kako im ocjene i ponašanje rastu.",
|
||||
"clearBrowserData": "Izbriši podatke preglednika",
|
||||
"companyAbout": "Kako ovo funkcionira",
|
||||
"companyAbout": "Kako radi",
|
||||
"forgotPassword": "Zaboravili ste lozinku?",
|
||||
"communityFacebook": "Facebook",
|
||||
"communityExtensions": "Dodaci i proširenja",
|
||||
"communityExtensions": "<a href='http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations' target='_blank'>Dodaci i prilagodbe</a>",
|
||||
"chores": "Obveze",
|
||||
"footerDevs": "Programeri",
|
||||
"footerDevs": "Razvojni programeri",
|
||||
"communityInstagram": "Instagram",
|
||||
"forgotPasswordSteps": "Unesite svoje korisničko ime ili adresu e-pošte koju ste koristili za registraciju svog Habitica računa.",
|
||||
"forgotPasswordSteps": "Unesite email adresu kojom ste se registrirali na svoj Habitica račun",
|
||||
"companyBlog": "Blog",
|
||||
"marketing3Lead2": "Ostali **alati trećih strana** povezuju Habiticu s raznim aspektima vašeg života. Naš API pruža jednostavnu integraciju za stvari kao što su [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), za koje gubite bodove prilikom pregledavanja neproduktivnih web stranica i dobivaju bodove kada su na produktivnim. [Više pogledajte ovdje](https://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
|
||||
"marketing3Lead2": "Ostali **alati trećih strana** povezuju Habiticu s raznim aspektima vašeg života. Naš API pruža jednostavnu integraciju za stvari poput [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), za koje gubite bodove prilikom pregledavanja neproduktivnih web stranica i dobivaju bodove kada su na produktivnim. [Više pogledajte ovdje](https://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
|
||||
"password": "Lozinka",
|
||||
"register": "Registar",
|
||||
"register": "Prijavi se",
|
||||
"missingNewPassword": "Nedostaje nova lozinka.",
|
||||
"pkQuestion7": "Zašto Habitica koristi pixel art?",
|
||||
"pkQuestion8": "Kako je Habitica utjecala na stvarne živote ljudi?",
|
||||
@@ -77,7 +77,7 @@
|
||||
"pkLogo": "Logotipi",
|
||||
"pkSamples": "Uzorci zaslona",
|
||||
"pkWebsite": "Web stranica",
|
||||
"sync": "Sinkronizacija",
|
||||
"sync": "Sinkroniziraj",
|
||||
"tasks": "Zadaci",
|
||||
"teams": "Timovi",
|
||||
"terms": "Odredbe i uvjeti",
|
||||
@@ -85,15 +85,15 @@
|
||||
"localStorageTryNext": "Ako se problem nastavi, <%= linkStart %>Prijavite grešku<%= linkEnd %> ako već niste.",
|
||||
"localStorageClear": "Obriši podatke",
|
||||
"localStorageClearExplanation": "Ovaj gumb će izbrisati lokalnu pohranu i većinu kolačića te vas odjaviti.",
|
||||
"username": "Korisničko ime",
|
||||
"username": "Korisničko Ime",
|
||||
"emailOrUsername": "E-pošta ili korisničko ime (razlikuje velika i mala slova)",
|
||||
"reportAccountProblems": "Prijavite probleme s računom",
|
||||
"reportCommunityIssues": "Prijavite probleme zajednice",
|
||||
"subscriptionPaymentIssues": "Problemi s pretplatom i plaćanjem",
|
||||
"generalQuestionsSite": "Opća pitanja o stranici",
|
||||
"businessInquiries": "Poslovni/Marketinški upiti",
|
||||
"merchandiseInquiries": "Upiti o fizičkoj robi (majice, naljepnice)",
|
||||
"tweet": "Tweet",
|
||||
"businessInquiries": "Poslovni/marketinški upiti",
|
||||
"merchandiseInquiries": "Upiti o fizičkoj robi (majice, naljepnice).",
|
||||
"tweet": "Tweetaj",
|
||||
"checkOutMobileApps": "Provjerite naše mobilne aplikacije!",
|
||||
"missingAuthHeaders": "Nedostaju zaglavlja za provjeru autentičnosti.",
|
||||
"missingUsernameEmail": "Nedostaje korisničko ime ili adresa e-pošte.",
|
||||
@@ -120,8 +120,8 @@
|
||||
"heroIdRequired": "\"heroId\" mora biti važeći UUID.",
|
||||
"cannotFulfillReq": "Vaš zahtjev ne može biti ispunjen. Pošaljite e-poruku na admin@habitica.com ako se ova pogreška nastavi pojavljivati.",
|
||||
"modelNotFound": "Ovaj model ne postoji.",
|
||||
"signUpWithSocial": "Registrirajte se sa <%= social %>",
|
||||
"loginWithSocial": "Prijavite se sa <%= social %>",
|
||||
"signUpWithSocial": "Prijavite se na <%= social %>",
|
||||
"loginWithSocial": "Prijavite se s <%= social %>",
|
||||
"confirmPassword": "Potvrdi lozinku",
|
||||
"usernamePlaceholder": "npr. HabitRabbit",
|
||||
"emailPlaceholder": "npr. gryphon@example.com",
|
||||
@@ -129,19 +129,19 @@
|
||||
"confirmPasswordPlaceholder": "Provjerite je li to ista lozinka!",
|
||||
"joinHabitica": "Pridružite se Habitici",
|
||||
"alreadyHaveAccountLogin": "Već imate Habitica račun? <strong>Prijavite se.</strong>",
|
||||
"dontHaveAccountSignup": "Nemate Habitica račun? <strong>Registriraj se.</strong>",
|
||||
"dontHaveAccountSignup": "Nemate Habitica račun? <strong>Registrirajte se.</strong>",
|
||||
"motivateYourself": "Motivirajte se da postignete svoje ciljeve.",
|
||||
"timeToGetThingsDone": "Vrijeme je za zabavu kada završite stvari! Pridružite se više od <%= userCountInMillions %> milijuna Habitičana i poboljšajte svoj život zadatak po zadatak.",
|
||||
"singUpForFree": "Registrirajte se besplatno",
|
||||
"singUpForFree": "Prijavite se besplatno",
|
||||
"or": "ILI",
|
||||
"gamifyYourLife": "Gamificirajte svoj život",
|
||||
"trackYourGoals": "Pratite svoje navike i ciljeve",
|
||||
"trackYourGoalsDesc": "Ostanite odgovorni praćenjem i upravljanjem svojim navikama, dnevnim ciljevima i popisom obveza pomoću Habiticinih mobilnih aplikacija i web sučelja jednostavnih za korištenje.",
|
||||
"earnRewardsDesc": "Označite zadatke kako biste podigli level svog Avatara i otključali značajke u igri kao što su borbeni oklopi, misteriozni kućni ljubimci, čarobne vještine, pa čak i misije!",
|
||||
"battleMonsters": "Borite se protiv čudovišta s prijateljima",
|
||||
"earnRewardsDesc": "Označite zadatke kako biste podigli razinu svog Avatara i otključali značajke u igri kao što su borbeni oklopi, misteriozni kućni ljubimci, čarobne vještine, pa čak i misije!",
|
||||
"battleMonsters": "Borite se s čudovištima s prijateljima",
|
||||
"battleMonstersDesc": "Borite se protiv čudovišta s drugim Habitičanima! Iskoristite zlato koje zaradite za kupnju nagrada u igri ili prilagođenih nagrada, poput gledanja epizode vaše omiljene TV emisije.",
|
||||
"playersUseToImprove": "Igrači koriste Habiticu za poboljšanje",
|
||||
"healthAndFitness": "Zdravlje i Fitness",
|
||||
"healthAndFitness": "Zdravlje i kondicija",
|
||||
"schoolAndWork": "Škola i Posao",
|
||||
"schoolAndWorkDesc": "Bilo da pripremate izvješće za svog učitelja ili šefa, lako je pratiti svoj napredak dok rješavate svoje najteže zadatke.",
|
||||
"muchmuchMore": "I još puno, puno više!",
|
||||
@@ -149,30 +149,33 @@
|
||||
"levelUpAnywhereDesc": "Naše mobilne aplikacije olakšavaju praćenje vaših zadataka dok ste u pokretu. Ostvarite svoje ciljeve jednim dodirom, bez obzira gdje se nalazite.",
|
||||
"joinMany": "Pridružite se više od <%= userCountInMillions %> milijuna ljudi koji se zabavljaju dok ostvaruju svoje ciljeve!",
|
||||
"joinToday": "Pridružite se Habitici već danas",
|
||||
"featuredIn": "Istaknuto u",
|
||||
"featuredIn": "Spominjano u",
|
||||
"getStarted": "Započnite!",
|
||||
"earnRewards": "Zaradite nagrade za svoje ciljeve",
|
||||
"school": "Škola",
|
||||
"work": "Posao",
|
||||
"pkAnswer6": "Puno različitih ljudi koristi Habiticu! Više od polovice naših korisnika ima od 18 do 34 godine, ali imamo bake i djedove koji koriste stranicu sa svojim mladim unucima i sve dobi između. Često će se obitelji pridružiti grupama i zajedno se boriti protiv čudovišta. <br /> Mnogi naši korisnici imaju iskustvo u igricama, ali iznenađujuće, kada smo prije nekog vremena proveli anketu, 40% naših korisnika identificiralo se kao neigrači! Stoga se čini da naša metoda može biti učinkovita za svakoga tko želi produktivnost i dobrobit kako bi se osjećao zabavnije.",
|
||||
"pkAnswer7": "Habitica koristi pixel art iz nekoliko razloga. Osim faktora zabavne nostalgije, pixel art je vrlo pristupačna našim umjetnicima volonterima koji žele dati svoj doprinos. Mnogo je lakše održati našu pikselnu umjetnost dosljednom čak i kada puno različitih umjetnika doprinosi, a omogućuje nam brzo stvaranje tone novih sadržaj!",
|
||||
"pkAnswer6": "Puno različitih ljudi koristi Habiticu! Više od polovice naših korisnika ima od 18 do 34 godine, ali imamo bake i djedove koji koriste stranicu sa svojim mladim unucima i sve dobi između. Često će se obitelji pridružiti zabavi i zajedno se boriti protiv čudovišta. <br /> Mnogi naši korisnici imaju iskustvo u igricama, ali iznenađujuće, kada smo prije nekog vremena proveli anketu, 40% naših korisnika identificiralo se kao neigrači! Stoga se čini da naša metoda može biti učinkovita za svakoga tko želi produktivnost i dobrobit kako bi se osjećao zabavnije.",
|
||||
"pkAnswer7": "Habitica koristi pixel art iz nekoliko razloga. Osim faktora zabavne nostalgije, pikselna umjetnost je vrlo pristupačna našim umjetnicima volonterima koji žele dati svoj doprinos. Mnogo je lakše održati našu pikselnu umjetnost dosljednom čak i kada puno različitih umjetnika pridonosi, a omogućuje nam brzo stvaranje gomile novih sadržaj!",
|
||||
"invalidEmailDomain": "Ne možete se registrirati s e-poštom sa sljedećim domenama: <%= domene %>",
|
||||
"localStorageTryFirst": "Ako imate problema s Habiticom, kliknite donji gumb za brisanje lokalne pohrane i većine kolačića za ovo web mjesto (druga web mjesta neće utjecati). Morat ćete se ponovno prijaviti nakon što to učinite, pa prvo provjerite znate li svoje podatke za prijavu, koji se mogu pronaći u Postavkama -> <%= linkStart %>Site<%= linkEnd %>.",
|
||||
"usernameTOSRequirements": "Korisnička imena moraju biti u skladu s našim <a href='/static/terms' target='_blank'>Uvjetima pružanja usluge</a> i<a href='/static/community-guidelines' target='_blank'>Smjernicama zajednice< /a>. Ako prethodno niste postavili ime za prijavu, vaše korisničko ime je automatski generirano.",
|
||||
"localStorageTryFirst": "Ako imate problema s Habiticom, kliknite donji gumb za brisanje lokalne pohrane i većine kolačića za ovo web mjesto (druga web mjesta neće utjecati). Morat ćete se ponovno prijaviti nakon što to učinite, pa prvo provjerite znate li svoje podatke za prijavu, koji se mogu pronaći u Postavke -> <%= linkStart %>Site<%= linkEnd %>.",
|
||||
"usernameTOSRequirements": "Korisnička imena moraju biti u skladu s našim <a href='/static/terms' target='_blank'>Uvjetima pružanja usluge</a> i <a href='/static/community-guidelines' target='_blank'>Smjernicama zajednice< /a>. Ako prethodno niste postavili ime za prijavu, vaše korisničko ime je automatski generirano.",
|
||||
"invalidLoginCredentialsLong": "O-Ne - vaša adresa e-pošte/korisničko ime ili lozinka nisu točni.\n- Provjerite jesu li ispravno upisani. Vaše korisničko ime i lozinka razlikuju velika i mala slova.\n- Možda ste se prijavili s Facebook ili Google prijavom, a ne putem e-pošte, pa provjerite i isprobajte ih.\n- Ako ste zaboravili lozinku, kliknite na \"Zaboravljena lozinka\".",
|
||||
"accountSuspended": "Ovaj račun, korisnički ID \"<%= userId %>\", blokiran je zbog kršenja Smjernica zajednice (https://habitica.com/static/community-guidelines) ili Uvjeta pružanja usluge (https://habitica.com/ statički/termini). Za pojedinosti ili zahtjev za deblokiranje pošaljite e-poruku našem upravitelju zajednice na <%= communityManagerEmail %> ili zamolite svog roditelja ili skrbnika da im pošalje e-poruku. Uključite svoje @Username u e-poruku.",
|
||||
"accountSuspended": "Ovaj račun, ID korisnika \"<%= userId %>\", blokiran je zbog kršenja Smjernica zajednice (https://habitica.com/static/community-guidelines) ili Uvjeta pružanja usluge (https://habitica.com/ static/terms). Za pojedinosti ili zahtjev za deblokiranje, pošaljite e-poruku našem upravitelju zajednice na <%= communityManagerEmail %> ili zamolite svog roditelja ili skrbnika da im pošalje e-poruku. Uključite svoje @Username u e-poruku.",
|
||||
"invalidReqParams": "Nevažeći parametri zahtjeva.",
|
||||
"usernameLimitations": "Korisničko ime mora imati od 1 do 20 znakova, samo slova od a do z, brojeve od 0 do 9, crtice ili podvlake i ne smije sadržavati neprikladne pojmove.",
|
||||
"healthAndFitnessDesc": "Nikad niste bili motivirani za čišćenje zubnim koncem? Čini se da ne možete doći u teretanu? Habitica napokon čini put ka zdravlju zabavnijim.",
|
||||
"healthAndFitnessDesc": "Nikad niste bili motivirani za čišćenje zubnim koncem? Čini se da ne možete doći u teretanu? Habitica napokon čini zabavnim ozdravljenje.",
|
||||
"muchmuchMoreDesc": "Naš potpuno prilagodljivi popis zadataka znači da možete oblikovati Habiticu kako bi odgovarala vašim osobnim ciljevima. Radite na kreativnim projektima, naglašavajte brigu o sebi ili slijedite drugačiji san -- sve ovisi o vama.",
|
||||
"learnMore": "Saznajte više",
|
||||
"learnMore": "Saznaj Više",
|
||||
"pkMoreQuestions": "Imate li pitanje koje nije na ovom popisu? Pošaljite e-mail na admin@habitica.com!",
|
||||
"usernameInfo": "Imena za prijavu sada su jedinstvena korisnička imena koja će biti vidljiva pored vašeg imena za prikaz i koristit će se za pozivnice, @spominjanja u chatu i slanje poruka.<br><br>Ako želite saznati više o ovoj promjeni, <a href='https ://habitica.fandom.com/wiki/Player_Names' target='_blank'>posjetite naš wiki</a>.",
|
||||
"privacy": "Politika privatnosti",
|
||||
"mobileApps": "Mobilne aplikacije",
|
||||
"mobileApps": "Mobilne Aplikacije",
|
||||
"newEmailRequired": "Nedostaje nova adresa e-pošte.",
|
||||
"signup": "Registriraj se",
|
||||
"signup": "Prijavite se",
|
||||
"emailUsernamePlaceholder": "npr. habitrabbit ili gryphon@example.com",
|
||||
"aboutHabitica": "Habitica je besplatna aplikacija za stjecanje navika i produktivnost koja vaš stvarni život tretira kao igru. S nagradama i kaznama u igri da vas motiviraju i snažnom društvenom mrežom da vas inspirira, Habitica vam može pomoći da postignete svoje ciljeve da postanete zdravi, marljivi i sretni.",
|
||||
"translateHabitica": "Prevedi Habiticu"
|
||||
"aboutHabitica": "Habitica je besplatna aplikacija za stjecanje navika i produktivnost koja vaš stvarni život tretira kao igru. S nagradama i kaznama unutar igre koje vas motiviraju i snažnom društvenom mrežom koja vas inspirira, Habitica vam može pomoći da postignete svoje ciljeve da postanete zdravi, vrijedni i sretni.",
|
||||
"translateHabitica": "Prevedi Habiticu",
|
||||
"footerCompany": "Društvo",
|
||||
"presskit": "Stisnite Kit",
|
||||
"guidanceForBlacksmiths": "Vodič za \"kovače\""
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"groupBy": "Grupiraj po <%= type %>",
|
||||
"classBonus": "(Ovaj predmet odgovara tvojoj klasi pa se zato njegova Statistika množi s 1.5.)",
|
||||
"classArmor": "Oklop klase",
|
||||
"featuredset": "Istaknuti komplet <%= name %>",
|
||||
"featuredset": "Istaknuti Set: <%= name %>",
|
||||
"mysterySets": "Tajni kompleti",
|
||||
"gearNotOwned": "Ne posjeduješ ovaj artikal.",
|
||||
"noGearItemsOfType": "Ne posjeduješ nijednog od ovih.",
|
||||
|
||||
@@ -195,5 +195,6 @@
|
||||
"selected": "Odabrano",
|
||||
"howManyToBuy": "Koliko bi ih htio/la kupiti?",
|
||||
"contactForm": "Kontaktiraj tim Moderatora",
|
||||
"finish": "Završi"
|
||||
"finish": "Završi",
|
||||
"options": "Opcije"
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
"seasonalShopClosedTitle": "<%= linkStart %>Leslie<%= linkEnd %>",
|
||||
"seasonalShopTitle": "<%= linkStart %>Sezonska Čarobnica<%= linkEnd %>",
|
||||
"seasonalShopClosedText": "Sezonski dućan je trenutno zatvoren!! Otvoren je samo tijekom Habitičinih četiriju Velikih gala.",
|
||||
"seasonalShopSummerText": "Sretno ljetno bal!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gala!",
|
||||
"seasonalShopSummerText": "Sretno ljetno prskanje!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gala!",
|
||||
"seasonalShopFallText": "Sretan jesenski festival!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gale!",
|
||||
"seasonalShopWinterText": "Sretna zimska zemlja čuda!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gale!",
|
||||
"seasonalShopSpringText": "Sretna proljetna zabava!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gale!",
|
||||
"seasonalShopSpringText": "Sretna proljetna veza!! Želite li kupiti neke rijetke predmete? Obavezno ih nabavite prije završetka Gale!",
|
||||
"seasonalShopFallTextBroken": "Oh.... Dobrodošao/la u Sezonski dućan... Trenutno skupljamo zalihe raznoraznih dobara jesenskog sezonskog izdanja ... Sve što se nalazi ovdje će biti dostupno za kupnju tijekom Jesenskog festivala svake godine, ali smo otvoreni samo do 31. listopada... Trebao/la bi se sada opremiti ili ćeš trebati čekati... i čekati... i čekati... <strong>*uzdah*</strong>",
|
||||
"seasonalShopBrokenText": "Moj paviljon!!!!!!! Moji ukrasi!!!! Joj, Demoralizator je sve uništio :( Molim te, pomozi ga poraziti u Krčmi tako da mogu započeti obnovu!",
|
||||
"seasonalShopRebirth": "Ako si kupio/la išta ove opreme u prošlosti, ali je trenutno ne posjeduješ, možeš je ponovno kupiti u stupcu Nagrada. U početku ćeš moći samo kupovati artikle za tvoju trenutnu klasu (Ratnik prema zadanim postavkama), ali bez brige, drugi artikli specifični za određenu klasu će postati dostupni ako se prebaciš u tu klasu.",
|
||||
@@ -74,51 +74,51 @@
|
||||
"magicianBunnySet": "Mađioničarev kunić (Čarobnjak)",
|
||||
"comfortingKittySet": "Utješna maca (Iscjelitelj)",
|
||||
"sneakySqueakerSet": "Skriveni cikavac (Lupež)",
|
||||
"sunfishWarriorSet": "Bucanjski (Ratnik)",
|
||||
"sunfishWarriorSet": "Sunčanica (Ratnik)",
|
||||
"shipSoothsayerSet": "Brodski prorok (Čarobnjak)",
|
||||
"strappingSailorSet": "Kršni moreplovac (Iscjelitelj)",
|
||||
"reefRenegadeSet": "Grebenski odmetnik (Lupež)",
|
||||
"scarecrowWarriorSet": "Strašilo (Ratnik)",
|
||||
"stitchWitchSet": "Vještica-vezica (Čarobnjak)",
|
||||
"potionerSet": "Izrađivač napitaka (Iscjelitelj)",
|
||||
"battleRogueSet": "Rat-tni (Lupež)",
|
||||
"battleRogueSet": "Bat-le (Lupež)",
|
||||
"springingBunnySet": "Skakutavi kunić (Iscjelitelj)",
|
||||
"grandMalkinSet": "Veličanstveno strašilo (Čarobnjak)",
|
||||
"cleverDogSet": "Pametan pas (Lupež)",
|
||||
"braveMouseSet": "Hrabri miš (Ratnik)",
|
||||
"summer2016SharkWarriorSet": "Morski Pas (Ratnik)",
|
||||
"summer2016SharkWarriorSet": "morski pas (ratnik)",
|
||||
"summer2016DolphinMageSet": "Dupin (Čarobnjak)",
|
||||
"summer2016SeahorseHealerSet": "Morski konjić (iscjelitelj)",
|
||||
"summer2016SeahorseHealerSet": "Morski konjić (Iscjelitelj)",
|
||||
"summer2016EelSet": "Jegulja (Lupež)",
|
||||
"fall2016SwampThingSet": "Močvarno biće (Ratnik)",
|
||||
"fall2016WickedSorcererSet": "Opaki vještac (Čarobnjak)",
|
||||
"fall2016GorgonHealerSet": "Gorgona (iscjelitelj)",
|
||||
"fall2016GorgonHealerSet": "Gorgona (Iscjelitelj)",
|
||||
"fall2016BlackWidowSet": "Crna Udovica (Lupež)",
|
||||
"winter2017IceHockeySet": "Hokej na ledu (Ratnik)",
|
||||
"winter2017WinterWolfSet": "Zimski vuk (Čarobnjak)",
|
||||
"winter2017SugarPlumSet": "Šećerna Vila (Iscjeljitelj)",
|
||||
"winter2017FrostyRogueSet": "Ledenko (Lupež)",
|
||||
"winter2017SugarPlumSet": "Šećerna Vila (Iscjelitelj)",
|
||||
"winter2017FrostyRogueSet": "Ledeni (Lupež)",
|
||||
"spring2017FelineWarriorSet": "Mačor (Ratnik)",
|
||||
"spring2017CanineConjurorSet": "Pseći prizivač (Čarobnjak)",
|
||||
"spring2017FloralMouseSet": "Cvijetni miš (Iscjelitelj)",
|
||||
"spring2017SneakyBunnySet": "Skriveni kunić (Lupež)",
|
||||
"summer2017SandcastleWarriorSet": "Pješćani Dvorac (Ratnik)",
|
||||
"summer2017SandcastleWarriorSet": "Dvorac od pijeska (Ratnik)",
|
||||
"summer2017WhirlpoolMageSet": "Vrtlog (Čarobnjak)",
|
||||
"summer2017SeashellSeahealerSet": "Školjkaški morski iscjelitelj (Iscjelitelj)",
|
||||
"summer2017SeaDragonSet": "Morski zmaj (Lupež)",
|
||||
"fall2017HabitoweenSet": "Habitoween (Ratnik)",
|
||||
"fall2017MasqueradeSet": "Maskembal (Čarobnjak)",
|
||||
"fall2017HauntedHouseSet": "Ukleta Kuća (Iscjeljitelj)",
|
||||
"fall2017HauntedHouseSet": "Ukleta Kuća (Iscjeljivatelj)",
|
||||
"fall2017TrickOrTreatSet": "Trik ili Poslastica (Lupež)",
|
||||
"winter2018ConfettiSet": "Konfeti (Čarobnjak)",
|
||||
"winter2018GiftWrappedSet": "Ukrasni Omotač (Ratnik)",
|
||||
"winter2018MistletoeSet": "Imela (Iscjeljitelj)",
|
||||
"winter2018GiftWrappedSet": "Zamotani Dar (Ratnik)",
|
||||
"winter2018MistletoeSet": "Imela (Iscjeljivatelj)",
|
||||
"winter2018ReindeerSet": "Sob (Lupež)",
|
||||
"spring2018SunriseWarriorSet": "Izlazak Sunca (Ratnik)",
|
||||
"spring2018TulipMageSet": "Tulipan (Čarobnjak)",
|
||||
"spring2018GarnetHealerSet": "Granat (Iscjeljitelj)",
|
||||
"spring2018GarnetHealerSet": "Granat (Iscjeljivatelj)",
|
||||
"spring2018DucklingRogueSet": "Pačić (Lupež)",
|
||||
"summer2018BettaFishWarriorSet": "Sijamska riba (Ratnik)",
|
||||
"summer2018BettaFishWarriorSet": "Betta Riba (Borac)",
|
||||
"summer2018LionfishMageSet": "Morski Lav (Čarobnjak)",
|
||||
"summer2018MerfolkMonarchSet": "Vladar sirena (Iscjelitelj)",
|
||||
"summer2018FisherRogueSet": "Lupeški ribar (Lupež)",
|
||||
@@ -130,33 +130,33 @@
|
||||
"winter2019PyrotechnicSet": "Pirotehničar (Čarobnjak)",
|
||||
"winter2019WinterStarSet": "Zimska zvijezda (Iscjelitelj)",
|
||||
"winter2019PoinsettiaSet": "Božićna zvijezda (Lupež)",
|
||||
"winterPromoGiftHeader": "POKLONITE PRETPLATU, DOBIJETE JEDNU BESPLATNO!!",
|
||||
"winterPromoGiftHeader": "POKLONITE PRETPLATU, DOBIJETE JEDNU BESPLATNO!",
|
||||
"winterPromoGiftDetails1": "Samo do 6. siječnja, kada nekome poklonite pretplatu, istu pretplatu dobivate besplatno!",
|
||||
"winterPromoGiftDetails2": "Molimo te da imaš na umu da će poklonjena pretplata, u slučaju da ti ili primatelj dara već imate ponavljajuću pretplatu, početi tek nakon što je prva pretplata otkazana ili istekne. Hvala puno na podršci! <3",
|
||||
"discountBundle": "paket",
|
||||
"g1g1Announcement": "<strong>Poklonite pretplatu i ostvarite besplatnu pretplatu</strong> događaj koji je upravo u tijeku!",
|
||||
"g1g1Announcement": "<strong>Poklonite pretplatu i ostvarite besplatnu pretplatu</strong> događaj koji je u tijeku!",
|
||||
"g1g1Details": "Poklonite pretplatu prijatelju i dobit ćete istu pretplatu besplatno!",
|
||||
"g1g1": "Pokloni jedan, dobij jedan",
|
||||
"g1g1": "Pokloni jedan, dobi jedan",
|
||||
"spring2019OrchidWarriorSet": "Orhideja (Ratnik)",
|
||||
"spring2019AmberMageSet": "Jantar (Čarobnjak)",
|
||||
"spring2019RobinHealerSet": "Crvendać (Iscjeljitelj)",
|
||||
"spring2019RobinHealerSet": "Crvendać (Iscjeljivatelj)",
|
||||
"spring2019CloudRogueSet": "Oblak (Lupež)",
|
||||
"summer2019SeaTurtleWarriorSet": "Morska Kornjača (Ratnik)",
|
||||
"summer2019WaterLilyMageSet": "Lopoč (Čarobnjak)",
|
||||
"summer2019ConchHealerSet": "Školjka (Iscjeljitelj)",
|
||||
"summer2019ConchHealerSet": "Školjka (Iscjeljivatelj)",
|
||||
"fall2019CyclopsSet": "Kiklop (Čarobnjak)",
|
||||
"fall2019LichSet": "Pijavica (Čarobnjak)",
|
||||
"fall2019LichSet": "Pijavica (Iscjeljivatelj)",
|
||||
"fall2019RavenSet": "Gavran (Ratnik)",
|
||||
"winter2020EvergreenSet": "Zimzelen (Ratnik)",
|
||||
"winter2020EvergreenSet": "Zimzeleni (Ratnik)",
|
||||
"winter2020CarolOfTheMageSet": "Pjesma Čarobnjaka (Čarobnjak)",
|
||||
"winter2020WinterSpiceSet": "Zimski Začini (Iscjeljitelj)",
|
||||
"winter2020WinterSpiceSet": "Zimski Začin (Iscjeljivatelj)",
|
||||
"winter2020LanternSet": "Lampa (Lupež)",
|
||||
"spring2020BeetleWarriorSet": "Kornjaš Nosorog (Ratnik)",
|
||||
"spring2020BeetleWarriorSet": "Nosorog Kornjaš (Ratnik)",
|
||||
"spring2020PuddleMageSet": "Lokva (Čarobnjak)",
|
||||
"spring2020IrisHealerSet": "Zjenica (Isjeljitelj)",
|
||||
"spring2020IrisHealerSet": "Zjena (Iscjeljitelj)",
|
||||
"summer2020RainbowTroutWarriorSet": "Dugina Pastrva (Ratnik)",
|
||||
"summer2020OarfishMageSet": "Riba Veslo (Čarobnjak)",
|
||||
"summer2020SeaGlassHealerSet": "Morska Trava (Iscjeljitelj)",
|
||||
"summer2020SeaGlassHealerSet": "Morsko Staklo (Iscjeljitelj)",
|
||||
"summer2020CrocodileRogueSet": "Krokodil (Lupež)",
|
||||
"fall2020WraithWarriorSet": "Utvara (Ratnik)",
|
||||
"fall2020DeathsHeadMothHealerSet": "Mrtvački Moljac (Iscjeljitelj)",
|
||||
@@ -166,17 +166,17 @@
|
||||
"spring2021WillowHealerSet": "Vrba (Iscjeljitelj)",
|
||||
"summer2021FlyingFishWarriorSet": "Leteća Riba (Ratnik)",
|
||||
"summer2021NautilusMageSet": "Nautilus (Čarobnjak)",
|
||||
"summer2021ParrotHealerSet": "Papagaj (Iscjeljitelj)",
|
||||
"summer2021ParrotHealerSet": "Papagaj (Iscjelitelj)",
|
||||
"summer2021ClownfishRogueSet": "Riba Klaun (Lupež)",
|
||||
"spring2023CaterpillarRogueSet": "Gusjenica (Lupež)",
|
||||
"g1g1Limitations": "Ovo je vremenski ograničen događaj koji počinje 15. prosinca u 8:00 ET (13:00 UTC) i završit će 8. siječnja u 23:59 ET (9. siječnja 04:59 UTC). Ova promocija vrijedi samo kada darujete drugom Habitičanu. Ako vi ili vaš primatelj dara već imate pretplatu, poklonjena pretplata će dodati mjesece kredita koji će se koristiti tek nakon što se trenutna pretplata otkaže ili istekne.",
|
||||
"g1g1Limitations": "Ovo je vremenski ograničen događaj koji počinje 15. prosinca u 8:00 ET (13:00 UTC) i završit će 8. siječnja u 23:59 ET (9. siječnja 04:59 UTC). Ova promocija vrijedi samo kada darujete drugom Habiticu. Ako vi ili vaš primatelj dara već imate pretplatu, poklonjena pretplata će dodati mjesece kredita koji će se koristiti tek nakon što se trenutna pretplata otkaže ili istekne.",
|
||||
"anniversaryLimitations": "Ovo je vremenski ograničen događaj koji počinje 30. siječnja u 8:00 ET (13:00 UTC) i završit će 8. veljače u 23:59 ET (04:59 UTC). Ograničeno izdanje Jubilant Gryphatrice i deset čarobnih napitaka za izleganje bit će dostupni za kupnju tijekom tog vremena. Ostali darovi navedeni u odjeljku Četiri besplatno bit će automatski isporučeni na sve račune koji su bili aktivni 30 dana prije dana slanja dara. Računi stvoreni nakon slanja darova neće ih moći preuzeti.",
|
||||
"winter2023WalrusWarriorSet": "Morž (Ratnik)",
|
||||
"winter2023FairyLightsMageSet": "Vilinska Svjetla (Čarobnjak)",
|
||||
"winter2023CardinalHealerSet": "Kardinal (Iscjeljitelj)",
|
||||
"winter2023FairyLightsMageSet": "Vilinska svjetla (Čarobnjak)",
|
||||
"winter2023CardinalHealerSet": "Kardinal (Iscjelitelj)",
|
||||
"gemSaleHow": "Između <%= eventStartMonth %> <%= eventStartOrdinal %> i <%= eventEndOrdinal %>, jednostavno kupite bilo koji paket dragulja kao i obično i vašem će računu biti dodijeljen promotivni iznos dragulja. Više dragulja za potrošiti, podijeliti ili spremiti za buduća izdanja!",
|
||||
"spring2023HummingbirdWarriorSet": "Kolibrić (Ratnik)",
|
||||
"spring2023LilyHealerSet": "Ljiljan (Iscjeljitelj)",
|
||||
"spring2023LilyHealerSet": "Ljiljan (Iscjelitelj)",
|
||||
"celebrateBirthday": "Proslavite 10. rođendan Habitice uz darove i ekskluzivne artikle!",
|
||||
"jubilantGryphatricePromo": "Animirani ljubimac Gryphatrice",
|
||||
"anniversaryGryphatriceText": "Rijetki Jubilant Gryphatrice pridružuje se proslavi rođendana! Ne propustite priliku posjedovati ovog ekskluzivnog animiranog ljubimca.",
|
||||
@@ -185,22 +185,22 @@
|
||||
"buyNowGemsButton": "Kupite sada za 60 dragulja",
|
||||
"takeMeToStable": "Odvedi me u štalu",
|
||||
"plentyOfPotions": "Hrpa Napitaka",
|
||||
"fourForFreeText": "Kako bismo održali zabavu, dijelit ćemo ogrtače za zabavu, 20 dragulja i ograničeno izdanje rođendanske pozadine i kompleta predmeta koji uključuje ogrtač, navlake i masku za oči.",
|
||||
"fourForFreeText": "Kako bismo održali zabavu, podijelit ćemo ogrtače za zabavu, 20 dragulja i ograničeno izdanje rođendanske pozadine i kompleta predmeta koji uključuje ogrtač, navlake i masku za oči.",
|
||||
"visitTheMarketButton": "Posjetite tržnicu",
|
||||
"plentyOfPotionsText": "Vraćamo od zajednice 10 omiljenih Magičnih Napitaka za izljeganje. Posjetite tržnicu i popunite svoju kolekciju!",
|
||||
"fourForFree": "Četiri besplatno",
|
||||
"plentyOfPotionsText": "Vraćamo 10 omiljenih napitaka Magic Hatching zajednice. Posjetite The Market i popunite svoju kolekciju!",
|
||||
"fourForFree": "Četiri besplatno (maybe Četri za jedan besplatan)",
|
||||
"dayOne": "Dan 1",
|
||||
"dayFive": "Dan 5",
|
||||
"dayTen": "Dan 10",
|
||||
"partyRobes": "Ogrtači za zabave",
|
||||
"twentyGems": "20 Dragulja",
|
||||
"birthdaySet": "Rođendanski set",
|
||||
"fall2020TwoHeadedRogueSet": "DvoGlavi (Lupež)",
|
||||
"fall2020TwoHeadedRogueSet": "Dvije-Glave (Lupež) - [maybe Dvoglavi?]",
|
||||
"fall2020ThirdEyeMageSet": "Treće Oko (Čarobnjak)",
|
||||
"spring2021TwinFlowerRogueSet": "Cvijet Blizanac (Lupež)",
|
||||
"winter2021HollyIvyRogueSet": "Božikovina i Bršljan (Lupež)",
|
||||
"winter2021ArcticExplorerHealerSet": "Artički Istraživač (Iscjeljitelj)",
|
||||
"summer2019HammerheadRogueSet": "Morski Pas Čekić (Lupež)",
|
||||
"winter2021HollyIvyRogueSet": "Božićnjak i Bršljan (Lupež)",
|
||||
"winter2021ArcticExplorerHealerSet": "Istraživač Arktika (iscjelitelj)",
|
||||
"summer2019HammerheadRogueSet": "Morski Pas Čekićar (Lupež)",
|
||||
"spring2020LapisLazuliRogueSet": "Lapis Lazulij (Lupež)",
|
||||
"fall2019OperaticSpecterSet": "Operni Spektar (Lupež)",
|
||||
"anniversaryLimitedDates": "30. siječnja do 8. veljače",
|
||||
@@ -213,28 +213,28 @@
|
||||
"jubilantSuccess": "Uspješno ste kupili <strong>Jubilant Gryphatrice!</strong>",
|
||||
"stableVisit": "Posjetite štalu za opremanje!",
|
||||
"spring2022MagpieRogueSet": "Svraka (Lupež)",
|
||||
"spring2022RainstormWarriorSet": "Kišna Oluja (Ratnik)",
|
||||
"spring2022RainstormWarriorSet": "Kišna oluja (Ratnik)",
|
||||
"spring2022ForsythiaMageSet": "Forzicija (Čarobnjak)",
|
||||
"g1g1Returning": "U čast sezone, vraćamo vrlo posebnu promociju. Sada kada poklonite pretplatu, dobit ćete istu zauzvrat!",
|
||||
"summer2022CrabRogueSet": "Rak (Lupež)",
|
||||
"summer2022WaterspoutWarriorSet": "Vodena Pljuska (Ratnik)",
|
||||
"summer2022MantaRayMageSet": "Raž (Čarobnjak)",
|
||||
"g1g1Event": "U tijeku je događaj Pokloni jedan, donij jedan!",
|
||||
"summer2022WaterspoutWarriorSet": "Vodena pljuska (Ratnik)",
|
||||
"summer2022MantaRayMageSet": "Raža (Čarobnjak)",
|
||||
"g1g1Event": "U tijeku je događaj Pokloni jedan, Dobi jedan!",
|
||||
"howItWorks": "Kako radi",
|
||||
"royalPurpleJackolantern": "Kraljevski ljubičasti Jack-O-Lantern",
|
||||
"fall2022WatcherHealerSet": "Pogledač (Iscjeljitelj)",
|
||||
"fall2022OrcWarriorSet": "Ork (Ratnik)",
|
||||
"fall2022HarpyMageSet": "Harpa (Čarobnjak)",
|
||||
"fall2021OozeRogueSet": "Iscjedak (Lupež)",
|
||||
"fall2021HeadlessWarriorSet": "Bez glave (Ratnik)",
|
||||
"fall2021BrainEaterMageSet": "Gutač Mozga (Čarobnjak)",
|
||||
"fall2021FlameSummonerHealerSet": "Prizivač Vatre (Iscjeljitelj)",
|
||||
"fall2021HeadlessWarriorSet": "Bezglavi (Ratnik)",
|
||||
"fall2021BrainEaterMageSet": "Žderač mozga (Čarobnjak)",
|
||||
"fall2021FlameSummonerHealerSet": "Prizivač plamena (Iscjelitelj)",
|
||||
"winter2022FireworksRogueSet": "Vatromet (Lupež)",
|
||||
"winter2022StockingWarriorSet": "Čarapa (Ratnik)",
|
||||
"winter2022PomegranateMageSet": "Nar (Čarobnjak)",
|
||||
"winter2022IceCrystalHealerSet": "Ledeni Kristal (Iscjeljitelj)",
|
||||
"winter2022IceCrystalHealerSet": "Ledeni kristal (Iscjelitelj)",
|
||||
"limitations": "Ograničenja",
|
||||
"g1g1HowItWorks": "Upišite korisničko ime računa kojem želite darovati. Odatle odaberite duljinu podnožja koju želite pokloniti i nastavite sa isplatom. Vaš će račun automatski biti nagrađen istom razinom pretplate koju ste upravo darovali.",
|
||||
"g1g1HowItWorks": "Upišite korisničko ime računa kojem želite darovati. Odatle odaberite duljinu koju želite pokloniti i završite kupnju. Vaš će račun automatski biti nagrađen istom razinom pretplate koju ste upravo darovali.",
|
||||
"noLongerAvailable": "Ova stavka više nije dostupna.",
|
||||
"winter2023RibbonRogueSet": "Vrpca (Lupež)",
|
||||
"spring2023MoonstoneMageSet": "Mjesečev Kamen (Čarobnjak)",
|
||||
|
||||
@@ -38,18 +38,18 @@
|
||||
"magicalBee": "Čarobna pčela",
|
||||
"hatchingPotions": "Napitci za izlijeganje",
|
||||
"royalPurpleJackalope": "Plemeti ljubičasti rogati zec",
|
||||
"magicHatchingPotions": "Čarobni napitci za izlijeganje",
|
||||
"magicHatchingPotions": "Čarobni napici za izlijeganje",
|
||||
"hatchingPotion": "napitak za izlijeganje",
|
||||
"haveHatchablePet": "Imaš %= potion %> napitak za izlijeganje i <%= egg %> jaje da izležeš ovog ljubimca! <b>Klikni</b> da izležeš!",
|
||||
"quickInventory": "Brzi Inventar",
|
||||
"noFoodAvailable": "Trenutno nemaš hrane za ljubimce.",
|
||||
"dropsExplanation": "Dobij ove predmete brže s Draguljima ako ne želiš čekati da ih zaradiš izvršavanjem zadataka. <a href=\"https://habitica.fandom.com/wiki/Drops\">Nauči više o sustavu nagrada.</a>",
|
||||
"hatchedPetHowToUse": "Posjeti [Štalu](<%= stableUrl %>) da nahraniš i vodiš svojeg najnovijeg ljubimca!",
|
||||
"mountNotOwned": "Nemaš ovu jahaču životinju.",
|
||||
"mountNotOwned": "Nemaš ovu jahaću životinju.",
|
||||
"mountMasterName": "Gospodar Jahačih Životinja",
|
||||
"triadBingoName": "Trostruki Bingo",
|
||||
"triadBingoText2": " i oslobodio/la je punu štalu <%= count %> put/a",
|
||||
"hatchedPetGeneric": "Izlegao/la si novog ljubimca!",
|
||||
"hatchedPetGeneric": "Izlegao ti se novi ljubimac!",
|
||||
"beastMasterText2": " i oslobodio/la je svoje ljubimce <%= count %> put/a",
|
||||
"petNotOwned": "Nemaš ovog ljubimca.",
|
||||
"beastAchievement": "Zaslužio/la si postignuće \"Gospodar Zvijeri\" za skupljanje svih ljubimaca!",
|
||||
@@ -58,12 +58,55 @@
|
||||
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
|
||||
"mountName": "<%= potion(locale) %> <%= mount(locale) %>",
|
||||
"beastMasterProgress": "Napredak Gospodara Zvijeri",
|
||||
"beastMasterText": "Pronašao/la je svih 90 ljubimaca (nevjerojatno teško, čestitaj ovom/oj korisniku/ci!)",
|
||||
"beastMasterText": "Ova osoba pronašla je svih 90 ljubimaca (a to je jako teško, čestitajte joj)",
|
||||
"mountAchievement": "Zaslužio/la si postignuće \"Gospodar Jahačih Životinja\" za pripitomljivanje svih jahačih životinja!",
|
||||
"mountMasterText2": " i oslobodio/la je svih svojih 90 jahačih životinja <%= count %> put/a",
|
||||
"mountMasterText": "Pripitomio/la je svih 90 jahačih životinja (još teže, čestitaj ovom/oj korisniku/ci!)",
|
||||
"triadBingoText": "Pronašao/la je svih 90 ljubimaca, svih 90 jahačih životinja, i PONOVO pronašao/la svih 90 ljubimaca (KAKO TI JE TO USPJELO!)",
|
||||
"mountMasterText": "Ova je osoba pripitomila svih 90 jahaćih životinja (što je još teže i zaslužuje pohvalu)",
|
||||
"triadBingoText": "Ova je osoba pronašla svih 90 ljubimaca, svih 90 jahaćih životinja i svih 90 ljubimaca, po DRUGI PUT (KAKO TI JE TO UOPĆE USPJELO!?)",
|
||||
"triadBingoAchievement": "Zaslužio/la si postignuće \"Trostruki Bingo\" za pronalazak svih ljubimaca, pripitomljivanja svih jahačih životinja, i ponovni pronalazak svih ljubimaca!",
|
||||
"hatchedPet": "Izlegao/la si novo <%= potion %> <%= egg%>!",
|
||||
"feedPet": "Nahrani <%= text %> svojem/oj <%= name %>?"
|
||||
"feedPet": "Nahrani <%= text %> svojem/oj <%= name %>?",
|
||||
"mountsAndPetsReleased": "Oslobođeni životinje za jahanje i kućni ljubimci",
|
||||
"mountsReleased": "Životinje za jahanje puštene",
|
||||
"keyToPetsDesc": "Oslobodite sve standardne ljubimce kako biste ih mogli ponovno pokupiti. (Kustovi ljubimci i rijetki ljubimci nisu pogođeni.)",
|
||||
"raisedPet": "Uzgojili ste svog <%= ljubimca %>!",
|
||||
"premiumPotionNoDropExplanation": "Čarobni napitci za izleganje ne mogu se koristiti na jajima dobivenim iz zadataka. Jedini način da dobijete Čarobne napitke za izleganje je kupnjom ispod, a ne iz nasumičnih padavina.",
|
||||
"keyToBoth": "Glavni ključevi odgajivačnica",
|
||||
"releasePetsConfirm": "Jeste li sigurni da želite pustiti svoje standardne ljubimce?",
|
||||
"keyToMountsDesc": "Otpustite sve standardne životinje za jahanje kako biste ih mogli ponovno pokupiti. (Ne utječe na životinje za jahanje misije i rijetke nosače.)",
|
||||
"releaseBothSuccess": "Vaši standardni ljubimci i životinje za jahanje su pušteni!",
|
||||
"releaseBothConfirm": "Jeste li sigurni da želite pustiti svoje standardne ljubimce i životinje za jahanje?",
|
||||
"petsReleased": "Kućni ljubimci pušteni.",
|
||||
"releasePetsSuccess": "Vaši standardni ljubimci su pušteni!",
|
||||
"keyToBothDesc": "Otpustite sve standardne kućne ljubimce i životinje za jahanje kako biste ih mogli ponovno pokupiti. (Kustovi ljubimci/jahaći i rijetki ljubimci/jahaći nisu pogođeni.)",
|
||||
"keyToMounts": "Ključ od životinje za jahanje Kennels",
|
||||
"releaseMountsConfirm": "Jeste li sigurni da želite pustiti svoje standardne nosače?",
|
||||
"releaseMountsSuccess": "Vaši standardni nosači su pušteni!",
|
||||
"keyToPets": "Ključ uzgajivačnice kućnih ljubimaca",
|
||||
"dropsExplanationEggs": "Potrošite dragulje da biste brže dobili jaja, ako ne želite čekati da ispadnu standardna jaja ili ponavljati misije da zaradite misija jaja. <a href=\"https://habitica.fandom.com/wiki/Drops\">Saznajte više o sustavu pada.</a>",
|
||||
"welcomeStable": "Dobrodošli u Štalu!",
|
||||
"notEnoughPets": "Niste prikupili dovoljno ljubimaca",
|
||||
"sortByColor": "Boja",
|
||||
"filterByMagicPotion": "Čarobni napitak",
|
||||
"sortByHatchable": "Izlegujuće",
|
||||
"notEnoughFood": "Nemate dovoljno hrane",
|
||||
"hatch": "Izlegni!",
|
||||
"filterByStandard": "Standardni",
|
||||
"foodTitle": "Hrana za kućne ljubimce",
|
||||
"petLikeToEat": "Što moj ljubimac voli jesti?",
|
||||
"filterByWacky": "Ćaknut",
|
||||
"standard": "Standard",
|
||||
"clickOnPetToFeed": "Kliknite na ljubimca za hranjenje <%= foodName %> i gledajte kako raste!",
|
||||
"clickOnEggToHatch": "Kliknite na jaje da biste upotrijebili svoj <%= potionName %> napitak za izleganje i izlegli novog ljubimca!",
|
||||
"invalidAmount": "Nevažeća količina hrane, mora biti pozitivan cijeli broj",
|
||||
"dragThisFood": "Povucite ovo <%= foodName %> na ljubimca i gledajte kako raste!",
|
||||
"notEnoughMounts": "Niste sakupili dovoljno životinja za jahanje",
|
||||
"tooMuchFood": "Pokušavate svom ljubimcu dati previše hrane, akcija je otkazana",
|
||||
"filterByQuest": "Potraga (maybe Zadatak)",
|
||||
"dragThisPotion": "Povucite ovaj <%= potionName %> u jaje i izležite novog ljubimca!",
|
||||
"hatchDialogText": "Izlijte svoj <%= potionName %> napitak za izleganje na svoje <%= eggName %> jaje i ono će se izleći u <%= petName %>.",
|
||||
"notEnoughPetsMounts": "Niste sakupili dovoljno ljubimaca i životinja za jahanje",
|
||||
"clickOnPotionToHatch": "Kliknite na napitak za izleganje da biste ga upotrijebili na svom <%= eggName %> i izlegli novog ljubimca!",
|
||||
"petLikeToEatText": "Kućni ljubimci će rasti bez obzira čime ih hranite, ali će rasti brže ako ih hranite onom hranom za kućne ljubimce koju najviše vole. Eksperimentirajte kako biste otkrili uzorak ili pogledajte odgovore ovdje: <br/> <a href=\"https://habitica.fandom.com/wiki/Food_Preferences\" target=\"_blank\">https://habitica.fandom. com/wiki/Food_Preferences</a>",
|
||||
"welcomeStableText": "Dobrodošli u Štalu! Ja sam Matt, gospodar zvijeri. Svaki put kada izvršite zadatak, imat ćete slučajnu priliku da dobijete jaje ili napitak za izleganje kućnih ljubimaca. Kada izležete ljubimca, pojavit će se ovdje! Pritisnite sliku kućnog ljubimca da biste je dodali svom Avataru. Nahranite ih hranom za kućne ljubimce koju pronađete i oni će izrasti u izdržljive životinje za jahanje."
|
||||
}
|
||||
|
||||
@@ -155,5 +155,8 @@
|
||||
"usernameVerifiedConfirmation": "Tvoje korisničko ime, <%= username %>, je potvrđeno!",
|
||||
"usernameNotVerified": "Molimo te da potvrdiš svoje korisničko ime.",
|
||||
"changeUsernameDisclaimer": "Uskoro ćemo se prebaciti s korištenja imena za prijavu na jedinstvena, javna korisnička imena. Ovo korisničko ime će se koristiti za pozivnice, @spomene u chatu i u porukama.",
|
||||
"verifyUsernameVeteranPet": "Jedan od ovih veteranskih ljubimaca će te čekati nakon što potvrdiš!"
|
||||
"verifyUsernameVeteranPet": "Jedan od ovih veteranskih ljubimaca će te čekati nakon što potvrdiš!",
|
||||
"generalSettings": "Opće postavke",
|
||||
"siteData": "Podaci s web mjesta",
|
||||
"taskSettings": "Postavke zadatka"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"spellWizardFireballText": "Prasak Plamena",
|
||||
"spellWizardFireballNotes": "Sakupljaš XP i zadaješ vatrenu štetu Bosovima! (Na osnovi: INT)",
|
||||
"spellWizardMPHealText": "Eterični udar",
|
||||
"spellWizardFireballNotes": "Sakupljaš XP i zadaješ vatrenu štetu Bosovima! (Temeljeno na: INT)",
|
||||
"spellWizardMPHealText": "Eterski Nalet",
|
||||
"spellWizardMPHealNotes": "Žrtvuješ Manu kako bi ostatak tvoje Družine izuzev Čarobnjaka, dobio bodove Mane! (Na osnovi: INT)",
|
||||
"spellWizardEarthText": "Potres",
|
||||
"spellWizardEarthNotes": "Tvoja mentalna moć potresa tlo i jača Inteligenciju tvoje Družine! (Na osnovi: neojačane INT)",
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
"subscription": "Pretplata",
|
||||
"subscriptions": "Pretplate",
|
||||
"sendGems": "Pošalji Dragulje",
|
||||
"buyGemsGold": "Kupi Dragulje Zlatnicima",
|
||||
"buyGemsGold": "Besplatni mjesečni dragulji",
|
||||
"mustSubscribeToPurchaseGems": "Trebaš se pretplatiti za kupovinu dragulja bodovima Zlatnika",
|
||||
"reachedGoldToGemCapQuantity": "Količina od <%= quantity %> koju si tražio/la prelazi količinu koju možeš kupiti ovaj mjesec. Limit se resetira unutar prva tri dana svakog mjeseca. Hvala vam što ste pretplatnik!",
|
||||
"reachedGoldToGemCapQuantity": "Vaš traženi iznos <%= quantity %> premašuje iznos koji možete kupiti za ovaj mjesec (<%= convCap %>). Puni iznos postaje dostupan unutar prva tri dana svakog mjeseca. Hvala na pretplati!",
|
||||
"mysteryItem": "Ekskluzivni mjesečni artikli",
|
||||
"mysteryItemText": "Svaki mjesec ćeš dobiti jedinstveni kozmetički predmet za svog avatara! Uz to, za svaka tri mjeseca uzastopne pretplate, misteriozni Vremenski Putnici će ti dati pristup povijesnim (i futurističkim!) kozmetičkim predmetima.",
|
||||
"exclusiveJackalopePet": "Ekskluzivni ljubimac",
|
||||
"giftSubscription": "Želiš nekome drugome pokloniti pretplatu?",
|
||||
"exclusiveJackalopePet": "Poseban ljubimac",
|
||||
"giftSubscription": "Želiš li nekome pokloniti pretplatu?",
|
||||
"giftSubscriptionText4": "Hvala što podržavaš Habiticu!",
|
||||
"groupPlans": "Grupni planovi",
|
||||
"nowSubscribed": "Sad si pretplaćen/a na Habiticu!",
|
||||
"cancelSub": "Otkaži pretplatu",
|
||||
"cancelSubInfoGroupPlan": "Zato što imaš besplatnu pretplatu u sklopu Grupnog plana, ne možeš je otkazati. Ona će završiti kad više ne budeš u Grupi. Ako si ti vođa Grupe i želiš otkazati cijeli Grupni plan, to možeš učiniti iz kartice \"Detalji plaćanja\" u grupi.",
|
||||
"cancelSubInfoGroupPlan": "Budući da imate besplatnu pretplatu iz grupnog plana, ne možete je otkazati. Završit će kada više ne budete član grupnog plana. Ako ste voditelj grupe i želite otkazati grupni plan, to možete učiniti na kartici \"Grupna naplata\" grupnog plana.",
|
||||
"cancelingSubscription": "Otkazivanje pretplate",
|
||||
"contactUs": "Kontaktiraj nas",
|
||||
"checkout": "Odjava",
|
||||
@@ -21,7 +21,7 @@
|
||||
"subGemName": "Dragulji pretplatnika",
|
||||
"maxBuyGems": "Kupio/la si sve Dragulje koje možeš za ovaj mjesec. Više ih postane dostupno unutar prva tri dana svakog mjeseca. Zahvaljujemo ti na pretplati!",
|
||||
"timeTravelers": "Vremenski putnici",
|
||||
"timeTravelersPopoverNoSubMobile": "Izgleda da će ti trebati Mistični pješčani sat da bi otvorio/la vremenski portal i prizvao/la misteriozne Vremenske putnike.",
|
||||
"timeTravelersPopoverNoSubMobile": "Pretplatnici svaki mjesec primaju rijedak Mistični pješčani sat kako bi ga upotrijebili u Trgovini putnika kroz vrijeme!",
|
||||
"timeTravelersPopover": "Tvoj Mistični pješčani sat je otvorio naš vremenski portal! Odaberi što bi htio/la da ti donesemo iz prošlosti ili budućnosti.",
|
||||
"mysterySetNotFound": "Tajni komplet nije pronađen ili ga već posjeduješ.",
|
||||
"mysteryItemIsEmpty": "Nema tajnih artikala",
|
||||
@@ -90,7 +90,7 @@
|
||||
"mysterySet301703": "Komplet steampunk pauna",
|
||||
"mysterySet301704": "Komplet steampunk fazana",
|
||||
"mysterySetwondercon": "Wondercon",
|
||||
"subUpdateCard": "Ažuriraj karticu",
|
||||
"subUpdateCard": "Ažurirajte kreditnu karticu",
|
||||
"subUpdateTitle": "Ažuriraj",
|
||||
"notEnoughHourglasses": "Nemaš dovoljno Mističnih pješčanih satova.",
|
||||
"petsAlreadyOwned": "Već posjeduješ ovog ljubimca.",
|
||||
@@ -113,24 +113,110 @@
|
||||
"couponUsed": "Kod kupona je već iskorišten.",
|
||||
"couponCodeRequired": "Potreban je kod kupona.",
|
||||
"choosePaymentMethod": "Odaberi način plaćanja",
|
||||
"support": "PODRŠKA",
|
||||
"gemBenefitLeadin": "Dragulji ti omogućuju kupovinu zabavnih dodataka za svoj račun, uključujući?",
|
||||
"support": "Podrška",
|
||||
"gemBenefitLeadin": "Što možete kupiti s draguljima?",
|
||||
"gemBenefit1": "Jedinstvene i moderne kostime za svog avatara.",
|
||||
"gemBenefit2": "Pozadine kako bi mogao/la uroniti svog avatara u svijet Habitice!",
|
||||
"gemBenefit3": "Uzbudljive nizove Pustolovina koji ti poklanjaju jaja s ljubimcima.",
|
||||
"gemBenefit4": "Resetiraj Statističke bodove svog avatara i promijeni njegovu Klasu.",
|
||||
"subscriptionBenefit1": "Trgovac Aleksandar će ti prodavati Dragulje, 20 Zlatnika po komadu!",
|
||||
"subscriptionBenefit3": "Otkrivat ćeš više artikala na Habitici uz udvostručeni dnevni limit poklona.",
|
||||
"subscriptionBenefit4": "Jedinstveni kozmetički artikli će biti dostupni za tvog avatara svaki mjesec.",
|
||||
"subscriptionBenefit5": "Dobit ćeš ekskluzivnog kraljevski ljubičastog ljubimca - Rogatog zeca!",
|
||||
"subscriptionBenefit6": "Zaradi Mistične pješčane satove za korištenje u Dućanu Vremenskih putnika!",
|
||||
"subscriptionBenefit1": "Alexander the Merchant sada će vam prodati dragulje s tržišta za 20 zlata svaki!",
|
||||
"subscriptionBenefit3": "Otkrijte još više artikala u Habitici s 2x dnevnim popustom.",
|
||||
"subscriptionBenefit4": "Jedinstveni kozmetički predmet za ukrašavanje vašeg avatara svaki mjesec.",
|
||||
"subscriptionBenefit5": "Dobijte ljubimca Royal Purple Jackalope kada postanete novi pretplatnik.",
|
||||
"subscriptionBenefit6": "Zaradite mistične pješčane satove za kupnju artikala u Dućanu vremenskog putnika!",
|
||||
"purchaseAll": "Kupi komplet",
|
||||
"gemsRemaining": "dragulja preostalo",
|
||||
"notEnoughGemsToBuy": "Nisi u mogućnosti kupiti tu količinu dragulja",
|
||||
"viewSubscriptions": "Pregledaj pretplate",
|
||||
"howManyGemsPurchase": "Koliko Dragulja bi želio/la kupiti?",
|
||||
"howManyGemsSend": "Koliko dragulja želiš poslati?",
|
||||
"needToPurchaseGems": "Trebaš kupiti Dragulje kao dar?",
|
||||
"gemsRemaining": "Preostali Dragulji",
|
||||
"notEnoughGemsToBuy": "Ne možete kupiti tu količinu dragulja",
|
||||
"viewSubscriptions": "Pogledajte pretplate",
|
||||
"howManyGemsPurchase": "Koliko dragulja želite kupiti?",
|
||||
"howManyGemsSend": "Koliko dragulja želite poslati?",
|
||||
"needToPurchaseGems": "Trebate kupiti dragulje kao dar?",
|
||||
"organization": "Organizacija",
|
||||
"giftASubscription": "Pokloni Pretplatu"
|
||||
"giftASubscription": "Poklonite pretplatu",
|
||||
"wantToSendOwnGems": "Želite li poslati svoje dragulje?",
|
||||
"subWillBecomeInactive": "Postat će neaktivan",
|
||||
"cancelSubInfoApple": "Slijedite <a href=\"https://support.apple.com/en-us/HT202039\">službene upute tvrtke Apple</a> da biste otkazali pretplatu ili da biste vidjeli datum prekida pretplate ako ste je već otkazali. Ovaj vam zaslon ne može pokazati je li vaša pretplata otkazana.",
|
||||
"cancelSubInfoGoogle": "Idite na odjeljak \"Račun\" > \"Pretplate\" u aplikaciji Trgovina Google Play da biste otkazali svoju pretplatu ili da biste vidjeli datum prekida pretplate ako ste je već otkazali. Ovaj vam zaslon ne može pokazati je li vaša pretplata otkazana.",
|
||||
"confirmCancelSub": "Jeste li sigurni da želite otkazati svoju pretplatu? Izgubit ćete sve svoje pogodnosti pretplate.",
|
||||
"mysticHourglassNeededNoSub": "Za ovaj predmet potreban je mističan pješčani sat. Pretplatom na Habiticu zarađujete Mystic Hourglasses.",
|
||||
"mysterySet201912": "Polarni Pixie Set",
|
||||
"mysterySet201901": "Polaris set",
|
||||
"mysterySet201902": "Cryptic Crush Set",
|
||||
"mysterySet201903": "Set za pečenje Jaja",
|
||||
"mysterySet201904": "Raskošan Opalni set",
|
||||
"mysterySet201905": "Sjajni Zmajev set",
|
||||
"mysterySet201906": "Ljubazno Koi Set",
|
||||
"mysterySet201907": "Beach Buddy Set",
|
||||
"mysterySet201908": "Komotna Fauna set",
|
||||
"mysterySet201910": "Kriptične Vatre Set",
|
||||
"mysterySet201911": "Privačivač Kristala Set",
|
||||
"mysterySet202001": "Legendarni Lisičev Set",
|
||||
"mysterySet202002": "Elegantan set za srce",
|
||||
"mysterySet202003": "Set bodljikavih boraca",
|
||||
"mysterySet202004": "Moćni Monarh set",
|
||||
"mysterySet202005": "Čudesni Wyvern set",
|
||||
"mysterySet202006": "Multikromatski Merfolk set",
|
||||
"mysterySet202007": "Izvanredni Orka Set",
|
||||
"mysterySet202008": "Sovački Oracle Set",
|
||||
"mysterySet202009": "Čudesni Moljac Set",
|
||||
"mysterySet202010": "Beguilingly Batty Set",
|
||||
"mysterySet202011": "Rascvjetani Čarobnjak Set",
|
||||
"mysterySet202012": "LedenoPlameni Feniks Set",
|
||||
"mysterySet202101": "Oštar Sniježni Leopard Set",
|
||||
"mysterySet202102": "Šarmantni Šampion Set",
|
||||
"mysterySet202103": "Promatranje Cvjetanja Set",
|
||||
"mysterySet202104": "Čuvara Čička Set",
|
||||
"mysterySet202105": "Nebulin Zmaj Set",
|
||||
"mysterySet202106": "Zalazak Sunca Sirene Set",
|
||||
"mysterySet202108": "Vatreni Borac Set",
|
||||
"mysterySet202109": "Lunarni Lepidopteran Set",
|
||||
"mysterySet202111": "Kozmički Kronomancer Set",
|
||||
"mysterySet201909": "Pristupaačan Žir set",
|
||||
"mysterySet202110": "Gargojl Obrastao Bršljanom Set",
|
||||
"mysterySet202112": "Antartička Vodena Vila Set",
|
||||
"mysterySet202209": "Migični Učenjak Set",
|
||||
"mysterySet202210": "Zločudna Guja Set",
|
||||
"mysterySet202203": "Neustrašivi Vilin Konjic Set",
|
||||
"mysterySet202301": "Hrabri Lukavac Set",
|
||||
"mysterySet202201": "Ponoćni Veseljak Set",
|
||||
"mysterySet202207": "Plesajuća Meduza Set",
|
||||
"mysterySet202211": "Čarobnjak Struje Set",
|
||||
"mysterySet202206": "Morski Duh Set",
|
||||
"mysterySet202208": "Živahan Rep Set",
|
||||
"mysterySet202204": "Virtualni Pustolov Set",
|
||||
"mysterySet202202": "Tirkizni Dvorepi Set",
|
||||
"mysterySet202212": "Galagtički Zaštitnik Set",
|
||||
"mysterySet202205": "Sumrak-Krilati Zmaj Set",
|
||||
"mysterySet202302": "Lukava Torokuša Set",
|
||||
"backgroundAlreadyOwned": "Pozadina već u vlasništvu.",
|
||||
"supportHabitica": "Podržite Habiticu",
|
||||
"usuallyGems": "Obično <%= originalGems %>",
|
||||
"lookingForMoreItems": "Tražite više artikala?",
|
||||
"subscriptionCanceled": "Vaša pretplata je otkazana",
|
||||
"subscriptionInactiveDate": "Vaše pogodnosti pretplate postat će neaktivne <br><strong><%= datum %></strong>",
|
||||
"switchToRecurring": "Prebaciti se na ponavljajuću pretplatu?",
|
||||
"cancelYourSubscription": "Otkazati pretplatu?",
|
||||
"subscribersReceiveBenefits": "Pretplatnici dobivaju ove korisne pogodnosti!",
|
||||
"monthlyMysteryItems": "Mjesečne tajanstvene stavke",
|
||||
"doubleDropCap": "Dupli Drops (maybe Dupli Dobitci)",
|
||||
"youAreSubscribed": "Pretplaćeni ste na Habiticu",
|
||||
"dropCapReached": "Našli ste sve stavke za taj dan!",
|
||||
"dropCapExplanation": "Vaši će se dobitci poništiti s vašim zadacima sutra. Međutim, nastavit ćete zarađivati zlato, iskustvo i napredak u misiji kada dovršite zadatke.",
|
||||
"subCanceledTitle": "Pretplata otkazana",
|
||||
"dropCapLearnMore": "Saznajte više o Habiticinom sustavu dobitaka",
|
||||
"dropCapSubs": "Pretplatnici Habitice mogu pronaći dvostruko više nasumičnih predmeta svaki dan i primati mjesečne tajanstvene predmete!",
|
||||
"subscriptionStats": "Statistika pretplate",
|
||||
"subMonths": "Podmjeseci",
|
||||
"needToUpdateCard": "Trebate ažurirati svoju karticu?",
|
||||
"readyToResubscribe": "Jeste li spremni ponovno se pretplatiti?",
|
||||
"cancelSubAlternatives": "Ako imate tehničkih problema ili vam se čini da Habitica ne radi, razmislite o <a href='mailto:admin@habitica.com'>kontaktiranju s nama</a>. Želimo vam pomoći da izvučete najviše iz Habitice.",
|
||||
"sendAGift": "Pošalji poklon",
|
||||
"haveNonRecurringSub": "Imate neponavljajuću darovnu pretplatu.",
|
||||
"continueGiftSubBenefits": "Želite nastaviti svoje pogodnosti? Možete započeti novu pretplatu prije nego što istekne vaša darovana kako biste zadržali svoje pogodnosti aktivnima.",
|
||||
"subscriptionCreditConversion": "Pokretanje nove pretplate pretvorit će sve preostale mjesece u kredit koji će se koristiti nakon otkazivanja ponavljajuće pretplate.",
|
||||
"mysterySet202303": "Set za grivu",
|
||||
"mysterySet202107": "Set za plažu",
|
||||
"mysterySet202306": "Blještavi dugin set",
|
||||
"mysterySet202305": "Set zmaja sutona",
|
||||
"mysterySet202304": "Savršeni set za čaj"
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
"negative": "Negativna",
|
||||
"yellowred": "Slabe",
|
||||
"greenblue": "Jake",
|
||||
"edit": "Izmijeni",
|
||||
"edit": "Uredi",
|
||||
"save": "Spremi",
|
||||
"addChecklist": "Dodaj spisak",
|
||||
"checklist": "Spisak",
|
||||
"addChecklist": "Dodaj popis zadataka",
|
||||
"checklist": "Popis zadataka",
|
||||
"newChecklistItem": "Nova stavka na spisku",
|
||||
"expandChecklist": "Proširi spisak",
|
||||
"collapseChecklist": "Sažmi spisak",
|
||||
@@ -72,7 +72,7 @@
|
||||
"streakName": "<%= count %> postignuća za dosljednost",
|
||||
"streakText": "Postigao/la je <%= count %> 21-dnevnih uzastopnih ponavljanja Svakodnevnih zadataka",
|
||||
"streakSingular": "Ponavljač",
|
||||
"streakSingularText": "je 21 dan za redom obavio/la Svakodnevni zadatak",
|
||||
"streakSingularText": "21 dan za redom obavio/la je Svakodnevni zadatak",
|
||||
"perfectName": "<%= count %> savršenih dana",
|
||||
"perfectText": "Izvršeni su svi Svakodnevni zadaci <%= count %> dana za redom. S ovim postignućem dobivaš bonus koji iznosi +level/2 boda ojačanja za sve Statistike sljedeći dan. Oni iznad levela 100 ne dobivaju nikakve dodatne efekte ojačanja.",
|
||||
"perfectSingular": "Savršeni dan",
|
||||
|
||||
@@ -906,5 +906,20 @@
|
||||
"backgroundSummerSeashoreNotes": "Cavalca un'onda su una Spiaggia Estiva.",
|
||||
"backgrounds052025": "SET 132: Rilasciato a Maggio 2025",
|
||||
"backgroundTrailThroughAForestText": "Sentiero Attraverso una Foresta",
|
||||
"backgroundTrailThroughAForestNotes": "Passeggia lungo un Sentiero Attraverso una Foresta."
|
||||
"backgroundTrailThroughAForestNotes": "Passeggia lungo un Sentiero Attraverso una Foresta.",
|
||||
"backgrounds072025": "SET 134: Rilasciato Luglio 2025",
|
||||
"backgroundSirensLairText": "Tana della Sirena",
|
||||
"backgroundSirensLairNotes": "Abbi il coraggio di entrare nella Tana della Sirena.",
|
||||
"backgrounds082025": "SET 135: Rilasciato Agosto 2025",
|
||||
"backgroundSunnyStreetWithShopsText": "Strada Soleggiata con Negozi",
|
||||
"backgroundSunnyStreetWithShopsNotes": "Lasciati incantare dall’atmosfera di una strada soleggiata con negozi.",
|
||||
"backgroundAutumnSwampText": "Palude Autunnale",
|
||||
"backgroundAutumnSwampNotes": "Immergiti nelle inquietanti atmosfere di una palude d’autunno.",
|
||||
"backgrounds102025": "SET 137: Rilasciato Ottobre 2025",
|
||||
"backgroundInsideForestWitchsCottageNotes": "Tessi incantesimi nella casetta della Strega della Foresta.",
|
||||
"backgrounds112025": "SET 138: Rilasciato Novembre 2025",
|
||||
"backgroundCastleKeepWithBannersText": "Sala del castello con stendardi",
|
||||
"backgrounds092025": "SET 136: Rilasciato Settembre 2025",
|
||||
"backgroundInsideForestWitchsCottageText": "Casetta della Strega della Foresta",
|
||||
"backgroundCastleKeepWithBannersNotes": "Canta storie di gesta eroiche nella sala del castello con gli stendardi."
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"subGemName": "Gemme abbonato",
|
||||
"maxBuyGems": "Hai comprato tutte le Gemme a disposizione per questo mese. Altre saranno disponibili entro i primi tre giorni del mese prossimo. Grazie per esserti abbonato!",
|
||||
"timeTravelers": "Viaggiatori del Tempo",
|
||||
"timeTravelersPopoverNoSubMobile": "Pare che tu abbia bisogno di una Clessidra Mistica per aprire il portale temporale ed evocare i Misteriosi Viaggiatori del Tempo.",
|
||||
"timeTravelersPopoverNoSubMobile": "Gli abbonati ricevono una rara Clessidra Mistica ogni mese da utilizzare nel negozio dei Viaggiatori del Tempo.",
|
||||
"timeTravelersPopover": "La tua Clessidra Mistica ha aperto il nostro portale temporale! Scegli cosa vorresti recuperare dal passato o dal futuro.",
|
||||
"mysterySetNotFound": "Completo Mistery non trovato o già posseduto.",
|
||||
"mysteryItemIsEmpty": "Gli oggetti Mistery sono finiti",
|
||||
@@ -120,14 +120,14 @@
|
||||
"gemBenefit2": "Sfondi per immergere il tuo avatar nel mondi di Habitica!",
|
||||
"gemBenefit3": "Entusiasmanti Missioni che hanno come ricompensa uova di animali.",
|
||||
"gemBenefit4": "Resetta le statistiche del tuo avatar e cambia la sua classe.",
|
||||
"subscriptionBenefit1": "Alexander il Mercante ti venderà ora delle Gemme nel Mercato al prezzo di 20 Oro l'una!",
|
||||
"subscriptionBenefit3": "Scopri ancora più oggetti in Habitica con un bottino giornaliero raddoppiato.",
|
||||
"subscriptionBenefit4": "Ogni mese un costume unico e alla moda per il tuo avatar.",
|
||||
"subscriptionBenefit5": "Riceverai il Lepronte Porpora una volta diventato un nuovo Abbonato.",
|
||||
"subscriptionBenefit6": "Ottieni Clessidre Mistiche per comprare oggetti nel negozio dei Viaggiatori del Tempo!",
|
||||
"subscriptionBenefit1": "Ottieni fino a 50 gemme acquistabili con Oro nel Mercato per comprare Missioni, Personalizzazioni, Animali ed altro!",
|
||||
"subscriptionBenefit3": "Trova il doppio di Uova, Pozioni di schiusa e cibo ogni giorno per accrescere la tua collezioni di Animali!",
|
||||
"subscriptionBenefit4": "Rimani aggiornato con gli ultimi equipaggiamenti esclusivi. Abbonati adesso per ottenere <%= month %>’s <%= currentMysterySetName %>!",
|
||||
"subscriptionBenefit5": "Ottieni l'esclusivo Lepronte Porpora una volta che ti sei abbonato oggi!",
|
||||
"subscriptionBenefit6": "Non perderti neanche un oggetto con 1 Clessidra Mistica al mese da utilizzare nel negozio dei Viaggiatori del Tempo!",
|
||||
"purchaseAll": "Acquista Set",
|
||||
"gemsRemaining": "Gemme rimanenti",
|
||||
"notEnoughGemsToBuy": "Non puoi comprare quella quantità di Gemme",
|
||||
"gemsRemaining": "rimanenti",
|
||||
"notEnoughGemsToBuy": "Non ci sono più gemme disponibili per l'acquisto questo mese. Altre diventeranno disponibili entro i primi 3 giorni di ogni mese.",
|
||||
"subWillBecomeInactive": "Diventerà inattivo",
|
||||
"confirmCancelSub": "Sei sicuro di voler cancellare il tuo abbonamento? Perderai tutti i tuoi benefici.",
|
||||
"mysticHourglassNeededNoSub": "Questo articolo ha bisogno di una Clessidra Mistica. Ne otterrai sottoscrivendo un abbonamento ad Habitica.",
|
||||
@@ -226,5 +226,26 @@
|
||||
"mysterySet202305": "Set Drago del Vespro",
|
||||
"mysterySet202302": "Set del Prestigiatore Striato",
|
||||
"mysterySet202304": "Set Teiera Eccellente",
|
||||
"mysterySet202310": "Set Fantasma della Luce Spettrale"
|
||||
"mysterySet202310": "Set Fantasma della Luce Spettrale",
|
||||
"mysterySet202508": "Set della Lama Brillante",
|
||||
"mysterySet202403": "Set della Leggenda Fortunata",
|
||||
"mysterySet202409": "Set del Mago dell'Eliotropio",
|
||||
"mysterySet202407": "Set dell'amabile Axolotl",
|
||||
"mysterySet202509": "Set del Viandante spazzato dal vento",
|
||||
"mysterySet202511": "Set del Guerriero del Gelo",
|
||||
"mysterySet202408": "Set dell'Egida Arcana",
|
||||
"mysterySet202504": "Set dello Yeti sfuggente",
|
||||
"mysterySet202402": "Set del Paradiso Rosa",
|
||||
"mysterySet202412": "Set del Coniglietto del Bastoncino di Zucchero",
|
||||
"subscribeTo": "Abbonati a",
|
||||
"mysterySet202503": "Set Furia di Giada",
|
||||
"mysterySet202404": "Set del Mago dei Funghi",
|
||||
"mysterySet202405": "Set del Drago Dorato",
|
||||
"mysterySet202501": "Set del Vincolagelo",
|
||||
"mysterySet202502": "Set dell'Arlecchino sincero",
|
||||
"mysterySet202406": "Set del Bucaniere Fantasma",
|
||||
"mysterySet202411": "Set del Combattente peloso",
|
||||
"mysterySet202506": "Set della Luce Solare",
|
||||
"mysterySet202505": "Set della Coda di rondine volante",
|
||||
"mysterySet202507": "Set dello Skater coraggioso"
|
||||
}
|
||||
|
||||
@@ -108,5 +108,6 @@
|
||||
"resetFlags": "フラグのリセット",
|
||||
"cannotClose": "このチャレンジは、1人以上のプレイヤーが不適切だと報告したため、閉じることはできません。スタッフのメンバーが間もなく指示を含む連絡を取ります。48時間以上経過しても連絡がない場合は、admin@habitica.comにメールして支援を依頼してください。",
|
||||
"cannotMakeChallenge": "あなたのアカウントには現在チャット権限がないため、パブリックチャレンジを作成できません。詳しくは admin@habitica.com までお問い合わせください。",
|
||||
"messageChallengeFlagOfficial": "公式チャレンジは報告できません。"
|
||||
"messageChallengeFlagOfficial": "公式チャレンジは報告できません。",
|
||||
"deleteChallengeRefundDescription": "このチャレンジを消除すると、賞品のジェムが返金され、チャレンジのタスクは参加者のタスクボードに残ります。"
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"webFaqAnswer37": "「衣装を着る」オプションがオンになっているか確認してください。もしアバターが衣装を着ている場合、その装備セットが武装の代わりに表示されます。\n\nモバイル版で衣装を切り替えるには:\n * メニューから「装備」を選択し、「衣装を使用する」トグルを見つけます\n\nウェブ版で衣装を切り替えるには:\n * 所持品から「装備」を選択し、装備ドロワーの衣装タブで「衣装を使用する」トグルを見つけます",
|
||||
"webFaqAnswer38": "新しいHabiticaプレイヤーは基本の戦士クラスの装備しか購入できません。プレイヤーは装備を順番に購入して次のピースをアンロックする必要があります。\n\n多くの装備はクラス固有であり、プレイヤーは現在のクラスに属する装備のみ購入できます。",
|
||||
"webFaqAnswer39": "もし装備を手に入れたい場合は、Habiticaの有料会員になるか、ラッキー宝箱に挑戦するか、Habiticaの大祭のうちの1つで贅沢をすることができます。\n\nHabiticaの有料会員は毎月特別な独占装備セットと、タイムトラベラーショップで過去の装備セットを購入するための神秘的な砂時計を受け取ります。\n\nごほうびのラッキー宝箱には350以上の装備があります!100ゴールドで、特別な装備、ペットを乗騎に育てるための餌、またはレベルアップのための経験値のいずれかを受け取るチャンスがあります!\n\n四季ごとの大祭では、新しいクラスの装備がゴールドで購入でき、以前の大祭セットはジェムで購入できます。",
|
||||
"webFaqAnswer41": "神秘の砂時計はHabiticaの有料会員限定の通貨でタイムトラベラーの店で使用できます。有料会員は神秘の砂時計を登録特典がある月ごとに他の特典とともに受け取れます。\n特別な背景、ペット、クエスト、道具に興味があるならば有料プランのオプションをタイムトラベラーの店でチェックしてみてください。",
|
||||
"webFaqAnswer41": "神秘の砂時計はHabiticaの有料会員限定の通貨で、タイムトラベラーの店で使用できます。有料会員は登録している間、神秘の砂時計と、ほかにもいろいろな特典を毎月受け取れます。タイムトラベラーの店で買える特別な背景、ペット、クエストや装備に興味がある方は、ぜひ有料プランのオプションをチェックしてみてください!",
|
||||
"webFaqAnswer42": "自分自身を奮起させ、タスクを達成するために責任感を高める最良の方法の一つは、パーティーに参加することです! 他のHabiticaプレイヤーと一緒にパーティーを組むことは、クエストに挑戦してペットと装備を手に入れ、仲間のスキルからバフを受け、モチベーションを高める素晴らしい方法です。\n\n責任感を高める別の方法は、チャレンジに参加することです。 チャレンジは特定の目標に関連するタスクを自動的にリストに追加します! これにより、ジェムの賞を目指して競争する要素が追加され、モチベーションが向上するかもしれません。 Habiticaチームによって作成された公式のチャレンジだけでなく、他のプレイヤーによって作成されたチャレンジもあります。",
|
||||
"faqQuestion43": "クエストの進め方は?",
|
||||
"webFaqAnswer43": "クエストを始めるには、まずパーティーに参加する必要があります。パーティーは、単独でクエストに挑戦する冒険としても、他のHabiticaプレーヤーを招待してクエストに迅速に取り組むこともできます!\n\nパーティーから「クエストの開始」ボタンを選択して、インベントリからクエストスクロールを選択します。クエストを進めるために通常どおりタスクを完了してください!ボスクエストに挑戦している場合はモンスターに対してダメージを蓄積し、コレクションクエストに挑戦している場合はアイテムを見つけるチャンスがあります。すべての進捗状況は翌日に適用されます。\n\n十分なダメージを与えたり、すべてのアイテムを集めたりすると、クエストが完了し、報酬がもらえます!",
|
||||
@@ -192,7 +192,7 @@
|
||||
"subscriptionDetail001": "すべての有料会員は神秘の砂時計を毎月のミステリーアイテムと同じく毎月同じ日にもらえます。",
|
||||
"subscriptionDetail45": "もし追加で有料プランをプレゼントされた場合に神秘の砂時計を多くもらえたりジェムの最大値が早く増えたりはしますか?",
|
||||
"subscriptionDetail480": "これらの変更は神秘の砂時計と有料会員のジェムにのみ反映されます。そのほかすべての得点はそのまま残ります。",
|
||||
"subscriptionPara2": "もし上記の回答にない質問があるならば、いつでも <%= mailto %>.に連絡してください",
|
||||
"subscriptionPara2": "もし上記の回答にない質問があるならば、いつでも <%= mailto %>に連絡してください。",
|
||||
"subscriptionBenefitsAdjustments": "有料会員の特典調整",
|
||||
"subscriptionBenefitsFaqTitle": "有料会員の特典調整のよくある質問",
|
||||
"subscriptionPara0": "私たちはHabiticaの有料プランをより多くの神秘の砂時計とジェムで過去最高のものにしました!これらの変更は有料プランの特典をもっとわかりやすくするものです。",
|
||||
@@ -227,5 +227,15 @@
|
||||
"subscriptionDetail24": "有料会員が「タイムトラベラーズショップ」からアイテムを収集できる機会を、年間4回以上に増やしたいと考えました。",
|
||||
"subscriptionHeading3": "リリース当日特典",
|
||||
"subscriptionPara1": "新しいスケジュールへの移行をスムーズにするため、既存の有料会員にはリリース当日に追加の特典が用意されます。この変更に伴い、引き続きサポートしてくださる皆様に心から感謝いたします!",
|
||||
"subscriptionDetail4400": "現在、毎月ジェムを<%= initialNumber %>個アンロックしている場合、ジェムの上限は<%= roundedNumber %>個に調整されます。"
|
||||
"subscriptionDetail4400": "現在、毎月ジェムを<%= initialNumber %>個アンロックしている場合、ジェムの上限は<%= roundedNumber %>個に調整されます。",
|
||||
"subscriptionDetail48": "ミステリー装備セットなど、他の有料プランの特典には変更ありますか?",
|
||||
"subscriptionDetail33": "このご褒美は、11月19日以前に有料プランを始めたアカウントしか受け取れません。",
|
||||
"subscriptionDetail42": "有料プランに登録している間、1ヶ月間ログインしない場合、この特典はまだ受け取れますか?",
|
||||
"subscriptionDetail400": "現在の有料会員には、リリース後の最初の月の初回ログイン時に、最初のミスティック砂時計と毎月のジェム上限が+2増加します。つまり、もしすでに11月にログインしている場合、最初の定期的な増加は12月に行われます。",
|
||||
"subscriptionDetail40": "私は有料会員ですが、新しいスケジュールでは最初の定期的な神秘の砂時計とジェム上限の増加はいつ受け取れますか?",
|
||||
"subscriptionDetail420": "ミステリーギアセットと同様に、登録している間にログインしなくても神秘の砂時計やジェムの上限アップを見逃すことはありません。次回ログインしたときに、登録していた期間のすべての特典を受け取ることができます。",
|
||||
"subscriptionDetail43": "有料プランを申し込んでからキャンセルした場合でも、特典は受けられますか?",
|
||||
"subscriptionDetail47": "グループプランに登録している人はどう影響されますか?",
|
||||
"subscriptionDetail440": "これらの変更が有効となった日から、毎月受け取るジェムが奇数個の有料会員のジェムの上限に反映されます。",
|
||||
"subscriptionDetail430": "有料プランを解約すると特典の終了日が設定されますが、その日まではすべての特典を利用できます。つまり、利用可能な期間中は毎月、神秘の砂時計の受け取り、毎月初めのジェム上限増加が引き続き適用されます。"
|
||||
}
|
||||
|
||||