Compare commits

..

258 Commits

Author SHA1 Message Date
SabreCat f327795761 4.261.1 2023-02-27 16:17:17 -06:00
SabreCat 8cf5a380da fix(strings): more silly 2023-02-27 16:17:09 -06:00
SabreCat cc419385f6 4.261.0 2023-02-24 16:32:41 -06:00
SabreCat 45107fe48f Merge branch 'sabrecat/transactions-404' into release 2023-02-24 16:32:35 -06:00
SabreCat 80f517f1ad feat(content): subscriber items March 2023
Also fixes Vue templating in one paragraph of the Community Guidelines.
2023-02-24 16:31:50 -06:00
SabreCat 442d9ca9cd fix(permissions): route away from purchase history for non-support 2023-02-22 15:15:03 -06:00
SabreCat ab706abed5 fix(test): remove outdated event expectation 2023-02-15 15:29:23 -06:00
SabreCat 2ac21104a4 4.260.1 2023-02-13 11:51:45 -06:00
SabreCat 6b95f648c4 Merge remote-tracking branch 'CuriousMagpie/footer-link-updates' into release 2023-02-13 11:28:14 -06:00
SabreCat f9db4b9b5b fix(event): correct logic for various Valentine's items 2023-02-13 11:25:02 -06:00
SabreCat 74da6d8798 4.260.0 2023-02-12 23:17:16 -06:00
Natalie L a73e4d399e chore(content): add Pink Marble Magic Hatching Potion (#14497)
* chore(content): add quest text

* chore(content): add rest of potion quest content

* fix(image): pad quest scroll image

* feat(quest): add Rage action

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-02-12 23:17:56 -06:00
Natalie L 8f4d668b0f chore(content): add pet quest bundle and magic hatching potions for February (#14499) 2023-02-12 23:17:09 -06:00
CuriousMagpie 945c19cc80 chore(links): add weblate link to footer and update data display tool 2023-02-10 15:11:36 -05:00
gwenexner 7b4cfee290 Fixed release info for Set 105 (#14494)
Removed a stray space at the front of "Set 105", changed year to 2023.
2023-02-10 10:30:27 -06:00
SabreCat 015631685b 4.259.1 2023-02-08 15:04:19 -06:00
Natalie L 0b8f2bc58e update(content): revise community guidelines (#14481)
* update(content); revise community guidelines

* fix(CG): remove outdated spoiler advice, remove unneeded string token

* chore(CG): update date line to intended publication

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-02-08 15:04:30 -06:00
SabreCat 6c536c0b89 Merge branch 'release' into develop 2023-02-07 09:12:03 -06:00
SabreCat 1de2adf301 4.259.0 2023-02-07 09:11:52 -06:00
Natalie L 0335eb1f7e chore(content): add February backgrounds and Enchanted Armoire Items (#14482)
* chore(content): add February backgrounds and Enchanted Armoire Items

* fix(test): birthday week adjustment

* fix(strings): .

* fix(strings): correct background tokens

---------

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2023-02-07 09:12:19 -06:00
SabreCat e0a5938711 fix(test): update expectations for new flagging logic 2023-02-06 21:34:51 -06:00
SabreCat c7deb1eb19 4.258.2 2023-02-03 09:23:27 -06:00
SabreCat a213fb723a fix(purchases): correct hardcoded date range for Gryph 2023-02-03 09:23:21 -06:00
SabreCat 5f66aa35f2 4.258.1 2023-02-02 16:36:44 -06:00
SabreCat 96a8c1a41c fix(chat): correctly hide flag counts from non-moderators 2023-02-02 16:36:37 -06:00
SabreCat 0f9b6ab591 fix(lint): revert bad lint rule again 2023-01-31 11:00:08 -06:00
SabreCat 3470382528 fix(lint): revert bad lint rule again 2023-01-31 10:59:53 -06:00
SabreCat 4d953890c3 Merge branch 'release' into develop 2023-01-31 10:56:23 -06:00
SabreCat dd6897ac53 Merge branch 'sabrecat/admin-panel-gems' into release 2023-01-31 10:53:11 -06:00
SabreCat a19b5356b5 Merge branch 'sabrecat/admin-panel-gems' into develop 2023-01-31 10:53:03 -06:00
SabreCat b59fcd203b Merge branch 'sabrecat/fixes-202302' into release 2023-01-31 10:51:41 -06:00
SabreCat 0ca339829f 4.258.0 2023-01-31 10:35:50 -06:00
Natalie L 059269f9b0 chore(content): add February subscriber items (#14466)
* chore(content): add February subscriber items

* fix(strings): month typo

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-01-31 10:33:36 -06:00
SabreCat 5eda99b0b8 Merge branch 'release' into develop 2023-01-31 10:02:54 -06:00
Natalie L cfa85850bf chore(typos): miscellaneous string fixes (#14414)
* fix(string): questVice1Notes html changed to a mobile-device friendly format

* fix(strings): updated limited.json with "dateEnd" & "monthYYYY" months & put in chronological order

* fix(string): remove extra word from headSpecialSummer2022WarriorNotes

* fix(string): corrected armorSpecialSummer2022MageNotes

* fix: remove duplicated string and adjust upgrade button style

* fix(style): set border radii to 8px on upgrading-group id

* fix(payments): remove duplicate entry from another modal

* chore(fix): restore string inadvertently removed during a refactor

* chore(fix): comma dangle

* chore(typo): who knew, that Y was actually important...

* chore(typo): fix text in questBewilderNotes

* chore(string): clarify polar pets requirements

* couple small changes to the footer as pointed out by users

* chore(fix): correct name of Fabulous Party Hat

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-01-31 10:03:06 -06:00
SabreCat dd9e03044f chore(subproject): update habitica-images 2023-01-31 10:02:43 -06:00
SabreCat 27964a2d86 fix(analytics): add headers to group task assignment 2023-01-27 19:57:15 -06:00
SabreCat ecac3f0c5f fix(backgrounds): disallow equipping unowned bashground
Also add missing headers when recording group task creation
2023-01-27 19:26:19 -06:00
Weblate 9f64633a57 Merge branch 'origin/develop' into Weblate. 2023-01-26 22:11:34 +01:00
SabreCat 5dc4fccddc Merge branch 'release' into develop 2023-01-26 15:09:09 -06:00
SabreCat f03c37f420 4.257.0 2023-01-26 15:06:27 -06:00
SabreCat f31103094b fix(events): don't start "no event" until after birthday10 2023-01-26 15:05:07 -06:00
Weblate f30074ed7a Translated using Weblate (Malay)
Currently translated at 98.6% (144 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Indonesian)

Currently translated at 87.3% (652 of 746 strings)

Translated using Weblate (Arabic)

Currently translated at 60.1% (449 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 4.9% (9 of 181 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Arabic)

Currently translated at 58.4% (436 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (2735 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 96.5% (141 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Indonesian)

Currently translated at 86.5% (646 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 95.2% (139 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Indonesian)

Currently translated at 86.3% (644 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 93.8% (137 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 93.8% (137 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (2734 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 86.3% (644 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 92.4% (135 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 91.0% (133 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 61.6% (1695 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Portuguese)

Currently translated at 92.0% (197 of 214 strings)

Translated using Weblate (Malay)

Currently translated at 89.0% (130 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 87.6% (128 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 86.9% (127 of 146 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Hebrew)

Currently translated at 69.1% (101 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 86.3% (126 of 146 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Japanese)

Currently translated at 99.8% (2746 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 84.9% (124 of 146 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.4% (673 of 2749 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Russian)

Currently translated at 99.3% (2732 of 2749 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 83.5% (122 of 146 strings)

Translated using Weblate (Ukrainian)

Currently translated at 66.3% (501 of 755 strings)

Translated using Weblate (Malay)

Currently translated at 82.1% (120 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 81.5% (119 of 146 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (2743 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 75.3% (110 of 146 strings)

Translated using Weblate (Indonesian)

Currently translated at 86.3% (644 of 746 strings)

Translated using Weblate (Malay)

Currently translated at 73.9% (108 of 146 strings)

Translated using Weblate (Filipino)

Currently translated at 90.6% (164 of 181 strings)

Translated using Weblate (Indonesian)

Currently translated at 85.7% (640 of 746 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Japanese)

Currently translated at 99.6% (2740 of 2749 strings)

Translated using Weblate (Filipino)

Currently translated at 91.1% (165 of 181 strings)

Translated using Weblate (Filipino)

Currently translated at 91.9% (343 of 373 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (2737 of 2749 strings)

Translated using Weblate (Filipino)

Currently translated at 40.9% (9 of 22 strings)

Translated using Weblate (Japanese)

Currently translated at 99.3% (2731 of 2749 strings)

Translated using Weblate (Japanese)

Currently translated at 99.0% (2723 of 2749 strings)

Translated using Weblate (Filipino)

Currently translated at 91.1% (165 of 181 strings)

Translated using Weblate (Japanese)

Currently translated at 98.9% (2719 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 66.4% (97 of 146 strings)

Translated using Weblate (Arabic)

Currently translated at 86.8% (53 of 61 strings)

Translated using Weblate (Japanese)

Currently translated at 98.8% (2717 of 2749 strings)

Translated using Weblate (Russian)

Currently translated at 99.1% (2727 of 2749 strings)

Translated using Weblate (Bulgarian)

Currently translated at 65.0% (95 of 146 strings)

Translated using Weblate (Russian)

Currently translated at 99.0% (2724 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 82.6% (105 of 127 strings)

Translated using Weblate (Japanese)

Currently translated at 98.6% (2711 of 2749 strings)

Translated using Weblate (Japanese)

Currently translated at 98.5% (2710 of 2749 strings)

Translated using Weblate (Japanese)

Currently translated at 98.5% (2709 of 2749 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Ukrainian)

Currently translated at 61.7% (466 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Malay)

Currently translated at 65.7% (96 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 64.3% (94 of 146 strings)

Translated using Weblate (Russian)

Currently translated at 99.0% (2722 of 2749 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 98.8% (2717 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 60.9% (89 of 146 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Malay)

Currently translated at 47.9% (70 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.5% (2738 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (French)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Russian)

Currently translated at 99.5% (237 of 238 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (2709 of 2749 strings)

Translated using Weblate (Malay)

Currently translated at 38.3% (56 of 146 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Malay)

Currently translated at 55.2% (116 of 210 strings)

Translated using Weblate (Malay)

Currently translated at 21.9% (32 of 146 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2749 of 2749 strings)

Translated using Weblate (Indonesian)

Currently translated at 95.9% (212 of 221 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Arthur Ouzlaner <panther1984@gmail.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Falzart Werefox <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Hanafi <naflizo@gmail.com>
Co-authored-by: Keva Kursakov <kevakursakov@gmail.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: M <maperray@gmail.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Salman Mujeeb <kingleopard22@gmail.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: polyglottericus <vincemorel.vilan.889@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/he/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/id/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/id/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/id/
Translate-URL: https://translate.habitica.com/projects/habitica/content/fil/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/fil/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/it/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/fil/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/he/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/id/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ms/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Messages
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2023-01-26 20:39:15 +01:00
SabreCat 9aa8b6d64d fix(shops): use gala-specific logic for gala gear canBuy 2023-01-25 12:45:55 -06:00
SabreCat ce96f4065d fix(event): adjust potions end date 2023-01-25 11:08:35 -06:00
SabreCat def9aa16b5 fix(events): handle overlap of unseasonal events and seasonal 2023-01-25 10:51:47 -06:00
SabreCat efae9429c0 feat(event): adjust dates, add NPC variations 2023-01-24 16:11:16 -06:00
SabreCat ac239e32ce fix(payments): wrap up adjusted test expectations 2023-01-23 00:45:31 -06:00
SabreCat e1deb6adff fix(payments): add missing SKU variations 2023-01-22 23:21:22 -06:00
SabreCat 3474cbf138 fix(payments): correct more tests 2023-01-22 23:02:18 -06:00
SabreCat f845bbd7a0 fix(payments): address some test failures 2023-01-22 22:30:48 -06:00
SabreCat 0dfc8de300 fix(lint): remove extraneous import 2023-01-20 16:25:24 -06:00
SabreCat 1988ef957d fix(strings): dedupe jubilantGryphatrice 2023-01-20 16:15:33 -06:00
SabreCat e5bbde7e97 feat(event): 10th Birthday Bash
with @CuriousMagpie and @phillipthelen
2023-01-20 16:14:33 -06:00
dependabot[bot] b87cfb71f1 build(deps): bump core-js from 3.27.1 to 3.27.2 in /website/client (#14454)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.27.1 to 3.27.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.27.2/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 15:22:43 -05:00
dependabot[bot] 352b1170c4 build(deps): bump @vue/cli-plugin-babel in /website/client (#14116)
Bumps [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) from 4.5.15 to 5.0.8.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-babel)

---
updated-dependencies:
- dependency-name: "@vue/cli-plugin-babel"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 15:21:44 -05:00
dependabot[bot] 19d4c5102a build(deps): bump @babel/core from 7.20.5 to 7.20.12 (#14444)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.20.5 to 7.20.12.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.12/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 15:16:10 -05:00
dependabot[bot] 2c880708e3 build(deps): bump stripe from 11.4.0 to 11.6.0 (#14442)
Bumps [stripe](https://github.com/stripe/stripe-node) from 11.4.0 to 11.6.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v11.4.0...v11.6.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 15:12:39 -05:00
dependabot[bot] 9d0e2217d5 build(deps): bump core-js from 3.26.1 to 3.27.1 in /website/client (#14437)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.26.1 to 3.27.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.27.1/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:57:27 -05:00
dependabot[bot] 076c090197 build(deps): bump flat and @vue/cli-plugin-unit-mocha in /website/client (#14436)
Bumps [flat](https://github.com/hughsk/flat) to 5.0.2 and updates ancestor dependency [@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-unit-mocha). These dependencies need to be updated together.


Updates `flat` from 4.1.1 to 5.0.2
- [Release notes](https://github.com/hughsk/flat/releases)
- [Commits](https://github.com/hughsk/flat/compare/4.1.1...5.0.2)

Updates `@vue/cli-plugin-unit-mocha` from 4.5.15 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-unit-mocha)

---
updated-dependencies:
- dependency-name: flat
  dependency-type: indirect
- dependency-name: "@vue/cli-plugin-unit-mocha"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:57:00 -05:00
dependabot[bot] c8a9730ea1 build(deps-dev): bump axios from 1.2.1 to 1.2.2 (#14435)
Bumps [axios](https://github.com/axios/axios) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.2.1...1.2.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:56:28 -05:00
dependabot[bot] 652d792467 build(deps): bump json5 and tsconfig-paths (#14434)
Bumps [json5](https://github.com/json5/json5) and [tsconfig-paths](https://github.com/dividab/tsconfig-paths). These dependencies needed to be updated together.

Updates `json5` from 2.2.1 to 2.2.2
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.2)

Updates `tsconfig-paths` from 3.9.0 to 3.10.1
- [Release notes](https://github.com/dividab/tsconfig-paths/releases)
- [Changelog](https://github.com/dividab/tsconfig-paths/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dividab/tsconfig-paths/compare/v3.9.0...v3.10.1)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
- dependency-name: tsconfig-paths
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:56:02 -05:00
dependabot[bot] b9994f5c49 build(deps-dev): bump @babel/plugin-proposal-optional-chaining (#14426)
Bumps [@babel/plugin-proposal-optional-chaining](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-optional-chaining) from 7.18.9 to 7.20.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.7/packages/babel-plugin-proposal-optional-chaining)

---
updated-dependencies:
- dependency-name: "@babel/plugin-proposal-optional-chaining"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:48:33 -05:00
dependabot[bot] c164209c47 build(deps): bump jquery from 3.6.1 to 3.6.3 in /website/client (#14425)
Bumps [jquery](https://github.com/jquery/jquery) from 3.6.1 to 3.6.3.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.6.1...3.6.3)

---
updated-dependencies:
- dependency-name: jquery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-20 14:48:09 -05:00
SabreCat a8cb303f46 4.256.0 2023-01-10 08:47:00 -06:00
SabreCat 2f5fd4019d fix(admin): don't auto calculate Gem cap
also fixes .eslintrc to stop down prop mutations from error level
2023-01-09 16:08:54 -06:00
SabreCat d85436afbf Merge branch 'release' into develop 2023-01-09 15:53:16 -06:00
SabreCat d9455101d7 Merge branch 'release' into develop 2023-01-09 15:52:57 -06:00
Natalie L a80ac76015 chore(content): add January 2023 Backgrounds and Enchanted Armoire Item (#14440)
* chore: images & spritesheet

* chore: add january backgrounds and armoire item

* fix(backgrounds): typos and 2023 updates

Co-authored-by: SabreCat <sabe@habitica.com>
2023-01-09 15:39:04 -06:00
SabreCat dd569ab178 4.255.2 2023-01-06 15:54:13 -06:00
SabreCat 6726a2a7ac chore(subproj): update habitica-images 2023-01-06 15:54:09 -06:00
SabreCat 5dc372d143 fix(subs): better margins when subbed 2023-01-04 12:04:16 -06:00
SabreCat e251fad12c fix(subs): clarity and layout improvements 2023-01-03 17:05:48 -06:00
SabreCat 4fc880d6de 4.255.1 2022-12-29 11:09:09 -06:00
SabreCat f0c3be4800 fix(event): show NYE card on client 2022-12-29 11:07:17 -06:00
SabreCat c7aadede4d Merge branch 'release' into develop 2022-12-29 10:47:08 -06:00
SabreCat 5a07e5cbf3 4.255.0 2022-12-29 10:46:37 -06:00
Natalie L b1dab729b6 chore(content): january subscriber items (#14433)
Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-29 10:46:17 -06:00
SabreCat 95231b1ede chore(git): update subproject 2022-12-29 10:33:00 -06:00
SabreCat 43a196ffea 4.254.2 2022-12-28 11:43:07 -06:00
SabreCat f72224f9f1 fix(event): more date corrections 2022-12-28 11:42:56 -06:00
SabreCat ec2322bdd9 4.254.1 2022-12-27 11:59:21 -06:00
SabreCat 3adbc33546 fix(event): update Snowball dates 2022-12-27 11:59:15 -06:00
Weblate 37d48b3193 Merge branch 'origin/develop' into Weblate. 2022-12-23 22:38:30 +01:00
SabreCat b79f53a108 4.254.0 2022-12-23 15:35:50 -06:00
SabreCat 98c4910051 Merge branch 'release' into develop 2022-12-23 15:35:20 -06:00
Natalie L 55e7ef138e chore(content): add NYE party hat and migration script (#14419)
* chore(content): add NYE party hat and migration script

* chore(subproj): update habitica-images

* chore(sprites): corrected sprite CSS run

* fix(event): unbork migration, add latecomer hook

Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-23 15:35:23 -06:00
Weblate 474d3fb76f Translated using Weblate (Russian)
Currently translated at 98.5% (2707 of 2747 strings)

Translated using Weblate (Indonesian)

Currently translated at 93.2% (206 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Indonesian)

Currently translated at 84.6% (187 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 84.6% (187 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Indonesian)

Currently translated at 84.1% (186 of 221 strings)

Translated using Weblate (Russian)

Currently translated at 99.5% (237 of 238 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Russian)

Currently translated at 98.4% (2704 of 2747 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2747 of 2747 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Serbian)

Currently translated at 56.1% (419 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Serbian)

Currently translated at 75.6% (571 of 755 strings)

Translated using Weblate (Serbian)

Currently translated at 91.8% (124 of 135 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.5% (2734 of 2747 strings)

Translated using Weblate (Serbian)

Currently translated at 74.9% (566 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Serbian)

Currently translated at 23.9% (35 of 146 strings)

Translated using Weblate (Indonesian)

Currently translated at 89.7% (131 of 146 strings)

Translated using Weblate (French)

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2747 of 2747 strings)

Translated using Weblate (French)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (French)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2747 of 2747 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (238 of 238 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.5% (2736 of 2747 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.1% (2725 of 2747 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.0% (2720 of 2747 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.0% (2720 of 2747 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 96.6% (58 of 60 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (146 of 146 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Falzart Werefox <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fluffstuff <opositesandreality@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/id/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/sr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/sr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/it/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/sr/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/id/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/sr/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Faq
Translation: Habitica/Gear
Translation: Habitica/Limited
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Tasks
2022-12-23 22:12:37 +01:00
SabreCat b74c7aa009 chore(subproj): update module 2022-12-22 15:45:36 -06:00
SabreCat 825baaf7e9 fix(string): winter not spring 2022-12-20 10:05:31 -06:00
SabreCat 079279e5c1 Revert "fix(tests): if singleton event, always provide empty string suffix"
This reverts commit 64bf4ee4b6.
2022-12-20 09:51:24 -06:00
Weblate 01c7791fd9 Merge branch 'origin/develop' into Weblate. 2022-12-19 23:25:58 +01:00
Weblate 9ed06223e0 Translated using Weblate (Indonesian)
Currently translated at 88.1% (126 of 143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 60.0% (453 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2719 of 2719 strings)

Translated using Weblate (French)

Currently translated at 99.8% (2716 of 2719 strings)

Translated using Weblate (French)

Currently translated at 99.1% (2696 of 2719 strings)

Translated using Weblate (French)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (French)

Currently translated at 99.0% (739 of 746 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Polish)

Currently translated at 99.5% (743 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 59.8% (452 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (French)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Polish)

Currently translated at 98.9% (738 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (2703 of 2719 strings)

Translated using Weblate (Russian)

Currently translated at 99.8% (745 of 746 strings)

Translated using Weblate (French)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Spanish)

Currently translated at 94.9% (2581 of 2719 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (French)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (French)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Spanish)

Currently translated at 94.9% (2581 of 2719 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (2705 of 2719 strings)

Translated using Weblate (German)

Currently translated at 99.4% (742 of 746 strings)

Translated using Weblate (German)

Currently translated at 99.1% (740 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2719 of 2719 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2719 of 2719 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (German)

Currently translated at 99.0% (739 of 746 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2719 of 2719 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.9% (2718 of 2719 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Mara S. (Dolichotis) <marascherzer@gmail.com>
Co-authored-by: Marek Tomek <markowalzky2@gmail.com>
Co-authored-by: Muhammad Fauzi Ramadhan <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: そら <comi4work@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/id/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Communityguidelines
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Groups
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2022-12-19 23:25:48 +01:00
SabreCat 6d33ec02a8 Merge branch 'release' into develop 2022-12-19 16:24:48 -06:00
SabreCat c6d36ad6b1 4.253.0 2022-12-19 16:22:28 -06:00
SabreCat 64bf4ee4b6 fix(tests): if singleton event, always provide empty string suffix 2022-12-19 16:22:20 -06:00
Natalie L fd9d738cc6 chore(content): add winter wonderland items (#14407)
* chore(content): add winter wonderland items

* chore(typos): dates are hard

* fix(tz): how far back we have fallen

* fix(event): four extra hours for stragglers

* fix(typo): singular snowball spell

* fix(gear): remove stray incorrect event prop

* merge release

* Revert "merge release"

This reverts commit 83e29d0288.

* feat(content): add EN text

* fix(dates): 2022-2023 Winter

* chore(content): add featured quest bundle

* fix(event): delay Snowballs, add quests to Seasonal Shop

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-19 15:53:52 -06:00
dependabot[bot] 0d6dbfdc95 build(deps): bump bootstrap-vue from 2.22.0 to 2.23.1 in /website/client (#14323)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.22.0 to 2.23.1.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.22.0...v2.23.1)

---
updated-dependencies:
- dependency-name: bootstrap-vue
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:27:36 -05:00
dependabot[bot] 5162f8c2a0 build(deps): bump stripe from 10.13.0 to 11.4.0 (#14411)
Bumps [stripe](https://github.com/stripe/stripe-node) from 10.13.0 to 11.4.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v10.13.0...v11.4.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:24:37 -05:00
dependabot[bot] ae1c9c37c9 build(deps-dev): bump axios from 0.27.2 to 1.2.1 (#14397)
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 1.2.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.27.2...v1.2.1)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:22:03 -05:00
dependabot[bot] 0ed8a220d6 build(deps): bump uuid from 8.3.2 to 9.0.0 (#14209)
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.3.2 to 9.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.3.2...v9.0.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:20:13 -05:00
dependabot[bot] d2cbcbd062 build(deps-dev): bump sinon from 14.0.2 to 15.0.1 (#14412)
Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.2 to 15.0.1.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v14.0.2...v15.0.1)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:19:09 -05:00
dependabot[bot] 349a0eba44 build(deps): bump shell-quote and @storybook/vue in /website/client (#14398)
Bumps [shell-quote](https://github.com/ljharb/shell-quote) to 1.7.4 and updates ancestor dependency [@storybook/vue](https://github.com/storybookjs/storybook/tree/HEAD/app/vue). These dependencies need to be updated together.


Updates `shell-quote` from 1.7.2 to 1.7.4
- [Release notes](https://github.com/ljharb/shell-quote/releases)
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.7.2...v1.7.4)

Updates `@storybook/vue` from 6.3.13 to 6.5.14
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.14/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.5.14/app/vue)

---
updated-dependencies:
- dependency-name: shell-quote
  dependency-type: indirect
- dependency-name: "@storybook/vue"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-16 13:03:24 -05:00
dependabot[bot] 4f7ed6e7cc build(deps): bump core-js from 3.26.0 to 3.26.1 in /website/client (#14356)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.26.0 to 3.26.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.26.1/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-12-15 15:28:46 -06:00
Megan Searles 2eb7bab1dd WIP remove challenge tag from list if not in use (#14147)
* if tag not in use after leaving challenge, delete

* fix(tags): correct routing in store actions

Co-authored-by: Megan Shepherd <meg.d.shep@gmail.com>
Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-15 15:17:00 -06:00
dependabot[bot] 0224ce7e3e build(deps): bump chai from 4.3.6 to 4.3.7 in /website/client (#14363)
Bumps [chai](https://github.com/chaijs/chai) from 4.3.6 to 4.3.7.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v4.3.6...v4.3.7)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 15:13:25 -06:00
dependabot[bot] 0cbc2b5ffc build(deps): bump loader-utils from 2.0.3 to 2.0.4 (#14365)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.3 to 2.0.4.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v2.0.3...v2.0.4)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 15:13:06 -06:00
SabreCat 1f59d95465 Merge branch 'sabrecat/pass-change-max' into release 2022-12-15 15:02:05 -06:00
tvday cdd1bf1cf0 added field to updates to remove rewarded gear from pinned items, if present (#14406) 2022-12-15 14:48:22 -06:00
Patrick Delaney 7309ab4fd4 Update title in beforeDestroy() (#14408) 2022-12-15 14:48:08 -06:00
Adam Fitzgibbon 42e0bad4ac added validation for blocked users when inviting to groups by username (#14316) 2022-12-15 14:47:54 -06:00
dependabot[bot] 41cd99c920 build(deps): bump @babel/core from 7.19.6 to 7.20.5 (#14380)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.19.6 to 7.20.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.5/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 14:39:23 -06:00
dependabot[bot] 0902c63a79 build(deps): bump decode-uri-component in /website/client (#14384)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 14:39:01 -06:00
Phillip Thelen b97da5fe57 Add support for getting chat limit from database (#14392)
* Add support for getting chat limit from database

* fix lint error
2022-12-15 14:38:28 -06:00
dependabot[bot] 8a76561259 build(deps-dev): bump chalk from 5.1.2 to 5.2.0 (#14401)
Bumps [chalk](https://github.com/chalk/chalk) from 5.1.2 to 5.2.0.
- [Release notes](https://github.com/chalk/chalk/releases)
- [Commits](https://github.com/chalk/chalk/compare/v5.1.2...v5.2.0)

---
updated-dependencies:
- dependency-name: chalk
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 14:37:39 -06:00
dependabot[bot] d345e0d4a4 build(deps): bump amplitude-js from 8.21.1 to 8.21.3 in /website/client (#14402)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.21.1 to 8.21.3.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.21.1...v8.21.3)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 14:37:11 -06:00
dependabot[bot] 65ee50739f build(deps): bump superagent from 8.0.5 to 8.0.6 (#14403)
Bumps [superagent](https://github.com/ladjs/superagent) from 8.0.5 to 8.0.6.
- [Release notes](https://github.com/ladjs/superagent/releases)
- [Changelog](https://github.com/ladjs/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/ladjs/superagent/compare/v8.0.5...v8.0.6)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-15 14:36:53 -06:00
Phillip Thelen 2c9ee04c6d Optimise chat storage by not storing both equipped and costume (#14409)
* don’t store both equipped and costume

* fix lint
2022-12-15 14:30:15 -06:00
SabreCat 3893d38583 4.252.2 2022-12-15 14:04:45 -06:00
SabreCat 1587827b22 Merge branch 'develop' into release 2022-12-15 14:04:11 -06:00
SabreCat cfdef760d5 Revert "build(deps): bump passport from 0.5.0 to 0.6.0 (#14357)"
This reverts commit cf9fbd43bb.
2022-12-15 14:03:54 -06:00
Sabe Jones eb2cb9e921 Refactor FAQ (#14372)
* refactor(faq): fetch from API on web
Also make question list more maintainable, allowing different questions across platforms

* fix(tests): don't return null when function is expected
Also removes the unnecessary default to web in controller

* fix(tests): add new fields to expectation, add placeholders

* refactor(faq): allow reordering

Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-15 11:34:07 -06:00
SabreCat 591279c1a8 fix(dates): correct inconsistency 2022-12-15 09:00:12 -06:00
SabreCat ee91780f20 fix(typo): tomorrow and tomorrow 2022-12-14 14:41:33 -06:00
SabreCat a9629bdc0a 4.252.1 2022-12-14 14:13:42 -06:00
SabreCat 9c10cb3b88 chore(event): enable G1G1 promo 2022-12-14 14:13:36 -06:00
SabreCat 2d1fca402b 4.252.0 2022-12-13 14:51:53 -06:00
SabreCat a774d32b8a chore(subproj): update habitica-images 2022-12-13 14:51:42 -06:00
Natalie L 573c932565 chore(content): add Polar Pro achievement (#14399)
* chore(content): add Polar Pro achievement

* chore(script): add migration script

* fix(typo): rogue backticks

* fix(capitalization): revert css blurp

* fix(migration): no babby wuff

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-13 14:50:53 -06:00
dependabot[bot] 580139ff69 build(deps): bump express from 4.17.1 to 4.18.2 in /website/client (#14396)
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-08 10:10:07 -05:00
dependabot[bot] e0860e604e build(deps): bump qs from 6.5.2 to 6.5.3 (#14395)
Bumps [qs](https://github.com/ljharb/qs) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-08 10:09:34 -05:00
dependabot[bot] 9fc69456bb build(deps): bump qs from 6.5.2 to 6.5.3 in /website/client (#14394)
Bumps [qs](https://github.com/ljharb/qs) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-08 10:08:58 -05:00
Weblate 5bf14e05cc Merge branch 'origin/develop' into Weblate. 2022-12-06 20:49:01 +01:00
SabreCat 7d081056ba Merge branch 'release' into develop 2022-12-06 13:37:29 -06:00
Weblate 2ff7bef2a6 Merge branch 'origin/develop' into Weblate. 2022-12-06 20:36:09 +01:00
SabreCat 51b3b0c4c7 4.251.0 2022-12-06 13:34:53 -06:00
SabreCat 174a4e69f9 fix(backgrounds): we're in December now 2022-12-06 13:34:25 -06:00
Natalie L 1ce060eac6 chore(content): add December 2022 Backgrounds and Enchanted Armoire Items (#14382)
* chore(content): css and images

* chore(content): add December 2022 Backgrounds and Enchanted Armoire Items

* fix(typos): dots no dip

* fix(typo): capitalize game terms

* fix(typos): GitHub regex find, why

* fix(typo): last one maybe?

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-12-06 13:21:24 -06:00
Weblate 55f07f8ab2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (German)

Currently translated at 99.7% (737 of 739 strings)

Translated using Weblate (Korean)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Spanish)

Currently translated at 95.4% (2581 of 2705 strings)

Translated using Weblate (German)

Currently translated at 99.4% (735 of 739 strings)

Translated using Weblate (Ukrainian)

Currently translated at 59.4% (449 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.5% (663 of 2705 strings)

Translated using Weblate (Ukrainian)

Currently translated at 56.6% (428 of 755 strings)

Translated using Weblate (German)

Currently translated at 99.1% (733 of 739 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Spanish)

Currently translated at 97.7% (216 of 221 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 94.5% (714 of 755 strings)

Translated using Weblate (German)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Russian)

Currently translated at 93.2% (206 of 221 strings)

Translated using Weblate (German)

Currently translated at 99.0% (219 of 221 strings)

Translated using Weblate (German)

Currently translated at 98.6% (218 of 221 strings)

Translated using Weblate (Spanish)

Currently translated at 95.4% (2581 of 2705 strings)

Translated using Weblate (German)

Currently translated at 93.6% (207 of 221 strings)

Translated using Weblate (French)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (French)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (French)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (French)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (French)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (German)

Currently translated at 93.2% (206 of 221 strings)

Translated using Weblate (German)

Currently translated at 93.2% (206 of 221 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.4% (661 of 2705 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.3% (659 of 2705 strings)

Translated using Weblate (Ukrainian)

Currently translated at 55.8% (422 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 55.4% (419 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 54.0% (408 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 53.7% (406 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (374 of 374 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 94.1% (208 of 221 strings)

Translated using Weblate (Italian)

Currently translated at 96.3% (213 of 221 strings)

Translated using Weblate (German)

Currently translated at 92.7% (205 of 221 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.1% (654 of 2705 strings)

Translated using Weblate (Ukrainian)

Currently translated at 53.5% (404 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (German)

Currently translated at 92.3% (204 of 221 strings)

Translated using Weblate (Korean)

Currently translated at 75.0% (6 of 8 strings)

Translated using Weblate (Korean)

Currently translated at 77.7% (168 of 216 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (German)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Ukrainian)

Currently translated at 52.8% (399 of 755 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2705 of 2705 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Japanese)

Currently translated at 99.9% (2703 of 2705 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2705 of 2705 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 93.7% (708 of 755 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Korean)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 93.1% (703 of 755 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (Russian)

Currently translated at 99.8% (738 of 739 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (German)

Currently translated at 99.9% (2703 of 2705 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (739 of 739 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 51.9% (392 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Polish)

Currently translated at 64.8% (1754 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.8% (1753 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.7% (1752 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.6% (1749 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.6% (1748 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.5% (1747 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 64.5% (1746 of 2705 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 98.2% (57 of 58 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (374 of 374 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (German)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2705 of 2705 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.1% (652 of 2705 strings)

Translated using Weblate (Russian)

Currently translated at 99.8% (2702 of 2705 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2705 of 2705 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2705 of 2705 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 51.5% (389 of 755 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (German)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (German)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.1% (652 of 2701 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Ukrainian)

Currently translated at 50.5% (382 of 755 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 98.6% (141 of 143 strings)

Translated using Weblate (Bulgarian)

Currently translated at 65.0% (93 of 143 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (135 of 135 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 87.5% (2365 of 2701 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 96.5% (56 of 58 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 89.3% (193 of 216 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 96.9% (127 of 131 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.1% (651 of 2701 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 92.8% (701 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 49.8% (376 of 755 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 74.8% (95 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (374 of 374 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 93.7% (134 of 143 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 88.8% (192 of 216 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 95.5% (386 of 404 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (German)

Currently translated at 99.5% (402 of 404 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Polish)

Currently translated at 95.3% (204 of 214 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (181 of 181 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 99.0% (400 of 404 strings)

Translated using Weblate (German)

Currently translated at 99.0% (400 of 404 strings)

Translated using Weblate (German)

Currently translated at 99.0% (400 of 404 strings)

Translated using Weblate (German)

Currently translated at 99.0% (400 of 404 strings)

Translated using Weblate (German)

Currently translated at 99.0% (400 of 404 strings)

Translated using Weblate (German)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (German)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (German)

Currently translated at 100.0% (216 of 216 strings)

Translated using Weblate (German)

Currently translated at 100.0% (216 of 216 strings)

Translated using Weblate (German)

Currently translated at 97.7% (395 of 404 strings)

Translated using Weblate (German)

Currently translated at 97.7% (395 of 404 strings)

Translated using Weblate (German)

Currently translated at 97.7% (395 of 404 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (German)

Currently translated at 97.7% (395 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 47.6% (360 of 755 strings)

Translated using Weblate (German)

Currently translated at 97.7% (395 of 404 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 95.0% (384 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Ukrainian)

Currently translated at 47.2% (357 of 755 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2 of 2 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (German)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (German)

Currently translated at 97.5% (394 of 404 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (731 of 732 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.3% (142 of 143 strings)

Translated using Weblate (German)

Currently translated at 97.2% (393 of 404 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 85.1% (184 of 216 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Annika Frederike Schomber <nick.namen@gmx.de>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Danylo <nylo2005@gmail.com>
Co-authored-by: Dessie Z <desize1996@gmail.com>
Co-authored-by: Hexe des Windes (she/her) <krausanna1@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: IvorTheBoneless <bohdanfiloenko657@gmail.com>
Co-authored-by: KC <stuffr123456@gmail.com>
Co-authored-by: KanI <twinklingnerd@gmail.com>
Co-authored-by: Kedr <sergeysamori.ua@gmail.com>
Co-authored-by: Khsmty <me@taigasaito.org>
Co-authored-by: Lena Kubisa <lenorek.05.poczta@gmail.com>
Co-authored-by: Lio Zam <zerofux@web.de>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Mara S. (Dolichotis) <marascherzer@gmail.com>
Co-authored-by: Nakonana <nanaki1989@web.de>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Raithe <RaitheOfDureya@gmail.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sara López <sarayupy@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: Tobias Welti <tobias.welti@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Wolf Forst <wiesenkatz@proton.me>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: 박동훈 <creator98@naver.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hant_HK/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/content/it/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/front/de/
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/it/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/front/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/noscript/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/de/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/it/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hant/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Noscript
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2022-12-06 19:42:51 +01:00
SabreCat df25e0574d fix(auth): enforce max pass length at update 2022-12-05 16:36:42 -06:00
SabreCat 4fe8b63748 4.250.1 2022-12-05 14:47:18 -06:00
Natalie L b5c64185f0 chore(tavern): update to remove moderators from tavern (#14393)
* chore(tavern): update to remove moderators from tavern

* fix(tavern): additional cleanup, change string in Vue instead of Weblate

* fix(git): correct target branch

Co-authored-by: SabreCat <sabe@habitica.com>
2022-12-05 14:46:25 -06:00
dependabot[bot] debeee7569 build(deps): bump superagent from 8.0.4 to 8.0.5 (#14385)
Bumps [superagent](https://github.com/ladjs/superagent) from 8.0.4 to 8.0.5.
- [Release notes](https://github.com/ladjs/superagent/releases)
- [Changelog](https://github.com/ladjs/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/ladjs/superagent/compare/v8.0.4...v8.0.5)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 12:47:52 -05:00
dependabot[bot] 64b8a28363 build(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#14383)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 12:46:16 -05:00
SabreCat 894558f2df chore(images): update submodule 2022-12-02 13:21:32 -06:00
dependabot[bot] 57be0fbe45 build(deps): bump regenerator-runtime from 0.13.9 to 0.13.11 (#14370)
Bumps [regenerator-runtime](https://github.com/facebook/regenerator) from 0.13.9 to 0.13.11.
- [Release notes](https://github.com/facebook/regenerator/releases)
- [Commits](https://github.com/facebook/regenerator/compare/regenerator-runtime@0.13.9...regenerator-runtime@0.13.11)

---
updated-dependencies:
- dependency-name: regenerator-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 16:44:39 -05:00
dependabot[bot] cf9fbd43bb build(deps): bump passport from 0.5.0 to 0.6.0 (#14357)
Bumps [passport](https://github.com/jaredhanson/passport) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/jaredhanson/passport/releases)
- [Changelog](https://github.com/jaredhanson/passport/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jaredhanson/passport/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: passport
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 16:36:36 -05:00
SabreCat ea817eecf7 Merge branch 'release' into develop 2022-11-28 15:34:57 -06:00
SabreCat f1381878e7 4.250.0 2022-11-28 15:34:44 -06:00
Natalie L 9bd039b17b chore(content): add December 2022 Mystery Items (#14379)
* chore(submodule): images

* chore(content): December Mystery Items

* chore(content): sprites

* fix(typo): whitespace

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-11-28 15:34:18 -06:00
dependabot[bot] 8804892135 build(deps): bump superagent from 8.0.3 to 8.0.4 (#14375)
Bumps [superagent](https://github.com/visionmedia/superagent) from 8.0.3 to 8.0.4.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v8.0.3...v8.0.4)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 16:32:23 -05:00
SabreCat 90b34c4dac fix(shops): correct imports 2022-11-23 13:23:43 -06:00
SabreCat 96a919ed4b fix(shops): quest countdowns too 2022-11-23 13:13:06 -06:00
SabreCat e56b672226 4.249.7 2022-11-23 13:08:35 -06:00
SabreCat 91cbf7a2a9 fix(shops): show correct countdown outside of Gala 2022-11-23 13:08:23 -06:00
SabreCat 04e2a39a9f fix(test): rearrange for legacy event logic 2022-11-21 20:08:15 -06:00
SabreCat bdd926e110 4.249.6 2022-11-21 18:55:03 -06:00
SabreCat a8e9c9bc70 chore(event): set up Harvest Feast 2022 2022-11-21 18:54:57 -06:00
SabreCat 497073a714 4.249.5 2022-11-21 16:42:36 -06:00
SabreCat f1fa6a8456 Revert "Allow sub upgrades/downgrades on iOS (#14303)"
This reverts commit 9e98e56e9b.
2022-11-21 16:40:56 -06:00
prexio 3f690c24da Change Wikia to Fandom (#14291) 2022-11-18 16:54:12 -06:00
Natalie L f24d81d895 fix(content): quality of life change for staff and moderators (#14245)
* fix(content): quality of life change for staff and moderators

* fix(content): quality of life change for staff and moderators, I really mean it this time

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-11-18 16:52:09 -06:00
Sabe Jones 82c5e40b92 Enforce maximum password length (#14290)
* fix(auth): enforce maximum password length

* fix(auth): line length and better error message

* fix(auth): correctly import/export constant

Co-authored-by: SabreCat <sabe@habitica.com>
2022-11-18 16:49:10 -06:00
Adam Fitzgibbon 6b27e18699 add prop to task-wrapper so that the cursor remains consistant (#14302) 2022-11-18 16:48:34 -06:00
Adam Fitzgibbon 4f70a6fbf4 now grouping the stable A-Z sortBy option by first letter so that Show More functionality works like the other sort types (#14304) 2022-11-18 16:44:58 -06:00
Adam Fitzgibbon 300c2bb0a8 change currency to gold if the gear is owned (#14326)
* change currency to gold if the gear is owned

* fix linting error
2022-11-18 16:43:14 -06:00
Sky Chrastina 4b4f073089 Fix az sort (#14347)
* add stopword package

* sort pet and potion quests by stopword-ized text

* chore(package): revert package lock
Will update after merge

* fix(package): Friday brain

Co-authored-by: SabreCat <sabe@habitica.com>
2022-11-18 16:38:28 -06:00
Sky Chrastina 1d8e3d45a1 new check asset + css in shop, task, and buy gems (#14340) 2022-11-18 16:29:43 -06:00
Natalie L 116068effa fix(apiDescription): remove incorrect information (#14367) 2022-11-18 16:21:03 -06:00
SabreCat f2aaee15f3 Merge branch 'release' into develop 2022-11-18 15:29:06 -06:00
SabreCat 06a8d2bbd7 4.249.4 2022-11-18 15:12:32 -06:00
SabreCat 15353eba8a fix(subs): roll all the way back, didn't work :( 2022-11-18 15:12:14 -06:00
SabreCat febffb3f07 Revert "Fix double subscriptions, second attempt (#14345)"
This reverts commit 1a5cba57b7.
2022-11-18 14:26:49 -06:00
dependabot[bot] 25c7d52d6a build(deps-dev): bump chai from 4.3.6 to 4.3.7 (#14354)
Bumps [chai](https://github.com/chaijs/chai) from 4.3.6 to 4.3.7.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v4.3.6...v4.3.7)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-18 12:01:23 -05:00
dependabot[bot] 837c1c20a3 build(deps-dev): bump sinon from 14.0.1 to 14.0.2 (#14353)
Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.1 to 14.0.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v14.0.1...v14.0.2)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-18 12:01:06 -05:00
dependabot[bot] 02b11a61bc build(deps): bump dompurify from 2.4.0 to 2.4.1 in /website/client (#14352)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/2.4.0...2.4.1)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-18 12:00:51 -05:00
dependabot[bot] a0e28f7db4 build(deps): bump superagent from 8.0.2 to 8.0.3 (#14351)
Bumps [superagent](https://github.com/visionmedia/superagent) from 8.0.2 to 8.0.3.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v8.0.2...v8.0.3)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-18 12:00:34 -05:00
SabreCat fdfa2d6df4 Merge branch 'release' into develop 2022-11-15 19:29:37 -06:00
SabreCat 4fd2011be5 4.249.3 2022-11-15 19:29:18 -06:00
SabreCat 259131ee3f feat(transactions): UI updates
by @negue
2022-11-15 19:28:36 -06:00
Sabe Jones 1a5cba57b7 Fix double subscriptions, second attempt (#14345)
* fix(subscriptions): reject subs that come in too fast

* fix(lint): remove unused import

* fix(groups): individual subs may come rapidly

* fix(subscriptions): bad paren, handle rapid testing

* fix(test): reset dateUpdated between subs

* fix(test): one more block for dateUpdated

Co-authored-by: SabreCat <sabe@habitica.com>
2022-11-15 19:19:37 -06:00
SabreCat 5e05190f22 fix(event): start at 8AM not 8PM 2022-11-15 16:05:06 -06:00
SabreCat 81540ef399 fix(events): EST now not EDT 2022-11-14 14:38:58 -06:00
SabreCat 2bbff36cc8 4.249.2 2022-11-14 14:13:13 -06:00
SabreCat 9f52e47011 feat(content): November Quests and Hatching Potions
by @CuriousMagpie
2022-11-14 14:13:08 -06:00
Alys 4dca69f14b change the bannedWordUsed text as discussed with beffymaroo 2022-11-12 18:43:28 +10:00
dependabot[bot] 1378b1e1ad build(deps): bump @babel/preset-env from 7.19.1 to 7.20.2 (#14330)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.19.1 to 7.20.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.2/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 10:25:23 -05:00
dependabot[bot] 734a611a5c build(deps-dev): bump chalk from 5.1.0 to 5.1.2 (#14292)
Bumps [chalk](https://github.com/chalk/chalk) from 5.1.0 to 5.1.2.
- [Release notes](https://github.com/chalk/chalk/releases)
- [Commits](https://github.com/chalk/chalk/compare/v5.1.0...v5.1.2)

---
updated-dependencies:
- dependency-name: chalk
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 10:24:27 -05:00
SabreCat dbd485cb96 4.249.1 2022-11-09 16:11:49 -06:00
CuriousMagpie 4c62a48f5d chore(typo): who knew, that Y was actually important... 2022-11-09 16:11:45 -06:00
SabreCat 11496f3e0c Merge branch 'release' into develop 2022-11-09 15:33:32 -06:00
dependabot[bot] 9a3e3aaf42 build(deps): bump superagent from 8.0.2 to 8.0.3 (#14320)
Bumps [superagent](https://github.com/visionmedia/superagent) from 8.0.2 to 8.0.3.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v8.0.2...v8.0.3)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 14:16:10 -05:00
dependabot[bot] d9250fd780 build(deps): bump stripe from 10.13.0 to 10.16.0 (#14332)
Bumps [stripe](https://github.com/stripe/stripe-node) from 10.13.0 to 10.16.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v10.13.0...v10.16.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 16:27:13 -05:00
dependabot[bot] 70a5124815 build(deps): bump passport from 0.5.0 to 0.6.0 (#14341)
Bumps [passport](https://github.com/jaredhanson/passport) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/jaredhanson/passport/releases)
- [Changelog](https://github.com/jaredhanson/passport/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jaredhanson/passport/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: passport
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 16:26:14 -05:00
dependabot[bot] 532fa2816b build(deps): bump @babel/core from 7.19.6 to 7.20.2 (#14335)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.19.6 to 7.20.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.20.2/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 16:25:53 -05:00
dependabot[bot] d22f191f83 build(deps-dev): bump chai from 4.3.6 to 4.3.7 (#14342)
Bumps [chai](https://github.com/chaijs/chai) from 4.3.6 to 4.3.7.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v4.3.6...v4.3.7)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 16:25:20 -05:00
dependabot[bot] 2b49a800a5 build(deps-dev): bump sinon from 14.0.1 to 14.0.2 (#14343)
Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.1 to 14.0.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v14.0.1...v14.0.2)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 16:24:53 -05:00
SabreCat 0db927c726 4.249.0 2022-11-08 10:18:10 -06:00
SabreCat 6ee06f76e4 chore(i18n): update locale files
Also includes two fixes: empty Hourglass transaction logging and missing Recovery + Support guild category
2022-11-08 10:17:40 -06:00
SabreCat 978e8c4320 Merge branch 'release' into develop 2022-11-08 10:08:02 -06:00
Sabe Jones 5c7d537c61 Armoire and Backgrounds 2022/11 (#14329)
* chore(content): Add November Backgrounds and Enchanted Armoire Items

* fix(strings): typos and fullstops

* fix(style): de-whitespace

Co-authored-by: CuriousMagpie <eilatan@gmail.com>
2022-11-08 10:03:25 -06:00
Natalie L 0e6ece95a4 chore(fix): restore missing string (#14338)
* fix(string): questVice1Notes html changed to a mobile-device friendly format

* fix(strings): updated limited.json with "dateEnd" & "monthYYYY" months & put in chronological order

* fix(string): remove extra word from headSpecialSummer2022WarriorNotes

* fix(string): corrected armorSpecialSummer2022MageNotes

* fix: remove duplicated string and adjust upgrade button style

* fix(style): set border radii to 8px on upgrading-group id

* fix(payments): remove duplicate entry from another modal

* chore(fix): restore string inadvertently removed during a refactor

* chore(fix): comma dangle

Co-authored-by: SabreCat <sabe@habitica.com>
2022-11-08 09:59:40 -06:00
Weblate b08ed8b0fb Translated using Weblate (Spanish)
Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (German)

Currently translated at 97.0% (392 of 404 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 87.4% (2363 of 2701 strings)

Translated using Weblate (German)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (German)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 97.3% (735 of 755 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 90.9% (190 of 209 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 96.1% (126 of 131 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 88.1% (356 of 404 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.9% (2483 of 2701 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 95.0% (172 of 181 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (404 of 404 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (58 of 58 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 96.5% (390 of 404 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (143 of 143 strings)

Translated using Weblate (German)

Currently translated at 98.6% (141 of 143 strings)

Translated using Weblate (German)

Currently translated at 97.0% (391 of 403 strings)

Translated using Weblate (German)

Currently translated at 97.0% (391 of 403 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Dutch)

Currently translated at 88.1% (2381 of 2701 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Dutch)

Currently translated at 96.9% (710 of 732 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Spanish)

Currently translated at 95.5% (2581 of 2701 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.4% (728 of 732 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (German)

Currently translated at 99.1% (726 of 732 strings)

Translated using Weblate (German)

Currently translated at 100.0% (131 of 131 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Dante S <dantepicachu11@gmail.com>
Co-authored-by: Hexe des Windes (she/her) <krausanna1@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jonathan Garcia <jonathangarcia0@duck.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Mara S. (Dolichotis) <marascherzer@gmail.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Rhoslyn Ross <sofrdlf@vivaldi.net>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: UNI <nibi727171@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Wolf Forst <wiesenkatz@proton.me>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/de/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/it/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Groups
Translation: Habitica/Npc
Translation: Habitica/Questscontent
Translation: Habitica/Subscriber
2022-11-08 16:57:17 +01:00
SabreCat fafaa29d72 4.248.4 2022-11-04 16:10:31 -05:00
SabreCat 3a088de7e8 fix(package): roll back to Passport 0.5 2022-11-04 16:10:22 -05:00
SabreCat 835da85119 4.248.3 2022-11-02 15:18:19 -05:00
SabreCat f6e5360bdd Merge branch 'release' into develop 2022-11-02 14:54:09 -05:00
SabreCat eee8ad2029 fix(css): correct broken task creation dropdown on groups 2022-11-02 14:19:43 -05:00
SabreCat c7e73f9b85 4.248.2 2022-11-02 09:04:03 -05:00
SabreCat 9b1a726875 Revert "feat(subs): allow upgrade/downgrade on iOS"
This reverts commit 27440772f0.
2022-11-02 09:00:29 -05:00
Phillip Thelen 9e98e56e9b Allow sub upgrades/downgrades on iOS (#14303)
* Allow sub upgrades/downgrades on iOS

* fix check

* fix(lint): line length

* fix(typo): customER

* fix tests

* Implement correct handling for when subs are up/downgraded

* fix lint errors

* fix test

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-11-01 21:07:23 -05:00
Natalie L c16207c9ba Add Gift Messaging to Success Modal (#14270)
* initial commit: based on group-tracking-modal branch

* chore: merge group-tracking-modal

* update: create functions for each success condition

* chore: merge develop

* chore: work on successModal.vue & remove redundant code on groupPlan.vue

* update: remove `giftSubscriptionText4` from footer

* fix: correct groupPlan.vue file

* update: add messaging placeholder, clean up logic in a few places, update/add strings

* update: rearrange modal in order of display & test existence of 'gift-subscription' paymentType

* update: added props for receiverName so 'gift-subscription' works

* update: add close.svg & function
style: refactor CSS

* update: work on gift messaging

* update: work on gift messaging

* update: work on gift messaging

* update: let's make messages GO

* update: messages are a GO, we have LIFT OFF!

* fix: remove console log (oops)

Co-authored-by: SabreCat <sabe@habitica.com>
2022-11-01 20:55:40 -05:00
Weblate 53fb28cc48 Merge branch 'origin/develop' into Weblate. 2022-10-31 20:27:10 +01:00
SabreCat 1c0710b45b Merge branch 'release' into develop 2022-10-31 14:25:19 -05:00
Weblate 2add227b97 Translated using Weblate (Russian)
Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Russian)

Currently translated at 99.8% (2698 of 2701 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (732 of 732 strings)

Translated using Weblate (German)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2701 of 2701 strings)

Translated using Weblate (German)

Currently translated at 99.8% (2696 of 2701 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (732 of 732 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Mara S. (Dolichotis) <marascherzer@gmail.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translation: Habitica/Backgrounds
Translation: Habitica/Gear
Translation: Habitica/Subscriber
2022-10-31 17:53:38 +01:00
CuriousMagpie 4cc1f902c8 Merge remote-tracking branch 'upstream/develop' into develop 2022-10-31 10:47:24 -04:00
CuriousMagpie 1b52529822 chore(ladder update): 2022 Habitoween Ladder 2022-10-31 10:46:51 -04:00
Weblate 222ba544d7 Merge branch 'origin/develop' into Weblate. 2022-10-31 01:55:41 +01:00
SabreCat 2372efa22e Merge branch 'release' into develop 2022-10-30 19:54:18 -05:00
Weblate 18ec3eb355 Translated using Weblate (Spanish)
Currently translated at 95.7% (2581 of 2695 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 87.1% (2350 of 2695 strings)

Translated using Weblate (Spanish)

Currently translated at 95.7% (2581 of 2695 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (208 of 208 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 87.0% (2347 of 2695 strings)

Translated using Weblate (Spanish)

Currently translated at 95.7% (2580 of 2695 strings)

Translated using Weblate (Spanish)

Currently translated at 95.7% (2580 of 2695 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 87.0% (2345 of 2695 strings)

Translated using Weblate (Ukrainian)

Currently translated at 24.0% (647 of 2695 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (216 of 216 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (403 of 403 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2695 of 2695 strings)

Translated using Weblate (Ukrainian)

Currently translated at 23.4% (632 of 2695 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.9% (2343 of 2695 strings)

Translated using Weblate (German)

Currently translated at 95.5% (385 of 403 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.8% (2341 of 2695 strings)

Translated using Weblate (German)

Currently translated at 94.7% (382 of 403 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.7% (2339 of 2695 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Polish)

Currently translated at 74.1% (43 of 58 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.7% (2337 of 2695 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.5% (401 of 403 strings)

Translated using Weblate (Ukrainian)

Currently translated at 22.9% (619 of 2695 strings)

Translated using Weblate (Russian)

Currently translated at 99.8% (2692 of 2695 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.6% (2335 of 2695 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.6% (2334 of 2695 strings)

Translated using Weblate (Spanish)

Currently translated at 95.7% (2580 of 2695 strings)

Translated using Weblate (German)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2695 of 2695 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (403 of 403 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (216 of 216 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Spanish)

Currently translated at 99.5% (233 of 234 strings)

Translated using Weblate (Spanish)

Currently translated at 95.7% (2580 of 2695 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (755 of 755 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.5% (2332 of 2695 strings)

Translated using Weblate (German)

Currently translated at 91.5% (369 of 403 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 86.1% (2322 of 2695 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (216 of 216 strings)

Translated using Weblate (German)

Currently translated at 99.1% (232 of 234 strings)

Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: IvorTheBoneless <bohdanfiloenko657@gmail.com>
Co-authored-by: Lena Kubisa <lenorek.05.poczta@gmail.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Mara S. (Dolichotis) <marascherzer@gmail.com>
Co-authored-by: Sandra Marcial <sandramarcial80@gmail.com>
Co-authored-by: Sara López <sarayupy@gmail.com>
Co-authored-by: Sergey Shevelev <vlkgamer45@gmail.com>
Co-authored-by: UNI <nibi727171@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/de/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/es/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2022-10-28 18:35:58 +02:00
dependabot[bot] 62b4315b3d build(deps): bump apidoc from 0.53.0 to 0.53.1 (#14307)
Bumps [apidoc](https://github.com/apidoc/apidoc) from 0.53.0 to 0.53.1.
- [Release notes](https://github.com/apidoc/apidoc/releases)
- [Changelog](https://github.com/apidoc/apidoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/apidoc/apidoc/compare/0.53.0...0.53.1)

---
updated-dependencies:
- dependency-name: apidoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:24:26 -04:00
dependabot[bot] 56805e6c90 build(deps): bump rate-limiter-flexible from 2.3.11 to 2.4.0 (#14309)
Bumps [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) from 2.3.11 to 2.4.0.
- [Release notes](https://github.com/animir/node-rate-limiter-flexible/releases)
- [Commits](https://github.com/animir/node-rate-limiter-flexible/compare/v2.3.11...v2.4.0)

---
updated-dependencies:
- dependency-name: rate-limiter-flexible
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:23:56 -04:00
dependabot[bot] 0c6070dd9a build(deps): bump short-uuid from 4.2.0 to 4.2.2 (#14311)
Bumps [short-uuid](https://github.com/oculus42/short-uuid) from 4.2.0 to 4.2.2.
- [Release notes](https://github.com/oculus42/short-uuid/releases)
- [Changelog](https://github.com/oculus42/short-uuid/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/oculus42/short-uuid/commits)

---
updated-dependencies:
- dependency-name: short-uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:23:30 -04:00
dependabot[bot] 19c26c01e3 build(deps): bump @babel/core from 7.19.3 to 7.19.6 (#14312)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.19.3 to 7.19.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.19.6/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:23:09 -04:00
dependabot[bot] 0f3bc980d9 build(deps): bump smartbanner.js in /website/client (#14313)
Bumps [smartbanner.js](https://github.com/ain/smartbanner.js) from 1.19.0 to 1.19.1.
- [Release notes](https://github.com/ain/smartbanner.js/releases)
- [Commits](https://github.com/ain/smartbanner.js/compare/v1.19.0...v1.19.1)

---
updated-dependencies:
- dependency-name: smartbanner.js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:22:40 -04:00
dependabot[bot] 7f87120d34 build(deps): bump core-js from 3.25.5 to 3.26.0 in /website/client (#14314)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.25.5 to 3.26.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.26.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-28 11:22:19 -04:00
negue f7a03d2eb5 improve transactions logs + split createSubscription (#14289)
* improve transactions logs + split createSubscription
2022-10-27 08:39:06 +02:00
Sabe Jones 90250d1a25 Establish lock to avoid race scenario in subscriptions (#14267)
* fix(subscription): establish lock to avoid race scenario

* fix(lint): import syntax

* fix(lint): whitespace, dependency cycle

* fix(subs): skip locking on gifts and groups

* fix(subs): correctly reset _subSignature

* fix(sub): use findOneAndUpdate for unlock

* fix(test): save newly created user for some reason

Co-authored-by: SabreCat <sabe@habitica.com>
2022-10-25 16:44:33 -05:00
Gabriel Araujo 22a0c72f6e Update docker-compose.dev.yml to prevent error message on first build (#14178)
* Remove deprecated version element from top-level

* Remove unncessary image for client and server services

Co-authored-by: Gabriel Araujo <gabriel.goncalves@solarisbank.de>
2022-10-12 15:53:05 -05:00
Anton de Regt a4326498d1 Group category update issue (#14186)
* Overwrite arrays instead of merging

* Test removing a category

* Fix previous duplicated categories on group edit
2022-10-12 15:51:56 -05:00
Alex 8f26a22bd4 Update test.yml (#14187) 2022-10-12 15:47:46 -05:00
Antonio Sansotta 0b2cf5bceb Fixes issue #14175 - Consolidate Challenge category options list to common file (#14201)
* Issue #14175 - Created a categoryOptions.js file in website/common/script/content to store list of category Options. Imported and added the list to website/client/src/components : challenges/challengeModal, challenges/sidebar, groups/groupFormModal, and groups/groupSidebar. This replaced the statically typed lists that previously existed. Tested the challengeModal and sidebar but unable to test the groups files due to credit card requirements. -@Tundrian

* Issue #14175 - Created a categoryOptions.js file in website/common/script/content to store list of category Options. Imported and added the list to website/client/src/components : challenges/challengeModal, challenges/sidebar, groups/groupFormModal, and groups/groupSidebar. This replaced the statically typed lists that previously existed. Tested the challengeModal and sidebar but unable to test the groups files due to credit card requirements. -@Tundrian

Co-authored-by: SabreCat <sabe@habitica.com>
2022-10-12 15:46:36 -05:00
Sky Chrastina f43a0d8289 Add checkmark to completed quests in shop (#14269)
* add 'completed' property to quest items

* show checkmark on completed quests in the shop

* add 'completed' property to quest items

* show checkmark on completed quests in the shop
2022-10-12 15:44:22 -05:00
dependabot[bot] 39be8db4f9 build(deps): bump axios from 0.25.0 to 0.27.2 in /website/client (#14007)
Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 0.27.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.25.0...v0.27.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 17:34:16 -05:00
SabreCat f0a1f11a16 Merge branch 'release' into develop 2022-10-11 17:32:25 -05:00
dependabot[bot] 84c4b3536c build(deps): bump minimist, minimist and mkdirp in /website/client (#14286)
Bumps [minimist](https://github.com/minimistjs/minimist), [minimist](https://github.com/minimistjs/minimist) and [mkdirp](https://github.com/isaacs/node-mkdirp). These dependencies needed to be updated together.

Updates `minimist` from 1.2.5 to 1.2.7
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.7)

Updates `minimist` from 1.2.0 to 1.2.7
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.7)

Updates `mkdirp` from 0.5.1 to 0.5.6
- [Release notes](https://github.com/isaacs/node-mkdirp/releases)
- [Changelog](https://github.com/isaacs/node-mkdirp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-mkdirp/compare/0.5.1...v0.5.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: mkdirp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 15:53:10 -05:00
dependabot[bot] cf834f57d7 build(deps): bump ansi-html and webpack-dev-server in /website/client (#14285)
Removes [ansi-html](https://github.com/Tjatse/ansi-html). It's no longer used after updating ancestor dependency [webpack-dev-server](https://github.com/webpack/webpack-dev-server). These dependencies need to be updated together.


Removes `ansi-html`

Updates `webpack-dev-server` from 3.11.2 to 3.11.3
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/v3.11.3/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v3.11.2...v3.11.3)

---
updated-dependencies:
- dependency-name: ansi-html
  dependency-type: indirect
- dependency-name: webpack-dev-server
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 15:40:45 -05:00
dependabot[bot] 97be341ff6 build(deps): bump jwks-rsa from 2.1.4 to 2.1.5 (#14284)
Bumps [jwks-rsa](https://github.com/auth0/node-jwks-rsa) from 2.1.4 to 2.1.5.
- [Release notes](https://github.com/auth0/node-jwks-rsa/releases)
- [Changelog](https://github.com/auth0/node-jwks-rsa/blob/master/CHANGELOG.md)
- [Commits](https://github.com/auth0/node-jwks-rsa/compare/v2.1.4...v2.1.5)

---
updated-dependencies:
- dependency-name: jwks-rsa
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 15:40:30 -05:00
dependabot[bot] 15c68abafa build(deps): bump stripe from 8.222.0 to 10.13.0 (#14273)
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.222.0 to 10.13.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.222.0...v10.13.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 15:24:55 -05:00
dependabot[bot] 21a1b9449b build(deps): bump body-parser from 1.20.0 to 1.20.1 (#14271)
Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.20.0 to 1.20.1.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.20.0...1.20.1)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 15:22:57 -05:00
dependabot[bot] 0ec7784fb1 build(deps): bump @vue/cli-plugin-router in /website/client (#14121)
Bumps [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router) from 4.5.15 to 5.0.8.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-router)

---
updated-dependencies:
- dependency-name: "@vue/cli-plugin-router"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:59:32 -05:00
dependabot[bot] 9ddd0f29d0 build(deps): bump passport from 0.5.0 to 0.6.0 (#14043)
Bumps [passport](https://github.com/jaredhanson/passport) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/jaredhanson/passport/releases)
- [Changelog](https://github.com/jaredhanson/passport/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jaredhanson/passport/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: passport
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:57:26 -05:00
dependabot[bot] 37791dfe8d build(deps): bump intro.js from 5.1.0 to 6.0.0 in /website/client (#14122)
Bumps [intro.js](https://github.com/usablica/intro.js) from 5.1.0 to 6.0.0.
- [Release notes](https://github.com/usablica/intro.js/releases)
- [Commits](https://github.com/usablica/intro.js/compare/v5.1.0...v6.0.0)

---
updated-dependencies:
- dependency-name: intro.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:56:22 -05:00
dependabot[bot] 0322b657b8 build(deps): bump winston from 3.8.1 to 3.8.2 (#14221)
Bumps [winston](https://github.com/winstonjs/winston) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.8.1...v3.8.2)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:55:34 -05:00
dependabot[bot] cc39f6e4e9 build(deps): bump vue-router from 3.5.4 to 3.6.5 in /website/client (#14228)
Bumps [vue-router](https://github.com/vuejs/router) from 3.5.4 to 3.6.5.
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/commits)

---
updated-dependencies:
- dependency-name: vue-router
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:55:11 -05:00
dependabot[bot] 452b516c67 build(deps): bump amplitude-js from 8.21.0 to 8.21.1 in /website/client (#14248)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.21.0 to 8.21.1.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.21.0...v8.21.1)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:53:17 -05:00
dependabot[bot] 235eae32b0 build(deps): bump rate-limiter-flexible from 2.3.10 to 2.3.11 (#14249)
Bumps [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) from 2.3.10 to 2.3.11.
- [Release notes](https://github.com/animir/node-rate-limiter-flexible/releases)
- [Commits](https://github.com/animir/node-rate-limiter-flexible/commits)

---
updated-dependencies:
- dependency-name: rate-limiter-flexible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:52:59 -05:00
dependabot[bot] de9f1be7b9 build(deps): bump js2xmlparser from 4.0.2 to 5.0.0 (#14251)
Bumps [js2xmlparser](https://github.com/michaelkourlas/node-js2xmlparser) from 4.0.2 to 5.0.0.
- [Release notes](https://github.com/michaelkourlas/node-js2xmlparser/releases)
- [Changelog](https://github.com/michaelkourlas/node-js2xmlparser/blob/master/CHANGES.md)
- [Commits](https://github.com/michaelkourlas/node-js2xmlparser/compare/v4.0.2...v5.0.0)

---
updated-dependencies:
- dependency-name: js2xmlparser
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:51:58 -05:00
dependabot[bot] e75610447f build(deps): bump @hapi/hoek from 8.3.1 to 8.5.1 in /website/client (#14255)
Bumps [@hapi/hoek](https://github.com/hapijs/hoek) from 8.3.1 to 8.5.1.
- [Release notes](https://github.com/hapijs/hoek/releases)
- [Commits](https://github.com/hapijs/hoek/compare/v8.3.1...v8.5.1)

---
updated-dependencies:
- dependency-name: "@hapi/hoek"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:51:37 -05:00
dependabot[bot] bd4c65cd3e build(deps): bump @babel/core from 7.18.13 to 7.19.3 (#14256)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.18.13 to 7.19.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.19.3/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:50:39 -05:00
dependabot[bot] baf60dc951 build(deps): bump @google-cloud/trace-agent from 5.1.6 to 7.1.2 (#14259)
Bumps [@google-cloud/trace-agent](https://github.com/googleapis/cloud-trace-nodejs) from 5.1.6 to 7.1.2.
- [Release notes](https://github.com/googleapis/cloud-trace-nodejs/releases)
- [Changelog](https://github.com/googleapis/cloud-trace-nodejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/cloud-trace-nodejs/compare/v5.1.6...v7.1.2)

---
updated-dependencies:
- dependency-name: "@google-cloud/trace-agent"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:50:14 -05:00
dependabot[bot] 70e88d601c build(deps): bump superagent from 7.1.6 to 8.0.2 (#14272)
Bumps [superagent](https://github.com/visionmedia/superagent) from 7.1.6 to 8.0.2.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v7.1.6...v8.0.2)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:46:33 -05:00
dependabot[bot] 104ec60adb build(deps): bump bcrypt from 5.0.1 to 5.1.0 (#14274)
Bumps [bcrypt](https://github.com/kelektiv/node.bcrypt.js) from 5.0.1 to 5.1.0.
- [Release notes](https://github.com/kelektiv/node.bcrypt.js/releases)
- [Changelog](https://github.com/kelektiv/node.bcrypt.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kelektiv/node.bcrypt.js/compare/v5.0.1...v5.1.0)

---
updated-dependencies:
- dependency-name: bcrypt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:46:15 -05:00
dependabot[bot] e97454e0e7 build(deps): bump async from 2.6.3 to 3.2.3 (#14275)
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 3.2.3.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v3.2.3)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:45:14 -05:00
dependabot[bot] 144baa98b1 build(deps-dev): bump sinon from 13.0.2 to 14.0.1 (#14276)
Bumps [sinon](https://github.com/sinonjs/sinon) from 13.0.2 to 14.0.1.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v13.0.2...v14.0.1)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:44:22 -05:00
dependabot[bot] 02e33853b1 build(deps-dev): bump chalk from 4.1.2 to 5.1.0 (#14277)
Bumps [chalk](https://github.com/chalk/chalk) from 4.1.2 to 5.1.0.
- [Release notes](https://github.com/chalk/chalk/releases)
- [Commits](https://github.com/chalk/chalk/compare/v4.1.2...v5.1.0)

---
updated-dependencies:
- dependency-name: chalk
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:43:40 -05:00
dependabot[bot] 8c0d41d084 build(deps): bump express from 4.18.1 to 4.18.2 (#14280)
Bumps [express](https://github.com/expressjs/express) from 4.18.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.1...4.18.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:42:41 -05:00
dependabot[bot] 9d4f70371d build(deps): bump core-js from 3.24.1 to 3.25.5 in /website/client (#14282)
Bumps [core-js](https://github.com/zloirock/core-js) from 3.24.1 to 3.25.5.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.24.1...v3.25.5)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 14:42:22 -05:00
323 changed files with 15587 additions and 9249 deletions
@@ -0,0 +1,86 @@
/*
* Award Habitoween ladder items to participants in this month's Habitoween festivities
*/
/* eslint-disable no-console */
const MIGRATION_NAME = '20221031_habitoween_ladder'; // Update when running in future years
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {};
const inc = {
'items.food.Candy_Skeleton': 1,
'items.food.Candy_Base': 1,
'items.food.Candy_CottonCandyBlue': 1,
'items.food.Candy_CottonCandyPink': 1,
'items.food.Candy_Shade': 1,
'items.food.Candy_White': 1,
'items.food.Candy_Golden': 1,
'items.food.Candy_Zombie': 1,
'items.food.Candy_Desert': 1,
'items.food.Candy_Red': 1,
};
set.migration = MIGRATION_NAME;
if (user && user.items && user.items.pets && user.items.pets['JackOLantern-RoyalPurple']) {
set['items.mounts.JackOLantern-RoyalPurple'] = true;
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Glow']) {
set['items.pets.JackOLantern-RoyalPurple'] = 5;
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Glow']) {
set['items.mounts.JackOLantern-Glow'] = true;
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Ghost']) {
set['items.pets.JackOLantern-Glow'] = 5;
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Ghost']) {
set['items.mounts.JackOLantern-Ghost'] = true;
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Base']) {
set['items.pets.JackOLantern-Ghost'] = 5;
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Base']) {
set['items.mounts.JackOLantern-Base'] = true;
} else {
set['items.pets.JackOLantern-Base'] = 5;
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2022-10-01')},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,108 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20221213_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['BearCub-Base']
&& pets['BearCub-CottonCandyBlue']
&& pets['BearCub-CottonCandyPink']
&& pets['BearCub-Desert']
&& pets['BearCub-Golden']
&& pets['BearCub-Red']
&& pets['BearCub-Shade']
&& pets['BearCub-Skeleton']
&& pets['BearCub-White']
&& pets['BearCub-Zombie']
&& pets['Fox-Base']
&& pets['Fox-CottonCandyBlue']
&& pets['Fox-CottonCandyPink']
&& pets['Fox-Desert']
&& pets['Fox-Golden']
&& pets['Fox-Red']
&& pets['Fox-Shade']
&& pets['Fox-Skeleton']
&& pets['Fox-White']
&& pets['Fox-Zombie']
&& pets['Penguin-Base']
&& pets['Penguin-CottonCandyBlue']
&& pets['Penguin-CottonCandyPink']
&& pets['Penguin-Desert']
&& pets['Penguin-Golden']
&& pets['Penguin-Red']
&& pets['Penguin-Shade']
&& pets['Penguin-Skeleton']
&& pets['Penguin-White']
&& pets['Penguin-Zombie']
&& pets['Whale-Base']
&& pets['Whale-CottonCandyBlue']
&& pets['Whale-CottonCandyPink']
&& pets['Whale-Desert']
&& pets['Whale-Golden']
&& pets['Whale-Red']
&& pets['Whale-Shade']
&& pets['Whale-Skeleton']
&& pets['Whale-White']
&& pets['Whale-Zombie']
&& pets['Wolf-Base']
&& pets['Wolf-CottonCandyBlue']
&& pets['Wolf-CottonCandyPink']
&& pets['Wolf-Desert']
&& pets['Wolf-Golden']
&& pets['Wolf-Red']
&& pets['Wolf-Shade']
&& pets['Wolf-Skeleton']
&& pets['Wolf-White']
&& pets['Wolf-Zombie'] {
set['achievements.polarPro'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2022-11-01') },
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+144
View File
@@ -0,0 +1,144 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20221227_nye';
import { model as User } from '../../../website/server/models/user';
import { v4 as uuid } from 'uuid';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = { migration: MIGRATION_NAME };
let push;
if (typeof user.items.gear.owned.head_special_nye2021 !== 'undefined') {
set['items.gear.owned.head_special_nye2022'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2022',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2020 !== 'undefined') {
set['items.gear.owned.head_special_nye2021'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2021',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2019 !== 'undefined') {
set['items.gear.owned.head_special_nye2020'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2020',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2018 !== 'undefined') {
set['items.gear.owned.head_special_nye2019'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2019',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') {
set['items.gear.owned.head_special_nye2018'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2018',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') {
set['items.gear.owned.head_special_nye2017'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2017',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') {
set['items.gear.owned.head_special_nye2016'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2016',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
set['items.gear.owned.head_special_nye2015'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2015',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
set['items.gear.owned.head_special_nye2014'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2014',
_id: uuid(),
},
];
} else {
set['items.gear.owned.head_special_nye'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye',
_id: uuid(),
},
];
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
}
export default async function processUsers () {
let query = {
'auth.timestamps.loggedin': {$gt: new Date('2022-12-01')},
migration: {$ne: MIGRATION_NAME},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,88 @@
/* eslint-disable no-console */
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const MIGRATION_NAME = '20230123_habit_birthday';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count += 1;
const inc = { 'balance': 5 };
const set = {};
const push = {};
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.armor_special_birthday2022 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2023'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2021 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2022'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2020 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2021'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2019 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2020'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2018 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2019'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2017 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2018'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2016 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2017'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2015 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2016'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday !== 'undefined') {
set['items.gear.owned.armor_special_birthday2015'] = true;
} else {
set['items.gear.owned.armor_special_birthday'] = true;
}
push.notifications = {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_head_special_nye',
title: 'Birthday Bash Day 1!',
text: 'Enjoy your new Birthday Robe and 20 Gems on us!',
destination: 'equipment',
},
seen: false,
};
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: push}).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2022-12-23')},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,69 @@
/* eslint-disable no-console */
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const MIGRATION_NAME = '20230127_habit_birthday_day5';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count += 1;
const set = {};
const push = {};
set.migration = MIGRATION_NAME;
set['items.gear.owned.back_special_anniversary'] = true;
set['items.gear.owned.body_special_anniversary'] = true;
set['items.gear.owned.eyewear_special_anniversary'] = true;
push.notifications = {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_head_special_nye',
title: 'Birthday Bash Day 5!',
text: 'Come celebrate by wearing your new Habitica Hero Cape, Collar, and Mask!',
destination: 'equipment',
},
seen: false,
};
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: push}).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2022-12-23')},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,79 @@
/* eslint-disable no-console */
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const MIGRATION_NAME = '20230201_habit_birthday_day10';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count += 1;
const set = {
migration: MIGRATION_NAME,
'purchased.background.birthday_bash': true,
};
const push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_head_special_nye',
title: 'Birthday Bash Day 10!',
text: 'Join in for the end of our birthday celebrations with 10th Birthday background, Cake, and achievement!',
destination: 'backgrounds',
},
seen: false,
},
};
const inc = {
'items.food.Cake_Skeleton': 1,
'items.food.Cake_Base': 1,
'items.food.Cake_CottonCandyBlue': 1,
'items.food.Cake_CottonCandyPink': 1,
'items.food.Cake_Shade': 1,
'items.food.Cake_White': 1,
'items.food.Cake_Golden': 1,
'items.food.Cake_Zombie': 1,
'items.food.Cake_Desert': 1,
'items.food.Cake_Red': 1,
'achievements.habitBirthdays': 1,
};
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: push, $inc: inc }).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2022-12-23')},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+694 -1092
View File
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -1,11 +1,11 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.248.1",
"version": "4.261.1",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.19.3",
"@babel/preset-env": "^7.19.1",
"@babel/core": "^7.20.12",
"@babel/preset-env": "^7.20.2",
"@babel/register": "^7.18.9",
"@google-cloud/trace-agent": "^7.1.2",
"@parse/node-apn": "^5.1.3",
@@ -13,7 +13,7 @@
"accepts": "^1.3.8",
"amazon-payments": "^0.2.9",
"amplitude": "^6.0.0",
"apidoc": "^0.53.0",
"apidoc": "^0.53.1",
"apple-auth": "^1.0.7",
"bcrypt": "^5.1.0",
"body-parser": "^1.20.1",
@@ -54,24 +54,24 @@
"nconf": "^0.12.0",
"node-gcm": "^1.0.5",
"on-headers": "^1.0.2",
"passport": "^0.6.0",
"passport": "^0.5.0",
"passport-facebook": "^3.0.0",
"passport-google-oauth2": "^0.2.0",
"passport-google-oauth20": "2.0.0",
"paypal-rest-sdk": "^1.8.1",
"pp-ipn": "^1.1.0",
"ps-tree": "^1.0.0",
"rate-limiter-flexible": "^2.3.11",
"rate-limiter-flexible": "^2.4.0",
"redis": "^3.1.2",
"regenerator-runtime": "^0.13.9",
"regenerator-runtime": "^0.13.11",
"remove-markdown": "^0.5.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.0",
"stripe": "^10.13.0",
"superagent": "^8.0.2",
"short-uuid": "^4.2.2",
"stripe": "^11.6.0",
"superagent": "^8.0.6",
"universal-analytics": "^0.5.3",
"useragent": "^2.1.9",
"uuid": "^8.3.2",
"uuid": "^9.0.0",
"validator": "^13.7.0",
"vinyl-buffer": "^1.0.1",
"winston": "^3.8.2",
@@ -110,11 +110,11 @@
"apidoc": "gulp apidoc"
},
"devDependencies": {
"axios": "^0.27.2",
"chai": "^4.3.6",
"axios": "^1.2.2",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
"chai-moment": "^0.1.0",
"chalk": "^5.1.0",
"chalk": "^5.2.0",
"cross-spawn": "^7.0.3",
"expect.js": "^0.3.1",
"istanbul": "^1.1.0-alpha.1",
@@ -122,7 +122,7 @@
"monk": "^7.3.4",
"require-again": "^2.0.0",
"run-rs": "^0.7.7",
"sinon": "^14.0.1",
"sinon": "^15.0.1",
"sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0"
},
@@ -17,7 +17,7 @@ describe('Amazon Payments - Checkout', () => {
let closeOrderReferenceSpy;
let paymentBuyGemsStub;
let paymentCreateSubscritionStub;
let paymentCreateSubscriptionStub;
let amount = gemsBlock.price / 100;
function expectOrderReferenceSpy () {
@@ -85,8 +85,8 @@ describe('Amazon Payments - Checkout', () => {
paymentBuyGemsStub = sinon.stub(payments, 'buyGems');
paymentBuyGemsStub.resolves({});
paymentCreateSubscritionStub = sinon.stub(payments, 'createSubscription');
paymentCreateSubscritionStub.resolves({});
paymentCreateSubscriptionStub = sinon.stub(payments, 'createSubscription');
paymentCreateSubscriptionStub.resolves({});
sinon.stub(common, 'uuid').returns('uuid-generated');
sandbox.stub(gems, 'validateGiftMessage');
@@ -109,6 +109,7 @@ describe('Amazon Payments - Checkout', () => {
user,
paymentMethod,
headers,
sku: undefined,
};
if (gift) {
expectedArgs.gift = gift;
@@ -215,13 +216,14 @@ describe('Amazon Payments - Checkout', () => {
});
gift.member = receivingUser;
expect(paymentCreateSubscritionStub).to.be.calledOnce;
expect(paymentCreateSubscritionStub).to.be.calledWith({
expect(paymentCreateSubscriptionStub).to.be.calledOnce;
expect(paymentCreateSubscriptionStub).to.be.calledWith({
user,
paymentMethod: amzLib.constants.PAYMENT_METHOD_GIFT,
headers,
gift,
gemsBlock: undefined,
sku: undefined,
});
expectAmazonStubs();
});
+26 -127
View File
@@ -12,10 +12,10 @@ const { i18n } = common;
describe('Apple Payments', () => {
const subKey = 'basic_3mo';
describe('verifyGemPurchase', () => {
describe('verifyPurchase', () => {
let sku; let user; let token; let receipt; let
headers;
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let paymentBuyGemsStub; let
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let paymentBuySkuStub; let
iapGetPurchaseDataStub; let validateGiftMessageStub;
beforeEach(() => {
@@ -36,7 +36,7 @@ describe('Apple Payments', () => {
productId: 'com.habitrpg.ios.Habitica.21gems',
transactionId: token,
}]);
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
});
@@ -45,7 +45,7 @@ describe('Apple Payments', () => {
iap.validate.restore();
iap.isValidated.restore();
iap.getPurchaseData.restore();
payments.buyGems.restore();
payments.buySkuItem.restore();
gems.validateGiftMessage.restore();
});
@@ -54,7 +54,7 @@ describe('Apple Payments', () => {
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(false);
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
await expect(applePayments.verifyPurchase({ user, receipt, headers }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
@@ -66,7 +66,7 @@ describe('Apple Payments', () => {
iapGetPurchaseDataStub.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData').returns([]);
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
await expect(applePayments.verifyPurchase({ user, receipt, headers }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
@@ -76,7 +76,7 @@ describe('Apple Payments', () => {
it('errors if the user cannot purchase gems', async () => {
sinon.stub(user, 'canGetGems').resolves(false);
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
await expect(applePayments.verifyPurchase({ user, receipt, headers }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
@@ -94,14 +94,16 @@ describe('Apple Payments', () => {
productId: 'badProduct',
transactionId: token,
}]);
paymentBuySkuStub.restore();
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
await expect(applePayments.verifyPurchase({ user, receipt, headers }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
httpCode: 400,
name: 'BadRequest',
message: applePayments.constants.RESPONSE_INVALID_ITEM,
});
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
user.canGetGems.restore();
});
@@ -138,7 +140,7 @@ describe('Apple Payments', () => {
}]);
sinon.stub(user, 'canGetGems').resolves(true);
await applePayments.verifyGemPurchase({ user, receipt, headers });
await applePayments.verifyPurchase({ user, receipt, headers });
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
@@ -148,13 +150,13 @@ describe('Apple Payments', () => {
expect(iapGetPurchaseDataStub).to.be.calledOnce;
expect(validateGiftMessageStub).to.not.be.called;
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
expect(paymentBuySkuStub).to.be.calledOnce;
expect(paymentBuySkuStub).to.be.calledWith({
user,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
gemsBlock: common.content.gems[gemTest.gemsBlock],
headers,
gift: undefined,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
sku: gemTest.productId,
headers,
});
expect(user.canGetGems).to.be.calledOnce;
user.canGetGems.restore();
@@ -173,7 +175,7 @@ describe('Apple Payments', () => {
}]);
const gift = { uuid: receivingUser._id };
await applePayments.verifyGemPurchase({
await applePayments.verifyPurchase({
user, gift, receipt, headers,
});
@@ -187,18 +189,16 @@ describe('Apple Payments', () => {
expect(validateGiftMessageStub).to.be.calledOnce;
expect(validateGiftMessageStub).to.be.calledWith(gift, user);
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
expect(paymentBuySkuStub).to.be.calledOnce;
expect(paymentBuySkuStub).to.be.calledWith({
user,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
headers,
gift: {
type: 'gems',
gems: { amount: 4 },
member: sinon.match({ _id: receivingUser._id }),
uuid: receivingUser._id,
member: sinon.match({ _id: receivingUser._id }),
},
gemsBlock: common.content.gems['4gems'],
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
sku: 'com.habitrpg.ios.Habitica.4gems',
headers,
});
});
});
@@ -218,7 +218,6 @@ describe('Apple Payments', () => {
headers = {};
receipt = `{"token": "${token}"}`;
nextPaymentProcessing = moment.utc().add({ days: 2 });
user = new User();
iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
@@ -299,7 +298,6 @@ describe('Apple Payments', () => {
expirationDate: moment.utc().add({ day: 1 }).toDate(),
productId: option.sku,
transactionId: token,
originalTransactionId: token,
}]);
sub = common.content.subscriptionBlocks[option.subKey];
@@ -323,111 +321,12 @@ describe('Apple Payments', () => {
nextPaymentProcessing,
});
});
if (option !== subOptions[3]) {
const newOption = subOptions[3];
it(`upgrades a subscription from ${option.sku} to ${newOption.sku}`, async () => {
const oldSub = common.content.subscriptionBlocks[option.subKey];
user.profile.name = 'sender';
user.purchased.plan.paymentMethod = applePayments.constants.PAYMENT_METHOD_APPLE;
user.purchased.plan.customerId = token;
user.purchased.plan.planId = option.subKey;
user.purchased.plan.additionalData = receipt;
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{
expirationDate: moment.utc().add({ day: 2 }).toDate(),
productId: newOption.sku,
transactionId: `${token}new`,
originalTransactionId: token,
}]);
sub = common.content.subscriptionBlocks[newOption.subKey];
await applePayments.subscribe(newOption.sku,
user,
receipt,
headers,
nextPaymentProcessing);
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledWith(iap.APPLE, receipt);
expect(iapIsValidatedStub).to.be.calledOnce;
expect(iapIsValidatedStub).to.be.calledWith({});
expect(iapGetPurchaseDataStub).to.be.calledOnce;
expect(paymentsCreateSubscritionStub).to.be.calledOnce;
expect(paymentsCreateSubscritionStub).to.be.calledWith({
user,
customerId: token,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
sub,
headers,
additionalData: receipt,
nextPaymentProcessing,
updatedFrom: oldSub,
});
});
}
if (option !== subOptions[0]) {
const newOption = subOptions[0];
it(`downgrades a subscription from ${option.sku} to ${newOption.sku}`, async () => {
const oldSub = common.content.subscriptionBlocks[option.subKey];
user.profile.name = 'sender';
user.purchased.plan.paymentMethod = applePayments.constants.PAYMENT_METHOD_APPLE;
user.purchased.plan.customerId = token;
user.purchased.plan.planId = option.subKey;
user.purchased.plan.additionalData = receipt;
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{
expirationDate: moment.utc().add({ day: 2 }).toDate(),
productId: newOption.sku,
transactionId: `${token}new`,
originalTransactionId: token,
}]);
sub = common.content.subscriptionBlocks[newOption.subKey];
await applePayments.subscribe(newOption.sku,
user,
receipt,
headers,
nextPaymentProcessing);
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledWith(iap.APPLE, receipt);
expect(iapIsValidatedStub).to.be.calledOnce;
expect(iapIsValidatedStub).to.be.calledWith({});
expect(iapGetPurchaseDataStub).to.be.calledOnce;
expect(paymentsCreateSubscritionStub).to.be.calledOnce;
expect(paymentsCreateSubscritionStub).to.be.calledWith({
user,
customerId: token,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
sub,
headers,
additionalData: receipt,
nextPaymentProcessing,
updatedFrom: oldSub,
});
});
}
});
it('errors when a user is using the same subscription', async () => {
it('errors when a user is already subscribed', async () => {
payments.createSubscription.restore();
user = new User();
await user.save();
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{
expirationDate: moment.utc().add({ day: 1 }).toDate(),
productId: sku,
transactionId: token,
originalTransactionId: token,
}]);
await applePayments.subscribe(sku, user, receipt, headers, nextPaymentProcessing);
+34 -29
View File
@@ -12,11 +12,11 @@ const { i18n } = common;
describe('Google Payments', () => {
const subKey = 'basic_3mo';
describe('verifyGemPurchase', () => {
describe('verifyPurchase', () => {
let sku; let user; let token; let receipt; let signature; let
headers; const gemsBlock = common.content.gems['21gems'];
headers;
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
paymentBuyGemsStub; let validateGiftMessageStub;
paymentBuySkuStub; let validateGiftMessageStub;
beforeEach(() => {
sku = 'com.habitrpg.android.habitica.iap.21gems';
@@ -27,11 +27,10 @@ describe('Google Payments', () => {
iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
iapValidateStub = sinon.stub(iap, 'validate')
.resolves({});
iapValidateStub = sinon.stub(iap, 'validate').resolves({ productId: sku });
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
});
@@ -39,7 +38,7 @@ describe('Google Payments', () => {
iap.setup.restore();
iap.validate.restore();
iap.isValidated.restore();
payments.buyGems.restore();
payments.buySkuItem.restore();
gems.validateGiftMessage.restore();
});
@@ -48,7 +47,7 @@ describe('Google Payments', () => {
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(false);
await expect(googlePayments.verifyGemPurchase({
await expect(googlePayments.verifyPurchase({
user, receipt, signature, headers,
}))
.to.eventually.be.rejected.and.to.eql({
@@ -60,21 +59,25 @@ describe('Google Payments', () => {
it('should throw an error if productId is invalid', async () => {
receipt = `{"token": "${token}", "productId": "invalid"}`;
iapValidateStub.restore();
iapValidateStub = sinon.stub(iap, 'validate').resolves({});
await expect(googlePayments.verifyGemPurchase({
paymentBuySkuStub.restore();
await expect(googlePayments.verifyPurchase({
user, receipt, signature, headers,
}))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
httpCode: 400,
name: 'BadRequest',
message: googlePayments.constants.RESPONSE_INVALID_ITEM,
});
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
});
it('should throw an error if user cannot purchase gems', async () => {
sinon.stub(user, 'canGetGems').resolves(false);
await expect(googlePayments.verifyGemPurchase({
await expect(googlePayments.verifyPurchase({
user, receipt, signature, headers,
}))
.to.eventually.be.rejected.and.to.eql({
@@ -88,7 +91,7 @@ describe('Google Payments', () => {
it('purchases gems', async () => {
sinon.stub(user, 'canGetGems').resolves(true);
await googlePayments.verifyGemPurchase({
await googlePayments.verifyPurchase({
user, receipt, signature, headers,
});
@@ -101,15 +104,17 @@ describe('Google Payments', () => {
signature,
});
expect(iapIsValidatedStub).to.be.calledOnce;
expect(iapIsValidatedStub).to.be.calledWith({});
expect(iapIsValidatedStub).to.be.calledWith(
{ productId: sku },
);
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
expect(paymentBuySkuStub).to.be.calledOnce;
expect(paymentBuySkuStub).to.be.calledWith({
user,
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
gemsBlock,
headers,
gift: undefined,
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
sku,
headers,
});
expect(user.canGetGems).to.be.calledOnce;
user.canGetGems.restore();
@@ -120,7 +125,7 @@ describe('Google Payments', () => {
await receivingUser.save();
const gift = { uuid: receivingUser._id };
await googlePayments.verifyGemPurchase({
await googlePayments.verifyPurchase({
user, gift, receipt, signature, headers,
});
@@ -134,20 +139,20 @@ describe('Google Payments', () => {
signature,
});
expect(iapIsValidatedStub).to.be.calledOnce;
expect(iapIsValidatedStub).to.be.calledWith({});
expect(iapIsValidatedStub).to.be.calledWith(
{ productId: sku },
);
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
expect(paymentBuySkuStub).to.be.calledOnce;
expect(paymentBuySkuStub).to.be.calledWith({
user,
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
gemsBlock,
headers,
gift: {
type: 'gems',
gems: { amount: 21 },
member: sinon.match({ _id: receivingUser._id }),
uuid: receivingUser._id,
member: sinon.match({ _id: receivingUser._id }),
},
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
sku,
headers,
});
});
});
+24 -213
View File
@@ -11,10 +11,13 @@ import {
generateGroup,
} from '../../../../helpers/api-unit.helper';
import * as worldState from '../../../../../website/server/libs/worldState';
import { TransactionModel } from '../../../../../website/server/models/transaction';
describe('payments/index', () => {
let user; let group; let data; let
plan;
let user;
let group;
let data;
let plan;
beforeEach(async () => {
user = new User();
@@ -104,6 +107,23 @@ describe('payments/index', () => {
expect(recipient.purchased.plan.extraMonths).to.eql(3);
});
it('add a transaction entry to the recipient', async () => {
recipient.purchased.plan = plan;
expect(recipient.purchased.plan.extraMonths).to.eql(0);
await api.createSubscription(data);
expect(recipient.purchased.plan.extraMonths).to.eql(3);
const transactions = await TransactionModel
.find({ userId: recipient._id })
.sort({ createdAt: -1 })
.exec();
expect(transactions).to.have.lengthOf(1);
});
it('does not set negative extraMonths if plan has past dateTerminated date', async () => {
const dateTerminated = moment().subtract(2, 'months').toDate();
recipient.purchased.plan.dateTerminated = dateTerminated;
@@ -445,89 +465,6 @@ describe('payments/index', () => {
},
});
});
context('Upgrades subscription', () => {
it('from basic_earned to basic_6mo', async () => {
data.sub.key = 'basic_earned';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.customerId).to.eql('customer-id');
const created = user.purchased.plan.dateCreated;
const updated = user.purchased.plan.dateUpdated;
data.sub.key = 'basic_6mo';
data.updatedFrom = { key: 'basic_earned' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.dateCreated).to.eql(created);
expect(user.purchased.plan.dateUpdated).to.not.eql(updated);
expect(user.purchased.plan.customerId).to.eql('customer-id');
});
it('from basic_3mo to basic_12mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_3mo');
expect(user.purchased.plan.customerId).to.eql('customer-id');
const created = user.purchased.plan.dateCreated;
const updated = user.purchased.plan.dateUpdated;
data.sub.key = 'basic_12mo';
data.updatedFrom = { key: 'basic_3mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.dateCreated).to.eql(created);
expect(user.purchased.plan.dateUpdated).to.not.eql(updated);
expect(user.purchased.plan.customerId).to.eql('customer-id');
});
});
context('Downgrades subscription', () => {
it('from basic_6mo to basic_earned', async () => {
data.sub.key = 'basic_6mo';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.customerId).to.eql('customer-id');
const created = user.purchased.plan.dateCreated;
const updated = user.purchased.plan.dateUpdated;
data.sub.key = 'basic_earned';
data.updatedFrom = { key: 'basic_6mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.dateCreated).to.eql(created);
expect(user.purchased.plan.dateUpdated).to.not.eql(updated);
expect(user.purchased.plan.customerId).to.eql('customer-id');
});
it('from basic_12mo to basic_3mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
data.sub.key = 'basic_12mo';
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.customerId).to.eql('customer-id');
const created = user.purchased.plan.dateCreated;
const updated = user.purchased.plan.dateUpdated;
data.sub.key = 'basic_3mo';
data.updatedFrom = { key: 'basic_12mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_3mo');
expect(user.purchased.plan.dateCreated).to.eql(created);
expect(user.purchased.plan.dateUpdated).to.not.eql(updated);
expect(user.purchased.plan.customerId).to.eql('customer-id');
});
});
});
context('Block subscription perks', () => {
@@ -551,6 +488,7 @@ describe('payments/index', () => {
it('adds 10 to plan.consecutive.gemCapExtra for 6 month block', async () => {
data.sub.key = 'basic_6mo';
await api.createSubscription(data);
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
@@ -558,6 +496,7 @@ describe('payments/index', () => {
it('adds 20 to plan.consecutive.gemCapExtra for 12 month block', async () => {
data.sub.key = 'basic_12mo';
await api.createSubscription(data);
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
@@ -593,134 +532,6 @@ describe('payments/index', () => {
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
});
context('Upgrades subscription', () => {
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
data.sub.key = 'basic_earned';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
data.sub.key = 'basic_6mo';
data.updatedFrom = { key: 'basic_earned' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
});
it('Adds 15 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_3mo');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
data.sub.key = 'basic_12mo';
data.updatedFrom = { key: 'basic_3mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
});
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
data.sub.key = 'basic_earned';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
data.sub.key = 'basic_6mo';
data.updatedFrom = { key: 'basic_earned' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
});
it('Adds 3 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_3mo');
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
data.sub.key = 'basic_12mo';
data.updatedFrom = { key: 'basic_3mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
});
});
context('Downgrades subscription', () => {
it('does not remove from plan.consecutive.gemCapExtra from basic_6mo to basic_earned', async () => {
data.sub.key = 'basic_6mo';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
data.sub.key = 'basic_earned';
data.updatedFrom = { key: 'basic_6mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
});
it('does not remove from plan.consecutive.gemCapExtra from basic_12mo to basic_3mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
data.sub.key = 'basic_12mo';
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
data.sub.key = 'basic_3mo';
data.updatedFrom = { key: 'basic_12mo' };
await api.createSubscription(data);
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
});
it('does not remove from plan.consecutive.trinkets from basic_6mo to basic_earned', async () => {
data.sub.key = 'basic_6mo';
expect(user.purchased.plan.planId).to.not.exist;
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_6mo');
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
data.sub.key = 'basic_earned';
data.updatedFrom = { key: 'basic_6mo' };
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_earned');
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
});
it('does not remove from plan.consecutive.trinkets from basic_12mo to basic_3mo', async () => {
expect(user.purchased.plan.planId).to.not.exist;
data.sub.key = 'basic_12mo';
await api.createSubscription(data);
expect(user.purchased.plan.planId).to.eql('basic_12mo');
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
data.sub.key = 'basic_3mo';
data.updatedFrom = { key: 'basic_12mo' };
await api.createSubscription(data);
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
});
});
});
context('Mystery Items', () => {
@@ -0,0 +1,40 @@
import {
canBuySkuItem,
} from '../../../../../website/server/libs/payments/skuItem';
import { model as User } from '../../../../../website/server/models/user';
describe('payments/skuItems', () => {
let user;
let clock;
beforeEach(() => {
user = new User();
clock = null;
});
afterEach(() => {
if (clock !== null) clock.restore();
});
describe('#canBuySkuItem', () => {
it('returns true for random sku', () => {
expect(canBuySkuItem('something', user)).to.be.true;
});
describe('#gryphatrice', () => {
const sku = 'Pet-Gryphatrice-Jubilant';
it('returns true during birthday week', () => {
clock = sinon.useFakeTimers(new Date('2023-01-31'));
expect(canBuySkuItem(sku, user)).to.be.true;
});
it('returns false outside of birthday week', () => {
clock = sinon.useFakeTimers(new Date('2023-01-20'));
expect(canBuySkuItem(sku, user)).to.be.false;
});
it('returns false if user already owns it', () => {
clock = sinon.useFakeTimers(new Date('2023-02-01'));
user.items.pets['Gryphatrice-Jubilant'] = 5;
expect(canBuySkuItem(sku, user)).to.be.false;
});
});
});
});
@@ -541,6 +541,35 @@ describe('POST /chat', () => {
.to.eql(userWithStyle.preferences.background);
});
it('creates equipped to user styles', async () => {
const userWithStyle = await generateUser({
'preferences.costume': false,
'auth.timestamps.created': new Date('2022-01-01'),
});
await userWithStyle.sync();
const message = await userWithStyle.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
expect(message.message.id).to.exist;
expect(message.message.userStyles.items.gear.equipped)
.to.eql(userWithStyle.items.gear.equipped);
expect(message.message.userStyles.items.gear.costume).to.not.exist;
});
it('creates costume to user styles', async () => {
const userWithStyle = await generateUser({
'preferences.costume': true,
'auth.timestamps.created': new Date('2022-01-01'),
});
await userWithStyle.sync();
const message = await userWithStyle.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
expect(message.message.id).to.exist;
expect(message.message.userStyles.items.gear.costume).to.eql(userWithStyle.items.gear.costume);
expect(message.message.userStyles.items.gear.equipped).to.not.exist;
});
it('adds backer info to chat', async () => {
const backerInfo = {
npc: 'Town Crier',
@@ -66,7 +66,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
type: 'party',
privacy: 'private',
},
members: 1,
members: 2,
});
await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') });
@@ -76,12 +76,17 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
await admin.post(`/groups/${group._id}/chat/${privateMessage.id}/flag`);
// first test that the flag was actually successful
// author always sees own message; flag count is hidden from non-admins
let messages = await members[0].get(`/groups/${group._id}/chat`);
expect(messages[0].flagCount).to.eql(5);
expect(messages[0].flagCount).to.eql(0);
messages = await members[1].get(`/groups/${group._id}/chat`);
expect(messages.length).to.eql(0);
// admin cannot directly request private group chat, but after unflag,
// message should be revealed again and still have flagCount of 0
await admin.post(`/groups/${group._id}/chat/${privateMessage.id}/clearflags`);
messages = await members[0].get(`/groups/${group._id}/chat`);
messages = await members[1].get(`/groups/${group._id}/chat`);
expect(messages.length).to.eql(1);
expect(messages[0].flagCount).to.eql(0);
});
@@ -48,6 +48,19 @@ describe('Post /groups/:groupId/invite', () => {
});
});
it('returns error when recipient has blocked the senders', async () => {
const inviterNoBlocks = await inviter.update({ 'inbox.blocks': [] });
const userWithBlockedInviter = await generateUser({ 'inbox.blocks': [inviter._id] });
await expect(inviterNoBlocks.post(`/groups/${group._id}/invite`, {
usernames: [userWithBlockedInviter.auth.local.lowerCaseUsername],
}))
.to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
});
});
it('invites a user to a group by username', async () => {
const userToInvite = await generateUser();
@@ -21,11 +21,11 @@ describe('payments : apple #verify', () => {
let verifyStub;
beforeEach(async () => {
verifyStub = sinon.stub(applePayments, 'verifyGemPurchase').resolves({});
verifyStub = sinon.stub(applePayments, 'verifyPurchase').resolves({});
});
afterEach(() => {
applePayments.verifyGemPurchase.restore();
applePayments.verifyPurchase.restore();
});
it('makes a purchase', async () => {
@@ -21,11 +21,11 @@ describe('payments : google #verify', () => {
let verifyStub;
beforeEach(async () => {
verifyStub = sinon.stub(googlePayments, 'verifyGemPurchase').resolves({});
verifyStub = sinon.stub(googlePayments, 'verifyPurchase').resolves({});
});
afterEach(() => {
googlePayments.verifyGemPurchase.restore();
googlePayments.verifyPurchase.restore();
});
it('makes a purchase', async () => {
@@ -344,6 +344,24 @@ describe('POST /user/auth/local/register', () => {
});
});
it('enforces maximum length for the password', async () => {
const username = generateRandomUserName();
const email = `${username}@example.com`;
const password = '12345678910111213141516171819202122232425262728293031323334353637383940';
const confirmPassword = '12345678910111213141516171819202122232425262728293031323334353637383940';
await expect(api.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('requires a username', async () => {
const email = `${generateRandomUserName()}@example.com`;
const password = 'password';
@@ -96,6 +96,20 @@ describe('PUT /user/auth/update-password', async () => {
});
});
it('returns an error when newPassword is too long', async () => {
const body = {
password,
newPassword: '12345678910111213141516171819202122232425262728293031323334353637383940',
confirmPassword: '12345678910111213141516171819202122232425262728293031323334353637383940',
};
await expect(user.put(ENDPOINT, body)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('returns an error when confirmPassword is missing', async () => {
const body = {
password,
@@ -35,13 +35,6 @@ describe('GET /world-state', () => {
});
});
it('returns a string representing the current season for NPC sprites', async () => {
const res = await requester().get('/world-state');
expect(res).to.have.nested.property('npcImageSuffix');
expect(res.npcImageSuffix).to.be.a('string');
});
context('no current event', () => {
beforeEach(async () => {
sinon.stub(worldState, 'getCurrentEvent').returns(null);
+4
View File
@@ -37,6 +37,8 @@ describe('GET /faq', () => {
expect(res).to.have.property('questions');
expect(res.questions[0]).to.eql({
exclusions: [],
heading: 'overview',
question: translate('faqQuestion0'),
ios: translate('iosFaqAnswer0'),
});
@@ -57,6 +59,8 @@ describe('GET /faq', () => {
expect(res).to.have.property('questions');
expect(res.questions[0]).to.eql({
exclusions: [],
heading: 'overview',
question: translate('faqQuestion0'),
android: translate('androidFaqAnswer0'),
});
+7366 -5569
View File
File diff suppressed because it is too large Load Diff
+12 -11
View File
@@ -18,22 +18,22 @@
"@storybook/addon-links": "6.5.8",
"@storybook/addon-notes": "5.3.21",
"@storybook/addons": "6.5.9",
"@storybook/vue": "6.3.13",
"@vue/cli-plugin-babel": "^4.5.15",
"@storybook/vue": "6.5.14",
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-eslint": "^4.5.19",
"@vue/cli-plugin-router": "^5.0.8",
"@vue/cli-plugin-unit-mocha": "^4.5.15",
"@vue/cli-plugin-unit-mocha": "^5.0.8",
"@vue/cli-service": "^4.5.15",
"@vue/test-utils": "1.0.0-beta.29",
"amplitude-js": "^8.21.1",
"amplitude-js": "^8.21.3",
"axios": "^0.27.2",
"axios-progress-bar": "^1.2.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.6.0",
"bootstrap-vue": "^2.22.0",
"chai": "^4.3.6",
"core-js": "^3.25.5",
"dompurify": "^2.4.0",
"bootstrap-vue": "^2.23.1",
"chai": "^4.3.7",
"core-js": "^3.27.2",
"dompurify": "^2.4.1",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
@@ -42,13 +42,14 @@
"hellojs": "^1.19.5",
"inspectpack": "^4.7.1",
"intro.js": "^6.0.0",
"jquery": "^3.6.1",
"jquery": "^3.6.3",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"nconf": "^0.12.0",
"sass": "^1.34.0",
"sass-loader": "^8.0.2",
"smartbanner.js": "^1.19.0",
"smartbanner.js": "^1.19.1",
"stopword": "^2.0.5",
"svg-inline-loader": "^0.8.2",
"svg-url-loader": "^7.1.1",
"svgo": "^1.3.2",
@@ -65,6 +66,6 @@
"webpack": "^4.46.0"
},
"devDependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.18.9"
"@babel/plugin-proposal-optional-chaining": "^7.20.7"
}
}
+6
View File
@@ -35,6 +35,7 @@
<sub-canceled-modal v-if="isUserLoaded" />
<bug-report-modal v-if="isUserLoaded" />
<bug-report-success-modal v-if="isUserLoaded" />
<birthday-modal />
<snackbars />
<router-view v-if="!isUserLoggedIn || isStaticPage" />
<template v-else>
@@ -42,6 +43,7 @@
<damage-paused-banner />
<gems-promo-banner />
<gift-promo-banner />
<birthday-banner />
<notifications-display />
<app-menu />
<div
@@ -153,11 +155,13 @@
import axios from 'axios';
import { loadProgressBar } from 'axios-progress-bar';
import birthdayModal from '@/components/news/birthdayModal';
import AppMenu from './components/header/menu';
import AppHeader from './components/header/index';
import DamagePausedBanner from './components/header/banners/damagePaused';
import GemsPromoBanner from './components/header/banners/gemsPromo';
import GiftPromoBanner from './components/header/banners/giftPromo';
import BirthdayBanner from './components/header/banners/birthdayBanner';
import AppFooter from './components/appFooter';
import notificationsDisplay from './components/notifications';
import snackbars from './components/snackbars/notifications';
@@ -191,9 +195,11 @@ export default {
AppMenu,
AppHeader,
AppFooter,
birthdayModal,
DamagePausedBanner,
GemsPromoBanner,
GiftPromoBanner,
BirthdayBanner,
notificationsDisplay,
snackbars,
BuyModal,
@@ -156,6 +156,12 @@
height: 99px;
}
.Pet-Gryphatrice-Jubilant {
background: url("https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Gryphatrice-Jubilant.gif") no-repeat;
width: 81px;
height: 96px;
}
.Mount_Head_Gryphon-Gryphatrice, .Mount_Body_Gryphon-Gryphatrice {
width: 135px;
height: 135px;
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,61 @@
<svg width="199" height="24" viewBox="0 0 199 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#c19w6aye5a)" fill="#fff">
<path d="M56.47 18.83V6.003L56 3.662l.47-1.405h8.942c1.773 0 3.193.344 4.26 1.03 1.066.687 1.6 1.733 1.6 3.137 0 .765-.142 1.397-.424 1.896a4.175 4.175 0 0 1-1.035 1.24 4.14 4.14 0 0 1 1.505.703c.471.327.855.772 1.154 1.334.297.546.447 1.225.447 2.036 0 1.639-.487 2.918-1.46 3.839-.956.905-2.502 1.358-4.635 1.358H56.471zm5.177-10.136h2.777c.533 0 .918-.078 1.153-.234.235-.171.353-.429.353-.772 0-.359-.173-.609-.518-.75-.345-.155-.753-.233-1.223-.233h-2.542v1.99zm0 5.688h4c.628 0 1.067-.093 1.318-.28a.974.974 0 0 0 .377-.796c0-.75-.486-1.124-1.46-1.124h-4.235v2.2zM75.515 18.83V6.003l-.236-2.341.236-1.405h5.2V18.83h-5.2zM84 18.83V6.026l-.471-2.364.47-1.405h8.472c1.27 0 2.36.203 3.27.61.91.405 1.608 1.06 2.095 1.965.486.89.73 2.068.73 3.535 0 1.357-.228 2.473-.683 3.347a4.552 4.552 0 0 1-2 1.99l.4.327 1.623 2.2 1.341 1.194v1.405h-6.235l-2.588-4.284h-1.248v.515l.236 2.34-.236 1.429H84zm5.176-8.66h1.365c.55 0 1.02-.024 1.412-.071.408-.047.722-.187.941-.421.22-.25.33-.648.33-1.194 0-.578-.118-.991-.353-1.24-.236-.25-.565-.399-.989-.446a9.614 9.614 0 0 0-1.435-.093h-1.506l.235 3.464zM104.666 18.83V6.728l-4.706.234V2.257h14.707v4.705l-4.824-.234v8.357l.259 2.34-.259 1.405h-5.177zM116.785 18.83V6.026l-.235-2.34.235-1.429h5.177v6.344h4.918V2.257h5.177v8.802l.235 1.615v6.156h-5.412v-5.946h-4.918v1.639l.235 4.307h-5.412zM135.588 18.83V6.026l-.471-2.34.471-1.429h7.977c1.114 0 2.188.11 3.223.328 1.051.203 1.985.593 2.801 1.17.831.578 1.49 1.405 1.976 2.482.486 1.076.73 2.473.73 4.19 0 1.716-.251 3.128-.753 4.236-.487 1.092-1.146 1.943-1.977 2.552a7.477 7.477 0 0 1-2.8 1.264 14.463 14.463 0 0 1-3.2.35h-7.977zm5.224-4.448h1.788c.926 0 1.702-.101 2.33-.304a2.498 2.498 0 0 0 1.458-1.147c.33-.577.495-1.412.495-2.504 0-1.108-.173-1.92-.518-2.435-.33-.53-.816-.874-1.459-1.03-.628-.171-1.396-.257-2.306-.257h-1.788v7.677zM153.013 18.83l1.13-3.956V11.9l1.741-.702 3.294-8.918h7.083l4.024 10.486 1.812 3.324v2.739h-5.106l-1.177-3.488h-6.377l-1.012 3.488h-5.412zm7.977-7.584h3.53l-1.553-4.658h-.494l-1.483 4.658zM176.04 18.83v-6.788l-5.835-8.38V2.257h5.906l2.353 4.822h.47l2.33-4.822h5.883v1.405l-6.001 8.52.141 2.364v4.284h-5.247zM191.923 12.72l-2.07-8.847L192.676 2l2.8 1.896-2.141 8.824h-1.412zm.518 7.28-3.059-3.043 3.059-3.043 3.059 3.043L192.441 20z"/>
</g>
<g filter="url(#s1alkvv8kb)">
<path d="M5.87 18.825V7.601H3V3.17l8.228-.937.239 1.406-.24 2.344v12.841H5.87z" fill="url(#xidihnl5xc)"/>
<path d="M21.258 19.06a9.043 9.043 0 0 1-2.87-.446 6.484 6.484 0 0 1-2.369-1.453c-.67-.671-1.195-1.546-1.578-2.624-.383-1.094-.574-2.43-.574-4.007 0-1.562.191-2.883.574-3.96.382-1.094.909-1.977 1.578-2.648a6.092 6.092 0 0 1 2.368-1.453A8.63 8.63 0 0 1 21.257 2c1.356 0 2.584.281 3.684.844 1.116.562 2.001 1.468 2.655 2.718.67 1.234 1.004 2.89 1.004 4.968s-.335 3.741-1.004 4.991c-.654 1.25-1.539 2.156-2.655 2.718-1.1.547-2.328.82-3.683.82zm0-5.039c.701 0 1.187-.25 1.459-.75.27-.5.406-1.413.406-2.741 0-1.313-.136-2.219-.407-2.719-.27-.515-.757-.773-1.459-.773-.685 0-1.18.258-1.483.773-.287.516-.43 1.422-.43 2.719 0 1.312.143 2.226.43 2.742.303.5.798.75 1.483.75z" fill="url(#9hqzmmkygd)"/>
<path d="M32.721 12.014V4.745l-2.87.14V2.06h8.97v2.826l-2.943-.141v5.02l.158 1.405-.158.844h-3.157z" fill="url(#bzq8gpt5ve)"/>
<path d="M40.543 12.014v-7.69l-.144-1.407.144-.857H43.7v3.81h3V2.06h3.156v5.286l.144.97v3.698h-3.3V8.443h-3v.984l.143 2.587h-3.3z" fill="url(#4t6arxwa4f)"/>
</g>
<defs>
<linearGradient id="xidihnl5xc" x1="3" y1="2" x2="29.822" y2="35.308" gradientUnits="userSpaceOnUse">
<stop stop-color="#6133B4"/>
<stop offset="1" stop-color="#4F2A93"/>
</linearGradient>
<linearGradient id="9hqzmmkygd" x1="3" y1="2" x2="29.822" y2="35.308" gradientUnits="userSpaceOnUse">
<stop stop-color="#6133B4"/>
<stop offset="1" stop-color="#4F2A93"/>
</linearGradient>
<linearGradient id="bzq8gpt5ve" x1="3" y1="2" x2="29.822" y2="35.308" gradientUnits="userSpaceOnUse">
<stop stop-color="#6133B4"/>
<stop offset="1" stop-color="#4F2A93"/>
</linearGradient>
<linearGradient id="4t6arxwa4f" x1="3" y1="2" x2="29.822" y2="35.308" gradientUnits="userSpaceOnUse">
<stop stop-color="#6133B4"/>
<stop offset="1" stop-color="#4F2A93"/>
</linearGradient>
<filter id="c19w6aye5a" x="53" y="0" width="145.5" height="24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.101961 0 0 0 0 0.0941176 0 0 0 0 0.113725 0 0 0 0.12 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_45_799"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.101961 0 0 0 0 0.0941176 0 0 0 0 0.113725 0 0 0 0.24 0"/>
<feBlend in2="effect1_dropShadow_45_799" result="effect2_dropShadow_45_799"/>
<feBlend in="SourceGraphic" in2="effect2_dropShadow_45_799" result="shape"/>
</filter>
<filter id="s1alkvv8kb" x="0" y="0" width="53" height="23.059" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.101961 0 0 0 0 0.0941176 0 0 0 0 0.113725 0 0 0 0.12 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_45_799"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.101961 0 0 0 0 0.0941176 0 0 0 0 0.113725 0 0 0 0.24 0"/>
<feBlend in2="effect1_dropShadow_45_799" result="effect2_dropShadow_45_799"/>
<feBlend in="SourceGraphic" in2="effect2_dropShadow_45_799" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

@@ -0,0 +1,22 @@
<svg width="58" height="48" viewBox="0 0 58 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="m16.853 4.36 7.959-1.453-2.71 7.556-2.708 7.557-5.25-6.103-5.25-6.103 7.959-1.453z" fill="#5DDEAB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.771 1.454 40.731 0l-2.71 7.556-2.709 7.556-5.25-6.102-5.25-6.103 7.96-1.453z" fill="#5DDEAB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m43.272 13.659-7.96 1.453 2.71-7.556L40.73 0l5.25 6.103 5.25 6.102-7.96 1.454z" fill="#38C38D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m27.353 16.566-7.96 1.453 2.71-7.556 2.709-7.556 5.25 6.103 5.25 6.102-7.96 1.454zM11.434 19.473l-7.959 1.453 2.71-7.556 2.708-7.556 5.25 6.103 5.25 6.102-7.959 1.454z" fill="#B0F1D7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m3.475 20.926 28.05 18.662L19.394 18.02 3.475 20.926z" fill="#38C38D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.249 12.202 31.525 39.588l3.805-24.48 15.919-2.906z" fill="#B0F1D7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m19.394 18.02 12.131 21.568 3.787-24.476-15.918 2.907z" fill="#5DDEAB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m51.904 26.44-3.832-.897 1.132 3.736 1.132 3.737 2.7-2.84 2.7-2.84-3.832-.896zM44.24 24.647l-3.832-.897 1.132 3.736 1.132 3.736 2.7-2.84 2.7-2.839-3.832-.896z" fill="#87E3E1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m38.84 30.326 3.832.896-1.132-3.736-1.132-3.736-2.7 2.84-2.7 2.839 3.832.897zM46.504 32.12l3.832.896-1.132-3.736-1.132-3.737-2.7 2.84-2.7 2.84 3.832.896z" fill="#C0FBFA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.168 33.912 58 34.81l-1.132-3.736-1.133-3.736-2.7 2.84-2.7 2.839 3.833.896z" fill="#5EC5C2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m58 34.81-14.084 8.395 6.42-10.19L58 34.81z" fill="#C0FBFA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m35 29.427 8.916 13.779-1.252-11.986L35 29.427z" fill="#5EC5C2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m50.336 33.016-6.42 10.19-1.244-11.984 7.664 1.794z" fill="#87E3E1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m16.877 22.666-5.078 1.971 4.262 3.372 4.262 3.37.816-5.341.816-5.343-5.078 1.971zM6.721 26.609l-5.078 1.97 4.262 3.372 4.262 3.371.816-5.342.816-5.343-5.078 1.972z" fill="#7BE3CF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m5.09 37.294 5.077-1.972-4.262-3.371-4.261-3.371-.817 5.342-.816 5.343 5.078-1.971z" fill="#C5F3EA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m15.245 33.351 5.078-1.971-4.262-3.371-4.262-3.371-.816 5.342-.816 5.342 5.078-1.97z" fill="#C5F3EA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m25.4 29.41 5.078-1.972-4.262-3.371-4.261-3.372-.816 5.343-.816 5.342 5.078-1.97z" fill="#41C7AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.478 27.438 21.117 48l-.794-16.62 10.155-3.942z" fill="#C5F3EA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m0 39.269 21.117 8.73-10.961-12.672L0 39.269z" fill="#41C7AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.323 31.38 21.117 48l-10.95-12.678 10.156-3.942z" fill="#7BE3CF"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

+2 -2
View File
@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="10" viewBox="0 0 13 10">
<path fill-rule="evenodd" d="M4.662 9.832c-.312 0-.61-.123-.831-.344L0 5.657l1.662-1.662 2.934 2.934L10.534 0l1.785 1.529-6.764 7.893a1.182 1.182 0 0 1-.848.409l-.045.001"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="M6.54,13c-.3,0-.59-.13-.81-.35l-3.73-3.9,1.62-1.69,2.86,2.98L12.26,3l1.74,1.56L7.41,12.58c-.21,.25-.51,.4-.83,.42-.01,0-.03,0-.04,0Z" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 236 B

@@ -0,0 +1,22 @@
<svg width="518" height="152" viewBox="0 0 518 152" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M144.48 65.487v5.042h-1.772v-5.042h1.772zm1.621 6.671h5.013v1.782h-5.013v-1.782zm-10.027 0h5.013v1.782h-5.013v-1.782zm8.406 3.412v5.041h-1.772V75.57h1.772z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".5"/>
<path opacity=".92" fill-rule="evenodd" clip-rule="evenodd" d="m9.504 29.894 2.707-4.715 1.658.962-2.707 4.715-1.658-.962zm2.066-7.12-4.689-2.722.958-1.667 4.688 2.723-.957 1.667zm9.378 5.445-4.689-2.722.957-1.667 4.69 2.722-.958 1.667zm-6.03-7.755 2.707-4.715 1.658.962-2.707 4.715-1.658-.962z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m60.85 11.508.708-3.662 1.288.251-.708 3.662-1.288-.252zm-.24-5.076-3.642-.712.25-1.295 3.642.712-.25 1.295zm7.283 1.423-3.642-.711.25-1.295 3.642.712-.25 1.294zm-5.627-3.671.708-3.662 1.287.251-.708 3.662-1.287-.251z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".81"/>
<path opacity=".76" fill-rule="evenodd" clip-rule="evenodd" d="m107.034 22.162.493 5.675-1.995.175-.494-5.674 1.996-.176zm2.477 7.349 5.643-.497.175 2.007-5.644.496-.174-2.006zm-11.287.993 5.644-.497.174 2.007-5.643.496-.175-2.006zm9.797 3.008.494 5.675-1.996.175-.493-5.675 1.995-.175z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m16.191 92.492-5.006 1.636-.575-1.78 5.006-1.636.575 1.78zm-6.098 3.792 1.626 5.034-1.77.578-1.626-5.034 1.77-.578zM6.839 86.215l1.627 5.035-1.77.578-1.627-5.034 1.77-.579zm-.66 9.549-5.006 1.635-.576-1.78 5.007-1.635.575 1.78z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".91"/>
<path opacity=".92" fill-rule="evenodd" clip-rule="evenodd" d="m35.176 59.176 5.102-1.97.692 1.814-5.101 1.97-.693-1.814zm6.118-4.264-1.958-5.13 1.803-.696 1.958 5.13-1.803.696zm3.916 10.26-1.958-5.13 1.804-.696 1.958 5.13-1.804.696zm.17-9.935 5.1-1.969.693 1.814-5.101 1.969-.693-1.814z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m95.733 86.583-4.383 2.649-.931-1.559 4.383-2.648.93 1.558zm-4.949 4.93 2.634 4.407-1.55.936-2.633-4.407 1.55-.937zm-5.267-8.816 2.633 4.408-1.55.936-2.633-4.408 1.55-.936zm1.45 9.183-4.384 2.648-.93-1.558 4.382-2.648.931 1.558z" fill="#36205D" style="mix-blend-mode:multiply"/>
<path opacity=".98" fill-rule="evenodd" clip-rule="evenodd" d="m24.804 132.406-2.1-3.015 1.06-.746 2.1 3.014-1.06.747zm-3.747-3.307-2.998 2.111-.742-1.066 2.998-2.111.742 1.066zm5.996-4.222-2.998 2.111-.742-1.066 2.998-2.11.742 1.065zm-6.447 1.5-2.1-3.015 1.06-.746 2.1 3.014-1.06.747z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m60.65 142.295-1.594 3.144-1.105-.567 1.593-3.144 1.105.567zm-1.098 4.678 3.126 1.602-.563 1.112-3.127-1.602.564-1.112zm-6.254-3.204 3.127 1.602-.563 1.112-3.127-1.603.563-1.111zm4.165 4.814-1.593 3.144-1.106-.566 1.593-3.144 1.106.566z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".82"/>
<path opacity=".71" fill-rule="evenodd" clip-rule="evenodd" d="m110.507 140.233 2.321-4.582 1.611.826-2.321 4.581-1.611-.825zm1.599-6.817-4.556-2.335.821-1.62 4.556 2.335-.821 1.62zm9.112 4.669-4.556-2.335.821-1.62 4.556 2.335-.821 1.62zm-6.068-7.015 2.321-4.582 1.611.825-2.321 4.582-1.611-.825z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M373.52 65.487v5.042h1.772v-5.042h-1.772zm-1.621 6.671h-5.013v1.782h5.013v-1.782zm10.027 0h-5.013v1.782h5.013v-1.782zm-8.406 3.412v5.041h1.772V75.57h-1.772z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".5"/>
<path opacity=".92" fill-rule="evenodd" clip-rule="evenodd" d="m508.496 29.894-2.707-4.715-1.658.962 2.707 4.715 1.658-.962zm-2.066-7.12 4.689-2.722-.958-1.667-4.689 2.723.958 1.667zm-9.378 5.445 4.689-2.722-.957-1.667-4.689 2.722.957 1.667zm6.03-7.755-2.707-4.715-1.658.962 2.707 4.715 1.658-.962z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m457.15 11.508-.708-3.662-1.287.251.707 3.662 1.288-.252zm.24-5.076 3.642-.712-.25-1.295-3.642.712.25 1.295zm-7.283 1.423 3.642-.711-.251-1.295-3.641.712.25 1.294zm5.627-3.671-.708-3.662-1.287.251.708 3.662 1.287-.251z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".81"/>
<path opacity=".76" fill-rule="evenodd" clip-rule="evenodd" d="m410.966 22.162-.493 5.675 1.995.175.494-5.674-1.996-.176zm-2.477 7.349-5.643-.497-.175 2.007 5.644.496.174-2.006zm11.287.993-5.644-.497-.174 2.007 5.643.496.175-2.006zm-9.797 3.008-.494 5.675 1.996.175.493-5.675-1.995-.175z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m501.809 92.492 5.006 1.636.575-1.78-5.006-1.636-.575 1.78zm6.098 3.792-1.626 5.034 1.77.578 1.626-5.034-1.77-.578zm3.254-10.069-1.627 5.035 1.77.578 1.627-5.034-1.77-.579zm.66 9.549 5.006 1.635.576-1.78-5.007-1.635-.575 1.78z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".91"/>
<path opacity=".92" fill-rule="evenodd" clip-rule="evenodd" d="m482.824 59.176-5.102-1.97-.692 1.814 5.101 1.97.693-1.814zm-6.118-4.264 1.958-5.13-1.803-.696-1.958 5.13 1.803.696zm-3.916 10.26 1.958-5.13-1.804-.696-1.958 5.13 1.804.696zm-.169-9.935-5.102-1.969-.692 1.814 5.101 1.969.693-1.814z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m422.267 86.583 4.383 2.649.932-1.559-4.384-2.648-.931 1.558zm4.949 4.93-2.634 4.407 1.55.936 2.634-4.407-1.55-.937zm5.267-8.816-2.633 4.408 1.549.936 2.634-4.408-1.55-.936zm-1.449 9.183 4.383 2.648.931-1.558-4.383-2.648-.931 1.558z" fill="#36205D" style="mix-blend-mode:multiply"/>
<path opacity=".98" fill-rule="evenodd" clip-rule="evenodd" d="m493.196 132.406 2.099-3.015-1.06-.746-2.099 3.014 1.06.747zm3.747-3.307 2.998 2.111.742-1.066-2.998-2.111-.742 1.066zm-5.996-4.222 2.998 2.111.742-1.066-2.998-2.11-.742 1.065zm6.447 1.5 2.1-3.015-1.06-.746-2.099 3.014 1.059.747z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m457.351 142.295 1.593 3.144 1.105-.567-1.593-3.144-1.105.567zm1.097 4.678-3.126 1.602.563 1.112 3.127-1.602-.564-1.112zm6.254-3.204-3.127 1.602.563 1.112 3.127-1.603-.563-1.111zm-4.165 4.814 1.593 3.144 1.106-.566-1.593-3.144-1.106.566z" fill="#36205D" style="mix-blend-mode:multiply" opacity=".82"/>
<path opacity=".71" fill-rule="evenodd" clip-rule="evenodd" d="m407.493 140.233-2.321-4.582-1.611.826 2.321 4.581 1.611-.825zm-1.599-6.817 4.556-2.335-.821-1.62-4.556 2.335.821 1.62zm-9.112 4.669 4.556-2.335-.821-1.62-4.556 2.335.821 1.62zm6.068-7.015-2.321-4.582-1.611.825 2.321 4.582 1.611-.825z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.26512 0L4.84341 3.57829L3.57829 4.84341L0 1.26512L1.26512 0ZM7.15659 3.57829L10.7349 5.33207e-08L12 1.26512L8.42171 4.84341L7.15659 3.57829ZM5.33207e-08 10.7349L3.57829 7.15659L4.84341 8.42171L1.26512 12L5.33207e-08 10.7349ZM8.42171 7.15659L12 10.7349L10.7349 12L7.15659 8.42171L8.42171 7.15659Z" fill="#FFB445"/>
</svg>

After

Width:  |  Height:  |  Size: 469 B

@@ -0,0 +1,4 @@
<svg width="138" height="12" viewBox="0 0 138 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="m127.265 0 3.578 3.578-1.265 1.265L126 1.265 127.265 0zm5.892 3.578L136.735 0 138 1.265l-3.578 3.578-1.265-1.265zM126 10.735l3.578-3.578 1.265 1.265L127.265 12 126 10.735zm8.422-3.578L138 10.735 136.735 12l-3.578-3.578 1.265-1.265z" fill="#FFB445"/>
<path d="M114.445 4.555 112.5 1l-1.945 3.555L107.914 6h-3.828l-1.349-.737L101.5 3l-1.237 2.263L98.914 6H0v1h98.914l1.349.737L101.5 10l1.237-2.263L104.086 7h3.828l2.641 1.445L112.5 12l1.945-3.555L118 6.5l-3.555-1.945z" fill="#36205D"/>
</svg>

After

Width:  |  Height:  |  Size: 647 B

+10
View File
@@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path fill="#DE3F3F" d="M0 5.667 3.333 1h9.334L16 5.667l-8 8.666z"/>
<path fill="#FFF" opacity=".25" d="M4.667 5.533 4 2.333h4zM11.333 5.533l.667-3.2H8z"/>
<path fill="#FFF" opacity=".5" d="M4.667 5.533 8 2.333l3.333 3.2zM1.733 5.533 4 2.333l.667 3.2z"/>
<path fill="#34313A" opacity=".11" d="M14.267 5.533 12 2.333l-.667 3.2zM1.733 5.533h2.934L8 12.4z"/>
<path fill="#FFF" opacity=".5" d="M14.267 5.533h-2.934L8 12.4z"/>
<path fill="#FFF" opacity=".25" d="M4.667 5.533h6.666L8 12.4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 675 B

@@ -0,0 +1,37 @@
<svg width="85" height="32" viewBox="0 0 85 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="m4.93 12.255 2.466-.63-1.983-1.597-.63-2.468-1.595 1.986-2.465.63 1.983 1.597.63 2.468 1.595-1.986zM80.034 7.698l2.465-.63-1.983-1.597-.63-2.468-1.594 1.985-2.466.631 1.983 1.596.63 2.469 1.595-1.986zM42.27 7.427l2.929.487-1.368-2.638.487-2.932-2.635 1.37-2.928-.488 1.367 2.638-.486 2.932 2.634-1.37zM78.215 26.355l2.694 2.064.033-3.396 2.063-2.697-3.393-.034-2.694-2.065-.033 3.397-2.062 2.697 3.392.034zM38.321 28.092l2.092.348-.977-1.885.347-2.094-1.881.978-2.092-.348.977 1.884-.348 2.095 1.882-.978zM12.17 30.035l.916 1.915.981-1.882 1.913-.916-1.88-.982-.915-1.916-.981 1.882-1.913.917 1.88.982z" fill="#fff" fill-opacity=".5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m24.878 12.01 6.73-1.805 2.524 9.433-6.73 1.806-2.524-9.433z" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m18.148 13.816 6.73-1.805 2.524 9.433-6.73 1.805-2.524-9.433z" fill="#E1E0E3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m23.532 12.372 1.346-.361 2.524 9.433-1.346.36-2.524-9.432z" fill="#6133B4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m24.878 12.01 1.346-.36 2.524 9.433-1.346.36-2.524-9.432z" fill="#9A62FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m25.696 20.457 1.345-.36.361 1.347-1.346.36-.36-1.347zM23.532 12.372l1.346-.361.36 1.347-1.346.361-.36-1.347z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m18.148 13.816 5.384-1.444.36 1.348-5.383 1.444-.36-1.348zM20.312 21.902l5.384-1.445.36 1.348-5.383 1.444-.36-1.347zM26.224 11.65l5.383-1.445.36 1.348-5.383 1.444-.36-1.347zM28.387 19.735l5.384-1.444.36 1.347-5.383 1.445-.36-1.348z" fill="#BDA8FF" fill-opacity=".3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m27.041 20.096 1.346-.36.361 1.347-1.346.36-.36-1.347zM24.878 12.01l1.346-.36.36 1.347-1.346.361-.36-1.347z" fill="#6133B4"/>
<path clip-rule="evenodd" d="M24.735 4.954c-.335-1.183-1.148-2.301-2.285-2.51-1.138-.21-1.923.616-1.7 1.476.221.86 1 1.122 3.498 2.183.71.302.823.034.487-1.149z" stroke="#6133B4" stroke-width="1.5"/>
<path clip-rule="evenodd" d="M27.66 5.365c.648-1.044 1.737-1.895 2.888-1.782 1.151.112 1.678 1.123 1.228 1.889-.45.765-1.27.802-3.964 1.133-.765.094-.8-.195-.152-1.24z" stroke="#9A62FF" stroke-width="1.5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.319 4.294c-2.24-.315-1.259 2.44-.36 2.566.898.126 2.6-2.25.36-2.566z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m26.016 6.454 8.279 1.165-.582 4.145-8.279-1.165.582-4.145z" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m17.737 5.29 8.279 1.164-.582 4.145-8.279-1.165.582-4.145z" fill="#E1E0E3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m23.256 6.066 5.52.777-.582 4.144-5.52-.776.582-4.145z" fill="#9A62FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m23.256 6.066 2.76.388-.582 4.145-2.76-.388.582-4.145z" fill="#6133B4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m26.016 6.454 2.76.389-.195 1.381-2.76-.388.195-1.382z" fill="#6133B4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m23.256 6.066 2.76.388-.194 1.382-2.76-.388.194-1.382z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m17.349 8.053 5.52.776-.195 1.382-5.519-.777.194-1.381zM28.388 9.606l5.519.776-.194 1.382-5.52-.777.195-1.381z" fill="#BDA8FF" fill-opacity=".3"/>
<path clip-rule="evenodd" d="M56.55 9.16c-.624-1.413-1.83-2.662-3.282-2.724-1.452-.062-2.285 1.104-1.858 2.135.426 1.031 1.441 1.22 4.734 2.104.935.25 1.03-.102.406-1.515z" stroke="#6133B4" stroke-width="1.5"/>
<path clip-rule="evenodd" d="M60.26 9.16c.624-1.413 1.83-2.662 3.283-2.724 1.451-.062 2.284 1.104 1.857 2.135-.426 1.031-1.44 1.22-4.734 2.104-.935.25-1.03-.102-.406-1.515z" stroke="#9A62FF" stroke-width="1.5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.405 8.061c-2.842 0-1.14 3.256 0 3.256s2.842-3.256 0-3.256z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.405 10.802H68.91v5.259H58.405v-5.259z" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.901 10.802h10.504v5.259H47.901v-5.259z" fill="#E1E0E3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.904 10.802h7.002v5.259h-7.002v-5.259z" fill="#9A62FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.904 10.802h3.501v5.259h-3.501v-5.259zM58.405 10.802h3.501v1.753h-3.5v-1.753z" fill="#6133B4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.904 10.802h3.501v1.753h-3.501v-1.753z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.405 16.06h8.753v12.27h-8.753V16.06z" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.652 16.06h8.753v12.27h-8.753V16.06z" fill="#E1E0E3"/>
<path fill="#6133B4" d="M56.654 16.061h1.751v12.27h-1.751z"/>
<path fill="#9A62FF" d="M58.405 16.061h1.751v12.27h-1.751z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M56.654 26.578h1.751v1.753h-1.75v-1.753zM56.654 16.06h1.751v1.754h-1.75V16.06z" fill="#4F2A93"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.652 16.06h7.002v1.754h-7.002V16.06z" fill="#BDA8FF" fill-opacity=".3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.901 14.308h7.003v1.753H47.9v-1.753zM49.652 26.578h7.002v1.753h-7.002v-1.753zM60.156 16.06h7.002v1.754h-7.002V16.06z" fill="#BDA8FF" fill-opacity=".3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M61.906 14.308h7.003v1.753h-7.003v-1.753zM60.156 26.578h7.002v1.753h-7.002v-1.753z" fill="#BDA8FF" fill-opacity=".3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.405 26.578h1.75v1.753h-1.75v-1.753zM58.405 16.06h1.75v1.754h-1.75V16.06z" fill="#6133B4"/>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M3 12.606v1.778c0 .208.093.408.262.53 1.842 1.347 6.923 1.347 8.766 0a.655.655 0 0 0 .26-.53v-1.778c0-1.621-.831-3.177-2.091-4.104a.666.666 0 0 1 0-1.08c1.26-.927 2.092-2.483 2.092-4.105V1.54a.652.652 0 0 0-.261-.53c-1.843-1.346-6.924-1.346-8.766 0A.65.65 0 0 0 3 1.54v1.777c0 1.622.832 3.178 2.092 4.105.368.27.368.81 0 1.08C3.832 9.429 3 10.985 3 12.606" fill="#F19595"/>
<path d="M7.644 1.327c1.51 0 2.684.274 3.318.587v1.403c0 1.169-.594 2.332-1.551 3.036a2.006 2.006 0 0 0-.818 1.609c0 .63.305 1.232.817 1.608.958.705 1.552 1.868 1.552 3.036v1.404c-.634.313-1.809.587-3.318.587-1.508 0-2.683-.274-3.317-.587v-1.404c0-1.168.594-2.331 1.551-3.035.513-.377.817-.978.817-1.609 0-.63-.304-1.232-.816-1.609-.958-.704-1.552-1.867-1.552-3.036V1.914c.634-.313 1.809-.587 3.317-.587" fill-opacity=".9" fill="#FFF"/>
<path d="M7.797 2.324c-1.132 0-2.331.105-2.343.385-.01.226-.005.664.914 1.13.893.453 1.06 1.282 1.546 1.282.564 0 .596-.477 1.284-.95.71-.488.823-1.148.815-1.408-.011-.363-1.084-.439-2.216-.439" fill="#DE3F3F"/>
<path d="M9.198 4.17c.71-.487.823-1.146.815-1.407-.009-.288-.684-.395-1.526-.427.236.12.543.377.467.88-.078.525-.904 1.105-.77 1.568.025.09.069.162.124.221.247-.17.408-.502.89-.835" fill="#B01515"/>
<path d="M7.644 9.17c-.344 0-.433.628-.933 1.018-.613.478-1.196 1.067-1.356 1.914-.131.698-.012.785.148.834.16.049 1.386.257 2.588 0 1.203-.258 1.87-.737 1.755-1.227-.111-.466-.448-.865-1.068-1.325-.593-.44-.79-1.214-1.134-1.214" fill="#DE3F3F"/>
<path d="M5.503 12.936c.16.05 1.386.257 2.588 0 .956-.205 1.574-.55 1.729-.929a.096.096 0 0 0-.005-.023c-.067-.256-1.073-.41-2.325-.207-1.192.192-2.158.586-2.153 1.03.037.08.097.108.166.129" fill="#B01515"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,9 @@
<svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path fill="url(#sxizdfpdya)" d="M0 0h68v68H0z"/>
<defs>
<pattern id="sxizdfpdya" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#pomapjzcdb" transform="scale(.0147)"/>
</pattern>
<image id="pomapjzcdb" width="68" height="68" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5gwJFx8lKwafmAAABjRJREFUeNrtm39MVWUYx78IV5BfF3Qg8kNppNIoyhKWZmUBlpRNpC3Uac7EUUGrscxM+AOHia1foKmDHOHItkbhLGnpzGVBimtlozmVTeByCRDhwgXll/THc17de3zvuedernDd3uefc895f5/zuc/3ed57DyBNmjRpzpuH+sLvR8fGAODR0nS+YmAgAMCQNQMAMJKwkys//+tUAMDQDTrPzNgIACj58iAAoLH5LADgx/Kzwols/zyba3+jny9n7WNmJ3LXffzoONUHTrVPyvDg7sEUyQRvXrYKrvX2AgCmK2RUxL9OT35oDzWs38bVf3XlNe78sfindE3gam/TpCw87fwPwuuSEL2EXMg6DgBY/HW6+E4OdQAA4lZ4CYnotVgBAEvShuiIRwAAXxV/y9Xbve+jSSHj2SfIl1RLQpwkRO1LmDEimJV+Qyqy+709wvZx/3wBAFhk3QQAONlYqKoxpGuijLDfvnduodmnTwIAUrM2ataThDhKSEp9FH2o38/5iopCuuO1/drqceAy+YiSAPI5m+rE9UvLcjTnweKfJWk7nVtppb5qkhB7hLAI01Y8wdSjyzLM9aCOJ9qrI+jDZTqkNlwBAByLixZOpMtk4uIeZrVrqkgVhtYL4x9m830iXXJDJCH2CGGqwXKB4gKxevw9eBgA0HDwIgAg94UdAICZL1JSkd5H5w2VVB4ZHg8A6IkkEoKMREKPhVTM/AHFPdNLxHFP6TnKdTIX8vOp7a8AABxWcpnVwZ9pLvjSlRYAwNzoKEmIS1TGlnqc2H1aWO5n8qSIFGsAAKdazVx53pR5pDog1SkMuF8z7rnD1yi+a4bRICy39vUBAPwDAhSVe5uy3Scp283+iUjE8ymSEJcQolaPVxZkkldPJRKiYmZqtl+3iy9vaWwk1agcJTUKJ18S9TI5gSu59ASjP07R9F0PW1YLV1BlzSMfhh1SZSaEkHe25ZMK1LQBANpa2wEAyTELxjUw64dZFOYJs21bxkjxcdAL1qzdCgBYXrlLEuJSlWFPdGlmuOIL6Lz/L4pITeZmIicnnH/SVV5cOfM9rJ9TpUyF5rl0YZXtebpISTr6viTEpXHIgy9NAwD4+voCAA4da+YIamn05OqbzKNc+bqMhwAAAwMDCiHudUMkIc4Swr7zakvf7698omNoaKiKqA6uXG+/kpB7jRCmBsEhscoVyikWrpoFAPAYJZ8wcqvjQQBAeKgRADDmST7n3HdXlRoGpV+KXFcVxWiO391F+zCY7dxC9baXhOglxPIL/UhqNlOEunKfNwAgInKYU5kLJ9Sbqjds9Ej15iYZOJVhVlfM9k3oERqf8ZE+xK0JYZElix96/iQ1iFRtXcYm+3E+5OaUafwdv3md8yEWi0WoMrcjVjKjiyNXSYirCWE5hzqrPVPA5ybZR4xc+d6VlzlfkKbakj20voMrj00f4fZNWI4k4xB3J4R9p5dmQjM3OX7AU3Of4+cy7XI/Ve7Dxk3eEiMJuSciVZbd3jZSjfkgdVi2KUyzvb1ydf+Tnf1KQvQSYisLTcyYodlh8ub7uPjDXnt1xGpr3M7OrnEtVG97SYg9QrYVPQcAWDywXZXdQslF9HXMIlZbpDBrrTOofAhlv7W+bwjr118sI082SL/wfZpfJ33IhBJiDAxWvtx0iFg0zMcR9bwqtGFM1cOAQ0NGLBLXvzUPdRbe2y1Vxi1UpiFsr/LpE+76rIQR7jzI3yD0Hepsl1mPdVilMrbGhSY51zt7JSFuEameKZjOZbfrKnxdOoGqLCuX/U62SUIcJaS8ZQN3fmItX74hqpwj6M1q/h9BJataOQLKW14TD9Sib8JMZT7MrZOEuAUhDhO0AuMiwJb919k0LjIu/UH7MMuXSUIcsjveuYt7IH7MHSdq7FkOAAgJpm3/t/Lpf6v23rlj/7Pt7DYJ28t37hwlJDHh8TEA6LcOCJ8QM3an7e5DKE/mDrUIquHO/fzF8Y2X6WnhdTb+lqJsISHs/R1b47P2R/7NkYQ4pDJhIXPoCXp3c/sOIR7OvW1gi6QRPyJimnegMLtlqhI+JwgAYG7qEZL37uatuubB+rltVqkyExKH3G1TkzHefhixhkBJiDRp0qTddfsfGCIUXNZsU4gAAAAASUVORK5CYII="/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect width="16" height="16" fill="none"/><g id="b"><g id="c"><g id="d"><polygon id="e" points="12.2 2 14 3.8 9.8 8 14 12.2 12.2 14 8 9.8 3.8 14 2 12.2 6.2 8 2 3.8 3.8 2 8 6.2 12.2 2"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 308 B

+5
View File
@@ -0,0 +1,5 @@
<svg width="48" height="20" viewBox="0 0 48 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M48 10.334c0-3.418-1.653-6.115-4.813-6.115-3.174 0-5.094 2.697-5.094 6.088 0 4.019 2.267 6.048 5.52 6.048 1.587 0 2.787-.36 3.694-.868v-2.67c-.907.454-1.947.735-3.267.735-1.293 0-2.44-.454-2.587-2.03h6.52c0-.173.027-.868.027-1.188zm-6.587-1.268c0-1.51.92-2.137 1.76-2.137.813 0 1.68.628 1.68 2.136h-3.44zM32.947 4.22c-1.307 0-2.147.613-2.614 1.04l-.173-.827h-2.933V20l3.333-.707.013-3.779c.48.347 1.187.841 2.36.841 2.387 0 4.56-1.922 4.56-6.155-.013-3.871-2.213-5.98-4.546-5.98zm-.8 9.198c-.787 0-1.254-.28-1.574-.627l-.013-4.954c.347-.387.827-.654 1.587-.654 1.213 0 2.053 1.362 2.053 3.11 0 1.79-.827 3.125-2.053 3.125zM22.64 3.431l3.346-.72V0L22.64.708V3.43z" fill="#635BFF"/>
<path fill="#635BFF" d="M22.64 4.446h3.347v11.682H22.64z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m19.053 5.434-.213-.988h-2.88v11.682h3.333V8.211c.787-1.028 2.12-.841 2.534-.694V4.446c-.427-.16-1.987-.454-2.774.988zM12.387 1.549l-3.254.694-.013 10.694c0 1.976 1.48 3.431 3.453 3.431 1.094 0 1.894-.2 2.334-.44v-2.71c-.427.173-2.534.787-2.534-1.189V7.29h2.534V4.447h-2.534l.014-2.897zM3.373 7.837c0-.52.427-.72 1.134-.72 1.013 0 2.293.306 3.306.854V4.833a8.783 8.783 0 0 0-3.306-.614C1.8 4.22 0 5.634 0 7.997c0 3.685 5.067 3.098 5.067 4.687 0 .614-.534.814-1.28.814-1.107 0-2.52-.454-3.64-1.068v3.178a9.233 9.233 0 0 0 3.64.76c2.773 0 4.68-1.375 4.68-3.764-.014-3.98-5.094-3.271-5.094-4.767z" fill="#635BFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -49,6 +49,7 @@
<transactions
:hero="hero"
:reset-counter="resetCounter"
/>
<contributor-details
@@ -43,42 +43,55 @@
</label>
</div>
<div>
Months until renewal:
Perk offset months:
<strong>{{ hero.purchased.plan.consecutive.offset }}</strong>
</div>
<div>
Next Mystic Hourglass:
<strong>{{ nextHourglassDate }}</strong>
</div>
<div class="form-inline">
<label>
Mystic Hourglasses:
<input
v-model="hero.purchased.plan.consecutive.trinkets"
class="form-control"
type="number"
min="0"
step="1"
>
</label>
</div>
<div>
Gem cap:
<strong>{{ hero.purchased.plan.consecutive.gemCapExtra + 25 }}</strong>
</div>
<div class="form-inline">
<label>
Gems bought this month:
<input
v-model="hero.purchased.plan.gemsBought"
class="form-control"
type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25"
step="1"
>
</label>
</div>
<div>
Next Mystic Hourglass:
<strong>{{ nextHourglassDate }}</strong>
</div>
<div class="form-inline">
<label>
Mystic Hourglasses:
<input
v-model="hero.purchased.plan.consecutive.trinkets"
class="form-control"
type="number"
min="0"
step="1"
>
</label>
</div>
<div class="form-inline">
<label>
Gem cap increase:
<input
v-model="hero.purchased.plan.consecutive.gemCapExtra"
class="form-control"
type="number"
min="0"
max="25"
step="5"
>
</label>
</div>
<div>
Total Gem cap:
<strong>{{ Number(hero.purchased.plan.consecutive.gemCapExtra) + 25 }}</strong>
</div>
<div class="form-inline">
<label>
Gems bought this month:
<input
v-model="hero.purchased.plan.gemsBought"
class="form-control"
type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25"
step="1"
>
</label>
</div>
<div
v-if="hero.purchased.plan.extraMonths > 0"
>
@@ -139,13 +152,6 @@ export default {
return currentPlanContext.nextHourglassDate.format('MMMM');
},
},
watch: {
'hero.purchased.plan.consecutive.count' () { // eslint-disable-line object-shorthand
this.hero.purchased.plan.consecutive.gemCapExtra = Math.min(
Math.floor(this.hero.purchased.plan.consecutive.count / 3) * 5, 25,
);
},
},
methods: {
dateFormat (date) {
return moment(date).format('YYYY/MM/DD');
@@ -30,6 +30,10 @@ export default {
type: Object,
required: true,
},
resetCounter: {
type: Number,
required: true,
},
},
data () {
return {
@@ -38,6 +42,14 @@ export default {
hourglassTransactions: [],
};
},
watch: {
resetCounter () {
if (this.expand) {
this.expand = !this.expand;
this.toggleTransactionsOpen();
}
},
},
methods: {
async toggleTransactionsOpen () {
this.expand = !this.expand;
+10 -2
View File
@@ -86,6 +86,13 @@
>{{ $t('companyContribute') }}
</a>
</li>
<li>
<a
href="https://translate.habitica.com/"
target="_blank"
>{{ $t('translateHabitica') }}
</a>
</li>
</ul>
</div>
<!-- Support -->
@@ -224,7 +231,7 @@
></div>
</a><a
class="social-circle"
href="https://www.tumblr.com/Habitica"
href="http://blog.habitrpg.com/"
target="_blank"
>
<div
@@ -578,6 +585,7 @@ h3 {
.text{
display: inline-block;
vertical-align: bottom;
text-overflow: hidden;
}
}
@@ -814,7 +822,7 @@ export default {
...mapState({ user: 'user.data' }),
...mapState(['isUserLoaded']),
getDataDisplayToolUrl () {
const base = 'https://oldgods.net/habitrpg/habitrpg_user_data_display.html';
const base = 'https://tools.habitica.com/';
if (!this.user) return null;
return `${base}?uuid=${this.user._id}`;
},
@@ -50,7 +50,21 @@ export default {
challengeId: this.challengeId,
keep,
});
await this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true });
const userTasksByType = (await this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true })).data;
let tagInUse = false;
Object.keys(userTasksByType).forEach(taskType => {
userTasksByType[taskType].forEach(task => {
if (task.tags.indexOf(this.challengeId) > -1) {
tagInUse = true;
}
});
});
if (!tagInUse) {
await this.$store.dispatch(
'tags:deleteTag',
{ tagId: this.challengeId },
);
}
this.close();
},
close () {
+67 -39
View File
@@ -121,7 +121,7 @@
v-if="editing"
class="menu-container col-2"
:class="{active: activeTopPage === 'backgrounds'}"
@click="changeTopPage('backgrounds', '2022')"
@click="changeTopPage('backgrounds', '2023')"
>
<div class="menu-item">
<div
@@ -198,52 +198,79 @@
</div>
</div>
<div
v-if="!filterBackgrounds"
class="row text-center title-row"
>
<strong>{{ backgroundShopSets[1].text }}</strong>
</div>
<div
v-if="!filterBackgrounds"
class="row title-row"
v-if="!filterBackgrounds && user.purchased.background.birthday_bash"
>
<div
v-for="bg in backgroundShopSets[1].items"
:key="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="!user.purchased.background[bg.key]
? backgroundSelected(bg) : unlock('background.' + bg.key)"
class="row text-center title-row"
>
<strong>{{ backgroundShopSets[2].text }}</strong>
</div>
<div
class="row title-row"
>
<div
class="background"
:class="[`background_${bg.key}`, backgroundLockedStatus(bg.key)]"
></div>
<i
v-if="!user.purchased.background[bg.key]"
class="glyphicon glyphicon-lock"
></i>
<div
v-if="!user.purchased.background[bg.key]"
class="purchase-background single d-flex align-items-center justify-content-center"
v-for="bg in backgroundShopSets[2].items"
:key="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="unlock('background.' + bg.key)"
>
<div
class="svg-icon hourglass"
v-html="icons.hourglass"
class="background"
:class="`background_${bg.key}`"
></div>
<span class="price">1</span>
</div>
<span
v-if="!user.purchased.background[bg.key]"
class="badge-top"
@click.stop.prevent="togglePinned(bg)"
</div>
</div>
<div v-if="!filterBackgrounds">
<div
class="row text-center title-row"
>
<strong>{{ backgroundShopSets[1].text }}</strong>
</div>
<div
class="row title-row"
>
<div
v-for="bg in backgroundShopSets[1].items"
:key="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="!user.purchased.background[bg.key]
? backgroundSelected(bg) : unlock('background.' + bg.key)"
>
<pin-badge
:pinned="isBackgroundPinned(bg)"
/>
</span>
<div
class="background"
:class="[`background_${bg.key}`, backgroundLockedStatus(bg.key)]"
></div>
<i
v-if="!user.purchased.background[bg.key]"
class="glyphicon glyphicon-lock"
></i>
<div
v-if="!user.purchased.background[bg.key]"
class="purchase-background single d-flex align-items-center justify-content-center"
>
<div
class="svg-icon hourglass"
v-html="icons.hourglass"
></div>
<span class="price">1</span>
</div>
<span
v-if="!user.purchased.background[bg.key]"
class="badge-top"
@click.stop.prevent="togglePinned(bg)"
>
<pin-badge
:pinned="isBackgroundPinned(bg)"
/>
</span>
</div>
</div>
</div>
<sub-menu
@@ -1185,7 +1212,7 @@ export default {
},
],
bgSubMenuItems: ['2022', '2021', '2020', '2019', '2018', '2017', '2016', '2015', '2014'].map(y => ({
bgSubMenuItems: ['2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '2015', '2014'].map(y => ({
id: y,
label: y,
})),
@@ -1214,6 +1241,7 @@ export default {
2020: [],
2021: [],
2022: [],
2023: [],
};
// Hack to force update for now until we restructure the data
@@ -45,7 +45,7 @@
v-html="$t('dayStart', { startTime: groupStartTime } )"
>
</div>
<div class="ml-2">
<div class="create-task-area ml-2">
<button
id="create-task-btn"
v-if="canCreateTasks"
@@ -132,6 +132,14 @@
margin-bottom: 0px;
}
.create-task-area {
position: inherit;
.dropdown {
right: 24px;
}
}
.day-start {
height: 2rem;
padding: 0.25rem 0.75rem;
@@ -267,7 +267,7 @@
</div>
</div>
<div class="px-4">
<sidebar-section :title="$t('staffAndModerators')">
<sidebar-section :title="$t('staff')">
<div class="row">
<div
v-for="user in staff"
@@ -289,19 +289,6 @@
class="svg-icon staff-icon"
v-html="icons.tierStaff"
></div>
<div
v-if="user.type === 'Moderator' && user.name !== 'It\'s Bailey'"
class="svg-icon mod-icon"
v-html="icons.tierMod"
></div>
<div
v-if="user.name === 'It\'s Bailey'"
class="svg-icon npc-icon"
v-html="icons.tierNPC"
></div>
</div>
<div class="type">
{{ user.type }}
</div>
</div>
</div>
@@ -353,7 +340,7 @@
<li>
<a
v-once
href="https://oldgods.net/habitrpg/habitrpg_user_data_display.html"
href="https://tools.habitica.com/"
target="_blank"
>{{ $t('dataDisplayTool') }}</a>
</li>
@@ -772,6 +759,7 @@
</style>
<script>
import find from 'lodash/find';
import { mapState } from '@/libs/store';
import { goToModForm } from '@/libs/modform';
@@ -848,22 +836,23 @@ export default {
computed: {
...mapState({
user: 'user.data',
currentEvent: 'worldState.data.currentEvent',
currentEventList: 'worldState.data.currentEventList',
}),
questData () {
if (!this.group.quest) return {};
return quests.quests[this.group.quest.key];
},
imageURLs () {
if (!this.currentEvent || !this.currentEvent.season) {
const currentEvent = find(this.currentEventList, event => Boolean(event.season));
if (!currentEvent) {
return {
background: 'url(/static/npc/normal/tavern_background.png)',
npc: 'url(/static/npc/normal/tavern_npc.png)',
};
}
return {
background: `url(/static/npc/${this.currentEvent.season}/tavern_background.png)`,
npc: `url(/static/npc/${this.currentEvent.season}/tavern_npc.png)`,
background: `url(/static/npc/${currentEvent.season}/tavern_background.png)`,
npc: `url(/static/npc/${currentEvent.season}/tavern_npc.png)`,
};
},
},
@@ -0,0 +1,119 @@
<template>
<base-banner
banner-id="birthday-banner"
class="birthday-banner"
:show="showBirthdayBanner"
height="3rem"
:can-close="false"
>
<div
slot="content"
:aria-label="$t('celebrateBirthday')"
class="content d-flex justify-content-around align-items-center ml-auto mr-auto"
@click="showBirthdayModal"
>
<div
v-once
class="svg-icon svg-gifts left-gift"
v-html="icons.giftsBirthday"
>
</div>
<div
v-once
class="svg-icon svg-ten-birthday"
v-html="icons.tenBirthday"
>
</div>
<div
v-once
class="announce-text"
v-html="$t('celebrateBirthday')"
>
</div>
<div
v-once
class="svg-icon svg-gifts right-gift"
v-html="icons.giftsBirthday"
>
</div>
</div>
</base-banner>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.announce-text {
color: $purple-50;
}
.birthday-banner {
width: 100%;
min-height: 48px;
padding: 8px;
background-image: linear-gradient(90deg,
rgba(255,190,93,0) 0%,
rgba(255,190,93,1) 25%,
rgba(255,190,93,1) 75%,
rgba(255,190,93,0) 100%),
url('~@/assets/images/glitter.png');
cursor: pointer;
}
.left-gift {
margin: auto;
}
.right-gift {
margin: auto auto auto 8px;
filter: flipH;
transform: scaleX(-1);
}
.svg-gifts {
width: 85px;
}
.svg-ten-birthday {
width: 192.5px;
margin-left: 8px;
margin-right: 8.5px;
}
</style>
<script>
import find from 'lodash/find';
import { mapState } from '@/libs/store';
import BaseBanner from './base';
import giftsBirthday from '@/assets/svg/gifts-birthday.svg';
import tenBirthday from '@/assets/svg/10th-birthday-linear.svg';
export default {
components: {
BaseBanner,
},
data () {
return {
icons: Object.freeze({
giftsBirthday,
tenBirthday,
}),
};
},
computed: {
...mapState({
currentEventList: 'worldState.data.currentEventList',
}),
showBirthdayBanner () {
return Boolean(find(this.currentEventList, event => Boolean(event.event === 'birthday10')));
},
},
methods: {
showBirthdayModal () {
this.$root.$emit('bv::show::modal', 'birthday-modal');
},
},
};
</script>
@@ -0,0 +1,58 @@
<template>
<base-notification
:can-remove="canRemove"
:has-icon="true"
:notification="notification"
:read-after-click="true"
@click="action"
>
<div
slot="content"
>
<strong> {{ notification.data.title }} </strong>
<span> {{ notification.data.text }} </span>
</div>
<div
slot="icon"
class="mt-3"
:class="notification.data.icon"
></div>
</base-notification>
</template>
<script>
import BaseNotification from './base';
export default {
components: {
BaseNotification,
},
props: {
notification: {
type: Object,
default (data) {
return data;
},
},
canRemove: {
type: Boolean,
default: true,
},
},
methods: {
action () {
if (!this.notification || !this.notification.data) {
return;
}
if (this.notification.data.destination === 'backgrounds') {
this.$store.state.avatarEditorOptions.editingUser = true;
this.$store.state.avatarEditorOptions.startingPage = 'backgrounds';
this.$store.state.avatarEditorOptions.subpage = '2023';
this.$root.$emit('bv::show::modal', 'avatar-modal');
} else {
this.$router.push({ name: this.notification.data.destination || 'items' });
}
},
},
};
</script>
@@ -123,23 +123,24 @@ import successImage from '@/assets/svg/success.svg';
import starBadge from '@/assets/svg/star-badge.svg';
// Notifications
import NEW_STUFF from './notifications/newStuff';
import GROUP_TASK_NEEDS_WORK from './notifications/groupTaskNeedsWork';
import GUILD_INVITATION from './notifications/guildInvitation';
import PARTY_INVITATION from './notifications/partyInvitation';
import CARD_RECEIVED from './notifications/cardReceived';
import CHALLENGE_INVITATION from './notifications/challengeInvitation';
import QUEST_INVITATION from './notifications/questInvitation';
import GIFT_ONE_GET_ONE from './notifications/g1g1';
import GROUP_TASK_ASSIGNED from './notifications/groupTaskAssigned';
import GROUP_TASK_CLAIMED from './notifications/groupTaskClaimed';
import UNALLOCATED_STATS_POINTS from './notifications/unallocatedStatsPoints';
import NEW_MYSTERY_ITEMS from './notifications/newMysteryItems';
import CARD_RECEIVED from './notifications/cardReceived';
import NEW_INBOX_MESSAGE from './notifications/newPrivateMessage';
import GROUP_TASK_NEEDS_WORK from './notifications/groupTaskNeedsWork';
import GUILD_INVITATION from './notifications/guildInvitation';
import ITEM_RECEIVED from './notifications/itemReceived';
import NEW_CHAT_MESSAGE from './notifications/newChatMessage';
import WORLD_BOSS from './notifications/worldBoss';
import VERIFY_USERNAME from './notifications/verifyUsername';
import NEW_INBOX_MESSAGE from './notifications/newPrivateMessage';
import NEW_MYSTERY_ITEMS from './notifications/newMysteryItems';
import NEW_STUFF from './notifications/newStuff';
import ONBOARDING_COMPLETE from './notifications/onboardingComplete';
import GIFT_ONE_GET_ONE from './notifications/g1g1';
import PARTY_INVITATION from './notifications/partyInvitation';
import QUEST_INVITATION from './notifications/questInvitation';
import UNALLOCATED_STATS_POINTS from './notifications/unallocatedStatsPoints';
import VERIFY_USERNAME from './notifications/verifyUsername';
import WORLD_BOSS from './notifications/worldBoss';
import OnboardingGuide from './onboardingGuide';
export default {
@@ -147,24 +148,25 @@ export default {
MenuDropdown,
MessageCount,
// One component for each type
NEW_STUFF,
GROUP_TASK_NEEDS_WORK,
GUILD_INVITATION,
PARTY_INVITATION,
CARD_RECEIVED,
CHALLENGE_INVITATION,
QUEST_INVITATION,
GIFT_ONE_GET_ONE,
GROUP_TASK_ASSIGNED,
GROUP_TASK_CLAIMED,
UNALLOCATED_STATS_POINTS,
NEW_MYSTERY_ITEMS,
CARD_RECEIVED,
NEW_INBOX_MESSAGE,
GROUP_TASK_NEEDS_WORK,
GUILD_INVITATION,
ITEM_RECEIVED,
NEW_CHAT_MESSAGE,
WorldBoss: WORLD_BOSS,
VERIFY_USERNAME,
OnboardingGuide,
NEW_INBOX_MESSAGE,
NEW_MYSTERY_ITEMS,
NEW_STUFF,
ONBOARDING_COMPLETE,
GIFT_ONE_GET_ONE,
PARTY_INVITATION,
QUEST_INVITATION,
UNALLOCATED_STATS_POINTS,
VERIFY_USERNAME,
WorldBoss: WORLD_BOSS,
OnboardingGuide,
},
data () {
return {
@@ -185,6 +187,7 @@ export default {
// 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',
@@ -40,7 +40,7 @@
>{{ $t('editAvatar') }}</a>
<a
class="topbar-dropdown-item dropdown-item dropdown-separated"
@click="showAvatar('backgrounds', '2022')"
@click="showAvatar('backgrounds', '2023')"
>{{ $t('backgrounds') }}</a>
<a
class="topbar-dropdown-item dropdown-item"
@@ -787,18 +787,15 @@ export default {
if (sortBy === 'sortByColor') {
groupKey = 'potionKey';
} else if (sortBy === 'AZ') {
groupKey = '';
groupKey = i => i.eggName[0];
} else if (sortBy === 'sortByHatchable') {
groupKey = i => (i.isHatchable() ? 0 : 1);
}
const groupedPets = groupBy(pets, groupKey);
// Pets are rendered as grouped "rows". Count helps decide if show more button is necessary.
if (sortBy === 'AZ') {
this.petRowCount[animalGroup.key] = 1;
} else {
this.petRowCount[animalGroup.key] = Object.keys(groupedPets).length;
}
this.petRowCount[animalGroup.key] = Object.keys(groupedPets).length;
return groupedPets;
},
mounts (animalGroup, hideMissing, sortBy, searchText) {
@@ -814,14 +811,12 @@ export default {
if (sortBy === 'sortByColor') {
groupKey = 'potionKey';
} else if (sortBy === 'AZ') {
groupKey = '';
groupKey = i => i.eggName[0];
}
const groupedMounts = groupBy(mounts, groupKey);
if (sortBy === 'AZ') {
this.mountRowCount[animalGroup.key] = 1;
} else {
this.mountRowCount[animalGroup.key] = Object.keys(groupedMounts).length;
}
this.mountRowCount[animalGroup.key] = Object.keys(groupedMounts).length;
return groupedMounts;
},
// Actions
@@ -0,0 +1,877 @@
<template>
<b-modal
id="birthday-modal"
:hide-header="true"
:hide-footer="true"
>
<div class="modal-content">
<div
class="modal-close"
@click="close()"
>
<div
class="svg-icon svg-close"
v-html="icons.close"
>
</div>
</div>
<div
class="svg-confetti svg-icon"
v-html="icons.confetti"
>
</div>
<div>
<img
src="~@/assets/images/10-birthday.png"
class="ten-birthday"
>
</div>
<div class="limited-wrapper">
<div
class="svg-gifts svg-icon"
v-html="icons.gifts"
>
</div>
<div class="limited-event">
{{ $t('limitedEvent') }}
</div>
<div class="dates">
{{ $t('anniversaryLimitedDates') }}
</div>
<div
class="svg-gifts-flip svg-icon"
v-html="icons.gifts"
>
</div>
</div>
<div class="celebrate d-flex justify-content-center">
{{ $t('celebrateAnniversary') }}
</div>
<h2 class="d-flex justify-content-center">
<span
class="left-divider"
v-html="icons.divider"
></span>
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
{{ $t('jubilantGryphatricePromo') }}
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
<span
class="right-divider"
></span>
</h2>
<!-- gryphatrice info -->
<div class="d-flex">
<div class="jubilant-gryphatrice d-flex mr-auto">
<img
src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Gryphatrice-Jubilant-Large.gif"
width="156px"
height="144px"
alt="a pink, purple, and green gryphatrice pet winks at you adorably"
>
</div>
<div class="align-items-center">
<div class="limited-edition mr-auto">
{{ $t('limitedEdition') }}
</div>
<div class="gryphatrice-text">
{{ $t('anniversaryGryphatriceText') }}
</div>
<div
class="gryphatrice-price"
v-html="$t('anniversaryGryphatricePrice')"
>
</div>
</div>
</div>
<!-- beginning of payments -->
<!-- buy with money OR gems -->
<div
v-if="!ownGryphatrice && !gryphBought"
>
<div
v-if="selectedPage !== 'payment-buttons'"
id="initial-buttons"
class="d-flex justify-content-center"
>
<button
class="btn btn-secondary buy-now-left"
:class="{active: selectedPage === 'payment-buttons'}"
@click="selectedPage = 'payment-buttons'"
>
{{ $t('buyNowMoneyButton') }}
</button>
<button
class="btn btn-secondary buy-now-right"
@click="buyGryphatriceGems()"
>
{{ $t('buyNowGemsButton') }}
</button>
</div>
<!-- buy with money -->
<div
v-else-if="selectedPage === 'payment-buttons'"
id="payment-buttons"
class="d-flex flex-column"
>
<button
class="btn btn-secondary d-flex stripe"
@click="redirectToStripe({ sku: 'price_0MPZ6iZCD0RifGXlLah2furv' })"
>
<span
class="svg-stripe"
v-html="icons.stripe"
>
</span>
</button>
<button
class="btn btn-secondary d-flex paypal"
@click="openPaypal({
url: paypalCheckoutLink, type: 'sku', sku: 'Pet-Gryphatrice-Jubilant'
})"
>
<span
class="svg-paypal"
v-html="icons.paypal"
>
</span>
</button>
<amazon-button
:disabled="disabled"
:amazon-data="amazonData"
class="btn btn-secondary d-flex amazon"
v-html="icons.amazon"
/>
<div
class="pay-with-gems"
@click="selectedPage = 'initial-buttons'"
>
{{ $t('wantToPayWithGemsText') }}
</div>
</div>
</div>
<!-- Own the gryphatrice -->
<div
v-else
class="d-flex"
>
<button
class="own-gryphatrice-button"
@click="closeAndRedirect('/inventory/stable')"
v-html="$t('ownJubilantGryphatrice')"
>
</button>
</div>
<!-- end of payments -->
<h2 class="d-flex justify-content-center">
<span
class="left-divider"
v-html="icons.divider"
></span>
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
{{ $t('plentyOfPotions') }}
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
<span
class="right-divider"
></span>
</h2>
<div class="plenty-of-potions d-flex">
{{ $t('plentyOfPotionsText') }}
</div>
<div class="potions">
<div class="pot-1">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Porcelain.png">
</div>
<div class="pot-2">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Vampire.png">
</div>
<div class="pot-3">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Aquatic.png">
</div>
<div class="pot-4">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_StainedGlass.png">
</div>
<div class="pot-5">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Celestial.png">
</div>
<div class="pot-6">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Glow.png">
</div>
<div class="pot-7">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_AutumnLeaf.png">
</div>
<div class="pot-8">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_SandSculpture.png">
</div>
<div class="pot-9">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Peppermint.png">
</div>
<div class="pot-10">
<img src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Shimmer.png">
</div>
</div>
<button
class="btn btn-secondary d-flex justify-content-center visit-the-market"
@click="closeAndRedirect('/shops/market')"
>
{{ $t('visitTheMarketButton') }}
</button>
<h2 class="d-flex justify-content-center">
<span
class="left-divider"
v-html="icons.divider"
></span>
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
{{ $t('fourForFree') }}
<span
class="svg-cross"
v-html="icons.cross"
>
</span>
<span
class="right-divider"
></span>
</h2>
<div class="four-for-free">
{{ $t('fourForFreeText') }}
</div>
<div class="four-grid d-flex justify-content-center">
<div class="day-one-a">
<div class="day-text">
{{ $t('dayOne') }}
</div>
<div class="gift d-flex justify-content-center align-items-middle">
<img
src="~@/assets/images/robes.webp"
class="m-auto"
width="40px"
height="66px"
>
</div>
<div class="description">
{{ $t('partyRobes') }}
</div>
</div>
<div class="day-one-b">
<div class="day-text">
{{ $t('dayOne') }}
</div>
<div class="gift d-flex justify-content-center align-items-middle">
<div
class="svg-gem svg-icon m-auto"
v-html="icons.birthdayGems"
>
</div>
</div>
<div class="description">
{{ $t('twentyGems') }}
</div>
</div>
<div class="day-five">
<div class="day-text">
{{ $t('dayFive') }}
</div>
<div class="gift d-flex justify-content-center align-items-middle">
<img
src="~@/assets/images/habitica-hero-goober.webp"
class="m-auto"
><!-- Birthday Set -->
</div>
<div class="description">
{{ $t('birthdaySet') }}
</div>
</div>
<div class="day-ten">
<div class="day-text">
{{ $t('dayTen') }}
</div>
<div class="gift d-flex justify-content-center align-items-middle">
<div
class="svg-background svg-icon m-auto"
v-html="icons.birthdayBackground"
>
</div>
</div>
<div class="description">
{{ $t('background') }}
</div>
</div>
</div>
</div>
<div class="modal-bottom">
<div class="limitations d-flex justify-content-center">
{{ $t('limitations') }}
</div>
<div class="fine-print">
{{ $t('anniversaryLimitations') }}
</div>
</div>
</b-modal>
</template>
<style lang="scss">
#birthday-modal {
.modal-body {
padding: 0px;
border: 0px;
}
.modal-content {
border-radius: 14px;
border: 0px;
}
.modal-footer {
border-radius: 14px;
border: 0px;
}
.amazon {
margin-bottom: 16px;
svg {
width: 84px;
position: absolute;
}
.amazonpay-button-inner-image {
opacity: 0;
width: 100%;
}
}
}
</style>
<style scoped lang="scss">
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/mixins.scss';
#birthday-modal {
h2 {
font-size: 1.25rem;
font-weight: bold;
line-height: 1.4;
color: $white;
column-gap: 0.5rem;
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
align-content: center;
}
.modal-body{
box-shadow: 0 14px 28px 0 rgba(26, 24, 29, 0.24), 0 10px 10px 0 rgba(26, 24, 29, 0.28);
}
.modal-content {
width: 566px;
padding: 32px 24px 24px;
background: linear-gradient(158deg,#6133b4,#4f2a93);
border-top-left-radius: 12px;
border-top-right-radius: 12px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
.modal-bottom {
width: 566px;
background-color: $purple-50;
color: $purple-500;
line-height: 1.33;
border-top: 0px;
padding: 16px 40px 28px 40px;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
}
.limitations {
color: $white;
font-weight: bold;
line-height: 1.71;
margin-top: 8px;
justify-content: center;
}
.fine-print {
font-size: 0.75rem;
color: $purple-500;
line-height: 1.33;
margin-top: 8px;
text-align: center;
}
.ten-birthday {
position: relative;
width: 268px;
height: 244px;
margin: 0 125px 16px;
}
.limited-event {
font-size: 0.75rem;
font-weight: bold;
text-transform: uppercase;
text-align: center;
justify-content: center;
letter-spacing: 2.4px;
margin-top: -8px;
color: $yellow-50;
}
.dates {
font-size: 0.875rem;
font-weight: bold;
line-height: 1.71;
text-align: center;
justify-content: center;
color: $white;
}
.celebrate {
font-size: 1.25rem;
font-weight: bold;
line-height: 1.4;
margin: 16px 16px 24px 16px;
text-align: center;
color: $yellow-50;
}
.jubilant-gryphatrice {
height: 176px;
width: 204px;
border-radius: 12px;
background-color: $purple-50;
align-items: center;
justify-content: center;
margin-right: 24px;
margin-left: 4px;
color: $white;
}
.limited-wrapper {
margin-top: -36px;
margin-bottom: -36px;
}
.limited-edition, .gryphatrice-text, .gryphatrice-price {
max-width: 274px;
}
.limited-edition {
font-size: 0.75rem;
font-weight: bold;
text-transform: uppercase;
line-height:1.33;
letter-spacing:2.4px;
padding-top: 18px;
margin-left: 24px;
margin-bottom: 8px;
color: $yellow-50;
}
.gryphatrice-text, .gryphatrice-price {
font-size: 0.875rem;
line-height: 1.71;
margin-left: 24px;
margin-right: 4px;
color: $white;
}
.gryphatrice-price {
padding-top: 16px;
margin-left: 24px;
}
.buy-now-left {
width: 243px;
margin: 24px 8px 24px 0px;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12), 0 1px 2px 0 rgba(26, 24, 29, 0.24);
}
.buy-now-right {
width: 243px;
margin: 24px 0px 24px 8px;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12), 0 1px 2px 0 rgba(26, 24, 29, 0.24);
}
.stripe {
margin-top: 24px;
margin-bottom: 8px;
padding-bottom: 10px;
}
.paypal {
margin-bottom: 8px;
padding-bottom: 10px;
}
.stripe, .paypal, .amazon {
width: 506px;
height: 32px;
margin-left: 4px;
margin-right: 4px;
border-radius: 4px;
flex-direction: row;
justify-content: center;
align-items: center;
cursor: pointer;
}
.pay-with-gems {
color: $white;
text-align: center;
margin-bottom: 24px;
cursor: pointer;
}
.pay-with-gems:hover {
text-decoration: underline;
cursor: pointer;
}
.own-gryphatrice-button {
width: 506px;
height: 32px;
margin: 24px 4px;
border-radius: 4px;
justify-content: center;
align-items: center;
border: $green-100;
background-color: $green-100;
color: $green-1;
cursor: pointer;
}
.plenty-of-potions {
font-size: 0.875rem;
line-height: 1.71;
margin: 0 8px 24px;
text-align: center;
color: $white;
}
.potions {
display: grid;
grid-template-columns: 5;
grid-template-rows: 2;
gap: 24px 24px;
justify-content: center;
.pot-1, .pot-2, .pot-3, .pot-4, .pot-5,
.pot-6, .pot-7, .pot-8, .pot-9, .pot-10 {
height: 68px;
width: 68px;
border-radius: 8px;
background-color: $purple-50;
}
.pot-1 {
grid-column: 1 / 1;
grid-row: 1 / 2;
}
.pot-2 {
grid-column: 2 / 2;
grid-row: 1 / 2;
}
.pot-3 {
grid-column: 3 / 3;
grid-row: 1 / 2;
}
.pot-4 {
grid-column: 4 / 4;
grid-row: 1 / 2;
}
.pot-5 {
grid-column: 5 / 5;
grid-row: 1 / 2;
}
.pot-6 {
grid-column: 1 / 5;
grid-row: 2 / 2;
}
.pot-7 {
grid-column: 2 / 5;
grid-row: 2 / 2;
}
.pot-8 {
grid-column: 3 / 5;
grid-row: 2 / 2;
}
.pot-9 {
grid-column: 4 / 5;
grid-row: 2 / 2;
}
.pot-10 {
grid-column: 5 / 5;
grid-row: 2 / 2;
}
}
.visit-the-market {
height: 32px;
margin: 24px 4px;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12), 0 1px 2px 0 rgba(26, 24, 29, 0.24);
cursor: pointer;
}
.four-for-free {
font-size: 0.875rem;
line-height: 1.71;
margin: 0 36px 24px;
text-align: center;
color: $white;
}
.four-grid {
display: grid;
grid-template-columns: 4;
grid-template-rows: 1;
gap: 24px;
}
.day-one-a, .day-one-b, .day-five, .day-ten {
height: 140px;
width: 100px;
border-radius: 8px;
background-color: $purple-50;
}
.day-one-a {
grid-column: 1 / 1;
grid-row: 1 / 1;
}
.day-one-b {
grid-column: 2 / 2;
grid-row: 1 / 1;
}
.day-five {
grid-column: 3 / 3;
grid-row: 1 / 1;
}
.day-ten {
grid-column: 4 / 4;
grid-row: 1 / 1;
}
.day-text {
font-size: 0.75rem;
font-weight: bold;
line-height: 1.33;
letter-spacing: 2.4px;
text-align: center;
text-transform: uppercase;
padding: 4px 0px;
color: $yellow-50;
}
.gift {
height: 80px;
width: 84px;
margin: 0 8px 32px;
background-color: $purple-100;
}
.description {
font-size: 0.75rem;
line-height: 1.33;
text-align: center;
padding: 8px 0px;
margin-top: -32px;
color: $white;
}
// SVG CSS
.modal-close {
position: absolute;
right: 16px;
top: 16px;
cursor: pointer;
.svg-close {
width: 18px;
height: 18px;
vertical-align: middle;
fill: $purple-50;
& svg path {
fill: $purple-50 !important;;
}
& :hover {
fill: $purple-50;
}
}
}
.svg-confetti {
position: absolute;
height: 152px;
width: 518px;
margin-top: 24px;
}
.svg-gifts, .svg-gifts-flip {
position: relative;
height: 32px;
width: 85px;
}
.svg-gifts {
margin-left: 70px;
top: 30px;
}
.svg-gifts-flip {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
left: 366px;
bottom: 34px;
}
.left-divider, .right-divider {
background-image: url('~@/assets/images/fancy-divider.png');
background-position: right center;
background-repeat: no-repeat;
display: inline-flex;
flex-grow: 2;
min-height: 1.25rem;
}
.right-divider {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
.svg-cross {
height: 12px;
width: 12px;
color: $yellow-50;
}
.svg-gem {
height: 48px;
width: 58px;
}
.svg-background {
height: 68px;
width: 68px;
}
.svg-stripe {
height: 20px;
width: 48px;
}
.svg-paypal {
height: 16px;
width: 60px;
}
}
</style>
<script>
// to check if user owns JG or not
import { mapState } from '@/libs/store';
// Purchase functionality
import buy from '@/mixins/buy';
import notifications from '@/mixins/notifications';
import payments from '@/mixins/payments';
import content from '@/../../common/script/content/index';
import amazonButton from '@/components/payments/buttons/amazon';
// import images
import close from '@/assets/svg/new-close.svg';
import confetti from '@/assets/svg/confetti.svg';
import gifts from '@/assets/svg/gifts-birthday.svg';
import cross from '@/assets/svg/cross.svg';
import stripe from '@/assets/svg/stripe.svg';
import paypal from '@/assets/svg/paypal-logo.svg';
import amazon from '@/assets/svg/amazonpay.svg';
import birthdayGems from '@/assets/svg/birthday-gems.svg';
import birthdayBackground from '@/assets/svg/icon-background-birthday.svg';
export default {
components: {
amazonButton,
},
mixins: [buy, notifications, payments],
data () {
return {
amazonData: {
type: 'single',
sku: 'Pet-Gryphatrice-Jubilant',
},
icons: Object.freeze({
close,
confetti,
gifts,
cross,
stripe,
paypal,
amazon,
birthdayGems,
birthdayBackground,
}),
selectedPage: 'initial-buttons',
gryphBought: false,
};
},
computed: {
...mapState({
user: 'user.data',
}),
ownGryphatrice () {
return Boolean(this.user && this.user.items.pets['Gryphatrice-Jubilant']);
},
},
methods: {
hide () {
this.$root.$emit('bv::hide::modal', 'birthday-modal');
},
buyGryphatriceGems () {
const gryphatrice = content.petInfo['Gryphatrice-Jubilant'];
if (this.user.balance * 4 < gryphatrice.value) {
this.$root.$emit('bv::show::modal', 'buy-gems');
return this.hide();
}
if (!this.confirmPurchase(gryphatrice.currency, gryphatrice.value)) {
return null;
}
this.makeGenericPurchase(gryphatrice);
this.gryphBought = true;
return this.purchased(gryphatrice.text());
},
closeAndRedirect (route) {
const routeTerminator = route.split('/')[route.split('/').length - 1];
if (this.$router.history.current.name !== routeTerminator) {
this.$router.push(route);
}
this.hide();
},
close () {
this.$root.$emit('bv::hide::modal', 'birthday-modal');
},
},
};
</script>
@@ -78,6 +78,7 @@ export default {
orderReferenceId: null,
subscription: null,
coupon: null,
sku: null,
},
isAmazonSetup: false,
amazonButtonEnabled: false,
@@ -174,7 +175,10 @@ export default {
storePaymentStatusAndReload (url) {
let paymentType;
if (this.amazonPayments.type === 'single' && !this.amazonPayments.gift) paymentType = 'gems';
if (this.amazonPayments.type === 'single') {
if (this.amazonPayments.sku) paymentType = 'sku';
else if (!this.amazonPayments.gift) paymentType = 'gems';
}
if (this.amazonPayments.type === 'subscription') paymentType = 'subscription';
if (this.amazonPayments.groupId || this.amazonPayments.groupToCreate) paymentType = 'groupPlan';
if (this.amazonPayments.type === 'single' && this.amazonPayments.gift && this.amazonPayments.giftReceiver) {
@@ -223,6 +227,7 @@ export default {
const data = {
orderReferenceId: this.amazonPayments.orderReferenceId,
gift: this.amazonPayments.gift,
sku: this.amazonPayments.sku,
};
if (this.amazonPayments.gemsBlock) {
@@ -83,6 +83,7 @@
}
h4 {
color: $gray-10;
font-size: 0.875rem;
font-weight: bold;
text-align: center;
@@ -359,8 +359,8 @@
.svg-icon.check {
color: $purple-400;
width: 0.77rem;
height: 0.615rem;
width: 16px;
height: 16px;
}
.text-leadin {
@@ -1,8 +1,8 @@
<template>
<b-modal
id="payments-success-modal"
:hide-footer="isNewGroup || isGems || isSubscription"
:modal-class="isNewGroup || isGems || isSubscription
:hide-footer="isNewGroup || isGems || isSubscription || ownsJubilantGryphatrice"
:modal-class="isNewGroup || isGems || isSubscription || ownsJubilantGryphatrice
? ['modal-hidden-footer'] : []"
>
<!-- HEADER -->
@@ -20,7 +20,7 @@
<div class="check-container d-flex align-items-center justify-content-center">
<div
v-once
class="svg-icon check"
class="svg-icon svg-check"
v-html="icons.check"
></div>
</div>
@@ -107,6 +107,35 @@
class="small-text auto-renew"
>{{ $t('paymentAutoRenew') }}</span>
</template>
<!-- if you buy the Jubilant Gryphatrice during 10th birthday -->
<template
v-if="ownsJubilantGryphatrice"
>
<div class="words">
<p class="jub-success">
<span
v-once
v-html="$t('jubilantSuccess')"
>
</span>
</p>
<p class="jub-success">
<span
v-once
v-html="$t('stableVisit')"
>
</span>
</p>
</div>
<div class="gryph-bg">
<img
src="https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Gryphatrice-Jubilant-Large.gif"
alt="a pink, purple, and green gryphatrice pet winks at you adorably"
width="78px"
height="72px"
>
</div>
</template>
<!-- buttons for subscriptions / new Group / buy Gems for self -->
<button
v-if="isNewGroup || isGems || isSubscription"
@@ -116,6 +145,14 @@
>
{{ $t('onwards') }}
</button>
<!-- buttons for Jubilant Gryphatrice purchase during 10th birthday -->
<button
v-if="ownsJubilantGryphatrice"
class="btn btn-primary mx-auto btn-jub"
@click="closeAndRedirect()"
>
{{ $t('takeMeToStable') }}
</button>
</div>
</div>
<!-- FOOTER -->
@@ -232,9 +269,8 @@
margin-bottom: 16px;
}
.check {
width: 35.1px;
height: 28px;
.svg-check {
width: 45px;
color: $white;
}
}
@@ -293,6 +329,34 @@
.group-billing-date {
width: 269px;
}
.words {
margin-bottom: 16px;
justify-content: center;
font-size: 0.875rem;
color: $gray-50;
line-height: 1.71;
}
.jub-success {
margin-top: 0px;
margin-bottom: 0px;
}
.gryph-bg {
width: 110px;
height: 104px;
align-items: center;
justify-content: center;
padding: 16px;
border-radius: 4px;
background-color: $gray-700;
}
.btn-jub {
margin-bottom: 8px;
margin-top: 24px;
}
}
.modal-footer {
background: $gray-700;
@@ -430,6 +494,9 @@ export default {
isNewGroup () {
return this.paymentData.paymentType === 'groupPlan' && this.paymentData.newGroup;
},
ownsJubilantGryphatrice () {
return this.paymentData.paymentType === 'sku'; // will need to be revised when there are other discrete skus in system
},
},
mounted () {
this.$root.$on('habitica:payment-success', data => {
@@ -458,6 +525,12 @@ export default {
this.sendingInProgress = false;
this.$root.$emit('bv::hide::modal', 'payments-success-modal');
},
closeAndRedirect () {
if (this.$router.history.current.name !== 'stable') {
this.$router.push('/inventory/stable');
}
this.close();
},
submit () {
if (this.paymentData.group && !this.paymentData.newGroup) {
Analytics.track({
@@ -93,7 +93,7 @@
<div class="subscribe-card mx-auto">
<div
v-if="hasSubscription && !hasCanceledSubscription"
class="d-flex flex-column align-items-center"
class="d-flex flex-column align-items-center pt-4"
>
<div class="round-container bg-green-10 d-flex align-items-center justify-content-center">
<div
@@ -107,7 +107,7 @@
</h2>
<div
v-if="hasGroupPlan"
class="mx-5 text-center"
class="mx-5 mb-4 text-center"
>
{{ $t('youHaveGroupPlan') }}
</div>
@@ -130,7 +130,7 @@
</div>
<button
class="btn btn-primary btn-update-card
d-flex justify-content-center align-items-center"
d-flex justify-content-center align-items-center mb-4"
@click="redirectToStripeEdit()"
>
<div
@@ -143,21 +143,61 @@
</div>
<div
v-else
class="svg-icon"
class="svg-icon mb-4"
:class="paymentMethodLogo.class"
v-html="paymentMethodLogo.icon"
>
</div>
<div
v-if="purchasedPlanExtraMonthsDetails.months > 0"
class="extra-months green-10 py-2 px-3 mt-4"
class="extra-months green-10 py-2 px-3 mb-4"
v-html="$t('purchasedPlanExtraMonths',
{months: purchasedPlanExtraMonthsDetails.months})"
>
</div>
</div>
<div
v-if="hasCanceledSubscription"
v-if="hasGiftSubscription"
class="d-flex flex-column align-items-center mt-4"
>
<div class="round-container bg-green-10 d-flex align-items-center justify-content-center">
<div
v-once
class="svg-icon svg-check"
v-html="icons.checkmarkIcon"
></div>
</div>
<h2 class="green-10 mx-auto mb-75">
{{ $t('youAreSubscribed') }}
</h2>
<div
class="mx-4 text-center mb-4 lh-71"
>
<span v-once>
{{ $t('haveNonRecurringSub') }}
</span>
<span
v-once
v-html="$t('subscriptionInactiveDate', {date: subscriptionEndDate})"
>
</span>
</div>
<h2 v-once>
{{ $t('switchToRecurring') }}
</h2>
<small
v-once
class="mx-4 mb-3 text-center"
>
{{ $t('continueGiftSubBenefits') }}
</small>
<subscription-options
:note="'subscriptionCreditConversion'"
class="w-100 mb-2"
/>
</div>
<div
v-else-if="hasCanceledSubscription"
class="d-flex flex-column align-items-center mt-4"
>
<div class="round-container bg-gray-300 d-flex align-items-center justify-content-center">
@@ -180,7 +220,7 @@
</div>
<div
v-if="hasSubscription"
class="bg-gray-700 py-3 mt-4 mb-3 text-center"
class="bg-gray-700 py-3 mb-3 text-center"
>
<div class="header-mini mb-3">
{{ $t('subscriptionStats') }}
@@ -322,6 +362,12 @@
max-width: 21rem;
}
small {
color: $gray-100;
font-size: 12px ;
line-height: 1.33;
}
strong {
font-size: 16px;
}
@@ -399,6 +445,10 @@
height: 49px;
}
.lh-71 {
line-height: 1.71;
}
.maroon-50 {
color: $maroon-50;
}
@@ -443,7 +493,6 @@
}
.subscribe-card {
padding-top: 2rem;
width: 28rem;
border-radius: 8px;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
@@ -472,8 +521,7 @@
}
.svg-check {
width: 35.1px;
height: 28px;
width: 36px;
color: $white;
}
@@ -670,6 +718,9 @@ export default {
hasSubscription () {
return Boolean(this.user.purchased.plan.customerId);
},
hasGiftSubscription () {
return this.user.purchased.plan.customerId === 'Gift';
},
hasCanceledSubscription () {
return (
this.hasSubscription
@@ -1,6 +1,6 @@
<template>
<div id="subscription-form">
<b-form-group class="mb-4 w-100 h-100">
<b-form-group class="mb-3 w-100 h-100">
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
<b-form-radio
v-for="block in subscriptionBlocksOrdered"
@@ -32,6 +32,15 @@
</div>
</b-form-radio>
</b-form-group>
<div class="mx-4 mb-4 text-center">
<small
v-if="note"
v-once
class="font-italic"
>
{{ $t(note) }}
</small>
</div>
<!-- payment buttons first is for gift subs and the second is for renewing subs -->
<payments-buttons
v-if="userReceivingGift && userReceivingGift._id"
@@ -82,7 +91,10 @@
.subscription-bubble, .discount-bubble {
border-radius: 100px;
padding-left: 12px;
padding-right: 12px;
font-size: 12px;
line-height: 1.33;
}
.subscription-bubble {
@@ -100,8 +112,20 @@
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
small {
color: $gray-100;
display: inline-block;
font-size: 12px ;
font-weight: normal;
line-height: 1.33;
}
.subscribe-option {
border-bottom: 1px solid $gray-600;
background-color: $gray-700;
&:not(:last-of-type) {
border-bottom: 1px solid $gray-600;
}
}
</style>
@@ -121,6 +145,10 @@ export default {
paymentsMixin,
],
props: {
note: {
type: String,
default: null,
},
userReceivingGift: {
type: Object,
default () {},
@@ -154,13 +182,13 @@ export default {
subscriptionBubbles (subscription) {
switch (subscription) {
case 'basic_3mo':
return '<span class="subscription-bubble px-2 py-1 mr-1">Gem cap raised to 30</span><span class="subscription-bubble px-2 py-1">+1 Mystic Hourglass</span>';
return '<span class="subscription-bubble py-1 mr-1">Gem cap raised to 30</span><span class="subscription-bubble py-1">+1 Mystic Hourglass</span>';
case 'basic_6mo':
return '<span class="subscription-bubble px-2 py-1 mr-1">Gem cap raised to 35</span><span class="subscription-bubble px-2 py-1">+2 Mystic Hourglass</span>';
return '<span class="subscription-bubble py-1 mr-1">Gem cap raised to 35</span><span class="subscription-bubble py-1">+2 Mystic Hourglass</span>';
case 'basic_12mo':
return '<span class="discount-bubble px-2 py-1 mr-1">Save 20%</span><span class="subscription-bubble px-2 py-1 mr-1">Gem cap raised to 45</span><span class="subscription-bubble px-2 py-1">+4 Mystic Hourglass</span>';
return '<span class="discount-bubble py-1 mr-1">Save 20%</span><span class="subscription-bubble py-1 mr-1">Gem cap raised to 45</span><span class="subscription-bubble py-1">+4 Mystic Hourglass</span>';
default:
return '<span class="subscription-bubble px-2 py-1">Gem cap at 25</span>';
return '<span class="subscription-bubble py-1">Gem cap at 25</span>';
}
},
updateSubscriptionData (key) {
@@ -385,7 +385,6 @@ import EquipmentAttributesGrid from '../inventory/equipment/attributesGrid.vue';
import Item from '@/components/inventory/item';
import Avatar from '@/components/avatar';
import seasonalShopConfig from '@/../../common/script/libs/shops-seasonal.config';
import { drops as dropEggs } from '@/../../common/script/content/eggs';
import { drops as dropPotions } from '@/../../common/script/content/hatching-potions';
@@ -438,7 +437,6 @@ export default {
selectedAmountToBuy: 1,
isPinned: false,
endDate: seasonalShopConfig.dateRange.end,
};
},
computed: {
@@ -489,6 +487,9 @@ export default {
nonSubscriberHourglasses () {
return (!this.user.purchased.plan.customerId && !this.user.purchased.plan.consecutive.trinkets && this.getPriceClass() === 'hourglasses');
},
endDate () {
return moment(this.item.event.end);
},
},
watch: {
item: function itemChanged () {
@@ -8,16 +8,6 @@
:popover-position="'top'"
@click="itemSelected(item)"
>
<span slot="popoverContent">
<strong v-if="item.key === 'gem' && gemsLeft === 0">{{ $t('maxBuyGems') }}</strong>
<h4 class="popover-content-title">{{ item.text }}</h4>
<div
v-if="item.event"
class="mt-2"
>
{{ limitedString }}
</div>
</span>
<template
slot="itemBadge"
slot-scope="ctx"
@@ -32,11 +22,9 @@
import _filter from 'lodash/filter';
import _sortBy from 'lodash/sortBy';
import _map from 'lodash/map';
import moment from 'moment';
import { mapState } from '@/libs/store';
import pinUtils from '@/mixins/pinUtils';
import planGemLimits from '@/../../common/script/libs/planGemLimits';
import seasonalShopConfig from '@/../../common/script/libs/shops-seasonal.config';
import ShopItem from '../shopItem';
import CategoryItem from './categoryItem';
@@ -48,12 +36,6 @@ export default {
},
mixins: [pinUtils],
props: ['hideLocked', 'hidePinned', 'searchBy', 'sortBy', 'category'],
data () {
return {
timer: '',
limitedString: '',
};
},
computed: {
...mapState({
content: 'content',
@@ -106,43 +88,10 @@ export default {
return result;
},
},
mounted () {
this.countdownString();
this.timer = setInterval(this.countdownString, 1000);
},
beforeDestroy () {
this.cancelAutoUpdate();
},
methods: {
itemSelected (item) {
this.$root.$emit('buyModal::showItem', item);
},
countdownString () {
const diffDuration = moment.duration(moment(seasonalShopConfig.dateRange.end).diff(moment()));
if (diffDuration.asSeconds() <= 0) {
this.limitedString = this.$t('noLongerAvailable');
} else if (diffDuration.days() > 0 || diffDuration.months() > 0) {
this.limitedString = this.$t('limitedAvailabilityDays', {
days: moment(seasonalShopConfig.dateRange.end).diff(moment(), 'days'),
hours: diffDuration.hours(),
minutes: diffDuration.minutes(),
});
} else if (diffDuration.asMinutes() > 2) {
this.limitedString = this.$t('limitedAvailabilityHours', {
hours: diffDuration.hours(),
minutes: diffDuration.minutes(),
});
} else {
this.limitedString = this.$t('limitedAvailabilityMinutes', {
minutes: diffDuration.minutes(),
seconds: diffDuration.seconds(),
});
}
},
cancelAutoUpdate () {
clearInterval(this.timer);
},
},
};
</script>
@@ -146,6 +146,7 @@
</style>
<script>
import find from 'lodash/find';
import _filter from 'lodash/filter';
import _map from 'lodash/map';
import _throttle from 'lodash/throttle';
@@ -225,7 +226,7 @@ export default {
user: 'user.data',
userStats: 'user.data.stats',
userItems: 'user.data.items',
currentEvent: 'worldState.data.currentEvent',
currentEventList: 'worldState.data.currentEventList',
}),
market () {
return shops.getMarketShop(this.user);
@@ -292,15 +293,16 @@ export default {
return Object.values(this.viewOptions).some(g => g.selected);
},
imageURLs () {
if (!this.currentEvent || !this.currentEvent.season) {
const currentEvent = find(this.currentEventList, event => Boolean(event.season));
if (!currentEvent) {
return {
background: 'url(/static/npc/normal/market_background.png)',
npc: 'url(/static/npc/normal/market_banner_npc.png)',
};
}
return {
background: `url(/static/npc/${this.currentEvent.season}/market_background.png)`,
npc: `url(/static/npc/${this.currentEvent.season}/market_banner_npc.png)`,
background: `url(/static/npc/${currentEvent.season}/market_background.png)`,
npc: `url(/static/npc/${currentEvent.season}/market_banner_npc.png)`,
};
},
},
@@ -263,8 +263,8 @@
</style>
<script>
import moment from 'moment';
import { mapState } from '@/libs/store';
import seasonalShopConfig from '@/../../common/script/libs/shops-seasonal.config';
import svgClock from '@/assets/svg/clock.svg';
import svgClose from '@/assets/svg/close.svg';
@@ -319,7 +319,6 @@ export default {
isPinned: false,
selectedAmountToBuy: 1,
endDate: seasonalShopConfig.dateRange.end,
};
},
computed: {
@@ -343,6 +342,9 @@ export default {
if (this.priceType === 'hourglasses') return this.icons.hourglass;
return this.icons.gem;
},
endDate () {
return moment(this.item.event.end);
},
},
watch: {
item: function itemChanged () {
@@ -397,11 +397,14 @@
</style>
<script>
import find from 'lodash/find';
import _filter from 'lodash/filter';
import _sortBy from 'lodash/sortBy';
import _throttle from 'lodash/throttle';
import _groupBy from 'lodash/groupBy';
import _map from 'lodash/map';
import _each from 'lodash/each';
import * as stopword from 'stopword/dist/stopword.esm.mjs';
import { mapState } from '@/libs/store';
import ShopItem from '../shopItem';
@@ -426,6 +429,51 @@ import SelectTranslatedArray from '@/components/tasks/modal-controls/selectTrans
import QuestPopover from './questPopover';
import { worldStateMixin } from '@/mixins/worldState';
function splitMultipleDelims (text, delims) {
const omniDelim = 'θνι';
let workingText = text;
for (const delim of delims) {
workingText = workingText.replace(new RegExp(delim, 'g'), omniDelim);
}
return workingText.split(omniDelim);
}
function removeStopwordsFromText (text, language) {
// list of supported languages https://www.npmjs.com/package/stopword
const langs = {
bg: stopword.bul,
cs: stopword.ces,
da: stopword.dan,
de: stopword.deu,
en: stopword.eng,
en_GB: stopword.eng,
'en@pirate': stopword.eng.concat(["th'"]),
es: stopword.spa,
es_419: stopword.spa,
fr: stopword.fra,
he: stopword.heb,
hu: stopword.hun,
id: stopword.ind,
it: stopword.ita,
ja: stopword.jpn,
nl: stopword.nld,
pl: stopword.pol,
pt: stopword.por,
pt_BR: stopword.porBr,
ro: stopword.ron,
ru: stopword.rus,
sk: stopword.slv,
// sr: stopword.,
sv: stopword.swe,
tr: stopword.tur,
uk: stopword.ukr,
zh: stopword.zho,
zh_TW: stopword.zho,
};
const splitText = splitMultipleDelims(text, [' ', "'"]);
return stopword.removeStopwords(splitText, langs[language] || stopword.eng).join(' ').toLowerCase();
}
export default {
components: {
QuestPopover,
@@ -465,7 +513,7 @@ export default {
user: 'user.data',
userStats: 'user.data.stats',
userItems: 'user.data.items',
currentEvent: 'worldState.data.currentEvent',
currentEventList: 'worldState.data.currentEventList',
}),
shop () {
return shops.getQuestShop(this.user);
@@ -489,15 +537,16 @@ export default {
return Object.values(this.viewOptions).some(g => g.selected);
},
imageURLs () {
if (!this.currentEvent || !this.currentEvent.season) {
const currentEvent = find(this.currentEventList, event => Boolean(event.season));
if (!currentEvent) {
return {
background: 'url(/static/npc/normal/quest_shop_background.png)',
npc: 'url(/static/npc/normal/quest_shop_npc.png)',
};
}
return {
background: `url(/static/npc/${this.currentEvent.season}/quest_shop_background.png)`,
npc: `url(/static/npc/${this.currentEvent.season}/quest_shop_npc.png)`,
background: `url(/static/npc/${currentEvent.season}/quest_shop_background.png)`,
npc: `url(/static/npc/${currentEvent.season}/quest_shop_npc.png)`,
};
},
},
@@ -539,7 +588,14 @@ export default {
switch (sortBy) { // eslint-disable-line default-case
case 'AZ': {
result = _sortBy(result, ['text']);
if (category.identifier === 'pet' || category.identifier === 'hatchingPotion') {
_each(result, item => {
item.sortText = removeStopwordsFromText(item.text, this.user.preferences.language);
});
result = _sortBy(result, ['sortText']);
} else {
result = _sortBy(result, ['text']);
}
break;
}
@@ -206,12 +206,11 @@
}
span.svg-icon.inline.check {
height: 12px;
width: 10px;
height: 16px;
width: 16px;
position: absolute;
left: 8px;
top: 8px;
margin-top: 0;
left: 4px;
top: 4px;
color: $gray-200;
}
@@ -2,7 +2,7 @@
<div class="container-fluid">
<h1>{{ $t('communityGuidelines') }}</h1>
<hr>
<p>{{ $t('lastUpdated') }} July 28, 2021</p>
<p>{{ $t('lastUpdated') }} February 8, 2023</p>
<h2 id="welcome">
{{ $t('commGuideHeadingWelcome') }}
</h2>
@@ -21,6 +21,7 @@
<p v-html="$t('commGuidePara016')"></p>
<p v-html="$t('commGuidePara017')"></p>
<ul>
<li v-html="$t('commGuideList01F')"></li>
<li v-html="$t('commGuideList01A')"></li>
<li v-html="$t('commGuideList01B')"></li>
<li v-html="$t('commGuideList01C')"></li>
@@ -32,6 +33,7 @@
<img src="~@/assets/images/community-guidelines/publicSpaces.png">
</div>
<ul>
<li v-html="$t('commGuideList02N')"></li>
<li v-html="$t('commGuideList02A')"></li>
<li v-html="$t('commGuideList02B')"></li>
<li v-html="$t('commGuideList02G')"></li>
@@ -147,10 +149,9 @@
<li>
{{ $t('commGuideList10A') }}
<ul>
<li>{{ $t('commGuideList10A1') }}</li>
<li v-html="$t('commGuideList10A1')"></li>
</ul>
</li>
<li v-html="$t('commGuideList10C')"></li>
<li v-html="$t('commGuideList10D')"></li>
<li v-html="$t('commGuideList10F')"></li>
</ul>
@@ -176,50 +177,53 @@
<h2 id="meet-the-mods">
{{ $t('commGuideHeadingMeet') }}
</h2>
<p v-html="$t('commGuidePara006')"></p>
<p v-html="$t('commGuidePara007')"></p>
<p v-html="$t('commGuidePara008')"></p>
<p v-html="$t('commGuidePara009')"></p>
<div class="media align-items-center">
<img src="~@/assets/images/community-guidelines/staff.png">
<div class="media-body">
<ul>
<li>{{ $t('commGuideAKA', {habitName: 'Viirus', realName: 'Phillip'}) }}</li>
<li>
{{ $t('commGuideAKA', {habitName: 'heyeilatan', realName: 'Natalie'}) }}
({{ $t('commGuideOnGitHub', {gitHubName: 'CuriousMagpie'}) }})
- Web Developer
</li>
<li>
{{ $t('commGuideAKA', {habitName: 'Viirus', realName: 'Phillip'}) }}
- Mobile Developer
</li>
<li>
{{ $t('commGuideAKA', {habitName: 'redphoenix', realName: 'Vicky'}) }}
({{ $t('commGuideOnGitHub', {gitHubName: 'veeeeeee'}) }})
- Co-Founder
</li>
<li>
{{ $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
</li>
<li>
{{ $t('commGuideAKA', {habitName: 'Piyo', realName: 'Sara'}) }}
- Mobile Designer
</li>
<li>{{ $t('commGuideAKA', {habitName: 'Beffymaroo', realName: 'Beth'}) }}</li>
<li>{{ $t('commGuideAKA', {habitName: 'SabreCat', realName: 'Sabe'}) }}</li>
<li>{{ $t('commGuideAKA', {habitName: 'Apollo', realName: 'Tressley'}) }}</li>
<li>{{ $t('commGuideAKA', {habitName: 'Piyo', realName: 'Sara'}) }}</li>
</ul>
</div>
</div>
<p v-html="$t('commGuidePara010')"></p>
<div class="media align-items-center">
<img src="~@/assets/images/community-guidelines/moderators.png">
<div class="media-body">
<p v-html="$t('commGuidePara011')"></p>
<ul>
<li>Dewines</li>
<li>Nakonana</li>
<li>Cantras</li>
<li>Alys (LadyAlys {{ $t('commGuidePara011c') }})</li>
<li>Fox_town</li>
<li>MaybeSteveRogers</li>
<li>shanaqui</li>
<li>deilann (not yet pictured)</li>
</ul>
</div>
</div>
<p v-html="$t('commGuidePara012')"></p>
<p v-html="$t('commGuidePara013')"></p>
<p>
{{ $t('commGuidePara014') }}<br>
<em>
Lemoness, lefnire, Slappybag, litenull, Shaner, Bobbyroberts99, wc8,
Breadstrings, Megan, Blade, and Daniel the Bard
Breadstrings, Megan, Blade, Daniel the Bard, deilann, shanaqui, Nakonana,
Dewines, Alys, Fox_town, MaybeSteveRogers, and Cantras.
</em>
</p>
<h2 id="final">
@@ -240,6 +244,7 @@
</ul>
<p v-html="$t('commGuidePara069')"></p>
<ul class="list-2col list-unstyled">
<li>Beffymaroo</li>
<li>Breadstrings</li>
<li>Draayder</li>
<li>Kiwibot</li>
+28 -39
View File
@@ -5,36 +5,44 @@
>
<div class="row">
<div class="col-12 col-md-6 offset-md-3">
<h1 id="faq-heading">
<h1
v-once
id="faq-heading"
>
{{ $t('frequentlyAskedQuestions') }}
</h1>
<div
v-for="(heading, index) in headings"
v-for="(entry, index) in faq.questions"
:key="index"
class="faq-question"
>
<h2
v-b-toggle="heading"
v-once
v-b-toggle="entry.heading"
role="tab"
variant="info"
@click="handleClick($event)"
>
{{ $t(`faqQuestion${index}`) }}
{{ entry.question }}
</h2>
<b-collapse
:id="heading"
:visible="isVisible(heading)"
:id="entry.heading"
:visible="isVisible(entry.heading)"
accordion="faq"
role="tabpanel"
>
<div
v-markdown="$t(`webFaqAnswer${index}`, replacements)"
v-once
v-markdown="entry.web"
class="card-body"
></div>
</b-collapse>
</div>
<hr>
<p v-markdown="$t('webFaqStillNeedHelp')"></p>
<p
v-once
v-markdown="stillNeedHelp"
></p>
</div>
</div>
</div>
@@ -42,7 +50,7 @@
<style lang='scss' scoped>
.card-body {
margin-bottom: 1em;
margin-bottom: 1em;
}
.faq-question h2 {
@@ -70,53 +78,34 @@
</style>
<script>
// @TODO: env.EMAILS.TECH_ASSISTANCE_EMAIL
import markdownDirective from '@/directives/markdown';
const TECH_ASSISTANCE_EMAIL = 'admin@habitica.com';
export default {
directives: {
markdown: markdownDirective,
},
data () {
const headings = [
'overview',
'set-up-tasks',
'sample-tasks',
'task-color',
'health',
'party-with-friends',
'pets-mounts',
'character-classes',
'blue-mana-bar',
'monsters-quests',
'gems',
'bugs-features',
'world-boss',
'group-plans',
];
const hash = window.location.hash.replace('#', '');
return {
headings,
replacements: {
techAssistanceEmail: TECH_ASSISTANCE_EMAIL,
wikiTechAssistanceEmail: `mailto:${TECH_ASSISTANCE_EMAIL}`,
},
visible: hash && headings.includes(hash) ? hash : null,
faq: {},
headings: [],
stillNeedHelp: '',
};
},
mounted () {
async mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('help'),
subSection: this.$t('faq'),
});
this.faq = await this.$store.dispatch('faq:getFAQ');
for (const entry of this.faq.questions) {
this.headings.push(entry.heading);
}
this.stillNeedHelp = this.faq.stillNeedHelp.web;
},
methods: {
isVisible (heading) {
return this.visible && this.visible === heading;
const hash = window.location.hash.replace('#', '');
return hash && this.headings.includes(hash) && hash === heading;
},
handleClick (e) {
if (!e) return;
+4 -4
View File
@@ -1,5 +1,5 @@
<template>
<div class="task-wrapper">
<div class="task-wrapper" draggable>
<div
class="task transition"
:class="[{
@@ -773,9 +773,9 @@
}
.check.svg-icon {
width: 12.3px;
height: 9.8px;
margin: 9px 8px;
width: 16px;
height: 16px;
margin: 5px;
}
.challenge.broken {
@@ -1,105 +1,308 @@
<template>
<div class="row">
<div class="col-6">
<h1>{{ $t('gemTransactions') }}</h1>
<span v-if="gemTransactions.length === 0">{{ $t('noGemTransactions') }}</span>
<table class="table">
<tr
v-for="entry in gemTransactions"
:key="entry.createdAt"
<div>
<div class="clearfix">
<div class="mb-4 float-left">
<button
class="page-header btn-flat tab-button textCondensed"
:class="{'active': selectedTab === 'gems'}"
@click="selectTab('gems')"
>
<td>
<span
v-b-tooltip.hover="entry.createdAt"
>{{ entry.createdAt | timeAgo }}</span>
</td>
<td>
<span
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons.gem"
></span>
<span
class="amount gems"
:class="entry.amount < 0 ? 'deducted' : 'added'"
>{{ entry.amount * 4 }}</span>
</td>
<td>
<span>{{ transactionTypeText(entry.transactionType) }}</span>
</td>
<td>
<span v-html="entryReferenceText(entry)"></span>
</td>
</tr>
</table>
</div>
<div class="col-6">
<h1>{{ $t('hourglassTransactions') }}</h1>
<span v-if="hourglassTransactions.length === 0">{{ $t('noHourglassTransactions') }}</span>
<table class="table">
<tr
v-for="entry in hourglassTransactions"
:key="entry.createdAt"
{{ $t('gems') }}
</button>
<button
class="page-header btn-flat tab-button textCondensed"
:class="{'active': selectedTab === 'hourglass'}"
@click="selectTab('hourglass')"
>
<td>
<span
v-b-tooltip.hover="entry.createdAt"
>{{ entry.createdAt | timeAgo }}</span>
</td>
<td>
<span
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons.hourglass"
></span>
<span
class="amount hourglasses"
:class="entry.amount < 0 ? 'deducted' : 'added'"
>{{ entry.amount }}</span>
</td>
<td>
<span>{{ transactionTypeText(entry.transactionType) }}</span>
</td>
<td>
<span v-html="entryReferenceText(entry)"></span>
</td>
</tr>
</table>
{{ $t('mysticHourglass', { amount: ''}) }}
</button>
</div>
</div>
<div class="row">
<div class="col-12" v-if="selectedTab === 'gems'">
<span v-if="gemTransactions.length === 0">
{{ $t('noGemTransactions') }}
</span>
<table class="table">
<tr>
<th v-once class="timestamp-column">
{{ $t('timestamp')}}
</th>
<th v-once class="amount-column">
{{ $t('amount')}}
</th>
<th v-once class="action-column">
{{ $t('action')}}
</th>
<th v-once class="note-column">
{{ $t('note')}}
</th>
</tr>
<tr
v-for="entry in gemTransactions"
:key="entry.createdAt"
>
<td>
<span
v-b-tooltip.hover="entry.createdAt"
>{{ entry.createdAt | timeAgo }}</span>
</td>
<td>
<div class="amount-with-icon" :id="entry.id">
<span
class="svg-icon inline icon-16 my-1"
aria-hidden="true"
v-html="entry.amount < 0 ? icons.gemRed : icons.gem"
></span>
<span
class="amount gems"
:class="entry.amount | addedDeducted"
>{{ entry.amount * 4 }}</span>
</div>
<b-popover
v-if="typeof entry.currentAmount !== 'undefined'"
ref="popover"
:target="entry.id"
triggers="hover focus click"
placement="bottom"
>
<div class="remaining-amount-popover-content">
{{ $t('remainingBalance') }}:
<span
class="svg-icon inline icon-16 ml-1"
aria-hidden="true"
v-html="icons.gem"
></span>
<span
class="amount gems"
>{{ entry.currentAmount * 4 }}</span>
</div>
</b-popover>
</td>
<td class="entry-action">
<span v-html="transactionTypeText(entry.transactionType)"></span>
</td>
<td>
<span v-if="transactionTypes.gifted.includes(entry.transactionType)">
<router-link
class="user-link"
:to="{'name': 'userProfile', 'params': {'userId': entry.reference}}"
>
@{{ entry.referenceText }}
</router-link>
</span>
<span v-else-if="transactionTypes.challenges.includes(entry.transactionType)">
<router-link
class="challenge-link"
:to="{ name: 'challenge', params: { challengeId: entry.reference } }">
<span
v-markdown="entry.referenceText"
></span>
</router-link>
</span>
<span v-else v-html="entryReferenceText(entry)"></span>
<span v-if="entry.reference">
({{entry.reference}})
</span>
</td>
</tr>
</table>
</div>
<div class="col-12" v-if="selectedTab === 'hourglass'">
<span v-if="hourglassTransactions.length === 0">
{{ $t('noHourglassTransactions') }}
</span>
<table class="table">
<tr>
<th v-once class="timestamp-column">
{{ $t('timestamp')}}
</th>
<th v-once class="amount-column">
{{ $t('amount')}}
</th>
<th v-once class="action-column">
{{ $t('action')}}
</th>
<th v-once class="note-column">
{{ $t('note')}}
</th>
</tr>
<tr
v-for="entry in hourglassTransactions"
:key="entry.createdAt"
>
<td>
<span
v-b-tooltip.hover="entry.createdAt"
>{{ entry.createdAt | timeAgo }}</span>
</td>
<td>
<div class="amount-with-icon" :id="entry.id">
<span
class="svg-icon inline icon-16 my-1"
aria-hidden="true"
v-html="entry.amount < 0 ? icons.hourglassRed : icons.hourglass"
></span>
<span
class="amount hourglasses"
:class="entry.amount | addedDeducted"
>{{ entry.amount }}</span>
</div>
<b-popover
v-if="typeof entry.currentAmount !== 'undefined'"
ref="popover"
:target="entry.id"
triggers="hover focus click"
placement="bottom"
>
<div class="remaining-amount-popover-content">
{{ $t('remainingBalance') }}:
<span
class="svg-icon inline icon-16 ml-1"
aria-hidden="true"
v-html="icons.hourglass"
></span>
<span
class="amount gems"
>{{ entry.currentAmount }}</span>
</div>
</b-popover>
</td>
<td class="entry-action">
<span v-html="transactionTypeText(entry.transactionType)"></span>
</td>
<td>
<span v-html="entryReferenceText(entry)"></span>
</td>
</tr>
</table>
</div>
</div>
</div>
</template>
<style lang="scss">
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.page-header.btn-flat {
background: transparent;
}
.tab-button {
height: 2rem;
font-size: 24px;
font-weight: bold;
font-stretch: condensed;
line-height: 1.33;
letter-spacing: normal;
color: $gray-10;
margin-right: 1.125rem;
padding-left: 0;
padding-right: 0;
padding-bottom: 2.5rem;
&.active, &:hover {
color: $purple-300;
box-shadow: 0px -0.25rem 0px $purple-300 inset;
outline: none;
}
}
.amount-column {
white-space: nowrap;
}
.svg-icon {
vertical-align: middle;
}
.amount {
font-weight: bold;
font-size: 1.1rem;
margin-left: 4px;
}
.added::before {
content: "+";
}
.gems {
color: $gems-color;
color: $green-10;
&.deducted {
color: $red-10;
color: $maroon-50;
}
}
.hourglasses {
font-weight: bold;
color: $hourglass-color;
color: $green-10;
&.deducted {
color: $red-10;
color: $maroon-50;
}
}
.amount-with-icon {
display: inline-flex;
}
.remaining-amount-popover-content {
display: flex;
font-size: 12px;
line-height: 1.33;
color: $white;
}
table {
line-height: 1.71;
color: $gray-50;
}
th {
border-top: 0 !important;
padding: 0.25rem 0.5rem !important;
font-weight: bold;
line-height: 1.71;
color: $gray-50;
}
td {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
line-height: 1.71;
color: $gray-50;
}
th, td {
padding-top: 0.35rem !important;
padding-bottom: 0.35rem !important;
}
.timestamp-column, .action-column {
width: 20%;
}
.amount-column {
width: 10%;
}
.note-column {
width: 50%;
}
.challenge-link, .user-link {
color: $blue-10 !important;
}
.entry-action {
b {
text-transform: uppercase;
}
}
</style>
@@ -107,9 +310,15 @@
<script>
import moment from 'moment';
import svgGem from '@/assets/svg/gem.svg';
import svgGemRed from '@/assets/svg/gem-red.svg';
import svgHourglass from '@/assets/svg/hourglass.svg';
import svgHourglassRed from '@/assets/svg/hourglass-red.svg';
import markdownDirective from '@/directives/markdown';
export default {
directives: {
markdown: markdownDirective,
},
filters: {
timeAgo (value) {
return moment(value).fromNow();
@@ -118,6 +327,13 @@ export default {
// @TODO: Vue doesn't support this so we cant user preference
return moment(value).toDate().toString();
},
addedDeducted (amount) {
if (amount === 0) {
return '';
}
return amount < 0 ? 'deducted' : 'added';
},
},
props: {
gemTransactions: {
@@ -133,11 +349,21 @@ export default {
return {
icons: Object.freeze({
gem: svgGem,
gemRed: svgGemRed,
hourglass: svgHourglass,
hourglassRed: svgHourglassRed,
}),
selectedTab: 'gems',
transactionTypes: Object.freeze({
gifted: ['gift_send', 'gift_receive'],
challenges: ['create_challenge', 'create_bank_challenge'],
}),
};
},
methods: {
selectTab (type) {
this.selectedTab = type;
},
entryReferenceText (entry) {
if (entry.reference === undefined && entry.referenceText === undefined) {
return '';
@@ -863,16 +863,13 @@ export default {
this.loadUser();
this.oldTitle = this.$store.state.title;
this.selectPage(this.startingPage);
this.$root.$on('habitica:restoreTitle', () => {
if (this.oldTitle) {
this.$store.dispatch('common:setTitle', {
fullTitle: this.oldTitle,
});
}
});
},
beforeDestroy () {
this.$root.$off('habitica:restoreTitle');
if (this.oldTitle) {
this.$store.dispatch('common:setTitle', {
fullTitle: this.oldTitle,
});
}
},
methods: {
async loadUser () {
@@ -5,7 +5,6 @@
:hide-footer="true"
:hide-header="true"
@hide="beforeHide"
@hidden="onHidden"
@shown="onShown()"
>
<profile
@@ -55,14 +54,11 @@ export default {
},
beforeHide () {
if (this.$route.path !== window.location.pathname) {
this.$root.$emit('habitica:restoreTitle');
}
},
onHidden () {
if (this.$route.path !== window.location.pathname) {
this.$router.go(-1);
this.$router.back();
}
},
},
};
</script>
-40
View File
@@ -34,44 +34,4 @@ export default [
type: 'Staff',
uuid: 'f4e5c6da-0617-48bf-b3bd-9f97636774a8',
},
{
name: 'Alys',
type: 'Moderator',
uuid: 'd904bd62-da08-416b-a816-ba797c9ee265',
},
{
name: 'Cantras',
type: 'Moderator',
uuid: '28771972-ca6d-4c03-8261-e1734aa7d21d',
},
{
name: 'deilann',
type: 'Moderator',
uuid: 'e7b5d1e2-3b6e-4192-b867-8bafdb03eeec',
},
{
name: 'Dewines',
type: 'Moderator',
uuid: '262a7afb-6b57-4d81-88e0-80d2e9f6cbdc',
},
{
name: 'Fox_town',
type: 'Moderator',
uuid: 'a05f0152-d66b-4ef1-93ac-4adb195d0031',
},
{
name: 'MaybeSteveRogers',
type: 'Moderator',
uuid: '767e5d92-0e13-4e30-acb1-d8bba62824fc',
},
{
name: 'Nakonana',
type: 'Moderator',
uuid: '33bb14bd-814d-40cb-98a4-7b76a752761c',
},
{
name: 'shanaqui',
type: 'Moderator',
uuid: 'bb089388-28ae-4e42-a8fa-f0c2bfb6f779',
},
];
+1
View File
@@ -26,6 +26,7 @@ export default {
'Fox-Veteran',
'JackOLantern-Glow',
'Gryphon-Gryphatrice',
'Gryphatrice-Jubilant',
'JackOLantern-RoyalPurple',
];
const BASE_PETS = [
+9 -1
View File
@@ -9,7 +9,6 @@ import { CONSTANTS, setLocalSetting } from '@/libs/userlocalManager';
const { STRIPE_PUB_KEY } = process.env;
// const habiticaUrl = `${window.location.protocol}//${window.location.host}`;
let stripeInstance = null;
export default {
@@ -70,6 +69,7 @@ export default {
type,
giftData,
gemsBlock,
sku,
} = data;
let { url } = data;
@@ -93,6 +93,11 @@ export default {
url += `?gemsBlock=${gemsBlock.key}`;
}
if (type === 'sku') {
appState.sku = sku;
url += `?sku=${sku}`;
}
setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState));
window.open(url, '_blank');
@@ -129,6 +134,7 @@ export default {
if (data.group || data.groupToCreate) paymentType = 'groupPlan';
if (data.gift && data.gift.type === 'gems') paymentType = 'gift-gems';
if (data.gift && data.gift.type === 'subscription') paymentType = 'gift-subscription';
if (data.sku) paymentType = 'sku';
let url = '/stripe/checkout-session';
const postData = {};
@@ -148,6 +154,7 @@ export default {
if (data.coupon) postData.coupon = data.coupon;
if (data.groupId) postData.groupId = data.groupId;
if (data.demographics) postData.demographics = data.demographics;
if (data.sku) postData.sku = data.sku;
const response = await axios.post(url, postData);
@@ -250,6 +257,7 @@ export default {
if (data.type === 'single') {
this.amazonPayments.gemsBlock = data.gemsBlock;
this.amazonPayments.sku = data.sku;
}
if (data.gift) {
+5 -5
View File
@@ -272,6 +272,11 @@ const router = new VueRouter({
name: 'transactions',
path: 'transactions',
component: Transactions,
meta: {
privilegeNeeded: [
'userSupport',
],
},
},
{
name: 'notifications',
@@ -316,11 +321,6 @@ const router = new VueRouter({
{
name: 'front', path: 'front', component: HomePage, meta: { requiresLogin: false },
},
// Commenting out merch page see
// https://github.com/HabitRPG/habitica/issues/12039
// {
// name: 'merch', path: 'merch', component: MerchPage, meta: { requiresLogin: false },
// },
{
name: 'news', path: 'new-stuff', component: NewsPage, meta: { requiresLogin: false },
},
+7
View File
@@ -0,0 +1,7 @@
import axios from 'axios';
export async function getFAQ () {
const url = '/api/v4/faq?platform=web';
const response = await axios.get(url);
return response.data.data;
}
@@ -18,6 +18,7 @@ import * as snackbars from './snackbars';
import * as worldState from './worldState';
import * as news from './news';
import * as analytics from './analytics';
import * as faq from './faq';
// Actions should be named as 'actionName' and can be accessed as 'namespace:actionName'
// Example: fetch in user.js -> 'user:fetch'
@@ -41,6 +42,7 @@ const actions = flattenAndNamespace({
worldState,
news,
analytics,
faq,
});
export default actions;
+6 -6
View File
@@ -1,13 +1,13 @@
import axios from 'axios';
export async function getTags () {
const url = 'api/v4/tags';
const url = '/api/v4/tags';
const response = await axios.get(url);
return response.data.data;
}
export async function createTag (store, payload) {
const url = 'api/v4/tags';
const url = '/api/v4/tags';
const response = await axios.post(url, {
name: payload.name,
});
@@ -19,13 +19,13 @@ export async function createTag (store, payload) {
}
export async function getTag (store, payload) {
const url = `api/v4/tags/${payload.tagId}`;
const url = `/api/v4/tags/${payload.tagId}`;
const response = await axios.get(url);
return response.data.data;
}
export async function updateTag (store, payload) {
const url = `api/v4/tags/${payload.tagId}`;
const url = `/api/v4/tags/${payload.tagId}`;
const response = await axios.put(url, {
tagDetails: payload.tagDetails,
});
@@ -33,7 +33,7 @@ export async function updateTag (store, payload) {
}
export async function sortTag (store, payload) {
const url = 'api/v4/reorder-tags';
const url = '/api/v4/reorder-tags';
const response = await axios.post(url, {
tagId: payload.tagId,
to: payload.to,
@@ -42,7 +42,7 @@ export async function sortTag (store, payload) {
}
export async function deleteTag (store, payload) {
const url = `api/v4/tags/${payload.tagId}`;
const url = `/api/v4/tags/${payload.tagId}`;
const response = await axios.delete(url);
return response.data.data;
}
+15 -9
View File
@@ -127,16 +127,22 @@
"achievementReptacularRumbleModalText": "لقد جمعت كل الزواحف الأليفة!",
"achievementReptacularRumbleText": "لقد فقس جميع الألوان القياسية للحيوانات الأليفة الزواحف: التمساح، الزاحف المجنح، الأفعى، ترايسيراتوبس، السلحفاة، التيرانوصور ريكس وفيلوسيرابتور!",
"achievementBirdsOfAFeather": "أصدقاء الطيران",
"achievementZodiacZookeeper": "حارس حديقة الحيوانات الفلكية",
"achievementShadyCustomerText": "جمع كل حيوانات الظل الأليفة.",
"achievementShadyCustomerModalText": "لقد جمعت كل حيوانات الظل الأليفة!",
"achievementZodiacZookeeperModalText": "لقد جمعت كل الحيوانات الأليفة الفلكية!",
"achievementZodiacZookeeper": "حارس البروج",
"achievementShadyCustomerText": "جمعت كل الحيوانات الأليفة السوداء.",
"achievementShadyCustomerModalText": "لقد جمعت كل الحيوانات الأليفة السوداء!",
"achievementZodiacZookeeperModalText": "لقد جمعت كل حيوانات البروج الأليفة!",
"achievementBirdsOfAFeatherText": "لقد فقس جميع الألوان القياسية للحيوانات الأليفة الطائرة: الخنزير الطائر، البومة، الببغاء، الزاحف المجنح، الجرايفون، فالكون، الطاووس والديك!",
"achievementShadeOfItAllModalText": "قمت بترويض كل الحيوانات السوداء",
"achievementShadyCustomer": "عميل الظل",
"achievementShadeOfItAll": "الظل فوق كل شيء",
"achievementShadeOfItAllText": "روض كل حيوانات الظل السوداء.",
"achievementShadeOfItAllModalText": "لقد قمت بترويض كل الركوبات السوداء!",
"achievementShadyCustomer": "عميل مشبوه",
"achievementShadeOfItAll": "كل شيء في الظلام",
"achievementShadeOfItAllText": "قام بترويض كل الركوبات السوداء.",
"achievementWoodlandWizard": "ساحر الغابة",
"achievementWoodlandWizardText": "لقد فقس جميع الألوان القياسية لمخلوقات الغابة: الغرير، الدب، الغزال، الثعلب، الضفدع، القنفذ، البومة، الأفعى، السنجاب والشجيرة!",
"achievementWoodlandWizardModalText": "لقد جمعت كل حيوانات الغابة الأليفة!"
"achievementWoodlandWizardModalText": "لقد جمعت كل حيوانات الغابة الأليفة!",
"achievementPolarPro": "المحترف القطبي",
"achievementPolarProText": "فقست جميع الحيوانات الأليفة القطبية: الدب ، الثعلب ، البطريق ، الحوت ، والذئب!",
"achievementPolarProModalText": "لقد جمعت كل الحيوانات الأليفة القطبية!",
"achievementBoneToPick": "جامع العظام",
"achievementBoneToPickText": "فقست جميع الحيوانات الأليفة الهيكلية المغامرة والكلاسيكية!",
"achievementBoneToPickModalText": "لقد جمعت كل الحيوانات الأليفة الهيكلية المغامرة والكلاسيكية!"
}
+27 -1
View File
@@ -422,5 +422,31 @@
"backgroundDuckPondNotes": "أطعم الطيور المائية في بركة البط.",
"backgroundValentinesDayFeastingHallNotes": "اشعر بالحب في قاعة احتفالات عيد الحب.",
"hideLockedBackgrounds": "إخفاء الخلفيات المقفلة",
"backgrounds032019": "SET 58: تم إصداره في مارس 2019"
"backgrounds032019": "SET 58: تم إصداره في مارس 2019",
"backgroundFieldWithColoredEggsNotes": "ابحث عن كنز الربيع في حقل به بيض ملون.",
"backgroundFlowerMarketNotes": "اعثر على الزهور المثالية لباقة أو حديقة في سوق الزهور.",
"backgrounds052019": "المجموعة 60: صدرت في مايو 2019",
"backgroundHalflingsHouseNotes": "قم بزيارة منزل هافلينج الساحر.",
"backgroundBirchForestText": "غابة البتولا",
"backgroundBlossomingDesertNotes": "شاهد إزهارًا هائلًا نادرًا في الصحراء المزهرة.",
"backgroundDojoText": "دوجو",
"backgroundBlossomingDesertText": "الصحراء المزهرة",
"backgroundHalflingsHouseText": "منزل هافلينج",
"backgroundFlowerMarketText": "سوق الزهور",
"backgroundBirchForestNotes": "اقضِ بعض الوقت في غابة البتولا الهادئة.",
"backgroundFieldWithColoredEggsText": "حقل به بيض ملون",
"backgrounds042019": "المجموعة 59: صدرت في أبريل 2019",
"backgroundRainbowMeadowNotes": "ابحث عن وعاء الذهب حيث ينتهي قوس قزح في مرج.",
"backgrounds062019": "المجموعة 61: صدرت في يونيو 2019",
"backgroundUnderwaterVentsNotes": "غص في الأعماق حيث تكمن الفتحات المائية الحرارية.",
"backgroundRainbowMeadowText": "مرج قوس قزح",
"backgroundSeasideCliffsNotes": "قف على الشاطئ وسط جمال المنحدرات الساحلية المحيطة.",
"backgroundSchoolOfFishNotes": "اسبح بين سرب من الأسماك.",
"backgroundUnderwaterVentsText": "الفتحات الحرارية المائية",
"backgroundSeasideCliffsText": "المنحدرات الساحلية",
"backgroundParkWithStatueText": "حديقة بها تمثال",
"backgroundDojoNotes": "تعلم حركات جديدة في دوجو.",
"backgroundSchoolOfFishText": "سرب من الأسماك",
"backgrounds072019": "المجموعة 62: صدرت في يوليو 2019",
"backgroundParkWithStatueNotes": "اتبع مسارًا تصطف على جانبيه الأزهار عبر حديقة بها تمثال."
}
+2 -2
View File
@@ -91,7 +91,7 @@
"weaponSpecialTakeThisText": "Take This Sword",
"weaponSpecialTakeThisNotes": "This sword was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
"weaponSpecialTridentOfCrashingTidesText": "ترايدنت الأمواج المتضاربة",
"weaponSpecialTridentOfCrashingTidesNotes": "يمنحك القدرة على التحكم بالأسماك، وكذلك القدرة على تقديم بعض الطعنات القوية لمهماتك. يزيد الذكاء بقدر <%= int %>.",
"weaponSpecialTridentOfCrashingTidesNotes": "يمنحك القدرة على التحكم بالأسماك، وكذلك القدرة على توجيه بعض الطعنات القوية لمهماتك. يزيد الذكاء بقدر <%= int %>.",
"weaponSpecialTaskwoodsLanternText": "Taskwoods Lantern",
"weaponSpecialTaskwoodsLanternNotes": "Given at the dawn of time to the guardian ghost of the Taskwood Orchards, this lantern can illuminate the deepest darkness and weave powerful spells. Increases Perception and Intelligence by <%= attrs %> each.",
"weaponSpecialBardInstrumentText": "Bardic Lute",
@@ -117,7 +117,7 @@
"weaponSpecialYetiText": "رمح مروض اليتي",
"weaponSpecialYetiNotes": "هذا الرمح يسمح لمستخدمه الصيطرة على أي يتي. يزيد القوة بقدر <%= str %>. معدات الطبعة المحدودة لشتاء 2013-2014.",
"weaponSpecialSkiText": "عمود المتزلج القاتل",
"weaponSpecialSkiNotes": "سلاح قادر على تدمير المجموعات الكبيرة من الأعداء. وأيضاً يساعد مستخدمه على الانعطافات المتوازية. يزيد القوة بقدر <%= str %>. معدات الطبعة المحدودة لشتاء 2013-2014.",
"weaponSpecialSkiNotes": "سلاح قادر على تدمير المجموعات الكبيرة من الأعداء. وأيضاً يساعد مستخدمه على الانعطافات المتوازية. يزيد القوة بقدر <%= str %>. معدات الطبعة المحدودة لشتاء 2013-2014.",
"weaponSpecialCandycaneText": "قضيب حلوى القصب",
"weaponSpecialCandycaneNotes": "A powerful mage's staff. Powerfully DELICIOUS, we mean! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2013-2014 Winter Gear.",
"weaponSpecialSnowflakeText": "العصا السحرية ذات ندفة الثلج",
+4 -2
View File
@@ -11,7 +11,7 @@
"messageLikesFood": "<%= egg %> يحب <%= foodText %> كثيراً!",
"messageDontEnjoyFood": "<%= egg %> يأكل <%= foodText %> ولكنه لا يبدو مستمتعاً.",
"messageBought": "لقد اشتريت <%= itemText %>",
"messageUnEquipped": "<%= itemText %> unequipped.",
"messageUnEquipped": "<%= itemText %> غير مجهز/ة.",
"messageMissingEggPotion": "تفتقد أيًا من تلك البيضة أو جرعة الفقس.",
"messageInvalidEggPotionCombo": "لا يمكنك فقس بيض حيوانات التنقيب مع جرع فقس سحرية! جرب بيضة أخرى.",
"messageAlreadyPet": "لديك ذلك الحيوان الأليف. حاول فقس تركيبة مختلفة!",
@@ -50,5 +50,7 @@
"unallocatedStatsPoints": "You have <span class=\"notification-bold-blue\"><%= points %> unallocated Stat Points</span>",
"beginningOfConversation": "هذه هي بداية محادثتك مع <%= userName %>. تذكر أن تكون لطيفاً محترماً، واتبع إرشادات المنتدى!",
"messageDeletedUser": "عذراً، لقد حذف هذا المستخدم حسابه.",
"messageMissingDisplayName": "Missing display name."
"messageMissingDisplayName": "Missing display name.",
"messageBattleGearUnEquipped": "المعدات القتالية غير مجهزة.",
"messageCostumeUnEquipped": "الزي غير مجهز."
}
+11 -10
View File
@@ -1,8 +1,8 @@
{
"achievement": "Постижение",
"onwards": "Напред!",
"levelup": "Изпълнявайки целите си в истинския живот, Вие качихте ниво и здравето Ви беше запълнено!",
"reachedLevel": "Достигнахте ниво <%= level %>",
"levelup": "Изпълнявайки целите си в истинския живот, Вие се качихте ниво и здравето Ви беше запълнено!",
"reachedLevel": "Достигнахте Ниво <%= level %>",
"achievementLostMasterclasser": "Изпълнител на Мисии: Серия на Класовите Повелители",
"achievementLostMasterclasserText": "Завършихте шестнадесетте мисии от Серията на Класовите Повелители и разрешихте загадката на Изгубената Класова Повелителка!",
"achievementUndeadUndertaker": "Нежив Погребален Директор",
@@ -59,13 +59,13 @@
"foundNewItemsExplanation": "Завършека на задачи ви дава шанс да намерите предмети като Яйца, Излюпващи Отвари и Животинска Храна.",
"foundNewItems": "Намерихте нови предмети!",
"hideAchievements": "Скрий <%= category %>",
"showAllAchievements": "Покажи Всички",
"onboardingCompleteDescSmall": "Ако желаете още повече, отидете в Постижения и започнете събирането!",
"showAllAchievements": "Покажи Всички <%=category %>",
"onboardingCompleteDescSmall": "Ако желаете още повече, отидете в Постижения и започнете колекционирането!",
"onboardingCompleteDesc": "Получихте <strong>5 Постижения</strong> и <strong class=\"gold-amount\">100 Злато</strong> за завършения списък.",
"onboardingComplete": "Завършихте задачите си!",
"onboardingComplete": "Завършихте уводните си задачи!",
"earnedAchievement": "Получихте постижение!",
"yourProgress": "Вашият Напредък",
"gettingStartedDesc": "Изпълнете задачите и ще получите <strong>5 Постижения </strong> и <strong class=\"gold-amount\">100 Злато </strong>при завършване!",
"gettingStartedDesc": "Изпълнете тези уводни задачи и ще получите <strong>5 Постижения </strong> и <strong class=\"gold-amount\">100 Злато </strong>при завършване!",
"achievementPrimedForPaintingModalText": "Събрахте всички Бели Животни!",
"achievementPearlyProModalText": "Опитомихте всички Бели Оседлани Зверове!",
"achievementPearlyProText": "Опетомили са всички Оседлани Зверове.",
@@ -75,22 +75,23 @@
"achievementFedPet": "Нахрани Животно",
"achievementHatchedPetModalText": "Отиди в инвентара си и смеси излюпваща отвара с Яйце",
"achievementHatchedPet": "Излюпи Животно",
"viewAchievements": "Постижения",
"viewAchievements": регледай Постижения",
"letsGetStarted": "Нека да започнем!",
"onboardingProgress": "<%= percentage %>% напредък",
"achievementBareNecessitiesModalText": "Завършихте мисиите за Маймуна, Ленивец и Фиданка!",
"achievementBareNecessitiesText": "Завършили са всички мисии за Маймуна, Ленивец и Фиданка.",
"achievementBareNecessities": "От първа необходимост",
"achievementBoneCollectorText": "Събрали сте всички Скелети домашни любимци.",
"achievementBoneCollectorText": "Събрали са всички Скелетни Любимци.",
"achievementBoneCollector": "Колекционер на кости",
"achievementAllThatGlittersModalText": "Събрахте всички оседлани Златни животни!",
"achievementAllThatGlittersText": "Събрали сте всички оседлани Златни животни.",
"achievementAllThatGlitters": "Златен телец",
"achievementGoodAsGoldModalText": "Събрахте всички Златни домашни любимци!",
"achievementGoodAsGoldText": "Събрали сте всички Златни домашни любимци.",
"achievementGoodAsGoldText": "Събрахте всички Златни домашни любимци.",
"achievementGoodAsGold": "Златно сърце",
"achievementFreshwaterFriendsModalText": "Завършихте мисиите за аксолотъла, жабата и хипопотама!",
"achievementFreshwaterFriendsText": "Завършили сте мисиите за домашни любимци за аксолотъла, жабата и хипопотама.",
"achievementFreshwaterFriends": "Сладководни приятели",
"yourRewards": "Вашите възнаграждения"
"yourRewards": "Вашите Награди",
"achievementBoneCollectorModalText": "Събрали сте всичките Скелетни Любимци!"
}
+6 -3
View File
@@ -94,8 +94,8 @@
"achievementSkeletonCrewModalText": "Du hast alle Skelett-Reittiere gezähmt!",
"achievementSkeletonCrewText": "Hat alle Skelett-Reittiere gezähmt.",
"achievementSkeletonCrew": "Skelettbande",
"achievementBoneCollectorModalText": "Du hast alle Skelett-Haustiere gesammelt!",
"achievementBoneCollectorText": "Hat alle Skelett-Haustiere gesammelt.",
"achievementBoneCollectorModalText": "Du hast alle Skeletthaustiere gesammelt!",
"achievementBoneCollectorText": "Hat alle Skeletthaustiere gesammelt.",
"achievementBoneCollector": "Knochensammler",
"achievementRedLetterDayModalText": "Du hast alle roten Reittiere gezähmt!",
"achievementRedLetterDayText": "Hat alle roten Reittiere gezähmt.",
@@ -138,5 +138,8 @@
"achievementGroupsBeta2022ModalText": "Du hast mit Deinen Gruppen Habitica geholfen, indem ihr getestet und Feedback geschrieben habt!",
"achievementWoodlandWizardModalText": "Du hast alle Wald-Tiere gesammelt!",
"achievementWoodlandWizard": "Wald-Magier",
"achievementWoodlandWizardText": "Du hast alle Standard-Farben der Waldkreaturen ausgebrütet: Dachs, Bär, Hirsch, Fuchs, Frosch, Igel, Eule, Schlange, Eichhörnchen und Bäumling!"
"achievementWoodlandWizardText": "Du hast alle Standard-Farben der Waldkreaturen ausgebrütet: Dachs, Bär, Hirsch, Fuchs, Frosch, Igel, Eule, Schnecke, Eichhörnchen und Bäumling!",
"achievementBoneToPickModalText": "Du hast alle klassischen und Quest-Skeletthaustiere gesammelt!",
"achievementBoneToPick": "Ein harter Knochen",
"achievementBoneToPickText": "Hat alle klassischen und Quest-Skeletthaustiere ausgebrütet!"
}
+18 -1
View File
@@ -728,5 +728,22 @@
"backgroundAutumnPicnicNotes": "Genieße ein Herbstpicknick.",
"backgroundOldPhotoText": "Altes Foto",
"backgroundOldPhotoNotes": "Posiere auf einem alten Foto.",
"backgrounds092022": "Set 100: Veröffentlicht im September 2022"
"backgrounds092022": "Set 100: Veröffentlicht im September 2022",
"backgrounds102022": "Set 101: Veröffentlicht im Oktober 2022",
"backgroundSpookyRuinsText": "Gruselige Ruinen",
"backgroundMaskMakersWorkshopText": "Masken-Macher-Werkstatt",
"backgroundMaskMakersWorkshopNotes": "Probiere in der Masken-Macher-Werkstatt ein neues Gesicht aus.",
"backgroundCemeteryGateText": "Friedhofstor",
"backgroundCemeteryGateNotes": "Suche ein Friedhofstor heim.",
"backgroundSpookyRuinsNotes": "Erkunde gruselige Ruinen.",
"backgrounds112022": "Set 102: Veröffentlicht im November 2022",
"backgroundAmongGiantMushroomsNotes": "Bewundere Riesige Pilze.",
"backgroundAmongGiantMushroomsText": "Unter Riesigen Pilzen",
"backgroundMistyAutumnForestText": "Nebeliger Herbstwald",
"backgroundMistyAutumnForestNotes": "Durchstreife einen nebeligen Herbstwald.",
"backgroundAutumnBridgeText": "Brücke im Herbst",
"backgroundAutumnBridgeNotes": "Bewundere die Schönheit einer Brücke im Herbst.",
"backgrounds122022": "Set 103: Veröffentlicht im Dezember 2022",
"backgroundBranchesOfAHolidayTreeText": "Äste eines Festtagsbaums",
"backgroundBranchesOfAHolidayTreeNotes": "Baumle auf den Ästen eines Festtagsbaums."
}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -56,7 +56,7 @@
"mobileAndroid": "Android App",
"mobileIOS": "iOS App",
"oldNews": "Neuigkeiten",
"newsArchive": "Neuigkeiten-Archiv auf Wikia (mehrsprachig)",
"newsArchive": "Neuigkeiten-Archiv auf Fandom (mehrsprachig)",
"setNewPass": "Neues Passwort setzen",
"password": "Passwort",
"playButton": "Spielen",
+11 -1
View File
@@ -2730,5 +2730,15 @@
"armorSpecialFall2022HealerNotes": "Wie viele Beobachter könnte ein Beobachter beobachten, wenn ein Beobachter Beobachter beobachten könnte? Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2022 Herbstausrüstung.",
"headSpecialFall2022MageNotes": "Zieh andere in Deinen Bann und locke sie zu Dir hin mit dieser magischen Maidenmaske. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2022 Herbstausrüstung.",
"eyewearArmoireComedyMaskNotes": "Heiter! Eine malerische Maske für Dein fröhlich' Herz, spielend, Freude verkündend, Heiterkeit und Frohsinn auf der Bühne ausstrahlend. Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Theatermaskenset (Gegenstand 1 von 2).",
"eyewearArmoireTragedyMaskNotes": "Ach! Eine schwere Maske für Deinen armen Darsteller, stolzierend, sich grämend, und auf der Bühne Leid und Kummer ausdrückend. Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Theatermaskenset (Gegenstand 2 von 2)."
"eyewearArmoireTragedyMaskNotes": "Ach! Eine schwere Maske für Deinen armen Darsteller, stolzierend, sich grämend, und auf der Bühne Leid und Kummer ausdrückend. Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Theatermaskenset (Gegenstand 2 von 2).",
"armorArmoireSheetGhostCostumeText": "Bettuch-Geist-Kostüm",
"weaponMystery202211Text": "Blitzbeschwörer Stab",
"weaponMystery202211Notes": "Bündle die massive Macht eines Blitzgewitters mit diesem Stab. Gewährt keinen Attributbonus. November 2022 Abonnentengegenstand.",
"armorArmoireSheetGhostCostumeNotes": "Boo! Das ist das gruseligste Kostüm in Habitica, also geh vernünftig damit um … und gib Acht, dass Du nicht stolperst. Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Unabhängiger Gegenstand.",
"headMystery202211Text": "Blitzbeschwörer Hut",
"headMystery202211Notes": "Sei vorsichtig mit diesem blitzenden Hut, er kann einen sehr schockierenden Eindruck bei Deinen Bewunderern hinteralssen! Gewährt keinen Attributbonus. November 2022 Abonnentengegenstand.",
"weaponArmoireMagicSpatulaText": "Magischer Pfannenwender",
"weaponArmoireMagicSpatulaNotes": "Schau zu, wie Dein Essen durch die Luft fliegt und sich überschlägt. Du hast den Rest des Tages Glück wenn es dreimal magisch überschlägt, bevor es wieder am Pfannenwender landet. Erhöht Wahrnehmung um <%= per %>. Verzauberter Schrank: Küchenwerkzeugset (Gegenstand 1 von 2).",
"shieldArmoireBubblingCauldronText": "Übersprudelnder Kessel",
"shieldArmoireBubblingCauldronNotes": "Der perfekte Kessel, um einen Produktivitätstrank zu brühen oder eine würzige Suppe zu kochen. Um genau zu sein gibt es zwischen diesen beiden kaum einen Unterschied! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Küchenwerkzeugset (Gegenstand 2 von 2)."
}
+47 -12
View File
@@ -20,8 +20,8 @@
"dataTool": "Werkzeug zur Datenanzeige",
"resources": "Ressourcen",
"communityGuidelines": "Community-Richtlinien",
"bannedWordUsed": "Hoppla! Es sieht so aus, als würde dieser Beitrag ein Schimpfwort oder einen religiösen Fluch enthalten, oder sich auf Suchtstoffe oder nicht-jugendfreie Themen beziehen (<%= swearWordsUsed %>). Habitica hat Spieler unterschiedlichster Herkunft, weswegen wir unseren Chat besonders sauber halten wollen. Du kannst Deine Nachricht gerne überarbeiten, um sie doch noch posten zu können!",
"bannedSlurUsed": "Dein Beitrag enthielt unangebrachten Inhalt und Deine Chat Privilegien wurden Dir entzogen.",
"bannedWordUsed": "Hoppla! Es sieht so aus, als würde dieser Beitrag ein Schimpfwort enthalten, oder sich auf Suchtstoffe oder nicht-jugendfreie Themen beziehen (<%= swearWordsUsed %>). Habitica achtet darauf, unsere Chats frei von diesen Dingen zu halten. Du kannst Deine Nachricht gerne überarbeiten und sie wieder posten! Die betroffenen Wörter musst Du allerdings löschen, nicht einfach zensieren.",
"bannedSlurUsed": "Dein Beitrag enthielt unangebrachte Inhalte, daher wurden Dir Deine Chat-Privilegien entzogen.",
"party": "Party",
"usernameCopied": "Benutzername in die Zwischenablage kopiert.",
"createGroupPlan": "Erstellen",
@@ -107,7 +107,7 @@
"copyMessageAsToDo": "Nachricht als To-Do übernehmen",
"copyAsTodo": "Als To-Do kopieren",
"messageAddedAsToDo": "Nachricht als To-Do übernommen.",
"leaderOnlyChallenges": "Nur der Gruppenleiter kann Herausforderungen erstellen",
"leaderOnlyChallenges": "Nur die Gruppenleitung kann Herausforderungen erstellen",
"sendGift": "Ein Geschenk schicken",
"inviteFriends": "Lade Freunde ein",
"inviteByEmail": "Lade per E-Mail ein",
@@ -123,7 +123,7 @@
"sendGiftCost": "Insgesamt: $<%= cost %> USD",
"sendGiftFromBalance": "Vom Saldo",
"sendGiftPurchase": "Kauf",
"sendGiftMessagePlaceholder": "Persönliche Nachricht (optional)",
"sendGiftMessagePlaceholder": "Füge eine Geschenknachricht hinzu",
"sendGiftSubscription": "<%= months %> Monat(e): $<%= price %> USD",
"gemGiftsAreOptional": "Bitte nimm zur Kenntnis, dass Habitica niemals von Dir verlangen wird, anderen Spielern Edelsteine zu schenken. Bei anderen Spielern um Edelsteine zu betteln ist ein <strong>Verstoss gegen die Community-Richtlinien</strong>, und jedes Vorkommnis sollte bei <%= hrefTechAssistanceEmail %> gemeldet werden.",
"battleWithFriends": "Besiege mit Freunden Monster",
@@ -197,7 +197,7 @@
"userIsClamingTask": "`<%= username %> beansprucht:` <%= task %>",
"approvalRequested": "Zustimmung erbeten",
"cantDeleteAssignedGroupTasks": "Du kannst Gruppen-Aufgaben, die Dir zugewiesen wurden, nicht löschen.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> wurde auf einen Gruppenplan hochgestuft!",
"groupPlanUpgraded": "<strong><%- groupName %></strong> wurde erfolgreich auf einen Gruppenplan hochgestuft!",
"groupPlanCreated": "<strong><%- groupName %></strong> wurde erstellt!",
"onlyGroupLeaderCanInviteToGroupPlan": "Nur der Gruppenleiter kann Nutzer zu einer Gruppe mit einem Abonnement hinzufügen.",
"paymentDetails": "Zahlungsinformationen",
@@ -273,7 +273,7 @@
"createParty": "Erstelle eine Party",
"inviteMembersNow": "Möchtest Du jetzt Mitglieder einladen?",
"playInPartyTitle": "Spiele Habitica in einer Party!",
"playInPartyDescription": "Bewältige unglaubliche Quests - mit Freunden oder auf Dich allein gestellt. Besiege Monster, erstelle Wettbewerbe und hilf Dir selbst, verantwortungsvoll zu bleiben, indem Du einer Party beitrittst.",
"playInPartyDescription": "Bewältige unglaubliche Quests mit Freunden oder auf Dich allein gestellt. Besiege Monster, erstelle Herausforderungen und hilf Dir selbst, verantwortungsvoll zu bleiben, indem Du einer Party beitrittst.",
"wantToJoinPartyTitle": "Möchtest Du einer Party beitreten?",
"wantToJoinPartyDescription": "Gib Deinen Benutzernamen einem Freund, der bereits in einer Party ist, oder gehe zur <a href='/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'>Party Wanted Guild</a>, um potenzielle Verbündete zu finden!",
"copy": "Kopieren",
@@ -326,19 +326,19 @@
"whatsIncludedGroup": "Was beinhaltet das Abonnement",
"whatsIncludedGroupDesc": "Alle Mitglieder der Gruppe erhalten volle Abonnementvorteile, einschließlich der monatlichen Abonnentengegenstände, der Möglichkeit Edelsteine mit Gold zu kaufen, und das Königliche Purpurfarbene Wolpertinger-Reittier, das exklusiv für Benutzer mit einer Mitgliedschaft im Gruppenplan verfügbar ist.",
"howDoesBillingWork": "Wie funktioniert die Verrechnung?",
"howDoesBillingWorkDesc": "Gruppenleiter erhalten monatlich auf der Grundlage der Gruppenmitgliederzahl eine Gebühr in Rechnung gestellt. Diese Gebühr beinhaltet den Preis von $9 (USD) für das Abonnement des Gruppenleiters, plus $3 USD für jedes weitere Gruppenmitglied. Zum Beispiel: Eine Gruppe von vier Benutzern kostet $18 USD/Monat, da die Gruppe aus 1 Gruppenleiter + 3 Gruppenmitgliedern besteht.",
"howDoesBillingWorkDesc": "Auf Grundlage der Mitgliederzahl wird der Gruppenleitung monatlich eine Gebühr in Rechnung gestellt. Diese Gebühr beinhaltet den Preis von $9 (USD) für das Abonnement der Gruppenleitung, sowie $3 USD für jedes weitere Gruppenmitglied. Zum Beispiel: Eine Gruppe von vier Personen kostet $18 USD/Monat, da die Gruppe aus 1 Gruppenleitung + 3 weiteren Mitglieder besteht.",
"howToAssignTask": "Wie weise ich eine Aufgabe zu?",
"howToAssignTaskDesc": "Weise eine Aufgabe einem oder mehreren Gruppenmitgliedern (einschließlich des Gruppenleiters oder dem Organisator selbst) zu, indem Du ihre Benutzernamen in das Feld \"Zuweisen an\" im Bereich \"Aufgabe erstellen\" eingibst. Du kannst eine Aufgabe auch jemandem zuzuweisen, nachdem Du sie erstellt hast, indem du die Aufgabe bearbeitest und den Benutzer im Feld \"Zuweisen an\" hinzufügst!",
"howToAssignTaskDesc": "Weise eine Aufgabe einem oder mehreren Gruppenmitgliedern (einschließlich des Gruppenleiters oder dem Organisator selbst) zu, indem Du ihre Benutzernamen in das Feld \"Zuweisen an\" im Bereich \"Aufgabe erstellen\" einträgst. Du kannst eine Aufgabe auch jemandem zuzuweisen, nachdem Du sie erstellt hast, indem du die Aufgabe bearbeitest und den entsprechenden Namen im Feld \"Zuweisen an\" hinzufügst!",
"howToRequireApproval": "Wie markiert man eine Aufgabe mit \"Zustimmung benötigt\"?",
"howToRequireApprovalDesc": "Markiere die \"Zustimmung benötigt\" Einstellung, um eine Aufgabe durch einen Gruppenleiter oder einen Organisator bestätigen zu lassen. Der Benutzer, der die Aufgabe abhakt, erhält seine Belohnung für die Erledigung erst, nachdem die Zustimmung erteilt wurde.",
"howToRequireApprovalDesc2": "Gruppenleiter und Organisatoren können erledigte Aufgaben direkt von der Aufgabenliste oder aus dem Benachrichtigungs-Panel bestätigen.",
"howToRequireApprovalDesc": "Wähle die Option \"Zustimmung benötigt\" aus, um eine Aufgabe durch die Gruppenleitung oder die Organisation bestätigen zu lassen. Benutzende, welche die Aufgabe abhaken, erhalten ihre Belohnung hierfür erst, nachdem die Zustimmung erteilt wurde.",
"howToRequireApprovalDesc2": "Gruppenleitung und Organisation können erledigte Aufgaben direkt von der Aufgabenliste oder aus dem Benachrichtigungs-Panel bestätigen.",
"whatIsGroupManager": "Was ist ein Gruppen-Organisator?",
"whatIsGroupManagerDesc": "Gruppen-Organisatoren haben keinen Zugriff auf die Rechnungs-Details einer Gruppe, aber sie können verteilte Aufgaben für Gruppenmitglieder erstellen, zuweisen und bestätigen. Die Beförderung zum Organisator erfolgt in der Mitgliederliste.",
"goToTaskBoard": "Gehe zur Aufgabenliste",
"sharedCompletion": "Fertigstellungsbedingung",
"recurringCompletion": "Keine - Gruppenaufgabe kann nicht fertiggestellt werden",
"singleCompletion": "Einzeln - Ist erledigt sobald ein zugeteilter Benutzer abschliesst",
"allAssignedCompletion": "Alle - Ist erledigt sobald alle zugeteilten Benutzer abschliessen",
"allAssignedCompletion": "Alle Ist erledigt, sobald alle zugeteilten Benutzer abschliessen",
"pmReported": "Danke dass Du diese Nachricht gemeldet hast.",
"suggestedGroup": "Vorgeschlagen weil Du bei Habitica neu bist.",
"taskClaimed": "<%- userName %> hat die Aufgabe <span class=\"notification-bold\"><%- taskText %></span> übernommen.",
@@ -382,5 +382,40 @@
"sendGiftTotal": "Insgesamt:",
"chatTemporarilyUnavailable": "Chat aktuell nicht verfügbar. Bitte versuche es später erneut.",
"assignTo": "Zugewiesen an",
"newGroupsEnjoy": "Wir hoffen, Dir gefallen die neuen Gruppenpläne!"
"newGroupsEnjoy": "Wir hoffen, Dir gefallen die neuen Gruppenpläne!",
"groupUseDefault": "Wähle eine Antwort",
"createGroup": "Erstelle eine Gruppe",
"groupUse": "Was beschreibt den Zweck Deiner Gruppe am Besten?*",
"groupParentChildren": "Eltern(teile), die Aufgaben für ihre Kinder erstellen",
"groupCouple": "Ein Paar, das sich Aufgaben teilt",
"groupFriends": "Freunde, die sich Aufgaben teilen",
"groupCoworkers": "Arbeitskollegen, die sich Aufgaben teilen",
"groupManager": "Ein Manager, der Aufgaben für seine Mitarbeiter erstellt",
"groupTeacher": "Ein Lehrer, der Aufgaben für seine Schüler oder Studierenden erstellt",
"nameStar": "Name*",
"descriptionOptional": "Beschreibung",
"descriptionOptionalText": "Füge eine Beschreibung hinzu",
"nameStarText": "Füge einen Titel hinzu",
"nextPaymentMethod": "Weiter: Zahlungsmethode",
"dayStart": "<strong>Tageswechsel</strong>: <%= startTime %>",
"viewStatus": "Status",
"newGroupsWhatsNew": "Schau nach, was neu ist:",
"newGroupsBullet01": "Interagiere mit Aufgaben direkt vom Geteilte-Aufgaben-Brett",
"newGroupsBullet02": "Jeder kann eine unzugewiesene Aufgabe fertigstellen",
"youEmphasized": "<strong>Du</strong>",
"newGroupsBullet06": "Die Aufgabenstatusanzeige ermöglicht Dir schnell zu sehen, wer eine Aufgabe als erledigt markiert hat",
"newGroupsBullet08": "Der Gruppenleiter und die Gruppenmanager können schnell Aufgaben vom oberen Ende der Aufgabenlisten hinzufügen",
"sendGiftLabel": "Möchtest Du eine Geschenknachricht senden?",
"lastCompleted": "Zuletzt fertiggestellt",
"newGroupsBullet03": "Geteilte Aufgaben werden für alle zur selben Zeit zurückgesetzt, um die Zusammenarbeit zu erleichtern",
"newGroupsBullet04": "Geteilte Tagesaufgaben fügen keinen Schaden zu, wenn sie nicht erledigt werden oder im Gestrige-Aktivitäten-festhalten-Fenster erscheinen",
"newGroupsBullet07": "Schalte ein oder aus, dass geteilte Aufgaben auf Deiner persönlichen Aufgabenanzeige erscheinen",
"newGroupsBullet10": "Zuweisungsstatus bestimmt Abschlussbedingung:",
"newGroupsVisitFAQ": "Besuche die <a href='/static/faq#group-plans' target='_blank'>Häufigen Fragen</a> aus dem Hilfe-Dropdownmenü heraus für mehr Informationen.",
"newGroupsBullet05": "Die Farbe geteilter Aufgaben baut sich ab, wenn sie nicht erledigt werden, was das Verfolgen des Fortschritts erleichtert",
"newGroupsWelcome": "Wilkommen beim neuen Geteilte-Aufgaben-Brett!",
"newGroupsBullet10a": "<strong>Weise eine Aufgabe niemandem zu</strong>, wenn sie von jedem Mitglied abgeschlossen werden kann",
"newGroupsBullet10b": "<strong>Weise eine Aufgabe einem Mitglied zu</strong>, damit sie nur von diesem abgeschlossen werden kann",
"newGroupsBullet10c": "<strong>Weise eine Aufgabe mehreren Mitgliedern zu</strong>, wenn sie von allen abgeschlossen werden muss",
"newGroupsBullet09": "Eine geteilte Aufgabe kann als unfertig markiert werden um darauf aufmerksam zu machen, dass daran noch gearbeitet werden muss"
}
+7 -1
View File
@@ -229,5 +229,11 @@
"summer2022MantaRayMageSet": "Mantarochen (Magier)",
"julyYYYY": "Juli <%= year %>",
"octoberYYYY": "Oktober <%= year %>",
"februaryYYYY": "Februar <%= year %>"
"februaryYYYY": "Februar <%= year %>",
"fall2022KappaRogueSet": "Kappa (Schurke)",
"fall2022OrcWarriorSet": "Ork (Krieger)",
"fall2022HarpyMageSet": "Harpyie (Magier)",
"fall2022WatcherHealerSet": "Beobachter (Heiler)",
"gemSaleHow": "Kauf einfach zwischen <%= eventStartMonth %> <%= eventStartOrdinal %>und <%= eventEndOrdinal %> eines der Edelstein-Pakete wie normal und Deinem Konto werden automatisch die zusätzlichen Edelsteine gutgeschrieben. Das heißt insgesamt mehr Edelsteine zum ausgeben, teilen oder ansparen für zukünftige Veröffentlichungen!",
"gemSaleLimitations": "Dieses Sonderangebot gilt nur während der zeitlich beschränkten Aktion. Die Aktion startet am <%= eventStartOrdinal %>. <%= eventStartMonth %> um 8:00 EDT (12:00 UTC) und endet am <%= eventEndOrdinal %>. <%= eventStartMonth %> um 20:00 PM EDT (00:00 UTC). Das Sonderangebot ist nur verfügbar, wenn Du Edelsteine für Dich selbst kaufst."
}
+2 -2
View File
@@ -87,7 +87,7 @@
"paymentSuccessful": "Die Zahlung war erfolgreich!",
"paymentYouReceived": "Du hast erhalten:",
"paymentYouSentGems": "Du hast <strong><%- name %></strong> geschickt:",
"paymentYouSentSubscription": "Du hast <strong><%- name %></strong> ein <%= months %>-Monate-Abo für Habitica geschickt.",
"paymentYouSentSubscription": "Du hast <strong><%- name %></strong><br> ein <%= months %>-Monate-Abo für Habitica geschickt.",
"paymentSubBilling": "Dein Abonnement wird mit <strong>$<%= amount %></strong> alle <strong><%= months %> Monate</strong> verrechnet.",
"success": "Erfolg!",
"classGear": "Klassenausrüstung",
@@ -128,7 +128,7 @@
"nMonthsSubscriptionGift": "<%= nMonths %> Monat(e) Abonnement (Geschenk)",
"nGemsGift": "<%= nGems %> Edelsteine (Geschenk)",
"limitedAvailabilityMinutes": "Für <%= minutes %>min <%= seconds %>sek verfügbar",
"limitedAvailabilityHours": "Für <%= days %>t <%= hours %>std und <%= minutes %>min verfügbar",
"limitedAvailabilityHours": "Für t <%= hours %>std und <%= minutes %>min verfügbar",
"limitedAvailabilityDays": "Für <%= days %>t <%= hours %>std und <%= minutes %>min verfügbar",
"amountExp": "<%= amount %> Exp",
"newStuffPostedOn": "Veröffentlicht am <%= publishDate %> um <%= publishTime %>",
+1 -1
View File
@@ -659,7 +659,7 @@
"questSilverUnlockText": "Schaltet den Kauf von Silbernen Schlüpfelixieren auf dem Marktplatz frei",
"questRobotCompletion": "Als @Rev und der Rechenschafts-Buddy die letzte Schraube einsetzen, erwacht die Zeitmaschine zum Leben. @FolleMente und @McCoyly springen an Bord. „Danke für die Hilfe! Wir sehen uns in der Zukunft! Übrigens, die hier sollen Dir bei Deiner nächsten Erfindung helfen!\" Damit verschwinden die Zeitreisenden, aber im Wrack des alten Produktivitätsstabilisators verbleiben drei Eier mit Uhrwerken. Vielleicht sind das die entscheidenden Komponenten für eine neue Produktionslinie von Rechenschafts-Buddys!",
"questRobotNotes": "Im Max Kapazitäten-Labor verleiht @Rev der neuesten Erfindung, einem robotischen Rechenschafts-Buddy , den letzten Schliff, als plötzlich ein seltsames Metallfahrzeug in einer Rauchwolke erscheint, nur wenige Zentimeter vom Fluktuationsdetektor des Roboters entfernt! Die Insassen, zwei seltsame, in Silber gekleidete Gestalten, verlassen ihr Gefährt und nehmen ihre Weltraumhelme ab, wobei sie sich als @FolleMente und @McCoyly offenbaren. <br><br>„Ich postuliere, dass unsere Produktivitätsimplementierung eine Anomalie aufwies“, meint @FolleMente verlegen. <br><br>@ McCoyly verschränkt ihre Arme. „Das bedeutet, dass sie es versäumt haben, ihre Tagesaufgaben zu erledigen, was, wie ich postuliere, zur Zersetzung unseres Produktivitätsstabilisators geführt hat. Dabei handelt es sich um eine wesentliche Komponente für Zeitreisen, die zwingend Konsistenz benötigt, um richtig funktionieren zu können. Unsere Leistungen befeuern unsere Bewegung durch Zeit und Raum! Ich habe keine Zeit, um es genauer zu erklären, @Rev. Du wirst es in 37 Jahren entdecken oder vielleicht auch Deine Verbündeten, die Mysteriösen Zeitreisenden. Kannst Du uns vorerst dabei helfen, unsere Zeitmachine zu reparieren?\"",
"rockingReptilesNotes": "Beinhaltet den \"Insta-Gator\", \"Die Schlange der Ablenkung\" und den \"Veloci-Rpper\". Verfügbar bis zum 30. September.",
"rockingReptilesNotes": "Beinhaltet den \"Insta-Gator\", \"Die Schlange der Ablenkung\" und den \"Veloci-Rpper\". Verfügbar bis zum 30. November.",
"rockingReptilesText": "\"Rockendes Reptilien\"-Quest-Bundle",
"questRobotUnlockText": "Schaltet den Kauf von Robotereiern auf dem Markplatz frei",
"questRobotDropRobotEgg": "Roboter (Ei)",

Some files were not shown because too many files have changed in this diff Show More